diff --git a/.vpython3 b/.vpython3 index 14080bc..cf8d313 100644 --- a/.vpython3 +++ b/.vpython3
@@ -399,7 +399,7 @@ wheel < name: "infra/python/wheels/pytest-asyncio-py3" - version: "version:0.14.0" + version: "version:0.19.0" > wheel <
diff --git a/DEPS b/DEPS index 57cef0ae..61060ee 100644 --- a/DEPS +++ b/DEPS
@@ -304,7 +304,7 @@ # 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': '3b233921c78eb6b2bdaaad1525a8711c16a458af', + 'skia_revision': '0e0aa7e82d3a476d6e983b1fc383186082e948ad', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -312,11 +312,11 @@ # 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': '860a401fb6b8f77165fe1fb214d64ea38e2c8a39', + 'angle_revision': '34a06e25df2a1625bad36ab565319dace7cc5c54', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': 'f988757e44a35fc908b8ebb733d0eea1b5dc99a9', + 'swiftshader_revision': 'c85d70d97009a264fc5e7747316743a1abac5f67', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -375,7 +375,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '6834ebcc0933724042c4b8535bf85f04ff41dfd6', + 'catapult_revision': 'fb540cd80e69889f9d241a5b1946d9147c3f6c20', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. @@ -431,7 +431,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'a6dc75a19a9140a3f94d4a2effc433b68a623f66', + 'dawn_revision': 'a0456433619385c6c03e634d6069161bcb80d535', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -451,7 +451,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libavif # and whatever else without interference from each other. - 'libavif_revision': '24556f3c41b0efd06799da641229cff491f4a4a0', + 'libavif_revision': '129a59047ea2b31f21109b4ed07dde32662f1b4c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling nearby # and whatever else without interference from each other. @@ -790,7 +790,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '59e540aafc1605924674dc7c72fe7e8ce38160e7', + '52e08fba3410cf3b5d3d18734052bc45bc42f28c', 'condition': 'checkout_android and checkout_src_internal', }, @@ -1198,7 +1198,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'cfda6f1ab8b692fad1e5f0a9fc2cee273f19afbb', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '324dfc74b569a67598de148e85b2eb833bda1ecb', 'condition': 'checkout_chromeos', }, @@ -1702,7 +1702,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'be5933f4b25db0b6db546ed2949c52af2e0356fd', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '134b1104235eedbaa47555f5c27fa8d0b6c0c7c3', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1964,7 +1964,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': Var('chrome_git') + '/chrome/src-internal.git@670502a63cca8526c3bfb02c695f5aabe906d1c6', + 'url': Var('chrome_git') + '/chrome/src-internal.git@c6737ebfc10f0a0896b17cfd173c7df2c6c3f66f', 'condition': 'checkout_src_internal', },
diff --git a/ash/app_list/views/app_list_bubble_view.cc b/ash/app_list/views/app_list_bubble_view.cc index 8e6c47a..78c30837 100644 --- a/ash/app_list/views/app_list_bubble_view.cc +++ b/ash/app_list/views/app_list_bubble_view.cc
@@ -194,13 +194,21 @@ layer()->SetBackgroundBlur(ColorProvider::kBackgroundBlurSigma); layer()->SetBackdropFilterQuality(ColorProvider::kBackgroundBlurQuality); + const bool is_jelly_enabled = chromeos::features::IsJellyEnabled(); ui::ColorId background_color_id = - chromeos::features::IsJellyEnabled() + is_jelly_enabled ? static_cast<ui::ColorId>(cros_tokens::kCrosSysSystemBaseElevated) : kColorAshShieldAndBase80; SetBackground(views::CreateThemedRoundedRectBackground(background_color_id, kBubbleCornerRadius)); + SetBorder(std::make_unique<views::HighlightBorder>( + kBubbleCornerRadius, + is_jelly_enabled ? views::HighlightBorder::Type::kHighlightBorderOnShadow + : views::HighlightBorder::Type::kHighlightBorder1, + /*use_light_colors=*/false, + /*insets_type=*/views::HighlightBorder::InsetsType::kHalfInsets)); + views::FillLayout* layout = SetLayoutManager(std::make_unique<views::FillLayout>()); a11y_announcer_ = std::make_unique<AppListA11yAnnouncer>( @@ -588,14 +596,6 @@ return true; } -void AppListBubbleView::OnThemeChanged() { - views::View::OnThemeChanged(); - SetBorder(std::make_unique<views::HighlightBorder>( - kBubbleCornerRadius, views::HighlightBorder::Type::kHighlightBorder1, - /*use_light_colors=*/false, - /*insets_type=*/views::HighlightBorder::InsetsType::kHalfInsets)); -} - void AppListBubbleView::Layout() { views::View::Layout();
diff --git a/ash/app_list/views/app_list_bubble_view.h b/ash/app_list/views/app_list_bubble_view.h index 5f5724e..26690177 100644 --- a/ash/app_list/views/app_list_bubble_view.h +++ b/ash/app_list/views/app_list_bubble_view.h
@@ -96,7 +96,6 @@ // views::View: const char* GetClassName() const override; bool AcceleratorPressed(const ui::Accelerator& accelerator) override; - void OnThemeChanged() override; void Layout() override; // SearchBoxViewDelegate:
diff --git a/ash/app_list/views/app_list_folder_view.cc b/ash/app_list/views/app_list_folder_view.cc index f96ec57..d2a809e 100644 --- a/ash/app_list/views/app_list_folder_view.cc +++ b/ash/app_list/views/app_list_folder_view.cc
@@ -39,6 +39,7 @@ #include "base/metrics/histogram_macros.h" #include "base/ranges/algorithm.h" #include "base/strings/utf_string_conversions.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -615,6 +616,8 @@ DCHECK(view_delegate_); SetLayoutManager(std::make_unique<views::FillLayout>()); + const bool is_jelly_enabled = chromeos::features::IsJellyrollEnabled(); + // The background's corner radius cannot be changed in the same layer of the // contents container using layer animation, so use another layer to perform // such changes. @@ -629,8 +632,10 @@ gfx::RoundedCornersF(kFolderBackgroundRadius)); background_view_->layer()->SetIsFastRoundedCorner(true); background_view_->SetBorder(std::make_unique<views::HighlightBorder>( - kFolderBackgroundRadius, views::HighlightBorder::Type::kHighlightBorder1, - /*use_light_colors=*/!features::IsDarkLightModeEnabled())); + kFolderBackgroundRadius, + is_jelly_enabled ? views::HighlightBorder::Type::kHighlightBorderOnShadow + : views::HighlightBorder::Type::kHighlightBorder1, + /*use_light_colors=*/false)); background_view_->SetBackground( views::CreateThemedSolidBackground(kColorAshShieldAndBase80)); background_view_->SetVisible(false);
diff --git a/ash/app_list/views/app_list_toast_view.cc b/ash/app_list/views/app_list_toast_view.cc index 9a37ea0..799e257 100644 --- a/ash/app_list/views/app_list_toast_view.cc +++ b/ash/app_list/views/app_list_toast_view.cc
@@ -17,6 +17,7 @@ #include "ash/style/icon_button.h" #include "ash/style/pill_button.h" #include "ash/style/typography.h" +#include "chromeos/constants/chromeos_features.h" #include "components/vector_icons/vector_icons.h" #include "ui/color/color_id.h" #include "ui/compositor/layer.h" @@ -231,7 +232,10 @@ ColorProvider::BaseLayerType::kTransparent80), kCornerRadius)); SetBorder(std::make_unique<views::HighlightBorder>( - kCornerRadius, views::HighlightBorder::Type::kHighlightBorder1, + kCornerRadius, + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderNoShadow + : views::HighlightBorder::Type::kHighlightBorder1, /*use_light_colors=*/false)); } else { SetBackground(views::CreateRoundedRectBackground(
diff --git a/ash/app_list/views/continue_task_view.cc b/ash/app_list/views/continue_task_view.cc index 553e8f90..598d80e4 100644 --- a/ash/app_list/views/continue_task_view.cc +++ b/ash/app_list/views/continue_task_view.cc
@@ -24,6 +24,7 @@ #include "ash/style/typography.h" #include "base/functional/bind.h" #include "base/strings/string_util.h" +#include "chromeos/constants/chromeos_features.h" #include "extensions/common/constants.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -361,7 +362,9 @@ ColorProvider::BaseLayerType::kTransparent60))); SetBorder(std::make_unique<views::HighlightBorder>( GetCornerRadius(/*tablet_mode=*/true), - views::HighlightBorder::Type::kHighlightBorder2, + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderNoShadow + : views::HighlightBorder::Type::kHighlightBorder2, /*use_light_colors=*/false)); }
diff --git a/ash/app_list/views/remove_query_confirmation_dialog.cc b/ash/app_list/views/remove_query_confirmation_dialog.cc index 2d864c1..47f87af2 100644 --- a/ash/app_list/views/remove_query_confirmation_dialog.cc +++ b/ash/app_list/views/remove_query_confirmation_dialog.cc
@@ -15,6 +15,7 @@ #include "ash/style/ash_color_provider.h" #include "ash/style/pill_button.h" #include "base/functional/bind.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer.h" @@ -152,7 +153,9 @@ kDialogRoundedCornerRadius)); SetBorder(std::make_unique<views::HighlightBorder>( kDialogRoundedCornerRadius, - views::HighlightBorder::Type::kHighlightBorder1, + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderOnShadow + : views::HighlightBorder::Type::kHighlightBorder1, /*use_light_colors=*/false)); title_->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor( AshColorProvider::ContentLayerType::kTextColorPrimary));
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index 5ac4eba..b81a76c 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -429,7 +429,10 @@ views::HighlightBorder::PaintBorderToCanvas( canvas, *this, GetContentsBounds(), gfx::RoundedCornersF(corner_radius_), - views::HighlightBorder::Type::kHighlightBorder1, false); + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderNoShadow + : views::HighlightBorder::Type::kHighlightBorder1, + false); } }
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 175f5e7..854c1aa 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -5297,6 +5297,12 @@ <message name="IDS_ASH_SCREEN_CAPTURE_DISPLAY_SOURCE" desc="The name that is the display source of the screen capture notification."> Screen capture </message> + <message name="IDS_ASH_SCREEN_CAPTURE_GIF_PROGRESS_TITLE" desc="The title of the notification that shows up informing the user about the GIF file being processed."> + Creating GIF + </message> + <message name="IDS_ASH_SCREEN_CAPTURE_GIF_PROGRESS_MESSAGE" desc="The message of the notification that shows up informing the user about the GIF file being processed."> + Your GIF will be ready shortly + </message> <message name="IDS_ASH_SCREEN_CAPTURE_SCREENSHOT_TITLE" desc="The title of the notificaton which shows after a screenshot is taken."> Screenshot taken </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_GIF_PROGRESS_MESSAGE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_GIF_PROGRESS_MESSAGE.png.sha1 new file mode 100644 index 0000000..f4feb5b1 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_GIF_PROGRESS_MESSAGE.png.sha1
@@ -0,0 +1 @@ +f1aabcd202919e0a9348d82fef363cc814b1c1be \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_GIF_PROGRESS_TITLE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_GIF_PROGRESS_TITLE.png.sha1 new file mode 100644 index 0000000..f4feb5b1 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_GIF_PROGRESS_TITLE.png.sha1
@@ -0,0 +1 @@ +f1aabcd202919e0a9348d82fef363cc814b1c1be \ No newline at end of file
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc index 43415417..5b4ad315 100644 --- a/ash/capture_mode/capture_mode_controller.cc +++ b/ash/capture_mode/capture_mode_controller.cc
@@ -61,6 +61,7 @@ #include "ui/message_center/message_center.h" #include "ui/message_center/public/cpp/notification.h" #include "ui/message_center/public/cpp/notification_delegate.h" +#include "ui/message_center/public/cpp/notification_types.h" #include "ui/snapshot/snapshot.h" #include "ui/views/widget/widget.h" @@ -234,6 +235,16 @@ path)); } +// Adds the given `notification` to the message center after it removes any +// existing notification that has the same ID. +void AddNotificationToMessageCenter( + std::unique_ptr<message_center::Notification> notification) { + auto* message_center = message_center::MessageCenter::Get(); + message_center->RemoveNotification(notification->id(), + /*by_user=*/false); + message_center->AddNotification(std::move(notification)); +} + // Shows a Capture Mode related notification with the given parameters. // |for_video_thumbnail| will be considered only if |optional_fields| contain // an image to show in the notification as a thumbnail for what was captured. @@ -267,12 +278,7 @@ : kScreenShotNotificationType); } - // Remove the previous notification before showing the new one if there is - // any. - auto* message_center = message_center::MessageCenter::Get(); - message_center->RemoveNotification(notification_id, - /*by_user=*/false); - message_center->AddNotification(std::move(notification)); + AddNotificationToMessageCenter(std::move(notification)); } // Shows a notification informing the user that a Capture Mode operation has @@ -284,6 +290,24 @@ /*optional_fields=*/{}, /*delegate=*/nullptr); } +// Shows a notification that indicates to the user that the GIF file is being +// processed and will be ready shortly. +void ShowGifProgressNotification() { + message_center::RichNotificationData optional_fields; + optional_fields.progress = -1; // Infinite progress. + optional_fields.never_timeout = true; + AddNotificationToMessageCenter(CreateSystemNotificationPtr( + message_center::NOTIFICATION_TYPE_PROGRESS, kScreenCaptureNotificationId, + l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_GIF_PROGRESS_TITLE), + l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_GIF_PROGRESS_MESSAGE), + l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_DISPLAY_SOURCE), GURL(), + message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT, + kScreenCaptureNotifierId, + NotificationCatalogName::kScreenCapture), + optional_fields, /*delegate=*/nullptr, kCaptureModeIcon, + message_center::SystemNotificationWarningLevel::NORMAL)); +} + // Returns the ID of the message or the title for the notification based on // |allowance| and |for_title|. int GetDisabledNotificationMessageId(CaptureAllowance allowance, @@ -1216,6 +1240,13 @@ camera_controller_->MaybeRevertAutoCameraSelection(); video_recording_watcher_->ShutDown(); + + // GIF files take a while to finalize and fully get written to disk. Therefore + // we show a notification to the user to let them know that the file will be + // ready shortly. + if (current_video_file_path_.MatchesExtension(".gif")) { + ShowGifProgressNotification(); + } } void CaptureModeController::CaptureImage(const CaptureParams& capture_params, @@ -1835,6 +1866,12 @@ current_video_file_path_.clear(); if (should_delete_file) { + // Remove any lingering notification, e.g. the GIF progress notification, + // before proceeding, since it no longer makes sense as the file will be + // deleted. + message_center::MessageCenter::Get()->RemoveNotification( + kScreenCaptureNotificationId, /*by_user=*/false); + DeleteFileAsync(blocking_task_runner_, video_file_path, std::move(on_file_deleted_callback_for_test_)); } else {
diff --git a/ash/capture_mode/video_recording_watcher.cc b/ash/capture_mode/video_recording_watcher.cc index 9d25207..4908039 100644 --- a/ash/capture_mode/video_recording_watcher.cc +++ b/ash/capture_mode/video_recording_watcher.cc
@@ -282,6 +282,7 @@ recording_overlay_controller_.reset(); demo_tools_controller_.reset(); dimmers_.clear(); + ReleaseLayer(); if (features::IsProjectorEnabled()) ProjectorControllerImpl::Get()->OnRecordingEnded(is_in_projector_mode_);
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc index 1ac72de..12a6f5c 100644 --- a/ash/shelf/shelf_layout_manager_unittest.cc +++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -5069,9 +5069,11 @@ bitmap.allocN32Pixels(30, 30); gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); image_skia.MakeThreadSafe(); - status_area->eche_tray()->LoadBubble(GURL("http://google.com"), - gfx::Image(image_skia), u"app 1", - u"your phone"); + status_area->eche_tray()->LoadBubble( + GURL("http://google.com"), gfx::Image(image_skia), u"app 1", + u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::UNKNOWN); status_area->eche_tray()->ShowBubble(); UpdateAutoHideStateNow();
diff --git a/ash/system/eche/eche_tray.cc b/ash/system/eche/eche_tray.cc index ba4fb135..9491452e 100644 --- a/ash/system/eche/eche_tray.cc +++ b/ash/system/eche/eche_tray.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include "ash/accessibility/accessibility_controller_impl.h" +#include "ash/constants/ash_features.h" #include "ash/constants/notifier_catalogs.h" #include "ash/constants/tray_background_view_catalog.h" #include "ash/keyboard/ui/keyboard_ui_controller.h" @@ -34,6 +35,7 @@ #include "ash/system/tray/tray_container.h" #include "ash/system/tray/tray_popup_utils.h" #include "ash/system/tray/tray_utils.h" +#include "ash/webui/eche_app_ui/mojom/eche_app.mojom-shared.h" #include "ash/webui/eche_app_ui/mojom/eche_app.mojom.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" @@ -115,6 +117,9 @@ // Unload timeout to close Eche Bubble in case error from Ech web during closing constexpr base::TimeDelta kUnloadTimeoutDuration = base::Milliseconds(500); +// Timeout for initializer connection attempts. +constexpr base::TimeDelta kInitializerTimeout = base::Seconds(6); + // The ID for the "Copy/paste not yet implemented" toast. constexpr char kEcheTrayCopyPasteNotImplementedToastId[] = "eche_tray_toast_ids.copy_paste_not_implemented"; @@ -415,7 +420,6 @@ void EcheTray::OnConnectionStatusChanged( eche_app::mojom::ConnectionStatus connection_status) { - // TODO(b/274799846): Reintroduce timeout to conditional if (!features::IsEcheNetworkConnectionStateEnabled() || !initializer_webview_) { return; @@ -428,13 +432,25 @@ case eche_app::mojom::ConnectionStatus::kConnectionStatusConnected: eche_connection_status_handler_->SetConnectionStatusForUi( connection_status); + has_reported_initializer_result_ = true; + base::UmaHistogramBoolean("Eche.NetworkCheck.Result", true); break; case eche_app::mojom::ConnectionStatus::kConnectionStatusFailed: eche_connection_status_handler_->SetConnectionStatusForUi( connection_status); + base::UmaHistogramBoolean("Eche.NetworkCheck.Result", false); + has_reported_initializer_result_ = true; break; case eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected: - // TODO(b/274799846): Cleanup shutdown + if (!has_reported_initializer_result_) { + // If we've timedout or been disconnected before a success/failure has + // come in, report failure. + base::UmaHistogramBoolean("Eche.NetworkCheck.Result", false); + eche_connection_status_handler_->SetConnectionStatusForUi( + eche_app::mojom::ConnectionStatus::kConnectionStatusFailed); + } + + StartGracefulCloseInitializer(); break; } } @@ -443,16 +459,32 @@ if (!features::IsEcheNetworkConnectionStateEnabled() || IsInitialized()) { return; } - + has_reported_initializer_result_ = false; initializer_webview_ = CreateWebview(); initializer_webview_->Navigate(GURL(kEchePrewarmConnectionUrl)); + initializer_timeout_ = std::make_unique<base::DelayTimer>( + FROM_HERE, kInitializerTimeout, this, + &EcheTray::StartGracefulCloseInitializer); + initializer_timeout_->Reset(); // Starts the timer. SetIconVisibility(false); } -void EcheTray::OnPhoneHubDisconnected() { +void EcheTray::CloseInitializer() { initializer_webview_.reset(); } +void EcheTray::StartGracefulCloseInitializer() { + if (!initializer_webview_) { + return; + } + + initializer_timeout_.reset(); + eche_connection_status_handler_->NotifyRequestCloseConnection(); + unload_timer_ = std::make_unique<base::DelayTimer>( + FROM_HERE, kUnloadTimeoutDuration, this, &EcheTray::CloseInitializer); + unload_timer_->Reset(); // Starts the timer. +} + void EcheTray::SetUrl(const GURL& url) { if (web_view_ && url_ != url) web_view_->Navigate(url); @@ -473,10 +505,13 @@ } } -bool EcheTray::LoadBubble(const GURL& url, - const gfx::Image& icon, - const std::u16string& visible_name, - const std::u16string& phone_name) { +bool EcheTray::LoadBubble( + const GURL& url, + const gfx::Image& icon, + const std::u16string& visible_name, + const std::u16string& phone_name, + eche_app::mojom::ConnectionStatus last_connection_status, + eche_app::mojom::AppStreamLaunchEntryPoint entry_point) { if (Shell::Get()->IsInTabletMode()) { ash::ToastManager::Get()->Show(ash::ToastData( kEcheTrayTabletModeNotSupportedId, @@ -498,7 +533,7 @@ ShowBubble(); return true; } - InitBubble(phone_name); + InitBubble(phone_name, last_connection_status, entry_point); StartLoadingAnimation(); auto* phone_hub_tray = GetPhoneHubTray(); if (phone_hub_tray) { @@ -559,10 +594,22 @@ shelf()->UpdateAutoHideState(); } -void EcheTray::InitBubble(const std::u16string& phone_name) { - base::UmaHistogramEnumeration( - "Eche.StreamEvent", - eche_app::mojom::StreamStatus::kStreamStatusInitializing); +void EcheTray::InitBubble( + const std::u16string& phone_name, + eche_app::mojom::ConnectionStatus last_connection_status, + eche_app::mojom::AppStreamLaunchEntryPoint entry_point) { + if (features::IsEcheNetworkConnectionStateEnabled() && + last_connection_status == + eche_app::mojom::ConnectionStatus::kConnectionStatusFailed && + entry_point == eche_app::mojom::AppStreamLaunchEntryPoint::NOTIFICATION) { + base::UmaHistogramEnumeration( + "Eche.StreamEvent.FromNotification.PreviousNetworkCheckFailed.Result", + eche_app::mojom::StreamStatus::kStreamStatusInitializing); + } else { + base::UmaHistogramEnumeration( + "Eche.StreamEvent", + eche_app::mojom::StreamStatus::kStreamStatusInitializing); + } init_stream_timestamp_ = base::TimeTicks::Now(); TrayBubbleView::InitParams init_params; init_params.delegate = GetWeakPtr(); @@ -630,6 +677,9 @@ init_stream_timestamp_.reset(); } + // If there's an initializer session running it should also be shutdown. + StartGracefulCloseInitializer(); + if (!graceful_close_callback_) { PurgeAndClose(); return; @@ -950,6 +1000,10 @@ } } +bool EcheTray::IsBackgroundConnectionAttemptInProgress() { + return initializer_webview_ ? true : false; +} + BEGIN_METADATA(EcheTray, TrayBackgroundView) END_METADATA
diff --git a/ash/system/eche/eche_tray.h b/ash/system/eche/eche_tray.h index e4e1bc2..dfbfe93a 100644 --- a/ash/system/eche/eche_tray.h +++ b/ash/system/eche/eche_tray.h
@@ -17,6 +17,7 @@ #include "ash/system/screen_layout_observer.h" #include "ash/system/tray/tray_background_view.h" #include "ash/webui/eche_app_ui/eche_connection_status_handler.h" +#include "ash/webui/eche_app_ui/mojom/eche_app.mojom-shared.h" #include "ash/webui/eche_app_ui/mojom/eche_app.mojom.h" #include "base/gtest_prod_util.h" #include "base/timer/timer.h" @@ -155,7 +156,6 @@ void OnConnectionStatusChanged( eche_app::mojom::ConnectionStatus connection_status) override; void OnRequestBackgroundConnectionAttempt() override; - void OnPhoneHubDisconnected() override; // Sets the url that will be passed to the webview. // Setting a new value will cause the current bubble be destroyed. @@ -201,7 +201,9 @@ bool LoadBubble(const GURL& url, const gfx::Image& icon, const std::u16string& visible_name, - const std::u16string& phone_name); + const std::u16string& phone_name, + eche_app::mojom::ConnectionStatus last_connection_status, + eche_app::mojom::AppStreamLaunchEntryPoint entry_point); // Destroys the view inclusing the web view. // Note: `CloseBubble` only hides the view. @@ -222,7 +224,9 @@ // Set up the params and init the bubble. // Note: This function makes the bubble active and makes the // TrayBackgroundView's background inkdrop activate. - void InitBubble(const std::u16string& phone_name); + void InitBubble(const std::u16string& phone_name, + eche_app::mojom::ConnectionStatus last_connection_status, + eche_app::mojom::AppStreamLaunchEntryPoint entry_point); // Starts graceful close to ensure the connection resource is released before // the window is closed. @@ -231,6 +235,8 @@ void SetEcheConnectionStatusHandler( eche_app::EcheConnectionStatusHandler* eche_connection_status_handler); + bool IsBackgroundConnectionAttemptInProgress(); + // Test helpers bool get_is_landscape_for_test() { return is_landscape_; } TrayBubbleWrapper* get_bubble_wrapper_for_test() { return bubble_.get(); } @@ -314,6 +320,12 @@ // Returns true only if the bubble is initialized and visible. bool IsBubbleVisible(); + // Starts graceful shutdown for the initializer. + void StartGracefulCloseInitializer(); + + // Kills the renderer. + void CloseInitializer(); + // The url that is transferred to the web view. // In the current implementation, this is supposed to be // Eche window URL. However, the bubble does not interpret, @@ -333,6 +345,8 @@ // Webview used to create a prewarming channel, before we have a video to // attach to. std::unique_ptr<AshWebView> initializer_webview_{}; + std::unique_ptr<base::DelayTimer> initializer_timeout_{}; + bool has_reported_initializer_result_ = false; eche_app::EcheConnectionStatusHandler* eche_connection_status_handler_ = nullptr;
diff --git a/ash/system/eche/eche_tray_unittest.cc b/ash/system/eche/eche_tray_unittest.cc index d639491..2c00da9 100644 --- a/ash/system/eche/eche_tray_unittest.cc +++ b/ash/system/eche/eche_tray_unittest.cc
@@ -124,6 +124,8 @@ eche_connection_status_handler_->AddObserver( &fake_connection_status_observer_); eche_tray_ = StatusAreaWidgetTestHelper::GetStatusAreaWidget()->eche_tray(); + eche_tray_->SetEcheConnectionStatusHandler( + eche_connection_status_handler_.get()); phone_hub_tray_ = StatusAreaWidgetTestHelper::GetStatusAreaWidget()->phone_hub_tray(); @@ -189,8 +191,10 @@ EXPECT_FALSE(eche_tray()->GetVisible()); eche_tray()->SetVisiblePreferred(true); - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE(eche_tray()->is_active()); @@ -226,8 +230,10 @@ TEST_F(EcheTrayTest, EcheTrayIconResize) { eche_tray()->SetVisiblePreferred(true); - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); int image_width = phone_hub_tray() @@ -246,8 +252,10 @@ } TEST_F(EcheTrayTest, OnAnyBubbleVisibilityChanged) { - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE( @@ -265,8 +273,10 @@ // OnAnyBubbleVisibilityChanged() is called on the current bubble and hence // should be ignored. TEST_F(EcheTrayTest, OnAnyBubbleVisibilityChanged_SameWidget) { - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE( @@ -282,8 +292,10 @@ // OnAnyBubbleVisibilityChanged() is called on some other bubble but the // visible parameter is false, hence we should not do anything. TEST_F(EcheTrayTest, OnAnyBubbleVisibilityChanged_NonVisible) { - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE( @@ -304,8 +316,10 @@ // Allow us to create the bubble but it is not visible until we need this // bubble to show up. - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); EXPECT_FALSE(eche_tray()->is_active()); EXPECT_TRUE(eche_tray()->get_bubble_wrapper_for_test()); @@ -332,8 +346,10 @@ // Allow us to create the bubble but it is not visible until we need this // bubble to show up. - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); EXPECT_FALSE(eche_tray()->is_active()); EXPECT_TRUE(eche_tray()->get_bubble_wrapper_for_test()); @@ -360,8 +376,10 @@ } TEST_F(EcheTrayTest, EcheTrayMinimizeButtonClicked) { - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE( @@ -377,8 +395,10 @@ TEST_F(EcheTrayTest, EcheTrayCloseButtonClicked) { ResetUnloadWebContent(); eche_tray()->SetGracefulCloseCallback(base::BindOnce(&UnloadWebContent)); - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); ClickButton(eche_tray()->GetCloseButtonForTesting()); @@ -390,8 +410,10 @@ ResetWebContentGoBack(); eche_tray()->SetGracefulGoBackCallback( base::BindRepeating(&WebContentGoBack)); - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); ClickButton(eche_tray()->GetArrowBackButtonForTesting()); @@ -404,8 +426,10 @@ } TEST_F(EcheTrayTest, AcceleratorKeyHandled_Minimize) { - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE( @@ -431,8 +455,10 @@ TEST_F(EcheTrayTest, AcceleratorKeyHandled_Ctrl_W) { ResetUnloadWebContent(); eche_tray()->SetGracefulCloseCallback(base::BindOnce(&UnloadWebContent)); - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE( @@ -446,8 +472,10 @@ } TEST_F(EcheTrayTest, AcceleratorKeyHandled_Ctrl_C) { - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE( @@ -464,8 +492,10 @@ } TEST_F(EcheTrayTest, AcceleratorKeyHandled_Ctrl_V) { - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE( @@ -482,8 +512,10 @@ } TEST_F(EcheTrayTest, AcceleratorKeyHandled_Ctrl_X) { - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE( @@ -503,8 +535,10 @@ ResetWebContentGoBack(); eche_tray()->SetGracefulGoBackCallback( base::BindRepeating(&WebContentGoBack)); - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_BROWSER_BACK, 0); @@ -515,8 +549,10 @@ TEST_F(EcheTrayTest, AcceleratorKeyHandled_Esc) { ResetUnloadWebContent(); eche_tray()->SetGracefulCloseCallback(base::BindOnce(&UnloadWebContent)); - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE( @@ -532,8 +568,10 @@ TEST_F(EcheTrayTest, EcheTrayOnDisplayConfigurationChanged) { UpdateDisplay("800x600"); gfx::Size expected_eche_size = eche_tray()->CalculateSizeForEche(); - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_EQ(expected_eche_size.width(), @@ -556,8 +594,10 @@ TEST_F(EcheTrayTest, EcheTrayKeyboardShowHideUpdateBubbleBounds) { gfx::Size expected_eche_size = eche_tray()->CalculateSizeForEche(); - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_EQ(expected_eche_size.width(), @@ -586,8 +626,10 @@ TEST_F(EcheTrayTest, EcheTrayOnStreamOrientationChanged) { gfx::Size expected_eche_size = eche_tray()->CalculateSizeForEche(); - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_EQ(eche_tray()->get_is_landscape_for_test(), false); @@ -661,21 +703,21 @@ eche_tray()->OnConnectionStatusChanged( ConnectionStatus::kConnectionStatusConnecting); - EXPECT_EQ(GetLastConnectionChangedForUiStatus(), - ConnectionStatus::kConnectionStatusDisconnected); EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 0u); EXPECT_TRUE(eche_tray()->get_initializer_webview_for_test()); eche_tray()->OnConnectionStatusChanged( - ConnectionStatus::kConnectionStatusDisconnected); - EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 0u); + ConnectionStatus::kConnectionStatusConnected); + EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 1u); EXPECT_TRUE(eche_tray()->get_initializer_webview_for_test()); } TEST_F(EcheTrayTest, DISABLED_OnThemeChanged) { ResetUnloadWebContent(); - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE(eche_tray()->is_active()); @@ -702,8 +744,10 @@ TEST_F(EcheTrayTest, OnThemeChangedNoBubble) { ResetUnloadWebContent(); - eche_tray()->LoadBubble(GURL("http://google.com"), CreateTestImage(), - u"app 1", u"your phone"); + eche_tray()->LoadBubble( + GURL("http://google.com"), CreateTestImage(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray()->ShowBubble(); EXPECT_TRUE(eche_tray()->is_active());
diff --git a/ash/system/holding_space/holding_space_tray_child_bubble.cc b/ash/system/holding_space/holding_space_tray_child_bubble.cc index 3ff6e08..3b0958ee 100644 --- a/ash/system/holding_space/holding_space_tray_child_bubble.cc +++ b/ash/system/holding_space/holding_space_tray_child_bubble.cc
@@ -16,6 +16,7 @@ #include "ash/system/holding_space/holding_space_view_delegate.h" #include "base/functional/bind.h" #include "base/ranges/algorithm.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/compositor/callback_layer_animation_observer.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animation_observer.h" @@ -205,7 +206,10 @@ SetBackground(views::CreateThemedSolidBackground(kColorAshShieldAndBase80)); SetBorder(std::make_unique<views::HighlightBorder>( - kBubbleCornerRadius, views::HighlightBorder::Type::kHighlightBorder1, + kBubbleCornerRadius, + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderOnShadow + : views::HighlightBorder::Type::kHighlightBorder1, /*use_light_colors=*/false)); }
diff --git a/ash/system/phonehub/phone_hub_ui_controller_unittest.cc b/ash/system/phonehub/phone_hub_ui_controller_unittest.cc index 5c41dbcb..b3982237 100644 --- a/ash/system/phonehub/phone_hub_ui_controller_unittest.cc +++ b/ash/system/phonehub/phone_hub_ui_controller_unittest.cc
@@ -397,8 +397,10 @@ TEST_F(PhoneHubUiControllerTest, HandleBubbleOpenedShouldCloseEcheBubble) { EcheTray* eche_tray = StatusAreaWidgetTestHelper::GetStatusAreaWidget()->eche_tray(); - eche_tray->LoadBubble(GURL("http://google.com"), gfx::Image(), u"app 1", - u"your phone"); + eche_tray->LoadBubble( + GURL("http://google.com"), gfx::Image(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); eche_tray->ShowBubble(); EXPECT_TRUE( eche_tray->get_bubble_wrapper_for_test()->bubble_view()->GetVisible());
diff --git a/ash/system/power/power_button_menu_view.cc b/ash/system/power/power_button_menu_view.cc index fc371d3..370918a 100644 --- a/ash/system/power/power_button_menu_view.cc +++ b/ash/system/power/power_button_menu_view.cc
@@ -25,6 +25,7 @@ #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/time/time.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animator.h" @@ -58,7 +59,10 @@ SetFocusBehavior(FocusBehavior::ALWAYS); SetPaintToLayer(); SetBorder(std::make_unique<views::HighlightBorder>( - kPowerButtonMenuCornerRadius, kPowerButtonMenuBorderType, + kPowerButtonMenuCornerRadius, + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderOnShadow + : kPowerButtonMenuBorderType, /*use_light_colors=*/false)); SetBackground( views::CreateThemedSolidBackground(kPowerButtonMenuBackgroundColorId));
diff --git a/ash/system/status_area_widget_unittest.cc b/ash/system/status_area_widget_unittest.cc index 557a8c7..5afc831 100644 --- a/ash/system/status_area_widget_unittest.cc +++ b/ash/system/status_area_widget_unittest.cc
@@ -705,9 +705,11 @@ bitmap.allocN32Pixels(30, 30); gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); image_skia.MakeThreadSafe(); - status_area->eche_tray()->LoadBubble(GURL("http://google.com"), - gfx::Image(image_skia), u"app 1", - u"your phone"); + status_area->eche_tray()->LoadBubble( + GURL("http://google.com"), gfx::Image(image_skia), u"app 1", + u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST); status_area->eche_tray()->ShowBubble(); // Auto-hidden shelf would be forced to be visible.
diff --git a/ash/system/time/calendar_event_list_view.cc b/ash/system/time/calendar_event_list_view.cc index 4f3f16fb..a352219 100644 --- a/ash/system/time/calendar_event_list_view.cc +++ b/ash/system/time/calendar_event_list_view.cc
@@ -18,6 +18,7 @@ #include "ash/system/model/system_tray_model.h" #include "ash/system/time/calendar_event_list_item_view.h" #include "ash/system/time/calendar_event_list_item_view_jelly.h" +#include "ash/system/time/calendar_metrics.h" #include "ash/system/time/calendar_utils.h" #include "ash/system/time/calendar_view_controller.h" #include "chromeos/constants/chromeos_features.h" @@ -269,12 +270,17 @@ content_view_->InvalidateLayout(); + calendar_metrics::RecordEventListEventCount(multi_day_events.size() + + all_other_events.size()); + if (!multi_day_events.empty() || !all_other_events.empty()) return; } else { std::list<google_apis::calendar::CalendarEvent> events = calendar_view_controller_->SelectedDateEvents(); + calendar_metrics::RecordEventListEventCount(events.size()); + if (events.size() > 0) { for (auto& event : events) { auto* event_entry = content_view_->AddChildView(
diff --git a/ash/system/time/calendar_event_list_view_unittest.cc b/ash/system/time/calendar_event_list_view_unittest.cc index 841a354..d315ef7 100644 --- a/ash/system/time/calendar_event_list_view_unittest.cc +++ b/ash/system/time/calendar_event_list_view_unittest.cc
@@ -179,6 +179,9 @@ histogram_tester.ExpectTotalCount( "Ash.Calendar.UserJourneyTime.EventLaunched", 1); + EXPECT_EQ(histogram_tester.GetTotalSum( + "Ash.Calendar.EventListView.EventDisplayedCount"), + 0); } TEST_F(CalendarViewEventListViewTest, LaunchItem) { @@ -186,8 +189,6 @@ base::Time date; ASSERT_TRUE(base::Time::FromString("18 Nov 2021 10:00 GMT", &date)); CreateEventListView(date); - - SetSelectedDate(date); EXPECT_EQ(3u, content_view()->children().size()); // Launch the first item. @@ -199,6 +200,9 @@ histogram_tester.ExpectTotalCount( "Ash.Calendar.UserJourneyTime.EventLaunched", 1); histogram_tester.ExpectTotalCount("Ash.Calendar.EventListItem.Activated", 1); + EXPECT_EQ(histogram_tester.GetTotalSum( + "Ash.Calendar.EventListView.EventDisplayedCount"), + 3); } TEST_F(CalendarViewEventListViewTest, CheckTimeFormat) {
diff --git a/ash/system/time/calendar_metrics.cc b/ash/system/time/calendar_metrics.cc index 1359392..a9cb7e4 100644 --- a/ash/system/time/calendar_metrics.cc +++ b/ash/system/time/calendar_metrics.cc
@@ -4,6 +4,7 @@ #include "ash/system/time/calendar_metrics.h" +#include "ash/constants/ash_features.h" #include "ash/public/cpp/metrics_util.h" #include "base/check_op.h" #include "base/metrics/histogram_functions.h" @@ -41,6 +42,12 @@ "Ash.Calendar.EventListView.JoinMeetingButton.Pressed"; constexpr char kCalendarUpNextJoinButtonPressed[] = "Ash.Calendar.UpNextView.JoinMeetingButton.Pressed"; +constexpr char kCalendarEventListEventDisplayedCount[] = + "Ash.Calendar.EventListView.EventDisplayedCount"; +constexpr char kCalendarEventListJellyEventDisplayedCount[] = + "Ash.Calendar.EventListViewJelly.EventDisplayedCount"; +constexpr char kCalendarEventsDisplayedToUser[] = + "Ash.Calendar.EventsDisplayedToUser"; } // namespace @@ -141,6 +148,21 @@ GetEventType(event)); } +void RecordEventListEventCount(const int event_count) { + if (features::IsCalendarJellyEnabled()) { + base::UmaHistogramCounts100(kCalendarEventListJellyEventDisplayedCount, + event_count); + return; + } + + base::UmaHistogramCounts100(kCalendarEventListEventDisplayedCount, + event_count); +} + +void RecordEventsDisplayedToUser() { + base::UmaHistogramBoolean(kCalendarEventsDisplayedToUser, true); +} + } // namespace calendar_metrics } // namespace ash
diff --git a/ash/system/time/calendar_metrics.h b/ash/system/time/calendar_metrics.h index 1073965..de2d0125 100644 --- a/ash/system/time/calendar_metrics.h +++ b/ash/system/time/calendar_metrics.h
@@ -104,6 +104,10 @@ void RecordJoinButtonPressedFromUpNextView(const ui::Event& event); +void RecordEventListEventCount(const int event_count); + +void RecordEventsDisplayedToUser(); + } // namespace calendar_metrics } // namespace ash
diff --git a/ash/system/time/calendar_month_view.cc b/ash/system/time/calendar_month_view.cc index 3e2215ab..9606f14 100644 --- a/ash/system/time/calendar_month_view.cc +++ b/ash/system/time/calendar_month_view.cc
@@ -514,8 +514,20 @@ const CalendarModel::FetchingStatus status, const base::Time start_time, const google_apis::calendar::EventList* events) { - if (status == CalendarModel::kSuccess && start_time == fetch_month_) + if (status == CalendarModel::kSuccess && start_time == fetch_month_) { UpdateIsFetchedAndRepaint(true); + } + + if (!events || events->items().size() == 0) { + return; + } + + has_events_ = true; + + if (start_time == + calendar_view_controller_->GetOnScreenMonthFirstDayUTC().UTCMidnight()) { + calendar_view_controller_->EventsDisplayedToUser(); + } } void CalendarMonthView::EnableFocus() {
diff --git a/ash/system/time/calendar_month_view.h b/ash/system/time/calendar_month_view.h index e29e3b0e..afbe255 100644 --- a/ash/system/time/calendar_month_view.h +++ b/ash/system/time/calendar_month_view.h
@@ -160,6 +160,9 @@ // Returns the index of this month view's last row. int last_row_index() const { return last_row_index_; } + // If this month contains any events. + bool has_events() { return has_events_; } + private: // For unit tests. friend class CalendarMonthViewTest; @@ -185,6 +188,8 @@ // The index of this month view's last row. int last_row_index_; + bool has_events_ = false; + // The cells of each row that should be first focused on. These // `CalendarDateCellView`s are the children of this view. std::vector<CalendarDateCellView*> focused_cells_;
diff --git a/ash/system/time/calendar_month_view_unittest.cc b/ash/system/time/calendar_month_view_unittest.cc index 504d333..36046547 100644 --- a/ash/system/time/calendar_month_view_unittest.cc +++ b/ash/system/time/calendar_month_view_unittest.cc
@@ -16,6 +16,7 @@ #include "ash/system/time/calendar_utils.h" #include "ash/system/time/calendar_view_controller.h" #include "ash/test/ash_test_base.h" +#include "base/test/metrics/histogram_tester.h" #include "base/time/time.h" #include "base/time/time_override.h" #include "chromeos/ash/components/settings/scoped_timezone_settings.h" @@ -526,6 +527,41 @@ ->GetTooltipText()); } +TEST_F(CalendarMonthViewFetchTest, RecordEventsDisplayedToUserOnce) { + base::HistogramTester histogram_tester; + // Create a monthview based on Aug,1st 2021. Today is set to 18th. + base::Time date; + ASSERT_TRUE(base::Time::FromString("1 Aug 2021 10:00 GMT", &date)); + base::Time today; + ASSERT_TRUE(base::Time::FromString("18 Aug 2021 10:00 GMT", &today)); + SetTodayFromTime(today); + ash::system::ScopedTimezoneSettings timezone_settings(u"America/Los_Angeles"); + + CreateMonthView(date); + WaitUntilPainted(); + + // Nothing logged before we've fetched events. + histogram_tester.ExpectTotalCount("Ash.Calendar.EventsDisplayedToUser", 0); + + // Sets the event list response and fetches the events. + auto event_list = CreateMockEventList(); + SetEventList(std::move(event_list)); + calendar_model_->FetchEvents(calendar_utils::GetStartOfMonthUTC(today)); + WaitUntilFetched(); + + // After fetching, we expect the metric to be logged. + histogram_tester.ExpectTotalCount("Ash.Calendar.EventsDisplayedToUser", 1); + + // Fetch new events. + auto event_list_2 = CreateMockEventList(); + SetEventList(std::move(event_list_2)); + calendar_model_->FetchEvents(calendar_utils::GetStartOfMonthUTC(today)); + WaitUntilFetched(); + + // After fetching again, we don't expect any additional logs of the metric. + histogram_tester.ExpectTotalCount("Ash.Calendar.EventsDisplayedToUser", 1); +} + TEST_F(CalendarMonthViewFetchTest, TimeZone) { // Create a monthview based on Aug,1st 2021. Today is set to 18th. base::Time date;
diff --git a/ash/system/time/calendar_view.cc b/ash/system/time/calendar_view.cc index f64c4ad32..97f7d31 100644 --- a/ash/system/time/calendar_view.cc +++ b/ash/system/time/calendar_view.cc
@@ -22,7 +22,6 @@ #include "ash/system/tray/tri_view.h" #include "base/check.h" #include "base/functional/bind.h" -#include "base/memory/weak_ptr.h" #include "base/strings/string_number_conversions.h" #include "base/time/time.h" #include "components/vector_icons/vector_icons.h" @@ -1391,6 +1390,10 @@ scroll_view_->ScrollToPosition(scroll_view_->vertical_scroll_bar(), position); MaybeResetContentViewFocusBehavior(); + + if (current_month_->has_events()) { + calendar_view_controller_->EventsDisplayedToUser(); + } } void CalendarView::ScrollDownOneMonth() { @@ -1428,6 +1431,10 @@ scroll_view_->ScrollToPosition(scroll_view_->vertical_scroll_bar(), position); MaybeResetContentViewFocusBehavior(); + + if (current_month_->has_events()) { + calendar_view_controller_->EventsDisplayedToUser(); + } } void CalendarView::ScrollOneMonthAndAutoScroll(bool scroll_up) {
diff --git a/ash/system/time/calendar_view_controller.cc b/ash/system/time/calendar_view_controller.cc index f310ed50..1b9057de 100644 --- a/ash/system/time/calendar_view_controller.cc +++ b/ash/system/time/calendar_view_controller.cc
@@ -257,6 +257,17 @@ todays_date_cell_fetch_recorded_ = true; } +void CalendarViewController::EventsDisplayedToUser() { + // Only record this once per lifetime of the `CalendarView` (and therefore the + // controller). + if (events_shown_to_user_recorded_) { + return; + } + + calendar_metrics::RecordEventsDisplayedToUser(); + events_shown_to_user_recorded_ = true; +} + bool CalendarViewController::IsSelectedDateInCurrentMonth() { if (!selected_date_.has_value()) return false;
diff --git a/ash/system/time/calendar_view_controller.h b/ash/system/time/calendar_view_controller.h index bf7952c..af974dc 100644 --- a/ash/system/time/calendar_view_controller.h +++ b/ash/system/time/calendar_view_controller.h
@@ -89,6 +89,10 @@ // Called when the CalendarDateCellView representing today gets a fetch. void OnTodaysEventFetchComplete(); + // Called when the on screen month has finished loading and has any events to + // display to the user. Logs a metric once per CalendarView lifetime. + void EventsDisplayedToUser(); + // If the selected date in the current month. This is used to inform the // `CalendarView` if the month should be updated when a date is selected. bool IsSelectedDateInCurrentMonth(); @@ -228,6 +232,10 @@ // events has been recorded. bool todays_date_cell_fetch_recorded_ = false; + // Record if any events are displayed (via the dots in the current month) on + // screen to the user. + bool events_shown_to_user_recorded_ = false; + // The currently selected date. absl::optional<base::Time> selected_date_;
diff --git a/ash/system/time/calendar_view_unittest.cc b/ash/system/time/calendar_view_unittest.cc index ad5beac..7860d21 100644 --- a/ash/system/time/calendar_view_unittest.cc +++ b/ash/system/time/calendar_view_unittest.cc
@@ -2700,4 +2700,46 @@ EXPECT_EQ(focus_manager->GetFocusedView(), close_button()); } +TEST_F(CalendarViewWithJellyEnabledTest, RecordEventsDisplayedToUserOnce) { + base::HistogramTester histogram_tester; + base::Time now; + ASSERT_TRUE(base::Time::FromString("1 Oct 2021 10:00 GMT", &now)); + base::Time next_month; + ASSERT_TRUE(base::Time::FromString("1 Nov 2021 10:00 GMT", &next_month)); + // Set time override. + SetFakeNow(now); + base::subtle::ScopedTimeClockOverrides time_override( + &CalendarViewTest::FakeTimeNow, /*time_ticks_override=*/nullptr, + /*thread_ticks_override=*/nullptr); + + CreateCalendarView(); + // Mock events will be in the `next_month` so when the calendar opens we don't + // record the metric. + MockEventsFetched( + calendar_utils::GetStartOfMonthUTC(next_month), + CreateMockEventListWithEventStartTimeMoreThanTwoHoursAway()); + + // Make sure we're on the current month and no events have been displayed to + // the user. + EXPECT_EQ(u"October", GetCurrentLabelText()); + EXPECT_EQ(u"October", month_header()->GetText()); + EXPECT_EQ(u"2021", header_year()->GetText()); + histogram_tester.ExpectTotalCount("Ash.Calendar.EventsDisplayedToUser", 0); + + // Scroll down a month, this month should contain events. + ScrollDownOneMonth(); + + EXPECT_EQ(u"November", GetCurrentLabelText()); + EXPECT_EQ(u"November", month_header()->GetText()); + EXPECT_EQ(u"2021", header_year()->GetText()); + histogram_tester.ExpectTotalCount("Ash.Calendar.EventsDisplayedToUser", 1); + + // Scroll back and forward to land on the month containing events again. + ScrollDownOneMonth(); + ScrollUpOneMonth(); + + // We should still have only logged the metric once. + histogram_tester.ExpectTotalCount("Ash.Calendar.EventsDisplayedToUser", 1); +} + } // namespace ash
diff --git a/ash/system/tray/tray_bubble_view.cc b/ash/system/tray/tray_bubble_view.cc index ca495d5..c88b0e3 100644 --- a/ash/system/tray/tray_bubble_view.cc +++ b/ash/system/tray/tray_bubble_view.cc
@@ -535,7 +535,10 @@ } SetBorder(std::make_unique<views::HighlightBorder>( - params_.corner_radius, views::HighlightBorder::Type::kHighlightBorder1, + params_.corner_radius, + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderOnShadow + : views::HighlightBorder::Type::kHighlightBorder1, /*use_light_colors=*/false)); set_color(GetColorProvider()->GetColor( chromeos::features::IsJellyEnabled()
diff --git a/ash/system/tray/tray_container.cc b/ash/system/tray/tray_container.cc index e538922..0da9ea7 100644 --- a/ash/system/tray/tray_container.cc +++ b/ash/system/tray/tray_container.cc
@@ -13,6 +13,7 @@ #include "ash/shell.h" #include "ash/system/tray/tray_background_view.h" #include "ash/system/tray/tray_constants.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/compositor/layer.h" #include "ui/gfx/geometry/insets.h" #include "ui/views/border.h" @@ -116,7 +117,10 @@ canvas, *this, gfx::Rect(gfx::PointAtOffsetFromOrigin(bounds_origin), background_bounds.size()), - rounded_corners, views::HighlightBorder::Type::kHighlightBorder2, + rounded_corners, + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderNoShadow + : views::HighlightBorder::Type::kHighlightBorder2, /*use_light_colors=*/false); }
diff --git a/ash/webui/eche_app_ui/apps_launch_info_provider.h b/ash/webui/eche_app_ui/apps_launch_info_provider.h index 5612cba..51f084a 100644 --- a/ash/webui/eche_app_ui/apps_launch_info_provider.h +++ b/ash/webui/eche_app_ui/apps_launch_info_provider.h
@@ -45,4 +45,4 @@ } // namespace eche_app } // namespace ash -#endif // ASH_WEBUI_ECHE_APP_UI_APPS_LAUNCH_INFO_PROVIDER_H_ \ No newline at end of file +#endif // ASH_WEBUI_ECHE_APP_UI_APPS_LAUNCH_INFO_PROVIDER_H_
diff --git a/ash/webui/eche_app_ui/eche_alert_generator_unittest.cc b/ash/webui/eche_app_ui/eche_alert_generator_unittest.cc index 3818b61..ae32b69 100644 --- a/ash/webui/eche_app_ui/eche_alert_generator_unittest.cc +++ b/ash/webui/eche_app_ui/eche_alert_generator_unittest.cc
@@ -5,6 +5,7 @@ #include "ash/webui/eche_app_ui/eche_alert_generator.h" #include "ash/constants/ash_pref_names.h" +#include "ash/webui/eche_app_ui/apps_launch_info_provider.h" #include "ash/webui/eche_app_ui/launch_app_helper.h" #include "chromeos/ash/components/phonehub/fake_phone_hub_manager.h" #include "components/prefs/pref_registry_simple.h" @@ -77,12 +78,14 @@ alert_generator_.reset(); } - void FakeLaunchEcheAppFunction(const absl::optional<int64_t>& notification_id, - const std::string& package_name, - const std::u16string& visible_name, - const absl::optional<int64_t>& user_id, - const gfx::Image& icon, - const std::u16string& phone_name) { + void FakeLaunchEcheAppFunction( + const absl::optional<int64_t>& notification_id, + const std::string& package_name, + const std::u16string& visible_name, + const absl::optional<int64_t>& user_id, + const gfx::Image& icon, + const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launch_info_provider) { // Do nothing. }
diff --git a/ash/webui/eche_app_ui/eche_app_manager.cc b/ash/webui/eche_app_ui/eche_app_manager.cc index 4f8b33e..6acb795 100644 --- a/ash/webui/eche_app_ui/eche_app_manager.cc +++ b/ash/webui/eche_app_ui/eche_app_manager.cc
@@ -71,7 +71,9 @@ apps_launch_info_provider_(std::make_unique<AppsLaunchInfoProvider>( eche_connection_status_handler_.get())), stream_status_change_handler_( - std::make_unique<EcheStreamStatusChangeHandler>()), + std::make_unique<EcheStreamStatusChangeHandler>( + apps_launch_info_provider_.get(), + eche_connection_status_handler_.get())), eche_notification_click_handler_( std::make_unique<EcheNotificationClickHandler>( phone_hub_manager, @@ -85,8 +87,10 @@ std::make_unique<EcheConnectorImpl>(feature_status_provider_.get(), connection_manager_.get(), connection_scheduler_.get())), - signaler_(std::make_unique<EcheSignaler>(eche_connector_.get(), - connection_manager_.get())), + signaler_( + std::make_unique<EcheSignaler>(eche_connector_.get(), + connection_manager_.get(), + apps_launch_info_provider_.get())), message_receiver_( std::make_unique<EcheMessageReceiverImpl>(connection_manager_.get())), eche_presence_manager_(std::make_unique<EchePresenceManager>(
diff --git a/ash/webui/eche_app_ui/eche_app_manager_unittest.cc b/ash/webui/eche_app_ui/eche_app_manager_unittest.cc index 4655649..4180ac2 100644 --- a/ash/webui/eche_app_ui/eche_app_manager_unittest.cc +++ b/ash/webui/eche_app_ui/eche_app_manager_unittest.cc
@@ -35,12 +35,14 @@ namespace { -void LaunchEcheAppFunction(const absl::optional<int64_t>& notification_id, - const std::string& package_name, - const std::u16string& visible_name, - const absl::optional<int64_t>& user_id, - const gfx::Image& icon, - const std::u16string& phone_name) {} +void LaunchEcheAppFunction( + const absl::optional<int64_t>& notification_id, + const std::string& package_name, + const std::u16string& visible_name, + const absl::optional<int64_t>& user_id, + const gfx::Image& icon, + const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launcher_info_provider) {} void LaunchNotificationFunction( const absl::optional<std::u16string>& title,
diff --git a/ash/webui/eche_app_ui/eche_connection_status_handler.cc b/ash/webui/eche_app_ui/eche_connection_status_handler.cc index c266690..9f03622 100644 --- a/ash/webui/eche_app_ui/eche_connection_status_handler.cc +++ b/ash/webui/eche_app_ui/eche_connection_status_handler.cc
@@ -20,7 +20,7 @@ mojom::ConnectionStatus connection_status) {} void EcheConnectionStatusHandler::Observer:: OnRequestBackgroundConnectionAttempt() {} -void EcheConnectionStatusHandler::Observer::OnPhoneHubDisconnected() {} +void EcheConnectionStatusHandler::Observer::OnRequestCloseConnnection() {} void EcheConnectionStatusHandler::OnConnectionStatusChanged( mojom::ConnectionStatus connection_status) { @@ -49,6 +49,7 @@ void EcheConnectionStatusHandler::OnFeatureStatusChanged( FeatureStatus feature_status) { + PA_LOG(INFO) << __func__ << ": " << feature_status; feature_status_ = feature_status; switch (feature_status) { case FeatureStatus::kIneligible: @@ -83,6 +84,7 @@ void EcheConnectionStatusHandler::SetConnectionStatusForUi( mojom::ConnectionStatus connection_status) { + PA_LOG(INFO) << __func__ << ": " << connection_status; last_update_timestamp_ = base::Time::Now(); if (connection_status_for_ui_ == connection_status) { return; @@ -106,10 +108,14 @@ base::Time::Now() - last_update_timestamp_; if (time_since_last_check > features::kEcheBackgroundConnectionAttemptThrottleTimeout.Get()) { + PA_LOG(INFO) << __func__ << ": Requesting background connection attempt"; NotifyRequestBackgroundConnectionAttempt(); } if (time_since_last_check > - features::kEcheConnectionStatusResetTimeout.Get()) { + features::kEcheConnectionStatusResetTimeout.Get() && + connection_status_for_ui_ == + mojom::ConnectionStatus::kConnectionStatusConnected) { + PA_LOG(INFO) << __func__ << ": blocking ui"; connection_status_for_ui_ = mojom::ConnectionStatus::kConnectionStatusConnecting; } @@ -136,6 +142,12 @@ } } +void EcheConnectionStatusHandler::NotifyRequestCloseConnection() { + for (auto& observer : observer_list_) { + observer.OnRequestCloseConnnection(); + } +} + void EcheConnectionStatusHandler::NotifyRequestBackgroundConnectionAttempt() { for (auto& observer : observer_list_) { observer.OnRequestBackgroundConnectionAttempt();
diff --git a/ash/webui/eche_app_ui/eche_connection_status_handler.h b/ash/webui/eche_app_ui/eche_connection_status_handler.h index b6293a8b..419f3d9 100644 --- a/ash/webui/eche_app_ui/eche_connection_status_handler.h +++ b/ash/webui/eche_app_ui/eche_connection_status_handler.h
@@ -33,7 +33,7 @@ virtual void OnRequestBackgroundConnectionAttempt(); - virtual void OnPhoneHubDisconnected(); + virtual void OnRequestCloseConnnection(); }; EcheConnectionStatusHandler(); @@ -61,6 +61,9 @@ // EcheFeatureStatusProvider::Observer: void OnFeatureStatusChanged(FeatureStatus feature_status); + // Proxy to request that the webui shut down the connection. + void NotifyRequestCloseConnection(); + void Bind(mojo::PendingReceiver<mojom::ConnectionStatusObserver> receiver); private:
diff --git a/ash/webui/eche_app_ui/eche_connection_status_handler_unittest.cc b/ash/webui/eche_app_ui/eche_connection_status_handler_unittest.cc index 9f2450e5..d65f843 100644 --- a/ash/webui/eche_app_ui/eche_connection_status_handler_unittest.cc +++ b/ash/webui/eche_app_ui/eche_connection_status_handler_unittest.cc
@@ -30,8 +30,8 @@ return num_request_background_connection_attempt_calls_; } - size_t num_phone_hub_disconnected_calls() const { - return num_phone_hub_disconnected_calls_; + size_t num_request_close_connection_calls() const { + return num_request_close_connection_calls_; } mojom::ConnectionStatus last_connection_changed_status() const { @@ -59,15 +59,15 @@ ++num_request_background_connection_attempt_calls_; } - void OnPhoneHubDisconnected() override { - ++num_phone_hub_disconnected_calls_; + void OnRequestCloseConnnection() override { + ++num_request_close_connection_calls_; } private: size_t num_connection_status_changed_calls_ = 0; size_t num_connection_status_for_ui_changed_calls_ = 0; size_t num_request_background_connection_attempt_calls_ = 0; - size_t num_phone_hub_disconnected_calls_ = 0; + size_t num_request_close_connection_calls_ = 0; mojom::ConnectionStatus last_connection_changed_status_ = mojom::ConnectionStatus::kConnectionStatusDisconnected; mojom::ConnectionStatus last_connection_for_ui_changed_status_ = @@ -124,8 +124,8 @@ return fake_observer_.num_request_background_connection_attempt_calls(); } - size_t GetNumPhoneHubDisconnectedCalls() const { - return fake_observer_.num_phone_hub_disconnected_calls(); + size_t GetNumRequestCloceConnectionCalls() const { + return fake_observer_.num_request_close_connection_calls(); } mojom::ConnectionStatus GetLastConnectionChangedStatus() const { @@ -229,6 +229,7 @@ EXPECT_EQ(GetLastConnectionForUiChangedStatus(), mojom::ConnectionStatus::kConnectionStatusDisconnected); EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 0u); + EXPECT_EQ(GetNumConnectionStatusChangedCalls(), 1u); handler().CheckConnectionStatusForUi(); @@ -236,15 +237,21 @@ mojom::ConnectionStatus::kConnectionStatusDisconnected); EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 0u); + NotifyConnectionStatusChanged( + mojom::ConnectionStatus::kConnectionStatusConnected); + EXPECT_EQ(GetLastConnectionForUiChangedStatus(), + mojom::ConnectionStatus::kConnectionStatusConnected); + EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 1u); + SetFeatureStatus(FeatureStatus::kConnected); handler().CheckConnectionStatusForUi(); EXPECT_EQ(GetLastConnectionChangedStatus(), - mojom::ConnectionStatus::kConnectionStatusConnecting); - EXPECT_EQ(GetNumConnectionStatusChangedCalls(), 1u); + mojom::ConnectionStatus::kConnectionStatusConnected); + EXPECT_EQ(GetNumConnectionStatusChangedCalls(), 2u); EXPECT_EQ(GetLastConnectionForUiChangedStatus(), - mojom::ConnectionStatus::kConnectionStatusConnecting); - EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 1u); + mojom::ConnectionStatus::kConnectionStatusConnected); + EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 2u); } TEST_F(EcheConnectionStatusHandlerTest, @@ -257,32 +264,42 @@ EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 0u); EXPECT_EQ(GetNumRequestBackgroundConnectionAttemptCalls(), 0u); + NotifyConnectionStatusChanged( + mojom::ConnectionStatus::kConnectionStatusConnected); + EXPECT_EQ(GetLastConnectionForUiChangedStatus(), + mojom::ConnectionStatus::kConnectionStatusConnected); + EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 1u); + // After more than 10 seconds pass, extra calls should happen. SetFeatureStatus(FeatureStatus::kConnected); task_environment_.FastForwardBy(base::Seconds(11)); handler().CheckConnectionStatusForUi(); EXPECT_EQ(GetLastConnectionForUiChangedStatus(), - mojom::ConnectionStatus::kConnectionStatusConnecting); - EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 1u); + mojom::ConnectionStatus::kConnectionStatusConnected); + EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 2u); EXPECT_EQ(GetNumRequestBackgroundConnectionAttemptCalls(), 1u); // Reset to Disconnected handler().SetConnectionStatusForUi( mojom::ConnectionStatus::kConnectionStatusDisconnected); - EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 2u); + EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 3u); EXPECT_EQ(GetNumRequestBackgroundConnectionAttemptCalls(), 1u); EXPECT_EQ(GetLastConnectionForUiChangedStatus(), mojom::ConnectionStatus::kConnectionStatusDisconnected); // After more than 10 minutes pass, state should go back to Connecting. + handler().SetConnectionStatusForUi( + mojom::ConnectionStatus::kConnectionStatusConnected); + EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 4u); + task_environment_.FastForwardBy(base::Minutes(11)); handler().CheckConnectionStatusForUi(); EXPECT_EQ(GetLastConnectionForUiChangedStatus(), mojom::ConnectionStatus::kConnectionStatusConnecting); - EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 3u); + EXPECT_EQ(GetNumConnectionStatusForUiChangedCalls(), 5u); EXPECT_EQ(GetNumRequestBackgroundConnectionAttemptCalls(), 2u); }
diff --git a/ash/webui/eche_app_ui/eche_feature_status_provider.cc b/ash/webui/eche_app_ui/eche_feature_status_provider.cc index e27257f..195e1d1 100644 --- a/ash/webui/eche_app_ui/eche_feature_status_provider.cc +++ b/ash/webui/eche_app_ui/eche_feature_status_provider.cc
@@ -4,6 +4,7 @@ #include "ash/webui/eche_app_ui/eche_feature_status_provider.h" +#include "ash/constants/ash_features.h" #include "chromeos/ash/components/multidevice/logging/logging.h" #include "chromeos/ash/components/multidevice/remote_device_ref.h" #include "chromeos/ash/components/multidevice/software_feature.h" @@ -130,8 +131,10 @@ *status_ = computed_status; NotifyStatusChanged(); - // TODO(b/274530047): refactor to make this a normal observer. - eche_connection_status_handler_->OnFeatureStatusChanged(computed_status); + if (features::IsEcheNetworkConnectionStateEnabled()) { + // TODO(b/274530047): refactor to make this a normal observer. + eche_connection_status_handler_->OnFeatureStatusChanged(computed_status); + } } FeatureStatus EcheFeatureStatusProvider::ComputeStatus() {
diff --git a/ash/webui/eche_app_ui/eche_notification_click_handler.cc b/ash/webui/eche_app_ui/eche_notification_click_handler.cc index a95bbbc..abac5854 100644 --- a/ash/webui/eche_app_ui/eche_notification_click_handler.cc +++ b/ash/webui/eche_app_ui/eche_notification_click_handler.cc
@@ -58,7 +58,8 @@ notification_id, app_metadata.package_name, app_metadata.visible_app_name, app_metadata.user_id, app_metadata.icon, - phone_model_->phone_name().value_or(std::u16string())); + phone_model_->phone_name().value_or(std::u16string()), + apps_launch_info_provider_); break; case LaunchAppHelper::AppLaunchProhibitedReason::kDisabledByScreenLock: launch_app_helper_->ShowNotification(
diff --git a/ash/webui/eche_app_ui/eche_notification_click_handler_unittest.cc b/ash/webui/eche_app_ui/eche_notification_click_handler_unittest.cc index 5ee9ee584..ff46b5d 100644 --- a/ash/webui/eche_app_ui/eche_notification_click_handler_unittest.cc +++ b/ash/webui/eche_app_ui/eche_notification_click_handler_unittest.cc
@@ -4,6 +4,7 @@ #include "ash/webui/eche_app_ui/eche_notification_click_handler.h" +#include <memory> #include <string> #include "ash/constants/ash_features.h" @@ -68,12 +69,14 @@ handler_.reset(); } - void FakeLaunchEcheAppFunction(const absl::optional<int64_t>& notification_id, - const std::string& package_name, - const std::u16string& visible_name, - const absl::optional<int64_t>& user_id, - const gfx::Image& icon, - const std::u16string& phone_name) { + void FakeLaunchEcheAppFunction( + const absl::optional<int64_t>& notification_id, + const std::string& package_name, + const std::u16string& visible_name, + const absl::optional<int64_t>& user_id, + const gfx::Image& icon, + const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launch_info_provider) { num_app_launch_++; }
diff --git a/ash/webui/eche_app_ui/eche_recent_app_click_handler.cc b/ash/webui/eche_app_ui/eche_recent_app_click_handler.cc index 6ee72051..2cf87742 100644 --- a/ash/webui/eche_app_ui/eche_recent_app_click_handler.cc +++ b/ash/webui/eche_app_ui/eche_recent_app_click_handler.cc
@@ -93,7 +93,8 @@ app_metadata.visible_app_name, app_metadata.user_id, app_metadata.icon, phone_hub_manager_->GetPhoneModel()->phone_name().value_or( - std::u16string())); + std::u16string()), + apps_launch_info_provider_); break; case LaunchAppHelper::AppLaunchProhibitedReason::kDisabledByScreenLock: launch_app_helper_->ShowNotification(
diff --git a/ash/webui/eche_app_ui/eche_recent_app_click_handler_unittest.cc b/ash/webui/eche_app_ui/eche_recent_app_click_handler_unittest.cc index 3407f3f..072c08e 100644 --- a/ash/webui/eche_app_ui/eche_recent_app_click_handler_unittest.cc +++ b/ash/webui/eche_app_ui/eche_recent_app_click_handler_unittest.cc
@@ -58,7 +58,8 @@ apps_launch_info_provider_ = std::make_unique<AppsLaunchInfoProvider>( connection_status_handler_.get()); stream_status_change_handler_ = - std::make_unique<EcheStreamStatusChangeHandler>(); + std::make_unique<EcheStreamStatusChangeHandler>( + apps_launch_info_provider_.get(), connection_status_handler_.get()); handler_ = std::make_unique<EcheRecentAppClickHandler>( &fake_phone_hub_manager_, &fake_feature_status_provider_, launch_app_helper_.get(), stream_status_change_handler_.get(), @@ -73,12 +74,14 @@ stream_status_change_handler_.reset(); } - void FakeLaunchEcheAppFunction(const absl::optional<int64_t>& notification_id, - const std::string& package_name, - const std::u16string& visible_name, - const absl::optional<int64_t>& user_id, - const gfx::Image& icon, - const std::u16string& phone_name) { + void FakeLaunchEcheAppFunction( + const absl::optional<int64_t>& notification_id, + const std::string& package_name, + const std::u16string& visible_name, + const absl::optional<int64_t>& user_id, + const gfx::Image& icon, + const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launch_info_provider) { package_name_ = package_name; visible_name_ = visible_name; user_id_ = user_id.value();
diff --git a/ash/webui/eche_app_ui/eche_signaler.cc b/ash/webui/eche_app_ui/eche_signaler.cc index 352c0b6..4f4add83 100644 --- a/ash/webui/eche_app_ui/eche_signaler.cc +++ b/ash/webui/eche_app_ui/eche_signaler.cc
@@ -5,7 +5,11 @@ #include "ash/webui/eche_app_ui/eche_signaler.h" #include "ash/constants/ash_features.h" +#include "ash/root_window_controller.h" +#include "ash/shell.h" #include "ash/system/eche/eche_tray.h" +#include "ash/webui/eche_app_ui/apps_launch_info_provider.h" +#include "ash/webui/eche_app_ui/mojom/eche_app.mojom-shared.h" #include "ash/webui/eche_app_ui/proto/exo_messages.pb.h" #include "ash/webui/eche_app_ui/system_info_provider.h" #include "base/metrics/histogram_functions.h" @@ -22,14 +26,23 @@ // From google3: typescript/webrtc/webrtc_peer_connection.ts constexpr base::TimeDelta kSignalingTimeoutDuration = base::Milliseconds(10000); +EcheTray* GetEcheTray() { + return Shell::GetPrimaryRootWindowController() + ->GetStatusAreaWidget() + ->eche_tray(); +} + } // namespace namespace eche_app { EcheSignaler::EcheSignaler( EcheConnector* eche_connector, - secure_channel::ConnectionManager* connection_manager) - : eche_connector_(eche_connector), connection_manager_(connection_manager) { + secure_channel::ConnectionManager* connection_manager, + AppsLaunchInfoProvider* apps_launch_info_provider) + : eche_connector_(eche_connector), + apps_launch_info_provider_(apps_launch_info_provider), + connection_manager_(connection_manager) { connection_manager_->AddObserver(this); } @@ -167,8 +180,28 @@ PA_LOG(INFO) << "echeapi EcheSignaler timeout: " << probably_connection_failed_reason_; - base::UmaHistogramEnumeration("Eche.StreamEvent.ConnectionFail", - probably_connection_failed_reason_); + if (!features::IsEcheNetworkConnectionStateEnabled()) { + base::UmaHistogramEnumeration("Eche.StreamEvent.ConnectionFail", + probably_connection_failed_reason_); + return; + } + + EcheTray* eche_tray = GetEcheTray(); + if (eche_tray && eche_tray->IsBackgroundConnectionAttemptInProgress()) { + base::UmaHistogramEnumeration("Eche.NetworkCheck.FailureReason", + probably_connection_failed_reason_); + } else if (apps_launch_info_provider_->GetConnectionStatusForUi() == + mojom::ConnectionStatus::kConnectionStatusFailed && + apps_launch_info_provider_->entry_point() == + mojom::AppStreamLaunchEntryPoint::NOTIFICATION) { + base::UmaHistogramEnumeration( + "Eche.StreamEvent.FromNotification.PreviousNetworkCheckFailed." + "ConnectionFail", + probably_connection_failed_reason_); + } else { + base::UmaHistogramEnumeration("Eche.StreamEvent.ConnectionFail", + probably_connection_failed_reason_); + } } std::ostream& operator<<(
diff --git a/ash/webui/eche_app_ui/eche_signaler.h b/ash/webui/eche_app_ui/eche_signaler.h index 95bec2a..4023ef91 100644 --- a/ash/webui/eche_app_ui/eche_signaler.h +++ b/ash/webui/eche_app_ui/eche_signaler.h
@@ -6,6 +6,7 @@ #define ASH_WEBUI_ECHE_APP_UI_ECHE_SIGNALER_H_ #include "ash/system/eche/eche_tray.h" +#include "ash/webui/eche_app_ui/apps_launch_info_provider.h" #include "ash/webui/eche_app_ui/eche_connector.h" #include "ash/webui/eche_app_ui/mojom/eche_app.mojom.h" #include "ash/webui/eche_app_ui/system_info_provider.h" @@ -25,7 +26,8 @@ public secure_channel::ConnectionManager::Observer { public: EcheSignaler(EcheConnector* eche_connector, - secure_channel::ConnectionManager* connection_manager); + secure_channel::ConnectionManager* connection_manager, + AppsLaunchInfoProvider* apps_launch_info_provider); ~EcheSignaler() override; EcheSignaler(const EcheSignaler&) = delete; @@ -72,6 +74,7 @@ SystemInfoProvider* system_info_provider_ = nullptr; EcheConnector* eche_connector_ = nullptr; + AppsLaunchInfoProvider* apps_launch_info_provider_ = nullptr; secure_channel::ConnectionManager* connection_manager_ = nullptr; mojo::Remote<mojom::SignalingMessageObserver> observer_; mojo::Receiver<mojom::SignalingMessageExchanger> exchanger_{this};
diff --git a/ash/webui/eche_app_ui/eche_signaler_unittest.cc b/ash/webui/eche_app_ui/eche_signaler_unittest.cc index 9c881061..ec985d0 100644 --- a/ash/webui/eche_app_ui/eche_signaler_unittest.cc +++ b/ash/webui/eche_app_ui/eche_signaler_unittest.cc
@@ -10,6 +10,8 @@ #include "ash/constants/ash_features.h" #include "ash/system/eche/eche_tray.h" #include "ash/test/ash_test_base.h" +#include "ash/webui/eche_app_ui/apps_launch_info_provider.h" +#include "ash/webui/eche_app_ui/eche_connection_status_handler.h" #include "ash/webui/eche_app_ui/proto/exo_messages.pb.h" #include "ash/webui/eche_app_ui/system_info.h" #include "ash/webui/eche_app_ui/system_info_provider.h" @@ -165,8 +167,13 @@ // testing::Test: void SetUp() override { - signaler_ = std::make_unique<EcheSignaler>(&fake_connector_, - &fake_connection_manager_); + connection_status_handler_ = + std::make_unique<eche_app::EcheConnectionStatusHandler>(); + apps_launch_info_provider_ = std::make_unique<AppsLaunchInfoProvider>( + connection_status_handler_.get()); + signaler_ = std::make_unique<EcheSignaler>( + &fake_connector_, &fake_connection_manager_, + apps_launch_info_provider_.get()); } std::vector<uint8_t> getSignal(std::string data) { @@ -215,7 +222,8 @@ TaskRunner task_runner_; FakeEcheConnector fake_connector_{&task_runner_}; secure_channel::FakeConnectionManager fake_connection_manager_; - + std::unique_ptr<EcheConnectionStatusHandler> connection_status_handler_; + std::unique_ptr<AppsLaunchInfoProvider> apps_launch_info_provider_; std::unique_ptr<EcheSignaler> signaler_; base::test::ScopedFeatureList feature_list_; };
diff --git a/ash/webui/eche_app_ui/eche_stream_status_change_handler.cc b/ash/webui/eche_app_ui/eche_stream_status_change_handler.cc index 691679c..b6b2b04 100644 --- a/ash/webui/eche_app_ui/eche_stream_status_change_handler.cc +++ b/ash/webui/eche_app_ui/eche_stream_status_change_handler.cc
@@ -5,16 +5,26 @@ #include "ash/webui/eche_app_ui/eche_stream_status_change_handler.h" #include "ash/constants/ash_features.h" +#include "ash/webui/eche_app_ui/apps_launch_info_provider.h" #include "ash/webui/eche_app_ui/launch_app_helper.h" +#include "ash/webui/eche_app_ui/mojom/eche_app.mojom-shared.h" #include "base/metrics/histogram_functions.h" #include "chromeos/ash/components/multidevice/logging/logging.h" namespace ash { namespace eche_app { -EcheStreamStatusChangeHandler::EcheStreamStatusChangeHandler() = default; +EcheStreamStatusChangeHandler::EcheStreamStatusChangeHandler( + AppsLaunchInfoProvider* apps_launch_info_provider, + EcheConnectionStatusHandler* eche_connection_status_handler) + : apps_launch_info_provider_(apps_launch_info_provider), + eche_connection_status_handler_(eche_connection_status_handler) { + eche_connection_status_handler_->AddObserver(this); +} -EcheStreamStatusChangeHandler::~EcheStreamStatusChangeHandler() = default; +EcheStreamStatusChangeHandler::~EcheStreamStatusChangeHandler() { + eche_connection_status_handler_->RemoveObserver(this); +} void EcheStreamStatusChangeHandler::StartStreaming() { PA_LOG(INFO) << "echeapi EcheStreamStatusChangeHandler StartStreaming"; @@ -28,8 +38,18 @@ NotifyStreamStatusChanged(status); if (status == mojom::StreamStatus::kStreamStatusStarted) { - base::UmaHistogramEnumeration("Eche.StreamEvent", - mojom::StreamStatus::kStreamStatusStarted); + if (features::IsEcheNetworkConnectionStateEnabled() && + apps_launch_info_provider_->GetConnectionStatusForUi() == + mojom::ConnectionStatus::kConnectionStatusFailed && + apps_launch_info_provider_->entry_point() == + mojom::AppStreamLaunchEntryPoint::NOTIFICATION) { + base::UmaHistogramEnumeration( + "Eche.StreamEvent.FromNotification.PreviousNetworkCheckFailed.Result", + mojom::StreamStatus::kStreamStatusStarted); + } else { + base::UmaHistogramEnumeration("Eche.StreamEvent", + mojom::StreamStatus::kStreamStatusStarted); + } } } @@ -40,6 +60,10 @@ observer_remote_.Bind(std::move(observer)); } +void EcheStreamStatusChangeHandler::OnRequestCloseConnnection() { + CloseStream(); +} + void EcheStreamStatusChangeHandler::AddObserver(Observer* observer) { observer_list_.AddObserver(observer); }
diff --git a/ash/webui/eche_app_ui/eche_stream_status_change_handler.h b/ash/webui/eche_app_ui/eche_stream_status_change_handler.h index 9eb963bd7..830fffb 100644 --- a/ash/webui/eche_app_ui/eche_stream_status_change_handler.h +++ b/ash/webui/eche_app_ui/eche_stream_status_change_handler.h
@@ -5,6 +5,7 @@ #ifndef ASH_WEBUI_ECHE_APP_UI_ECHE_STREAM_STATUS_CHANGE_HANDLER_H_ #define ASH_WEBUI_ECHE_APP_UI_ECHE_STREAM_STATUS_CHANGE_HANDLER_H_ +#include "ash/webui/eche_app_ui/eche_connection_status_handler.h" #include "ash/webui/eche_app_ui/mojom/eche_app.mojom.h" #include "base/observer_list.h" #include "base/observer_list_types.h" @@ -15,11 +16,15 @@ namespace ash { namespace eche_app { +class AppsLaunchInfoProvider; + // Implements the DisplayStreamHandler interface to allow the WebUI to sync the // status of the video streaming for Eche, e.g. When the video streaming is // started in the Eche Web, we can register `Observer` and get this status via // `OnStartStreaming` and `OnStreamStatusChanged` event. -class EcheStreamStatusChangeHandler : public mojom::DisplayStreamHandler { +class EcheStreamStatusChangeHandler + : public mojom::DisplayStreamHandler, + public EcheConnectionStatusHandler::Observer { public: class Observer : public base::CheckedObserver { public: @@ -29,7 +34,9 @@ virtual void OnStreamStatusChanged(mojom::StreamStatus status) = 0; }; - EcheStreamStatusChangeHandler(); + EcheStreamStatusChangeHandler( + AppsLaunchInfoProvider* apps_launch_info_provider, + EcheConnectionStatusHandler* eche_connection_status_handler); ~EcheStreamStatusChangeHandler() override; EcheStreamStatusChangeHandler(const EcheStreamStatusChangeHandler&) = delete; @@ -42,6 +49,9 @@ void SetStreamActionObserver( mojo::PendingRemote<mojom::StreamActionObserver> observer) override; + // EcheConnectionStatusHandler::Observer: + void OnRequestCloseConnnection() override; + void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); @@ -55,6 +65,8 @@ void NotifyStreamStatusChanged(mojom::StreamStatus status); private: + AppsLaunchInfoProvider* apps_launch_info_provider_; + EcheConnectionStatusHandler* eche_connection_status_handler_; mojo::Receiver<mojom::DisplayStreamHandler> display_stream_receiver_{this}; mojo::Remote<mojom::StreamActionObserver> observer_remote_; base::ObserverList<Observer> observer_list_;
diff --git a/ash/webui/eche_app_ui/eche_stream_status_change_handler_unittest.cc b/ash/webui/eche_app_ui/eche_stream_status_change_handler_unittest.cc index 1e93232..923b761 100644 --- a/ash/webui/eche_app_ui/eche_stream_status_change_handler_unittest.cc +++ b/ash/webui/eche_app_ui/eche_stream_status_change_handler_unittest.cc
@@ -3,7 +3,10 @@ // found in the LICENSE file. #include "ash/webui/eche_app_ui/eche_stream_status_change_handler.h" +#include <memory> +#include "ash/webui/eche_app_ui/apps_launch_info_provider.h" +#include "ash/webui/eche_app_ui/eche_connection_status_handler.h" #include "base/task/single_thread_task_runner.h" #include "base/test/task_environment.h" #include "testing/gtest/include/gtest/gtest.h" @@ -89,11 +92,18 @@ // testing::Test: void SetUp() override { - handler_ = std::make_unique<EcheStreamStatusChangeHandler>(); + connection_status_handler_ = + std::make_unique<eche_app::EcheConnectionStatusHandler>(); + apps_launch_info_provider_ = std::make_unique<AppsLaunchInfoProvider>( + connection_status_handler_.get()); + handler_ = std::make_unique<EcheStreamStatusChangeHandler>( + apps_launch_info_provider_.get(), connection_status_handler_.get()); handler_->AddObserver(&fake_observer_); } void TearDown() override { + apps_launch_info_provider_.reset(); + connection_status_handler_.reset(); handler_->RemoveObserver(&fake_observer_); handler_.reset(); } @@ -120,6 +130,9 @@ private: FakeObserver fake_observer_; + std::unique_ptr<eche_app::EcheConnectionStatusHandler> + connection_status_handler_; + std::unique_ptr<AppsLaunchInfoProvider> apps_launch_info_provider_; std::unique_ptr<EcheStreamStatusChangeHandler> handler_; };
diff --git a/ash/webui/eche_app_ui/eche_tray_stream_status_observer.cc b/ash/webui/eche_app_ui/eche_tray_stream_status_observer.cc index fcf699b..3fef5d0 100644 --- a/ash/webui/eche_app_ui/eche_tray_stream_status_observer.cc +++ b/ash/webui/eche_app_ui/eche_tray_stream_status_observer.cc
@@ -40,11 +40,14 @@ const gfx::Image& icon, const std::u16string& visible_name, const std::u16string& phone_name, + eche_app::mojom::ConnectionStatus last_connection_status, + eche_app::mojom::AppStreamLaunchEntryPoint entry_point, EcheTray::GracefulCloseCallback graceful_close_callback, EcheTray::GracefulGoBackCallback graceful_go_back_callback) { auto* eche_tray = ash::GetEcheTray(); DCHECK(eche_tray); - eche_tray->LoadBubble(url, icon, visible_name, phone_name); + eche_tray->LoadBubble(url, icon, visible_name, phone_name, + last_connection_status, entry_point); eche_tray->SetGracefulCloseCallback(std::move(graceful_close_callback)); eche_tray->SetGracefulGoBackCallback(std::move(graceful_go_back_callback)); }
diff --git a/ash/webui/eche_app_ui/eche_tray_stream_status_observer.h b/ash/webui/eche_app_ui/eche_tray_stream_status_observer.h index e0321d8..04f32ee 100644 --- a/ash/webui/eche_app_ui/eche_tray_stream_status_observer.h +++ b/ash/webui/eche_app_ui/eche_tray_stream_status_observer.h
@@ -8,6 +8,7 @@ #include "ash/system/eche/eche_tray.h" #include "ash/webui/eche_app_ui/eche_stream_status_change_handler.h" #include "ash/webui/eche_app_ui/feature_status_provider.h" +#include "ash/webui/eche_app_ui/mojom/eche_app.mojom-shared.h" #include "ash/webui/eche_app_ui/mojom/eche_app.mojom.h" #include "base/scoped_observation.h" #include "url/gurl.h" @@ -26,6 +27,8 @@ const gfx::Image& icon, const std::u16string& visible_name, const std::u16string& phone_name, + eche_app::mojom::ConnectionStatus last_connection_status, + eche_app::mojom::AppStreamLaunchEntryPoint entry_point, EcheTray::GracefulCloseCallback graceful_close_callback, EcheTray::GracefulGoBackCallback graceful_go_back_callback);
diff --git a/ash/webui/eche_app_ui/eche_tray_stream_status_observer_unittest.cc b/ash/webui/eche_app_ui/eche_tray_stream_status_observer_unittest.cc index 89c767e7..1e077df 100644 --- a/ash/webui/eche_app_ui/eche_tray_stream_status_observer_unittest.cc +++ b/ash/webui/eche_app_ui/eche_tray_stream_status_observer_unittest.cc
@@ -3,12 +3,15 @@ // found in the LICENSE file. #include "ash/webui/eche_app_ui/eche_tray_stream_status_observer.h" +#include <memory> #include "ash/constants/ash_features.h" #include "ash/system/eche/eche_tray.h" #include "ash/system/status_area_widget_test_helper.h" #include "ash/test/ash_test_base.h" #include "ash/test/test_ash_web_view_factory.h" +#include "ash/webui/eche_app_ui/apps_launch_info_provider.h" +#include "ash/webui/eche_app_ui/eche_connection_status_handler.h" #include "ash/webui/eche_app_ui/eche_stream_status_change_handler.h" #include "ash/webui/eche_app_ui/fake_feature_status_provider.h" #include "base/test/scoped_feature_list.h" @@ -59,15 +62,21 @@ AshTestBase::SetUp(); eche_tray_ = ash::StatusAreaWidgetTestHelper::GetStatusAreaWidget()->eche_tray(); - + connection_status_handler_ = + std::make_unique<EcheConnectionStatusHandler>(); + apps_launch_info_provider_ = std::make_unique<AppsLaunchInfoProvider>( + connection_status_handler_.get()); stream_status_change_handler_ = - std::make_unique<EcheStreamStatusChangeHandler>(); + std::make_unique<EcheStreamStatusChangeHandler>( + apps_launch_info_provider_.get(), connection_status_handler_.get()); observer_ = std::make_unique<EcheTrayStreamStatusObserver>( stream_status_change_handler_.get(), &fake_feature_status_provider_); } void TearDown() override { observer_.reset(); + apps_launch_info_provider_.reset(); + connection_status_handler_.reset(); stream_status_change_handler_.reset(); AshTestBase::TearDown(); } @@ -87,6 +96,8 @@ private: base::test::ScopedFeatureList scoped_feature_list_; EcheTray* eche_tray_ = nullptr; + std::unique_ptr<EcheConnectionStatusHandler> connection_status_handler_; + std::unique_ptr<AppsLaunchInfoProvider> apps_launch_info_provider_; std::unique_ptr<EcheStreamStatusChangeHandler> stream_status_change_handler_; std::unique_ptr<EcheTrayStreamStatusObserver> observer_; FakeFeatureStatusProvider fake_feature_status_provider_; @@ -97,6 +108,8 @@ TEST_F(EcheTrayStreamStatusObserverTest, LaunchBubble) { LaunchBubble(GURL("http://google.com"), gfx::Image(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST, base::BindOnce(&GracefulCloseFunction), base::BindRepeating(&GracefulGoBackFunction)); @@ -115,6 +128,8 @@ EXPECT_FALSE(eche_tray()->get_bubble_wrapper_for_test()); LaunchBubble(GURL("http://google.com"), gfx::Image(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST, base::BindOnce(&GracefulCloseFunction), base::BindRepeating(&GracefulGoBackFunction)); @@ -135,6 +150,8 @@ TEST_F(EcheTrayStreamStatusObserverTest, OnStreamStatusChanged) { LaunchBubble(GURL("http://google.com"), gfx::Image(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST, base::BindOnce(&GracefulCloseFunction), base::BindRepeating(&GracefulGoBackFunction)); OnStreamStatusChanged(mojom::StreamStatus::kStreamStatusStarted); @@ -157,6 +174,8 @@ ResetUnloadWebContent(); SetStatus(FeatureStatus::kConnecting); LaunchBubble(GURL("http://google.com"), gfx::Image(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST, base::BindOnce(&GracefulCloseFunction), base::BindRepeating(&GracefulGoBackFunction)); OnStreamStatusChanged(mojom::StreamStatus::kStreamStatusStarted); @@ -180,6 +199,8 @@ ResetUnloadWebContent(); SetStatus(FeatureStatus::kConnecting); LaunchBubble(GURL("http://google.com"), gfx::Image(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST, base::BindOnce(&GracefulCloseFunction), base::BindRepeating(&GracefulGoBackFunction)); OnStreamStatusChanged(mojom::StreamStatus::kStreamStatusStarted); @@ -203,6 +224,8 @@ ResetUnloadWebContent(); SetStatus(FeatureStatus::kConnecting); LaunchBubble(GURL("http://google.com"), gfx::Image(), u"app 1", u"your phone", + eche_app::mojom::ConnectionStatus::kConnectionStatusDisconnected, + eche_app::mojom::AppStreamLaunchEntryPoint::APPS_LIST, base::BindOnce(&GracefulCloseFunction), base::BindRepeating(&GracefulGoBackFunction)); OnStreamStatusChanged(mojom::StreamStatus::kStreamStatusStarted);
diff --git a/ash/webui/eche_app_ui/launch_app_helper.cc b/ash/webui/eche_app_ui/launch_app_helper.cc index e90b541..e0d8d6b 100644 --- a/ash/webui/eche_app_ui/launch_app_helper.cc +++ b/ash/webui/eche_app_ui/launch_app_helper.cc
@@ -9,6 +9,7 @@ #include "ash/public/cpp/system/toast_manager.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" +#include "ash/webui/eche_app_ui/apps_launch_info_provider.h" #include "ash/webui/eche_app_ui/eche_alert_generator.h" #include "base/check.h" #include "base/metrics/histogram_functions.h" @@ -92,14 +93,17 @@ kEcheAppToastId, ash::ToastCatalogName::kEcheAppToast, text)); } -void LaunchAppHelper::LaunchEcheApp(absl::optional<int64_t> notification_id, - const std::string& package_name, - const std::u16string& visible_name, - const absl::optional<int64_t>& user_id, - const gfx::Image& icon, - const std::u16string& phone_name) { +void LaunchAppHelper::LaunchEcheApp( + absl::optional<int64_t> notification_id, + const std::string& package_name, + const std::u16string& visible_name, + const absl::optional<int64_t>& user_id, + const gfx::Image& icon, + const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launch_info_provider) { launch_eche_app_function_.Run(notification_id, package_name, visible_name, - user_id, icon, phone_name); + user_id, icon, phone_name, + apps_launch_info_provider); // Sessions can last for well over a day, so this check exists to cover that // corner case and clears the |session_packages_launched_| set so we can
diff --git a/ash/webui/eche_app_ui/launch_app_helper.h b/ash/webui/eche_app_ui/launch_app_helper.h index 66a4100..2e6dab0 100644 --- a/ash/webui/eche_app_ui/launch_app_helper.h +++ b/ash/webui/eche_app_ui/launch_app_helper.h
@@ -25,6 +25,8 @@ namespace eche_app { +class AppsLaunchInfoProvider; + // A helper class for launching/closing the app or show a notification. class LaunchAppHelper { public: @@ -71,7 +73,8 @@ const std::u16string& visible_name, const absl::optional<int64_t>& user_id, const gfx::Image& icon, - const std::u16string& phone_name)>; + const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launch_info_provider)>; // Enum representing potential reasons why an app is forbidden to launch. enum class AppLaunchProhibitedReason { @@ -116,7 +119,8 @@ const std::u16string& visible_name, const absl::optional<int64_t>& user_id, const gfx::Image& icon, - const std::u16string& phone_name); + const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launch_info_provider); const base::flat_set<std::string> GetSessionPackagesLaunchedForTest() const { return session_packages_launched_;
diff --git a/ash/webui/eche_app_ui/launch_app_helper_unittest.cc b/ash/webui/eche_app_ui/launch_app_helper_unittest.cc index 3b7068d..5e8d8ca0 100644 --- a/ash/webui/eche_app_ui/launch_app_helper_unittest.cc +++ b/ash/webui/eche_app_ui/launch_app_helper_unittest.cc
@@ -4,6 +4,7 @@ #include "ash/webui/eche_app_ui/launch_app_helper.h" +#include <memory> #include <ostream> #include <string> @@ -11,6 +12,7 @@ #include "ash/shell.h" #include "ash/system/toast/toast_manager_impl.h" #include "ash/test/ash_test_base.h" +#include "ash/webui/eche_app_ui/apps_launch_info_provider.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" @@ -41,7 +43,8 @@ const std::u16string& visible_name, const absl::optional<int64_t>& user_id, const gfx::Image& icon, - const std::u16string& phone_name) { + const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launch_info_provider) { launchEcheApp_ = true; } @@ -88,6 +91,9 @@ /*disabled_features=*/{}); fake_phone_hub_manager_ = std::make_unique<phonehub::FakePhoneHubManager>(); + connection_handler_ = std::make_unique<EcheConnectionStatusHandler>(); + apps_launch_info_provider_ = + std::make_unique<AppsLaunchInfoProvider>(connection_handler_.get()); launch_app_helper_ = std::make_unique<LaunchAppHelper>( fake_phone_hub_manager_.get(), base::BindRepeating(&Callback::LaunchEcheAppFunction), @@ -125,7 +131,8 @@ const gfx::Image& icon, const std::u16string& phone_name) { launch_app_helper_->LaunchEcheApp(notification_id, package_name, - visible_name, user_id, icon, phone_name); + visible_name, user_id, icon, phone_name, + apps_launch_info_provider_.get()); } void ShowNotification( @@ -146,6 +153,8 @@ private: base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<phonehub::FakePhoneHubManager> fake_phone_hub_manager_; + std::unique_ptr<EcheConnectionStatusHandler> connection_handler_; + std::unique_ptr<AppsLaunchInfoProvider> apps_launch_info_provider_; std::unique_ptr<LaunchAppHelper> launch_app_helper_; ToastManagerImpl* toast_manager_ = nullptr; };
diff --git a/ash/wm/desks/templates/saved_desk_icon_view.cc b/ash/wm/desks/templates/saved_desk_icon_view.cc index 12ed1b5..c05026a2 100644 --- a/ash/wm/desks/templates/saved_desk_icon_view.cc +++ b/ash/wm/desks/templates/saved_desk_icon_view.cc
@@ -9,6 +9,7 @@ #include "ash/public/cpp/rounded_image_view.h" #include "ash/public/cpp/saved_desk_delegate.h" #include "ash/shell.h" +#include "ash/style/ash_color_provider.h" #include "base/check.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -262,7 +263,10 @@ ui::ResourceBundle::GetSharedInstance() .GetImageNamed(resource_id) .AsImageSkia(), - GetColorProvider()->GetColor(cros_tokens::kCrosSysOnSurface)), + // TODO(shidi): Replace the ash color provider with MaterialNext color + // provider. + AshColorProvider::Get()->GetContentLayerColor( + AshColorProvider::ContentLayerType::kIconColorPrimary)), /*is_default=*/true)); }
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index 98aaabe..0bf852b 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -363,6 +363,12 @@ // Don't try to write the final XML report in child processes. switches.erase(kGTestOutputFlag); +#if BUILDFLAG(IS_IOS) + // We only need the xctest flag for the parent process. Passing it to + // child processes will cause the tests not to run, so remove it. + switches.erase(switches::kEnableRunIOSUnittestsWithXCTest); +#endif + if (switches.find(switches::kTestLauncherRetriesLeft) == switches.end()) { switches[switches::kTestLauncherRetriesLeft] = #if BUILDFLAG(IS_WIN)
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn index 35c9a627..980b8896 100644 --- a/build/config/BUILD.gn +++ b/build/config/BUILD.gn
@@ -231,6 +231,9 @@ visibility = [ ":executable_deps", ":loadable_module_deps", + ":rust_bin_deps", + ":rust_cdylib_deps", + ":rust_dylib_deps", ":shared_library_deps", ] @@ -272,6 +275,15 @@ public_configs = [ "//build/config/sanitizers:link_executable" ] } +# Only the rust_bin template in BUILDCONFIG.gn should reference this. +group("rust_bin_deps") { + public_deps = [ ":common_deps" ] + if (export_libcxxabi_from_executables) { + public_deps += [ "//buildtools/third_party/libc++abi" ] + } + public_configs = [ "//build/config/sanitizers:link_executable" ] +} + # Only the loadable_module template in BUILDCONFIG.gn should reference this. group("loadable_module_deps") { public_deps = [ ":common_deps" ] @@ -286,6 +298,20 @@ public_configs = [ "//build/config/sanitizers:link_shared_library" ] } +# Only the rust_dylib template in BUILDCONFIG.gn should reference this. +group("rust_dylib_deps") { + public_deps = [ ":common_deps" ] + + public_configs = [ "//build/config/sanitizers:link_shared_library" ] +} + +# Only the rust_cdylib template in BUILDCONFIG.gn should reference this. +group("rust_cdylib_deps") { + public_deps = [ ":common_deps" ] + + public_configs = [ "//build/config/sanitizers:link_shared_library" ] +} + # Executable configs ----------------------------------------------------------- # Windows linker setup for EXEs and DLLs.
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index e4925e51..ca7debd 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn
@@ -514,6 +514,14 @@ "executable", "loadable_module", "shared_library", + + # TODO(crbug.com/1426886): When bindgen is not built in the Chromium + # build it will be safe to add rust_bin here. Right now it would make + # a conflict between the Chromium libc++ that this selects and the + # clang libraries that are shipped with the Rust toolchain. + # "rust_bin", + "rust_dylib", + "rust_cdylib", ]) { template(_target_type) { # Alias "target_name" because it is clobbered by forward_variables_from().
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 16ee982..d3adf97 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -2670,9 +2670,12 @@ if (is_android || (is_chromeos_ash && is_chromeos_device)) { # Use orderfile for linking Chrome on Android and Chrome OS. # This config enables using an orderfile for linking in LLD. - # TODO: Consider using call graph sort instead, at least on Android. config("chrome_orderfile_config") { - if (chrome_orderfile_path != "" && !enable_call_graph_profile_sort) { + # Don't try to use an orderfile with call graph sorting, except on Android, + # where we care about memory used by code, so we still want to mandate + # ordering. + if (chrome_orderfile_path != "" && + (is_android || !enable_call_graph_profile_sort)) { assert(use_lld) _rebased_orderfile = rebase_path(chrome_orderfile_path, root_build_dir) ldflags = [
diff --git a/build/fuchsia/test/OWNERS b/build/fuchsia/test/OWNERS index 97ae20ba..ea44fd1 100644 --- a/build/fuchsia/test/OWNERS +++ b/build/fuchsia/test/OWNERS
@@ -1,3 +1,2 @@ chonggu@google.com -grt@chromium.org -kmarshall@chromium.org \ No newline at end of file +zijiehe@google.com
diff --git a/build/fuchsia/test/common.py b/build/fuchsia/test/common.py index c8b9098..48531302 100644 --- a/build/fuchsia/test/common.py +++ b/build/fuchsia/test/common.py
@@ -14,7 +14,7 @@ import time from argparse import ArgumentParser -from typing import Iterable, List, Optional +from typing import Iterable, List, Optional, Tuple from compatible_utils import get_ssh_prefix, get_host_arch @@ -350,3 +350,25 @@ sys.exit(0) signal.signal(signal.SIGTERM, _sigterm_handler) + + +def get_system_info(target: Optional[str] = None) -> Tuple[str, str]: + """Retrieves installed OS version frm device. + + Returns: + Tuple of strings, containing {product, version number), or a pair of + empty strings to indicate an error. + """ + info_cmd = run_ffx_command(('target', 'show', '--json'), + target_id=target, + capture_output=True, + check=False) + if info_cmd.returncode == 0: + info_json = json.loads(info_cmd.stdout.strip()) + for info in info_json: + if info['title'] == 'Build': + return (info['child'][1]['value'], info['child'][0]['value']) + + # If the information was not retrieved, return empty strings to indicate + # unknown system info. + return ('', '')
diff --git a/build/fuchsia/test/ffx_emulator.py b/build/fuchsia/test/ffx_emulator.py index 9e0a3318..5d3991e 100644 --- a/build/fuchsia/test/ffx_emulator.py +++ b/build/fuchsia/test/ffx_emulator.py
@@ -13,9 +13,9 @@ from contextlib import AbstractContextManager -from common import check_ssh_config_file, run_ffx_command, \ - SDK_ROOT -from compatible_utils import get_host_arch +from common import check_ssh_config_file, find_image_in_sdk, get_system_info, \ + run_ffx_command, SDK_ROOT +from compatible_utils import get_host_arch, get_sdk_hash from ffx_integration import ScopedFfxConfig _EMU_COMMAND_RETRIES = 3 @@ -27,14 +27,23 @@ if args.product_bundle: self._product_bundle = args.product_bundle else: - target_cpu = get_host_arch() - self._product_bundle = f'terminal.qemu-{target_cpu}' + self._product_bundle = 'terminal.qemu-' + get_host_arch() self._enable_graphics = args.enable_graphics self._hardware_gpu = args.hardware_gpu self._logs_dir = args.logs_dir self._with_network = args.with_network - self._node_name = 'fuchsia-emulator-' + str(random.randint(1, 9999)) + if args.everlasting: + # Do not change the name, it will break the logic. + # ffx has a prefix-matching logic, so 'fuchsia-emulator' is not + # usable to avoid breaking local development workflow. I.e. + # developers can create an everlasting emulator and an ephemeral one + # without interfering each other. + self._node_name = 'fuchsia-everlasting-emulator' + assert self._everlasting() + else: + self._node_name = 'fuchsia-emulator-' + str(random.randint( + 1, 9999)) # Set the download path parallel to Fuchsia SDK directory # permanently so that scripts can always find the product bundles. @@ -45,19 +54,20 @@ 'sdk_override.txt') self._scoped_pb_metadata = None if os.path.exists(override_file): + assert not args.everlasting, \ + ('Do not use an everlasting emulator with the ' + 'sdk_override.txt, it will mass up the local configuration.') with open(override_file) as f: pb_metadata = f.read().split('\n') pb_metadata.append('{sdk.root}/*.json') self._scoped_pb_metadata = ScopedFfxConfig( 'pbms.metadata', json.dumps((pb_metadata))) - def __enter__(self) -> str: - """Start the emulator. + def _everlasting(self) -> bool: + return self._node_name == 'fuchsia-everlasting-emulator' - Returns: - The node name of the emulator. - """ - + def _start_emulator(self) -> None: + """Start the emulator.""" logging.info('Starting emulator %s', self._node_name) if self._scoped_pb_metadata: self._scoped_pb_metadata.__enter__() @@ -127,11 +137,9 @@ except (subprocess.TimeoutExpired, subprocess.CalledProcessError): run_ffx_command(('emu', 'stop')) - return self._node_name - def __exit__(self, exc_type, exc_value, traceback) -> bool: + def _shutdown_emulator(self, exc_type, exc_value, traceback) -> None: """Shutdown the emulator.""" - logging.info('Stopping the emulator %s', self._node_name) # The emulator might have shut down unexpectedly, so this command # might fail. @@ -140,5 +148,29 @@ if self._scoped_pb_metadata: self._scoped_pb_metadata.__exit__(exc_type, exc_value, traceback) + def __enter__(self) -> str: + """Start the emulator if necessary. + + Returns: + The node name of the emulator. + """ + + if self._everlasting(): + sdk_hash = get_sdk_hash(find_image_in_sdk(self._product_bundle)) + sys_info = get_system_info(self._node_name) + if sdk_hash == sys_info: + return self._node_name + logging.info( + ('The emulator version [%s] does not match the SDK [%s], ' + 'updating...'), sys_info, sdk_hash) + + self._start_emulator() + return self._node_name + + def __exit__(self, exc_type, exc_value, traceback) -> bool: + """Shutdown the emulator if necessary.""" + + if not self._everlasting(): + self._shutdown_emulator(exc_type, exc_value, traceback) # Do not suppress exceptions. return False
diff --git a/build/fuchsia/test/ffx_emulator_unittests.py b/build/fuchsia/test/ffx_emulator_unittests.py index 81f1f61..e12f13aa 100755 --- a/build/fuchsia/test/ffx_emulator_unittests.py +++ b/build/fuchsia/test/ffx_emulator_unittests.py
@@ -12,6 +12,22 @@ class FfxEmulatorTest(unittest.TestCase): """Unittests for ffx_emulator.py""" + def test_use_fixed_node_name(self) -> None: + """FfxEmulator should use a fixed node name.""" + # Allowing the test case to access FfxEmulator._node_name directly. + # pylint: disable=protected-access + self.assertEqual( + FfxEmulator( + argparse.Namespace( + **{ + 'product_bundle': None, + 'enable_graphics': False, + 'hardware_gpu': False, + 'logs_dir': '.', + 'with_network': False, + 'everlasting': True + }))._node_name, 'fuchsia-everlasting-emulator') + def test_use_random_node_name(self) -> None: """FfxEmulator should not use a fixed node name.""" # Allowing the test case to access FfxEmulator._node_name directly. @@ -24,7 +40,8 @@ 'enable_graphics': False, 'hardware_gpu': False, 'logs_dir': '.', - 'with_network': False + 'with_network': False, + 'everlasting': False }))._node_name, 'fuchsia-everlasting-emulator')
diff --git a/build/fuchsia/test/ffx_integration.py b/build/fuchsia/test/ffx_integration.py index 507479b..08cd6fa 100644 --- a/build/fuchsia/test/ffx_integration.py +++ b/build/fuchsia/test/ffx_integration.py
@@ -15,7 +15,6 @@ from common import run_continuous_ffx_command, run_ffx_command, SDK_ROOT -_EMU_COMMAND_RETRIES = 3 RUN_SUMMARY_SCHEMA = \ 'https://fuchsia.dev/schema/ffx_test/run_summary-8d1dd964.json'
diff --git a/build/fuchsia/test/flash_device.py b/build/fuchsia/test/flash_device.py index 8bf6420e2..8380ff6 100755 --- a/build/fuchsia/test/flash_device.py +++ b/build/fuchsia/test/flash_device.py
@@ -5,7 +5,6 @@ """Implements commands for flashing a Fuchsia device.""" import argparse -import json import logging import os import subprocess @@ -14,8 +13,9 @@ from typing import Optional, Tuple -from common import check_ssh_config_file, find_image_in_sdk, \ - register_device_args, run_ffx_command +import common +from common import check_ssh_config_file, get_system_info, find_image_in_sdk, \ + register_device_args from compatible_utils import get_sdk_hash, get_ssh_keys, pave, \ running_unattended, add_exec_to_file, get_host_arch from ffx_integration import ScopedFfxConfig @@ -39,26 +39,14 @@ # into zedboot. if running_unattended(): with ScopedFfxConfig('discovery.zedboot.enabled', 'true'): - run_ffx_command(('target', 'reboot'), target_id=target) - wait_cmd = run_ffx_command(('target', 'wait', '-t', '180'), - target, - check=False) + common.run_ffx_command(('target', 'reboot'), target_id=target) + wait_cmd = common.run_ffx_command(('target', 'wait', '-t', '180'), + target, + check=False) if wait_cmd.returncode != 0: return ('', '') - info_cmd = run_ffx_command(('target', 'show', '--json'), - target_id=target, - capture_output=True, - check=False) - if info_cmd.returncode == 0: - info_json = json.loads(info_cmd.stdout.strip()) - for info in info_json: - if info['title'] == 'Build': - return (info['child'][1]['value'], info['child'][0]['value']) - - # If the information was not retrieved, return empty strings to indicate - # unknown system info. - return ('', '') + return get_system_info(target) def update_required(os_check, system_image_dir: Optional[str], @@ -122,12 +110,12 @@ return manifest = os.path.join(system_image_dir, 'flash-manifest.manifest') - run_ffx_command(('target', 'flash', manifest, '--no-bootloader-reboot'), - target_id=target_id, - configs=[ - 'fastboot.usb.disabled=true', - 'ffx.fastboot.inline_target=true' - ]) + common.run_ffx_command( + ('target', 'flash', manifest, '--no-bootloader-reboot'), + target_id=target_id, + configs=[ + 'fastboot.usb.disabled=true', 'ffx.fastboot.inline_target=true' + ]) def _remove_stale_flash_file_lock() -> None: @@ -152,18 +140,18 @@ lock(_FF_LOCK, timeout=_FF_LOCK_ACQ_TIMEOUT): if serial_num: with ScopedFfxConfig('discovery.zedboot.enabled', 'true'): - run_ffx_command(('target', 'reboot', '-b'), - target, - check=False) + common.run_ffx_command(('target', 'reboot', '-b'), + target, + check=False) for _ in range(10): time.sleep(10) - if run_ffx_command(('target', 'list', serial_num), - check=False).returncode == 0: + if common.run_ffx_command(('target', 'list', serial_num), + check=False).returncode == 0: break _run_flash_command(system_image_dir, serial_num) else: _run_flash_command(system_image_dir, target) - run_ffx_command(('target', 'wait'), target) + common.run_ffx_command(('target', 'wait'), target) def update(system_image_dir: str, @@ -193,9 +181,9 @@ # TODO(crbug.com/1405525): We should check the device state # before and after rebooting it to avoid unnecessary reboot or # undesired state. - run_ffx_command(('target', 'reboot', '-r'), - target, - check=False) + common.run_ffx_command(('target', 'reboot', '-r'), + target, + check=False) try: pave(system_image_dir, target) time.sleep(180)
diff --git a/build/fuchsia/test/flash_device_unittests.py b/build/fuchsia/test/flash_device_unittests.py index 05fe878..d09a95db 100755 --- a/build/fuchsia/test/flash_device_unittests.py +++ b/build/fuchsia/test/flash_device_unittests.py
@@ -24,23 +24,23 @@ context_mock = mock.Mock() context_mock.__enter__ = mock.Mock(return_value=None) context_mock.__exit__ = mock.Mock(return_value=None) - self._config_patcher = mock.patch('flash_device.ScopedFfxConfig', - return_value=context_mock) + config_patcher = mock.patch('flash_device.ScopedFfxConfig', + return_value=context_mock) ffx_mock = mock.Mock() ffx_mock.returncode = 0 - self._ffx_patcher = mock.patch('flash_device.run_ffx_command', - return_value=ffx_mock) - self._sdk_hash_patcher = mock.patch('flash_device.get_sdk_hash', - return_value=(_TEST_PRODUCT, - _TEST_VERSION)) - self._swarming_patcher = mock.patch('flash_device.running_unattended', - return_value=False) - self._check_patcher = mock.patch('flash_device.check_ssh_config_file') - self._config_mock = self._config_patcher.start() - self._ffx_mock = self._ffx_patcher.start() - self._sdk_hash_mock = self._sdk_hash_patcher.start() - self._check_patcher_mock = self._check_patcher.start() - self._swarming_mock = self._swarming_patcher.start() + ffx_patcher = mock.patch('common.run_ffx_command', + return_value=ffx_mock) + sdk_hash_patcher = mock.patch('flash_device.get_sdk_hash', + return_value=(_TEST_PRODUCT, + _TEST_VERSION)) + swarming_patcher = mock.patch('flash_device.running_unattended', + return_value=False) + check_patcher = mock.patch('flash_device.check_ssh_config_file') + self._config_mock = config_patcher.start() + self._ffx_mock = ffx_patcher.start() + self._sdk_hash_mock = sdk_hash_patcher.start() + self._check_patcher_mock = check_patcher.start() + self._swarming_mock = swarming_patcher.start() self.addCleanup(self._config_mock.stop) self.addCleanup(self._ffx_mock.stop) self.addCleanup(self._sdk_hash_mock.stop)
diff --git a/build/fuchsia/test/start_emulator.py b/build/fuchsia/test/start_emulator.py index 897ea79..cd16505f 100755 --- a/build/fuchsia/test/start_emulator.py +++ b/build/fuchsia/test/start_emulator.py
@@ -9,6 +9,8 @@ import sys import time +from contextlib import AbstractContextManager + from common import catch_sigterm, register_log_args from ffx_emulator import FfxEmulator @@ -42,9 +44,13 @@ femu_args.add_argument('--with-network', action='store_true', help='Run emulator with emulated nic via tun/tap.') + femu_args.add_argument('--everlasting', + action='store_true', + help='If the emulator should be long-living.') -def create_emulator_from_args(args: argparse.Namespace) -> FfxEmulator: +def create_emulator_from_args( + args: argparse.Namespace) -> AbstractContextManager: """Helper method for initializing an FfxEmulator class with parsed arguments.""" return FfxEmulator(args)
diff --git a/build/rust/cargo_crate.gni b/build/rust/cargo_crate.gni index e3faa1f9..2ccfcadd 100644 --- a/build/rust/cargo_crate.gni +++ b/build/rust/cargo_crate.gni
@@ -99,32 +99,16 @@ _rustenv = invoker.rustenv } if (defined(invoker.cargo_pkg_authors)) { - _rustenv += [ string_join("=", - [ - "CARGO_PKG_AUTHORS", - invoker.cargo_pkg_authors, - ]) ] + _rustenv += [ "CARGO_PKG_AUTHORS=${invoker.cargo_pkg_authors}" ] } if (defined(invoker.cargo_pkg_version)) { - _rustenv += [ string_join("=", - [ - "CARGO_PKG_VERSION", - invoker.cargo_pkg_version, - ]) ] + _rustenv += [ "CARGO_PKG_VERSION=${invoker.cargo_pkg_version}" ] } if (defined(invoker.cargo_pkg_name)) { - _rustenv += [ string_join("=", - [ - "CARGO_PKG_NAME", - invoker.cargo_pkg_name, - ]) ] + _rustenv += [ "CARGO_PKG_NAME=${invoker.cargo_pkg_name}" ] } if (defined(invoker.cargo_pkg_description)) { - _rustenv += [ string_join("=", - [ - "CARGO_PKG_DESCRIPTION", - invoker.cargo_pkg_description, - ]) ] + _rustenv += [ "CARGO_PKG_DESCRIPTION=${invoker.cargo_pkg_description}" ] } # The main target, either a Rust source set or an executable.
diff --git a/build/rust/clanglibs/find_clanglibs.py b/build/rust/clanglibs/find_clanglibs.py index 8fd667a..8373b2c 100755 --- a/build/rust/clanglibs/find_clanglibs.py +++ b/build/rust/clanglibs/find_clanglibs.py
@@ -49,8 +49,12 @@ output.write("#[link(name=\"{}\")]\n".format(basename)) full_path = os.path.join(args.clang_libs_dir, f) depfile.write(" {} \\\n".format(full_path)) - output.write("#[link(name=\"stdc++\")]\n") - output.write("#[link(name=\"z\")]\n") + if sys.platform.startswith('linux'): + output.write("#[link(name=\"stdc++\")]\n") + else: + output.write("#[link(name=\"c++\")]\n") + if sys.platform.startswith('linux') or sys.platform == 'darwin': + output.write("#[link(name=\"z\")]\n") output.write("extern {}\n")
diff --git a/build/rust/rust_target.gni b/build/rust/rust_target.gni index 5561d0d7..7ded1fcc 100644 --- a/build/rust/rust_target.gni +++ b/build/rust/rust_target.gni
@@ -113,11 +113,7 @@ if (defined(invoker.edition)) { _edition = invoker.edition } - _configs = [ string_join("", - [ - "//build/rust:edition_", - _edition, - ]) ] + _configs = [ "//build/rust:edition_${_edition}" ] _test_configs = [] if (invoker.target_type == "executable") { if (defined(invoker.executable_configs)) { @@ -302,11 +298,7 @@ aliased_deps = _rust_aliased_deps public_deps = _rust_public_deps rustflags = _rustflags - rustflags += [ string_join("", - [ - "-Cmetadata=", - _metadata, - ]) ] + rustflags += [ "-Cmetadata=${_metadata}" ] rustenv = _rustenv # The Rust tool() declarations, like C++ ones, use the output_name and
diff --git a/build/rust/rust_unit_test.gni b/build/rust/rust_unit_test.gni index d263477..219914d 100644 --- a/build/rust/rust_unit_test.gni +++ b/build/rust/rust_unit_test.gni
@@ -63,11 +63,7 @@ if (defined(invoker.edition)) { _edition = invoker.edition } - _configs += [ string_join("", - [ - "//build/rust:edition_", - _edition, - ]) ] + _configs += [ "//build/rust:edition_${_edition}" ] # We require that all source files are listed, even though this is # not a requirement for rustc. The reason is to ensure that tools
diff --git a/build/rust/tests/BUILD.gn b/build/rust/tests/BUILD.gn index be9c6dd78..c0a8aa0 100644 --- a/build/rust/tests/BUILD.gn +++ b/build/rust/tests/BUILD.gn
@@ -66,6 +66,7 @@ "test_rust_exe:test_rust_exe_unittests", "test_rust_multiple_dep_versions_exe/v1:test_lib_v1_unittests", "test_rust_multiple_dep_versions_exe/v2:test_lib_v2_unittests", + "test_rust_shared_library:test_rust_shared_library_unittests", "test_rust_static_library:test_rust_static_library_unittests", "test_rust_static_library_non_standard_arrangement:foo_tests", "test_rust_unittests", @@ -84,16 +85,6 @@ if (enable_rust_bindgen) { deps += [ "bindgen_test:bindgen_test_lib_unittests" ] } - - # TODO(crbug.com/1297592): The bot isolate does not end up including any - # .so files so the tests fail: - # - # error while loading shared libraries: libtest_rust_shared_library.so: - # cannot open shared object file: No such file or directory - if (false) { - deps += - [ "test_rust_shared_library:test_rust_shared_library_unittests" ] - } } if (local_libstd_supported) {
diff --git a/buildtools/third_party/libc++abi/BUILD.gn b/buildtools/third_party/libc++abi/BUILD.gn index 4e1e334..3ab30c4 100644 --- a/buildtools/third_party/libc++abi/BUILD.gn +++ b/buildtools/third_party/libc++abi/BUILD.gn
@@ -6,7 +6,10 @@ source_set("libc++abi") { if (export_libcxxabi_from_executables) { - visibility = [ "//build/config:executable_deps" ] + visibility = [ + "//build/config:executable_deps", + "//build/config:rust_bin_deps", + ] } else { visibility = [ "//buildtools/third_party/libc++" ] }
diff --git a/cc/trees/frame_rate_estimator.cc b/cc/trees/frame_rate_estimator.cc index e47b7be6..80dd0ab1 100644 --- a/cc/trees/frame_rate_estimator.cc +++ b/cc/trees/frame_rate_estimator.cc
@@ -24,21 +24,22 @@ FrameRateEstimator::~FrameRateEstimator() = default; -void FrameRateEstimator::SetFrameEstimationEnabled(bool enabled) { +void FrameRateEstimator::SetVideoConferenceMode(bool enabled) { static const bool feature_allowed = base::FeatureList::IsEnabled(features::kReducedFrameRateEstimation); - if (!feature_allowed || enabled == frame_rate_estimation_enabled_) { + if (!feature_allowed || enabled == assumes_video_conference_mode_) { return; } - frame_rate_estimation_enabled_ = enabled; + assumes_video_conference_mode_ = enabled; last_draw_time_ = base::TimeTicks(); num_of_consecutive_frames_with_min_delta_ = 0u; } void FrameRateEstimator::WillDraw(base::TimeTicks now) { - if (!frame_rate_estimation_enabled_ || input_priority_mode_) + if (!assumes_video_conference_mode_ || input_priority_mode_) { return; + } if (last_draw_time_ == base::TimeTicks()) { last_draw_time_ = now; @@ -62,8 +63,9 @@ } base::TimeDelta FrameRateEstimator::GetPreferredInterval() const { - if (!frame_rate_estimation_enabled_ || input_priority_mode_) + if (!assumes_video_conference_mode_ || input_priority_mode_) { return viz::BeginFrameArgs::MinInterval(); + } constexpr size_t kMinNumOfFramesWithMinDelta = 4u; if (num_of_consecutive_frames_with_min_delta_ >= kMinNumOfFramesWithMinDelta) @@ -73,9 +75,6 @@ } void FrameRateEstimator::NotifyInputEvent() { - if (!frame_rate_estimation_enabled_) - return; - input_priority_mode_ = true; notifier_.Schedule(); }
diff --git a/cc/trees/frame_rate_estimator.h b/cc/trees/frame_rate_estimator.h index 29cad71..79845b6 100644 --- a/cc/trees/frame_rate_estimator.h +++ b/cc/trees/frame_rate_estimator.h
@@ -18,7 +18,7 @@ explicit FrameRateEstimator(base::SequencedTaskRunner* task_runner); ~FrameRateEstimator(); - void SetFrameEstimationEnabled(bool enabled); + void SetVideoConferenceMode(bool enabled); void WillDraw(base::TimeTicks now); void NotifyInputEvent(); base::TimeDelta GetPreferredInterval() const; @@ -29,7 +29,7 @@ // Set if an estimated frame rate should be used or we should assume the // highest frame rate available. - bool frame_rate_estimation_enabled_ = false; + bool assumes_video_conference_mode_ = false; // The frame time for the last drawn frame since frame estimation was // enabled.
diff --git a/cc/trees/frame_rate_estimator_unittest.cc b/cc/trees/frame_rate_estimator_unittest.cc index ee4c755..13bc187 100644 --- a/cc/trees/frame_rate_estimator_unittest.cc +++ b/cc/trees/frame_rate_estimator_unittest.cc
@@ -37,16 +37,16 @@ TEST_F(FrameRateEstimatorTest, ToggleEstimationEnabled) { EXPECT_EQ(estimator_->GetPreferredInterval(), viz::BeginFrameArgs::MinInterval()); - estimator_->SetFrameEstimationEnabled(true); + estimator_->SetVideoConferenceMode(true); EXPECT_NE(estimator_->GetPreferredInterval(), viz::BeginFrameArgs::MinInterval()); - estimator_->SetFrameEstimationEnabled(false); + estimator_->SetVideoConferenceMode(false); EXPECT_EQ(estimator_->GetPreferredInterval(), viz::BeginFrameArgs::MinInterval()); } TEST_F(FrameRateEstimatorTest, FrameHistoryUsed) { - estimator_->SetFrameEstimationEnabled(true); + estimator_->SetVideoConferenceMode(true); EXPECT_NE(estimator_->GetPreferredInterval(), viz::BeginFrameArgs::MinInterval()); base::TimeTicks time; @@ -63,7 +63,7 @@ } TEST_F(FrameRateEstimatorTest, InputPriorityMode) { - estimator_->SetFrameEstimationEnabled(true); + estimator_->SetVideoConferenceMode(true); estimator_->NotifyInputEvent(); EXPECT_EQ(estimator_->GetPreferredInterval(), viz::BeginFrameArgs::MinInterval()); @@ -74,7 +74,7 @@ } TEST_F(FrameRateEstimatorTest, RafAtHalfFps) { - estimator_->SetFrameEstimationEnabled(true); + estimator_->SetVideoConferenceMode(true); // Recorded rAF intervals at 30 fps. const base::TimeDelta kIntervals[] = { base::Microseconds(33425), base::Microseconds(33298),
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 0f865aa..2f0eff2 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -1477,8 +1477,8 @@ // Only enable frame rate estimation if it would help lower the composition // rate for videos. - const bool enable_frame_rate_estimation = num_of_layers_with_videos > 1; - frame_rate_estimator_.SetFrameEstimationEnabled(enable_frame_rate_estimation); + const bool assumes_video_conference_mode = num_of_layers_with_videos > 1; + frame_rate_estimator_.SetVideoConferenceMode(assumes_video_conference_mode); // When doing a resourceless software draw, we don't have control over the // surface the compositor draws to, so even though the frame may not be
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 6bcde5f..c38b1195 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -18065,7 +18065,7 @@ #else status = ContinuedScrollBegin(kInvalidId); EXPECT_EQ(ScrollThread::SCROLL_IGNORED, status.thread); - EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer, + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); #endif }
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index c080ac8d..5f88f43 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -401,6 +401,7 @@ "//components/browser_ui/util/android:java", "//components/browser_ui/webshare/android:java", "//components/browser_ui/widget/android:java", + "//components/browsing_data/core:java", "//components/commerce/core:proto_java", "//components/commerce/core/android:core_java", "//components/component_updater/android:background_task_update_scheduler_java", @@ -589,8 +590,6 @@ "//chrome/browser:sharing_send_message_result_generated_enum", "//chrome/browser/notifications/scheduler/public:jni_enums", "//chrome/browser/ui:duplicate_download_enums_java", - "//components/browsing_data/core:browsing_data_utils_java", - "//components/browsing_data/core:clear_browsing_data_tab_java", "//components/contextual_search/core/browser:quick_action_category_enum_javagen", "//components/dom_distiller/core:distiller_type_java", "//components/ntp_tiles:ntp_tiles_enums_java", @@ -924,6 +923,7 @@ "//chrome/browser/profiles/android:junit", "//chrome/browser/quick_delete:java", "//chrome/browser/quick_delete:junit", + "//chrome/browser/recent_tabs:java", "//chrome/browser/recent_tabs/internal:junit", "//chrome/browser/safety_check/android:java", "//chrome/browser/safety_check/android:junit", @@ -1567,6 +1567,7 @@ "//components/browser_ui/util/android:java", "//components/browser_ui/widget/android:java", "//components/browser_ui/widget/android:test_support_java", + "//components/browsing_data/core:java", "//components/commerce/core:proto_java", "//components/commerce/core/android:core_java", "//components/content_settings/android:content_settings_enums_java", @@ -3571,7 +3572,6 @@ "java/src/org/chromium/chrome/browser/notifications/PushMessagingServiceBridge.java", "java/src/org/chromium/chrome/browser/notifications/scheduler/DisplayAgent.java", "java/src/org/chromium/chrome/browser/notifications/scheduler/NotificationSchedulerTask.java", - "java/src/org/chromium/chrome/browser/ntp/ForeignSessionHelper.java", "java/src/org/chromium/chrome/browser/ntp/RecentTabsPagePrefs.java", "java/src/org/chromium/chrome/browser/ntp/RecentlyClosedBridge.java", "java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 735c62b1..01cac95 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -772,7 +772,6 @@ "java/src/org/chromium/chrome/browser/notifications/scheduler/DisplayAgent.java", "java/src/org/chromium/chrome/browser/notifications/scheduler/NotificationSchedulerTask.java", "java/src/org/chromium/chrome/browser/ntp/FeedPositionUtils.java", - "java/src/org/chromium/chrome/browser/ntp/ForeignSessionHelper.java", "java/src/org/chromium/chrome/browser/ntp/IncognitoCookieControlsManager.java", "java/src/org/chromium/chrome/browser/ntp/IncognitoDescriptionView.java", "java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java index 235ee69..bd49b6b 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java
@@ -971,6 +971,12 @@ public void addCustomView(@NonNull View customView, @Nullable Runnable backPressRunnable) { assert mCustomView == null : "Only one client at a time is supported to add a custom view."; + // Hide any tab grid dialog before we add the custom view. + if (mTabGridDialogControllerSupplier != null + && mTabGridDialogControllerSupplier.hasValue()) { + mTabGridDialogControllerSupplier.get().hideDialog(false); + } + // The grid tab switcher for tablets translates up over top of the browser controls, causing // the custom view to do the same. if (mIsTablet) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabSideSheetStrategy.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabSideSheetStrategy.java index 231a3c00..340fd660 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabSideSheetStrategy.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabSideSheetStrategy.java
@@ -140,42 +140,47 @@ updateShadowOffset(); } - int start; - int end; - int restWidth = mVersionCompat.getDisplayWidth() - mUnclampedInitialWidth; + AnimatorUpdateListener updateListener; Window window = mActivity.getWindow(); - configureLayoutBeyondScreen(true); - // For smooth animation, make the window full-width first and then translate it - // rather than resizing the window itself during the animation. + int displayWidth = mVersionCompat.getDisplayWidth(); + int xOffset = mVersionCompat.getXOffset(); + int start = window.getAttributes().width; + int end = calculateWidth(mIsMaximized ? displayWidth : mUnclampedInitialWidth); if (mSheetOnRight) { - setWindowWidth(mVersionCompat.getDisplayWidth()); - start = window.getAttributes().x; - end = (mIsMaximized ? 0 : restWidth) + mVersionCompat.getXOffset(); + updateListener = (anim) -> { + WindowManager.LayoutParams attrs = window.getAttributes(); + attrs.width = (int) anim.getAnimatedValue(); + attrs.x = (displayWidth - attrs.width) + xOffset; + window.setAttributes(attrs); + }; } else { - if (mIsMaximized) { - // For the left-side sheet, adjust the start x (to be negative) before - // animating the full-width tab back into screen. - var attrs = mActivity.getWindow().getAttributes(); - attrs.x = -restWidth + mVersionCompat.getXOffset(); - attrs.width = mVersionCompat.getDisplayWidth(); - mActivity.getWindow().setAttributes(attrs); - } - start = window.getAttributes().x; - end = (mIsMaximized ? 0 : -restWidth) + mVersionCompat.getXOffset(); + updateListener = (anim) -> setWindowWidth((int) anim.getAnimatedValue()); } - AnimatorUpdateListener updateListener = (anim) -> setWindowX((int) anim.getAnimatedValue()); + // Keep the WebContents invisible during the animation to hide the jerky visual artifacts + // of the contents due to resizing. + setContentVisible(false); startAnimation(start, end, updateListener, () -> onMaximizeEnd(animate), animate); return mIsMaximized; } + private void setContentVisible(boolean visible) { + View content = (ViewGroup) mActivity.findViewById(R.id.compositor_view_holder); + if (visible) { + // Set a slight delay in restoring the view to hide the visual glitch caused by + // the resized web contents. + new Handler().postDelayed(() -> content.setVisibility(View.VISIBLE), 20); + } else { + content.setVisibility(View.INVISIBLE); + } + } + private void onMaximizeEnd(boolean animate) { if (isMaximized()) { - configureLayoutBeyondScreen(false); maybeInvokeResizeCallback(); + setContentVisible(true); } else { // System UI dimensions are not settled yet. Post the task. new Handler().post(() -> { - configureLayoutBeyondScreen(false); initializeSize(); maybeInvokeResizeCallback(); }); @@ -306,6 +311,7 @@ mIsMaximized = false; toggleMaximize(/*animate=*/false); } + setContentVisible(true); } private void positionOnWindow() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java index ca9b00c..3141fa63 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -10,7 +10,6 @@ import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.provider.Settings; import androidx.annotation.VisibleForTesting; @@ -91,14 +90,6 @@ return FirstRunUtils.canAllowSync() && !signinManager.isSigninDisabledByPolicy() && signinManager.isSigninSupported(); } - - /** @return true if first use hints should be skipped. */ - @VisibleForTesting - protected boolean shouldSkipFirstUseHints(Activity activity) { - return Settings.Secure.getInt( - activity.getContentResolver(), Settings.Secure.SKIP_FIRST_USE_HINTS, 0) - != 0; - } } private final Activity mActivity;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/SessionsInvalidationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/SessionsInvalidationManager.java index 2949f6b..20699b0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/SessionsInvalidationManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/SessionsInvalidationManager.java
@@ -11,8 +11,8 @@ import org.chromium.base.ApplicationState; import org.chromium.base.ApplicationStatus; import org.chromium.base.ThreadUtils; -import org.chromium.chrome.browser.ntp.ForeignSessionHelper; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper; /** * Class responsible for managing registration for invalidations for noisy sync
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsGroupView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsGroupView.java index f18cb23..24b821d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsGroupView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsGroupView.java
@@ -14,7 +14,7 @@ import android.widget.TextView; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSession; +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSession; import org.chromium.components.browser_ui.widget.TintedDrawable; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java index c7be9c5..fa154a4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
@@ -11,9 +11,10 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.browser.invalidation.SessionsInvalidationManager; -import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSession; -import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionTab; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper; +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSession; +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSessionTab; import org.chromium.chrome.browser.signin.SyncConsentActivityLauncherImpl; import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; import org.chromium.chrome.browser.signin.services.ProfileDataCache;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPagePrefs.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPagePrefs.java index 7231a23..3a526ee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPagePrefs.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPagePrefs.java
@@ -5,8 +5,8 @@ package org.chromium.chrome.browser.ntp; import org.chromium.base.annotations.NativeMethods; -import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSession; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSession; /** * Allows Java code to read and modify preferences related to the {@link RecentTabsPage}.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java index 970d773..9a876ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
@@ -26,9 +26,9 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSession; -import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionTab; -import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionWindow; +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSession; +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSessionTab; +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSessionWindow; import org.chromium.chrome.browser.signin.LegacySyncPromoView; import org.chromium.chrome.browser.ui.favicon.FaviconHelper.DefaultFaviconHelper; import org.chromium.chrome.browser.ui.favicon.FaviconHelper.FaviconImageCallback;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java index 5ff757e..6163007 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -18,6 +18,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ObserverList; @@ -39,6 +40,7 @@ import org.chromium.chrome.browser.content.ContentUtils; import org.chromium.chrome.browser.contextmenu.ContextMenuPopulatorFactory; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.incognito.IncognitoUtils; import org.chromium.chrome.browser.native_page.NativePageAssassin; import org.chromium.chrome.browser.night_mode.NightModeUtils; @@ -1682,8 +1684,14 @@ return userAgentOverrideOption; } + CommandLine commandLine = CommandLine.getInstance(); + // For --request-desktop-sites, always override the user agent. + boolean alwaysRequestDesktopSite = + commandLine.hasSwitch(ChromeSwitches.REQUEST_DESKTOP_SITES); + boolean shouldRequestDesktopSite = - TabUtils.readRequestDesktopSiteContentSettings(profile, url); + TabUtils.readRequestDesktopSiteContentSettings(profile, url) + || alwaysRequestDesktopSite; if (!shouldRequestDesktopSite && ContentFeatureList.isEnabled( ContentFeatureList.REQUEST_DESKTOP_SITE_ADDITIONS)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstallBroadcastReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstallBroadcastReceiver.java index 4074864..ae1d0c8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstallBroadcastReceiver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstallBroadcastReceiver.java
@@ -31,6 +31,7 @@ private static final String NOTIFICATION_ID = "WebApkInstallNotification.notification_id"; private static final String WEBAPK_START_URL = "WebApkInstallNotification.start_url"; + private static final String RETRY_PROTO = "WebApkInstallNotification.retry_proto"; private final WebApkInstallCoordinatorBridge mBridge; @@ -47,22 +48,27 @@ @Override public void onReceive(Context context, Intent intent) { - assert intent != null && !intent.hasExtra(NOTIFICATION_ID); + assert intent != null && intent.hasExtra(NOTIFICATION_ID); String id = intent.getStringExtra(NOTIFICATION_ID); + WebApkInstallService.cancelNotification(id); + if (ACTION_RETRY_INSTALL.equals(intent.getAction())) { + // TODO(crbug/1409642): Implement the retry. + } if (ACTION_OPEN_IN_BROWSER.equals(intent.getAction())) { openInChrome(context, intent.getStringExtra(WEBAPK_START_URL)); } } - static PendingIntentProvider createPendingIntent( - Context context, String notificationId, String url, String action) { + static PendingIntentProvider createPendingIntent(Context context, String notificationId, + String url, String action, byte[] serializedProto) { Intent intent = new Intent(action); intent.setClass(context, WebApkInstallBroadcastReceiver.class); intent.putExtra(NOTIFICATION_ID, notificationId); intent.putExtra(WEBAPK_START_URL, url); + intent.putExtra(RETRY_PROTO, serializedProto); int requestCode = 0; int flags = PendingIntent.FLAG_UPDATE_CURRENT;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstallService.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstallService.java index d2f2ff3a..0bffc87 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstallService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstallService.java
@@ -15,6 +15,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.chrome.R; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.notifications.NotificationUmaTracker; import org.chromium.chrome.browser.notifications.NotificationUmaTracker.SystemNotificationType; import org.chromium.chrome.browser.notifications.NotificationWrapperBuilderFactory; @@ -35,7 +36,6 @@ /** Java counterpart to webapk_install_service.h. */ public class WebApkInstallService { /** Prefix used for generating a unique notification tag. */ - @VisibleForTesting static final String WEBAPK_INSTALL_NOTIFICATION_TAG_PREFIX = "webapk_install_notification_tag_prefix."; @@ -59,7 +59,7 @@ showNotification(notificationId, SystemNotificationType.WEBAPK_INSTALL_COMPLETE, shortName, url, icon, context.getResources().getString(R.string.notification_webapk_installed), - clickPendingIntent); + clickPendingIntent, null); } /** Display a notification when an install starts. */ @@ -73,7 +73,7 @@ icon = WebappsIconUtils.generateAdaptiveIconBitmap(icon); } showNotification(notificationId, SystemNotificationType.WEBAPK_INSTALL_IN_PROGRESS, - shortName, url, icon, message, null); + shortName, url, icon, message, null, null); WebappsUtils.showToast(message); } @@ -81,7 +81,8 @@ @CalledByNative @VisibleForTesting static void showInstallFailedNotification(String notificationId, String shortName, String url, - Bitmap icon, boolean isIconMaskable, @WebApkInstallResult int resultCode) { + Bitmap icon, boolean isIconMaskable, @WebApkInstallResult int resultCode, + byte[] serializedProto) { Context context = ContextUtils.getApplicationContext(); String titleMessage = context.getResources().getString( R.string.notification_webapk_install_failed, shortName); @@ -89,18 +90,18 @@ PendingIntentProvider openUrlIntent = WebApkInstallBroadcastReceiver.createPendingIntent(context, notificationId, url, - WebApkInstallBroadcastReceiver.ACTION_OPEN_IN_BROWSER); + WebApkInstallBroadcastReceiver.ACTION_OPEN_IN_BROWSER, null); if (isIconMaskable && WebappsIconUtils.doesAndroidSupportMaskableIcons()) { icon = WebappsIconUtils.generateAdaptiveIconBitmap(icon); } showNotification(notificationId, SystemNotificationType.WEBAPK_INSTALL_FAILED, titleMessage, - url, icon, contentMessage, openUrlIntent); + url, icon, contentMessage, openUrlIntent, serializedProto); } private static void showNotification(String notificationId, @SystemNotificationType int type, String shortName, String url, Bitmap icon, String message, - PendingIntentProvider clickPendingIntent) { + PendingIntentProvider clickPendingIntent, byte[] serializedProto) { Context context = ContextUtils.getApplicationContext(); String channelId; @@ -114,7 +115,7 @@ } NotificationMetadata metadata = new NotificationMetadata( - type, WEBAPK_INSTALL_NOTIFICATION_TAG_PREFIX + notificationId, PLATFORM_ID); + type, getInstallNotificationTag(notificationId), PLATFORM_ID); NotificationWrapperBuilder notificationBuilder = NotificationWrapperBuilderFactory.createNotificationWrapperBuilder( @@ -131,6 +132,17 @@ .setAutoCancel(true); if (type == SystemNotificationType.WEBAPK_INSTALL_FAILED) { + if (ChromeFeatureList.isEnabled(ChromeFeatureList.WEB_APK_INSTALL_RETRY) + && serializedProto != null && serializedProto.length > 0) { + PendingIntentProvider retryIntent = + WebApkInstallBroadcastReceiver.createPendingIntent(context, notificationId, + url, WebApkInstallBroadcastReceiver.ACTION_RETRY_INSTALL, + serializedProto); + notificationBuilder.addAction(0 /* no icon */, + context.getResources().getString( + R.string.webapk_install_failed_action_retry), + retryIntent, NotificationUmaTracker.ActionType.WEB_APK_ACTION_RETRY); + } notificationBuilder.addAction(0 /* no icon */, context.getResources().getString(R.string.webapk_install_failed_action_open), clickPendingIntent, @@ -149,8 +161,7 @@ static void cancelNotification(String notificationId) { NotificationManagerProxy notificationManager = new NotificationManagerProxyImpl(ContextUtils.getApplicationContext()); - notificationManager.cancel( - WEBAPK_INSTALL_NOTIFICATION_TAG_PREFIX + notificationId, PLATFORM_ID); + notificationManager.cancel(getInstallNotificationTag(notificationId), PLATFORM_ID); } private static String getInstallErrorMessage(@WebApkInstallResult int resultCode) { @@ -160,4 +171,8 @@ R.string.notification_webapk_install_failed_contents_general); return message; } + + static String getInstallNotificationTag(String notificationId) { + return WebApkInstallService.WEBAPK_INSTALL_NOTIFICATION_TAG_PREFIX + notificationId; + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunActivitySigninAndSyncTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunActivitySigninAndSyncTest.java index 81a2afc..3f04dcce 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunActivitySigninAndSyncTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunActivitySigninAndSyncTest.java
@@ -54,7 +54,6 @@ import org.chromium.base.test.util.Matchers; import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.locale.LocaleManagerDelegate; import org.chromium.chrome.browser.profiles.Profile; @@ -77,7 +76,6 @@ * Integration tests for the first run experience with sign-in and sync decoupled. */ @RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({ChromeSwitches.FORCE_ENABLE_SIGNIN_FRE}) @DoNotBatch(reason = "This test interacts with native initialization") public class FirstRunActivitySigninAndSyncTest { private static final String TEST_EMAIL = "test.account@gmail.com";
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java index 1851a9e..659c3dd 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java
@@ -87,7 +87,7 @@ * Render tests for sync consent fragment. */ @RunWith(ChromeJUnit4ClassRunner.class) -@Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, ChromeSwitches.FORCE_ENABLE_SIGNIN_FRE}) +@Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public class SyncConsentFragmentTest { private static final int RENDER_REVISION = 1; private static final String RENDER_DESCRIPTION = "Change button style";
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabTestRule.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabTestRule.java index 202fd60a..9b1e470 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabTestRule.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabTestRule.java
@@ -130,6 +130,8 @@ PartialCustomTabHandleStrategyFactory mHandleStrategyFactory; @Mock DisplayMetrics mMetrics; + @Mock + ViewGroup mCompositorViewHolder; Context mContext; List<WindowManager.LayoutParams> mAttributeResults; @@ -148,6 +150,7 @@ when(mActivity.getResources()).thenReturn(mResources); when(mActivity.getWindowManager()).thenReturn(mWindowManager); when(mActivity.findViewById(R.id.coordinator)).thenReturn(mCoordinatorLayout); + when(mActivity.findViewById(R.id.compositor_view_holder)).thenReturn(mCompositorViewHolder); when(mActivity.findViewById(android.R.id.content)).thenReturn(mContentFrame); when(mActivity.findViewById(R.id.custom_tabs_handle_view_stub)).thenReturn(mHandleViewStub); when(mActivity.findViewById(R.id.custom_tabs_handle_view)).thenReturn(mHandleView);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java index 2c2c6f1..8490519 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java
@@ -77,12 +77,6 @@ public boolean isSyncAllowed() { return isSyncAllowed; } - - // TODO(https://crbug.com/1409385): Delete this method after launch is complete. - @Override - public boolean shouldSkipFirstUseHints(Activity activity) { - return shouldSkipFirstUseHints; - } } private static class TestFirstRunFlowSequencer extends FirstRunFlowSequencer {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/invalidation/SessionsInvalidationManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/invalidation/SessionsInvalidationManagerTest.java index 0997ef4..add546f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/invalidation/SessionsInvalidationManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/invalidation/SessionsInvalidationManagerTest.java
@@ -22,8 +22,8 @@ import org.chromium.base.ApplicationState; import org.chromium.base.ApplicationStatus; import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.ntp.ForeignSessionHelper; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper; import java.util.concurrent.atomic.AtomicBoolean;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInstallNotificationTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInstallNotificationTest.java index aa16225..bb15ce7 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInstallNotificationTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInstallNotificationTest.java
@@ -10,6 +10,7 @@ import static org.robolectric.Shadows.shadowOf; import android.app.Notification; +import android.app.Notification.Action; import android.app.NotificationManager; import android.content.Context; import android.graphics.Bitmap; @@ -22,6 +23,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -32,10 +34,13 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.R; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.notifications.channels.ChromeChannelDefinitions; +import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.url_formatter.SchemeDisplay; import org.chromium.components.url_formatter.UrlFormatter; import org.chromium.components.url_formatter.UrlFormatterJni; +import org.chromium.components.webapps.WebApkInstallResult; import org.chromium.content_public.browser.test.util.TestThreadUtils; /** @@ -52,6 +57,9 @@ @Rule public JniMocker mJniMocker = new JniMocker(); + @Rule + public TestRule mProcessor = new Features.JUnitProcessor(); + @Mock private UrlFormatter.Natives mUrlFormatterJniMock; @@ -80,8 +88,7 @@ MANIFEST_URL, SHORT_NAME, URL, mIcon, false /* isIconMaskable */); }); - String notificationId = - WebApkInstallService.WEBAPK_INSTALL_NOTIFICATION_TAG_PREFIX + MANIFEST_URL; + String notificationId = WebApkInstallService.getInstallNotificationTag(MANIFEST_URL); Notification notification = mShadowNotificationManager.getAllNotifications().get(0); Assert.assertNotNull(notification); @@ -127,4 +134,86 @@ Assert.assertNotNull(notification.contentIntent); } + + @Test + @Features.EnableFeatures({ChromeFeatureList.WEB_APK_INSTALL_FAILURE_NOTIFICATION, + ChromeFeatureList.WEB_APK_INSTALL_RETRY}) + public void + testFailureNotification() { + WebApkInstallService.showInstallFailedNotification(MANIFEST_URL, SHORT_NAME, URL, mIcon, + false /* isIconMaskable */, WebApkInstallResult.FAILURE, null); + + Notification notification = mShadowNotificationManager.getAllNotifications().get(0); + + Assert.assertNotNull(notification); + Assert.assertEquals( + mContext.getString(R.string.notification_webapk_install_failed, SHORT_NAME), + notification.extras.getString(Notification.EXTRA_TITLE)); + Assert.assertEquals( + ChromeChannelDefinitions.ChannelId.WEBAPPS, notification.getChannelId()); + Assert.assertEquals( + mContext.getString( + R.string.notification_webapk_install_failed_contents_general, SHORT_NAME), + notification.extras.getString(Notification.EXTRA_TEXT)); + + Bitmap largeIcon = + ((BitmapDrawable) notification.getLargeIcon().loadDrawable(mContext)).getBitmap(); + Assert.assertTrue(mIcon.sameAs(largeIcon)); + Bitmap expectedSmallIcon = + BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_chrome); + Bitmap smallIcon = + ((BitmapDrawable) notification.getSmallIcon().loadDrawable(mContext)).getBitmap(); + Assert.assertTrue(expectedSmallIcon.sameAs(smallIcon)); + + Assert.assertNotNull(notification.contentIntent); + + Action[] actions = notification.actions; + Assert.assertEquals(1, actions.length); + Assert.assertEquals( + mContext.getString(R.string.webapk_install_failed_action_open), actions[0].title); + Assert.assertNotNull(actions[0].actionIntent); + } + + @Test + @Features.EnableFeatures({ChromeFeatureList.WEB_APK_INSTALL_FAILURE_NOTIFICATION, + ChromeFeatureList.WEB_APK_INSTALL_RETRY}) + public void + testFailureNotificationWithRetryAction() { + byte[] serializedProto = new byte[] {1, 2}; + WebApkInstallService.showInstallFailedNotification(MANIFEST_URL, SHORT_NAME, URL, mIcon, + false /* isIconMaskable */, WebApkInstallResult.FAILURE, serializedProto); + + Notification notification = mShadowNotificationManager.getAllNotifications().get(0); + + Assert.assertNotNull(notification); + Assert.assertEquals( + mContext.getString(R.string.notification_webapk_install_failed, SHORT_NAME), + notification.extras.getString(Notification.EXTRA_TITLE)); + Assert.assertEquals( + ChromeChannelDefinitions.ChannelId.WEBAPPS, notification.getChannelId()); + Assert.assertEquals( + mContext.getString( + R.string.notification_webapk_install_failed_contents_general, SHORT_NAME), + notification.extras.getString(Notification.EXTRA_TEXT)); + + Bitmap largeIcon = + ((BitmapDrawable) notification.getLargeIcon().loadDrawable(mContext)).getBitmap(); + Assert.assertTrue(mIcon.sameAs(largeIcon)); + Bitmap expectedSmallIcon = + BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_chrome); + Bitmap smallIcon = + ((BitmapDrawable) notification.getSmallIcon().loadDrawable(mContext)).getBitmap(); + Assert.assertTrue(expectedSmallIcon.sameAs(smallIcon)); + + Assert.assertNotNull(notification.contentIntent); + + Action[] actions = notification.actions; + Assert.assertEquals(2, actions.length); + Assert.assertEquals( + mContext.getString(R.string.webapk_install_failed_action_retry), actions[0].title); + Assert.assertNotNull(actions[0].actionIntent); + Assert.assertEquals( + mContext.getString(R.string.webapk_install_failed_action_open), actions[1].title); + Assert.assertNotNull(actions[1].actionIntent); + } }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index cf538b7..00d20eb 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -14070,6 +14070,9 @@ <message name="IDS_SETTINGS_SAFEBROWSING_ENHANCED_IPH_BUBBLE_TEXT" desc="The text on an In-Product-Help bubble that is shown when a user navigates to the security settings page from an ESB promotion"> Get more protection against dangerous websites and downloads </message> + <message name="IDS_SETTINGS_SAFEBROWSING_ENHANCED_IPH_BUBBLE_CLOSE_BUTTON_ARIA_LABEL_TEXT" desc="The accessibility label associated with the In-Product-Help bubble's close button"> + Close tip + </message> <!-- Tailored security dialog for consented primary accounts --> <message name="IDS_TAILORED_SECURITY_ENABLED_DIALOG_TITLE" desc="Title shown in the tab dialog when the account tailored security setting changes for a consented primary account">
diff --git a/chrome/app/generated_resources_grd/IDS_SETTINGS_SAFEBROWSING_ENHANCED_IPH_BUBBLE_CLOSE_BUTTON_ARIA_LABEL_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_SETTINGS_SAFEBROWSING_ENHANCED_IPH_BUBBLE_CLOSE_BUTTON_ARIA_LABEL_TEXT.png.sha1 new file mode 100644 index 0000000..40b2bea9 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_SETTINGS_SAFEBROWSING_ENHANCED_IPH_BUBBLE_CLOSE_BUTTON_ARIA_LABEL_TEXT.png.sha1
@@ -0,0 +1 @@ +c12ff1f51aa44b96c22f4cfe4b17b5d5f39024d2 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 451dcec..4607e1b 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2514,6 +2514,13 @@ "performance_monitor/metric_evaluator_helper_posix.h", ] } + if (enable_supervised_users && + (is_android || is_win || is_linux || is_mac || is_chromeos_lacros)) { + sources += [ + "metrics/family_link_user_metrics_provider.cc", + "metrics/family_link_user_metrics_provider.h", + ] + } if (is_android) { sources += [ @@ -3042,8 +3049,6 @@ "memory_details_android.cc", "metrics/chrome_android_metrics_provider.cc", "metrics/chrome_android_metrics_provider.h", - "metrics/family_link_user_metrics_provider.cc", - "metrics/family_link_user_metrics_provider.h", "metrics/incognito_observer_android.cc", "metrics/page_load_metrics_provider.cc", "metrics/page_load_metrics_provider.h", @@ -3292,6 +3297,7 @@ "//chrome/browser/privacy:jni_headers", "//chrome/browser/privacy_sandbox/android:jni_headers", "//chrome/browser/reading_list/android", + "//chrome/browser/recent_tabs:jni_headers", "//chrome/browser/safe_browsing/android:safe_browsing_enums", "//chrome/browser/safety_check/android", "//chrome/browser/search_resumption:jni_headers", @@ -3572,6 +3578,8 @@ "download/bubble/download_bubble_ui_controller.h", "download/bubble/download_bubble_update_service.cc", "download/bubble/download_bubble_update_service.h", + "download/bubble/download_bubble_update_service_factory.cc", + "download/bubble/download_bubble_update_service_factory.h", "download/bubble/download_bubble_utils.cc", "download/bubble/download_bubble_utils.h", "download/bubble/download_display.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 1ef088f5..bbd45870 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1356,31 +1356,57 @@ kSidePanelJourneysOpensFromOmniboxParams, std::size(kSidePanelJourneysOpensFromOmniboxParams), nullptr}, }; -const FeatureEntry::FeatureParam - kJourneysCosineSimilarityNoPairwiseMergeParams[] = { +const FeatureEntry::FeatureParam kJourneysAllVisitsNoPairwiseMergeParams[] = { + {"collections_blocklist", + "/collection/it_glossary,/collection/periodicals,/collection/" + "software,/collection/websites"}, + {"exclude_entities_that_have_no_collections", "true"}, + {"use_pairwise_merge", "false"}, + {"search_visits_only", "false"}, +}; +const FeatureEntry::FeatureParam kJourneysAllVisitsWithPairwiseMergeParams[] = { + {"collections_blocklist", + "/collection/it_glossary,/collection/periodicals,/collection/" + "software,/collection/websites"}, + {"exclude_entities_that_have_no_collections", "true"}, + {"use_pairwise_merge", "true"}, + {"search_visits_only", "false"}, +}; +const FeatureEntry::FeatureParam kJourneysSearchVisitsNoPairwiseMergeParams[] = + { {"collections_blocklist", "/collection/it_glossary,/collection/periodicals,/collection/" "software,/collection/websites"}, {"exclude_entities_that_have_no_collections", "true"}, - {"use_content_clustering_cosine_similarity", "true"}, {"use_pairwise_merge", "false"}, + {"search_visits_only", "true"}, }; const FeatureEntry::FeatureParam - kJourneysCosineSimilarityWithPairwiseMergeParams[] = { + kJourneysSearchVisitsWithPairwiseMergeParams[] = { {"collections_blocklist", "/collection/it_glossary,/collection/periodicals,/collection/" "software,/collection/websites"}, {"exclude_entities_that_have_no_collections", "true"}, - {"use_content_clustering_cosine_similarity", "true"}, {"use_pairwise_merge", "true"}, + {"search_visits_only", "true"}, }; const FeatureEntry::FeatureVariation kJourneysContentClusteringVariations[] = { - {"Cosine Similarity With Blocklist and No Pairwise Merge", - kJourneysCosineSimilarityNoPairwiseMergeParams, - std::size(kJourneysCosineSimilarityNoPairwiseMergeParams), nullptr}, - {"Cosine Similarity With Blocklist and Pairwise Merge", - kJourneysCosineSimilarityWithPairwiseMergeParams, - std::size(kJourneysCosineSimilarityWithPairwiseMergeParams), nullptr}, + {"All Visits With Blocklist and No Pairwise Merge", + kJourneysAllVisitsNoPairwiseMergeParams, + std::size(kJourneysAllVisitsNoPairwiseMergeParams), nullptr}, + {"All Visits With Blocklist and Pairwise Merge", + kJourneysAllVisitsWithPairwiseMergeParams, + std::size(kJourneysAllVisitsWithPairwiseMergeParams), nullptr}, + {"Search Visits With Blocklist and No Pairwise Merge", + kJourneysSearchVisitsNoPairwiseMergeParams, + std::size(kJourneysSearchVisitsNoPairwiseMergeParams), nullptr}, + {"Search Visits With Blocklist and Pairwise Merge", + kJourneysSearchVisitsWithPairwiseMergeParams, + std::size(kJourneysSearchVisitsWithPairwiseMergeParams), nullptr}, +}; +const FeatureEntry::FeatureParam + kJourneysLabelsWithSearchVisitEntitiesParams[] = { + {"labels_from_search_visit_entities", "true"}, }; const FeatureEntry::FeatureParam kJourneysLabelsWithEntitiesParams[] = { {"labels_from_entities", "true"}, @@ -1396,6 +1422,8 @@ {"With Entities, No Hostnames", kJourneysLabelsWithEntitiesNoHostnamesParams, std::size(kJourneysLabelsWithEntitiesNoHostnamesParams), nullptr}, + {"With Search Entities", kJourneysLabelsWithSearchVisitEntitiesParams, + std::size(kJourneysLabelsWithSearchVisitEntitiesParams), nullptr}, }; #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID) @@ -1759,37 +1787,34 @@ std::size(kOmniboxUniformRowHeight40), nullptr}, }; -const FeatureEntry::FeatureParam - kOrganicRepeatableQueriesCappedWithHighPrivilege[] = { - {"MaxNumRepeatableQueries", "4"}, - {"ScaleRepeatableQueriesScores", "true"}, - {"PrivilegeRepeatableQueries", "true"}}; -const FeatureEntry::FeatureParam - kOrganicRepeatableQueriesCappedWithLowPrivilege[] = { - {"MaxNumRepeatableQueries", "4"}, - {"ScaleRepeatableQueriesScores", "true"}, - {"PrivilegeRepeatableQueries", "false"}}; -const FeatureEntry::FeatureParam - kOrganicRepeatableQueriesUncappedWithHighPrivilege[] = { - {"ScaleRepeatableQueriesScores", "true"}, - {"PrivilegeRepeatableQueries", "true"}}; -const FeatureEntry::FeatureParam - kOrganicRepeatableQueriesUncappedWithLowPrivilege[] = { - {"ScaleRepeatableQueriesScores", "true"}, - {"PrivilegeRepeatableQueries", "false"}}; +const FeatureEntry::FeatureParam kRepeatableQueries_6Searches_90Days[] = { + {"RepeatableQueriesIgnoreDuplicateVisits", "true"}, + {"RepeatableQueriesMinVisitCount", "6"}, +}; +const FeatureEntry::FeatureParam kRepeatableQueries_12Searches_90Days[] = { + {"RepeatableQueriesIgnoreDuplicateVisits", "true"}, + {"RepeatableQueriesMinVisitCount", "12"}, +}; +const FeatureEntry::FeatureParam kRepeatableQueries_6Searches_7Days[] = { + {"RepeatableQueriesIgnoreDuplicateVisits", "true"}, + {"RepeatableQueriesMinVisitCount", "6"}, + {"RepeatableQueriesMaxAgeDays", "7"}, +}; +const FeatureEntry::FeatureParam kRepeatableQueries_12Searches_7Days[] = { + {"RepeatableQueriesIgnoreDuplicateVisits", "true"}, + {"RepeatableQueriesMinVisitCount", "12"}, + {"RepeatableQueriesMaxAgeDays", "7"}, +}; const FeatureEntry::FeatureVariation kOrganicRepeatableQueriesVariations[] = { - {"- No max, High privilege", - kOrganicRepeatableQueriesUncappedWithHighPrivilege, - std::size(kOrganicRepeatableQueriesUncappedWithHighPrivilege), nullptr}, - {"- No max, Low privilege", - kOrganicRepeatableQueriesUncappedWithLowPrivilege, - std::size(kOrganicRepeatableQueriesUncappedWithLowPrivilege), nullptr}, - {"- Max 4, High privilege", - kOrganicRepeatableQueriesCappedWithHighPrivilege, - std::size(kOrganicRepeatableQueriesCappedWithHighPrivilege), nullptr}, - {"- Max 4, Low privilege", kOrganicRepeatableQueriesCappedWithLowPrivilege, - std::size(kOrganicRepeatableQueriesCappedWithLowPrivilege), nullptr}, + {"6+ uses, once in last 90d", kRepeatableQueries_6Searches_90Days, + std::size(kRepeatableQueries_6Searches_90Days), nullptr}, + {"12+ uses, once in last 90d", kRepeatableQueries_12Searches_90Days, + std::size(kRepeatableQueries_12Searches_90Days), nullptr}, + {"6+ uses, once in last 7d", kRepeatableQueries_6Searches_7Days, + std::size(kRepeatableQueries_6Searches_7Days), nullptr}, + {"12+ uses, once in last 7d", kRepeatableQueries_12Searches_7Days, + std::size(kRepeatableQueries_12Searches_7Days), nullptr}, }; const FeatureEntry::FeatureParam kMinimumTabWidthSettingPinned[] = { @@ -2143,33 +2168,6 @@ #endif // BUILDFLAG(IS_ANDROID) -const FeatureEntry::FeatureParam kResamplingInputEventsLSQEnabled[] = { - {"predictor", features::kPredictorNameLsq}}; -const FeatureEntry::FeatureParam kResamplingInputEventsKalmanEnabled[] = { - {"predictor", features::kPredictorNameKalman}}; -const FeatureEntry::FeatureParam kResamplingInputEventsLinearFirstEnabled[] = { - {"predictor", features::kPredictorNameLinearFirst}}; -const FeatureEntry::FeatureParam kResamplingInputEventsLinearSecondEnabled[] = { - {"predictor", features::kPredictorNameLinearSecond}}; -const FeatureEntry::FeatureParam - kResamplingInputEventsLinearResamplingEnabled[] = { - {"predictor", features::kPredictorNameLinearResampling}}; - -const FeatureEntry::FeatureVariation kResamplingInputEventsFeatureVariations[] = - {{features::kPredictorNameLsq, kResamplingInputEventsLSQEnabled, - std::size(kResamplingInputEventsLSQEnabled), nullptr}, - {features::kPredictorNameKalman, kResamplingInputEventsKalmanEnabled, - std::size(kResamplingInputEventsKalmanEnabled), nullptr}, - {features::kPredictorNameLinearFirst, - kResamplingInputEventsLinearFirstEnabled, - std::size(kResamplingInputEventsLinearFirstEnabled), nullptr}, - {features::kPredictorNameLinearSecond, - kResamplingInputEventsLinearSecondEnabled, - std::size(kResamplingInputEventsLinearSecondEnabled), nullptr}, - {features::kPredictorNameLinearResampling, - kResamplingInputEventsLinearResamplingEnabled, - std::size(kResamplingInputEventsLinearResamplingEnabled), nullptr}}; - const FeatureEntry::FeatureParam kResamplingScrollEventsPredictionTimeBasedEnabled[] = { {"mode", features::kPredictionTypeTimeBased}, @@ -2188,17 +2186,6 @@ std::size(kResamplingScrollEventsPredictionFramesBasedEnabled), nullptr}}; -const FeatureEntry::FeatureParam kFilteringPredictionEmptyFilterEnabled[] = { - {"filter", features::kFilterNameEmpty}}; -const FeatureEntry::FeatureParam kFilteringPredictionOneEuroFilterEnabled[] = { - {"filter", features::kFilterNameOneEuro}}; - -const FeatureEntry::FeatureVariation kFilteringPredictionFeatureVariations[] = { - {features::kFilterNameEmpty, kFilteringPredictionEmptyFilterEnabled, - std::size(kFilteringPredictionEmptyFilterEnabled), nullptr}, - {features::kFilterNameOneEuro, kFilteringPredictionOneEuroFilterEnabled, - std::size(kFilteringPredictionOneEuroFilterEnabled), nullptr}}; - #if BUILDFLAG(IS_ANDROID) const FeatureEntry::FeatureParam kTabGroupsContinuationAndroid_LowEndSupport[] = { @@ -6663,20 +6650,6 @@ flag_descriptions::kDropInputEventsBeforeFirstPaintDescription, kOsAll, FEATURE_VALUE_TYPE(blink::features::kDropInputEventsBeforeFirstPaint)}, - {"enable-resampling-input-events", - flag_descriptions::kEnableResamplingInputEventsName, - flag_descriptions::kEnableResamplingInputEventsDescription, kOsAll, - FEATURE_WITH_PARAMS_VALUE_TYPE(blink::features::kResamplingInputEvents, - kResamplingInputEventsFeatureVariations, - "ResamplingInputEvents")}, - - {"enable-resampling-scroll-events", - flag_descriptions::kEnableResamplingScrollEventsName, - flag_descriptions::kEnableResamplingScrollEventsDescription, kOsAll, - FEATURE_WITH_PARAMS_VALUE_TYPE(blink::features::kResamplingScrollEvents, - kResamplingInputEventsFeatureVariations, - "ResamplingScrollEvents")}, - // Should only be available if kResamplingScrollEvents is on, and using // linear resampling. {"enable-resampling-scroll-events-experimental-prediction", @@ -6689,13 +6662,6 @@ kResamplingScrollEventsExperimentalPredictionVariations, "ResamplingScrollEventsExperimentalLatency")}, - {"enable-filtering-scroll-events", - flag_descriptions::kFilteringScrollPredictionName, - flag_descriptions::kFilteringScrollPredictionDescription, kOsAll, - FEATURE_WITH_PARAMS_VALUE_TYPE(blink::features::kFilteringScrollPrediction, - kFilteringPredictionFeatureVariations, - "FilteringScrollPrediction")}, - #if BUILDFLAG(IS_CHROMEOS_ASH) {"enable-vaapi-jpeg-image-decode-acceleration", flag_descriptions::kVaapiJpegImageDecodeAccelerationName,
diff --git a/chrome/browser/android/foreign_session_helper.cc b/chrome/browser/android/foreign_session_helper.cc index 3f9742be..5acbcc3f 100644 --- a/chrome/browser/android/foreign_session_helper.cc +++ b/chrome/browser/android/foreign_session_helper.cc
@@ -9,15 +9,12 @@ #include "base/android/jni_string.h" #include "base/functional/bind.h" -#include "chrome/android/chrome_jni_headers/ForeignSessionHelper_jni.h" #include "chrome/browser/android/tab_android.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile_android.h" +#include "chrome/browser/recent_tabs/jni_headers/ForeignSessionHelper_jni.h" #include "chrome/browser/sessions/session_restore.h" #include "chrome/browser/sync/session_sync_service_factory.h" #include "chrome/browser/sync/sync_service_factory.h" -#include "chrome/browser/ui/android/tab_model/tab_model.h" -#include "chrome/browser/ui/android/tab_model/tab_model_list.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "components/prefs/pref_service.h" @@ -31,13 +28,13 @@ #include "content/public/browser/web_contents.h" #include "url/android/gurl_android.h" +using base::android::AttachCurrentThread; +using base::android::ConvertJavaStringToUTF8; +using base::android::ConvertUTF16ToJavaString; +using base::android::ConvertUTF8ToJavaString; using base::android::JavaParamRef; using base::android::ScopedJavaGlobalRef; using base::android::ScopedJavaLocalRef; -using base::android::AttachCurrentThread; -using base::android::ConvertUTF16ToJavaString; -using base::android::ConvertUTF8ToJavaString; -using base::android::ConvertJavaStringToUTF8; using sync_sessions::OpenTabsUIDelegate; using sync_sessions::SyncedSession; @@ -48,31 +45,35 @@ SessionSyncServiceFactory::GetInstance()->GetForProfile(profile); // Only return the delegate if it exists. - if (!service) - return NULL; + if (!service) { + return nullptr; + } return service->GetOpenTabsUIDelegate(); } bool ShouldSkipTab(const sessions::SessionTab& session_tab) { - if (session_tab.navigations.empty()) - return true; + if (session_tab.navigations.empty()) { + return true; + } - int selected_index = session_tab.normalized_navigation_index(); - const sessions::SerializedNavigationEntry& current_navigation = - session_tab.navigations.at(selected_index); + int selected_index = session_tab.normalized_navigation_index(); + const sessions::SerializedNavigationEntry& current_navigation = + session_tab.navigations.at(selected_index); - if (current_navigation.virtual_url().is_empty()) - return true; + if (current_navigation.virtual_url().is_empty()) { + return true; + } - return false; + return false; } bool ShouldSkipWindow(const sessions::SessionWindow& window) { for (const auto& tab_ptr : window.tabs) { const sessions::SessionTab& session_tab = *(tab_ptr.get()); - if (!ShouldSkipTab(session_tab)) + if (!ShouldSkipTab(session_tab)) { return false; + } } return true; } @@ -80,8 +81,9 @@ bool ShouldSkipSession(const SyncedSession& session) { for (const auto& window_pair : session.windows) { const sessions::SessionWindow& window = window_pair.second->wrapped_window; - if (!ShouldSkipWindow(window)) + if (!ShouldSkipWindow(window)) { return false; + } } return true; } @@ -112,8 +114,9 @@ for (const auto& tab_ptr : window.tabs) { const sessions::SessionTab& session_tab = *(tab_ptr.get()); - if (ShouldSkipTab(session_tab)) + if (ShouldSkipTab(session_tab)) { return; + } JNI_ForeignSessionHelper_CopyTabToJava(env, session_tab, j_window); } @@ -126,8 +129,9 @@ for (const auto& window_pair : session.windows) { const sessions::SessionWindow& window = window_pair.second->wrapped_window; - if (ShouldSkipWindow(window)) + if (ShouldSkipWindow(window)) { continue; + } ScopedJavaLocalRef<jobject> last_pushed_window; last_pushed_window.Reset(Java_ForeignSessionHelper_pushWindow( @@ -142,8 +146,8 @@ static jlong JNI_ForeignSessionHelper_Init( JNIEnv* env, const JavaParamRef<jobject>& profile) { - ForeignSessionHelper* foreign_session_helper = new ForeignSessionHelper( - ProfileAndroid::FromProfileAndroid(profile)); + ForeignSessionHelper* foreign_session_helper = + new ForeignSessionHelper(ProfileAndroid::FromProfileAndroid(profile)); return reinterpret_cast<intptr_t>(foreign_session_helper); } @@ -163,8 +167,7 @@ } } -ForeignSessionHelper::~ForeignSessionHelper() { -} +ForeignSessionHelper::~ForeignSessionHelper() = default; void ForeignSessionHelper::Destroy(JNIEnv* env) { delete this; @@ -178,8 +181,9 @@ void ForeignSessionHelper::TriggerSessionSync(JNIEnv* env) { syncer::SyncService* service = SyncServiceFactory::GetForProfile(profile_); - if (!service) + if (!service) { return; + } service->TriggerRefresh({syncer::SESSIONS}); } @@ -191,8 +195,9 @@ } void ForeignSessionHelper::FireForeignSessionCallback() { - if (callback_.is_null()) + if (callback_.is_null()) { return; + } JNIEnv* env = AttachCurrentThread(); Java_ForeignSessionCallback_onUpdated(env, callback_); @@ -202,12 +207,14 @@ JNIEnv* env, const JavaParamRef<jobject>& result) { OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(profile_); - if (!open_tabs) + if (!open_tabs) { return false; + } std::vector<const SyncedSession*> sessions; - if (!open_tabs->GetAllForeignSessions(&sessions)) + if (!open_tabs->GetAllForeignSessions(&sessions)) { return false; + } // Use a pref to keep track of sessions that were collapsed by the user. // To prevent the pref from accumulating stale sessions, clear it each time @@ -223,14 +230,16 @@ // Note: we don't own the SyncedSessions themselves. for (size_t i = 0; i < sessions.size(); ++i) { const SyncedSession& session = *(sessions[i]); - if (ShouldSkipSession(session)) + if (ShouldSkipSession(session)) { continue; + } const bool is_collapsed = (collapsed_sessions.Find(session.GetSessionTag()) != nullptr); - if (is_collapsed) + if (is_collapsed) { pref_collapsed_sessions.Set(session.GetSessionTag(), true); + } last_pushed_session.Reset(Java_ForeignSessionHelper_pushSession( env, result, ConvertUTF8ToJavaString(env, session.GetSessionTag()), @@ -275,13 +284,13 @@ if (!tab_android) return false; content::WebContents* web_contents = tab_android->web_contents(); - if (!web_contents) + if (!web_contents) { return false; + } WindowOpenDisposition disposition = static_cast<WindowOpenDisposition>(j_disposition); - SessionRestore::RestoreForeignSessionTab(web_contents, - *session_tab, + SessionRestore::RestoreForeignSessionTab(web_contents, *session_tab, disposition); return true; @@ -291,16 +300,18 @@ JNIEnv* env, const JavaParamRef<jstring>& session_tag) { OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(profile_); - if (open_tabs) + if (open_tabs) { open_tabs->DeleteForeignSession(ConvertJavaStringToUTF8(env, session_tag)); + } } void ForeignSessionHelper::SetInvalidationsForSessionsEnabled( JNIEnv* env, jboolean enabled) { syncer::SyncService* service = SyncServiceFactory::GetForProfile(profile_); - if (!service) + if (!service) { return; + } service->SetInvalidationsForSessionsEnabled(enabled); }
diff --git a/chrome/browser/android/foreign_session_helper.h b/chrome/browser/android/foreign_session_helper.h index e4a5e318..a128230a 100644 --- a/chrome/browser/android/foreign_session_helper.h +++ b/chrome/browser/android/foreign_session_helper.h
@@ -14,6 +14,8 @@ using base::android::ScopedJavaLocalRef; +// TODO(crbug.com/1426935): Move this class to chrome/browser/recent_tabs module +// once dependency issues have been resolved. class ForeignSessionHelper { public: explicit ForeignSessionHelper(Profile* profile); @@ -41,9 +43,7 @@ void DeleteForeignSession( JNIEnv* env, const base::android::JavaParamRef<jstring>& session_tag); - void SetInvalidationsForSessionsEnabled( - JNIEnv* env, - jboolean enabled); + void SetInvalidationsForSessionsEnabled(JNIEnv* env, jboolean enabled); private: // Fires |callback_| if it is not null.
diff --git a/chrome/browser/android/metrics/BUILD.gn b/chrome/browser/android/metrics/BUILD.gn index 8d739a9..c8d7a77 100644 --- a/chrome/browser/android/metrics/BUILD.gn +++ b/chrome/browser/android/metrics/BUILD.gn
@@ -51,6 +51,7 @@ "//chrome/browser/signin/services/android:java", "//chrome/browser/tab:java", "//chrome/test/android:chrome_java_integration_test_support", + "//components/browsing_data/core:java", "//components/metrics:metrics_java", "//content/public/test/android:content_java_test_support", "//third_party/android_support_test_runner:rules_java",
diff --git a/chrome/browser/android/webapk/webapk_install_service.cc b/chrome/browser/android/webapk/webapk_install_service.cc index 49ef703..63c4402 100644 --- a/chrome/browser/android/webapk/webapk_install_service.cc +++ b/chrome/browser/android/webapk/webapk_install_service.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/android/jni_android.h" +#include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/feature_list.h" #include "base/files/file_path.h" @@ -141,6 +142,7 @@ const SkBitmap& primary_icon, bool is_primary_icon_maskable, webapps::WebApkInstallResult result, + std::unique_ptr<std::string> serialized_proto, bool relax_updates, const std::string& webapk_package_name) { installs_.erase(shortcut_info.manifest_url); @@ -149,7 +151,8 @@ HandleFinishInstallNotifications( GetNotificationId(shortcut_info.manifest_url, shortcut_info.manifest_id), shortcut_info.url, shortcut_info.short_name, primary_icon, - is_primary_icon_maskable, result, webapk_package_name); + is_primary_icon_maskable, result, std::move(serialized_proto), + webapk_package_name); if (base::FeatureList::IsEnabled( webapps::features::kWebApkInstallFailureNotification)) { @@ -182,13 +185,15 @@ bool is_primary_icon_maskable, ServiceInstallFinishCallback finish_callback, webapps::WebApkInstallResult result, + std::unique_ptr<std::string> serialized_proto, bool relax_updates, const std::string& webapk_package_name) { installs_.erase(manifest_url); install_ids_.erase(manifest_id); HandleFinishInstallNotifications( GetNotificationId(manifest_url, manifest_id), url, short_name, - primary_icon, is_primary_icon_maskable, result, webapk_package_name); + primary_icon, is_primary_icon_maskable, result, + std::move(serialized_proto), webapk_package_name); std::move(finish_callback).Run(result); } @@ -200,6 +205,7 @@ const SkBitmap& primary_icon, bool is_primary_icon_maskable, webapps::WebApkInstallResult result, + std::unique_ptr<std::string> serialized_proto, const std::string& webapk_package_name) { if (result == webapps::WebApkInstallResult::SUCCESS) { ShowInstalledNotification(notification_id, short_name, url, primary_icon, @@ -209,7 +215,7 @@ result != webapps::WebApkInstallResult::PROBABLE_FAILURE) { ShowInstallFailedNotification(notification_id, short_name, url, primary_icon, is_primary_icon_maskable, - result); + result, std::move(serialized_proto)); } else { JNIEnv* env = base::android::AttachCurrentThread(); base::android::ScopedJavaLocalRef<jstring> java_notification_id = @@ -272,7 +278,8 @@ const GURL& url, const SkBitmap& primary_icon, bool is_primary_icon_maskable, - webapps::WebApkInstallResult result) { + webapps::WebApkInstallResult result, + std::unique_ptr<std::string> serialized_proto) { JNIEnv* env = base::android::AttachCurrentThread(); base::android::ScopedJavaLocalRef<jstring> java_notification_id = base::android::ConvertUTF8ToJavaString(env, notification_id.spec()); @@ -282,8 +289,11 @@ base::android::ConvertUTF8ToJavaString(env, url.spec()); base::android::ScopedJavaLocalRef<jobject> java_primary_icon = gfx::ConvertToJavaBitmap(primary_icon); + base::android::ScopedJavaLocalRef<jbyteArray> java_serialized_proto = + base::android::ToJavaByteArray(env, *serialized_proto); Java_WebApkInstallService_showInstallFailedNotification( env, java_notification_id, java_short_name, java_url, java_primary_icon, - is_primary_icon_maskable, static_cast<int>(result)); + is_primary_icon_maskable, static_cast<int>(result), + java_serialized_proto); }
diff --git a/chrome/browser/android/webapk/webapk_install_service.h b/chrome/browser/android/webapk/webapk_install_service.h index 0cae1c69..7501c93 100644 --- a/chrome/browser/android/webapk/webapk_install_service.h +++ b/chrome/browser/android/webapk/webapk_install_service.h
@@ -42,11 +42,14 @@ // Called when the creation/updating of a WebAPK is finished or failed. // Parameters: // - the result of the installation. + // - serialized proto for the installation, if exist. // - true if Chrome received a "request updates less frequently" directive. // from the WebAPK server. // - the package name of the WebAPK. - using FinishCallback = base::OnceCallback< - void(webapps::WebApkInstallResult, bool, const std::string&)>; + using FinishCallback = base::OnceCallback<void(webapps::WebApkInstallResult, + std::unique_ptr<std::string>, + bool, + const std::string&)>; // Called when the installation of a WebAPK that was scheduled by the // WebApkInstallCoordinatorService finished or failed to pass the result back @@ -103,32 +106,37 @@ const SkBitmap& primary_icon, bool is_priamry_icon_maskable, webapps::WebApkInstallResult result, + std::unique_ptr<std::string> serialized_webapk, bool relax_updates, const std::string& webapk_package_name); // Called once the install scheduled from the service completed or failed. // Triggers the callback to propagate the |WebApkInstallResult| to the // scheduling Client. - void OnFinishedInstallForService(const GURL& manifest_url, - const GURL& manifest_id, - const GURL& url, - const std::u16string& short_name, - const SkBitmap& primary_icon, - bool is_primary_icon_maskable, - ServiceInstallFinishCallback done_callback, - webapps::WebApkInstallResult result, - bool relax_updates, - const std::string& webapk_package_name); + void OnFinishedInstallForService( + const GURL& manifest_url, + const GURL& manifest_id, + const GURL& url, + const std::u16string& short_name, + const SkBitmap& primary_icon, + bool is_primary_icon_maskable, + ServiceInstallFinishCallback done_callback, + webapps::WebApkInstallResult result, + std::unique_ptr<std::string> serialized_webapk, + bool relax_updates, + const std::string& webapk_package_name); // Removes current notifications about an ongoing install and adds a // installed-notification if the installation was successful. - void HandleFinishInstallNotifications(const GURL& manifest_url, - const GURL& url, - const std::u16string& short_name, - const SkBitmap& primary_icon, - bool is_primary_icon_maskable, - webapps::WebApkInstallResult result, - const std::string& webapk_package_name); + void HandleFinishInstallNotifications( + const GURL& manifest_url, + const GURL& url, + const std::u16string& short_name, + const SkBitmap& primary_icon, + bool is_primary_icon_maskable, + webapps::WebApkInstallResult result, + std::unique_ptr<std::string> serialized_webapk, + const std::string& webapk_package_name); // Shows a notification that an install is in progress. static void ShowInstallInProgressNotification( @@ -153,7 +161,8 @@ const GURL& url, const SkBitmap& primary_icon, bool is_primary_icon_maskable, - webapps::WebApkInstallResult result); + webapps::WebApkInstallResult result, + std::unique_ptr<std::string> serialized_webapk); raw_ptr<content::BrowserContext> browser_context_;
diff --git a/chrome/browser/android/webapk/webapk_installer.cc b/chrome/browser/android/webapk/webapk_installer.cc index f969c075b..45ab9d2 100644 --- a/chrome/browser/android/webapk/webapk_installer.cc +++ b/chrome/browser/android/webapk/webapk_installer.cc
@@ -267,7 +267,10 @@ void WebApkInstaller::OnResult(webapps::WebApkInstallResult result) { weak_ptr_factory_.InvalidateWeakPtrs(); - std::move(finish_callback_).Run(result, relax_updates_, webapk_package_); + + std::move(finish_callback_) + .Run(result, std::move(serialized_webapk_), relax_updates_, + webapk_package_); if (task_type_ == WebApkInstaller::INSTALL) { if (result == webapps::WebApkInstallResult::SUCCESS) { @@ -463,7 +466,7 @@ } )"); - SendRequest(traffic_annotation_update_request, std::move(update_request)); + SendRequest(traffic_annotation_update_request, *update_request); } void WebApkInstaller::OnURLLoaderComplete( @@ -565,8 +568,7 @@ } )"); - SendRequest(traffic_annotation_install_from_service, - std::move(serialized_webapk_)); + SendRequest(traffic_annotation_install_from_service, *serialized_webapk_); return; } @@ -598,6 +600,22 @@ DCHECK(!install_from_webapk_service_); DCHECK(install_shortcut_info_); + // Using empty string for |primary_icon_data| and |splash_icon_data| here + // because in WebApk installs, we are using the icon data from |hashes|. + webapps::BuildProto( + *install_shortcut_info_, install_shortcut_info_->manifest_id, + std::string() /* primary_icon_data */, is_primary_icon_maskable_, + std::string() /* splash_icon_data */, "" /* package_name */, + "" /* version */, std::move(*hashes), false /* is_manifest_stale */, + false /* is_app_identity_update_supported */, + base::BindOnce(&WebApkInstaller::OnInstallProtoBuilt, + weak_ptr_factory_.GetWeakPtr())); +} + +void WebApkInstaller::OnInstallProtoBuilt( + std::unique_ptr<std::string> serialized_proto) { + serialized_webapk_ = std::move(serialized_proto); + net::NetworkTrafficAnnotationTag traffic_annotation_install_from_chrome = net::DefineNetworkTrafficAnnotation("webapk_create", R"( semantics { @@ -642,22 +660,12 @@ } )"); - // Using empty string for |primary_icon_data| and |splash_icon_data| here - // because in WebApk installs, we are using the icon data from |hashes|. - webapps::BuildProto( - *install_shortcut_info_, install_shortcut_info_->manifest_id, - std::string() /* primary_icon_data */, is_primary_icon_maskable_, - std::string() /* splash_icon_data */, "" /* package_name */, - "" /* version */, std::move(*hashes), false /* is_manifest_stale */, - false /* is_app_identity_update_supported */, - base::BindOnce(&WebApkInstaller::SendRequest, - weak_ptr_factory_.GetWeakPtr(), - traffic_annotation_install_from_chrome)); + SendRequest(traffic_annotation_install_from_chrome, *serialized_webapk_); } void WebApkInstaller::SendRequest( const net::NetworkTrafficAnnotationTag& traffic_annotation, - std::unique_ptr<std::string> serialized_proto) { + const std::string& serialized_proto) { DCHECK(server_url_.is_valid()); timer_.Start( @@ -672,7 +680,7 @@ request->credentials_mode = network::mojom::CredentialsMode::kOmit; loader_ = network::SimpleURLLoader::Create(std::move(request), traffic_annotation); - loader_->AttachStringForUpload(*serialized_proto, kProtoMimeType); + loader_->AttachStringForUpload(serialized_proto, kProtoMimeType); loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( GetURLLoaderFactory(browser_context_), base::BindOnce(&WebApkInstaller::OnURLLoaderComplete,
diff --git a/chrome/browser/android/webapk/webapk_installer.h b/chrome/browser/android/webapk/webapk_installer.h index 8d1bf1e..26bbc65 100644 --- a/chrome/browser/android/webapk/webapk_installer.h +++ b/chrome/browser/android/webapk/webapk_installer.h
@@ -226,11 +226,14 @@ absl::optional<std::map<std::string, webapps::WebApkIconHasher::Icon>> hashes); + // Called with the serialized proto for the WebAPK install. + void OnInstallProtoBuilt(std::unique_ptr<std::string> serialized_proto); + // Sends a request to WebAPK server to create/update WebAPK. During a // successful request the WebAPK server responds with a token to send to // Google Play. void SendRequest(const net::NetworkTrafficAnnotationTag& traffic_annotation, - std::unique_ptr<std::string> serialized_proto); + const std::string& serialized_proto); // Returns the WebAPK server URL based on the command line. GURL GetServerUrl();
diff --git a/chrome/browser/android/webapk/webapk_installer_unittest.cc b/chrome/browser/android/webapk/webapk_installer_unittest.cc index 17c6e27..083b9908 100644 --- a/chrome/browser/android/webapk/webapk_installer_unittest.cc +++ b/chrome/browser/android/webapk/webapk_installer_unittest.cc
@@ -166,6 +166,7 @@ private: void OnCompleted(webapps::WebApkInstallResult result, + std::unique_ptr<std::string> serialized_webapk, bool relax_updates, const std::string& webapk_package) { result_ = result;
diff --git a/chrome/browser/android/webapk/webapk_update_manager.cc b/chrome/browser/android/webapk/webapk_update_manager.cc index 8a8b227..85a4711 100644 --- a/chrome/browser/android/webapk/webapk_update_manager.cc +++ b/chrome/browser/android/webapk/webapk_update_manager.cc
@@ -40,6 +40,7 @@ // Called after the update either succeeds or fails. void OnUpdated(const JavaRef<jobject>& java_callback, webapps::WebApkInstallResult result, + std::unique_ptr<std::string> serialized_proto, bool relax_updates, const std::string& webapk_package) { JNIEnv* env = base::android::AttachCurrentThread(); @@ -245,6 +246,7 @@ FROM_HERE, base::BindOnce(&OnUpdated, callback_ref, webapps::WebApkInstallResult::FAILURE, + nullptr /* serialized_proto */, false /* relax_updates */, "" /* webapk_package */)); return; }
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index 7cca218..8463c92 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm
@@ -208,7 +208,7 @@ Browser* CreateBrowser(Profile* profile) { // Closes the first run if we open a new window. if (auto* fre_service = - FirstRunServiceFactory::GetForBrowserContext(profile)) { + FirstRunServiceFactory::GetForBrowserContextIfExists(profile)) { fre_service->FinishFirstRunWithoutResumeTask(); } @@ -647,7 +647,7 @@ // in the first run experience. if (auto* profile = [self lastProfileIfLoaded]) { if (auto* fre_service = - FirstRunServiceFactory::GetForBrowserContext(profile)) { + FirstRunServiceFactory::GetForBrowserContextIfExists(profile)) { fre_service->FinishFirstRunWithoutResumeTask(); } }
diff --git a/chrome/browser/ash/account_manager/account_manager_util.cc b/chrome/browser/ash/account_manager/account_manager_util.cc index df94662..1f7d26a 100644 --- a/chrome/browser/ash/account_manager/account_manager_util.cc +++ b/chrome/browser/ash/account_manager/account_manager_util.cc
@@ -63,8 +63,7 @@ cryptohome_root_dir, g_browser_process->system_network_context_manager() ->GetSharedURLLoaderFactory(), - base::BindRepeating(&DelayNetworkCall, - base::Milliseconds(kDefaultNetworkRetryDelayMS)), + base::BindRepeating(&DelayNetworkCall), std::move(initialization_callback)); crosapi::AccountManagerMojoService* account_manager_mojo_service =
diff --git a/chrome/browser/ash/crosapi/browser_data_back_migrator.cc b/chrome/browser/ash/crosapi/browser_data_back_migrator.cc index e06655c..38c20fa 100644 --- a/chrome/browser/ash/crosapi/browser_data_back_migrator.cc +++ b/chrome/browser/ash/crosapi/browser_data_back_migrator.cc
@@ -100,6 +100,18 @@ browser_data_back_migrator_metrics::RecordNumberOfLacrosSecondaryProfiles( ash_profile_dir_); + // Get the forward migration timestamp, record the delta and then clear the + // timestamp right away. This prevents the scenario in which the time is + // recorded, then backward migration fails and is retried and then the time is + // recorded again. + auto forward_migration_completion_time = + crosapi::browser_util::GetProfileMigrationCompletionTimeForUser( + local_state_, user_id_hash_); + browser_data_back_migrator_metrics::RecordBackwardMigrationTimeDelta( + forward_migration_completion_time); + crosapi::browser_util::ClearProfileMigrationCompletionTimeForUser( + local_state_, user_id_hash_); + running_ = true; migration_start_time_ = base::TimeTicks::Now();
diff --git a/chrome/browser/ash/crosapi/browser_data_back_migrator_metrics.cc b/chrome/browser/ash/crosapi/browser_data_back_migrator_metrics.cc index 6c5cbe1..5f694fc7 100644 --- a/chrome/browser/ash/crosapi/browser_data_back_migrator_metrics.cc +++ b/chrome/browser/ash/crosapi/browser_data_back_migrator_metrics.cc
@@ -78,6 +78,21 @@ number_of_secondary_profiles); } +void RecordBackwardMigrationTimeDelta( + absl::optional<base::Time> forward_migration_completion_time) { + if (!forward_migration_completion_time.has_value()) { + VLOG(1) << "Forward migration completion time not found."; + return; + } + + base::TimeDelta time_delta = + base::Time::Now() - forward_migration_completion_time.value(); + + base::UmaHistogramCustomTimes( + browser_data_back_migrator_metrics::kElapsedTimeBetweenDataMigrations, + time_delta, base::Minutes(1), base::Days(24), 100); +} + std::string TaskStatusToString( BrowserDataBackMigrator::TaskStatus task_status) { switch (task_status) {
diff --git a/chrome/browser/ash/crosapi/browser_data_back_migrator_metrics.h b/chrome/browser/ash/crosapi/browser_data_back_migrator_metrics.h index d93fd55..780b9f1 100644 --- a/chrome/browser/ash/crosapi/browser_data_back_migrator_metrics.h +++ b/chrome/browser/ash/crosapi/browser_data_back_migrator_metrics.h
@@ -15,6 +15,8 @@ "Ash.BrowserDataBackMigrator.SuccessfulMigrationTime"; constexpr char kNumberOfLacrosSecondaryProfilesUMA[] = "Ash.BrowserDataBackMigrator.NumberOfLacrosSecondaryProfiles"; +constexpr char kElapsedTimeBetweenDataMigrations[] = + "Ash.BrowserDataBackMigrator.ElapsedTimeBetweenDataMigrations"; constexpr char kPreMigrationCleanUpTimeUMA[] = "Ash.BrowserDataBackMigrator.ElapsedTimePreMigrationCleanUp"; @@ -48,6 +50,11 @@ void RecordNumberOfLacrosSecondaryProfiles( const base::FilePath& ash_profile_dir); +// Records `kElapsedTimeBetweenDataMigrations` with the amount of time between +// successfully completing forward migration and starting backward migration. +void RecordBackwardMigrationTimeDelta( + absl::optional<base::Time> forward_migration_completion_time); + // Converts `TaskStatus` to string. std::string TaskStatusToString(BrowserDataBackMigrator::TaskStatus task_status);
diff --git a/chrome/browser/ash/crosapi/browser_data_back_migrator_metrics_unittest.cc b/chrome/browser/ash/crosapi/browser_data_back_migrator_metrics_unittest.cc index 7975aa4..54b55107 100644 --- a/chrome/browser/ash/crosapi/browser_data_back_migrator_metrics_unittest.cc +++ b/chrome/browser/ash/crosapi/browser_data_back_migrator_metrics_unittest.cc
@@ -187,4 +187,18 @@ browser_data_back_migrator_metrics::IsSecondaryProfileDirectory("")); } +TEST(BrowserDataBackMigratorMetricsTest, RecordBackwardMigrationTimeDelta) { + base::HistogramTester histogram_tester; + + browser_data_back_migrator_metrics::RecordBackwardMigrationTimeDelta( + absl::nullopt); + histogram_tester.ExpectTotalCount( + browser_data_back_migrator_metrics::kElapsedTimeBetweenDataMigrations, 0); + + browser_data_back_migrator_metrics::RecordBackwardMigrationTimeDelta( + base::Time::UnixEpoch()); + histogram_tester.ExpectTotalCount( + browser_data_back_migrator_metrics::kElapsedTimeBetweenDataMigrations, 1); +} + } // namespace ash
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator.cc b/chrome/browser/ash/crosapi/browser_data_migrator.cc index ff35b74..6b5afc7 100644 --- a/chrome/browser/ash/crosapi/browser_data_migrator.cc +++ b/chrome/browser/ash/crosapi/browser_data_migrator.cc
@@ -312,6 +312,8 @@ crosapi::browser_util::ClearProfileMigrationCompletedForUser(local_state, user_id_hash); + crosapi::browser_util::ClearProfileMigrationCompletionTimeForUser( + local_state, user_id_hash); local_state->CommitPendingWrite(); @@ -435,6 +437,13 @@ crosapi::browser_util::SetProfileMigrationCompletedForUser( local_state_, user_id_hash_, mode); + // Profile migration is marked as completed both when the migration is + // performed (here) and for a new user without actually performing data + // migration (`ProfileImpl::OnLocaleReady`). The timestamp of completed + // migration is only recorded when the migration is actually performed. + crosapi::browser_util::SetProfileMigrationCompletionTimeForUser( + local_state_, user_id_hash_); + ClearMigrationAttemptCountForUser(local_state_, user_id_hash_); } // If migration has failed or skipped, we silently relaunch ash and send them
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc index 0a8a054..58cecc41f 100644 --- a/chrome/browser/ash/crosapi/browser_util.cc +++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -14,6 +14,7 @@ #include "base/containers/flat_map.h" #include "base/files/file_util.h" #include "base/json/json_reader.h" +#include "base/json/values_util.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" @@ -290,6 +291,8 @@ // This pref is to record whether the user clicks "Go to files" button // on error page of the data migration. const char kGotoFilesPref[] = "lacros.goto_files"; +const char kProfileMigrationCompletionTimeForUserPref[] = + "lacros.profile_migration_completion_time_for_user"; void RegisterProfilePrefs(PrefRegistrySimple* registry) { registry->RegisterBooleanPref(kLaunchOnLoginPref, /*default_value=*/false); @@ -306,6 +309,8 @@ registry->RegisterDictionaryPref( kProfileDataBackwardMigrationCompletedForUserPref, base::Value::Dict()); registry->RegisterListPref(kGotoFilesPref); + registry->RegisterDictionaryPref(kProfileMigrationCompletionTimeForUserPref, + base::Value::Dict()); } base::FilePath GetUserDataDir() { @@ -1083,6 +1088,38 @@ } } +void SetProfileMigrationCompletionTimeForUser(PrefService* local_state, + const std::string& user_id_hash) { + ScopedDictPrefUpdate update(local_state, + kProfileMigrationCompletionTimeForUserPref); + update->Set(user_id_hash, base::TimeToValue(base::Time::Now())); +} + +absl::optional<base::Time> GetProfileMigrationCompletionTimeForUser( + PrefService* local_state, + const std::string& user_id_hash) { + const auto* pref = + local_state->FindPreference(kProfileMigrationCompletionTimeForUserPref); + + if (!pref) { + return absl::nullopt; + } + + const base::Value* value = pref->GetValue(); + DCHECK(value->is_dict()); + + return base::ValueToTime(value->GetDict().Find(user_id_hash)); +} + +void ClearProfileMigrationCompletionTimeForUser( + PrefService* local_state, + const std::string& user_id_hash) { + ScopedDictPrefUpdate update(local_state, + kProfileMigrationCompletionTimeForUserPref); + base::Value::Dict& dict = update.Get(); + dict.Remove(user_id_hash); +} + void SetProfileDataBackwardMigrationCompletedForUser( PrefService* local_state, const std::string& user_id_hash) {
diff --git a/chrome/browser/ash/crosapi/browser_util.h b/chrome/browser/ash/crosapi/browser_util.h index 156b9501..84fbb521 100644 --- a/chrome/browser/ash/crosapi/browser_util.h +++ b/chrome/browser/ash/crosapi/browser_util.h
@@ -10,6 +10,7 @@ #include "base/auto_reset.h" #include "base/feature_list.h" #include "base/strings/string_piece.h" +#include "base/time/time.h" #include "chromeos/ash/components/standalone_browser/lacros_availability.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -425,19 +426,38 @@ const std::string& user_id_hash, MigrationMode mode); -// Sets the value of `kProfileMigrationCompletedForUser1Pref` to be true -// for the user identified by `user_id_hash`. +// Sets the value of `kProfileMigrationCompletedForUserPref` or +// `kProfileMoveMigrationCompletedForUserPref` to be true for the user +// identified by `user_id_hash`, depending on `mode`. void SetProfileMigrationCompletedForUser(PrefService* local_state, const std::string& user_id_hash, MigrationMode mode); -// Clears the value of `kProfileMigrationCompletedForUser1Pref` for user -// identified by `user_id_hash`. +// Clears the values of `kProfileMigrationCompletedForUserPref` and +// `kProfileMoveMigrationCompletedForUserPref` prefs for user identified by +// `user_id_hash`: void ClearProfileMigrationCompletedForUser(PrefService* local_state, const std::string& user_id_hash); +// Sets the value of `kProfileMigrationCompletionTimeForUserPref` for the user +// identified by `user_id_hash` to the current time. +void SetProfileMigrationCompletionTimeForUser(PrefService* local_state, + const std::string& user_id_hash); + +// Gets the value of `kProfileMigrationCompletionTimeForUserPref` for the user +// identified by `user_id_hash`. +absl::optional<base::Time> GetProfileMigrationCompletionTimeForUser( + PrefService* local_state, + const std::string& user_id_hash); + +// Clears the value of `kProfileMigrationCompletionTimeForUserPref` for the user +// identified by `user_id_hash`. +void ClearProfileMigrationCompletionTimeForUser( + PrefService* local_state, + const std::string& user_id_hash); + // Sets the value of `kProfileDataBackwardMigrationCompletedForUserPref` for the -// user identified by `user_id_hash`; +// user identified by `user_id_hash`. void SetProfileDataBackwardMigrationCompletedForUser( PrefService* local_state, const std::string& user_id_hash);
diff --git a/chrome/browser/ash/customization/customization_document.cc b/chrome/browser/ash/customization/customization_document.cc index 7a7b321..a8b44b7 100644 --- a/chrome/browser/ash/customization/customization_document.cc +++ b/chrome/browser/ash/customization/customization_document.cc
@@ -432,7 +432,7 @@ const std::string& StartupCustomizationDocument::initial_locale_default() const { - DCHECK(configured_locales_.size() > 0); + DCHECK_GT(configured_locales_.size(), 0UL); return configured_locales_.front(); } @@ -484,7 +484,6 @@ : CustomizationDocument(kAcceptedManifestVersion), num_retries_(0), load_started_(false), - network_delay_(base::Milliseconds(kDefaultNetworkRetryDelayMS)), apply_tasks_started_(0), apply_tasks_finished_(0), apply_tasks_success_(0) {} @@ -492,14 +491,13 @@ ServicesCustomizationDocument::ServicesCustomizationDocument( const std::string& manifest) : CustomizationDocument(kAcceptedManifestVersion), - network_delay_(base::Milliseconds(kDefaultNetworkRetryDelayMS)), apply_tasks_started_(0), apply_tasks_finished_(0), apply_tasks_success_(0) { LoadManifestFromString(manifest); } -ServicesCustomizationDocument::~ServicesCustomizationDocument() {} +ServicesCustomizationDocument::~ServicesCustomizationDocument() = default; // static ServicesCustomizationDocument* ServicesCustomizationDocument::GetInstance() { @@ -625,10 +623,16 @@ } void ServicesCustomizationDocument::StartFileFetch() { - DelayNetworkCall( - network_delay_, - base::BindOnce(&ServicesCustomizationDocument::DoStartFileFetch, - weak_ptr_factory_.GetWeakPtr())); + if (custom_network_delay_) { + DelayNetworkCallWithCustomDelay( + base::BindOnce(&ServicesCustomizationDocument::DoStartFileFetch, + weak_ptr_factory_.GetWeakPtr()), + custom_network_delay_.value()); + } else { + DelayNetworkCall( + base::BindOnce(&ServicesCustomizationDocument::DoStartFileFetch, + weak_ptr_factory_.GetWeakPtr())); + } } void ServicesCustomizationDocument::DoStartFileFetch() { @@ -850,7 +854,10 @@ scoped_refptr<network::SharedURLLoaderFactory> factory) { g_test_overrides = new CustomizationDocumentTestOverride; g_test_overrides->customization_document = new ServicesCustomizationDocument; - g_test_overrides->customization_document->network_delay_ = base::TimeDelta(); + // `base::TimeDelta()` means zero time delta - i.e. the request will be + // started immediately. + g_test_overrides->customization_document->custom_network_delay_ = + absl::make_optional(base::TimeDelta()); g_test_overrides->url_loader_factory = std::move(factory); }
diff --git a/chrome/browser/ash/customization/customization_document.h b/chrome/browser/ash/customization/customization_document.h index 18feb85..5b5547a 100644 --- a/chrome/browser/ash/customization/customization_document.h +++ b/chrome/browser/ash/customization/customization_document.h
@@ -304,8 +304,9 @@ // Manifest fetch is already in progress. bool load_started_; - // Delay between checks for network online state. - base::TimeDelta network_delay_; + // Delay between checks for network online state. If the optional is empty, + // the default value for delay is used. + absl::optional<base::TimeDelta> custom_network_delay_ = absl::nullopt; // Known external loaders. ExternalLoaders external_loaders_;
diff --git a/chrome/browser/ash/eche_app/eche_app_manager_factory.cc b/chrome/browser/ash/eche_app/eche_app_manager_factory.cc index 32512f6..bf08f5e 100644 --- a/chrome/browser/ash/eche_app/eche_app_manager_factory.cc +++ b/chrome/browser/ash/eche_app/eche_app_manager_factory.cc
@@ -11,6 +11,7 @@ #include "ash/shell.h" #include "ash/system/eche/eche_tray.h" #include "ash/webui/eche_app_ui/apps_access_manager_impl.h" +#include "ash/webui/eche_app_ui/apps_launch_info_provider.h" #include "ash/webui/eche_app_ui/eche_app_manager.h" #include "ash/webui/eche_app_ui/eche_tray_stream_status_observer.h" #include "ash/webui/eche_app_ui/eche_uid_provider.h" @@ -71,6 +72,7 @@ const absl::optional<int64_t>& user_id, const gfx::Image& icon, const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launch_info_provider, Profile* profile) { EcheAppManagerFactory::GetInstance()->SetLastLaunchedAppInfo( LaunchedAppInfo::Builder() @@ -79,6 +81,7 @@ .SetUserId(user_id) .SetIcon(icon) .SetPhoneName(phone_name) + .SetAppsLaunchInfoProvider(apps_launch_info_provider) .Build()); std::u16string url; // Use hash mark(#) to send params to webui so we don't need to reload the @@ -107,6 +110,8 @@ const auto gurl = GURL(url); return LaunchBubble(gurl, icon, visible_name, phone_name, + apps_launch_info_provider->GetConnectionStatusForUi(), + apps_launch_info_provider->entry_point(), base::BindOnce(&EnsureStreamClose, profile), base::BindRepeating(&StreamGoBack, profile)); } @@ -117,22 +122,26 @@ EcheAppManagerFactory::LaunchEcheApp( profile, absl::nullopt, last_launched_app_info->package_name(), last_launched_app_info->visible_name(), last_launched_app_info->user_id(), - last_launched_app_info->icon(), last_launched_app_info->phone_name()); + last_launched_app_info->icon(), last_launched_app_info->phone_name(), + last_launched_app_info->apps_launch_info_provider()); } } // namespace LaunchedAppInfo::~LaunchedAppInfo() = default; -LaunchedAppInfo::LaunchedAppInfo(const std::string& package_name, - const std::u16string& visible_name, - const absl::optional<int64_t>& user_id, - const gfx::Image& icon, - const std::u16string& phone_name) { +LaunchedAppInfo::LaunchedAppInfo( + const std::string& package_name, + const std::u16string& visible_name, + const absl::optional<int64_t>& user_id, + const gfx::Image& icon, + const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launch_info_provider) { package_name_ = package_name; visible_name_ = visible_name; user_id_ = user_id; icon_ = icon; phone_name_ = phone_name; + apps_launch_info_provider_ = apps_launch_info_provider; } LaunchedAppInfo::Builder::Builder() = default; @@ -200,9 +209,10 @@ const std::u16string& visible_name, const absl::optional<int64_t>& user_id, const gfx::Image& icon, - const std::u16string& phone_name) { + const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launch_info_provider) { LaunchWebApp(package_name, notification_id, visible_name, user_id, icon, - phone_name, profile); + phone_name, apps_launch_info_provider, profile); EcheAppManagerFactory::GetInstance() ->CloseConnectionOrLaunchErrorNotifications(); }
diff --git a/chrome/browser/ash/eche_app/eche_app_manager_factory.h b/chrome/browser/ash/eche_app/eche_app_manager_factory.h index cc5811c..b4fff45 100644 --- a/chrome/browser/ash/eche_app/eche_app_manager_factory.h +++ b/chrome/browser/ash/eche_app/eche_app_manager_factory.h
@@ -20,6 +20,7 @@ class EcheAppManager; class EcheAppNotificationController; class SystemInfo; +class AppsLaunchInfoProvider; class LaunchedAppInfo { public: @@ -29,8 +30,9 @@ ~Builder(); std::unique_ptr<LaunchedAppInfo> Build() { - return base::WrapUnique(new LaunchedAppInfo( - package_name_, visible_name_, user_id_, icon_, phone_name_)); + return base::WrapUnique(new LaunchedAppInfo(package_name_, visible_name_, + user_id_, icon_, phone_name_, + apps_launch_info_provider_)); } Builder& SetPackageName(const std::string& package_name) { package_name_ = package_name; @@ -57,12 +59,19 @@ return *this; } + Builder& SetAppsLaunchInfoProvider( + AppsLaunchInfoProvider* apps_launch_info_provider) { + apps_launch_info_provider_ = apps_launch_info_provider; + return *this; + } + private: std::string package_name_; std::u16string visible_name_; absl::optional<int64_t> user_id_; gfx::Image icon_; std::u16string phone_name_; + AppsLaunchInfoProvider* apps_launch_info_provider_; }; LaunchedAppInfo() = delete; @@ -75,13 +84,17 @@ absl::optional<int64_t> user_id() const { return user_id_; } gfx::Image icon() const { return icon_; } std::u16string phone_name() const { return phone_name_; } + AppsLaunchInfoProvider* apps_launch_info_provider() { + return apps_launch_info_provider_; + } protected: LaunchedAppInfo(const std::string& package_name, const std::u16string& visible_name, const absl::optional<int64_t>& user_id, const gfx::Image& icon, - const std::u16string& phone_name); + const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launch_info_provider); private: std::string package_name_; @@ -89,6 +102,7 @@ absl::optional<int64_t> user_id_; gfx::Image icon_; std::u16string phone_name_; + AppsLaunchInfoProvider* apps_launch_info_provider_; }; // Factory to create a single EcheAppManager. @@ -111,7 +125,8 @@ const std::u16string& visible_name, const absl::optional<int64_t>& user_id, const gfx::Image& icon, - const std::u16string& phone_name); + const std::u16string& phone_name, + AppsLaunchInfoProvider* apps_launch_info_provider); void SetLastLaunchedAppInfo( std::unique_ptr<LaunchedAppInfo> last_launched_app_info);
diff --git a/chrome/browser/ash/eche_app/eche_app_manager_factory_unittest.cc b/chrome/browser/ash/eche_app/eche_app_manager_factory_unittest.cc index c7a3621..bf4345a 100644 --- a/chrome/browser/ash/eche_app/eche_app_manager_factory_unittest.cc +++ b/chrome/browser/ash/eche_app/eche_app_manager_factory_unittest.cc
@@ -10,6 +10,7 @@ #include "ash/system/status_area_widget_test_helper.h" #include "ash/system/tray/tray_bubble_wrapper.h" #include "ash/test/test_ash_web_view_factory.h" +#include "ash/webui/eche_app_ui/apps_launch_info_provider.h" #include "ash/webui/eche_app_ui/eche_alert_generator.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/ash/eche_app/eche_app_notification_controller.h" @@ -159,9 +160,13 @@ const char16_t visible_name_1[] = u"Fake App 1"; const char package_name_1[] = "com.fakeapp1"; const char16_t phone_name[] = u"your phone"; + auto apps_launch_info_provider = std::make_unique<AppsLaunchInfoProvider>( + std::make_unique<EcheConnectionStatusHandler>().get()); + EcheAppManagerFactory::LaunchEcheApp( GetProfile(), /*notification_id=*/absl::nullopt, package_name_1, - visible_name_1, user_id, gfx::Image(), phone_name); + visible_name_1, user_id, gfx::Image(), phone_name, + apps_launch_info_provider.get()); // Wait for Eche Tray to load Eche Web to complete base::RunLoop().RunUntilIdle(); // Eche icon should be visible after launch. @@ -173,7 +178,8 @@ const char package_name_2[] = "com.fakeapp2"; EcheAppManagerFactory::LaunchEcheApp( GetProfile(), /*notification_id=*/absl::nullopt, package_name_2, - visible_name_2, user_id, gfx::Image(), phone_name); + visible_name_2, user_id, gfx::Image(), phone_name, + apps_launch_info_provider.get()); // Wait for Eche Tray to load Eche Web to complete base::RunLoop().RunUntilIdle(); EXPECT_EQ(widget, eche_tray()->GetBubbleWidget()); @@ -185,10 +191,12 @@ const std::string package_name = "com.fakeapp"; const gfx::Image icon = gfx::test::CreateImage(100, 100); const std::u16string phone_name = u"your phone"; + auto apps_launch_info_provider = std::make_unique<AppsLaunchInfoProvider>( + std::make_unique<EcheConnectionStatusHandler>().get()); EcheAppManagerFactory::LaunchEcheApp( GetProfile(), /*notification_id=*/absl::nullopt, package_name, - visible_name, user_id, icon, phone_name); + visible_name, user_id, icon, phone_name, apps_launch_info_provider.get()); std::unique_ptr<LaunchedAppInfo> launched_app_info = EcheAppManagerFactory::GetInstance()->GetLastLaunchedAppInfo(); @@ -208,9 +216,13 @@ const char16_t visible_name[] = u"Fake App"; const char package_name[] = "com.fakeapp"; const char16_t phone_name[] = u"your phone"; + auto apps_launch_info_provider = std::make_unique<AppsLaunchInfoProvider>( + std::make_unique<EcheConnectionStatusHandler>().get()); + EcheAppManagerFactory::LaunchEcheApp( GetProfile(), /*notification_id=*/absl::nullopt, package_name, - visible_name, user_id, gfx::Image(), phone_name); + visible_name, user_id, gfx::Image(), phone_name, + apps_launch_info_provider.get()); // Wait for Eche Tray to load Eche Web to complete base::RunLoop().RunUntilIdle(); // Eche tray should be visible when streaming is active, not ative when
diff --git a/chrome/browser/ash/eol_incentive_util.cc b/chrome/browser/ash/eol_incentive_util.cc index 4702a514..574bd989 100644 --- a/chrome/browser/ash/eol_incentive_util.cc +++ b/chrome/browser/ash/eol_incentive_util.cc
@@ -13,7 +13,9 @@ #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" +#include "chromeos/ash/components/browser_context_helper/browser_context_helper.h" #include "components/prefs/pref_service.h" +#include "components/user_manager/user.h" namespace ash::eol_incentive_util { namespace { @@ -62,6 +64,12 @@ return EolIncentiveType::kNone; } + const user_manager::User* user = + BrowserContextHelper::Get()->GetUserByBrowserContext(profile); + if (user && user->GetType() != user_manager::USER_TYPE_REGULAR) { + return EolIncentiveType::kNone; + } + // If EOL is more than kFirstIncentiveDaysInAdvance away, don't show any // incentives. const base::TimeDelta time_to_eol = eol_date - now;
diff --git a/chrome/browser/ash/login/arc_terms_of_service_browsertest.cc b/chrome/browser/ash/login/arc_terms_of_service_browsertest.cc deleted file mode 100644 index 33c80cc8..0000000 --- a/chrome/browser/ash/login/arc_terms_of_service_browsertest.cc +++ /dev/null
@@ -1,742 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ash/login/screens/arc_terms_of_service_screen.h" - -#include "ash/components/arc/arc_prefs.h" -#include "ash/components/arc/arc_util.h" -#include "ash/constants/ash_features.h" -#include "ash/constants/ash_switches.h" -#include "ash/public/cpp/login_screen_test_api.h" -#include "base/command_line.h" -#include "base/functional/callback_helpers.h" -#include "base/hash/sha1.h" -#include "base/memory/ptr_util.h" -#include "base/strings/strcat.h" -#include "base/strings/stringprintf.h" -#include "base/test/scoped_feature_list.h" -#include "chrome/browser/ash/arc/arc_util.h" -#include "chrome/browser/ash/arc/session/arc_service_launcher.h" -#include "chrome/browser/ash/login/existing_user_controller.h" -#include "chrome/browser/ash/login/login_wizard.h" -#include "chrome/browser/ash/login/oobe_screen.h" -#include "chrome/browser/ash/login/screens/recommend_apps_screen.h" -#include "chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h" -#include "chrome/browser/ash/login/test/js_checker.h" -#include "chrome/browser/ash/login/test/login_manager_mixin.h" -#include "chrome/browser/ash/login/test/oobe_base_test.h" -#include "chrome/browser/ash/login/test/oobe_screen_exit_waiter.h" -#include "chrome/browser/ash/login/test/oobe_screen_waiter.h" -#include "chrome/browser/ash/login/test/session_manager_state_waiter.h" -#include "chrome/browser/ash/login/test/webview_content_extractor.h" -#include "chrome/browser/ash/login/ui/login_display_host.h" -#include "chrome/browser/ash/login/wizard_controller.h" -#include "chrome/browser/ash/policy/core/device_local_account.h" -#include "chrome/browser/ash/policy/core/device_policy_builder.h" -#include "chrome/browser/ash/policy/core/device_policy_cros_browser_test.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/consent_auditor/consent_auditor_factory.h" -#include "chrome/browser/consent_auditor/consent_auditor_test_utils.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/webui/ash/login/arc_terms_of_service_screen_handler.h" -#include "chrome/browser/ui/webui/ash/login/gaia_screen_handler.h" -#include "chrome/browser/ui/webui/ash/login/recommend_apps_screen_handler.h" -#include "chrome/common/pref_names.h" -#include "chrome/grit/generated_resources.h" -#include "chrome/test/base/interactive_test_utils.h" -#include "chromeos/ash/components/dbus/session_manager/fake_session_manager_client.h" -#include "components/consent_auditor/fake_consent_auditor.h" -#include "components/policy/core/common/cloud/test/policy_builder.h" -#include "components/prefs/pref_service.h" -#include "components/web_resource/web_resource_pref_names.h" -#include "content/public/test/browser_test.h" -#include "content/public/test/browser_test_utils.h" -#include "net/dns/mock_host_resolver.h" -#include "net/test/embedded_test_server/http_request.h" -#include "net/test/embedded_test_server/http_response.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "ui/base/l10n/l10n_util.h" - -namespace ash { -namespace { - -namespace em = ::enterprise_management; - -using ::consent_auditor::FakeConsentAuditor; -using ::sync_pb::UserConsentTypes; -using ArcPlayTermsOfServiceConsent = - ::sync_pb::UserConsentTypes::ArcPlayTermsOfServiceConsent; -using ArcBackupAndRestoreConsent = - ::sync_pb::UserConsentTypes::ArcBackupAndRestoreConsent; -using ArcGoogleLocationServiceConsent = - ::sync_pb::UserConsentTypes::ArcGoogleLocationServiceConsent; -using ::net::test_server::BasicHttpResponse; -using ::net::test_server::HttpRequest; -using ::net::test_server::HttpResponse; -using ::testing::ElementsAre; - -const char kAccountId[] = "dla@example.com"; -const char kDisplayName[] = "display name"; - -constexpr char kTosPath[] = "/about/play-terms.html"; -constexpr char kTosContent[] = "Arc TOS for test."; - -constexpr char kPrivacyPolicyPath[] = "/policies/privacy/"; -constexpr char kPrivacyPolicyContent[] = "Arc Privarcy Policy for test."; - -constexpr char kArcTosID[] = "arc-tos"; - -const test::UIPath kArcEnableBackupRestore = {kArcTosID, - "arcEnableBackupRestore"}; -const test::UIPath kArcEnableLocationService = {kArcTosID, - "arcEnableLocationService"}; -const test::UIPath kArcExtraContent = {kArcTosID, "arcExtraContent"}; -const test::UIPath kArcLocationService = {kArcTosID, "arcLocationService"}; -const test::UIPath kArcPolicyLink = {kArcTosID, "arcPolicyLink"}; -const test::UIPath kArcReviewSettingsCheckbox = {kArcTosID, - "arcReviewSettingsCheckbox"}; -const test::UIPath kArcTosAcceptButton = {kArcTosID, "arcTosAcceptButton"}; -const test::UIPath kArcTosBackButton = {kArcTosID, "arcTosBackButton"}; -const test::UIPath kArcTosNextButton = {kArcTosID, "arcTosNextButton"}; -const test::UIPath kArcTosOverlayWebview = {kArcTosID, "arcTosOverlayWebview"}; -const test::UIPath kArcTosRetryButton = {kArcTosID, "arcTosRetryButton"}; -const test::UIPath kArcTosView = {kArcTosID, "arcTosView"}; -const test::UIPath kArcTosDialog = {kArcTosID, "arcTosDialog"}; - -ArcPlayTermsOfServiceConsent BuildArcPlayTermsOfServiceConsent(bool accepted) { - ArcPlayTermsOfServiceConsent play_consent; - play_consent.set_status(accepted ? sync_pb::UserConsentTypes::GIVEN - : UserConsentTypes::NOT_GIVEN); - play_consent.set_confirmation_grd_id(IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT); - play_consent.set_consent_flow(ArcPlayTermsOfServiceConsent::SETUP); - play_consent.set_play_terms_of_service_text_length(strlen(kTosContent)); - play_consent.set_play_terms_of_service_hash( - base::SHA1HashString(kTosContent)); - return play_consent; -} - -ArcBackupAndRestoreConsent BuildArcBackupAndRestoreConsent(bool accepted) { - ArcBackupAndRestoreConsent backup_and_restore_consent; - backup_and_restore_consent.set_confirmation_grd_id( - IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT); - backup_and_restore_consent.add_description_grd_ids( - IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE); - backup_and_restore_consent.set_status(accepted ? UserConsentTypes::GIVEN - : UserConsentTypes::NOT_GIVEN); - return backup_and_restore_consent; -} - -ArcGoogleLocationServiceConsent BuildArcGoogleLocationServiceConsent( - bool accepted) { - ArcGoogleLocationServiceConsent location_service_consent; - location_service_consent.set_confirmation_grd_id( - IDS_ARC_OOBE_TERMS_BUTTON_ACCEPT); - location_service_consent.add_description_grd_ids( - IDS_ARC_OPT_IN_LOCATION_SETTING); - location_service_consent.set_status(accepted ? UserConsentTypes::GIVEN - : UserConsentTypes::NOT_GIVEN); - return location_service_consent; -} - -} // namespace - -class ArcTermsOfServiceScreenTest : public OobeBaseTest { - public: - ArcTermsOfServiceScreenTest() { - // ARC ToS screen is not shown when OobeConsolidatedConsent is enabled, and - // its content is moved to the consolidated consent screen. - feature_list_.InitAndDisableFeature(features::kOobeConsolidatedConsent); - } - - ArcTermsOfServiceScreenTest(const ArcTermsOfServiceScreenTest&) = delete; - ArcTermsOfServiceScreenTest& operator=(const ArcTermsOfServiceScreenTest&) = - delete; - - ~ArcTermsOfServiceScreenTest() override = default; - - void RegisterAdditionalRequestHandlers() override { - embedded_test_server()->RegisterRequestHandler(base::BindRepeating( - &ArcTermsOfServiceScreenTest::HandleRequest, base::Unretained(this))); - } - - void SetUpOnMainThread() override { - // Enable ARC for testing. - arc::ArcServiceLauncher::Get()->ResetForTesting(); - OobeBaseTest::SetUpOnMainThread(); - } - - void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitchASCII(switches::kArcAvailability, - "officially-supported"); - command_line->AppendSwitchASCII(switches::kArcTosHostForTests, - TestServerBaseUrl()); - OobeBaseTest::SetUpCommandLine(command_line); - } - - void SetUpExitCallback() { - ArcTermsOfServiceScreen* terms_of_service_screen = - static_cast<ArcTermsOfServiceScreen*>( - WizardController::default_controller()->screen_manager()->GetScreen( - ArcTermsOfServiceScreenView::kScreenId)); - original_callback_ = - terms_of_service_screen->get_exit_callback_for_testing(); - terms_of_service_screen->set_exit_callback_for_testing( - base::BindRepeating(&ArcTermsOfServiceScreenTest::ScreenExitCallback, - base::Unretained(this))); - // Skip RecommendAppsScreen because it is shown right after the ArcToS - // screen and doesn't work correctly in the test environment. (More precise, - // it requires display with some particular height/width which is not set.) - RecommendAppsScreen* recommend_apps_screen = - static_cast<RecommendAppsScreen*>( - WizardController::default_controller()->screen_manager()->GetScreen( - RecommendAppsScreenView::kScreenId)); - recommend_apps_screen->SetSkipForTesting(); - } - - void LoginAsRegularUser() { - SetUpExitCallback(); - login_manager_mixin_.LoginAsNewRegularUser(); - OobeScreenExitWaiter(GetFirstSigninScreen()).Wait(); - } - - void ShowArcTosScreen() { - ASSERT_FALSE(screen_exit_result_.has_value()); - LoginDisplayHost::default_host()->StartWizard( - ArcTermsOfServiceScreenView::kScreenId); - } - - void TriggerArcTosScreen() { - LoginAsRegularUser(); - ShowArcTosScreen(); - } - - protected: - // When enabled serves terms of service with a footer that contains a link - // to the privacy policy. - void set_serve_tos_with_privacy_policy_footer(bool serve_with_footer) { - serve_tos_with_privacy_policy_footer_ = serve_with_footer; - } - - void set_on_screen_exit_called(base::OnceClosure on_screen_exit_called) { - on_screen_exit_called_ = std::move(on_screen_exit_called); - } - - const absl::optional<ArcTermsOfServiceScreen::Result>& screen_exit_result() - const { - return screen_exit_result_; - } - - void WaitForTermsOfServiceWebViewToLoad() { - OobeScreenWaiter(ArcTermsOfServiceScreenView::kScreenId).Wait(); - test::OobeJS().CreateVisibilityWaiter(true, kArcTosDialog)->Wait(); - } - - void WaitForScreenExitResult() { - if (screen_exit_result_.has_value()) - return; - - base::RunLoop run_loop; - on_screen_exit_called_ = run_loop.QuitClosure(); - run_loop.Run(); - } - - base::HistogramTester histogram_tester_; - - private: - void ScreenExitCallback(ArcTermsOfServiceScreen::Result result) { - ASSERT_FALSE(screen_exit_result_.has_value()); - screen_exit_result_ = result; - original_callback_.Run(result); - if (on_screen_exit_called_) - std::move(on_screen_exit_called_).Run(); - } - - // Returns the base URL of the embedded test server. - // The string will have the format "http://127.0.0.1:${PORT_NUMBER}" where - // PORT_NUMBER is a randomly assigned port number. - std::string TestServerBaseUrl() { - return std::string(base::TrimString( - embedded_test_server()->base_url().DeprecatedGetOriginAsURL().spec(), - "/", base::TrimPositions::TRIM_TRAILING)); - } - - // Handles both Terms of Service and Privacy policy requests. - std::unique_ptr<HttpResponse> HandleRequest(const HttpRequest& request) { - if (!(request.relative_url == kTosPath || - request.relative_url == kPrivacyPolicyPath)) { - return nullptr; - } - - if (request.relative_url == kPrivacyPolicyPath) - return BuildHttpResponse(kPrivacyPolicyContent); - - // The terms of service screen determines the URL of the privacy policy - // by scanning the terms of service http response. It looks for an <a> tag - // with with href that matches '/policies/privacy/' that is also a child of - // an element with class 'play-footer'. - std::string content = kTosContent; - if (serve_tos_with_privacy_policy_footer_) { - std::string href = TestServerBaseUrl() + "/policies/privacy/"; - std::string footer = base::StringPrintf( - "<div class='play-footer'><a href='%s'>", href.c_str()); - content += footer; - } - return BuildHttpResponse(content); - } - - // Returns a successful `BasicHttpResponse` with `content`. - std::unique_ptr<BasicHttpResponse> BuildHttpResponse( - const std::string& content) { - std::unique_ptr<BasicHttpResponse> http_response = - std::make_unique<BasicHttpResponse>(); - http_response->set_code(net::HTTP_OK); - http_response->set_content_type("text/html"); - http_response->set_content(content); - return http_response; - } - - bool serve_tos_with_privacy_policy_footer_ = false; - - base::test::ScopedFeatureList feature_list_; - absl::optional<ArcTermsOfServiceScreen::Result> screen_exit_result_; - ArcTermsOfServiceScreen::ScreenExitCallback original_callback_; - base::OnceClosure on_screen_exit_called_ = base::DoNothing(); - - LoginManagerMixin login_manager_mixin_{&mixin_host_}; -}; - -// Tests that screen fetches the terms of service from the specified URL -// and the content is displayed as a <webview>. -IN_PROC_BROWSER_TEST_F(ArcTermsOfServiceScreenTest, TermsOfServiceContent) { - TriggerArcTosScreen(); - ASSERT_NO_FATAL_FAILURE(WaitForTermsOfServiceWebViewToLoad()); - EXPECT_EQ(kTosContent, test::GetWebViewContents(kArcTosView)); - - EXPECT_FALSE(screen_exit_result().has_value()); -} - -// Tests that clicking on "More" button unhides some terms of service paragraphs -// of the screen. -IN_PROC_BROWSER_TEST_F(ArcTermsOfServiceScreenTest, ClickOnMore) { - TriggerArcTosScreen(); - ASSERT_NO_FATAL_FAILURE(WaitForTermsOfServiceWebViewToLoad()); - // By default, these paragraphs should be hidden. - test::OobeJS().ExpectHiddenPath(kArcExtraContent); - test::OobeJS().ExpectHiddenPath(kArcTosAcceptButton); - - // Click on 'More' button. - test::OobeJS().ClickOnPath(kArcTosNextButton); - - // Paragraphs should now be visible. - test::OobeJS().ExpectHiddenPath(kArcTosNextButton); - test::OobeJS().ExpectVisiblePath(kArcExtraContent); - - EXPECT_FALSE(screen_exit_result().has_value()); - EXPECT_THAT(histogram_tester_.GetAllSamples( - "OOBE.ArcTermsOfServiceScreen.UserActions"), - ElementsAre(base::Bucket( - static_cast<int>( - ArcTermsOfServiceScreen::UserAction::kNextButtonClicked), - 1))); -} - -// Tests that all "learn more" links opens correct popup dialog. -IN_PROC_BROWSER_TEST_F(ArcTermsOfServiceScreenTest, LearnMoreDialogs) { - TriggerArcTosScreen(); - ASSERT_NO_FATAL_FAILURE(WaitForTermsOfServiceWebViewToLoad()); - test::OobeJS().ClickOnPath(kArcTosNextButton); - - // List of pairs of {html element ids, html pop up dialog id}. - std::vector<std::pair<std::string, std::string>> learn_more_links{ - {"learnMoreLinkMetrics", "arcMetricsPopup"}, - {"learnMoreLinkBackupRestore", "arcBackupRestorePopup"}, - {"learnMoreLinkLocationService", "arcLocationServicePopup"}, - {"learnMoreLinkPai", "arcPaiPopup"}}; - - for (const auto& pair : learn_more_links) { - auto [html_element_id, popup_html_element_id] = pair; - test::OobeJS().ExpectAttributeEQ( - "open", {kArcTosID, popup_html_element_id}, false); - test::OobeJS().ClickOnPath({kArcTosID, html_element_id}); - test::OobeJS().ExpectAttributeEQ( - "open", {kArcTosID, popup_html_element_id}, true); - test::OobeJS().ClickOnPath( - {kArcTosID, popup_html_element_id, "closeButton"}); - test::OobeJS().ExpectAttributeEQ( - "open", {kArcTosID, popup_html_element_id}, false); - } - EXPECT_FALSE(screen_exit_result().has_value()); - EXPECT_THAT( - histogram_tester_.GetAllSamples( - "OOBE.ArcTermsOfServiceScreen.UserActions"), - ElementsAre( - base::Bucket( - static_cast<int>( - ArcTermsOfServiceScreen::UserAction::kNextButtonClicked), - 1), - base::Bucket(static_cast<int>(ArcTermsOfServiceScreen::UserAction:: - kMetricsLearnMoreClicked), - 1), - base::Bucket(static_cast<int>(ArcTermsOfServiceScreen::UserAction:: - kBackupRestoreLearnMoreClicked), - 1), - base::Bucket(static_cast<int>(ArcTermsOfServiceScreen::UserAction:: - kLocationServiceLearnMoreClicked), - 1), - base::Bucket(static_cast<int>(ArcTermsOfServiceScreen::UserAction:: - kPlayAutoInstallLearnMoreClicked), - 1))); -} - -// Test that checking the "review after signing" checkbox updates pref -// kShowArcSettingsOnSessionStart. -IN_PROC_BROWSER_TEST_F(ArcTermsOfServiceScreenTest, ReviewPlayOptions) { - TriggerArcTosScreen(); - ASSERT_NO_FATAL_FAILURE(WaitForTermsOfServiceWebViewToLoad()); - Profile* profile = ProfileManager::GetActiveUserProfile(); - EXPECT_FALSE( - profile->GetPrefs()->GetBoolean(prefs::kShowArcSettingsOnSessionStart)); - - test::OobeJS().ClickOnPath(kArcTosNextButton); - test::OobeJS().ClickOnPath(kArcReviewSettingsCheckbox); - test::OobeJS().ClickOnPath(kArcTosAcceptButton); - - EXPECT_TRUE( - profile->GetPrefs()->GetBoolean(prefs::kShowArcSettingsOnSessionStart)); - WaitForScreenExitResult(); - EXPECT_EQ(screen_exit_result(), ArcTermsOfServiceScreen::Result::ACCEPTED); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Arc-tos.Accepted", 1); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Arc-tos.Skipped", 0); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Arc-tos.Back", 0); - histogram_tester_.ExpectTotalCount("OOBE.StepCompletionTime.Arc_tos", 1); - histogram_tester_.ExpectTotalCount( - "OOBE.ArcTermsOfServiceScreen.ReviewFollowingSetup", 1); - EXPECT_THAT( - histogram_tester_.GetAllSamples( - "OOBE.ArcTermsOfServiceScreen.UserActions"), - ElementsAre( - base::Bucket( - static_cast<int>( - ArcTermsOfServiceScreen::UserAction::kAcceptButtonClicked), - 1), - base::Bucket( - static_cast<int>( - ArcTermsOfServiceScreen::UserAction::kNextButtonClicked), - 1))); -} - -// Test whether google privacy policy can be loaded. -IN_PROC_BROWSER_TEST_F(ArcTermsOfServiceScreenTest, PrivacyPolicy) { - // Privacy policy link is parsed from the footer of the TOS content response. - set_serve_tos_with_privacy_policy_footer(true); - TriggerArcTosScreen(); - ASSERT_NO_FATAL_FAILURE(WaitForTermsOfServiceWebViewToLoad()); - - test::OobeJS().ClickOnPath(kArcTosNextButton); - test::OobeJS().ClickOnPath(kArcPolicyLink); - - test::OobeJS() - .CreateWaiter(base::StrCat( - {"!", test::GetOobeElementPath({kArcTosID}), ".overlayLoading_"})) - ->Wait(); - EXPECT_EQ(test::GetWebViewContents(kArcTosOverlayWebview), - kPrivacyPolicyContent); - - EXPECT_THAT( - histogram_tester_.GetAllSamples( - "OOBE.ArcTermsOfServiceScreen.UserActions"), - ElementsAre( - base::Bucket( - static_cast<int>( - ArcTermsOfServiceScreen::UserAction::kNextButtonClicked), - 1), - base::Bucket( - static_cast<int>( - ArcTermsOfServiceScreen::UserAction::kPolicyLinkClicked), - 1))); - - EXPECT_FALSE(screen_exit_result().has_value()); -} - -IN_PROC_BROWSER_TEST_F(ArcTermsOfServiceScreenTest, RetryAndBackButtonClicked) { - // Back button is shown only in demo mode. - WizardController::default_controller()->SimulateDemoModeSetupForTesting(); - // Accept EULA cause it is expected in case of back button pressed by - // WizardController::OnArcTermsOfServiceScreenExit. - g_browser_process->local_state()->SetBoolean(prefs::kEulaAccepted, true); - - TriggerArcTosScreen(); - WaitForTermsOfServiceWebViewToLoad(); - - test::OobeJS().ClickOnPath(kArcTosRetryButton); - test::OobeJS().ClickOnPath(kArcTosBackButton); - - WaitForScreenExitResult(); - EXPECT_EQ(screen_exit_result(), ArcTermsOfServiceScreen::Result::BACK); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Arc-tos.Accepted", 0); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Arc-tos.Skipped", 0); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Arc-tos.Back", 1); - histogram_tester_.ExpectTotalCount("OOBE.StepCompletionTime.Arc_tos", 1); - EXPECT_THAT( - histogram_tester_.GetAllSamples( - "OOBE.ArcTermsOfServiceScreen.UserActions"), - ElementsAre( - base::Bucket( - static_cast<int>( - ArcTermsOfServiceScreen::UserAction::kRetryButtonClicked), - 1), - base::Bucket( - static_cast<int>( - ArcTermsOfServiceScreen::UserAction::kBackButtonClicked), - 1))); -} - -IN_PROC_BROWSER_TEST_F(ArcTermsOfServiceScreenTest, NextButtonFocused) { - TriggerArcTosScreen(); - WaitForTermsOfServiceWebViewToLoad(); - test::OobeJS().CreateFocusWaiter(kArcTosNextButton)->Wait(); - - // TODO(crbug/1167720): Make this a method of JSChecker - ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( - nullptr, ui::VKEY_RETURN, false /* control */, false /* shift */, - false /* alt */, false /* command */)); - test::OobeJS().CreateVisibilityWaiter(true, kArcTosAcceptButton)->Wait(); - - EXPECT_THAT(histogram_tester_.GetAllSamples( - "OOBE.ArcTermsOfServiceScreen.UserActions"), - ElementsAre(base::Bucket( - static_cast<int>( - ArcTermsOfServiceScreen::UserAction::kNextButtonClicked), - 1))); -} - -// There are two checkboxes for enabling/disabling arc backup restore and -// arc location service. This parameterized test executes all 4 combinations -// of enabled/disabled states and checks that advancing to the next screen by -// accepting. -class ParameterizedArcTermsOfServiceScreenTest - : public ArcTermsOfServiceScreenTest, - public testing::WithParamInterface<std::tuple<bool, bool>> { - public: - ParameterizedArcTermsOfServiceScreenTest() = default; - - ParameterizedArcTermsOfServiceScreenTest( - const ParameterizedArcTermsOfServiceScreenTest&) = delete; - ParameterizedArcTermsOfServiceScreenTest& operator=( - const ParameterizedArcTermsOfServiceScreenTest&) = delete; - - ~ParameterizedArcTermsOfServiceScreenTest() = default; - - void SetUp() override { - std::tie(accept_backup_restore_, accept_location_service_) = GetParam(); - ArcTermsOfServiceScreenTest::SetUp(); - } - - // Common routine that enables/disables checkboxes based on test parameters. - // When `accept` is true, advances to next screen by clicking on the "Accept" - // button. - // `play_consent`, `backup_and_restore_consent` and `location_service_consent` - // are the expected consents recordings. - void AdvanceNextScreenWithExpectations( - bool accept, - ArcPlayTermsOfServiceConsent play_consent, - ArcBackupAndRestoreConsent backup_and_restore_consent, - ArcGoogleLocationServiceConsent location_service_consent) { - ASSERT_NO_FATAL_FAILURE(WaitForTermsOfServiceWebViewToLoad()); - - test::OobeJS().ClickOnPath(kArcTosNextButton); - - // Wait for checkboxes to become visible. - test::OobeJS().CreateVisibilityWaiter(true, kArcLocationService)->Wait(); - - Profile* profile = ProfileManager::GetActiveUserProfile(); - FakeConsentAuditor* auditor = static_cast<FakeConsentAuditor*>( - ConsentAuditorFactory::GetInstance()->SetTestingFactoryAndUse( - profile, base::BindRepeating(&BuildFakeConsentAuditor))); - - if (!accept_backup_restore_) - test::OobeJS().ClickOnPath(kArcEnableBackupRestore); - - if (!accept_location_service_) { - test::OobeJS().ClickOnPath(kArcEnableLocationService); - } - - EXPECT_CALL(*auditor, RecordArcPlayConsent( - testing::_, - consent_auditor::ArcPlayConsentEq(play_consent))); - EXPECT_CALL(*auditor, - RecordArcBackupAndRestoreConsent( - testing::_, consent_auditor::ArcBackupAndRestoreConsentEq( - backup_and_restore_consent))); - EXPECT_CALL( - *auditor, - RecordArcGoogleLocationServiceConsent( - testing::_, consent_auditor::ArcGoogleLocationServiceConsentEq( - location_service_consent))); - - if (accept) - test::OobeJS().ClickOnPath(kArcTosAcceptButton); - } - - protected: - bool accept_backup_restore_; - bool accept_location_service_; -}; - -// Tests that clicking on "Accept" button records the expected consents. -// When TOS are accepted we should also record whether backup restores and -// location services are enabled. -IN_PROC_BROWSER_TEST_P(ParameterizedArcTermsOfServiceScreenTest, ClickAccept) { - TriggerArcTosScreen(); - ASSERT_NO_FATAL_FAILURE(WaitForTermsOfServiceWebViewToLoad()); - ArcPlayTermsOfServiceConsent play_consent = - BuildArcPlayTermsOfServiceConsent(true); - ArcBackupAndRestoreConsent backup_and_restore_consent = - BuildArcBackupAndRestoreConsent(accept_backup_restore_); - ArcGoogleLocationServiceConsent location_service_consent = - BuildArcGoogleLocationServiceConsent(accept_location_service_); - - AdvanceNextScreenWithExpectations( - true, play_consent, backup_and_restore_consent, location_service_consent); - - WaitForScreenExitResult(); - EXPECT_EQ(screen_exit_result(), ArcTermsOfServiceScreen::Result::ACCEPTED); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Arc-tos.Accepted", 1); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Arc-tos.Skipped", 0); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Arc-tos.Back", 0); - histogram_tester_.ExpectTotalCount("OOBE.StepCompletionTime.Arc_tos", 1); - - histogram_tester_.ExpectTotalCount( - "OOBE.WebViewLoader.FirstLoadResult.ArcTosView", 1); -} - -INSTANTIATE_TEST_SUITE_P(All, - ParameterizedArcTermsOfServiceScreenTest, - testing::Combine(testing::Bool(), testing::Bool())); - -class PublicAccountArcTermsOfServiceScreenTest - : public ArcTermsOfServiceScreenTest { - public: - PublicAccountArcTermsOfServiceScreenTest() = default; - - PublicAccountArcTermsOfServiceScreenTest( - const PublicAccountArcTermsOfServiceScreenTest&) = delete; - PublicAccountArcTermsOfServiceScreenTest& operator=( - const PublicAccountArcTermsOfServiceScreenTest&) = delete; - - ~PublicAccountArcTermsOfServiceScreenTest() override = default; - - void SetUpInProcessBrowserTestFixture() override { - ArcTermsOfServiceScreenTest::SetUpInProcessBrowserTestFixture(); - SessionManagerClient::InitializeFakeInMemory(); - InitializePolicy(); - } - - void InitializePolicy() { - device_policy()->policy_data().set_public_key_version(1); - policy::DeviceLocalAccountTestHelper::SetupDeviceLocalAccount( - &device_local_account_policy_, kAccountId, kDisplayName); - UploadDeviceLocalAccountPolicy(); - } - - void BuildDeviceLocalAccountPolicy() { - device_local_account_policy_.SetDefaultSigningKey(); - device_local_account_policy_.Build(); - } - - void UploadDeviceLocalAccountPolicy() { - BuildDeviceLocalAccountPolicy(); - policy_test_server_mixin_.UpdatePolicy( - policy::dm_protocol::kChromePublicAccountPolicyType, kAccountId, - device_local_account_policy_.payload().SerializeAsString()); - } - - void UploadAndInstallDeviceLocalAccountPolicy() { - UploadDeviceLocalAccountPolicy(); - session_manager_client()->set_device_local_account_policy( - kAccountId, device_local_account_policy_.GetBlob()); - } - - void AddPublicSessionToDevicePolicy() { - em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); - policy::DeviceLocalAccountTestHelper::AddPublicSession(&proto, kAccountId); - RefreshDevicePolicy(); - policy_test_server_mixin_.UpdateDevicePolicy(proto); - } - - void WaitForDisplayName() { - policy::DictionaryLocalStateValueWaiter("UserDisplayName", kDisplayName, - account_id_.GetUserEmail()) - .Wait(); - } - - void WaitForPolicy() { - // Wait for the display name becoming available as that indicates - // device-local account policy is fully loaded, which is a prerequisite for - // successful login. - WaitForDisplayName(); - } - - void StartLogin() { - ASSERT_TRUE(LoginScreenTestApi::ExpandPublicSessionPod(account_id_)); - LoginScreenTestApi::ClickPublicExpandedSubmitButton(); - } - - void StartPublicSession() { - UploadAndInstallDeviceLocalAccountPolicy(); - AddPublicSessionToDevicePolicy(); - WaitForPolicy(); - StartLogin(); - } - - private: - FakeSessionManagerClient* session_manager_client() { - return FakeSessionManagerClient::Get(); - } - - void RefreshDevicePolicy() { policy_helper()->RefreshDevicePolicy(); } - - policy::DevicePolicyBuilder* device_policy() { - return policy_helper()->device_policy(); - } - - policy::DevicePolicyCrosTestHelper* policy_helper() { - return &policy_helper_; - } - - const AccountId account_id_ = - AccountId::FromUserEmail(GenerateDeviceLocalAccountUserId( - kAccountId, - policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)); - policy::DevicePolicyCrosTestHelper policy_helper_; - policy::UserPolicyBuilder device_local_account_policy_; - EmbeddedPolicyTestServerMixin policy_test_server_mixin_{&mixin_host_}; - DeviceStateMixin device_state_{ - &mixin_host_, DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED}; -}; - -IN_PROC_BROWSER_TEST_F(PublicAccountArcTermsOfServiceScreenTest, - SkippedForPublicAccount) { - StartPublicSession(); - - test::WaitForPrimaryUserSessionStart(); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Arc-tos.Accepted", 0); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Arc-tos.Skipped", 0); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Arc-tos.Back", 0); - histogram_tester_.ExpectTotalCount("OOBE.StepCompletionTime.Arc_tos", 0); -} - -} // namespace ash
diff --git a/chrome/browser/ash/login/demo_mode/demo_setup_browsertest.cc b/chrome/browser/ash/login/demo_mode/demo_setup_browsertest.cc index 257105c..6e1b261e 100644 --- a/chrome/browser/ash/login/demo_mode/demo_setup_browsertest.cc +++ b/chrome/browser/ash/login/demo_mode/demo_setup_browsertest.cc
@@ -74,7 +74,6 @@ using test::DemoModeSetupResult; using test::SetupDummyOfflinePolicyDir; -constexpr char kArcTosId[] = "arc-tos"; constexpr char kConsolidatedConsentId[] = "consolidated-consent"; constexpr char kDemoSetupId[] = "demo-setup"; constexpr char kDemoPrefsId[] = "demo-preferences"; @@ -113,11 +112,6 @@ const test::UIPath kDemoSetupErrorDialogMessage = {kDemoSetupId, "errorMessage"}; -const test::UIPath kArcTosDialog = {kArcTosId, "arcTosDialog"}; -const test::UIPath kArcTosAcceptButton = {kArcTosId, "arcTosAcceptButton"}; -const test::UIPath kArcTosBackButton = {kArcTosId, "arcTosBackButton"}; -const test::UIPath kArcTosNextButton = {kArcTosId, "arcTosNextButton"}; - const test::UIPath kCCAcceptButton = {kConsolidatedConsentId, "acceptButton"}; const test::UIPath kCCArcTosLink = {kConsolidatedConsentId, "arcTosLink"}; const test::UIPath kCCBackButton = {kConsolidatedConsentId, "backButton"}; @@ -327,18 +321,6 @@ ASSERT_TRUE(arc::IsArcAvailable()); } - void SetPlayStoreTermsForTesting() { - test::ExecuteOobeJS( - R"(login.ArcTermsOfServiceScreen.setTosForTesting( - 'Test Play Store Terms of Service');)"); - } - - void WaitForArcTosScreen() { - OobeScreenWaiter(ArcTermsOfServiceScreenView::kScreenId).Wait(); - SetPlayStoreTermsForTesting(); - test::OobeJS().CreateVisibilityWaiter(true, kArcTosDialog)->Wait(); - } - void WaitForConsolidatedConsentScreen() { test::WaitForConsolidatedConsentScreen(); @@ -359,13 +341,6 @@ test::OobeJS().ExpectDisabledPath(kDemoPreferencesNext); } - void AcceptArcTos() { - test::OobeJS().CreateVisibilityWaiter(true, kArcTosNextButton)->Wait(); - test::OobeJS().ClickOnPath(kArcTosNextButton); - test::OobeJS().CreateVisibilityWaiter(true, kArcTosAcceptButton)->Wait(); - test::OobeJS().ClickOnPath(kArcTosAcceptButton); - } - void AcceptTermsAndExpectDemoSetupProgress() { test::LockDemoDeviceInstallAttributes(); // TODO(b/246012796): If possible, re-enable waiting on the setup screen to @@ -519,16 +494,14 @@ AcceptTermsAndExpectDemoSetupProgress(); - if (features::IsOobeConsolidatedConsentEnabled()) { - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTime.Consolidated-consent", 1); - histogram_tester_.ExpectTotalCount( - "OOBE.StepShownStatus.Consolidated-consent", 1); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Consolidated-consent." - "AcceptedDemo", - 1); - } + histogram_tester_.ExpectTotalCount( + "OOBE.StepCompletionTime.Consolidated-consent", 1); + histogram_tester_.ExpectTotalCount( + "OOBE.StepShownStatus.Consolidated-consent", 1); + histogram_tester_.ExpectTotalCount( + "OOBE.StepCompletionTimeByExitReason.Consolidated-consent." + "AcceptedDemo", + 1); // Verify the email corresponds to US. EXPECT_EQ("admin-us@cros-demo-mode.com", @@ -787,29 +760,20 @@ TriggerDemoModeOnWelcomeScreen(); - if (features::IsOobeConsolidatedConsentEnabled()) { - UseOnlineModeOnNetworkScreen(); - OobeScreenWaiter(DemoPreferencesScreenView::kScreenId).Wait(); - ProceedThroughDemoPreferencesScreen(); - test::WaitForConsolidatedConsentScreen(); - test::OobeJS().ClickOnPath(kCCBackButton); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTime.Consolidated-consent", 1); - histogram_tester_.ExpectTotalCount( - "OOBE.StepShownStatus.Consolidated-consent", 1); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Consolidated-consent." - "BackDemo", - 1); - } else { - // User cannot go to ARC ToS screen without accepting eula - simulate that. - StartupUtils::MarkEulaAccepted(); - UseOnlineModeOnNetworkScreen(); - OobeScreenWaiter(DemoPreferencesScreenView::kScreenId).Wait(); - ProceedThroughDemoPreferencesScreen(); - OobeScreenWaiter(ArcTermsOfServiceScreenView::kScreenId).Wait(); - test::OobeJS().ClickOnPath(kArcTosBackButton); - } + UseOnlineModeOnNetworkScreen(); + OobeScreenWaiter(DemoPreferencesScreenView::kScreenId).Wait(); + ProceedThroughDemoPreferencesScreen(); + test::WaitForConsolidatedConsentScreen(); + test::OobeJS().ClickOnPath(kCCBackButton); + histogram_tester_.ExpectTotalCount( + "OOBE.StepCompletionTime.Consolidated-consent", 1); + histogram_tester_.ExpectTotalCount( + "OOBE.StepShownStatus.Consolidated-consent", 1); + histogram_tester_.ExpectTotalCount( + "OOBE.StepCompletionTimeByExitReason.Consolidated-consent." + "BackDemo", + 1); + OobeScreenWaiter(DemoPreferencesScreenView::kScreenId).Wait(); }
diff --git a/chrome/browser/ash/login/screens/mock_arc_terms_of_service_screen.cc b/chrome/browser/ash/login/screens/mock_arc_terms_of_service_screen.cc deleted file mode 100644 index 217eea1..0000000 --- a/chrome/browser/ash/login/screens/mock_arc_terms_of_service_screen.cc +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ash/login/screens/mock_arc_terms_of_service_screen.h" -#include "base/memory/weak_ptr.h" - -namespace ash { - -MockArcTermsOfServiceScreen::MockArcTermsOfServiceScreen( - base::WeakPtr<ArcTermsOfServiceScreenView> view, - const ScreenExitCallback& exit_callback) - : ArcTermsOfServiceScreen(std::move(view), exit_callback) {} - -MockArcTermsOfServiceScreen::~MockArcTermsOfServiceScreen() = default; - -void MockArcTermsOfServiceScreen::ExitScreen(Result result) { - exit_callback()->Run(result); -} - -MockArcTermsOfServiceScreenView::MockArcTermsOfServiceScreenView() = default; - -MockArcTermsOfServiceScreenView::~MockArcTermsOfServiceScreenView() { - if (observer_) - observer_->OnViewDestroyed(this); -} - -void MockArcTermsOfServiceScreenView::AddObserver( - ArcTermsOfServiceScreenViewObserver* observer) { - observer_ = observer; - MockAddObserver(observer); -} - -void MockArcTermsOfServiceScreenView::RemoveObserver( - ArcTermsOfServiceScreenViewObserver* observer) { - if (observer_ == observer) - observer_ = nullptr; - MockRemoveObserver(observer); -} - -} // namespace ash
diff --git a/chrome/browser/ash/login/screens/mock_arc_terms_of_service_screen.h b/chrome/browser/ash/login/screens/mock_arc_terms_of_service_screen.h deleted file mode 100644 index d7d51b3..0000000 --- a/chrome/browser/ash/login/screens/mock_arc_terms_of_service_screen.h +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_ASH_LOGIN_SCREENS_MOCK_ARC_TERMS_OF_SERVICE_SCREEN_H_ -#define CHROME_BROWSER_ASH_LOGIN_SCREENS_MOCK_ARC_TERMS_OF_SERVICE_SCREEN_H_ - -#include "base/memory/weak_ptr.h" -#include "chrome/browser/ash/login/screens/arc_terms_of_service_screen.h" -#include "chrome/browser/ui/webui/ash/login/arc_terms_of_service_screen_handler.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace ash { - -class MockArcTermsOfServiceScreen : public ArcTermsOfServiceScreen { - public: - MockArcTermsOfServiceScreen(base::WeakPtr<ArcTermsOfServiceScreenView> view, - const ScreenExitCallback& exit_callback); - ~MockArcTermsOfServiceScreen() override; - - MOCK_METHOD(void, ShowImpl, ()); - MOCK_METHOD(void, HideImpl, ()); - - void ExitScreen(Result result); -}; - -class MockArcTermsOfServiceScreenView : public ArcTermsOfServiceScreenView { - public: - MockArcTermsOfServiceScreenView(); - ~MockArcTermsOfServiceScreenView() override; - - void AddObserver(ArcTermsOfServiceScreenViewObserver* observer) override; - void RemoveObserver(ArcTermsOfServiceScreenViewObserver* observer) override; - - MOCK_METHOD(void, Show, ()); - MOCK_METHOD(void, Hide, ()); - MOCK_METHOD(void, Bind, (ArcTermsOfServiceScreen * screen)); - MOCK_METHOD(void, - MockAddObserver, - (ArcTermsOfServiceScreenViewObserver * observer)); - MOCK_METHOD(void, - MockRemoveObserver, - (ArcTermsOfServiceScreenViewObserver * observer)); - - private: - ArcTermsOfServiceScreenViewObserver* observer_ = nullptr; -}; - -} // namespace ash - -#endif // CHROME_BROWSER_ASH_LOGIN_SCREENS_MOCK_ARC_TERMS_OF_SERVICE_SCREEN_H_
diff --git a/chrome/browser/ash/login/ui/login_display_host_webui.cc b/chrome/browser/ash/login/ui/login_display_host_webui.cc index 143919aa..20dc6823 100644 --- a/chrome/browser/ash/login/ui/login_display_host_webui.cc +++ b/chrome/browser/ash/login/ui/login_display_host_webui.cc
@@ -1130,8 +1130,7 @@ } if (StartupUtils::IsEulaAccepted()) { - DelayNetworkCall(base::Milliseconds(kDefaultNetworkRetryDelayMS), - ServicesCustomizationDocument::GetInstance() + DelayNetworkCall(ServicesCustomizationDocument::GetInstance() ->EnsureCustomizationAppliedClosure()); g_browser_process->platform_part()
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc index 4d530e3..204a184 100644 --- a/chrome/browser/ash/login/wizard_controller.cc +++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -2160,8 +2160,7 @@ return; } - DelayNetworkCall(base::Milliseconds(kDefaultNetworkRetryDelayMS), - base::BindOnce(&WizardController::StartTimezoneResolve, + DelayNetworkCall(base::BindOnce(&WizardController::StartTimezoneResolve, weak_factory_.GetWeakPtr())); } @@ -2189,8 +2188,7 @@ void WizardController::PerformPostNetworkScreenActions() { StartNetworkTimezoneResolve(); - DelayNetworkCall(base::Milliseconds(kDefaultNetworkRetryDelayMS), - ServicesCustomizationDocument::GetInstance() + DelayNetworkCall(ServicesCustomizationDocument::GetInstance() ->EnsureCustomizationAppliedClosure()); GetAutoEnrollmentController()->Start();
diff --git a/chrome/browser/ash/login/wizard_controller_browsertest.cc b/chrome/browser/ash/login/wizard_controller_browsertest.cc index 012e791..e1a9a1ea 100644 --- a/chrome/browser/ash/login/wizard_controller_browsertest.cc +++ b/chrome/browser/ash/login/wizard_controller_browsertest.cc
@@ -37,7 +37,6 @@ #include "chrome/browser/ash/login/screens/device_disabled_screen.h" #include "chrome/browser/ash/login/screens/error_screen.h" #include "chrome/browser/ash/login/screens/hid_detection_screen.h" -#include "chrome/browser/ash/login/screens/mock_arc_terms_of_service_screen.h" #include "chrome/browser/ash/login/screens/mock_consolidated_consent_screen.h" #include "chrome/browser/ash/login/screens/mock_demo_preferences_screen.h" #include "chrome/browser/ash/login/screens/mock_demo_setup_screen.h" @@ -635,15 +634,6 @@ base::BindRepeating(&WizardController::OnDemoPreferencesScreenExit, base::Unretained(wizard_controller)))); - mock_arc_terms_of_service_screen_view_ = - std::make_unique<MockArcTermsOfServiceScreenView>(); - mock_arc_terms_of_service_screen_ = - MockScreenExpectLifecycle(std::make_unique<MockArcTermsOfServiceScreen>( - mock_arc_terms_of_service_screen_view_->AsWeakPtr(), - base::BindRepeating( - &WizardController::OnArcTermsOfServiceScreenExit, - base::Unretained(wizard_controller)))); - device_disabled_screen_view_ = std::make_unique<MockDeviceDisabledScreenView>(); MockScreen(std::make_unique<DeviceDisabledScreen>( @@ -721,15 +711,6 @@ base::BindRepeating(&WizardController::OnDemoPreferencesScreenExit, base::Unretained(wizard_controller)))); - mock_arc_terms_of_service_screen_view_ = - std::make_unique<MockArcTermsOfServiceScreenView>(); - mock_arc_terms_of_service_screen_ = - MockScreenExpectLifecycle(std::make_unique<MockArcTermsOfServiceScreen>( - mock_arc_terms_of_service_screen_view_->AsWeakPtr(), - base::BindRepeating( - &WizardController::OnArcTermsOfServiceScreenExit, - base::Unretained(wizard_controller)))); - mock_consolidated_consent_screen_view_ = std::make_unique<MockConsolidatedConsentScreenView>(); mock_consolidated_consent_screen_ = MockScreenExpectLifecycle( @@ -896,10 +877,6 @@ std::unique_ptr<MockDemoPreferencesScreenView> mock_demo_preferences_screen_view_; - MockArcTermsOfServiceScreen* mock_arc_terms_of_service_screen_ = nullptr; - std::unique_ptr<MockArcTermsOfServiceScreenView> - mock_arc_terms_of_service_screen_view_; - MockConsolidatedConsentScreen* mock_consolidated_consent_screen_ = nullptr; std::unique_ptr<MockConsolidatedConsentScreenView> mock_consolidated_consent_screen_view_;
diff --git a/chrome/browser/ash/net/delay_network_call.cc b/chrome/browser/ash/net/delay_network_call.cc index 8be17f8..aa38886 100644 --- a/chrome/browser/ash/net/delay_network_call.cc +++ b/chrome/browser/ash/net/delay_network_call.cc
@@ -19,10 +19,10 @@ namespace ash { -const unsigned kDefaultNetworkRetryDelayMS = 3000; - namespace { +constexpr base::TimeDelta kDefaultRetryDelay = base::Seconds(3); + bool IsCaptivePortal(const NetworkState* default_network) { if (!network_portal_detector::IsInitialized()) { // Network portal detector is not initialized yet so we can't reliably @@ -69,11 +69,18 @@ return false; } -void DelayNetworkCall(base::TimeDelta retry, base::OnceClosure callback) { +void DelayNetworkCall(base::OnceClosure callback) { + DelayNetworkCallWithCustomDelay(std::move(callback), kDefaultRetryDelay); +} + +void DelayNetworkCallWithCustomDelay(base::OnceClosure callback, + base::TimeDelta retry_delay) { if (AreNetworkCallsDelayed()) { content::GetUIThreadTaskRunner({})->PostDelayedTask( FROM_HERE, - base::BindOnce(&DelayNetworkCall, retry, std::move(callback)), retry); + base::BindOnce(&DelayNetworkCallWithCustomDelay, std::move(callback), + retry_delay), + retry_delay); return; }
diff --git a/chrome/browser/ash/net/delay_network_call.h b/chrome/browser/ash/net/delay_network_call.h index b430c1d..948be1fe 100644 --- a/chrome/browser/ash/net/delay_network_call.h +++ b/chrome/browser/ash/net/delay_network_call.h
@@ -15,15 +15,17 @@ namespace ash { -// Default delay to be used as an argument to DelayNetworkCall(). -extern const unsigned kDefaultNetworkRetryDelayMS; - // Returns `true` if network calls will be delayed by `DelayNetworkCall()`. bool AreNetworkCallsDelayed(); // Delay callback until the network is connected or while on a captive portal. // Also see `AreNetworkCallsDelayed()`. -void DelayNetworkCall(base::TimeDelta retry, base::OnceClosure callback); +void DelayNetworkCall(base::OnceClosure callback); + +// Same as above `DelayNetworkCall()` except it allows a custom `retry_delay` to +// be passed. +void DelayNetworkCallWithCustomDelay(base::OnceClosure callback, + base::TimeDelta retry_delay); } // namespace ash
diff --git a/chrome/browser/background_fetch/background_fetch_delegate_impl_unittest.cc b/chrome/browser/background_fetch/background_fetch_delegate_impl_unittest.cc index cd598b4..dbdd8f4 100644 --- a/chrome/browser/background_fetch/background_fetch_delegate_impl_unittest.cc +++ b/chrome/browser/background_fetch/background_fetch_delegate_impl_unittest.cc
@@ -51,8 +51,11 @@ content::BrowserTaskEnvironment task_environment_; std::unique_ptr<ukm::TestAutoSetUkmRecorder> recorder_; - raw_ptr<BackgroundFetchDelegateImpl> delegate_; std::unique_ptr<TestingProfile> profile_; + + // Can't outlive `profile_` which owns it. + raw_ptr<BackgroundFetchDelegateImpl> delegate_; + const GURL kOriginUrl{"https://example.com/"}; };
diff --git a/chrome/browser/browser_process_platform_part_ash.cc b/chrome/browser/browser_process_platform_part_ash.cc index db1a69bc..cb4d119f 100644 --- a/chrome/browser/browser_process_platform_part_ash.cc +++ b/chrome/browser/browser_process_platform_part_ash.cc
@@ -235,9 +235,7 @@ g_browser_process->shared_url_loader_factory(), ash::SimpleGeolocationProvider::DefaultGeolocationProviderURL(), base::BindRepeating(&ash::system::ApplyTimeZone), - base::BindRepeating( - &ash::DelayNetworkCall, - base::Milliseconds(ash::kDefaultNetworkRetryDelayMS)), + base::BindRepeating(&ash::DelayNetworkCall), g_browser_process->local_state()); } return timezone_resolver_.get();
diff --git a/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.cc b/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.cc index 07238ba..98657b17 100644 --- a/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.cc +++ b/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.cc
@@ -263,35 +263,10 @@ namespace extensions { -struct SmartCardProviderPrivateAPI::PendingEstablishContext { - base::OneShotTimer timer; - CreateContextCallback callback; -}; - struct SmartCardProviderPrivateAPI::PendingReleaseContext { base::OneShotTimer timer; }; -struct SmartCardProviderPrivateAPI::PendingListReaders { - base::OneShotTimer timer; - device::mojom::SmartCardContext::ListReadersCallback callback; -}; - -struct SmartCardProviderPrivateAPI::PendingGetStatusChange { - base::OneShotTimer timer; - device::mojom::SmartCardContext::GetStatusChangeCallback callback; -}; - -struct SmartCardProviderPrivateAPI::PendingConnect { - base::OneShotTimer timer; - device::mojom::SmartCardContext::ConnectCallback callback; -}; - -struct SmartCardProviderPrivateAPI::PendingDisconnect { - base::OneShotTimer timer; - DisconnectCallback callback; -}; - // static BrowserContextKeyedAPIFactory<SmartCardProviderPrivateAPI>* SmartCardProviderPrivateAPI::GetFactoryInstance() { @@ -326,37 +301,13 @@ void SmartCardProviderPrivateAPI::CreateContext( CreateContextCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - RequestId request_id = request_id_generator_.GenerateNextId(); - base::Value::List event_args; - event_args.Append(request_id.GetUnsafeValue()); - - auto event = std::make_unique<extensions::Event>( + DispatchEventWithTimeout( + scard_api::OnEstablishContextRequested::kEventName, extensions::events:: SMART_CARD_PROVIDER_PRIVATE_ON_ESTABLISH_CONTEXT_REQUESTED, - scard_api::OnEstablishContextRequested::kEventName, std::move(event_args), - &*browser_context_); - - const std::string provider_extension_id = GetListenerExtensionId(*event); - - if (provider_extension_id.empty()) { - std::move(callback).Run( - SmartCardCreateContextResult::NewError(SmartCardError::kNoService)); - return; - } - - auto pending = std::make_unique<PendingEstablishContext>(); - pending->callback = std::move(callback); - pending->timer.Start( - FROM_HERE, response_time_limit_, - base::BindOnce(&SmartCardProviderPrivateAPI::OnEstablishContextTimeout, - weak_ptr_factory_.GetWeakPtr(), provider_extension_id, - request_id)); - - pending_establish_context_[request_id] = std::move(pending); - - event_router_->DispatchEventToExtension(provider_extension_id, - std::move(event)); + std::move(callback), pending_establish_context_, + &SmartCardProviderPrivateAPI::OnEstablishContextTimeout); } void SmartCardProviderPrivateAPI::OnMojoContextDisconnected() { @@ -425,40 +376,15 @@ Handle scard_handle, device::mojom::SmartCardDisposition disposition, DisconnectCallback callback) { - RequestId request_id = request_id_generator_.GenerateNextId(); - - base::Value::List event_args; - event_args.Append(request_id.GetUnsafeValue()); - event_args.Append(scard_handle.GetUnsafeValue()); - event_args.Append(ToValue(disposition)); - - auto event = std::make_unique<extensions::Event>( + DispatchEventWithTimeout( + scard_api::OnDisconnectRequested::kEventName, extensions::events::SMART_CARD_PROVIDER_PRIVATE_ON_DISCONNECT_REQUESTED, - scard_api::OnDisconnectRequested::kEventName, std::move(event_args), - base::to_address(browser_context_)); - - const std::string provider_extension_id = GetListenerExtensionId(*event); - - if (provider_extension_id.empty()) { - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, - base::BindOnce(std::move(callback), - SmartCardResult::NewError(SmartCardError::kNoService))); - return; - } - - auto pending = std::make_unique<PendingDisconnect>(); - pending->callback = std::move(callback); - pending->timer.Start( - FROM_HERE, response_time_limit_, - base::BindOnce(&SmartCardProviderPrivateAPI::OnDisconnectTimeout, - weak_ptr_factory_.GetWeakPtr(), provider_extension_id, - request_id)); - - pending_disconnect_[request_id] = std::move(pending); - - event_router_->DispatchEventToExtension(provider_extension_id, - std::move(event)); + std::move(callback), pending_disconnect_, + &SmartCardProviderPrivateAPI::OnDisconnectTimeout, + /*event_arguments=*/ + base::Value::List() + .Append(scard_handle.GetUnsafeValue()) + .Append(ToValue(disposition))); } void SmartCardProviderPrivateAPI::ReportEstablishContextResult( @@ -467,7 +393,7 @@ SmartCardResultPtr result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - std::unique_ptr<PendingEstablishContext> pending = + std::unique_ptr<PendingResult<CreateContextCallback>> pending = Extract(pending_establish_context_, request_id); if (!pending) { if (result->is_success() && scard_context) { @@ -525,7 +451,7 @@ SmartCardResultPtr result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - std::unique_ptr<PendingListReaders> pending = + std::unique_ptr<PendingResult<ListReadersCallback>> pending = Extract(pending_list_readers_, request_id); if (!pending) { return; @@ -543,7 +469,7 @@ SmartCardResultPtr result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - std::unique_ptr<PendingGetStatusChange> pending = + std::unique_ptr<PendingResult<GetStatusChangeCallback>> pending = Extract(pending_get_status_change_, request_id); if (!pending) { return; @@ -589,7 +515,7 @@ SmartCardResultPtr result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - std::unique_ptr<PendingConnect> pending = + std::unique_ptr<PendingResult<ConnectCallback>> pending = Extract(pending_connect_, request_id); if (!pending) { // TODO(crbug.com/1386175): Send disconnect request to PC/SC provider @@ -614,7 +540,7 @@ device::mojom::SmartCardResultPtr result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - std::unique_ptr<PendingDisconnect> pending = + std::unique_ptr<PendingResult<DisconnectCallback>> pending = Extract(pending_disconnect_, request_id); if (!pending) { return; @@ -649,42 +575,64 @@ return (*listener_set.cbegin())->extension_id(); } +template <typename ResultPtr, + typename Callback = base::OnceCallback<void(ResultPtr)>> +void SmartCardProviderPrivateAPI::DispatchEventWithTimeout( + const std::string& event_name, + extensions::events::HistogramValue histogram_value, + base::OnceCallback<void(ResultPtr)> callback, + PendingResultMap<Callback>& pending_results, + void (SmartCardProviderPrivateAPI::*OnTimeout)(const std::string&, + RequestId), + base::Value::List event_arguments, + absl::optional<base::TimeDelta> timeout) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + RequestId request_id = request_id_generator_.GenerateNextId(); + + event_arguments.Insert(event_arguments.begin(), + base::Value(request_id.GetUnsafeValue())); + + auto event = std::make_unique<extensions::Event>(histogram_value, event_name, + std::move(event_arguments), + &*browser_context_); + + const std::string provider_extension_id = GetListenerExtensionId(*event); + if (provider_extension_id.empty()) { + ResultPtr error(absl::in_place); + error->set_error(SmartCardError::kNoService); + std::move(callback).Run(std::move(error)); + return; + } + + auto pending = std::make_unique<PendingResult<Callback>>(); + pending->callback = std::move(callback); + pending->timer.Start(FROM_HERE, + timeout ? timeout.value() : response_time_limit_, + base::BindOnce(OnTimeout, weak_ptr_factory_.GetWeakPtr(), + provider_extension_id, request_id)); + + pending_results[request_id] = std::move(pending); + + event_router_->DispatchEventToExtension(provider_extension_id, + std::move(event)); +} + void SmartCardProviderPrivateAPI::ListReaders(ListReadersCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); const ContextId scard_context = context_receivers_.current_context(); DCHECK(!scard_context.is_null()); - RequestId request_id = request_id_generator_.GenerateNextId(); - base::Value::List event_args; - event_args.Append(request_id.GetUnsafeValue()); event_args.Append(scard_context.GetUnsafeValue()); - auto event = std::make_unique<extensions::Event>( + DispatchEventWithTimeout( + scard_api::OnListReadersRequested::kEventName, extensions::events::SMART_CARD_PROVIDER_PRIVATE_ON_LIST_READERS_REQUESTED, - scard_api::OnListReadersRequested::kEventName, std::move(event_args), - &*browser_context_); - - const std::string provider_extension_id = GetListenerExtensionId(*event); - if (provider_extension_id.empty()) { - std::move(callback).Run( - SmartCardListReadersResult::NewError(SmartCardError::kNoService)); - return; - } - - auto pending = std::make_unique<PendingListReaders>(); - pending->callback = std::move(callback); - pending->timer.Start( - FROM_HERE, response_time_limit_, - base::BindOnce(&SmartCardProviderPrivateAPI::OnListReadersTimeout, - weak_ptr_factory_.GetWeakPtr(), provider_extension_id, - request_id)); - - pending_list_readers_[request_id] = std::move(pending); - - event_router_->DispatchEventToExtension(provider_extension_id, - std::move(event)); + std::move(callback), pending_list_readers_, + &SmartCardProviderPrivateAPI::OnListReadersTimeout, + std::move(event_args)); } void SmartCardProviderPrivateAPI::GetStatusChange( @@ -696,10 +644,7 @@ const ContextId scard_context = context_receivers_.current_context(); DCHECK(!scard_context.is_null()); - RequestId request_id = request_id_generator_.GenerateNextId(); - base::Value::List event_args; - event_args.Append(request_id.GetUnsafeValue()); event_args.Append(scard_context.GetUnsafeValue()); const bool finite_timeout = @@ -718,31 +663,13 @@ } event_args.Append(std::move(reader_states_list)); - auto event = std::make_unique<extensions::Event>( - events::SMART_CARD_PROVIDER_PRIVATE_ON_GET_STATUS_CHANGE_REQUESTED, - scard_api::OnGetStatusChangeRequested::kEventName, std::move(event_args), - &*browser_context_); - - const std::string provider_extension_id = GetListenerExtensionId(*event); - if (provider_extension_id.empty()) { - std::move(callback).Run( - SmartCardStatusChangeResult::NewError(SmartCardError::kNoService)); - return; - } - - auto pending = std::make_unique<PendingGetStatusChange>(); - pending->callback = std::move(callback); - if (finite_timeout) { - pending->timer.Start( - FROM_HERE, std::max(base::Milliseconds(500), time_delta * 2), - base::BindOnce(&SmartCardProviderPrivateAPI::OnGetStatusChangeTimeout, - weak_ptr_factory_.GetWeakPtr(), provider_extension_id, - request_id)); - } - pending_get_status_change_[request_id] = std::move(pending); - - event_router_->DispatchEventToExtension(provider_extension_id, - std::move(event)); + DispatchEventWithTimeout( + scard_api::OnGetStatusChangeRequested::kEventName, + extensions::events:: + SMART_CARD_PROVIDER_PRIVATE_ON_GET_STATUS_CHANGE_REQUESTED, + std::move(callback), pending_get_status_change_, + &SmartCardProviderPrivateAPI::OnGetStatusChangeTimeout, + std::move(event_args), std::max(base::Milliseconds(500), time_delta * 2)); } void SmartCardProviderPrivateAPI::Connect( @@ -755,41 +682,17 @@ const ContextId scard_context = context_receivers_.current_context(); CHECK(!scard_context.is_null()); - RequestId request_id = request_id_generator_.GenerateNextId(); - base::Value::List event_args; - event_args.Append(request_id.GetUnsafeValue()); event_args.Append(scard_context.GetUnsafeValue()); event_args.Append(reader); event_args.Append(ToValue(share_mode)); event_args.Append(ToValue(*preferred_protocols.get())); - auto event = std::make_unique<extensions::Event>( + DispatchEventWithTimeout( + scard_api::OnConnectRequested::kEventName, extensions::events::SMART_CARD_PROVIDER_PRIVATE_ON_CONNECT_REQUESTED, - scard_api::OnConnectRequested::kEventName, std::move(event_args), - &*browser_context_); - - const std::string provider_extension_id = GetListenerExtensionId(*event); - if (provider_extension_id.empty()) { - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, - base::BindOnce(std::move(callback), SmartCardConnectResult::NewError( - SmartCardError::kNoService))); - return; - } - - auto pending = std::make_unique<PendingConnect>(); - pending->callback = std::move(callback); - pending->timer.Start( - FROM_HERE, response_time_limit_, - base::BindOnce(&SmartCardProviderPrivateAPI::OnConnectTimeout, - weak_ptr_factory_.GetWeakPtr(), provider_extension_id, - request_id)); - - pending_connect_[request_id] = std::move(pending); - - event_router_->DispatchEventToExtension(provider_extension_id, - std::move(event)); + std::move(callback), pending_connect_, + &SmartCardProviderPrivateAPI::OnConnectTimeout, std::move(event_args)); } void SmartCardProviderPrivateAPI::Disconnect(
diff --git a/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.h b/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.h index 1068e6c..d1610bd 100644 --- a/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.h +++ b/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.h
@@ -88,6 +88,16 @@ void SetResponseTimeLimitForTesting(base::TimeDelta); private: + template <typename Callback> + struct PendingResult { + base::OneShotTimer timer; + Callback callback; + }; + + template <typename Callback> + using PendingResultMap = + std::map<RequestId, std::unique_ptr<PendingResult<Callback>>>; + // BrowserContextKeyedAPI: static const bool kServiceIsCreatedWithBrowserContext = false; static const char* service_name() { return "SmartCardProviderPrivateAPI"; } @@ -124,6 +134,17 @@ void OnDisconnectTimeout(const std::string& provider_extension_id, RequestId request_id); + template <typename ResultPtr, typename Callback> + void DispatchEventWithTimeout( + const std::string& event_name, + extensions::events::HistogramValue histogram_value, + base::OnceCallback<void(ResultPtr)> callback, + PendingResultMap<Callback>& pending_results, + void (SmartCardProviderPrivateAPI::*OnTimeout)(const std::string&, + RequestId), + base::Value::List event_arguments = base::Value::List(), + absl::optional<base::TimeDelta> timeout = absl::nullopt); + device::mojom::SmartCardConnectResultPtr CreateSmartCardConnection( Handle handle, device::mojom::SmartCardProtocol active_protocol); @@ -132,27 +153,16 @@ base::TimeDelta response_time_limit_{base::Minutes(5)}; - struct PendingEstablishContext; - std::map<RequestId, std::unique_ptr<PendingEstablishContext>> - pending_establish_context_; + PendingResultMap<CreateContextCallback> pending_establish_context_; struct PendingReleaseContext; std::map<RequestId, std::unique_ptr<PendingReleaseContext>> pending_release_context_; - struct PendingListReaders; - std::map<RequestId, std::unique_ptr<PendingListReaders>> - pending_list_readers_; - - struct PendingGetStatusChange; - std::map<RequestId, std::unique_ptr<PendingGetStatusChange>> - pending_get_status_change_; - - struct PendingConnect; - std::map<RequestId, std::unique_ptr<PendingConnect>> pending_connect_; - - struct PendingDisconnect; - std::map<RequestId, std::unique_ptr<PendingDisconnect>> pending_disconnect_; + PendingResultMap<ListReadersCallback> pending_list_readers_; + PendingResultMap<GetStatusChangeCallback> pending_get_status_change_; + PendingResultMap<ConnectCallback> pending_connect_; + PendingResultMap<DisconnectCallback> pending_disconnect_; RequestId::Generator request_id_generator_; const raw_ref<content::BrowserContext> browser_context_;
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc index 1763b88..dee61f0e 100644 --- a/chrome/browser/content_settings/content_settings_browsertest.cc +++ b/chrome/browser/content_settings/content_settings_browsertest.cc
@@ -122,28 +122,6 @@ return count; } -class CookieChangeObserver : public content::WebContentsObserver { - public: - explicit CookieChangeObserver(content::WebContents* web_contents) - : content::WebContentsObserver(web_contents) {} - ~CookieChangeObserver() override = default; - - void Wait() { run_loop_.Run(); } - - void OnCookiesAccessed(content::RenderFrameHost* render_frame_host, - const content::CookieAccessDetails& details) override { - run_loop_.Quit(); - } - - void OnCookiesAccessed(content::NavigationHandle* navigation, - const content::CookieAccessDetails& details) override { - run_loop_.Quit(); - } - - private: - base::RunLoop run_loop_; -}; - class MockWebContentsLoadFailObserver : public content::WebContentsObserver { public: explicit MockWebContentsLoadFailObserver(content::WebContents* web_contents) @@ -446,9 +424,14 @@ CookieSettingsFactory::GetForProfile(browser()->profile()).get(); settings->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); + content::CookieChangeObserver observer1( + browser()->tab_strip_model()->GetActiveWebContents()); + WriteCookie(browser()); ASSERT_TRUE(ReadCookie(browser()).empty()); + observer1.Wait(); + browsing_data::CannedCookieHelper* accepted = GetSiteSettingsCookieContainer(browser()); browsing_data::CannedCookieHelper* blocked = @@ -460,8 +443,14 @@ settings->SetCookieSetting(GetPageURL(), CONTENT_SETTING_ALLOW); + content::CookieChangeObserver observer2( + browser()->tab_strip_model()->GetActiveWebContents()); + WriteCookie(browser()); ASSERT_FALSE(ReadCookie(browser()).empty()); + + observer2.Wait(); + accepted = GetSiteSettingsCookieContainer(browser()); blocked = GetSiteSettingsBlockedCookieContainer(browser()); @@ -892,8 +881,13 @@ CookieSettingsFactory::GetForProfile(browser()->profile()) ->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); + content::CookieChangeObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); + observer.Wait(); + content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame(); @@ -929,7 +923,13 @@ CookieSettingsFactory::GetForProfile(browser()->profile()) ->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); + content::CookieChangeObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); + + observer.Wait(); + EXPECT_TRUE(PageSpecificContentSettings::GetForFrame( web_contents->GetPrimaryMainFrame()) ->IsContentBlocked(ContentSettingsType::COOKIES)); @@ -968,7 +968,11 @@ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), http_url)); EXPECT_TRUE(GetSiteSettingsCookieContainer(browser())->empty()); + content::CookieChangeObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), https_url)); + observer.Wait(); EXPECT_FALSE(GetSiteSettingsCookieContainer(browser())->empty()); } @@ -1338,7 +1342,7 @@ EXPECT_EQ(true, result2); { - CookieChangeObserver observer( + content::CookieChangeObserver observer( browser()->tab_strip_model()->GetActiveWebContents()); // Set a cookie, see that it's reported. content::EvalJsResult result3 = @@ -1358,7 +1362,7 @@ } { - CookieChangeObserver observer( + content::CookieChangeObserver observer( browser()->tab_strip_model()->GetActiveWebContents()); // Now set with cookies blocked. content_settings::CookieSettings* settings =
diff --git a/chrome/browser/content_settings/request_desktop_site_web_contents_observer_android.cc b/chrome/browser/content_settings/request_desktop_site_web_contents_observer_android.cc index c38eb34..955729d0 100644 --- a/chrome/browser/content_settings/request_desktop_site_web_contents_observer_android.cc +++ b/chrome/browser/content_settings/request_desktop_site_web_contents_observer_android.cc
@@ -4,9 +4,11 @@ #include "chrome/browser/content_settings/request_desktop_site_web_contents_observer_android.h" +#include "base/command_line.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/android/tab_model/tab_model.h" +#include "chrome/common/chrome_switches.h" #include "components/content_settings/core/common/content_settings_utils.h" #include "components/content_settings/core/common/pref_names.h" #include "components/prefs/pref_service.h" @@ -72,6 +74,9 @@ url, url, ContentSettingsType::REQUEST_DESKTOP_SITE, &setting_info); bool use_rds = content_settings::ValueToContentSetting(setting) == CONTENT_SETTING_ALLOW; + // For --request-desktop-sites, always override the user agent. + use_rds |= base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kRequestDesktopSites); bool is_global_setting = setting_info.primary_pattern.MatchesAllHosts(); // Take secondary settings into account if ContentSetting is global setting.
diff --git a/chrome/browser/creator/android/BUILD.gn b/chrome/browser/creator/android/BUILD.gn index 4285f47..a2e4c81 100644 --- a/chrome/browser/creator/android/BUILD.gn +++ b/chrome/browser/creator/android/BUILD.gn
@@ -99,6 +99,7 @@ "//base:base_junit_test_support", "//chrome/browser/feed/android:feed_java_resources", "//chrome/browser/feed/android:java", + "//chrome/browser/feedback/android:java", "//chrome/browser/profiles/android:java", "//chrome/browser/share:java", "//chrome/browser/ui/messages/android:java",
diff --git a/chrome/browser/creator/android/java/src/org/chromium/chrome/browser/creator/CreatorCoordinatorTest.java b/chrome/browser/creator/android/java/src/org/chromium/chrome/browser/creator/CreatorCoordinatorTest.java index 9c64898..9764be1 100644 --- a/chrome/browser/creator/android/java/src/org/chromium/chrome/browser/creator/CreatorCoordinatorTest.java +++ b/chrome/browser/creator/android/java/src/org/chromium/chrome/browser/creator/CreatorCoordinatorTest.java
@@ -9,6 +9,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -33,6 +34,7 @@ import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.browser.creator.CreatorCoordinator.ContentChangedListener; import org.chromium.chrome.browser.creator.test.R; +import org.chromium.chrome.browser.feed.FeedActionDelegate; import org.chromium.chrome.browser.feed.FeedListContentManager.ExternalViewContent; import org.chromium.chrome.browser.feed.FeedListContentManager.FeedContent; import org.chromium.chrome.browser.feed.FeedListContentManager.NativeViewContent; @@ -40,8 +42,10 @@ import org.chromium.chrome.browser.feed.FeedServiceBridge; import org.chromium.chrome.browser.feed.FeedServiceBridgeJni; import org.chromium.chrome.browser.feed.FeedStream; +import org.chromium.chrome.browser.feed.FeedStreamJni; import org.chromium.chrome.browser.feed.SingleWebFeedEntryPoint; import org.chromium.chrome.browser.feed.webfeed.WebFeedBridge; +import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncher; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; @@ -68,6 +72,8 @@ @Mock private FeedServiceBridge.Natives mFeedServiceBridgeJniMock; @Mock + private FeedStream.Natives mFeedStreamJniMock; + @Mock private FeedReliabilityLoggingBridge.Natives mFeedReliabilityLoggingBridgeJniMock; @Mock private WindowAndroid mWindowAndroid; @@ -85,6 +91,10 @@ private FeedStream mStreamMock; @Mock private SignInInterstitialInitiator mSignInInterstitialInitiator; + @Mock + private FeedActionDelegate mFeedActionDelegate; + @Mock + private HelpAndFeedbackLauncher mHelpAndFeedbackLauncher; @Rule public ActivityScenarioRule<TestActivity> mActivityScenarioRule = @@ -105,6 +115,7 @@ public void setUpTest() { MockitoAnnotations.initMocks(this); mJniMocker.mock(FeedServiceBridgeJni.TEST_HOOKS, mFeedServiceBridgeJniMock); + mJniMocker.mock(FeedStreamJni.TEST_HOOKS, mFeedStreamJniMock); mJniMocker.mock(WebFeedBridge.getTestHooksForTesting(), mWebFeedBridgeJniMock); mJniMocker.mock(FeedReliabilityLoggingBridge.getTestHooksForTesting(), mFeedReliabilityLoggingBridgeJniMock); @@ -285,4 +296,24 @@ assertEquals(followButton.getVisibility(), View.GONE); assertEquals(followingButton.getVisibility(), View.VISIBLE); } + + @Test + public void testCreatorCoordinator_QueryFeed_nullUrl() { + CreatorCoordinator creatorCoordinator = newCreatorCoordinator( + null, mWebFeedIdDefault, mEntryPointDefault, mFollowingDefault); + PropertyModel creatorModel = creatorCoordinator.getCreatorModel(); + creatorCoordinator.queryFeedStream( + mFeedActionDelegate, mHelpAndFeedbackLauncher, mShareDelegateSupplier); + verify(mWebFeedBridgeJniMock).queryWebFeedId(anyString(), any()); + } + + @Test + public void testCreatorCoordinator_QueryFeed_nullWebFeedId() { + CreatorCoordinator creatorCoordinator = + newCreatorCoordinator(mUrlDefault, null, mEntryPointDefault, mFollowingDefault); + PropertyModel creatorModel = creatorCoordinator.getCreatorModel(); + creatorCoordinator.queryFeedStream( + mFeedActionDelegate, mHelpAndFeedbackLauncher, mShareDelegateSupplier); + verify(mWebFeedBridgeJniMock).queryWebFeed(anyString(), any()); + } }
diff --git a/chrome/browser/download/bubble/download_bubble_ui_controller.cc b/chrome/browser/download/bubble/download_bubble_ui_controller.cc index 0d35bd0..b09cc6be 100644 --- a/chrome/browser/download/bubble/download_bubble_ui_controller.cc +++ b/chrome/browser/download/bubble/download_bubble_ui_controller.cc
@@ -12,14 +12,16 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/content_index/content_index_provider_impl.h" #include "chrome/browser/download/bubble/download_bubble_prefs.h" +#include "chrome/browser/download/bubble/download_bubble_update_service.h" +#include "chrome/browser/download/bubble/download_bubble_update_service_factory.h" #include "chrome/browser/download/bubble/download_bubble_utils.h" #include "chrome/browser/download/bubble/download_display_controller.h" #include "chrome/browser/download/chrome_download_manager_delegate.h" #include "chrome/browser/download/download_core_service.h" #include "chrome/browser/download/download_core_service_factory.h" -#include "chrome/browser/download/download_crx_util.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_item_warning_data.h" +#include "chrome/browser/download/download_ui_model.h" #include "chrome/browser/download/offline_item_model_manager.h" #include "chrome/browser/download/offline_item_model_manager_factory.h" #include "chrome/browser/download/offline_item_utils.h" @@ -37,115 +39,33 @@ #include "components/offline_items_collection/core/offline_content_aggregator.h" #include "content/public/browser/download_manager.h" -using DownloadCreationType = ::download::DownloadItem::DownloadCreationType; - namespace { -constexpr int kShowDownloadsInBubbleForNumDays = 1; -constexpr int kMaxDownloadsToShow = 100; + +using DownloadCreationType = ::download::DownloadItem::DownloadCreationType; +using DownloadUIModelPtr = DownloadUIModel::DownloadUIModelPtr; + // Don't show the partial view more than once per 15 seconds, as this pops up // automatically and may be annoying to the user. The time is reset when the // user clicks on the button to open the main view. constexpr base::TimeDelta kShowPartialViewMinInterval = base::Seconds(15); -// Don't show the "download started" animation/UI for an extension or theme -// (crx) download until 2 seconds after it has begun. If it is a small download -// that finishes in under 2 seconds, the download UI does not show at all. If it -// is a large download that takes longer than 2 seconds, show the UI so that the -// user knows Chrome is working on it. -constexpr base::TimeDelta kCrxShowNewItemDelay = base::Seconds(2); -// Limit the size of the |delayed_crx_guids_| set so it doesn't grow -// unboundedly. It is unlikely that the user would have 20 active crx downloads -// simultaneously. -constexpr int kMaxDelayedCrxGuids = 20; - -bool FindOfflineItemByContentId(const ContentId& to_find, - const OfflineItem& candidate) { - return candidate.id == to_find; -} - -using DownloadUIModelPtrList = std::list<DownloadUIModelPtr>; - -// Sorting order is 1) Active in-progress downloads, 2) Paused in-progress -// downloads, 3) Other downloads -int GetSortOrder(DownloadUIModel* a) { - if (a->GetState() == download::DownloadItem::IN_PROGRESS) { - return a->IsPaused() ? 2 : 1; - } - return 3; -} - -struct StartTimeComparator { - bool operator()(const DownloadUIModelPtrList::iterator& a_iter, - const DownloadUIModelPtrList::iterator& b_iter) const { - DownloadUIModel* a = (*a_iter).get(); - DownloadUIModel* b = (*b_iter).get(); - int a_sort_order = GetSortOrder(a); - int b_sort_order = GetSortOrder(b); - if (a_sort_order < b_sort_order) { - return true; - } else if (a_sort_order > b_sort_order) { - return false; - } else { - // For the same sort order, sub-order by reverse chronological order. - return (a->GetStartTime() > b->GetStartTime()); - } - } -}; -using SortedDownloadUIModelSet = - std::multiset<DownloadUIModelPtrList::iterator, StartTimeComparator>; - -// Returns whether model was added. -bool MaybeAddModel(DownloadUIModelPtr model, - base::Time cutoff_time, - DownloadUIModelPtrList& models_aggregate, - SortedDownloadUIModelSet& sorted_ui_model_iters) { - if (model->ShouldShowInBubble() && - DownloadUIModelIsRecent(model.get(), cutoff_time)) { - models_aggregate.push_front(std::move(model)); - sorted_ui_model_iters.insert(models_aggregate.begin()); - return true; - } - return false; -} - -std::vector<DownloadUIModelPtr> GetSortedModelPtrVector( - DownloadUIModelPtrList models_list, - SortedDownloadUIModelSet sorted_iters) { - std::vector<DownloadUIModelPtr> items; - if (models_list.empty()) { - return items; - } - DCHECK(!sorted_iters.empty()); - SortedDownloadUIModelSet::const_iterator sorted_it = sorted_iters.begin(); - for (size_t i = 0; i < kMaxDownloadsToShow; ++i) { - DownloadUIModelPtrList::iterator model_it = *sorted_it; - DCHECK(model_it != models_list.end()); - items.push_back(std::move(*model_it)); - ++sorted_it; - if (sorted_it == sorted_iters.end()) { - break; - } - } - return items; -} } // namespace DownloadBubbleUIController::DownloadBubbleUIController(Browser* browser) + : DownloadBubbleUIController( + browser, + DownloadBubbleUpdateServiceFactory::GetForProfile( + browser->profile())) {} + +DownloadBubbleUIController::DownloadBubbleUIController( + Browser* browser, + DownloadBubbleUpdateService* update_service) : browser_(browser), profile_(browser->profile()), + update_service_(update_service), download_manager_(profile_->GetDownloadManager()), - download_notifier_(download_manager_, this), - aggregator_(OfflineContentAggregatorFactory::GetForKey( - profile_->GetProfileKey())), offline_manager_( - OfflineItemModelManagerFactory::GetForBrowserContext(profile_)) { - if (profile_->IsOffTheRecord()) { - Profile* original_profile = profile_->GetOriginalProfile(); - original_notifier_ = std::make_unique<download::AllDownloadItemNotifier>( - original_profile->GetDownloadManager(), this); - } - observation_.Observe(aggregator_.get()); -} + OfflineItemModelManagerFactory::GetForBrowserContext(profile_)) {} DownloadBubbleUIController::~DownloadBubbleUIController() = default; @@ -158,115 +78,19 @@ display_controller_->HandleButtonPressed(); } -bool DownloadBubbleUIController::MaybeAddOfflineItem(const OfflineItem& item, - bool is_new) { - if (profile_->IsOffTheRecord() != item.is_off_the_record) { - return false; - } - - if (OfflineItemUtils::IsDownload(item.id)) { - return false; - } - - if (item.state == OfflineItemState::CANCELLED) { - return false; - } - - if (item.id.name_space == ContentIndexProviderImpl::kProviderNamespace) { - return false; - } - - OfflineItemModel model(offline_manager_, item); - if (!model.ShouldShowInBubble()) { - return false; - } - - offline_items_.push_back(item); - if (is_new && model.ShouldNotifyUI()) { - model.SetActionedOn(false); - } - return true; +void DownloadBubbleUIController::OnDownloadManagerGoingDown() { + download_manager_ = nullptr; } -void DownloadBubbleUIController::MaybeAddOfflineItems( - base::OnceCallback<void()> callback, - bool is_new, - const OfflineItemList& offline_items) { - for (const OfflineItem& item : offline_items) { - MaybeAddOfflineItem(item, is_new); - } - std::move(callback).Run(); -} - -void DownloadBubbleUIController::InitOfflineItems( - DownloadDisplayController* display_controller, - base::OnceCallback<void()> callback) { - display_controller_ = display_controller; - aggregator_->GetAllItems(base::BindOnce( - &DownloadBubbleUIController::MaybeAddOfflineItems, - weak_factory_.GetWeakPtr(), std::move(callback), /*is_new=*/false)); -} - -const OfflineItemList& DownloadBubbleUIController::GetOfflineItems() { - PruneOfflineItems(); - return offline_items_; -} - -const std::vector<download::DownloadItem*> -DownloadBubbleUIController::GetDownloadItems() { - std::vector<download::DownloadItem*> download_items; - download_manager_->GetAllDownloads(&download_items); - if (original_notifier_) { - original_notifier_->GetManager()->GetAllDownloads(&download_items); - } - return download_items; -} - -void DownloadBubbleUIController::OnManagerGoingDown( - content::DownloadManager* manager) { - if (manager == download_manager_) { - download_manager_ = nullptr; - } -} - -void DownloadBubbleUIController::OnContentProviderGoingDown() { - observation_.Reset(); -} - -void DownloadBubbleUIController::OnItemsAdded( +void DownloadBubbleUIController::OnOfflineItemsAdded( const OfflineContentProvider::OfflineItemList& items) { - bool any_new = false; - for (const OfflineItem& item : items) { - if (MaybeAddOfflineItem(item, /*is_new=*/true)) { - any_new = true; - } - } - if (any_new) { - display_controller_->OnNewItem(/*show_animation=*/false); - } + display_controller_->OnNewItem(/*show_animation=*/false); } -void DownloadBubbleUIController::OnNewItem(download::DownloadItem* item, - bool may_show_animation) { - if (download_crx_util::IsExtensionDownload(*item) && - delayed_crx_guids_.size() < kMaxDelayedCrxGuids) { - const std::string& guid = item->GetGuid(); - DCHECK(!delayed_crx_guids_.contains(guid)); - delayed_crx_guids_.insert(guid); - base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&DownloadBubbleUIController::OnDelayedNewItemByGuid, - weak_factory_.GetWeakPtr(), guid, may_show_animation), - kCrxShowNewItemDelay); - return; - } - DoOnNewItem(item, may_show_animation); -} - -void DownloadBubbleUIController::DoOnNewItem(download::DownloadItem* item, - bool may_show_animation) { +void DownloadBubbleUIController::OnDownloadItemAdded( + download::DownloadItem* item, + bool may_show_animation) { DownloadItemModel model(item); - UpdateInProgressDownloadItems(model); if (model.ShouldNotifyUI()) { model.SetActionedOn(false); } @@ -274,94 +98,37 @@ model.ShouldShowDownloadStartedAnimation()); } -void DownloadBubbleUIController::OnDelayedNewItemByGuid( - const std::string& guid, - bool may_show_animation) { - // This assumes that for extension/theme downloads, the DownloadItem is - // removed from the DownloadManager upon completion. - download::DownloadItem* item = download_manager_->GetDownloadByGuid(guid); - if (item && !item->IsDone()) { - DoOnNewItem(item, may_show_animation); - } - size_t erased = delayed_crx_guids_.erase(guid); - DCHECK_EQ(erased, 1u); -} - -void DownloadBubbleUIController::UpdateInProgressDownloadItems( - const DownloadUIModel& model) { - const std::string& guid = model.GetDownloadItem()->GetGuid(); - if (IsModelInProgress(&model)) { - in_progress_download_item_guids_.insert(guid); - } else { - in_progress_download_item_guids_.erase(guid); - } -} - bool DownloadBubbleUIController::ShouldShowIncognitoIcon( const DownloadUIModel* model) const { return download::IsDownloadBubbleV2Enabled(profile_) && model->GetDownloadItem() && model->GetDownloadItem()->IsOffTheRecord(); } -void DownloadBubbleUIController::OnItemRemoved(const ContentId& id) { +void DownloadBubbleUIController::OnOfflineItemRemoved(const ContentId& id) { if (OfflineItemUtils::IsDownload(id)) { return; } - offline_items_.erase( - std::remove_if(offline_items_.begin(), offline_items_.end(), - [&id](const OfflineItem& candidate) { - return FindOfflineItemByContentId(id, candidate); - }), - offline_items_.end()); offline_manager_->RemoveOfflineItemModelData(id); display_controller_->OnRemovedItem(id); } -void DownloadBubbleUIController::OnDownloadRemoved( - content::DownloadManager* manager, +void DownloadBubbleUIController::OnDownloadItemRemoved( download::DownloadItem* item) { - in_progress_download_item_guids_.erase(item->GetGuid()); std::make_unique<DownloadItemModel>(item)->SetActionedOn(true); const ContentId& id = OfflineItemUtils::GetContentIdForDownload(item); display_controller_->OnRemovedItem(id); } -void DownloadBubbleUIController::OnItemUpdated( - const OfflineItem& item, - const absl::optional<UpdateDelta>& update_delta) { - // Update item - offline_items_.erase( - std::remove_if(offline_items_.begin(), offline_items_.end(), - [&item](const OfflineItem& candidate) { - return FindOfflineItemByContentId(item.id, candidate); - }), - offline_items_.end()); - bool was_added = MaybeAddOfflineItem(item, /*is_new=*/false); +void DownloadBubbleUIController::OnOfflineItemUpdated(const OfflineItem& item) { OfflineItemModel model(offline_manager_, item); display_controller_->OnUpdatedItem( model.IsDone(), IsPendingDeepScanning(&model), - was_added && - (browser_ == chrome::FindLastActiveWithProfile(profile_.get()))); + browser_ == chrome::FindLastActiveWithProfile(profile_.get())); } -void DownloadBubbleUIController::OnDownloadUpdated( - content::DownloadManager* manager, +void DownloadBubbleUIController::OnDownloadItemUpdated( download::DownloadItem* item) { - // If the item is an extension or theme download waiting out its 2-second - // delay, don't show a UI update for it. - if (delayed_crx_guids_.contains(item->GetGuid())) { - return; - } DownloadItemModel model(item); - UpdateInProgressDownloadItems(model); - // manager can be different from download_notifier_ when the current profile - // is off the record. - if (manager != download_notifier_.GetManager()) { - display_controller_->OnUpdatedItem(item->IsDone(), - IsPendingDeepScanning(&model), - /*may_show_details=*/false); - return; - } bool may_show_details = model.ShouldShowInBubble() && (browser_ == chrome::FindLastActiveWithProfile(profile_.get())); @@ -369,102 +136,11 @@ item->IsDone(), IsPendingDeepScanning(&model), may_show_details); } -void DownloadBubbleUIController::PruneOfflineItems() { - base::Time cutoff_time = - base::Time::Now() - base::Days(kShowDownloadsInBubbleForNumDays); - - for (auto item_iter = offline_items_.begin(); - item_iter != offline_items_.end();) { - std::unique_ptr<DownloadUIModel> offline_model = - std::make_unique<OfflineItemModel>(offline_manager_, *item_iter); - if (!DownloadUIModelIsRecent(offline_model.get(), cutoff_time)) { - offline_model->SetActionedOn(true); - item_iter = offline_items_.erase(item_iter); - } else { - item_iter++; - } - } -} - -std::vector<DownloadUIModelPtr> -DownloadBubbleUIController::GetAllItemsToDisplay() { - base::Time cutoff_time = - base::Time::Now() - base::Days(kShowDownloadsInBubbleForNumDays); - - // This list will contain all models, not limited to kMaxDownloadsToShow. - // Must use a list, not a vector, because we are storing iterators which must - // not be invalidated. - DownloadUIModelPtrList models_aggregate; - // Sort iterators into the above vector in a set, as a set does not allow - // move semantics over unique_ptr, preventing us from putting - // DownloadUIModelPtr directly in the set. - SortedDownloadUIModelSet sorted_ui_model_iters; - for (const OfflineItem& item : GetOfflineItems()) { - DownloadUIModelPtr model = OfflineItemModel::Wrap( - offline_manager_, item, - std::make_unique<DownloadUIModel::BubbleStatusTextBuilder>()); - MaybeAddModel(std::move(model), cutoff_time, models_aggregate, - sorted_ui_model_iters); - } - for (download::DownloadItem* item : GetDownloadItems()) { - DownloadUIModelPtr model = DownloadItemModel::Wrap( - item, std::make_unique<DownloadUIModel::BubbleStatusTextBuilder>()); - MaybeAddModel(std::move(model), cutoff_time, models_aggregate, - sorted_ui_model_iters); - } - - return GetSortedModelPtrVector(std::move(models_aggregate), - std::move(sorted_ui_model_iters)); -} - -std::vector<DownloadUIModelPtr> -DownloadBubbleUIController::GetInProgressItems() { - base::Time cutoff_time = - base::Time::Now() - base::Days(kShowDownloadsInBubbleForNumDays); - - std::set<std::string> download_item_guids_to_remove; - - // This sorts the models. See comments above in GetAllItemsToDisplay. - DownloadUIModelPtrList models; - SortedDownloadUIModelSet sorted_ui_model_iters; - for (const OfflineItem& item : GetOfflineItems()) { - DownloadUIModelPtr model = OfflineItemModel::Wrap( - offline_manager_, item, - std::make_unique<DownloadUIModel::BubbleStatusTextBuilder>()); - if (IsModelInProgress(model.get())) { - MaybeAddModel(std::move(model), cutoff_time, models, - sorted_ui_model_iters); - } - } - for (const std::string& guid : in_progress_download_item_guids_) { - download::DownloadItem* item = download_manager_->GetDownloadByGuid(guid); - if (!item) { - download_item_guids_to_remove.insert(guid); - continue; - } - DownloadUIModelPtr model = DownloadItemModel::Wrap( - item, std::make_unique<DownloadUIModel::BubbleStatusTextBuilder>()); - if (!IsModelInProgress(model.get()) || - !MaybeAddModel(std::move(model), cutoff_time, models, - sorted_ui_model_iters)) { - download_item_guids_to_remove.insert(guid); - } - } - - for (const std::string& guid_to_remove : download_item_guids_to_remove) { - in_progress_download_item_guids_.erase(guid_to_remove); - } - - return GetSortedModelPtrVector(std::move(models), - std::move(sorted_ui_model_iters)); -} - std::vector<DownloadUIModelPtr> DownloadBubbleUIController::GetDownloadUIModels( bool is_main_view) { - // Prune just to keep the list of offline entries small. - PruneOfflineItems(); - - std::vector<DownloadUIModelPtr> all_items = GetAllItemsToDisplay(); + std::vector<DownloadUIModelPtr> all_items; + update_service_->GetAllModelsToDisplay( + all_items, /*force_backfill_download_items=*/true); std::vector<DownloadUIModelPtr> items_to_return; for (auto& model : all_items) { if (!is_main_view && model->WasActionedOn()) { @@ -557,6 +233,9 @@ DownloadCommands::Command command) { DCHECK(command == DownloadCommands::RETRY); display_controller_->HideBubble(); + if (!download_manager_) { + return; + } RecordDownloadRetry( OfflineItemUtils::ConvertFailStateToDownloadInterruptReason( model->GetLastFailState()));
diff --git a/chrome/browser/download/bubble/download_bubble_ui_controller.h b/chrome/browser/download/bubble/download_bubble_ui_controller.h index c8d58e69..2a57a6b 100644 --- a/chrome/browser/download/bubble/download_bubble_ui_controller.h +++ b/chrome/browser/download/bubble/download_bubble_ui_controller.h
@@ -8,6 +8,7 @@ #include <set> #include "base/scoped_observation.h" +#include "chrome/browser/download/bubble/download_bubble_update_service.h" #include "chrome/browser/download/bubble/download_display_controller.h" #include "chrome/browser/download/offline_item_model.h" #include "components/download/content/public/all_download_item_notifier.h" @@ -18,73 +19,55 @@ class Profile; -using OfflineItemState = ::offline_items_collection::OfflineItemState; -using ContentId = ::offline_items_collection::ContentId; -using OfflineContentProvider = - ::offline_items_collection::OfflineContentProvider; -using OfflineContentAggregator = - ::offline_items_collection::OfflineContentAggregator; -using OfflineItem = ::offline_items_collection::OfflineItem; -using UpdateDelta = ::offline_items_collection::UpdateDelta; -using DownloadUIModelPtr = ::DownloadUIModel::DownloadUIModelPtr; -using OfflineItemList = - ::offline_items_collection::OfflineContentAggregator::OfflineItemList; - // This handles the window-level logic for controlling the download bubble. // There is one instance of this class per browser window, and it is owned by // the download toolbar button. -class DownloadBubbleUIController - : public OfflineContentProvider::Observer, - public download::AllDownloadItemNotifier::Observer { +class DownloadBubbleUIController { public: explicit DownloadBubbleUIController(Browser* browser); + // Used to inject a custom DownloadBubbleUpdateService for testing. Prefer + // the constructor above which uses that of the profile. + DownloadBubbleUIController(Browser* browser, + DownloadBubbleUpdateService* update_service); + DownloadBubbleUIController(const DownloadBubbleUIController&) = delete; DownloadBubbleUIController& operator=(const DownloadBubbleUIController&) = delete; - ~DownloadBubbleUIController() override; + ~DownloadBubbleUIController(); + + // These methods are called to notify the UI of new events. + // |may_show_animation| is whether the window this controller belongs to may + // show the animation. (Whether the animation is actually shown may depend on + // the download and the device's graphics capabilities.) We don't show an + // animation for offline items. Notifications for created/added download items + // generally come from the DownloadUIController(Delegate) (except for crx + // downloads, which come via the DownloadBubbleUpdateService), and the rest + // are called from DownloadBubbleUpdateService. + void OnDownloadItemAdded(download::DownloadItem* item, + bool may_show_animation); + void OnDownloadItemUpdated(download::DownloadItem* item); + void OnDownloadItemRemoved(download::DownloadItem* item); + void OnDownloadManagerGoingDown(); + void OnOfflineItemsAdded( + const OfflineContentProvider::OfflineItemList& items); + void OnOfflineItemUpdated(const OfflineItem& item); + void OnOfflineItemRemoved(const ContentId& id); // Get the entries for the main view of the Download Bubble. The main view // contains all the recent downloads (finished within the last 24 hours). - std::vector<DownloadUIModelPtr> GetMainView(); + std::vector<DownloadUIModel::DownloadUIModelPtr> GetMainView(); // Get the entries for the partial view of the Download Bubble. The partial // view contains in-progress and uninteracted downloads, meant to capture the // user's recent tasks. This can only be opened by the browser in the event of // new downloads, and user action only creates a main view. - std::vector<DownloadUIModelPtr> GetPartialView(); - - // Get all entries that should be displayed in the UI, including downloads and - // offline items. - std::vector<DownloadUIModelPtr> GetAllItemsToDisplay(); - - // Gets all entries that are in-progress (as determined by IsModelInProgress). - // Includes downloads and offline items. Also prunes invalid guids from - // |in_progress_download_item_guids_|. Virtual for testing. - virtual std::vector<DownloadUIModelPtr> GetInProgressItems(); - - // The list is needed to populate GetAllItemsToDisplay. - virtual const OfflineItemList& GetOfflineItems(); - - // The list is needed to populate GetAllItemsToDisplay. - virtual const std::vector<download::DownloadItem*> GetDownloadItems(); - - // This function makes sure that the offline items field is - // populated, and then calls the given callback. After this, GetOfflineItems - // will return a populated list. - virtual void InitOfflineItems(DownloadDisplayController* display_controller, - base::OnceCallback<void()> callback); + std::vector<DownloadUIModel::DownloadUIModelPtr> GetPartialView(); // Process button press on the bubble. void ProcessDownloadButtonPress(DownloadUIModel* model, DownloadCommands::Command command, bool is_main_view); - // Notify when a new download is ready to be shown on UI, and if the window - // this controller belongs to may show the animation. (Whether the animation - // is actually shown may depend on the download and the device's graphics - // capabilities.) - void OnNewItem(download::DownloadItem* item, bool may_show_animation); - // Notify when a download toolbar button (in any window) is pressed. void HandleButtonPressed(); @@ -113,99 +96,40 @@ return display_controller_; } - download::AllDownloadItemNotifier& get_download_notifier_for_testing() { - return download_notifier_; + void SetDownloadDisplayController(DownloadDisplayController* controller) { + display_controller_ = controller; } - download::AllDownloadItemNotifier* get_original_notifier_for_testing() { - return original_notifier_.get(); - } + DownloadBubbleUpdateService* update_service() { return update_service_; } void set_manager_for_testing(content::DownloadManager* manager) { download_manager_ = manager; } - OfflineItemModelManager* offline_manager_for_testing() { - return offline_manager_; - } - private: friend class DownloadBubbleUIControllerTest; friend class DownloadBubbleUIControllerIncognitoTest; - // AllDownloadItemNotifier::Observer - void OnDownloadUpdated(content::DownloadManager* manager, - download::DownloadItem* item) override; - void OnDownloadRemoved(content::DownloadManager* manager, - download::DownloadItem* item) override; - void OnManagerGoingDown(content::DownloadManager* manager) override; - - // OfflineContentProvider::Observer - void OnItemsAdded( - const OfflineContentProvider::OfflineItemList& items) override; - void OnItemRemoved(const ContentId& id) override; - void OnItemUpdated(const OfflineItem& item, - const absl::optional<UpdateDelta>& update_delta) override; - void OnContentProviderGoingDown() override; - - // Try to add the items to the set/list(s) and calling callback on completion. - void MaybeAddOfflineItems(base::OnceCallback<void()> callback, - bool is_new, - const OfflineItemList& offline_items); - - // Try to add the new item to the list, returning success status. - bool MaybeAddOfflineItem(const OfflineItem& item, bool is_new); - - // Prune OfflineItems to recent items to in-progress offline items, or - // downloads started in the last day. - void PruneOfflineItems(); // Common method for getting main and partial views. - std::vector<DownloadUIModelPtr> GetDownloadUIModels(bool is_main_view); + std::vector<DownloadUIModel::DownloadUIModelPtr> GetDownloadUIModels( + bool is_main_view); // Kick off retrying an eligible interrupted download. void RetryDownload(DownloadUIModel* model, DownloadCommands::Command command); - // Implements OnNewItem(). - void DoOnNewItem(download::DownloadItem* item, bool may_show_animation); - - // Called by OnNewItem() if the new download UI notification should be - // delayed. If the guid no longer corresponds to a live DownloadItem, this - // does not notify the UI. This also removes the guid from the set of delayed - // guids. - void OnDelayedNewItemByGuid(const std::string& guid, - bool will_show_animation); - - void UpdateInProgressDownloadItems(const DownloadUIModel& model); - raw_ptr<Browser, DanglingUntriaged> browser_; raw_ptr<Profile, DanglingUntriaged> profile_; + raw_ptr<DownloadBubbleUpdateService> update_service_; raw_ptr<content::DownloadManager, DanglingUntriaged> download_manager_; - download::AllDownloadItemNotifier download_notifier_; - // Null if the profile is not off the record. - std::unique_ptr<download::AllDownloadItemNotifier> original_notifier_; - raw_ptr<OfflineContentAggregator, DanglingUntriaged> aggregator_; raw_ptr<OfflineItemModelManager, DanglingUntriaged> offline_manager_; - base::ScopedObservation<OfflineContentProvider, - OfflineContentProvider::Observer> - observation_{this}; + // DownloadDisplayController and DownloadBubbleUIController have the same // lifetime. Both are owned, constructed together, and destructed together by // DownloadToolbarButtonView. If one is valid, so is the other. raw_ptr<DownloadDisplayController, DanglingUntriaged> display_controller_; - // Pruned list of offline items. - OfflineItemList offline_items_; - absl::optional<base::Time> last_partial_view_shown_time_ = absl::nullopt; - // Set of GUIDs for extension/theme (crx) downloads that are pending notifying - // the UI. GUIDs are added here when the download begins, and are removed - // when the 2 second delay is up. - std::set<std::string> delayed_crx_guids_; - - // Currently in-progress downloads. - std::set<std::string> in_progress_download_item_guids_; - base::WeakPtrFactory<DownloadBubbleUIController> weak_factory_{this}; };
diff --git a/chrome/browser/download/bubble/download_bubble_ui_controller_unittest.cc b/chrome/browser/download/bubble/download_bubble_ui_controller_unittest.cc index aced206..28be732 100644 --- a/chrome/browser/download/bubble/download_bubble_ui_controller_unittest.cc +++ b/chrome/browser/download/bubble/download_bubble_ui_controller_unittest.cc
@@ -6,16 +6,20 @@ #include "base/command_line.h" #include "base/files/file_path.h" +#include "base/functional/bind.h" #include "base/memory/raw_ptr.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" +#include "chrome/browser/download/bubble/download_bubble_update_service.h" #include "chrome/browser/download/bubble/download_display.h" #include "chrome/browser/download/bubble/download_display_controller.h" #include "chrome/browser/download/bubble/download_icon_state.h" #include "chrome/browser/download/chrome_download_manager_delegate.h" #include "chrome/browser/download/download_core_service.h" #include "chrome/browser/download/download_core_service_factory.h" +#include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_prefs.h" +#include "chrome/browser/download/offline_item_model_manager_factory.h" #include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h" #include "chrome/browser/profiles/profile_key.h" #include "chrome/browser/ui/browser.h" @@ -28,6 +32,7 @@ #include "components/download/public/common/download_item.h" #include "components/download/public/common/mock_download_item.h" #include "components/offline_items_collection/core/offline_item.h" +#include "components/offline_items_collection/core/offline_item_state.h" #include "components/offline_items_collection/core/test_support/mock_offline_content_provider.h" #include "content/public/browser/download_item_utils.h" #include "content/public/test/browser_task_environment.h" @@ -35,48 +40,99 @@ #include "content/public/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" -using testing::_; -using testing::NiceMock; -using testing::Return; -using testing::ReturnRef; -using testing::ReturnRefOfCopy; -using testing::SetArgPointee; - namespace { +using ::offline_items_collection::OfflineItemState; +using ::testing::_; +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::ReturnRefOfCopy; +using ::testing::SetArgPointee; +using ::testing::StrictMock; using StrictMockDownloadItem = testing::StrictMock<download::MockDownloadItem>; using DownloadDangerType = download::DownloadDangerType; using DownloadIconState = download::DownloadIconState; using DownloadState = download::DownloadItem::DownloadState; +using DownloadUIModelPtr = DownloadUIModel::DownloadUIModelPtr; +using OfflineItemList = + offline_items_collection::OfflineContentProvider::OfflineItemList; + const char kProviderNamespace[] = "mock_namespace"; class MockDownloadDisplayController : public DownloadDisplayController { public: MockDownloadDisplayController(Browser* browser, DownloadBubbleUIController* bubble_controller) - : DownloadDisplayController(nullptr, browser, bubble_controller) {} + : DownloadDisplayController(nullptr, browser, bubble_controller) { + bubble_controller->SetDownloadDisplayController(this); + } void MaybeShowButtonWhenCreated() override {} MOCK_METHOD1(OnNewItem, void(bool)); MOCK_METHOD3(OnUpdatedItem, void(bool, bool, bool)); MOCK_METHOD1(OnRemovedItem, void(const ContentId&)); }; -struct DownloadSortingState { - std::string id; - base::TimeDelta offset; - DownloadState state; - bool is_paused; - DownloadSortingState(const std::string& id, - base::TimeDelta offset, - DownloadState state, - bool is_paused) { - this->id = id; - this->offset = offset; - this->state = state; - this->is_paused = is_paused; - } -}; +class MockDownloadBubbleUpdateService : public DownloadBubbleUpdateService { + public: + enum class ModelType { + kDownloadItem, + kOfflineItem, + }; -} // namespace + MockDownloadBubbleUpdateService( + Profile* profile, + const std::vector<std::unique_ptr<StrictMockDownloadItem>>& + download_items, + const OfflineItemList& offline_items) + : DownloadBubbleUpdateService(profile), + profile_(profile), + download_items_(download_items), + offline_items_(offline_items) {} + MockDownloadBubbleUpdateService(const MockDownloadBubbleUpdateService&) = + delete; + MockDownloadBubbleUpdateService& operator=( + const MockDownloadBubbleUpdateService&) = delete; + + ~MockDownloadBubbleUpdateService() override = default; + + bool GetAllModelsToDisplay( + std::vector<DownloadUIModelPtr>& models, + bool force_backfill_download_items = true) override { + models.clear(); + int download_item_index = 0, offline_item_index = 0; + // Compose a list of models from the items stored in the test fixture. + for (ModelType type : model_types_) { + if (type == ModelType::kDownloadItem) { + auto model = DownloadItemModel::Wrap( + download_items_.at(download_item_index++).get()); + if (model->ShouldShowInBubble()) { + models.push_back(std::move(model)); + } + } else { + auto model = OfflineItemModel::Wrap( + OfflineItemModelManagerFactory::GetForBrowserContext(profile_), + offline_items_.at(offline_item_index++)); + if (model->ShouldShowInBubble()) { + models.push_back(std::move(model)); + } + } + } + return true; + } + + void AddModel(ModelType type) { model_types_.push_back(type); } + + MOCK_METHOD(DownloadDisplayController::ProgressInfo, + GetProgressInfo, + (), + (const override)); + + private: + Profile* profile_; + std::vector<ModelType> model_types_; + const std::vector<std::unique_ptr<StrictMockDownloadItem>>& download_items_; + const OfflineItemList& offline_items_; +}; class DownloadBubbleUIControllerTest : public testing::Test { public: @@ -109,17 +165,21 @@ OfflineContentAggregatorFactory::GetForKey(profile_->GetProfileKey()) ->RegisterProvider(kProviderNamespace, content_provider_.get()); + mock_update_service_ = + std::make_unique<StrictMock<MockDownloadBubbleUpdateService>>( + profile_, items_, offline_items_); window_ = std::make_unique<TestBrowserWindow>(); Browser::CreateParams params(profile_, true); params.type = Browser::TYPE_NORMAL; params.window = window_.get(); browser_ = std::unique_ptr<Browser>(Browser::Create(params)); - controller_ = std::make_unique<DownloadBubbleUIController>(browser_.get()); + controller_ = std::make_unique<DownloadBubbleUIController>( + browser_.get(), mock_update_service_.get()); display_controller_ = std::make_unique<NiceMock<MockDownloadDisplayController>>( browser_.get(), controller_.get()); - second_controller_ = - std::make_unique<DownloadBubbleUIController>(browser_.get()); + second_controller_ = std::make_unique<DownloadBubbleUIController>( + browser_.get(), mock_update_service_.get()); second_display_controller_ = std::make_unique<NiceMock<MockDownloadDisplayController>>( browser_.get(), second_controller_.get()); @@ -130,17 +190,13 @@ void TearDown() override { DownloadCoreServiceFactory::GetForBrowserContext(profile_) ->SetDownloadManagerDelegateForTesting(nullptr); - for (auto& item : items_) { - item->RemoveObserver(&controller_->get_download_notifier_for_testing()); - item->RemoveObserver( - &second_controller_->get_download_notifier_for_testing()); - } // The controller needs to be reset before download manager, because the // download_notifier_ will unregister itself from the manager. controller_.reset(); second_controller_.reset(); display_controller_.reset(); second_display_controller_.reset(); + mock_update_service_.reset(); } protected: @@ -161,6 +217,9 @@ content_provider() { return *content_provider_; } + MockDownloadBubbleUpdateService* mock_update_service() { + return mock_update_service_.get(); + } void InitDownloadItem( const base::FilePath::CharType* path, @@ -219,10 +278,11 @@ .WillRepeatedly(SetArgPointee<0>(items)); EXPECT_CALL(*manager_, GetDownloadByGuid(id)) .WillRepeatedly(Return(&(item(index)))); - item(index).AddObserver(&controller().get_download_notifier_for_testing()); - content::DownloadItemUtils::AttachInfoForTesting(&(item(index)), profile_, + content::DownloadItemUtils::AttachInfoForTesting(&(item(index)), profile(), nullptr); - controller().OnNewItem(&item(index), may_show_animation); + mock_update_service_->AddModel( + MockDownloadBubbleUpdateService::ModelType::kDownloadItem); + controller().OnDownloadItemAdded(&item(index), may_show_animation); } void UpdateDownloadItem( @@ -247,7 +307,7 @@ EXPECT_CALL(item(item_index), GetDangerType()) .WillRepeatedly(Return(danger_type)); EXPECT_CALL(item(item_index), IsPaused()).WillRepeatedly(Return(is_paused)); - item(item_index).NotifyObserversDownloadUpdated(); + controller().OnDownloadItemUpdated(&item(item_index)); } void InitOfflineItem(OfflineItemState state, std::string id) { @@ -255,14 +315,14 @@ item.state = state; item.id.id = id; offline_items_.push_back(item); - content_provider().NotifyOnItemsAdded({item}); + mock_update_service_->AddModel( + MockDownloadBubbleUpdateService::ModelType::kOfflineItem); + controller().OnOfflineItemsAdded({item}); } void UpdateOfflineItem(int item_index, OfflineItemState state) { offline_items_[item_index].state = state; - UpdateDelta delta; - delta.state_changed = true; - content_provider().NotifyOnItemUpdated(offline_items_[item_index], delta); + controller().OnOfflineItemUpdated(offline_items_[item_index]); } content::BrowserTaskEnvironment task_environment_{ @@ -281,6 +341,8 @@ NiceMock<offline_items_collection::MockOfflineContentProvider>> content_provider_; std::unique_ptr<TestBrowserWindow> window_; + std::unique_ptr<StrictMock<MockDownloadBubbleUpdateService>> + mock_update_service_; std::unique_ptr<Browser> browser_; raw_ptr<TestingProfile> profile_; }; @@ -370,166 +432,6 @@ EXPECT_EQ(main_view.size(), 2u); } -TEST_F(DownloadBubbleUIControllerTest, FastCrxDownloadShowsNoUI) { - std::string id = "fast_crx"; - EXPECT_CALL(display_controller(), OnNewItem(_)).Times(0); - EXPECT_CALL(display_controller(), OnUpdatedItem(_, _, _)).Times(0); - InitDownloadItem(FILE_PATH_LITERAL("/foo/bar2.pdf"), - download::DownloadItem::IN_PROGRESS, id, - /*is_transient=*/false, /*start_time=*/base::Time::Now(), - /*may_show_animation=*/true, - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - "application/x-chrome-extension"); - EXPECT_CALL(*manager_, GetDownloadByGuid(id)) - .WillRepeatedly(Return(items_[0].get())); - task_environment_.FastForwardBy(base::Seconds(1)); - UpdateDownloadItem(/*item_index=*/0, DownloadState::COMPLETE); -} - -TEST_F(DownloadBubbleUIControllerTest, SlowCrxDownloadShowsDelayedUI) { - std::string id = "slow_crx"; - EXPECT_CALL(display_controller(), OnNewItem(_)).Times(0); - EXPECT_CALL(display_controller(), OnUpdatedItem(_, _, _)).Times(0); - InitDownloadItem(FILE_PATH_LITERAL("/foo/bar2.pdf"), - download::DownloadItem::IN_PROGRESS, id, - /*is_transient=*/false, /*start_time=*/base::Time::Now(), - /*may_show_animation=*/true, - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - "application/x-chrome-extension"); - EXPECT_CALL(*manager_, GetDownloadByGuid(id)) - .WillRepeatedly(Return(items_[0].get())); - EXPECT_CALL(display_controller(), OnNewItem(true)).Times(1); - EXPECT_CALL(display_controller(), OnUpdatedItem(false, false, true)).Times(1); - task_environment_.FastForwardBy(base::Seconds(2)); - UpdateDownloadItem(/*item_index=*/0, DownloadState::IN_PROGRESS); - EXPECT_CALL(display_controller(), OnUpdatedItem(true, false, true)).Times(1); - UpdateDownloadItem(/*item_index=*/0, DownloadState::COMPLETE); -} - -TEST_F(DownloadBubbleUIControllerTest, ListIsSorted) { - std::vector<DownloadSortingState> sort_states = { - DownloadSortingState("Download 1", base::Hours(2), - DownloadState::IN_PROGRESS, /*is_paused=*/false), - DownloadSortingState("Download 2", base::Hours(4), - DownloadState::IN_PROGRESS, /*is_paused=*/true), - DownloadSortingState("Download 3", base::Hours(3), - DownloadState::COMPLETE, /*is_paused=*/false), - DownloadSortingState("Download 4", base::Hours(0), - DownloadState::IN_PROGRESS, /*is_paused=*/false), - DownloadSortingState("Download 5", base::Hours(1), - DownloadState::COMPLETE, /*is_paused=*/false)}; - - // Offline item will be in-progress. Non in-progress offline items do not - // surface. - std::string offline_item = "Offline 1"; - // First non-paused in-progress, then paused in-progress, then completed, - // sub-sorted by starting times. - std::vector<std::string> sorted_ids = {"Download 4", "Download 1", - "Offline 1", "Download 2", - "Download 5", "Download 3"}; - base::Time now = base::Time::Now(); - for (unsigned long i = 0; i < sort_states.size(); i++) { - InitDownloadItem(FILE_PATH_LITERAL("/foo/bar.pdf"), - DownloadState::IN_PROGRESS, sort_states[i].id, - /*is_transient=*/false, now - sort_states[i].offset); - UpdateDownloadItem(/*item_index=*/i, sort_states[i].state, - sort_states[i].is_paused); - } - InitOfflineItem(OfflineItemState::IN_PROGRESS, offline_item); - - std::vector<DownloadUIModelPtr> in_progress_models = - controller().GetInProgressItems(); - EXPECT_EQ(in_progress_models.size(), 4u); - for (unsigned long i = 0; i < 4u; i++) { - EXPECT_EQ(in_progress_models[i]->GetContentId().id, sorted_ids[i]); - } - - std::vector<DownloadUIModelPtr> models = controller().GetMainView(); - EXPECT_EQ(models.size(), sorted_ids.size()); - for (unsigned long i = 0; i < models.size(); i++) { - EXPECT_EQ(models[i]->GetContentId().id, sorted_ids[i]); - } -} - -TEST_F(DownloadBubbleUIControllerTest, ListIsRecent) { - std::vector<std::string> ids = {"Download 1", "Download 2", "Download 3", - "Offline 1"}; - std::vector<base::TimeDelta> start_time_offsets = { - base::Hours(1), base::Hours(25), base::Hours(2)}; - std::vector<std::string> sorted_ids = {"Download 1", "Download 3", - "Offline 1"}; - base::Time now = base::Time::Now(); - InitDownloadItem(FILE_PATH_LITERAL("/foo/bar.pdf"), - download::DownloadItem::IN_PROGRESS, ids[0], - /*is_transient=*/false, now - start_time_offsets[0]); - InitDownloadItem(FILE_PATH_LITERAL("/foo/bar2.pdf"), - download::DownloadItem::IN_PROGRESS, ids[1], - /*is_transient=*/false, now - start_time_offsets[1]); - InitDownloadItem(FILE_PATH_LITERAL("/foo/bar3.pdf"), - download::DownloadItem::IN_PROGRESS, ids[2], - /*is_transient=*/false, now - start_time_offsets[2]); - InitOfflineItem(OfflineItemState::IN_PROGRESS, ids[3]); - - std::vector<DownloadUIModelPtr> in_progress_models = - controller().GetInProgressItems(); - EXPECT_EQ(in_progress_models.size(), sorted_ids.size()); - for (unsigned long i = 0; i < in_progress_models.size(); i++) { - EXPECT_EQ(in_progress_models[i]->GetContentId().id, sorted_ids[i]); - } - - std::vector<DownloadUIModelPtr> models = controller().GetMainView(); - EXPECT_EQ(models.size(), sorted_ids.size()); - for (unsigned long i = 0; i < models.size(); i++) { - EXPECT_EQ(models[i]->GetContentId().id, sorted_ids[i]); - } -} - -// Tests that the list is limited to kMaxDownloadsToShow items, and that they -// are the most recent kMaxDownloadsToShow items. -TEST_F(DownloadBubbleUIControllerTest, ListIsCappedAndMostRecent) { - const size_t kMaxDownloadsToShow = 100; - const size_t kNumDownloads = kMaxDownloadsToShow + 1; - const base::Time kFirstStartTime = - base::Time::Now() - base::Seconds(kNumDownloads); - // Create 101 downloads in chronological order, such that the first 100 are - // *not* the 100 most recent. Note that DownloadManager does not guarantee - // any order on the items returned from GetAllDownloads(). We still want to - // ensure that the most recent ones are returned. - for (size_t i = 0; i < kNumDownloads; ++i) { - std::string id = base::NumberToString(i); - InitDownloadItem(FILE_PATH_LITERAL("/foo/bar.pdf"), - download::DownloadItem::IN_PROGRESS, id, - /*is_transient=*/false, - kFirstStartTime + base::Seconds(i)); - } - - std::vector<DownloadUIModelPtr> in_progress_models = - controller().GetInProgressItems(); - EXPECT_EQ(in_progress_models.size(), kMaxDownloadsToShow); - for (const DownloadUIModelPtr& model : in_progress_models) { - // Expect the oldest download, which started at kFirstStartTime, to be the 1 - // excluded, due to the sorting in GetInProgressItems. - EXPECT_GT(model->GetStartTime(), kFirstStartTime); - } - - std::vector<DownloadUIModelPtr> partial_view_models = - controller().GetPartialView(); - EXPECT_EQ(partial_view_models.size(), kMaxDownloadsToShow); - for (const DownloadUIModelPtr& model : partial_view_models) { - // Expect the oldest download, which started at kFirstStartTime, to be the 1 - // excluded, despite being the first returned from GetAllDownloads(). - EXPECT_GT(model->GetStartTime(), kFirstStartTime); - } - - std::vector<DownloadUIModelPtr> main_view_models = controller().GetMainView(); - EXPECT_EQ(main_view_models.size(), kMaxDownloadsToShow); - for (const DownloadUIModelPtr& model : main_view_models) { - // Expect the oldest download, which started at kFirstStartTime, to be the 1 - // excluded, despite being the first returned from GetAllDownloads(). - EXPECT_GT(model->GetStartTime(), kFirstStartTime); - } -} - TEST_F(DownloadBubbleUIControllerTest, OpeningMainViewRemovesCompletedEntryFromPartialView) { std::vector<std::string> ids = {"Download 1", "Offline 1"}; @@ -541,9 +443,8 @@ EXPECT_EQ(second_controller().GetPartialView().size(), 2ul); UpdateDownloadItem(/*item_index=*/0, DownloadState::COMPLETE); - // Completed offline item is removed. UpdateOfflineItem(/*item_index=*/0, OfflineItemState::COMPLETE); - EXPECT_EQ(controller().GetMainView().size(), 1ul); + EXPECT_EQ(controller().GetMainView().size(), 2ul); // Download was removed from partial view because it is completed. EXPECT_EQ(controller().GetPartialView().size(), 0ul); EXPECT_EQ(second_controller().GetPartialView().size(), 0ul); @@ -603,77 +504,4 @@ EXPECT_EQ(controller().GetPartialView().size(), 1u); } -class DownloadBubbleUIControllerIncognitoTest - : public DownloadBubbleUIControllerTest { - public: - DownloadBubbleUIControllerIncognitoTest() = default; - DownloadBubbleUIControllerIncognitoTest( - const DownloadBubbleUIControllerIncognitoTest&) = delete; - DownloadBubbleUIControllerIncognitoTest& operator=( - const DownloadBubbleUIControllerIncognitoTest&) = delete; - - void SetUp() override { - DownloadBubbleUIControllerTest::SetUp(); - incognito_profile_ = TestingProfile::Builder().BuildIncognito(profile()); - incognito_window_ = std::make_unique<TestBrowserWindow>(); - Browser::CreateParams params(incognito_profile_, true); - params.type = Browser::TYPE_NORMAL; - params.window = incognito_window_.get(); - incognito_browser_ = std::unique_ptr<Browser>(Browser::Create(params)); - incognito_controller_ = - std::make_unique<DownloadBubbleUIController>(incognito_browser_.get()); - incognito_display_controller_ = - std::make_unique<NiceMock<MockDownloadDisplayController>>( - incognito_browser_.get(), incognito_controller_.get()); - } - - void TearDown() override { - for (auto& item : items()) { - item->RemoveObserver( - incognito_controller_->get_original_notifier_for_testing()); - } - // The controller needs to be reset before download manager, because the - // download_notifier_ will unregister itself from the manager. - incognito_controller_.reset(); - incognito_display_controller_.reset(); - DownloadBubbleUIControllerTest::TearDown(); - } - - protected: - std::unique_ptr<TestBrowserWindow> incognito_window_; - std::unique_ptr<Browser> incognito_browser_; - raw_ptr<TestingProfile> incognito_profile_; - std::unique_ptr<DownloadBubbleUIController> incognito_controller_; - std::unique_ptr<NiceMock<MockDownloadDisplayController>> - incognito_display_controller_; -}; - -TEST_F(DownloadBubbleUIControllerIncognitoTest, - IncludeDownloadsFromMainProfile) { - std::string download_id = "Download 1"; - InitDownloadItem(FILE_PATH_LITERAL("/foo/bar.pdf"), - download::DownloadItem::IN_PROGRESS, download_id); - std::vector<DownloadUIModelPtr> main_view = - incognito_controller_->GetMainView(); - // The main view should contain downloads from the main profile. - EXPECT_EQ(main_view.size(), 1ul); -} - -TEST_F(DownloadBubbleUIControllerIncognitoTest, DoesNotShowDetailsIfDone) { - std::string download_id = "Download 1"; - InitDownloadItem(FILE_PATH_LITERAL("/foo/bar.pdf"), - download::DownloadItem::IN_PROGRESS, download_id); - UpdateDownloadItem(/*item_index=*/0, DownloadState::COMPLETE); - item(0).AddObserver( - incognito_controller_->get_original_notifier_for_testing()); - content::DownloadItemUtils::AttachInfoForTesting(&(item(0)), - incognito_profile_, nullptr); - // `may_show_details` is false because the download is initiated from the - // main profile. - EXPECT_CALL( - *incognito_display_controller_, - OnUpdatedItem(/*is_done=*/true, /*is_pending_deep_scanning=*/false, - /*may_show_details=*/false)) - .Times(1); - item(0).NotifyObserversDownloadUpdated(); -} +} // namespace
diff --git a/chrome/browser/download/bubble/download_bubble_update_service.cc b/chrome/browser/download/bubble/download_bubble_update_service.cc index 3eb110a..13460309 100644 --- a/chrome/browser/download/bubble/download_bubble_update_service.cc +++ b/chrome/browser/download/bubble/download_bubble_update_service.cc
@@ -14,8 +14,10 @@ #include "base/task/single_thread_task_runner.h" #include "base/time/time.h" #include "chrome/browser/content_index/content_index_provider_impl.h" +#include "chrome/browser/download/bubble/download_bubble_ui_controller.h" #include "chrome/browser/download/bubble/download_bubble_utils.h" #include "chrome/browser/download/bubble/download_display_controller.h" +#include "chrome/browser/download/download_crx_util.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_ui_model.h" #include "chrome/browser/download/offline_item_model_manager.h" @@ -24,6 +26,9 @@ #include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_key.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_window.h" #include "components/download/content/public/all_download_item_notifier.h" #include "components/download/public/common/download_item.h" #include "components/offline_items_collection/core/offline_content_provider.h" @@ -54,6 +59,16 @@ // Amount of time to show an item in the bubble. Items older than this duration // ago will be pruned. constexpr base::TimeDelta kShowItemInBubbleDuration = base::Hours(24); +// Don't send the "download started" notification for an extension or theme +// (crx) download until 2 seconds after it has begun. If it is a small download +// that finishes in under 2 seconds, the download UI does not show at all. If it +// is a large download that takes longer than 2 seconds, show the UI so that the +// user knows Chrome is working on it. +constexpr base::TimeDelta kCrxShowNewItemDelay = base::Seconds(2); +// Limit the size of the |delayed_crx_guids_| set so it doesn't grow +// unboundedly. It is unlikely that the user would have 20 active crx downloads +// simultaneously. +constexpr int kMaxDelayedCrxGuids = 20; template <typename Item> ItemSortKey::State GetState(const Item& item) { @@ -169,6 +184,11 @@ DownloadBubbleUpdateService::~DownloadBubbleUpdateService() = default; +void DownloadBubbleUpdateService::Shutdown() { + offline_content_provider_observation_.Reset(); + weak_factory_.InvalidateWeakPtrs(); +} + size_t DownloadBubbleUpdateService::GetMaxNumItemsToShow() const { size_t max = max_num_items_to_show_for_testing_.value_or(kDefaultMaxNumItemsToShow); @@ -327,15 +347,59 @@ if (download_manager_shut_down_) { return; } + if (download_crx_util::IsExtensionDownload(*item) && + delayed_crx_guids_.size() < kMaxDelayedCrxGuids) { + const std::string& guid = item->GetGuid(); + CHECK(!delayed_crx_guids_.contains(guid)); + delayed_crx_guids_.insert(guid); + base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + &DownloadBubbleUpdateService::OnDelayedCrxDownloadCreated, + weak_factory_.GetWeakPtr(), guid), + kCrxShowNewItemDelay); + return; + } MaybeAddDownloadItemToCache(item, /*is_new=*/true); } +void DownloadBubbleUpdateService::OnDelayedCrxDownloadCreated( + const std::string& guid) { + if (download_manager_shut_down_) { + return; + } + // This assumes that for extension/theme downloads, the DownloadItem is + // removed from the DownloadManager upon completion. + download::DownloadItem* item = + download_item_notifier_.GetManager()->GetDownloadByGuid(guid); + if (item && !item->IsDone()) { + MaybeAddDownloadItemToCache(item, /*is_new=*/true); + + Browser* browser_to_show_animation = + FindBrowserToShowAnimation(item, profile_); + for (Browser* browser : chrome::FindAllBrowsersWithProfile(profile_)) { + if (browser->window() && + browser->window()->GetDownloadBubbleUIController()) { + browser->window()->GetDownloadBubbleUIController()->OnDownloadItemAdded( + item, /*may_show_animation=*/browser == browser_to_show_animation); + } + } + } + size_t erased = delayed_crx_guids_.erase(guid); + CHECK_EQ(erased, 1u); +} + void DownloadBubbleUpdateService::OnDownloadUpdated( content::DownloadManager* manager, download::DownloadItem* item) { if (download_manager_shut_down_) { return; } + // If the item is an extension or theme download waiting out its 2-second + // delay, don't show a UI update for it. + if (delayed_crx_guids_.contains(item->GetGuid())) { + return; + } bool cache_was_at_max = IsCacheAtMax(download_items_); bool removed_item = RemoveDownloadItemFromCache(item); bool added_back_at_end = MaybeAddDownloadItemToCache(item, /*is_new=*/false); @@ -345,6 +409,14 @@ std::prev(GetLastIter(download_items_))->first; StartBackfillDownloadItems(last_key); } + + for (Browser* browser : chrome::FindAllBrowsersWithProfile(profile_)) { + if (browser->window() && + browser->window()->GetDownloadBubbleUIController()) { + browser->window()->GetDownloadBubbleUIController()->OnDownloadItemUpdated( + item); + } + } } void DownloadBubbleUpdateService::OnDownloadRemoved( @@ -359,6 +431,14 @@ const ItemSortKey& last_key = GetLastIter(download_items_)->first; StartBackfillDownloadItems(last_key); } + + for (Browser* browser : chrome::FindAllBrowsersWithProfile(profile_)) { + if (browser->window() && + browser->window()->GetDownloadBubbleUIController()) { + browser->window()->GetDownloadBubbleUIController()->OnDownloadItemRemoved( + item); + } + } } void DownloadBubbleUpdateService::OnManagerGoingDown( @@ -370,6 +450,14 @@ download_manager_shut_down_ = true; download_items_.clear(); download_items_iter_map_.clear(); + for (Browser* browser : chrome::FindAllBrowsersWithProfile(profile_)) { + if (browser->window() && + browser->window()->GetDownloadBubbleUIController()) { + browser->window() + ->GetDownloadBubbleUIController() + ->OnDownloadManagerGoingDown(); + } + } } } @@ -387,6 +475,14 @@ for (const OfflineItem& item : items) { MaybeAddOfflineItemToCache(item, /*is_new=*/true); } + + for (Browser* browser : chrome::FindAllBrowsersWithProfile(profile_)) { + if (browser->window() && + browser->window()->GetDownloadBubbleUIController()) { + browser->window()->GetDownloadBubbleUIController()->OnOfflineItemsAdded( + items); + } + } } void DownloadBubbleUpdateService::OnItemRemoved(const ContentId& id) { @@ -405,6 +501,14 @@ const ItemSortKey& last_key = GetLastIter(offline_items_)->first; StartBackfillOfflineItems(last_key); } + + for (Browser* browser : chrome::FindAllBrowsersWithProfile(profile_)) { + if (browser->window() && + browser->window()->GetDownloadBubbleUIController()) { + browser->window()->GetDownloadBubbleUIController()->OnOfflineItemRemoved( + id); + } + } } void DownloadBubbleUpdateService::OnItemUpdated( @@ -427,6 +531,14 @@ const ItemSortKey& last_key = std::prev(GetLastIter(offline_items_))->first; StartBackfillOfflineItems(last_key); } + + for (Browser* browser : chrome::FindAllBrowsersWithProfile(profile_)) { + if (browser->window() && + browser->window()->GetDownloadBubbleUIController()) { + browser->window()->GetDownloadBubbleUIController()->OnOfflineItemUpdated( + item); + } + } } void DownloadBubbleUpdateService::OnContentProviderGoingDown() { @@ -566,12 +678,18 @@ void DownloadBubbleUpdateService::BackfillDownloadItems( const ItemSortKey& last_key) { + if (download_manager_shut_down_) { + return; + } BackfillItemsImpl(last_key, GetAllDownloadItems(), download_items_, download_items_iter_map_); } void DownloadBubbleUpdateService::StartBackfillOfflineItems( const ItemSortKey& last_key) { + if (offline_content_provider_shut_down_) { + return; + } offline_items_collection::OfflineContentProvider* provider = OfflineContentAggregatorFactory::GetForKey(profile_->GetProfileKey()); provider->GetAllItems(
diff --git a/chrome/browser/download/bubble/download_bubble_update_service.h b/chrome/browser/download/bubble/download_bubble_update_service.h index c2920d7..4c3c0bc 100644 --- a/chrome/browser/download/bubble/download_bubble_update_service.h +++ b/chrome/browser/download/bubble/download_bubble_update_service.h
@@ -15,6 +15,7 @@ #include "chrome/browser/download/bubble/download_display_controller.h" #include "chrome/browser/download/download_ui_model.h" #include "components/download/content/public/all_download_item_notifier.h" +#include "components/keyed_service/core/keyed_service.h" #include "components/offline_items_collection/core/offline_content_provider.h" #include "components/offline_items_collection/core/offline_item.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -32,10 +33,9 @@ // Caches download items and offline items in sorted order, so that UI updates // can be processed more quickly without fetching and sorting all items every // time. Passes notifications on to the window-level UI controllers. -// TODO(chlily): Instantiate this as a KeyedService. -// TODO(chlily): Hook this up to the window-level UI controllers. class DownloadBubbleUpdateService - : public download::AllDownloadItemNotifier::Observer, + : public KeyedService, + public download::AllDownloadItemNotifier::Observer, public offline_items_collection::OfflineContentProvider::Observer { public: // Defines sort priority for items. @@ -85,8 +85,8 @@ // be backfilled synchronously if necessary; offline items will not be // backfilled synchronously). |models| is cleared. Returns whether results are // complete. Results may not be complete if there might be more items to be - // returned after backfilling. - bool GetAllModelsToDisplay( + // returned after backfilling. Virtual for testing. + virtual bool GetAllModelsToDisplay( std::vector<DownloadUIModel::DownloadUIModelPtr>& models, bool force_backfill_download_items = false); @@ -94,8 +94,11 @@ // cache or backfill missing items, so the returned progress info may be // slightly inaccurate in edge cases. This is ok, as it is only for the // purpose of showing a progress ring around the icon, which is not precise - // anyway. - DownloadDisplayController::ProgressInfo GetProgressInfo() const; + // anyway. Virtual for testing. + virtual DownloadDisplayController::ProgressInfo GetProgressInfo() const; + + // KeyedService: + void Shutdown() override; // download::AllDownloadItemNotifier::Observer: void OnDownloadCreated(content::DownloadManager* manager, @@ -237,6 +240,11 @@ base::Time cutoff_time, std::vector<DownloadUIModel::DownloadUIModelPtr>& models); + // Called when a crx download has waited out its 2 second delay. Adds the + // item to the cache if it's not already done, and notifies window-level + // controllers. + void OnDelayedCrxDownloadCreated(const std::string& guid); + #if DCHECK_IS_ON() // Checks that the cache data structures are consistent. bool ConsistencyCheckCaches() const; @@ -284,6 +292,11 @@ bool download_manager_shut_down_ = false; bool offline_content_provider_shut_down_ = false; + // Set of GUIDs for extension/theme (crx) downloads that are pending notifying + // the UI. GUIDs are added here when the download begins, and are removed + // when the 2 second delay is up. + std::set<std::string> delayed_crx_guids_; + // Observes the offline content provider. base::ScopedObservation< offline_items_collection::OfflineContentProvider,
diff --git a/chrome/browser/download/bubble/download_bubble_update_service_factory.cc b/chrome/browser/download/bubble/download_bubble_update_service_factory.cc new file mode 100644 index 0000000..12936b9 --- /dev/null +++ b/chrome/browser/download/bubble/download_bubble_update_service_factory.cc
@@ -0,0 +1,42 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/download/bubble/download_bubble_update_service_factory.h" + +#include "base/no_destructor.h" +#include "chrome/browser/download/bubble/download_bubble_update_service.h" +#include "chrome/browser/download/offline_item_model_manager_factory.h" +#include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_selections.h" + +// static +DownloadBubbleUpdateServiceFactory* +DownloadBubbleUpdateServiceFactory::GetInstance() { + static base::NoDestructor<DownloadBubbleUpdateServiceFactory> instance; + return instance.get(); +} + +// static +DownloadBubbleUpdateService* DownloadBubbleUpdateServiceFactory::GetForProfile( + Profile* profile) { + return static_cast<DownloadBubbleUpdateService*>( + GetInstance()->GetServiceForBrowserContext(profile, /*create=*/true)); +} + +DownloadBubbleUpdateServiceFactory::DownloadBubbleUpdateServiceFactory() + : ProfileKeyedServiceFactory( + "DownloadBubbleUpdateService", + ProfileSelections::BuildForRegularAndIncognito()) { + DependsOn(OfflineContentAggregatorFactory::GetInstance()); + DependsOn(OfflineItemModelManagerFactory::GetInstance()); +} + +DownloadBubbleUpdateServiceFactory::~DownloadBubbleUpdateServiceFactory() = + default; + +KeyedService* DownloadBubbleUpdateServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + return new DownloadBubbleUpdateService(Profile::FromBrowserContext(context)); +}
diff --git a/chrome/browser/download/bubble/download_bubble_update_service_factory.h b/chrome/browser/download/bubble/download_bubble_update_service_factory.h new file mode 100644 index 0000000..cf4c349 --- /dev/null +++ b/chrome/browser/download/bubble/download_bubble_update_service_factory.h
@@ -0,0 +1,38 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_UPDATE_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_UPDATE_SERVICE_FACTORY_H_ + +#include "base/no_destructor.h" +#include "chrome/browser/profiles/profile_keyed_service_factory.h" + +class DownloadBubbleUpdateService; +class Profile; + +class DownloadBubbleUpdateServiceFactory : public ProfileKeyedServiceFactory { + public: + DownloadBubbleUpdateServiceFactory( + const DownloadBubbleUpdateServiceFactory&) = delete; + DownloadBubbleUpdateServiceFactory& operator=( + const DownloadBubbleUpdateServiceFactory&) = delete; + + // Returns the singleton instance of DownloadBubbleUpdateServiceFactory. + static DownloadBubbleUpdateServiceFactory* GetInstance(); + + // Returns the DownloadBubbleUpdateService associated with |profile|. + static DownloadBubbleUpdateService* GetForProfile(Profile* profile); + + private: + friend class base::NoDestructor<DownloadBubbleUpdateServiceFactory>; + + DownloadBubbleUpdateServiceFactory(); + ~DownloadBubbleUpdateServiceFactory() override; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; +}; + +#endif // CHROME_BROWSER_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_UPDATE_SERVICE_FACTORY_H_
diff --git a/chrome/browser/download/bubble/download_bubble_update_service_unittest.cc b/chrome/browser/download/bubble/download_bubble_update_service_unittest.cc index 1acc88a3..e04c68a 100644 --- a/chrome/browser/download/bubble/download_bubble_update_service_unittest.cc +++ b/chrome/browser/download/bubble/download_bubble_update_service_unittest.cc
@@ -117,6 +117,7 @@ const std::string& guid, bool is_paused, base::Time start_time = base::Time::Now(), + bool is_crx = false, bool observe = true) { size_t index = download_items_.size(); download_items_.push_back(std::make_unique<NiceMockDownloadItem>()); @@ -138,6 +139,12 @@ EXPECT_CALL(item, IsDone()).WillRepeatedly(Return(false)); EXPECT_CALL(item, IsTransient()).WillRepeatedly(Return(false)); EXPECT_CALL(item, IsPaused()).WillRepeatedly(Return(is_paused)); + EXPECT_CALL(item, GetTargetDisposition()) + .WillRepeatedly( + Return(is_crx ? download::DownloadItem::TARGET_DISPOSITION_OVERWRITE + : download::DownloadItem::TARGET_DISPOSITION_PROMPT)); + EXPECT_CALL(item, GetMimeType()) + .WillRepeatedly(Return(is_crx ? "application/x-chrome-extension" : "")); std::vector<download::DownloadItem*> items; for (size_t i = 0; i < download_items_.size(); ++i) { items.push_back(&GetDownloadItem(i)); @@ -270,15 +277,45 @@ EXPECT_EQ(models[5]->GetContentId().id, "completed_offline_item"); } -TEST_F(DownloadBubbleUpdateServiceTest, AddsDownloadItems) { +TEST_F(DownloadBubbleUpdateServiceTest, AddsNonCrxDownloadItems) { InitDownloadItem(DownloadState::IN_PROGRESS, "new_download", - /*is_paused=*/false); + /*is_paused=*/false, base::Time::Now(), /*is_crx=*/false, + /*observe=*/false); + // Manually notify the service of the new download rather than going through + // the observer update notification in InitDownloadItem(). + update_service_->OnDownloadCreated(download_manager_, &GetDownloadItem(0)); DownloadUIModelPtrVector models; EXPECT_TRUE(update_service_->GetAllModelsToDisplay(models)); ASSERT_EQ(models.size(), 1u); EXPECT_EQ(models[0]->GetContentId().id, "new_download"); } +TEST_F(DownloadBubbleUpdateServiceTest, DelaysCrx) { + InitDownloadItem(DownloadState::IN_PROGRESS, "in_progress_crx", + /*is_paused=*/false, base::Time::Now(), /*is_crx=*/true, + /*observe=*/false); + // Manually notify the service of the new download rather than going through + // the observer update notification in InitDownloadItem(). + update_service_->OnDownloadCreated(download_manager_, &GetDownloadItem(0)); + + DownloadUIModelPtrVector models; + EXPECT_TRUE(update_service_->GetAllModelsToDisplay(models)); + // The crx download does not show up immediately. + EXPECT_EQ(models.size(), 0u); + + // Updates are also withheld. + UpdateDownloadItem(0, DownloadState::IN_PROGRESS, /*is_paused=*/true); + EXPECT_TRUE(update_service_->GetAllModelsToDisplay(models)); + EXPECT_EQ(models.size(), 0u); + + task_environment_.FastForwardBy(base::Seconds(2)); + + // After the delay, the crx is added. + EXPECT_TRUE(update_service_->GetAllModelsToDisplay(models)); + ASSERT_EQ(models.size(), 1u); + EXPECT_EQ(models[0]->GetContentId().id, "in_progress_crx"); +} + TEST_F(DownloadBubbleUpdateServiceTest, EvictsExcessItemsAndBackfills) { update_service_->set_max_num_items_to_show_for_testing(3); update_service_->set_extra_items_to_cache_for_testing(0);
diff --git a/chrome/browser/download/bubble/download_bubble_utils.cc b/chrome/browser/download/bubble/download_bubble_utils.cc index 6e72ee9a..2efd9541 100644 --- a/chrome/browser/download/bubble/download_bubble_utils.cc +++ b/chrome/browser/download/bubble/download_bubble_utils.cc
@@ -5,10 +5,15 @@ #include "chrome/browser/download/bubble/download_bubble_utils.h" #include "base/time/time.h" +#include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/download/download_ui_model.h" +#include "chrome/browser/ui/browser_finder.h" #include "components/download/public/common/download_item.h" #include "components/offline_items_collection/core/offline_item.h" #include "components/offline_items_collection/core/offline_item_state.h" +#include "content/public/browser/download_item_utils.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_delegate.h" base::Time GetItemStartTime(const download::DownloadItem* item) { return item->GetStartTime(); @@ -105,3 +110,30 @@ bool IsItemPaused(const offline_items_collection::OfflineItem& item) { return item.state == offline_items_collection::OfflineItemState::PAUSED; } + +Browser* FindBrowserToShowAnimation(download::DownloadItem* item, + Profile* profile) { + content::WebContents* web_contents = + content::DownloadItemUtils::GetWebContents(item); + // For the case of DevTools web contents, we'd like to use target browser + // shelf although saving from the DevTools web contents. + if (web_contents && DevToolsWindow::IsDevToolsWindow(web_contents)) { + DevToolsWindow* devtools_window = + DevToolsWindow::AsDevToolsWindow(web_contents); + content::WebContents* inspected = + devtools_window->GetInspectedWebContents(); + // Do not overwrite web contents for the case of remote debugging. + if (inspected) { + web_contents = inspected; + } + } + Browser* browser_to_show_animation = + web_contents ? chrome::FindBrowserWithWebContents(web_contents) : nullptr; + + // As a last resort, use the last active browser for this profile. Not ideal, + // but better than not showing the download at all. + if (browser_to_show_animation == nullptr) { + browser_to_show_animation = chrome::FindLastActiveWithProfile(profile); + } + return browser_to_show_animation; +}
diff --git a/chrome/browser/download/bubble/download_bubble_utils.h b/chrome/browser/download/bubble/download_bubble_utils.h index 42213637..d7fda60b 100644 --- a/chrome/browser/download/bubble/download_bubble_utils.h +++ b/chrome/browser/download/bubble/download_bubble_utils.h
@@ -40,4 +40,9 @@ bool IsItemPaused(const download::DownloadItem* item); bool IsItemPaused(const offline_items_collection::OfflineItem& item); +// Finds the browser most appropriate to show the "download started" animation +// in. +Browser* FindBrowserToShowAnimation(download::DownloadItem* item, + Profile* profile); + #endif // CHROME_BROWSER_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_UTILS_H_
diff --git a/chrome/browser/download/bubble/download_display_controller.cc b/chrome/browser/download/bubble/download_display_controller.cc index 91e7c59..e20d2bd 100644 --- a/chrome/browser/download/bubble/download_display_controller.cc +++ b/chrome/browser/download/bubble/download_display_controller.cc
@@ -4,8 +4,10 @@ #include "chrome/browser/download/bubble/download_display_controller.h" +#include "base/functional/bind.h" #include "base/numerics/safe_conversions.h" #include "base/power_monitor/power_monitor.h" +#include "base/task/sequenced_task_runner.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "chrome/browser/download/bubble/download_bubble_prefs.h" @@ -31,6 +33,7 @@ namespace { using DownloadIconState = download::DownloadIconState; +using DownloadUIModelPtr = DownloadUIModel::DownloadUIModelPtr; // The amount of time for the toolbar icon to be visible after a download is // completed. @@ -64,7 +67,7 @@ }; AllDownloadUIModelsInfo GetAllModelsInfo( - std::vector<std::unique_ptr<DownloadUIModel>>& all_models) { + const std::vector<DownloadUIModelPtr>& all_models) { AllDownloadUIModelsInfo info; for (const auto& model : all_models) { if (model->GetDangerType() == @@ -99,12 +102,12 @@ : display_(display), browser_(browser), download_manager_(browser_->profile()->GetDownloadManager()), - download_notifier_(download_manager_, this), bubble_controller_(bubble_controller) { - bubble_controller_->InitOfflineItems( - this, - base::BindOnce(&DownloadDisplayController::MaybeShowButtonWhenCreated, - weak_factory_.GetWeakPtr())); + bubble_controller_->SetDownloadDisplayController(this); + // |display| can be null in tests. + if (display) { + MaybeShowButtonWhenCreated(); + } base::PowerMonitor::AddPowerSuspendObserver(this); } @@ -117,9 +120,7 @@ return; } - std::vector<std::unique_ptr<DownloadUIModel>> all_models = - bubble_controller_->GetAllItemsToDisplay(); - UpdateToolbarButtonState(all_models); + UpdateButtonStateFromAllModels(true); if (display_->IsFullscreenWithParentViewHidden()) { fullscreen_notification_shown_ = true; ExclusiveAccessContext* exclusive_access_context = @@ -143,8 +144,8 @@ if (!download::ShouldShowDownloadBubble(browser_->profile())) { return; } - std::vector<std::unique_ptr<DownloadUIModel>> all_models = - bubble_controller_->GetAllItemsToDisplay(); + std::vector<DownloadUIModelPtr> all_models = + UpdateButtonStateFromAllModels(true); AllDownloadUIModelsInfo info = GetAllModelsInfo(all_models); bool will_show_details = may_show_details && ((is_done && info.all_done) || is_deep_scanning); @@ -160,29 +161,20 @@ if (will_show_details) { display_->ShowDetails(); } - UpdateToolbarButtonState(all_models); } void DownloadDisplayController::OnRemovedItem(const ContentId& id) { if (!download::ShouldShowDownloadBubble(browser_->profile())) { return; } - std::vector<std::unique_ptr<DownloadUIModel>> all_models = - bubble_controller_->GetAllItemsToDisplay(); + std::vector<DownloadUIModelPtr> all_models = + UpdateButtonStateFromAllModels(true); // Hide the button if there is only one download item left and that item is // about to be removed. if (all_models.size() == 1 && all_models[0]->GetContentId() == id) { HideToolbarButton(); return; } - UpdateToolbarButtonState(all_models); -} - -void DownloadDisplayController::OnManagerGoingDown( - content::DownloadManager* manager) { - if (download_manager_ == manager) { - download_manager_ = nullptr; - } } void DownloadDisplayController::OnButtonPressed() { @@ -235,9 +227,7 @@ } fullscreen_notification_shown_ = false; - std::vector<std::unique_ptr<DownloadUIModel>> all_models = - bubble_controller_->GetAllItemsToDisplay(); - UpdateToolbarButtonState(all_models); + UpdateButtonStateFromAllModels(true); if (download::ShouldShowDownloadBubble(browser_->profile()) && details_shown_while_fullscreen_) { display_->ShowDetails(); @@ -246,9 +236,7 @@ } void DownloadDisplayController::OnResume() { - std::vector<std::unique_ptr<DownloadUIModel>> all_models = - bubble_controller_->GetAllItemsToDisplay(); - UpdateToolbarButtonState(all_models); + UpdateButtonStateFromAllModels(true); } void DownloadDisplayController::UpdateToolbarButtonState( @@ -258,8 +246,7 @@ return; } AllDownloadUIModelsInfo info = GetAllModelsInfo(all_models); - base::Time last_complete_time = - GetLastCompleteTime(bubble_controller_->GetOfflineItems()); + base::Time last_complete_time = GetLastCompleteTime(all_models); if (info.in_progress_count > 0) { icon_info_.icon_state = DownloadIconState::kProgress; @@ -298,6 +285,23 @@ display_->UpdateDownloadIcon(/*show_animation=*/false); } +std::vector<DownloadUIModelPtr> +DownloadDisplayController::UpdateButtonStateFromAllModels(bool may_retry) { + std::vector<std::unique_ptr<DownloadUIModel>> all_models; + bool results_complete = + bubble_controller_->update_service()->GetAllModelsToDisplay(all_models); + UpdateToolbarButtonState(all_models); + if (!results_complete && may_retry) { + base::SequencedTaskRunner::GetCurrentDefault()->PostTask( + FROM_HERE, + base::BindOnce( + base::IgnoreResult( + &DownloadDisplayController::UpdateButtonStateFromAllModels), + weak_factory_.GetWeakPtr(), /*may_retry=*/false)); + } + return all_models; +} + void DownloadDisplayController::ScheduleToolbarDisappearance( base::TimeDelta interval) { icon_disappearance_timer_.Stop(); @@ -314,13 +318,13 @@ } base::Time DownloadDisplayController::GetLastCompleteTime( - const offline_items_collection::OfflineContentAggregator::OfflineItemList& - offline_items) { + const std::vector<std::unique_ptr<DownloadUIModel>>& all_models) { base::Time last_time = DownloadPrefs::FromDownloadManager(download_manager_) ->GetLastCompleteTime(); - for (const auto& offline_item : offline_items) { - if (last_time < offline_item.completion_time) - last_time = offline_item.completion_time; + for (const auto& model : all_models) { + if (last_time < model->GetEndTime()) { + last_time = model->GetEndTime(); + } } return last_time; } @@ -330,14 +334,12 @@ return; } - std::vector<std::unique_ptr<DownloadUIModel>> all_models = - bubble_controller_->GetAllItemsToDisplay(); - UpdateToolbarButtonState(all_models); + std::vector<DownloadUIModelPtr> all_models = + UpdateButtonStateFromAllModels(true); if (display_->IsShowing()) { ScheduleToolbarDisappearance( kToolbarIconVisibilityTimeInterval - - (base::Time::Now() - - GetLastCompleteTime(bubble_controller_->GetOfflineItems()))); + (base::Time::Now() - GetLastCompleteTime(all_models))); } } @@ -363,26 +365,5 @@ DownloadDisplayController::ProgressInfo DownloadDisplayController::GetProgress() { - ProgressInfo progress_info; - std::vector<std::unique_ptr<DownloadUIModel>> in_progress_models = - bubble_controller_->GetInProgressItems(); - progress_info.download_count = in_progress_models.size(); - int64_t received_bytes = 0; - int64_t total_bytes = 0; - - for (const auto& model : in_progress_models) { - if (model->GetTotalBytes() <= 0) { - // There may or may not be more data coming down this pipe. - progress_info.progress_certain = false; - } else { - received_bytes += model->GetCompletedBytes(); - total_bytes += model->GetTotalBytes(); - } - } - - if (total_bytes > 0) { - progress_info.progress_percentage = - base::ClampFloor(received_bytes * 100.0 / total_bytes); - } - return progress_info; + return bubble_controller_->update_service()->GetProgressInfo(); }
diff --git a/chrome/browser/download/bubble/download_display_controller.h b/chrome/browser/download/bubble/download_display_controller.h index b68aeb6a..eddbf84 100644 --- a/chrome/browser/download/bubble/download_display_controller.h +++ b/chrome/browser/download/bubble/download_display_controller.h
@@ -33,10 +33,8 @@ // future OfflineItems include regular Download on Desktop platforms, // we can remove AllDownloadItemNotifier::Observer. // TODO(chlily): Consolidate this with DownloadBubbleUIController. -class DownloadDisplayController - : public download::AllDownloadItemNotifier::Observer, - public FullscreenObserver, - public base::PowerSuspendObserver { +class DownloadDisplayController : public FullscreenObserver, + public base::PowerSuspendObserver { public: DownloadDisplayController(DownloadDisplay* display, Browser* browser, @@ -61,9 +59,8 @@ // Returns a ProgressInfo where |download_count| is the number of currently // active downloads. If we know the final size of all downloads, // |progress_certain| is true. |progress_percentage| is the percentage - // complete of all in-progress downloads. - // - // This implementation will match the one in download_status_updater.cc + // complete of all in-progress downloads. Forwards to the + // DownloadBubbleUpdateService. ProgressInfo GetProgress(); // Returns an IconInfo that contains current state of the icon. @@ -118,10 +115,6 @@ // Returns the DownloadDisplay. Should always return a valid display. DownloadDisplay* download_display_for_testing() { return display_; } - download::AllDownloadItemNotifier& get_download_notifier_for_testing() { - return download_notifier_; - } - void set_manager_for_testing(content::DownloadManager* manager) { download_manager_ = manager; } @@ -129,6 +122,14 @@ private: friend class DownloadDisplayControllerTest; + // Gets all models to display, then updates the toolbar button state + // accordingly. Returns the vector of all models. If the + // DownloadBubbleUpdateService indicated that results might not have been + // complete, |may_retry| specifies whether to post a task to retry fetching + // all models and updating the button. + std::vector<DownloadUIModel::DownloadUIModelPtr> + UpdateButtonStateFromAllModels(bool may_retry); + // Stops and restarts `icon_disappearance_timer_`. The toolbar button will // be hidden after the `interval`. void ScheduleToolbarDisappearance(base::TimeDelta interval); @@ -153,12 +154,8 @@ bool HasRecentCompleteDownload(base::TimeDelta interval, base::Time last_complete_time); - // AllDownloadItemNotifier::Observer - void OnManagerGoingDown(content::DownloadManager* manager) override; - base::Time GetLastCompleteTime( - const offline_items_collection::OfflineContentAggregator::OfflineItemList& - offline_items); + const std::vector<std::unique_ptr<DownloadUIModel>>& all_models); // The pointer is created in ToolbarView and owned by ToolbarView. raw_ptr<DownloadDisplay> const display_; @@ -166,7 +163,6 @@ base::ScopedObservation<FullscreenController, FullscreenObserver> observation_{this}; raw_ptr<content::DownloadManager> download_manager_; - download::AllDownloadItemNotifier download_notifier_; base::OneShotTimer icon_disappearance_timer_; base::OneShotTimer icon_inactive_timer_; IconInfo icon_info_;
diff --git a/chrome/browser/download/bubble/download_display_controller_unittest.cc b/chrome/browser/download/bubble/download_display_controller_unittest.cc index 06177550..4d52292 100644 --- a/chrome/browser/download/bubble/download_display_controller_unittest.cc +++ b/chrome/browser/download/bubble/download_display_controller_unittest.cc
@@ -17,6 +17,8 @@ #include "chrome/browser/download/download_core_service_factory.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_prefs.h" +#include "chrome/browser/download/offline_item_model_manager_factory.h" +#include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/test_browser_window.h" @@ -32,17 +34,21 @@ #include "content/public/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" -using testing::_; -using testing::NiceMock; -using testing::Return; -using testing::ReturnRef; -using testing::ReturnRefOfCopy; -using testing::SetArgPointee; - namespace { -using StrictMockDownloadItem = testing::StrictMock<download::MockDownloadItem>; +using ::offline_items_collection::OfflineItem; +using ::testing::_; +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::ReturnRefOfCopy; +using ::testing::SetArgPointee; +using ::testing::StrictMock; +using StrictMockDownloadItem = StrictMock<download::MockDownloadItem>; using DownloadIconState = download::DownloadIconState; using DownloadState = download::DownloadItem::DownloadState; +using DownloadUIModelPtr = DownloadUIModel::DownloadUIModelPtr; +using OfflineItemList = + offline_items_collection::OfflineContentProvider::OfflineItemList; using OfflineItemState = offline_items_collection::OfflineItemState; class FakeDownloadDisplay : public DownloadDisplay { @@ -101,43 +107,78 @@ RAW_PTR_EXCLUSION DownloadDisplayController* controller_ = nullptr; }; -class FakeDownloadBubbleUIController : public DownloadBubbleUIController { +// TODO(chlily): Pull this and the very similar class in +// DownloadBubbleUIControllerTest out into a test utils file. +class MockDownloadBubbleUpdateService : public DownloadBubbleUpdateService { public: - explicit FakeDownloadBubbleUIController(Browser* browser) - : DownloadBubbleUIController(browser) {} - ~FakeDownloadBubbleUIController() override = default; - const OfflineItemList& GetOfflineItems() override { return offline_items_; } - void InitOfflineItems(DownloadDisplayController* display_controller, - base::OnceCallback<void()> callback) override { - std::move(callback).Run(); - } - void AddOfflineItem(OfflineItem& item) { offline_items_.push_back(item); } - void UpdateOfflineItem(int index, OfflineItemState state) { - offline_items_[index].state = state; - } - std::vector<DownloadUIModelPtr> GetInProgressItems() override { - std::vector<DownloadUIModelPtr> in_progress_models; - for (auto* item : in_progress_download_items_) { - in_progress_models.push_back(DownloadItemModel::Wrap(item)); - } - for (const auto& item : offline_items_) { - if (item.state == OfflineItemState::IN_PROGRESS) { - in_progress_models.push_back( - OfflineItemModel::Wrap(offline_manager_for_testing(), item)); + enum class ModelType { + kDownloadItem, + kOfflineItem, + }; + + MockDownloadBubbleUpdateService( + Profile* profile, + const std::vector<std::unique_ptr<StrictMockDownloadItem>>& + download_items, + const OfflineItemList& offline_items) + : DownloadBubbleUpdateService(profile), + profile_(profile), + download_items_(download_items), + offline_items_(offline_items) {} + MockDownloadBubbleUpdateService(const MockDownloadBubbleUpdateService&) = + delete; + MockDownloadBubbleUpdateService& operator=( + const MockDownloadBubbleUpdateService&) = delete; + + ~MockDownloadBubbleUpdateService() override = default; + + bool GetAllModelsToDisplay( + std::vector<DownloadUIModelPtr>& models, + bool force_backfill_download_items = true) override { + models.clear(); + int download_item_index = 0, offline_item_index = 0; + // Compose a list of models from the items stored in the test fixture. + for (ModelType type : model_types_) { + if (type == ModelType::kDownloadItem) { + auto model = DownloadItemModel::Wrap( + download_items_.at(download_item_index++).get()); + if (model->ShouldShowInBubble()) { + models.push_back(std::move(model)); + } + } else { + auto model = OfflineItemModel::Wrap( + OfflineItemModelManagerFactory::GetForBrowserContext(profile_), + offline_items_.at(offline_item_index++)); + if (model->ShouldShowInBubble()) { + models.push_back(std::move(model)); + } } } - return in_progress_models; - } - void AddInProgressItemForTesting(download::DownloadItem* item) { - in_progress_download_items_.insert(item); - } - void RemoveInProgressItemForTesting(download::DownloadItem* item) { - in_progress_download_items_.erase(item); + return true; } - protected: - OfflineItemList offline_items_; - std::set<download::DownloadItem*> in_progress_download_items_; + void AddModel(ModelType type) { model_types_.push_back(type); } + + void RemoveLastDownload() { + for (auto reverse_it = model_types_.rbegin(); + reverse_it != model_types_.rend(); ++reverse_it) { + if (*reverse_it == ModelType::kDownloadItem) { + model_types_.erase(std::next(reverse_it).base()); + break; + } + } + } + + MOCK_METHOD(DownloadDisplayController::ProgressInfo, + GetProgressInfo, + (), + (const override)); + + private: + Profile* profile_; + std::vector<ModelType> model_types_; + const std::vector<std::unique_ptr<StrictMockDownloadItem>>& download_items_; + const OfflineItemList& offline_items_; }; class MockDownloadCoreService : public DownloadCoreService { @@ -163,8 +204,6 @@ return std::make_unique<MockDownloadCoreService>(); } -} // namespace - class DownloadDisplayControllerTest : public testing::Test { public: DownloadDisplayControllerTest() @@ -193,14 +232,17 @@ EXPECT_CALL(*mock_download_core_service(), GetDownloadManagerDelegate()) .WillRepeatedly(Return(delegate_.get())); + mock_update_service_ = + std::make_unique<StrictMock<MockDownloadBubbleUpdateService>>( + profile_, items_, offline_items_); display_ = std::make_unique<FakeDownloadDisplay>(); window_ = std::make_unique<TestBrowserWindow>(); Browser::CreateParams params(profile_, true); params.type = Browser::TYPE_NORMAL; params.window = window_.get(); browser_ = std::unique_ptr<Browser>(Browser::Create(params)); - bubble_controller_ = - std::make_unique<FakeDownloadBubbleUIController>(browser_.get()); + bubble_controller_ = std::make_unique<DownloadBubbleUIController>( + browser_.get(), mock_update_service_.get()); bubble_controller_->set_manager_for_testing(manager_.get()); controller_ = std::make_unique<DownloadDisplayController>( display_.get(), browser_.get(), bubble_controller_.get()); @@ -209,12 +251,10 @@ } void TearDown() override { - for (auto& item : items_) { - item->RemoveObserver(&controller_->get_download_notifier_for_testing()); - } // The controller needs to be reset before download manager, because the // download_notifier_ will unregister itself from the manager. controller_.reset(); + mock_update_service_.reset(); } Browser* browser() { return browser_.get(); } @@ -224,7 +264,7 @@ download::MockDownloadItem& item(size_t index) { return *items_[index]; } FakeDownloadDisplay& display() { return *display_; } DownloadDisplayController& controller() { return *controller_; } - FakeDownloadBubbleUIController& bubble_controller() { + DownloadBubbleUIController& bubble_controller() { return *bubble_controller_; } Profile* profile() { return profile_; } @@ -244,6 +284,7 @@ EXPECT_CALL(item(index), IsPaused()).WillRepeatedly(Return(false)); EXPECT_CALL(item(index), GetStartTime()) .WillRepeatedly(Return(base::Time::Now())); + EXPECT_CALL(item(index), GetEndTime()).WillRepeatedly(Return(base::Time())); EXPECT_CALL(item(index), GetDangerType()) .WillRepeatedly(Return(download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)); EXPECT_CALL(item(index), IsDangerous()).WillRepeatedly(Return(false)); @@ -273,36 +314,46 @@ // will generally set this to false in OnNewItem(). DownloadItemModel(&item(index)).SetActionedOn(false); - if (state == download::DownloadItem::IN_PROGRESS) { - bubble_controller().AddInProgressItemForTesting(&(item(index))); - } - std::vector<download::DownloadItem*> items; for (size_t i = 0; i < items_.size(); ++i) { items.push_back(&item(i)); } EXPECT_CALL(*manager_.get(), GetAllDownloads(_)) .WillRepeatedly(SetArgPointee<0>(items)); - item(index).AddObserver(&controller().get_download_notifier_for_testing()); content::DownloadItemUtils::AttachInfoForTesting(&(item(index)), profile_, nullptr); - controller().OnNewItem( - /*show_animation=*/false); + mock_update_service_->AddModel( + MockDownloadBubbleUpdateService::ModelType::kDownloadItem); + DownloadDisplayController::ProgressInfo progress_info; + progress_info.download_count = in_progress_count_; + progress_info.progress_percentage = in_progress_count_ > 0 ? 50 : 0; + EXPECT_CALL(*mock_update_service_, GetProgressInfo()) + .WillRepeatedly(Return(progress_info)); + controller().OnNewItem(/*show_animation=*/false); } void InitOfflineItem(OfflineItemState state) { OfflineItem item; item.state = state; - bubble_controller().AddOfflineItem(item); + offline_items_.push_back(item); + if (state == OfflineItemState::IN_PROGRESS) { + ++in_progress_count_; + } + DownloadDisplayController::ProgressInfo progress_info; + progress_info.download_count = in_progress_count_; + progress_info.progress_percentage = in_progress_count_ > 0 ? 50 : 0; + progress_info.progress_certain = false; + EXPECT_CALL(*mock_update_service_, GetProgressInfo()) + .WillRepeatedly(Return(progress_info)); + mock_update_service_->AddModel( + MockDownloadBubbleUpdateService::ModelType::kOfflineItem); controller().OnNewItem(/*show_animation=*/false); } void UpdateOfflineItem(int item_index, OfflineItemState state, bool is_pending_deep_scanning) { - if (state == OfflineItemState::COMPLETE) { - bubble_controller().UpdateOfflineItem(item_index, state); - } + offline_items_[item_index].state = state; controller().OnUpdatedItem(state == OfflineItemState::COMPLETE, is_pending_deep_scanning, /*may_show_details=*/true); @@ -325,10 +376,8 @@ .WillRepeatedly(Return(in_progress_count_)); DownloadPrefs::FromDownloadManager(&manager()) ->SetLastCompleteTime(base::Time::Now()); - bubble_controller().RemoveInProgressItemForTesting(&(item(item_index))); } else { EXPECT_CALL(item(item_index), IsDone()).WillRepeatedly(Return(false)); - bubble_controller().AddInProgressItemForTesting(&(item(item_index))); } controller().OnUpdatedItem( state == DownloadState::COMPLETE, @@ -346,6 +395,7 @@ } EXPECT_CALL(*manager_.get(), GetAllDownloads(_)) .WillRepeatedly(SetArgPointee<0>(items)); + mock_update_service_->RemoveLastDownload(); } bool VerifyDisplayState(bool shown, @@ -387,9 +437,11 @@ std::unique_ptr<DownloadDisplayController> controller_; std::unique_ptr<FakeDownloadDisplay> display_; std::vector<std::unique_ptr<StrictMockDownloadItem>> items_; - + std::vector<OfflineItem> offline_items_; std::unique_ptr<NiceMock<content::MockDownloadManager>> manager_; - std::unique_ptr<FakeDownloadBubbleUIController> bubble_controller_; + std::unique_ptr<StrictMock<MockDownloadBubbleUpdateService>> + mock_update_service_; + std::unique_ptr<DownloadBubbleUIController> bubble_controller_; TestingProfileManager testing_profile_manager_; raw_ptr<Profile> profile_; std::unique_ptr<TestBrowserWindow> window_; @@ -952,3 +1004,5 @@ /*icon_state=*/DownloadIconState::kComplete, /*is_active=*/true)); } + +} // namespace
diff --git a/chrome/browser/download/download_ui_controller.cc b/chrome/browser/download/download_ui_controller.cc index 4df03037..c21f771 100644 --- a/chrome/browser/download/download_ui_controller.cc +++ b/chrome/browser/download/download_ui_controller.cc
@@ -13,6 +13,8 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/devtools/devtools_window.h" +#include "chrome/browser/download/bubble/download_bubble_utils.h" +#include "chrome/browser/download/download_crx_util.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_shelf.h" #include "chrome/browser/download/download_stats.h" @@ -138,29 +140,14 @@ download::DownloadItem* item) { if (!DownloadItemModel(item).ShouldShowInBubble()) return; - - content::WebContents* web_contents = - content::DownloadItemUtils::GetWebContents(item); - // For the case of DevTools web contents, we'd like to use target browser - // shelf although saving from the DevTools web contents. - if (web_contents && DevToolsWindow::IsDevToolsWindow(web_contents)) { - DevToolsWindow* devtools_window = - DevToolsWindow::AsDevToolsWindow(web_contents); - content::WebContents* inspected = - devtools_window->GetInspectedWebContents(); - // Do not overwrite web contents for the case of remote debugging. - if (inspected) - web_contents = inspected; + // crx downloads are handled by the DownloadBubbleUpdateService. + // TODO(chlily): Consolidate these code paths. + if (download_crx_util::IsExtensionDownload(*item)) { + return; } + Browser* browser_to_show_animation = - web_contents ? chrome::FindBrowserWithWebContents(web_contents) : nullptr; - - // As a last resort, use the last active browser for this profile. Not ideal, - // but better than not showing the download at all. - if (browser_to_show_animation == nullptr) { - browser_to_show_animation = chrome::FindLastActiveWithProfile(profile_); - } - + FindBrowserToShowAnimation(item, profile_); BrowserList* browser_list = BrowserList::GetInstance(); if (!browser_list) return; @@ -168,7 +155,7 @@ for (auto* browser : *browser_list) { if (browser && browser->window() && browser->window()->GetDownloadBubbleUIController()) { - browser->window()->GetDownloadBubbleUIController()->OnNewItem( + browser->window()->GetDownloadBubbleUIController()->OnDownloadItemAdded( item, /*may_show_animation=*/(browser == browser_to_show_animation)); } }
diff --git a/chrome/browser/enterprise/profile_token_management/profile_token_navigation_throttle.cc b/chrome/browser/enterprise/profile_token_management/profile_token_navigation_throttle.cc index afc26e5..621a2be 100644 --- a/chrome/browser/enterprise/profile_token_management/profile_token_navigation_throttle.cc +++ b/chrome/browser/enterprise/profile_token_management/profile_token_navigation_throttle.cc
@@ -6,6 +6,7 @@ #include "base/containers/contains.h" #include "base/feature_list.h" +#include "base/memory/weak_ptr.h" #include "chrome/browser/enterprise/profile_token_management/token_management_features.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profiles_state.h" @@ -58,11 +59,8 @@ std::unique_ptr<ProfileTokenNavigationThrottle> ProfileTokenNavigationThrottle::MaybeCreateThrottleFor( content::NavigationHandle* navigation_handle) { - if (!base::FeatureList::IsEnabled(features::kEnableProfileTokenManagement)) { - return nullptr; - } - - if (!profiles::IsProfileCreationAllowed()) { + if (!base::FeatureList::IsEnabled(features::kEnableProfileTokenManagement) || + !profiles::IsProfileCreationAllowed()) { return nullptr; } @@ -87,7 +85,7 @@ token_info_getter_->GetTokenInfo( navigation_handle(), base::BindOnce(&ProfileTokenNavigationThrottle::OnTokenInfoReceived, - base::Unretained(this))); + weak_ptr_factory_.GetWeakPtr())); return DEFER; } return PROCEED;
diff --git a/chrome/browser/enterprise/profile_token_management/profile_token_navigation_throttle.h b/chrome/browser/enterprise/profile_token_management/profile_token_navigation_throttle.h index 8514179f..5facce7 100644 --- a/chrome/browser/enterprise/profile_token_management/profile_token_navigation_throttle.h +++ b/chrome/browser/enterprise/profile_token_management/profile_token_navigation_throttle.h
@@ -7,6 +7,7 @@ #include <memory> +#include "base/memory/weak_ptr.h" #include "content/public/browser/navigation_throttle.h" namespace content { @@ -61,6 +62,7 @@ void OnTokenInfoReceived(const std::string& id, const std::string& management_token); std::unique_ptr<TokenInfoGetter> token_info_getter_; + base::WeakPtrFactory<ProfileTokenNavigationThrottle> weak_ptr_factory_{this}; }; } // namespace profile_token_management
diff --git a/chrome/browser/fast_checkout/fast_checkout_client.h b/chrome/browser/fast_checkout/fast_checkout_client.h index 9ec45f0a..cf4d66d 100644 --- a/chrome/browser/fast_checkout/fast_checkout_client.h +++ b/chrome/browser/fast_checkout/fast_checkout_client.h
@@ -56,6 +56,8 @@ const autofill::FormFieldData& field, const autofill::AutofillManager& autofill_manager) = 0; + virtual bool IsNotShownYet() const = 0; + protected: FastCheckoutClient() = default; virtual ~FastCheckoutClient() = default;
diff --git a/chrome/browser/fast_checkout/fast_checkout_client_impl.cc b/chrome/browser/fast_checkout/fast_checkout_client_impl.cc index 7777c98e..2ffc151 100644 --- a/chrome/browser/fast_checkout/fast_checkout_client_impl.cc +++ b/chrome/browser/fast_checkout/fast_checkout_client_impl.cc
@@ -627,4 +627,8 @@ is_running_, autofill_manager); } +bool FastCheckoutClientImpl::IsNotShownYet() const { + return fast_checkout_ui_state_ == FastCheckoutUIState::kNotShownYet; +} + WEB_CONTENTS_USER_DATA_KEY_IMPL(FastCheckoutClientImpl);
diff --git a/chrome/browser/fast_checkout/fast_checkout_client_impl.h b/chrome/browser/fast_checkout/fast_checkout_client_impl.h index f281441..c912b4b 100644 --- a/chrome/browser/fast_checkout/fast_checkout_client_impl.h +++ b/chrome/browser/fast_checkout/fast_checkout_client_impl.h
@@ -53,6 +53,7 @@ bool IsSupported(const autofill::FormData& form, const autofill::FormFieldData& field, const autofill::AutofillManager& autofill_manager) override; + bool IsNotShownYet() const override; // FastCheckoutControllerImpl::Delegate: void OnOptionsSelected(
diff --git a/chrome/browser/fast_checkout/fast_checkout_client_impl_unittest.cc b/chrome/browser/fast_checkout/fast_checkout_client_impl_unittest.cc index 24d9008..cc0b58e 100644 --- a/chrome/browser/fast_checkout/fast_checkout_client_impl_unittest.cc +++ b/chrome/browser/fast_checkout/fast_checkout_client_impl_unittest.cc
@@ -432,6 +432,7 @@ EXPECT_FALSE(fast_checkout_client()->TryToStart( GURL(kUrl), autofill::FormData(), autofill::FormFieldData(), nullptr)); + EXPECT_TRUE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, Start_ShouldRunReturnsFalse_NoRun) { @@ -450,6 +451,7 @@ EXPECT_FALSE(fast_checkout_client()->TryToStart( GURL(kUrl), autofill::FormData(), autofill::FormFieldData(), autofill_manager()->GetWeakPtr())); + EXPECT_TRUE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, Start_ShouldRunReturnsTrue_Run) { @@ -476,6 +478,7 @@ EXPECT_TRUE(fast_checkout_client()->IsRunning()); EXPECT_TRUE(fast_checkout_client()->IsShowing()); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -504,6 +507,7 @@ // `FastCheckoutClient` is not running anymore. EXPECT_FALSE(fast_checkout_client()->IsRunning()); ExpectRunOutcomeUkm(FastCheckoutRunOutcome::kInvalidPersonalData); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -539,12 +543,14 @@ // `FastCheckoutClient` is still running. EXPECT_TRUE(fast_checkout_client()->IsRunning()); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, Stop_WhenIsRunning_CancelsTheRun) { // `FastCheckoutClient` is not running initially. EXPECT_FALSE(fast_checkout_client()->IsRunning()); EXPECT_FALSE(fast_checkout_client()->IsShowing()); + EXPECT_TRUE(fast_checkout_client()->IsNotShownYet()); // Starting the run successfully. EXPECT_TRUE(fast_checkout_client()->TryToStart( @@ -561,6 +567,7 @@ // `FastCheckoutClient` is not running anymore. EXPECT_FALSE(fast_checkout_client()->IsRunning()); EXPECT_FALSE(fast_checkout_client()->IsShowing()); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, OnDismiss_WhenIsRunning_CancelsTheRun) { @@ -578,6 +585,7 @@ EXPECT_FALSE(fast_checkout_client()->IsRunning()); ExpectRunOutcomeUkm(FastCheckoutRunOutcome::kBottomsheetDismissed); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -619,6 +627,7 @@ // Expect this `Stop(..)` call to not crash the test. fast_checkout_client()->Stop(/*allow_further_runs=*/true); ExpectRunOutcomeUkm(FastCheckoutRunOutcome::kAutofillManagerDestroyed); + EXPECT_TRUE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -641,6 +650,7 @@ EXPECT_THAT(fast_checkout_client()->form_signatures_to_fill_, UnorderedElementsAre(address_form->form_signature(), credit_card_form->form_signature())); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -666,6 +676,7 @@ Pair(Pair(credit_card_form->form_signature(), autofill::FormType::kCreditCardForm), FastCheckoutClientImpl::FillingState::kFilling))); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, OnAfterLoadedServerPredictions_FillsForms) { @@ -709,6 +720,7 @@ autofill::FormType::kCreditCardForm), FastCheckoutClientImpl::FillingState::kNotFilled))); EXPECT_TRUE(fast_checkout_client()->credit_card_form_global_id_.has_value()); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -754,6 +766,7 @@ EXPECT_FALSE(fast_checkout_client()->IsRunning()); EXPECT_EQ(fast_checkout_client()->fast_checkout_ui_state_, FastCheckoutUIState::kWasShown); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); ExpectRunOutcomeUkm(FastCheckoutRunOutcome::kSuccess); auto ukm_entries = ukm_recorder_.GetEntries( Autofill_FastCheckoutFormStatus::kEntryName, @@ -795,6 +808,7 @@ EXPECT_FALSE(fast_checkout_client()->IsRunning()); ExpectRunOutcomeUkm( FastCheckoutRunOutcome::kNavigationWhileBottomsheetWasShown); + EXPECT_TRUE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -807,6 +821,7 @@ fast_checkout_client()->OnAutofillManagerReset(*autofill_manager()); EXPECT_FALSE(fast_checkout_client()->IsRunning()); ExpectRunOutcomeUkm(FastCheckoutRunOutcome::kPageRefreshed); + EXPECT_TRUE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, OnAutofillManagerDestroyed_ResetsState) { @@ -818,6 +833,7 @@ fast_checkout_client()->OnAutofillManagerDestroyed(*autofill_manager()); EXPECT_FALSE(fast_checkout_client()->IsRunning()); ExpectRunOutcomeUkm(FastCheckoutRunOutcome::kAutofillManagerDestroyed); + EXPECT_TRUE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, TimeoutTimer_ThirtyMinutesPassed_StopsRun) { @@ -833,6 +849,7 @@ task_environment()->RunUntilIdle(); EXPECT_FALSE(fast_checkout_client()->IsRunning()); ExpectRunOutcomeUkm(FastCheckoutRunOutcome::kTimeout); + EXPECT_TRUE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, OnNavigation_OtherUrl_StopsRun) { @@ -844,6 +861,7 @@ fast_checkout_client()->OnNavigation(GURL(kOtherUrl), false); EXPECT_FALSE(fast_checkout_client()->IsRunning()); ExpectRunOutcomeUkm(FastCheckoutRunOutcome::kOriginChange); + EXPECT_TRUE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -856,6 +874,7 @@ fast_checkout_client()->OnNavigation(GURL(kUrl), false); EXPECT_FALSE(fast_checkout_client()->IsRunning()); ExpectRunOutcomeUkm(FastCheckoutRunOutcome::kNonCheckoutPage); + EXPECT_TRUE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -867,6 +886,7 @@ EXPECT_TRUE(fast_checkout_client()->IsRunning()); fast_checkout_client()->OnNavigation(GURL(kUrl), true); EXPECT_TRUE(fast_checkout_client()->IsRunning()); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -892,6 +912,7 @@ fast_checkout_client()->run_id_)); fast_checkout_client()->OnFullCardRequestSucceeded(*full_card_request, *credit_card, cvc); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, OnFullCardRequestFailed_StopsRun) { @@ -906,6 +927,7 @@ fast_checkout_client()->OnFullCardRequestFailed(card_type, failure_type); EXPECT_FALSE(fast_checkout_client()->IsRunning()); ExpectRunOutcomeUkm(FastCheckoutRunOutcome::kCvcPopupError); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F( @@ -920,6 +942,7 @@ EXPECT_CALL(*accessibility_service(), Announce(announcement_text)); fast_checkout_client()->OnAfterDidFillAutofillFormData( *autofill_manager(), address_form->global_id()); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F( @@ -936,6 +959,7 @@ EXPECT_CALL(*accessibility_service(), Announce(announcement_text)); fast_checkout_client()->OnAfterDidFillAutofillFormData( *autofill_manager(), address_form->global_id()); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F( @@ -954,6 +978,7 @@ EXPECT_CALL(*accessibility_service(), Announce(announcement_text)); fast_checkout_client()->OnAfterDidFillAutofillFormData( *autofill_manager(), credit_card_form->global_id()); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -972,6 +997,7 @@ fast_checkout_client()->OnAfterLoadedServerPredictions(*autofill_manager()); EXPECT_FALSE(fast_checkout_client()->IsRunning()); + EXPECT_TRUE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -994,6 +1020,7 @@ fast_checkout_client()->OnAfterLoadedServerPredictions(*autofill_manager()); EXPECT_FALSE(fast_checkout_client()->IsRunning()); + EXPECT_TRUE(fast_checkout_client()->IsNotShownYet()); } TEST_F(FastCheckoutClientImplTest, @@ -1011,4 +1038,5 @@ FormFieldDataEqualTo(field), _, Eq(u""))); StartRunAndSelectOptions({credit_card_form->form_signature()}, /*local_card=*/true); + EXPECT_FALSE(fast_checkout_client()->IsNotShownYet()); }
diff --git a/chrome/browser/fast_checkout/mock_fast_checkout_client.h b/chrome/browser/fast_checkout/mock_fast_checkout_client.h index 0d13a8e0..370d9df 100644 --- a/chrome/browser/fast_checkout/mock_fast_checkout_client.h +++ b/chrome/browser/fast_checkout/mock_fast_checkout_client.h
@@ -31,6 +31,13 @@ OnNavigation, (const GURL& url, bool is_cart_or_checkout_url), (override)); + MOCK_METHOD(bool, + IsSupported, + (const autofill::FormData&, + const autofill::FormFieldData&, + const autofill::AutofillManager&), + (override)); + MOCK_METHOD(bool, IsNotShownYet, (), (const override)); }; #endif
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 068c0e0..195457e6 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -2444,11 +2444,6 @@ "expiry_milestone": 117 }, { - "name": "enable-filtering-scroll-events", - "owners": [ "eirage", "nzolghadr", "input-dev" ], - "expiry_milestone": 85 - }, - { "name": "enable-first-party-sets", "owners": [ "chrome-first-party-sets@chromium.org" ], "expiry_milestone": 120 @@ -3032,16 +3027,6 @@ "expiry_milestone": 120 }, { - "name": "enable-resampling-input-events", - "owners": [ "eirage", "nzolghadr", "input-dev" ], - "expiry_milestone": 85 - }, - { - "name": "enable-resampling-scroll-events", - "owners": [ "eirage", "nzolghadr", "input-dev" ], - "expiry_milestone": 85 - }, - { "name": "enable-resampling-scroll-events-experimental-prediction", "owners": [ "input-dev" ], "expiry_milestone": 95
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 81a7f22..01f5e77b 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1341,15 +1341,6 @@ "Enables storing preferences in a second, Gaia-account-scoped storage for " "syncing users"; -const char kEnableResamplingInputEventsName[] = - "Enable resampling input events"; -const char kEnableResamplingInputEventsDescription[] = - "Predicts mouse and touch inputs position at rAF time based on previous " - "input"; -const char kEnableResamplingScrollEventsName[] = - "Enable resampling scroll events"; -const char kEnableResamplingScrollEventsDescription[] = - "Predicts the scroll amount at vsync time based on previous input"; const char kEnableResamplingScrollEventsExperimentalPredictionName[] = "Enable experimental prediction for scroll events"; const char kEnableResamplingScrollEventsExperimentalPredictionDescription[] = @@ -1481,10 +1472,6 @@ "Enables running extensions on chrome:// URLs, where extensions explicitly " "request this permission."; -const char kFilteringScrollPredictionName[] = "Filtering scroll prediction"; -const char kFilteringScrollPredictionDescription[] = - "Enable filtering of predicted scroll events"; - const char kFractionalScrollOffsetsName[] = "Fractional Scroll Offsets"; const char kFractionalScrollOffsetsDescription[] = "Enables fractional scroll offsets inside Blink, exposing non-integer "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index f08362f..65ef3cb 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -749,10 +749,6 @@ extern const char kEnablePreferencesAccountStorageName[]; extern const char kEnablePreferencesAccountStorageDescription[]; -extern const char kEnableResamplingInputEventsName[]; -extern const char kEnableResamplingInputEventsDescription[]; -extern const char kEnableResamplingScrollEventsName[]; -extern const char kEnableResamplingScrollEventsDescription[]; extern const char kEnableResamplingScrollEventsExperimentalPredictionName[]; extern const char kEnableResamplingScrollEventsExperimentalPredictionDescription[]; @@ -823,9 +819,6 @@ extern const char kExtensionsOnChromeUrlsName[]; extern const char kExtensionsOnChromeUrlsDescription[]; -extern const char kFilteringScrollPredictionName[]; -extern const char kFilteringScrollPredictionDescription[]; - extern const char kFractionalScrollOffsetsName[]; extern const char kFractionalScrollOffsetsDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 02af7d8..a8eae33 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -401,6 +401,7 @@ &webapps::features::kInstallableAmbientBadgeInfoBar, &webapps::features::kInstallableAmbientBadgeMessage, &webapps::features::kWebApkInstallFailureNotification, + &webapps::features::kWebApkInstallFailureRetry, &webapps::features::kWebApkUniqueId, &network::features::kPrivateStateTokens, };
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 e6593634..23102c1 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
@@ -561,6 +561,9 @@ public static final String WEB_APK_TRAMPOLINE_ON_INITIAL_INTENT = "WebApkTrampolineOnInitialIntent"; public static final String WEB_APK_UNIQUE_ID = "WebApkUniqueId"; + public static final String WEB_APK_INSTALL_FAILURE_NOTIFICATION = + "kWebApkInstallFailureNotification"; + public static final String WEB_APK_INSTALL_RETRY = "WebApkInstallFailureRetry"; public static final String WEB_FEED = "WebFeed"; public static final String WEB_FEED_AWARENESS = "WebFeedAwareness"; public static final String WEB_FEED_ONBOARDING = "WebFeedOnboarding";
diff --git a/chrome/browser/headless/headless_mode_browsertest_mac.mm b/chrome/browser/headless/headless_mode_browsertest_mac.mm index 785ec8df..87e23f96 100644 --- a/chrome/browser/headless/headless_mode_browsertest_mac.mm +++ b/chrome/browser/headless/headless_mode_browsertest_mac.mm
@@ -83,12 +83,11 @@ gfx::NativeWindow native_window = browser()->window()->GetNativeWindow(); NSWindow* ns_window = native_window.GetNativeNSWindow(); - // Expect the platform window size to be smaller than the requested window - // size due to Cocoa clamping the window dimensions to the monitor work - // area. + // Expect the platform window size to be the same as the requested window + // size. NSRect frame_rect = [ns_window frame]; - EXPECT_LT(NSWidth(frame_rect), kWindowSize.width()); - EXPECT_LT(NSHeight(frame_rect), kWindowSize.height()); + EXPECT_EQ(NSWidth(frame_rect), kWindowSize.width()); + EXPECT_EQ(NSHeight(frame_rect), kWindowSize.height()); // Expect the reported browser window size to be the same as the requested // window size.
diff --git a/chrome/browser/headless/headless_mode_protocol_browsertest.cc b/chrome/browser/headless/headless_mode_protocol_browsertest.cc index ae6098b..85c83b0 100644 --- a/chrome/browser/headless/headless_mode_protocol_browsertest.cc +++ b/chrome/browser/headless/headless_mode_protocol_browsertest.cc
@@ -216,13 +216,7 @@ HEADLESS_MODE_PROTOCOL_TEST(MAYBE_ScreencastBasics, "sanity/screencast-basics.js") -// https://crbug.com/1424570 -#if BUILDFLAG(IS_MAC) -#define MAYBE_LargeBrowserWindowSize DISABLED_LargeBrowserWindowSize -#else -#define MAYBE_LargeBrowserWindowSize LargeBrowserWindowSize -#endif -HEADLESS_MODE_PROTOCOL_TEST(MAYBE_LargeBrowserWindowSize, +HEADLESS_MODE_PROTOCOL_TEST(LargeBrowserWindowSize, "sanity/large-browser-window-size.js") } // namespace headless
diff --git a/chrome/browser/interstitials/chrome_settings_page_helper.cc b/chrome/browser/interstitials/chrome_settings_page_helper.cc index fa4806d..ba6128d 100644 --- a/chrome/browser/interstitials/chrome_settings_page_helper.cc +++ b/chrome/browser/interstitials/chrome_settings_page_helper.cc
@@ -56,6 +56,8 @@ params.bubble_arrow = user_education::HelpBubbleArrow::kBottomLeft; params.bubble_text = l10n_util::GetStringUTF16( IDS_SETTINGS_SAFEBROWSING_ENHANCED_IPH_BUBBLE_TEXT); + params.close_button_alt_text_id = + IDS_SETTINGS_SAFEBROWSING_ENHANCED_IPH_BUBBLE_CLOSE_BUTTON_ARIA_LABEL_TEXT; // In rare circumstances, this happens outside of a Browser, better ignore // than crash.
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index 824ee97..74fb9c7 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -124,7 +124,6 @@ #if BUILDFLAG(IS_ANDROID) #include "chrome/browser/metrics/chrome_android_metrics_provider.h" -#include "chrome/browser/metrics/family_link_user_metrics_provider.h" #include "chrome/browser/metrics/page_load_metrics_provider.h" #include "components/metrics/android_metrics_provider.h" #else @@ -202,6 +201,12 @@ #include "chrome/browser/metrics/bluetooth_metrics_provider.h" #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_ANDROID) +#include "chrome/browser/metrics/family_link_user_metrics_provider.h" +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS_LACROS))||BUILDFLAG(IS_ANDROID)) + namespace { #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) @@ -824,8 +829,6 @@ std::make_unique<ChromeAndroidMetricsProvider>(local_state)); metrics_service_->RegisterMetricsProvider( std::make_unique<PageLoadMetricsProvider>()); - metrics_service_->RegisterMetricsProvider( - std::make_unique<FamilyLinkUserMetricsProvider>()); #else metrics_service_->RegisterMetricsProvider( base::WrapUnique(new performance_manager::MetricsProvider(local_state))); @@ -847,6 +850,23 @@ #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_LINUX) || // BUILDFLAG(IS_CHROMEOS_LACROS)) +#if BUILDFLAG(ENABLE_SUPERVISED_USERS) && \ + (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS_LACROS)) + if (base::FeatureList::IsEnabled( + kExtendFamilyLinkUserLogSegmentToAllPlatforms)) { + metrics_service_->RegisterMetricsProvider( + std::make_unique<FamilyLinkUserMetricsProvider>()); + } +#endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) && (BUILDFLAG(IS_WIN) || + // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS_LACROS) ) + +#if BUILDFLAG(ENABLE_SUPERVISED_USERS) && BUILDFLAG(IS_ANDROID) + metrics_service_->RegisterMetricsProvider( + std::make_unique<FamilyLinkUserMetricsProvider>()); +#endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) && BUILDFLAG(IS_ANDROID) + #if BUILDFLAG(IS_CHROMEOS_LACROS) metrics_service_->RegisterMetricsProvider( std::make_unique<LacrosMetricsProvider>());
diff --git a/chrome/browser/metrics/family_link_user_metrics_provider.cc b/chrome/browser/metrics/family_link_user_metrics_provider.cc index 07f604e..db51e67 100644 --- a/chrome/browser/metrics/family_link_user_metrics_provider.cc +++ b/chrome/browser/metrics/family_link_user_metrics_provider.cc
@@ -5,8 +5,19 @@ #include "chrome/browser/metrics/family_link_user_metrics_provider.h" #include "base/metrics/histogram_functions.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/signin/identity_manager_factory.h" +#include "chrome/browser/supervised_user/supervised_user_service.h" +#include "chrome/browser/supervised_user/supervised_user_service_factory.h" #include "components/session_manager/core/session_manager.h" +#include "components/signin/public/identity_manager/identity_manager.h" + +#if !BUILDFLAG(IS_ANDROID) +#include "chrome/browser/signin/identity_manager_factory.h" +#include "chrome/browser/ui/browser_finder.h" +#endif namespace { @@ -20,9 +31,17 @@ capabilities.is_subject_to_parental_controls() != signin::Tribool::kUnknown; } - } // namespace +// This flag is used to controls two things: +// 1. Enables the metrics provider for all platforms +// 2. Updates the existing implementation on Android to calculate the value +// on-demand instead of with an observer + +BASE_FEATURE(kExtendFamilyLinkUserLogSegmentToAllPlatforms, + "ExtendFamilyLinkUserLogSegmentToAllPlatforms", + base::FEATURE_DISABLED_BY_DEFAULT); + FamilyLinkUserMetricsProvider::FamilyLinkUserMetricsProvider() { auto* factory = IdentityManagerFactory::GetInstance(); if (factory) @@ -34,18 +53,64 @@ bool FamilyLinkUserMetricsProvider::ProvideHistograms() { // This function is called at unpredictable intervals throughout the Chrome // session, so guarantee it will never crash. - if (!log_segment_) - return false; - base::UmaHistogramEnumeration(kFamilyLinkUserLogSegmentHistogramName, - log_segment_.value()); - return true; + + if (base::FeatureList::IsEnabled( + kExtendFamilyLinkUserLogSegmentToAllPlatforms)) { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + std::vector<Profile*> profile_list = profile_manager->GetLoadedProfiles(); + absl::optional<FamilyLinkUserMetricsProvider::LogSegment> + merged_log_segment; + for (Profile* profile : profile_list) { +#if !BUILDFLAG(IS_ANDROID) + // TODO(b/274889379): Mock call to GetBrowserCount(). + if (!FamilyLinkUserMetricsProvider:: + skip_active_browser_count_for_unittesting_ && + chrome::GetBrowserCount(profile) == 0) { + // The profile is loaded, but there's no opened browser for this + // profile. + continue; + } +#endif + identity_manager_ = IdentityManagerFactory::GetForProfile(profile); + AccountInfo account_info = identity_manager_->FindExtendedAccountInfo( + identity_manager_->GetPrimaryAccountInfo( + signin::ConsentLevel::kSignin)); + absl::optional<FamilyLinkUserMetricsProvider::LogSegment> profileStatus = + SupervisionStatusOfProfile(account_info); + if (merged_log_segment.has_value() && profileStatus.has_value() && + merged_log_segment.value() != profileStatus.value()) { + base::UmaHistogramEnumeration(kFamilyLinkUserLogSegmentHistogramName, + LogSegment::kMixedProfile); + return true; + } + merged_log_segment = profileStatus; + } + + if (merged_log_segment.has_value()) { + base::UmaHistogramEnumeration(kFamilyLinkUserLogSegmentHistogramName, + merged_log_segment.value()); + return true; + } + + } else { + if (!log_segment_) { + return false; + } + base::UmaHistogramEnumeration(kFamilyLinkUserLogSegmentHistogramName, + log_segment_.value()); + return true; + } + return false; } void FamilyLinkUserMetricsProvider::IdentityManagerCreated( signin::IdentityManager* identity_manager) { CHECK(identity_manager); DCHECK(!identity_manager_); - + if (base::FeatureList::IsEnabled( + kExtendFamilyLinkUserLogSegmentToAllPlatforms)) { + return; + } identity_manager_ = identity_manager; scoped_observation_.Observe(identity_manager_); // The account may have been updated before registering the observer. @@ -59,6 +124,10 @@ void FamilyLinkUserMetricsProvider::OnPrimaryAccountChanged( const signin::PrimaryAccountChangeEvent& event_details) { + if (base::FeatureList::IsEnabled( + kExtendFamilyLinkUserLogSegmentToAllPlatforms)) { + return; + } signin::PrimaryAccountChangeEvent::Type event_type = event_details.GetEventTypeFor(signin::ConsentLevel::kSignin); switch (event_type) { @@ -82,6 +151,10 @@ void FamilyLinkUserMetricsProvider::OnIdentityManagerShutdown( signin::IdentityManager* identity_manager) { + if (base::FeatureList::IsEnabled( + kExtendFamilyLinkUserLogSegmentToAllPlatforms)) { + return; + } DCHECK_EQ(identity_manager, identity_manager_); identity_manager_ = nullptr; scoped_observation_.Reset(); @@ -89,6 +162,10 @@ void FamilyLinkUserMetricsProvider::OnExtendedAccountInfoUpdated( const AccountInfo& account_info) { + if (base::FeatureList::IsEnabled( + kExtendFamilyLinkUserLogSegmentToAllPlatforms)) { + return; + } if (identity_manager_->GetPrimaryAccountId(signin::ConsentLevel::kSignin) != account_info.account_id) { // Only record extended account information associated with the primary @@ -122,11 +199,42 @@ } } +absl::optional<FamilyLinkUserMetricsProvider::LogSegment> +FamilyLinkUserMetricsProvider::SupervisionStatusOfProfile( + const AccountInfo& account_info) { + if (!AreParentalSupervisionCapabilitiesKnown(account_info.capabilities)) { + return absl::nullopt; + } + auto is_subject_to_parental_controls = + account_info.capabilities.is_subject_to_parental_controls(); + if (is_subject_to_parental_controls == signin::Tribool::kTrue) { + auto can_stop_supervision = + account_info.capabilities.can_stop_parental_supervision(); + if (can_stop_supervision == signin::Tribool::kTrue) { + return FamilyLinkUserMetricsProvider::LogSegment:: + kSupervisionEnabledByUser; + } else { + // Log as a supervised user that has parental supervision enabled + // by a policy applied to their account, e.g. Unicorn accounts. + return FamilyLinkUserMetricsProvider::LogSegment:: + kSupervisionEnabledByPolicy; + } + } else { + // Log as unsupervised user if the account is not subject to parental + // controls. + return FamilyLinkUserMetricsProvider::LogSegment::kUnsupervised; + } +} + // static const char* FamilyLinkUserMetricsProvider::GetHistogramNameForTesting() { return kFamilyLinkUserLogSegmentHistogramName; } void FamilyLinkUserMetricsProvider::SetLogSegment(LogSegment log_segment) { + if (base::FeatureList::IsEnabled( + kExtendFamilyLinkUserLogSegmentToAllPlatforms)) { + return; + } log_segment_ = log_segment; }
diff --git a/chrome/browser/metrics/family_link_user_metrics_provider.h b/chrome/browser/metrics/family_link_user_metrics_provider.h index 07e717d..606192fe 100644 --- a/chrome/browser/metrics/family_link_user_metrics_provider.h +++ b/chrome/browser/metrics/family_link_user_metrics_provider.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_METRICS_FAMILY_LINK_USER_METRICS_PROVIDER_H_ #include "base/memory/raw_ptr.h" +#include "chrome/browser/metrics/cached_metrics_profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "components/metrics/metrics_provider.h" #include "components/session_manager/core/session_manager_observer.h" @@ -15,6 +16,9 @@ // Categorizes the primary account of the active user profile into a FamilyLink // supervision type to segment the Chrome user population. // TODO(crbug.com/1347816): Support multi-profile supervision type segmentation. + +BASE_DECLARE_FEATURE(kExtendFamilyLinkUserLogSegmentToAllPlatforms); + class FamilyLinkUserMetricsProvider : public metrics::MetricsProvider, public IdentityManagerFactory::Observer, public signin::IdentityManager::Observer { @@ -33,10 +37,14 @@ // User that has chosen to be supervised by FamilyLink (maps to Geller // accounts). kSupervisionEnabledByUser = 2, + // Profile contains users with multiple different supervision status + // used only when ExtendFamilyLinkUserLogSegmentToAllPlatforms flag is + // enabled + kMixedProfile = 3, // Add future entries above this comment, in sync with // "FamilyLinkUserLogSegment" in src/tools/metrics/histograms/enums.xml. // Update kMaxValue to the last value. - kMaxValue = kSupervisionEnabledByUser + kMaxValue = kMixedProfile }; FamilyLinkUserMetricsProvider(); @@ -61,6 +69,10 @@ static const char* GetHistogramNameForTesting(); + // Used to skip the check for active browsers in ProvideHistograms() while + // testing + bool skip_active_browser_count_for_unittesting_ = false; + private: void SetLogSegment(LogSegment log_segment); @@ -80,6 +92,10 @@ // Cache the log segment because it won't change during the session once // assigned. absl::optional<LogSegment> log_segment_; + + // Used when kExtendFamilyLinkUserLogSegmentToAllPlatforms is enabled + absl::optional<LogSegment> SupervisionStatusOfProfile( + const AccountInfo& account_info); }; #endif // CHROME_BROWSER_METRICS_FAMILY_LINK_USER_METRICS_PROVIDER_H_
diff --git a/chrome/browser/metrics/family_link_user_metrics_provider_unittest.cc b/chrome/browser/metrics/family_link_user_metrics_provider_unittest.cc index 6d9db052..22e4ea04 100644 --- a/chrome/browser/metrics/family_link_user_metrics_provider_unittest.cc +++ b/chrome/browser/metrics/family_link_user_metrics_provider_unittest.cc
@@ -7,26 +7,42 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" +#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile.h" +#include "chrome/test/base/testing_profile_manager.h" #include "components/metrics/metrics_features.h" +#include "components/prefs/pref_service.h" #include "components/signin/public/identity_manager/account_capabilities_test_mutator.h" #include "components/signin/public/identity_manager/account_info.h" #include "components/signin/public/identity_manager/identity_test_environment.h" #include "components/signin/public/identity_manager/identity_test_utils.h" +#include "components/supervised_user/core/common/features.h" +#include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h" namespace { constexpr char kTestEmail[] = "test@gmail.com"; +constexpr char kTestEmail1[] = "test1@gmail.com"; +constexpr char kTestEmail2[] = "test2@gmail.com"; +constexpr char kTestProfile[] = "profile"; +constexpr char kTestProfile1[] = "profile1"; +constexpr char kTestProfile2[] = "profile2"; + } // namespace class FamilyLinkUserMetricsProviderTest : public testing::Test, public testing::WithParamInterface<bool> { protected: - FamilyLinkUserMetricsProviderTest() = default; + FamilyLinkUserMetricsProviderTest() + : test_profile_manager_(TestingBrowserProcess::GetGlobal()) {} void SetUp() override { + ASSERT_TRUE(test_profile_manager_.SetUp()); EnableAccountCapabilitiesFetches(identity_manager()); + metrics_provider()->skip_active_browser_count_for_unittesting_ = true; if (ShouldEmitHistogramsEarlier()) { feature_list_.InitWithFeatures( @@ -37,9 +53,7 @@ } } - void TearDown() override { - metrics_provider()->OnIdentityManagerShutdown(identity_manager()); - } + void TearDown() override { test_profile_manager_.DeleteAllTestingProfiles(); } signin::IdentityManager* identity_manager() { return identity_test_env()->identity_manager(); @@ -63,12 +77,37 @@ } bool ShouldEmitHistogramsEarlier() const { return GetParam(); } + TestingProfileManager* test_profile_manager() { + return &test_profile_manager_; + } + + void CreateTestingProfile(const std::string& test_email, + const std::string& test_profile, + bool is_subject_to_parental_controls, + bool can_stop_parental_supervision) { + Profile* profile = test_profile_manager()->CreateTestingProfile( + test_profile, IdentityTestEnvironmentProfileAdaptor:: + GetIdentityTestEnvironmentFactories()); + EnableAccountCapabilitiesFetches( + IdentityManagerFactory::GetForProfile(profile)); + AccountInfo account = signin::MakePrimaryAccountAvailable( + IdentityManagerFactory::GetForProfile(profile), test_email, + signin::ConsentLevel::kSignin); + AccountCapabilitiesTestMutator mutator(&account.capabilities); + mutator.set_is_subject_to_parental_controls( + is_subject_to_parental_controls); + mutator.set_can_stop_parental_supervision(can_stop_parental_supervision); + signin::UpdateAccountInfoForAccount( + IdentityManagerFactory::GetForProfile(profile), account); + } private: - base::test::SingleThreadTaskEnvironment task_environment_; + content::BrowserTaskEnvironment task_environment_; + signin::IdentityTestEnvironment identity_test_env_; FamilyLinkUserMetricsProvider metrics_provider_; base::test::ScopedFeatureList feature_list_; + TestingProfileManager test_profile_manager_; }; INSTANTIATE_TEST_SUITE_P(All, @@ -86,7 +125,8 @@ histogram_tester.ExpectTotalCount( FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), - /*count=*/0); + /*expected_count=*/0); + metrics_provider()->OnIdentityManagerShutdown(identity_manager()); } TEST_P(FamilyLinkUserMetricsProviderTest, AdultUser) { @@ -111,6 +151,7 @@ FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), FamilyLinkUserMetricsProvider::LogSegment::kUnsupervised, /*expected_bucket_count=*/1); + metrics_provider()->OnIdentityManagerShutdown(identity_manager()); } TEST_P(FamilyLinkUserMetricsProviderTest, UserWithOptionalSupervision) { @@ -137,6 +178,7 @@ FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), FamilyLinkUserMetricsProvider::LogSegment::kSupervisionEnabledByUser, /*expected_bucket_count=*/1); + metrics_provider()->OnIdentityManagerShutdown(identity_manager()); } TEST_P(FamilyLinkUserMetricsProviderTest, UserWithRequiredSupervision) { @@ -162,7 +204,8 @@ histogram_tester.ExpectUniqueSample( FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), FamilyLinkUserMetricsProvider::LogSegment::kSupervisionEnabledByPolicy, - /*expected_bucket_count=*/1); + /*count=*/1); + metrics_provider()->OnIdentityManagerShutdown(identity_manager()); } TEST_P(FamilyLinkUserMetricsProviderTest, @@ -178,7 +221,8 @@ histogram_tester.ExpectTotalCount( FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), - /*count=*/0); + /*expected_count=*/0); + metrics_provider()->OnIdentityManagerShutdown(identity_manager()); } TEST_P(FamilyLinkUserMetricsProviderTest, @@ -201,6 +245,7 @@ FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), FamilyLinkUserMetricsProvider::LogSegment::kUnsupervised, /*expected_bucket_count=*/1); + metrics_provider()->OnIdentityManagerShutdown(identity_manager()); } TEST_P(FamilyLinkUserMetricsProviderTest, SetChildAsPrimaryAccount) { @@ -233,6 +278,7 @@ FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), FamilyLinkUserMetricsProvider::LogSegment::kSupervisionEnabledByPolicy, /*expected_bucket_count=*/1); + metrics_provider()->OnIdentityManagerShutdown(identity_manager()); } TEST_P(FamilyLinkUserMetricsProviderTest, ClearLogOnUserSignout) { @@ -261,4 +307,149 @@ FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), FamilyLinkUserMetricsProvider::LogSegment::kUnsupervised, /*expected_bucket_count=*/1); + metrics_provider()->OnIdentityManagerShutdown(identity_manager()); +} + +TEST_P(FamilyLinkUserMetricsProviderTest, + ProfileWithUnknownCapabilitiesDoesNotOutputHistogram) { + base::test::ScopedFeatureList feature{ + kExtendFamilyLinkUserLogSegmentToAllPlatforms}; + + Profile* profile = test_profile_manager()->CreateTestingProfile( + kTestProfile, IdentityTestEnvironmentProfileAdaptor:: + GetIdentityTestEnvironmentFactories()); + EnableAccountCapabilitiesFetches( + IdentityManagerFactory::GetForProfile(profile)); + AccountInfo account = signin::MakePrimaryAccountAvailable( + IdentityManagerFactory::GetForProfile(profile), kTestEmail, + signin::ConsentLevel::kSignin); + // Does not set account capabilities, default is unknown. + + base::HistogramTester histogram_tester; + ProvideHistograms(); + histogram_tester.ExpectTotalCount( + FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), + /*expected_count=*/0); +} + +TEST_P(FamilyLinkUserMetricsProviderTest, + ProfileWithRequiredSupervisionLoggedAsSupervisionEnabledByPolicy) { + base::test::ScopedFeatureList feature{ + kExtendFamilyLinkUserLogSegmentToAllPlatforms}; + + // Profile with supervision set by policy + CreateTestingProfile(kTestEmail2, kTestProfile2, + /*is_subject_to_parental_controls=*/true, + /*can_stop_parental_supervision=*/false); + + base::HistogramTester histogram_tester; + ProvideHistograms(); + + histogram_tester.ExpectUniqueSample( + FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), + FamilyLinkUserMetricsProvider::LogSegment::kSupervisionEnabledByPolicy, + /*expected_bucket_count=*/1); +} + +TEST_P(FamilyLinkUserMetricsProviderTest, + ProfileWithOptionalSupervisionLoggedSupervisionEnabledByUser) { + base::test::ScopedFeatureList feature{ + kExtendFamilyLinkUserLogSegmentToAllPlatforms}; + + // Profile with supervision set by user + CreateTestingProfile(kTestEmail1, kTestProfile1, + /*is_subject_to_parental_controls=*/true, + /*can_stop_parental_supervision=*/true); + + base::HistogramTester histogram_tester; + ProvideHistograms(); + + histogram_tester.ExpectUniqueSample( + FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), + FamilyLinkUserMetricsProvider::LogSegment::kSupervisionEnabledByUser, + /*expected_bucket_count=*/1); +} + +TEST_P(FamilyLinkUserMetricsProviderTest, + ProfileWithAdultUserLoggedAsUnsupervised) { + base::test::ScopedFeatureList feature{ + kExtendFamilyLinkUserLogSegmentToAllPlatforms}; + + // Adult profile + CreateTestingProfile(kTestEmail, kTestProfile, + /*is_subject_to_parental_controls=*/false, + /*can_stop_parental_supervision=*/false); + + base::HistogramTester histogram_tester; + ProvideHistograms(); + + histogram_tester.ExpectUniqueSample( + FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), + FamilyLinkUserMetricsProvider::LogSegment::kUnsupervised, + /*expected_bucket_count=*/1); +} + +TEST_P(FamilyLinkUserMetricsProviderTest, + ProfilesWithMixedSupervisedUsersLoggedAsMixedProfile) { + base::test::ScopedFeatureList feature{ + kExtendFamilyLinkUserLogSegmentToAllPlatforms}; + + // Profile with supervision set by user + CreateTestingProfile(kTestEmail1, kTestProfile1, + /*is_subject_to_parental_controls=*/true, + /*can_stop_parental_supervision=*/false); + // Profile with supervision set by policy + CreateTestingProfile(kTestEmail2, kTestProfile2, + /*is_subject_to_parental_controls=*/true, + /*can_stop_parental_supervision=*/true); + + base::HistogramTester histogram_tester; + ProvideHistograms(); + histogram_tester.ExpectBucketCount( + FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), + FamilyLinkUserMetricsProvider::LogSegment::kMixedProfile, + /*expected_count=*/1); +} + +TEST_P(FamilyLinkUserMetricsProviderTest, + ProfilesWithMixedSupervisedAndAdultUsersLoggedAsMixedProfile) { + base::test::ScopedFeatureList feature{ + kExtendFamilyLinkUserLogSegmentToAllPlatforms}; + + // Adult profile + + CreateTestingProfile(kTestEmail, kTestProfile, + /*is_subject_to_parental_controls=*/false, + /*can_stop_parental_supervision=*/false); + + // Profile with supervision set by user + CreateTestingProfile(kTestEmail1, kTestProfile1, + /*is_subject_to_parental_controls=*/true, + /*can_stop_parental_supervision=*/false); + + // Profile with supervision set by policy + CreateTestingProfile(kTestEmail2, kTestProfile2, + /*is_subject_to_parental_controls=*/true, + /*can_stop_parental_supervision=*/true); + + base::HistogramTester histogram_tester; + ProvideHistograms(); + histogram_tester.ExpectBucketCount( + FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), + FamilyLinkUserMetricsProvider::LogSegment::kMixedProfile, + /*expected_count=*/1); +} + +TEST_P(FamilyLinkUserMetricsProviderTest, + NoProfilesAddedShouldNotLogHistogram) { + base::test::ScopedFeatureList feature{ + kExtendFamilyLinkUserLogSegmentToAllPlatforms}; + + // Add no profiles + base::HistogramTester histogram_tester; + ProvideHistograms(); + histogram_tester.ExpectBucketCount( + FamilyLinkUserMetricsProvider::GetHistogramNameForTesting(), + FamilyLinkUserMetricsProvider::LogSegment::kMixedProfile, + /*expected_count=*/0); }
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index 3ebd417..db593e5 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -1079,6 +1079,7 @@ UpdateAllStorageAccessSettings(profile_); break; case ContentSettingsType::DEFAULT: + UpdateAntiAbuseSettings(profile_); UpdateCookieSettings(profile_); UpdateLegacyCookieSettings(profile_); UpdateAllStorageAccessSettings(profile_);
diff --git a/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java b/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java index 1b7fb461..74b08f9 100644 --- a/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java +++ b/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java
@@ -127,7 +127,7 @@ ActionType.OFFLINE_CONTENT_SUGGESTION_SETTINGS, ActionType.SHARING_TRY_AGAIN, ActionType.SETTINGS, ActionType.ANNOUNCEMENT_ACK, ActionType.ANNOUNCEMENT_OPEN, ActionType.PRICE_DROP_VISIT_SITE, ActionType.PRICE_DROP_TURN_OFF_ALERT, - ActionType.WEB_APK_ACTION_BACK_TO_SITE}) + ActionType.WEB_APK_ACTION_BACK_TO_SITE, ActionType.WEB_APK_ACTION_RETRY}) @Retention(RetentionPolicy.SOURCE) public @interface ActionType { int UNKNOWN = -1; @@ -186,8 +186,10 @@ // Back to site button on WebAPK install error notification. int WEB_APK_ACTION_BACK_TO_SITE = 28; + // Retry button on WebAPK install error notification. + int WEB_APK_ACTION_RETRY = 29; - int NUM_ENTRIES = 29; + int NUM_ENTRIES = 30; } /**
diff --git a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc index 18446dc6..d0745c6 100644 --- a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc +++ b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
@@ -73,13 +73,8 @@ } // namespace -// TODO(crbug.com/1369012): Fix flakiness. -#if BUILDFLAG(IS_MAC) -#define MAYBE_LargestContentfulPaint DISABLED_LargestContentfulPaint -#else -#define MAYBE_LargestContentfulPaint LargestContentfulPaint -#endif -IN_PROC_BROWSER_TEST_F(MetricIntegrationTest, MAYBE_LargestContentfulPaint) { +// TODO(crbug.com/1369012, crbug.com/1426420): Fix flakiness. +IN_PROC_BROWSER_TEST_F(MetricIntegrationTest, DISABLED_LargestContentfulPaint) { auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>( web_contents()); Start();
diff --git a/chrome/browser/printing/print_backend_service_manager.cc b/chrome/browser/printing/print_backend_service_manager.cc index d3151de..2d4760b9 100644 --- a/chrome/browser/printing/print_backend_service_manager.cc +++ b/chrome/browser/printing/print_backend_service_manager.cc
@@ -8,6 +8,7 @@ #include <string> #include <utility> +#include "base/check_op.h" #include "base/containers/contains.h" #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" @@ -15,6 +16,7 @@ #include "base/logging.h" #include "base/memory/scoped_refptr.h" #include "base/metrics/histogram_functions.h" +#include "base/notreached.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "base/unguessable_token.h" @@ -185,8 +187,8 @@ void PrintBackendServiceManager::EnumeratePrinters( mojom::PrintBackendService::EnumeratePrintersCallback callback) { CallbackContext context; - auto& service = GetServiceAndCallbackContext(kEmptyPrinterName, - ClientType::kQuery, context); + auto& service = + GetServiceAndCallbackContextForQuery(kEmptyPrinterName, context); SaveCallback(GetRemoteSavedEnumeratePrintersCallbacks(context.is_sandboxed), context.remote_id, context.saved_callback_id, @@ -202,8 +204,7 @@ const std::string& printer_name, mojom::PrintBackendService::FetchCapabilitiesCallback callback) { CallbackContext context; - auto& service = - GetServiceAndCallbackContext(printer_name, ClientType::kQuery, context); + auto& service = GetServiceAndCallbackContextForQuery(printer_name, context); SaveCallback(GetRemoteSavedFetchCapabilitiesCallbacks(context.is_sandboxed), context.remote_id, context.saved_callback_id, @@ -221,8 +222,8 @@ void PrintBackendServiceManager::GetDefaultPrinterName( mojom::PrintBackendService::GetDefaultPrinterNameCallback callback) { CallbackContext context; - auto& service = GetServiceAndCallbackContext(kEmptyPrinterName, - ClientType::kQuery, context); + auto& service = + GetServiceAndCallbackContextForQuery(kEmptyPrinterName, context); SaveCallback( GetRemoteSavedGetDefaultPrinterNameCallbacks(context.is_sandboxed), @@ -239,8 +240,7 @@ mojom::PrintBackendService::GetPrinterSemanticCapsAndDefaultsCallback callback) { CallbackContext context; - auto& service = - GetServiceAndCallbackContext(printer_name, ClientType::kQuery, context); + auto& service = GetServiceAndCallbackContextForQuery(printer_name, context); SaveCallback(GetRemoteSavedGetPrinterSemanticCapsAndDefaultsCallbacks( context.is_sandboxed), @@ -259,6 +259,7 @@ PrintBackendServiceManager::ContextId PrintBackendServiceManager::EstablishPrintingContext( + ClientId client_id, const std::string& printer_name #if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) , @@ -272,8 +273,8 @@ // could be needed. Associate this with the printing document client type, // given that most cases would fall into this usage. CallbackContext context; - auto& service = GetServiceAndCallbackContext( - printer_name, ClientType::kPrintDocument, context); + auto& service = GetServiceAndCallbackContextForPrintDocumentClient( + client_id, printer_name, context); LogCallToRemote("EstablishPrintingContext", context); ContextId context_id = ContextId(++last_context_id_); @@ -287,7 +288,7 @@ } void PrintBackendServiceManager::UseDefaultSettings( - const std::string& printer_name, + ClientId client_id, mojom::PrintBackendService::UseDefaultSettingsCallback callback) { // Even though this call does not require a UI, it is used exclusively as // part of preparation for system print. It is called immediately before a @@ -295,15 +296,13 @@ // it will behave better to ensure this uses the same type to reuse the same // process. CallbackContext context; - auto& service = GetServiceAndCallbackContext( - printer_name, ClientType::kQueryWithUi, context); + auto& service = GetServiceAndCallbackContextForQueryWithUiClient( + client_id, kEmptyPrinterName, context); SaveCallback(GetRemoteSavedUseDefaultSettingsCallbacks(context.is_sandboxed), context.remote_id, context.saved_callback_id, std::move(callback)); - SetCrashKeys(printer_name); - LogCallToRemote("UseDefaultSettings", context); service->UseDefaultSettings( base::BindOnce(&PrintBackendServiceManager::OnDidUseDefaultSettings, @@ -312,22 +311,20 @@ #if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) void PrintBackendServiceManager::AskUserForSettings( - const std::string& printer_name, + ClientId client_id, gfx::NativeView parent_view, int max_pages, bool has_selection, bool is_scripted, mojom::PrintBackendService::AskUserForSettingsCallback callback) { CallbackContext context; - auto& service = GetServiceAndCallbackContext( - printer_name, ClientType::kQueryWithUi, context); + auto& service = GetServiceAndCallbackContextForQueryWithUiClient( + client_id, kEmptyPrinterName, context); SaveCallback(GetRemoteSavedAskUserForSettingsCallbacks(context.is_sandboxed), context.remote_id, context.saved_callback_id, std::move(callback)); - SetCrashKeys(printer_name); - LogCallToRemote("AskUserForSettings", context); service->AskUserForSettings( NativeViewToUint(parent_view), max_pages, has_selection, is_scripted, @@ -337,12 +334,16 @@ #endif // BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) void PrintBackendServiceManager::UpdatePrintSettings( + absl::optional<ClientId> client_id, const std::string& printer_name, base::Value::Dict job_settings, mojom::PrintBackendService::UpdatePrintSettingsCallback callback) { CallbackContext context; auto& service = - GetServiceAndCallbackContext(printer_name, ClientType::kQuery, context); + client_id.has_value() + ? GetServiceAndCallbackContextForQueryWithUiClient( + *client_id, printer_name, context) + : GetServiceAndCallbackContextForQuery(printer_name, context); SaveCallback(GetRemoteSavedUpdatePrintSettingsCallbacks(context.is_sandboxed), context.remote_id, context.saved_callback_id, @@ -358,6 +359,7 @@ } void PrintBackendServiceManager::StartPrinting( + ClientId client_id, const std::string& printer_name, int document_cookie, const std::u16string& document_name, @@ -365,8 +367,8 @@ const PrintSettings& settings, mojom::PrintBackendService::StartPrintingCallback callback) { CallbackContext context; - auto& service = GetServiceAndCallbackContext( - printer_name, ClientType::kPrintDocument, context); + auto& service = GetServiceAndCallbackContextForPrintDocumentClient( + client_id, printer_name, context); SaveCallback(GetRemoteSavedStartPrintingCallbacks(context.is_sandboxed), context.remote_id, context.saved_callback_id, @@ -383,6 +385,7 @@ #if BUILDFLAG(IS_WIN) void PrintBackendServiceManager::RenderPrintedPage( + ClientId client_id, const std::string& printer_name, int document_cookie, const PrintedPage& page, @@ -390,8 +393,8 @@ base::ReadOnlySharedMemoryRegion serialized_page_data, mojom::PrintBackendService::RenderPrintedPageCallback callback) { CallbackContext context; - auto& service = GetServiceAndCallbackContext( - printer_name, ClientType::kPrintDocument, context); + auto& service = GetServiceAndCallbackContextForPrintDocumentClient( + client_id, printer_name, context); SaveCallback(GetRemoteSavedRenderPrintedPageCallbacks(context.is_sandboxed), context.remote_id, context.saved_callback_id, @@ -413,6 +416,7 @@ #endif // BUILDFLAG(IS_WIN) void PrintBackendServiceManager::RenderPrintedDocument( + ClientId client_id, const std::string& printer_name, int document_cookie, uint32_t page_count, @@ -420,8 +424,8 @@ base::ReadOnlySharedMemoryRegion serialized_data, mojom::PrintBackendService::RenderPrintedDocumentCallback callback) { CallbackContext context; - auto& service = GetServiceAndCallbackContext( - printer_name, ClientType::kPrintDocument, context); + auto& service = GetServiceAndCallbackContextForPrintDocumentClient( + client_id, printer_name, context); SaveCallback( GetRemoteSavedRenderPrintedDocumentCallbacks(context.is_sandboxed), @@ -437,12 +441,13 @@ } void PrintBackendServiceManager::DocumentDone( + ClientId client_id, const std::string& printer_name, int document_cookie, mojom::PrintBackendService::DocumentDoneCallback callback) { CallbackContext context; - auto& service = GetServiceAndCallbackContext( - printer_name, ClientType::kPrintDocument, context); + auto& service = GetServiceAndCallbackContextForPrintDocumentClient( + client_id, printer_name, context); SaveCallback(GetRemoteSavedDocumentDoneCallbacks(context.is_sandboxed), context.remote_id, context.saved_callback_id, @@ -458,12 +463,13 @@ } void PrintBackendServiceManager::Cancel( + ClientId client_id, const std::string& printer_name, int document_cookie, mojom::PrintBackendService::CancelCallback callback) { CallbackContext context; - auto& service = GetServiceAndCallbackContext( - printer_name, ClientType::kPrintDocument, context); + auto& service = GetServiceAndCallbackContextForPrintDocumentClient( + client_id, printer_name, context); SaveCallback(GetRemoteSavedCancelCallbacks(context.is_sandboxed), context.remote_id, context.saved_callback_id, @@ -558,6 +564,26 @@ return RemoteId(1); } +PrintBackendServiceManager::RemoteId +PrintBackendServiceManager::GetRemoteIdForQueryWithUiClientId( + ClientId client_id) const { + const auto& iter = query_with_ui_clients_.find(client_id); + CHECK(iter != query_with_ui_clients_.cend()); + return iter->second; +} + +PrintBackendServiceManager::RemoteId +PrintBackendServiceManager::GetRemoteIdForPrintDocumentClientId( + ClientId client_id) const { + for (const auto& item : print_document_clients_) { + const ClientsSet& clients = item.second; + if (clients.contains(client_id)) { + return item.first; + } + } + NOTREACHED_NORETURN(); +} + absl::optional<PrintBackendServiceManager::ClientId> PrintBackendServiceManager::RegisterClient( ClientType client_type, @@ -1126,13 +1152,34 @@ } const mojo::Remote<mojom::PrintBackendService>& -PrintBackendServiceManager::GetServiceAndCallbackContext( +PrintBackendServiceManager::GetServiceAndCallbackContextForQuery( const std::string& printer_name, - ClientType client_type, CallbackContext& context) { context.remote_id = GetRemoteIdForPrinterName(printer_name); context.saved_callback_id = base::UnguessableToken::Create(); - return GetService(printer_name, client_type, &context.is_sandboxed); + return GetService(printer_name, ClientType::kQuery, &context.is_sandboxed); +} + +const mojo::Remote<mojom::PrintBackendService>& +PrintBackendServiceManager::GetServiceAndCallbackContextForQueryWithUiClient( + ClientId client_id, + const std::string& printer_name, + CallbackContext& context) { + context.remote_id = GetRemoteIdForQueryWithUiClientId(client_id); + context.saved_callback_id = base::UnguessableToken::Create(); + return GetService(printer_name, ClientType::kQueryWithUi, + &context.is_sandboxed); +} + +const mojo::Remote<mojom::PrintBackendService>& +PrintBackendServiceManager::GetServiceAndCallbackContextForPrintDocumentClient( + ClientId client_id, + const std::string& printer_name, + CallbackContext& context) { + context.remote_id = GetRemoteIdForPrintDocumentClientId(client_id); + context.saved_callback_id = base::UnguessableToken::Create(); + return GetService(printer_name, ClientType::kPrintDocument, + &context.is_sandboxed); } template <class... T, class... X>
diff --git a/chrome/browser/printing/print_backend_service_manager.h b/chrome/browser/printing/print_backend_service_manager.h index 05b60020..734ddd8 100644 --- a/chrome/browser/printing/print_backend_service_manager.h +++ b/chrome/browser/printing/print_backend_service_manager.h
@@ -136,29 +136,45 @@ const std::string& printer_name, mojom::PrintBackendService::GetPrinterSemanticCapsAndDefaultsCallback callback); - ContextId EstablishPrintingContext(const std::string& printer_name + ContextId EstablishPrintingContext(ClientId client_id, + const std::string& printer_name #if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) , gfx::NativeView parent_view #endif ); void UseDefaultSettings( - const std::string& printer_name, + ClientId client_id, mojom::PrintBackendService::UseDefaultSettingsCallback callback); #if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) void AskUserForSettings( - const std::string& printer_name, + ClientId client_id, gfx::NativeView parent_view, int max_pages, bool has_selection, bool is_scripted, mojom::PrintBackendService::AskUserForSettingsCallback callback); #endif + // `UpdatePrintSettings()` can be used in two different scenarios: + // - For Print Preview, where the desire is to use the appropriate + // service based on the `printer_name` indicated. + // - System printing, where a particular PrintBackendService instance + // is desired, and is selected based upon a ClientId. + // When `client_id` is null, then the `printer_name` will be used to select + // the service. Otherwise the `client_id` value will be used, similar to + // other methods related for supporting the system print dialog and for + // printing the document. + // TODO(crbug.com/1414968): Remove use of optional for `client_id` once + // this the callers are updated to take advantage of `UpdatePrintSettings()` + // no longer being needed for Print Preview queries after + // https://crrev.com/1117252. void UpdatePrintSettings( + absl::optional<ClientId> client_id, const std::string& printer_name, base::Value::Dict job_settings, mojom::PrintBackendService::UpdatePrintSettingsCallback callback); void StartPrinting( + ClientId client_id, const std::string& printer_name, int document_cookie, const std::u16string& document_name, @@ -167,6 +183,7 @@ mojom::PrintBackendService::StartPrintingCallback callback); #if BUILDFLAG(IS_WIN) void RenderPrintedPage( + ClientId client_id, const std::string& printer_name, int document_cookie, const PrintedPage& page, @@ -175,16 +192,19 @@ mojom::PrintBackendService::RenderPrintedPageCallback callback); #endif void RenderPrintedDocument( + ClientId client_id, const std::string& printer_name, int document_cookie, uint32_t page_count, mojom::MetafileDataType data_type, base::ReadOnlySharedMemoryRegion serialized_data, mojom::PrintBackendService::RenderPrintedDocumentCallback callback); - void DocumentDone(const std::string& printer_name, + void DocumentDone(ClientId client_id, + const std::string& printer_name, int document_cookie, mojom::PrintBackendService::DocumentDoneCallback callback); - void Cancel(const std::string& printer_name, + void Cancel(ClientId client_id, + const std::string& printer_name, int document_cookie, mojom::PrintBackendService::CancelCallback callback); @@ -324,8 +344,18 @@ void SetCrashKeys(const std::string& printer_name); // Determine the remote ID that is used for the specified `printer_name`. + // Could generate a new RemoteId if one has not been previously created + // for the indicated printer. RemoteId GetRemoteIdForPrinterName(const std::string& printer_name); + // Determine the remote ID that is used for the specified `client_id` of a + // query with UI client. Will crash if no such client is found. + RemoteId GetRemoteIdForQueryWithUiClientId(ClientId client_id) const; + + // Determine the remote ID that is used for the specified `client_id` of a + // print document client. Will crash if no such client is found. + RemoteId GetRemoteIdForPrintDocumentClientId(ClientId client_id) const; + // Common helper for registering clients. The `destination` parameter can be // either a `std::string` for a printer name or a `RemoteId` which was // generated from a prior registration. This method will DCHECK if the @@ -440,10 +470,36 @@ RemoteSavedCancelCallbacks& GetRemoteSavedCancelCallbacks(bool sandboxed); // Helper function to get the service and initialize a `context` for a given - // `printer_name`. - const mojo::Remote<mojom::PrintBackendService>& GetServiceAndCallbackContext( + // `printer_name`. This is used for calls supporting Print Preview, where + // the client type is `kQuery`. + // TODO(crbug.com/1418830): Replace out parameter `context` with a + // structured return. + const mojo::Remote<mojom::PrintBackendService>& + GetServiceAndCallbackContextForQuery(const std::string& printer_name, + CallbackContext& context); + + // Helper function to get the service and initialize a `context` for a given + // query with UI `client_id`. Use `printer_name` for extra sandbox behavior + // handling. This is used for calls supporting system print dialogs and + // printing of a document. + // TODO(crbug.com/1418830): Replace out parameter `context` with a + // structured return. + const mojo::Remote<mojom::PrintBackendService>& + GetServiceAndCallbackContextForQueryWithUiClient( + ClientId client_id, const std::string& printer_name, - ClientType client_type, + CallbackContext& context); + + // Helper function to get the service and initialize a `context` for a given + // print document `client_id`. Use `printer_name` for extra sandbox behavior + // handling. This is used for calls supporting system print dialogs and + // printing of a document. + // TODO(crbug.com/1418830): Replace out parameter `context` with a + // structured return. + const mojo::Remote<mojom::PrintBackendService>& + GetServiceAndCallbackContextForPrintDocumentClient( + ClientId client_id, + const std::string& printer_name, CallbackContext& context); // Helper functions to save outstanding callbacks.
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc index 044b34d..b496ff4 100644 --- a/chrome/browser/printing/print_job.cc +++ b/chrome/browser/printing/print_job.cc
@@ -153,17 +153,6 @@ UpdatePrintedDocument(new_doc); } -#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) -void PrintJob::SetPrintDocumentClient( - PrintBackendServiceManager::ClientId client_id) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(worker_); - worker_->PostTask(FROM_HERE, - base::BindOnce(&PrintJobWorker::SetPrintDocumentClient, - base::Unretained(worker_.get()), client_id)); -} -#endif - #if BUILDFLAG(IS_WIN) // static std::vector<uint32_t> PrintJob::GetFullPageMapping(
diff --git a/chrome/browser/printing/print_job.h b/chrome/browser/printing/print_job.h index a1431cb..f0a77ac6 100644 --- a/chrome/browser/printing/print_job.h +++ b/chrome/browser/printing/print_job.h
@@ -22,10 +22,6 @@ #include "chromeos/crosapi/mojom/local_printer.mojom.h" #endif -#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) -#include "chrome/browser/printing/print_backend_service_manager.h" -#endif - namespace base { class Location; class RefCountedMemory; @@ -87,14 +83,6 @@ const std::u16string& name, uint32_t page_count); -#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) - // Called to notify the print job that it has already been registered with the - // PrintBackendServiceManager as a print document client. The PrintJob takes - // responsibility for (and passes along to PrintJobWorker) unregistering the - // client ID with PrintBackendServiceManager once printing is completed. - void SetPrintDocumentClient(PrintBackendServiceManager::ClientId client_id); -#endif - #if BUILDFLAG(IS_WIN) void StartConversionToNativeFormat( scoped_refptr<base::RefCountedMemory> print_data,
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc index 8980d28b..ef8aad1 100644 --- a/chrome/browser/printing/print_job_worker.cc +++ b/chrome/browser/printing/print_job_worker.cc
@@ -26,7 +26,6 @@ #include "content/public/browser/global_routing_id.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" -#include "printing/buildflags/buildflags.h" #include "printing/mojom/print.mojom.h" #include "printing/print_job_constants.h" #include "printing/printed_document.h" @@ -39,7 +38,7 @@ #include "printing/printed_page_win.h" #endif -#if BUILDFLAG(IS_WIN) || BUILDFLAG(ENABLE_OOP_PRINTING) +#if BUILDFLAG(IS_WIN) #include "printing/printing_features.h" #endif @@ -77,15 +76,6 @@ Stop(); } -#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) -void PrintJobWorker::SetPrintDocumentClient( - PrintBackendServiceManager::ClientId client_id) { - // This call should only be made for configurations that use - // `PrintJobWorkerOop`. - NOTREACHED(); -} -#endif - bool PrintJobWorker::StartPrintingSanityCheck( const PrintedDocument* new_document) const { DCHECK(task_runner_->RunsTasksInCurrentSequence());
diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h index d315a5d..4f4ab568 100644 --- a/chrome/browser/printing/print_job_worker.h +++ b/chrome/browser/printing/print_job_worker.h
@@ -18,10 +18,6 @@ #include "printing/page_number.h" #include "printing/printing_context.h" -#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) -#include "chrome/browser/printing/print_backend_service_manager.h" -#endif - namespace printing { class PrintJob; @@ -44,17 +40,6 @@ virtual ~PrintJobWorker(); -#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) - // Called to notify the print job that it has already been registered with the - // PrintBackendServiceManager as a print document client. The PrintJobWorker - // takes responsibility for unregistering the client ID once the print job is - // completed. This is only meaningful for jobs which are being printed OOP; - // this will DCHECK if it is used for jobs that make all the platform printing - // calls from the browser process. - virtual void SetPrintDocumentClient( - PrintBackendServiceManager::ClientId client_id); -#endif - // Starts the printing loop. Every pages are printed as soon as the data is // available. Makes sure the new_document is the right one. virtual void StartPrinting(PrintedDocument* new_document);
diff --git a/chrome/browser/printing/print_job_worker_oop.cc b/chrome/browser/printing/print_job_worker_oop.cc index 8ba3d0c..c9576f1 100644 --- a/chrome/browser/printing/print_job_worker_oop.cc +++ b/chrome/browser/printing/print_job_worker_oop.cc
@@ -48,10 +48,12 @@ PrintJobWorkerOop::PrintJobWorkerOop( std::unique_ptr<PrintingContext::Delegate> printing_context_delegate, std::unique_ptr<PrintingContext> printing_context, + absl::optional<PrintBackendServiceManager::ClientId> client_id, PrintJob* print_job, mojom::PrintTargetType print_target_type) : PrintJobWorkerOop(std::move(printing_context_delegate), std::move(printing_context), + client_id, print_job, print_target_type, /*simulate_spooling_memory_errors=*/false) {} @@ -59,6 +61,7 @@ PrintJobWorkerOop::PrintJobWorkerOop( std::unique_ptr<PrintingContext::Delegate> printing_context_delegate, std::unique_ptr<PrintingContext> printing_context, + absl::optional<PrintBackendServiceManager::ClientId> client_id, PrintJob* print_job, mojom::PrintTargetType print_target_type, bool simulate_spooling_memory_errors) @@ -66,20 +69,13 @@ std::move(printing_context), print_job), simulate_spooling_memory_errors_(simulate_spooling_memory_errors), + service_manager_client_id_(client_id), print_target_type_(print_target_type) {} PrintJobWorkerOop::~PrintJobWorkerOop() { DCHECK(!service_manager_client_id_.has_value()); } -#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) -void PrintJobWorkerOop::SetPrintDocumentClient( - PrintBackendServiceManager::ClientId client_id) { - DCHECK(!service_manager_client_id_.has_value()); - service_manager_client_id_ = client_id; -} -#endif - void PrintJobWorkerOop::StartPrinting(PrintedDocument* new_document) { if (!StartPrintingSanityCheck(new_document)) return; @@ -393,8 +389,8 @@ } service_mgr.StartPrinting( - device_name_, document_cookie, document_name_, print_target_type_, - document_oop_->settings(), + *service_manager_client_id_, device_name_, document_cookie, + document_name_, print_target_type_, document_oop_->settings(), base::BindOnce(&PrintJobWorkerOop::OnDidStartPrinting, ui_weak_factory_.GetWeakPtr())); } @@ -414,8 +410,8 @@ PrintBackendServiceManager& service_mgr = PrintBackendServiceManager::GetInstance(); service_mgr.RenderPrintedPage( - device_name_, document_cookie, *page, page_data_type, - std::move(serialized_page_data), + *service_manager_client_id_, device_name_, document_cookie, *page, + page_data_type, std::move(serialized_page_data), base::BindOnce(&PrintJobWorkerOop::OnDidRenderPrintedPage, ui_weak_factory_.GetWeakPtr(), page_index)); } @@ -432,8 +428,8 @@ PrintBackendServiceManager& service_mgr = PrintBackendServiceManager::GetInstance(); service_mgr.RenderPrintedDocument( - device_name_, document_cookie, document_oop_->page_count(), data_type, - std::move(serialized_data), + *service_manager_client_id_, device_name_, document_cookie, + document_oop_->page_count(), data_type, std::move(serialized_data), base::BindOnce(&PrintJobWorkerOop::OnDidRenderPrintedDocument, ui_weak_factory_.GetWeakPtr())); } @@ -447,7 +443,8 @@ PrintBackendServiceManager& service_mgr = PrintBackendServiceManager::GetInstance(); - service_mgr.DocumentDone(device_name_, document_cookie, + service_mgr.DocumentDone(*service_manager_client_id_, device_name_, + document_cookie, base::BindOnce(&PrintJobWorkerOop::OnDidDocumentDone, ui_weak_factory_.GetWeakPtr(), printing_context()->job_id())); @@ -473,7 +470,7 @@ // Retain a reference to the PrintJob to ensure it doesn't get deleted before // the `OnDidCancel()` callback occurs. service_mgr.Cancel( - device_name_, document_oop_->cookie(), + *service_manager_client_id_, device_name_, document_oop_->cookie(), base::BindOnce(&PrintJobWorkerOop::OnDidCancel, ui_weak_factory_.GetWeakPtr(), std::move(job))); }
diff --git a/chrome/browser/printing/print_job_worker_oop.h b/chrome/browser/printing/print_job_worker_oop.h index b92e14d..bcf299a 100644 --- a/chrome/browser/printing/print_job_worker_oop.h +++ b/chrome/browser/printing/print_job_worker_oop.h
@@ -31,9 +31,16 @@ // thread. PrintJob always outlives its worker instance. class PrintJobWorkerOop : public PrintJobWorker { public: + // The `client_id` specifies the print document client registered with + // `PrintBackendServiceManager`. `PrintJobWorkerOop` takes responsibility + // for unregistering the client ID with `PrintBackendServiceManager` once + // printing is completed. + // The `client_id` can be empty. This can occur for placeholder print jobs + // that don't actually initiate printing such as during content analysis. PrintJobWorkerOop( std::unique_ptr<PrintingContext::Delegate> printing_context_delegate, std::unique_ptr<PrintingContext> printing_context, + absl::optional<PrintBackendServiceManager::ClientId> client_id, PrintJob* print_job, mojom::PrintTargetType print_target_type); PrintJobWorkerOop(const PrintJobWorkerOop&) = delete; @@ -41,10 +48,6 @@ ~PrintJobWorkerOop() override; // `PrintJobWorker` overrides. -#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) - void SetPrintDocumentClient( - PrintBackendServiceManager::ClientId client_id) override; -#endif void StartPrinting(PrintedDocument* new_document) override; protected: @@ -52,10 +55,13 @@ PrintJobWorkerOop( std::unique_ptr<PrintingContext::Delegate> printing_context_delegate, std::unique_ptr<PrintingContext> printing_context, + absl::optional<PrintBackendServiceManager::ClientId> client_id, PrintJob* print_job, mojom::PrintTargetType print_target_type, bool simulate_spooling_memory_errors); + // Local callback wrappers for Print Backend Service mojom call. Virtual to + // support testing. virtual void OnDidStartPrinting(mojom::ResultCode result); #if BUILDFLAG(IS_WIN) virtual void OnDidRenderPrintedPage(uint32_t page_index,
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc index 4f9fe26..9c9a56c2 100644 --- a/chrome/browser/printing/print_view_manager_base.cc +++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -382,18 +382,6 @@ #if BUILDFLAG(ENABLE_OOP_PRINTING) if (printing::features::kEnableOopPrintDriversJobPrint.Get()) { -#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) - if (params) { - CHECK(params->params->document_cookie); - // Want the same PrintBackend service as the query so that we use the - // same device context. - DCHECK(query_with_ui_client_id_.has_value()); - print_document_client_id_ = - PrintBackendServiceManager::GetInstance() - .RegisterPrintDocumentClientReusingClientRemote( - *query_with_ui_client_id_); - } -#endif // Finished getting all settings (defaults and from user), no further need // to be registered as a system print client. UnregisterSystemPrintClient(); @@ -571,6 +559,11 @@ if (!printer_query) { printer_query = queue_->CreatePrinterQuery(render_frame_host->GetGlobalId()); +#if BUILDFLAG(ENABLE_OOP_PRINTING) + if (query_with_ui_client_id_.has_value()) { + printer_query->SetClientId(*query_with_ui_client_id_); + } +#endif } // Sometimes it is desired to get the PDF settings as opposed to the settings @@ -1028,14 +1021,6 @@ return true; #endif -#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) - if (print_document_client_id_) { - // Ensure that the print job knows it is already registered as a client. - print_job_->SetPrintDocumentClient(*print_document_client_id_); - print_document_client_id_.reset(); - } -#endif - // Settings are already loaded. Go ahead. This will set // print_job_->is_job_pending() to true. print_job_->StartPrinting();
diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h index 52faaed..5aec084 100644 --- a/chrome/browser/printing/print_view_manager_base.h +++ b/chrome/browser/printing/print_view_manager_base.h
@@ -359,14 +359,7 @@ #if BUILDFLAG(ENABLE_OOP_PRINTING) // Client ID with the print backend service manager for system print dialog. absl::optional<PrintBackendServiceManager::ClientId> query_with_ui_client_id_; - -#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) - // Client ID with the print backend service manager to reuse for printing, to - // get the same device context as was used with the system print dialog. - absl::optional<PrintBackendServiceManager::ClientId> - print_document_client_id_; #endif -#endif // BUILDFLAG(ENABLE_OOP_PRINTING) #if BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS) // Indicates that a snapshot of the page/document is currently being made.
diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc index d01d616..7f77a94 100644 --- a/chrome/browser/printing/printer_query.cc +++ b/chrome/browser/printing/printer_query.cc
@@ -10,6 +10,7 @@ #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/location.h" +#include "base/notreached.h" #include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" @@ -247,6 +248,13 @@ } #endif +#if BUILDFLAG(ENABLE_OOP_PRINTING) +void PrinterQuery::SetClientId(PrintBackendServiceManager::ClientId client_id) { + // Only supposed to be called for `PrinterQueryOop` objects. + NOTREACHED_NORETURN(); +} +#endif + std::unique_ptr<PrintSettings> PrinterQuery::GetPdfSettings() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/chrome/browser/printing/printer_query.h b/chrome/browser/printing/printer_query.h index 9afb999d..08f55844 100644 --- a/chrome/browser/printing/printer_query.h +++ b/chrome/browser/printing/printer_query.h
@@ -11,9 +11,15 @@ #include "base/values.h" #include "build/build_config.h" #include "content/public/browser/global_routing_id.h" +#include "printing/buildflags/buildflags.h" #include "printing/mojom/print.mojom.h" #include "printing/print_settings.h" #include "printing/printing_context.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +#if BUILDFLAG(ENABLE_OOP_PRINTING) +#include "chrome/browser/printing/print_backend_service_manager.h" +#endif namespace content { class WebContents; @@ -82,6 +88,14 @@ base::OnceClosure callback); #endif +#if BUILDFLAG(ENABLE_OOP_PRINTING) + // Provide the client ID when the caller has registered with the + // `PrintBackendServiceManager` for getting settings for system print. + // Only intended to be used when out-of-process printing is in use, will + // DCHECK if used for in-browser printing. + virtual void SetClientId(PrintBackendServiceManager::ClientId client_id); +#endif + int cookie() const; mojom::ResultCode last_status() const { return last_status_; }
diff --git a/chrome/browser/printing/printer_query_oop.cc b/chrome/browser/printing/printer_query_oop.cc index 24c6772..2237b86 100644 --- a/chrome/browser/printing/printer_query_oop.cc +++ b/chrome/browser/printing/printer_query_oop.cc
@@ -47,6 +47,11 @@ return CreatePrintJobWorker(print_job); } +void PrinterQueryOop::SetClientId( + PrintBackendServiceManager::ClientId client_id) { + query_with_ui_client_id_ = client_id; +} + void PrinterQueryOop::OnDidUseDefaultSettings( SettingsCallback callback, mojom::PrintSettingsResultPtr print_settings) { @@ -89,10 +94,33 @@ VLOG(1) << "Ask user for settings from service complete"; result = mojom::ResultCode::kSuccess; printing_context()->ApplyPrintSettings(print_settings->get_settings()); + + // Use the same PrintBackendService for querying and printing, so that the + // same device context can be used with both. + print_document_client_id_ = + PrintBackendServiceManager::GetInstance() + .RegisterPrintDocumentClientReusingClientRemote( + *query_with_ui_client_id_); } InvokeSettingsCallback(std::move(callback), result); } +#else // BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) +void PrinterQueryOop::OnDidAskUserForSettings( + SettingsCallback callback, + std::unique_ptr<PrintSettings> new_settings, + mojom::ResultCode result) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (result == mojom::ResultCode::kSuccess) { + // Want the same PrintBackend service as the query so that we use the same + // device context. + print_document_client_id_ = + PrintBackendServiceManager::GetInstance() + .RegisterPrintDocumentClientReusingClientRemote( + *query_with_ui_client_id_); + } + std::move(callback).Run(std::move(new_settings), result); +} #endif // BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) void PrinterQueryOop::UseDefaultSettings(SettingsCallback callback) { @@ -124,8 +152,10 @@ // browser process. // - Other platforms don't have a system print UI or do not use OOP // printing, so this does not matter. - PrinterQuery::GetSettingsWithUI(document_page_count, has_selection, - is_scripted, std::move(callback)); + PrinterQuery::GetSettingsWithUI( + document_page_count, has_selection, is_scripted, + base::BindOnce(&PrinterQueryOop::OnDidAskUserForSettings, + weak_factory_.GetWeakPtr(), std::move(callback))); #endif } @@ -145,7 +175,7 @@ PrintBackendServiceManager::GetInstance(); service_mgr.UpdatePrintSettings( - device_name, std::move(new_settings), + query_with_ui_client_id_, device_name, std::move(new_settings), base::BindOnce(&PrinterQueryOop::OnDidUpdatePrintSettings, weak_factory_.GetWeakPtr(), device_name, std::move(callback))); @@ -169,6 +199,14 @@ VLOG(1) << "Update print settings via service complete for " << device_name; result = mojom::ResultCode::kSuccess; printing_context()->ApplyPrintSettings(print_settings->get_settings()); + + // Query work completed, next step will be to print. + // TODO(crbug.com/1414968): Registration for printing a document will + // need to be made before calling `UpdatePrintSettings()` once it requires + // a context ID. + print_document_client_id_ = + PrintBackendServiceManager::GetInstance().RegisterPrintDocumentClient( + device_name); } InvokeSettingsCallback(std::move(callback), result); } @@ -176,12 +214,13 @@ void PrinterQueryOop::SendUseDefaultSettings(SettingsCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(features::kEnableOopPrintDriversJobPrint.Get()); + CHECK(query_with_ui_client_id_.has_value()); PrintBackendServiceManager& service_mgr = PrintBackendServiceManager::GetInstance(); service_mgr.UseDefaultSettings( - /*printer_name=*/std::string(), + *query_with_ui_client_id_, base::BindOnce(&PrinterQueryOop::OnDidUseDefaultSettings, weak_factory_.GetWeakPtr(), std::move(callback))); } @@ -217,7 +256,7 @@ PrintBackendServiceManager& service_mgr = PrintBackendServiceManager::GetInstance(); service_mgr.AskUserForSettings( - /*printer_name=*/std::string(), parent_view, document_page_count, + *query_with_ui_client_id_, parent_view, document_page_count, has_selection, is_scripted, base::BindOnce(&PrinterQueryOop::OnDidAskUserForSettings, weak_factory_.GetWeakPtr(), std::move(callback))); @@ -228,7 +267,7 @@ PrintJob* print_job) { return std::make_unique<PrintJobWorkerOop>( std::move(printing_context_delegate_), std::move(printing_context_), - print_job, print_target_type_); + print_document_client_id_, print_job, print_target_type_); } } // namespace printing
diff --git a/chrome/browser/printing/printer_query_oop.h b/chrome/browser/printing/printer_query_oop.h index cf09c05..2485f50 100644 --- a/chrome/browser/printing/printer_query_oop.h +++ b/chrome/browser/printing/printer_query_oop.h
@@ -10,6 +10,7 @@ #include "base/functional/callback.h" #include "base/values.h" #include "build/build_config.h" +#include "chrome/browser/printing/print_backend_service_manager.h" #include "chrome/browser/printing/print_job_worker_oop.h" #include "chrome/browser/printing/printer_query.h" #include "chrome/services/printing/public/mojom/print_backend_service.mojom.h" @@ -17,6 +18,7 @@ #include "printing/mojom/print.mojom.h" #include "printing/print_settings.h" #include "printing/printing_context.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace printing { @@ -25,8 +27,10 @@ explicit PrinterQueryOop(content::GlobalRenderFrameHostId rfh_id); ~PrinterQueryOop() override; + // PrinterQuery overrides: std::unique_ptr<PrintJobWorker> TransferContextToNewWorker( PrintJob* print_job) override; + void SetClientId(PrintBackendServiceManager::ClientId client_id) override; protected: // Local callback wrappers for Print Backend Service mojom call. Virtual to @@ -38,6 +42,11 @@ virtual void OnDidAskUserForSettings( SettingsCallback callback, mojom::PrintSettingsResultPtr print_settings); +#else + virtual void OnDidAskUserForSettings( + SettingsCallback callback, + std::unique_ptr<PrintSettings> new_settings, + mojom::ResultCode result); #endif void OnDidUpdatePrintSettings(const std::string& device_name, SettingsCallback callback, @@ -64,6 +73,11 @@ virtual std::unique_ptr<PrintJobWorkerOop> CreatePrintJobWorker( PrintJob* print_job); + const absl::optional<PrintBackendServiceManager::ClientId>& + print_document_client_id() const { + return print_document_client_id_; + } + mojom::PrintTargetType print_target_type() const { return print_target_type_; } @@ -71,6 +85,9 @@ private: mojom::PrintTargetType print_target_type_ = mojom::PrintTargetType::kDirectToDevice; + absl::optional<PrintBackendServiceManager::ClientId> query_with_ui_client_id_; + absl::optional<PrintBackendServiceManager::ClientId> + print_document_client_id_; base::WeakPtrFactory<PrinterQueryOop> weak_factory_{this}; };
diff --git a/chrome/browser/printing/system_access_process_print_browsertest.cc b/chrome/browser/printing/system_access_process_print_browsertest.cc index d4e9d922..14f2f71 100644 --- a/chrome/browser/printing/system_access_process_print_browsertest.cc +++ b/chrome/browser/printing/system_access_process_print_browsertest.cc
@@ -151,12 +151,14 @@ TestPrintJobWorkerOop( std::unique_ptr<PrintingContext::Delegate> printing_context_delegate, std::unique_ptr<PrintingContext> printing_context, + PrintBackendServiceManager::ClientId client_id, PrintJob* print_job, mojom::PrintTargetType print_target_type, bool simulate_spooling_memory_errors, TestPrintJobWorkerOop::PrintCallbacks* callbacks) : PrintJobWorkerOop(std::move(printing_context_delegate), std::move(printing_context), + client_id, print_job, print_target_type, simulate_spooling_memory_errors), @@ -250,8 +252,8 @@ PrintJob* print_job) override { return std::make_unique<TestPrintJobWorkerOop>( std::move(printing_context_delegate_), std::move(printing_context_), - print_job, print_target_type(), simulate_spooling_memory_errors_, - callbacks_); + *print_document_client_id(), print_job, print_target_type(), + simulate_spooling_memory_errors_, callbacks_); } bool simulate_spooling_memory_errors_;
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 43ac4a4..b398758f 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -228,6 +228,7 @@ #include "chrome/browser/browsing_data/chrome_browsing_data_lifetime_manager_factory.h" #include "chrome/browser/cart/cart_service_factory.h" #include "chrome/browser/commerce/coupons/coupon_service_factory.h" +#include "chrome/browser/download/bubble/download_bubble_update_service_factory.h" #include "chrome/browser/feedback/feedback_uploader_factory_chrome.h" #include "chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_factory.h" #include "chrome/browser/media_galleries/gallery_watch_manager.h" @@ -598,6 +599,9 @@ DocumentSuggestionsServiceFactory::GetInstance(); DomainDiversityReporterFactory::GetInstance(); dom_distiller::DomDistillerServiceFactory::GetInstance(); +#if !BUILDFLAG(IS_ANDROID) + DownloadBubbleUpdateServiceFactory::GetInstance(); +#endif DownloadCoreServiceFactory::GetInstance(); #if !BUILDFLAG(IS_ANDROID) DriveServiceFactory::GetInstance();
diff --git a/chrome/browser/quick_delete/BUILD.gn b/chrome/browser/quick_delete/BUILD.gn index a5add96..ac70b4e 100644 --- a/chrome/browser/quick_delete/BUILD.gn +++ b/chrome/browser/quick_delete/BUILD.gn
@@ -17,6 +17,7 @@ "//chrome/browser/tabmodel:java", "//chrome/browser/ui/android/layouts:java", "//chrome/browser/ui/messages/android:java", + "//components/browsing_data/core:java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_annotation_annotation_jvm_java", "//ui/android:ui_no_recycler_view_java", @@ -51,6 +52,7 @@ "//chrome/browser/ui/messages/android:java", "//chrome/test/android:chrome_java_integration_test_support", "//chrome/test/android:chrome_java_test_support_common", + "//components/browsing_data/core:java", "//third_party/androidx:androidx_test_runner_java", "//third_party/junit:junit", "//third_party/mockito:mockito_java", @@ -78,6 +80,7 @@ "//chrome/browser/ui/android/layouts/test:java", "//chrome/test/android:chrome_java_integration_test_support", "//chrome/test/android:chrome_java_test_support_common", + "//components/browsing_data/core:java", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:espresso_java", "//third_party/androidx:androidx_test_runner_java",
diff --git a/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegate.java b/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegate.java index 75d627d5..65fafa9 100644 --- a/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegate.java +++ b/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegate.java
@@ -7,6 +7,7 @@ import androidx.annotation.IntDef; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.chrome.browser.browsing_data.ClearBrowsingDataAction; /** * A delegate class to record metrics associated with {@link QuickDeleteController}. @@ -29,8 +30,20 @@ int MAX_VALUE = DIALOG_DISMISSED_IMPLICITLY; } + /** + * A method to record the metrics of an action {@link PrivacyQuickDelete} related with + * QuickDelete. + * + * @param privacyQuickDelete action taken related to QuickDelete. + */ public static void recordHistogram(@PrivacyQuickDelete int privacyQuickDelete) { RecordHistogram.recordEnumeratedHistogram( "Privacy.QuickDelete", privacyQuickDelete, PrivacyQuickDelete.MAX_VALUE); + + if (privacyQuickDelete == PrivacyQuickDelete.DELETE_CLICKED) { + RecordHistogram.recordEnumeratedHistogram("Privacy.ClearBrowsingData.Action", + ClearBrowsingDataAction.QUICK_DELETE_LAST15_MINUTES, + ClearBrowsingDataAction.MAX_VALUE); + } } }
diff --git a/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteControllerTest.java b/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteControllerTest.java index 64e16b5..8a282f80 100644 --- a/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteControllerTest.java +++ b/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteControllerTest.java
@@ -28,6 +28,7 @@ import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.HistogramWatcher; import org.chromium.chrome.R; +import org.chromium.chrome.browser.browsing_data.ClearBrowsingDataAction; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.layouts.LayoutTestUtils; @@ -105,6 +106,22 @@ @Test @MediumTest + public void testQuickDeleteLast15MinutesHistogram_WhenClickingDelete() throws IOException { + openQuickDeleteDialog(); + + HistogramWatcher histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecords("Privacy.ClearBrowsingData.Action", + ClearBrowsingDataAction.QUICK_DELETE_LAST15_MINUTES, 1) + .build(); + + onViewWaiting(withId(R.id.positive_button)).perform(click()); + + histogramWatcher.assertExpected(); + } + + @Test + @MediumTest public void testCancelClickedHistogram_WhenClickingCancel() throws IOException { openQuickDeleteDialog();
diff --git a/chrome/browser/quick_delete/android/junit/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegateTest.java b/chrome/browser/quick_delete/android/junit/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegateTest.java index 19887e81..ce00a140 100644 --- a/chrome/browser/quick_delete/android/junit/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegateTest.java +++ b/chrome/browser/quick_delete/android/junit/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegateTest.java
@@ -10,12 +10,14 @@ import org.junit.runner.RunWith; import org.chromium.base.test.params.BlockJUnit4RunnerDelegate; -import org.chromium.base.test.params.ParameterAnnotations.ClassParameter; +import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter; import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate; +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.HistogramWatcher; +import org.chromium.chrome.browser.browsing_data.ClearBrowsingDataAction; import java.util.Arrays; import java.util.List; @@ -27,32 +29,35 @@ @UseRunnerDelegate(BlockJUnit4RunnerDelegate.class) @Batch(Batch.PER_CLASS) public class QuickDeleteMetricsDelegateTest { - @ClassParameter - private static List<ParameterSet> sClassParams = Arrays.asList( - new ParameterSet() - .value(QuickDeleteMetricsDelegate.PrivacyQuickDelete.MENU_ITEM_CLICKED) - .name("MenuItem"), - new ParameterSet() - .value(QuickDeleteMetricsDelegate.PrivacyQuickDelete.DELETE_CLICKED) - .name("Delete"), - new ParameterSet() - .value(QuickDeleteMetricsDelegate.PrivacyQuickDelete.CANCEL_CLICKED) - .name("Cancel"), - new ParameterSet() - .value(QuickDeleteMetricsDelegate.PrivacyQuickDelete - .DIALOG_DISMISSED_IMPLICITLY) - .name("Dismissed")); - - private @QuickDeleteMetricsDelegate.PrivacyQuickDelete int mPrivacyQuickDeleteMetric; - - public QuickDeleteMetricsDelegateTest( - @QuickDeleteMetricsDelegate.PrivacyQuickDelete int privacyQuickDeleteMetric) { - mPrivacyQuickDeleteMetric = privacyQuickDeleteMetric; + /** + * Class to parameterize the params for {@link + * QuickDeleteMetricsDelegateTest.testRecordHistogram}. + */ + public static class MethodParams implements ParameterProvider { + @Override + public List<ParameterSet> getParameters() { + return Arrays.asList( + new ParameterSet() + .value(QuickDeleteMetricsDelegate.PrivacyQuickDelete.MENU_ITEM_CLICKED) + .name("MenuItem"), + new ParameterSet() + .value(QuickDeleteMetricsDelegate.PrivacyQuickDelete.DELETE_CLICKED) + .name("Delete"), + new ParameterSet() + .value(QuickDeleteMetricsDelegate.PrivacyQuickDelete.CANCEL_CLICKED) + .name("Cancel"), + new ParameterSet() + .value(QuickDeleteMetricsDelegate.PrivacyQuickDelete + .DIALOG_DISMISSED_IMPLICITLY) + .name("Dismissed")); + } } @Test @SmallTest - public void testRecordHistogram() { + @UseMethodParameter(MethodParams.class) + public void testRecordHistogram( + @QuickDeleteMetricsDelegate.PrivacyQuickDelete int mPrivacyQuickDeleteMetric) { HistogramWatcher histogramWatcher = HistogramWatcher.newBuilder() .expectIntRecords("Privacy.QuickDelete", mPrivacyQuickDeleteMetric, 1) @@ -62,4 +67,19 @@ histogramWatcher.assertExpected(); } + + @Test + @SmallTest + public void testRecordClearBrowsingDataActionHistogram() { + HistogramWatcher histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecords("Privacy.ClearBrowsingData.Action", + ClearBrowsingDataAction.QUICK_DELETE_LAST15_MINUTES, 1) + .build(); + + QuickDeleteMetricsDelegate.recordHistogram( + QuickDeleteMetricsDelegate.PrivacyQuickDelete.DELETE_CLICKED); + + histogramWatcher.assertExpected(); + } }
diff --git a/chrome/browser/recent_tabs/BUILD.gn b/chrome/browser/recent_tabs/BUILD.gn index 1d216d4e..5ea2ff0 100644 --- a/chrome/browser/recent_tabs/BUILD.gn +++ b/chrome/browser/recent_tabs/BUILD.gn
@@ -6,13 +6,21 @@ import("//chrome/android/features/android_library_factory_tmpl.gni") android_library("java") { - sources = [ "android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsFeatureHelper.java" ] + sources = [ + "android/java/src/org/chromium/chrome/browser/recent_tabs/ForeignSessionHelper.java", + "android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsFeatureHelper.java", + ] deps = [ "//base:base_java", + "//base:jni_java", "//chrome/browser/profiles/android:java", + "//chrome/browser/tab:java", + "//content/public/android:content_java", + "//url:gurl_java", ] - resources_package = "org.chromium.chrome.recent_tabs" + + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] } android_library_factory("factory_java") { @@ -23,3 +31,7 @@ "//chrome/browser/recent_tabs/internal:java", ] } + +generate_jni("jni_headers") { + sources = [ "android/java/src/org/chromium/chrome/browser/recent_tabs/ForeignSessionHelper.java" ] +}
diff --git a/chrome/browser/recent_tabs/OWNERS b/chrome/browser/recent_tabs/OWNERS index dc9aaf8..2100443d 100644 --- a/chrome/browser/recent_tabs/OWNERS +++ b/chrome/browser/recent_tabs/OWNERS
@@ -1,2 +1,3 @@ +bjfong@google.com ckitagawa@chromium.org fredmello@chromium.org \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ForeignSessionHelper.java b/chrome/browser/recent_tabs/android/java/src/org/chromium/chrome/browser/recent_tabs/ForeignSessionHelper.java similarity index 92% rename from chrome/android/java/src/org/chromium/chrome/browser/ntp/ForeignSessionHelper.java rename to chrome/browser/recent_tabs/android/java/src/org/chromium/chrome/browser/recent_tabs/ForeignSessionHelper.java index 1f5e797..4e83f29 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ForeignSessionHelper.java +++ b/chrome/browser/recent_tabs/android/java/src/org/chromium/chrome/browser/recent_tabs/ForeignSessionHelper.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.ntp; +package org.chromium.chrome.browser.recent_tabs; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; @@ -24,7 +24,7 @@ /** * Callback interface for getting notified when foreign session sync is updated. */ - interface ForeignSessionCallback { + public interface ForeignSessionCallback { /** * This method will be called every time foreign session sync is updated. * @@ -38,7 +38,7 @@ /** * Represents synced foreign session. */ - static class ForeignSession { + public static class ForeignSession { public final String tag; public final String name; public final long modifiedTime; @@ -55,7 +55,7 @@ * Represents synced foreign window. Note that desktop Chrome can have multiple windows in a * session. */ - static class ForeignSessionWindow { + public static class ForeignSessionWindow { public final long timestamp; public final int sessionId; public final List<ForeignSessionTab> tabs = new ArrayList<ForeignSessionTab>(); @@ -69,7 +69,7 @@ /** * Represents synced foreign tab. */ - static class ForeignSessionTab { + public static class ForeignSessionTab { public final GURL url; public final String title; public final long timestamp; @@ -126,14 +126,14 @@ /** * @return {@code True} iff Tab sync is enabled. */ - boolean isTabSyncEnabled() { + public boolean isTabSyncEnabled() { return ForeignSessionHelperJni.get().isTabSyncEnabled(mNativeForeignSessionHelper); } /** * Force a sync for sessions. */ - void triggerSessionSync() { + public void triggerSessionSync() { ForeignSessionHelperJni.get().triggerSessionSync(mNativeForeignSessionHelper); } @@ -141,7 +141,7 @@ * Sets callback instance that will be called on every foreign session sync update. * @param callback The callback to be invoked. */ - void setOnForeignSessionCallback(ForeignSessionCallback callback) { + public void setOnForeignSessionCallback(ForeignSessionCallback callback) { ForeignSessionHelperJni.get().setOnForeignSessionCallback( mNativeForeignSessionHelper, callback); } @@ -150,7 +150,7 @@ * @return The list of synced foreign sessions. If it fails to get them for some reason will * return an empty list. */ - List<ForeignSession> getForeignSessions() { + public List<ForeignSession> getForeignSessions() { if (!isTabSyncEnabled()) { return Collections.emptyList(); } @@ -172,7 +172,7 @@ * @param windowOpenDisposition The WindowOpenDisposition flag. * @return {@code True} iff the tab is successfully opened. */ - boolean openForeignSessionTab(Tab tab, ForeignSession session, + public boolean openForeignSessionTab(Tab tab, ForeignSession session, ForeignSessionTab foreignTab, int windowOpenDisposition) { return ForeignSessionHelperJni.get().openForeignSessionTab(mNativeForeignSessionHelper, tab, session.tag, foreignTab.id, windowOpenDisposition); @@ -185,7 +185,7 @@ * the future. * @param session Session to be deleted. */ - void deleteForeignSession(ForeignSession session) { + public void deleteForeignSession(ForeignSession session) { ForeignSessionHelperJni.get().deleteForeignSession( mNativeForeignSessionHelper, session.tag); }
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn index dbe1250..897c611 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -443,6 +443,7 @@ "background/logging/log_store_test.js", "background/output/output_test.js", "background/panel/i_search_test.js", + "background/panel/panel_background_test.js", "background/panel/panel_node_menu_background_test.js", "background/portals_test.js", "background/settings_test.js",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_background.js index 301db52..290c6fa 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_background.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_background.js
@@ -40,6 +40,10 @@ this.savedNode_; /** @private {Promise} */ this.resolvePanelCollapsed_; + /** @private {function()|undefined} */ + this.tutorialReadyCallback_; + /** @private {boolean} */ + this.tutorialReadyForTesting_ = false; } static init() { @@ -79,6 +83,9 @@ PanelBackground.instance.incrementalSearch_( searchStr, dir, opt_nextObject)); BridgeHelper.registerHandler( + TARGET, Action.ON_TUTORIAL_READY, + () => PanelBackground.instance.onTutorialReady_()); + BridgeHelper.registerHandler( TARGET, Action.PERFORM_CUSTOM_ACTION_ON_CURRENT_NODE, actionId => PanelBackground.instance.performCustomActionOnCurrentNode_( actionId)); @@ -181,14 +188,21 @@ */ incrementalSearch_(searchStr, dir, opt_nextObject) { if (!this.iSearch_) { - console.error( - 'Trying to incrementally search when no ISearch has been created'); + console.error('Trying to search when no ISearch has been created'); return; } this.iSearch_.search(searchStr, dir, opt_nextObject); } + /** @private */ + onTutorialReady_() { + this.tutorialReadyForTesting_ = true; + if (this.tutorialReadyCallback_) { + this.tutorialReadyCallback_(); + } + } + /** * @param {number} actionId * @private
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_background_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_background_test.js new file mode 100644 index 0000000..9e6ad98d --- /dev/null +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_background_test.js
@@ -0,0 +1,32 @@ +// 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 test fixture. +GEN_INCLUDE(['../../testing/chromevox_e2e_test_base.js']); + +/** + * Test fixture for PanelBackground. + */ +ChromeVoxPanelBackgroundTest = class extends ChromeVoxE2ETest { + /** @override */ + async setUpDeferred() { + await super.setUpDeferred(); + + // Alphabetical based on file path. + await importModule( + 'PanelBackground', '/chromevox/background/panel/panel_background.js'); + } +}; + +AX_TEST_F('ChromeVoxPanelBackgroundTest', 'OnTutorialReady', async function() { + const callbackPromise = new Promise( + resolve => PanelBackground.instance.tutorialReadyCallback_ = resolve); + + assertFalse(PanelBackground.instance.tutorialReadyForTesting_); + + PanelBackground.instance.onTutorialReady_(); + await callbackPromise; + + assertTrue(PanelBackground.instance.tutorialReadyForTesting_); +});
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 af562d6..2315ad29 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/background_bridge.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/background_bridge.js
@@ -299,6 +299,13 @@ dir, opt_nextObject); }, + /** @return {!Promise} */ + async onTutorialReady() { + return BridgeHelper.sendMessage( + BridgeConstants.PanelBackground.TARGET, + BridgeConstants.PanelBackground.Action.ON_TUTORIAL_READY); + }, + /** * @param {number} actionId * @return {!Promise}
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 7429c3d5..e435317 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/bridge_constants.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/bridge_constants.js
@@ -156,6 +156,7 @@ GET_TAB_MENU_DATA: 'getTabMenuData', INCREMENTAL_SEARCH: 'incrementalSearch', NODE_MENU_CALLBACK: 'nodeMenuCallback', + ON_TUTORIAL_READY: 'onTutorialReady', PERFORM_CUSTOM_ACTION_ON_CURRENT_NODE: 'performCustomActionOnCurrentNode', PERFORM_STANDARD_ACTION_ON_CURRENT_NODE: 'performStandardActionOnCurrentNode',
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/command_store.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/command_store.js index 8dcdfe4..5e06193 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/command_store.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/command_store.js
@@ -311,180 +311,180 @@ */ CommandStore.COMMAND_DATA = { [Command.TOGGLE_STICKY_MODE]: { - msgId: 'toggle_sticky_mode', category: CommandCategory.MODIFIER_KEYS, + msgId: 'toggle_sticky_mode', }, [Command.PASS_THROUGH_MODE]: { - msgId: 'pass_through_key_description', category: CommandCategory.MODIFIER_KEYS, + msgId: 'pass_through_key_description', }, [Command.STOP_SPEECH]: { - msgId: 'stop_speech_key', category: CommandCategory.CONTROLLING_SPEECH, + msgId: 'stop_speech_key', }, [Command.OPEN_CHROMEVOX_MENUS]: { - msgId: 'menus_title', category: CommandCategory.NO_CATEGORY, + msgId: 'menus_title', }, [Command.RESET_TEXT_TO_SPEECH_SETTINGS]: { - msgId: 'reset_tts_settings', category: CommandCategory.CONTROLLING_SPEECH, + msgId: 'reset_tts_settings', }, [Command.DECREASE_TTS_RATE]: { - msgId: 'decrease_tts_rate', category: CommandCategory.CONTROLLING_SPEECH, + msgId: 'decrease_tts_rate', }, [Command.INCREASE_TTS_RATE]: { - msgId: 'increase_tts_rate', category: CommandCategory.CONTROLLING_SPEECH, + msgId: 'increase_tts_rate', }, [Command.DECREASE_TTS_PITCH]: { - msgId: 'decrease_tts_pitch', category: CommandCategory.CONTROLLING_SPEECH, + msgId: 'decrease_tts_pitch', }, [Command.INCREASE_TTS_PITCH]: { - msgId: 'increase_tts_pitch', category: CommandCategory.CONTROLLING_SPEECH, + msgId: 'increase_tts_pitch', }, [Command.DECREASE_TTS_VOLUME]: { - msgId: 'decrease_tts_volume', category: CommandCategory.CONTROLLING_SPEECH, + msgId: 'decrease_tts_volume', }, [Command.INCREASE_TTS_VOLUME]: { - msgId: 'increase_tts_volume', category: CommandCategory.CONTROLLING_SPEECH, + msgId: 'increase_tts_volume', }, [Command.CYCLE_PUNCTUATION_ECHO]: { - msgId: 'cycle_punctuation_echo', category: CommandCategory.CONTROLLING_SPEECH, + msgId: 'cycle_punctuation_echo', }, [Command.CYCLE_TYPING_ECHO]: { - msgId: 'cycle_typing_echo', category: CommandCategory.CONTROLLING_SPEECH, + msgId: 'cycle_typing_echo', }, [Command.TOGGLE_DICTATION]: { - msgId: 'toggle_dictation', category: CommandCategory.ACTIONS, + msgId: 'toggle_dictation', }, [Command.TOGGLE_EARCONS]: { - msgId: 'toggle_earcons', category: CommandCategory.CONTROLLING_SPEECH, + msgId: 'toggle_earcons', }, [Command.TOGGLE_SPEECH_ON_OR_OFF]: { - msgId: 'speech_on_off_description', category: CommandCategory.CONTROLLING_SPEECH, + msgId: 'speech_on_off_description', }, [Command.HANDLE_TAB]: { - msgId: 'handle_tab_next', category: CommandCategory.NAVIGATION, + msgId: 'handle_tab_next', }, [Command.HANDLE_TAB_PREV]: { - msgId: 'handle_tab_prev', category: CommandCategory.NAVIGATION, + msgId: 'handle_tab_prev', }, [Command.FORWARD]: { - msgId: 'forward', category: CommandCategory.NAVIGATION, + msgId: 'forward', }, [Command.BACKWARD]: { - msgId: 'backward', category: CommandCategory.NAVIGATION, + msgId: 'backward', }, [Command.RIGHT]: { - msgId: 'right', category: CommandCategory.NAVIGATION, + msgId: 'right', }, [Command.LEFT]: { - msgId: 'left', category: CommandCategory.NAVIGATION, + msgId: 'left', }, [Command.PREVIOUS_GRANULARITY]: { - msgId: 'previous_granularity', category: CommandCategory.NAVIGATION, + msgId: 'previous_granularity', }, [Command.NEXT_GRANULARITY]: { - msgId: 'next_granularity', category: CommandCategory.NAVIGATION, + msgId: 'next_granularity', }, [Command.PREVIOUS_AT_GRANULARITY]: { - msgId: 'previous_at_granularity', category: CommandCategory.NAVIGATION, + msgId: 'previous_at_granularity', }, [Command.NEXT_AT_GRANULARITY]: { - msgId: 'next_at_granularity', category: CommandCategory.NAVIGATION, + msgId: 'next_at_granularity', }, [Command.PREVIOUS_CHARACTER]: { - msgId: 'previous_character', category: CommandCategory.NAVIGATION, + msgId: 'previous_character', }, [Command.NEXT_CHARACTER]: { - msgId: 'next_character', category: CommandCategory.NAVIGATION, + msgId: 'next_character', }, [Command.PREVIOUS_WORD]: { - msgId: 'previous_word', category: CommandCategory.NAVIGATION, + msgId: 'previous_word', }, [Command.NEXT_WORD]: { - msgId: 'next_word', category: CommandCategory.NAVIGATION, + msgId: 'next_word', }, [Command.PREVIOUS_LINE]: { - msgId: 'previous_line', category: CommandCategory.NAVIGATION, + msgId: 'previous_line', }, [Command.NEXT_LINE]: { - msgId: 'next_line', category: CommandCategory.NAVIGATION, + msgId: 'next_line', }, [Command.PREVIOUS_SENTENCE]: { - msgId: 'previous_sentence', category: CommandCategory.NAVIGATION, + msgId: 'previous_sentence', }, [Command.NEXT_SENTENCE]: { - msgId: 'next_sentence', category: CommandCategory.NAVIGATION, + msgId: 'next_sentence', }, [Command.PREVIOUS_OBJECT]: { - msgId: 'previous_object', category: CommandCategory.NAVIGATION, + msgId: 'previous_object', }, [Command.NEXT_OBJECT]: { - msgId: 'next_object', category: CommandCategory.NAVIGATION, + msgId: 'next_object', }, [Command.PREVIOUS_GROUP]: { - msgId: 'previous_group', category: CommandCategory.NAVIGATION, + msgId: 'previous_group', }, [Command.NEXT_GROUP]: { - msgId: 'next_group', category: CommandCategory.NAVIGATION, + msgId: 'next_group', }, [Command.PREVIOUS_SIMILAR_ITEM]: { - msgId: 'previous_similar_item', category: CommandCategory.NAVIGATION, + msgId: 'previous_similar_item', }, [Command.NEXT_SIMILAR_ITEM]: { - msgId: 'next_similar_item', category: CommandCategory.NAVIGATION, + msgId: 'next_similar_item', }, [Command.PREVIOUS_INVALID_ITEM]: { - msgId: 'previous_invalid_item', category: CommandCategory.NAVIGATION, + msgId: 'previous_invalid_item', }, [Command.NEXT_INVALID_ITEM]: { - msgId: 'next_invalid_item', category: CommandCategory.NAVIGATION, + msgId: 'next_invalid_item', }, [Command.JUMP_TO_TOP]: { - msgId: 'jump_to_top', category: CommandCategory.NAVIGATION, + msgId: 'jump_to_top', }, [Command.JUMP_TO_BOTTOM]: { - msgId: 'jump_to_bottom', category: CommandCategory.NAVIGATION, + msgId: 'jump_to_bottom', }, // Intentionally uncategorized. @@ -492,384 +492,389 @@ [Command.MOVE_TO_END_OF_LINE]: {category: CommandCategory.NO_CATEGORY}, [Command.JUMP_TO_DETAILS]: { - msgId: 'jump_to_details', category: CommandCategory.NAVIGATION, + msgId: 'jump_to_details', }, [Command.READ_FROM_HERE]: { - msgId: 'read_from_here', category: CommandCategory.NAVIGATION, + msgId: 'read_from_here', }, [Command.FORCE_CLICK_ON_CURRENT_ITEM]: { - msgId: 'force_click_on_current_item', category: CommandCategory.ACTIONS, + msgId: 'force_click_on_current_item', }, [Command.FORCE_LONG_CLICK_ON_CURRENT_ITEM]: { + category: CommandCategory.NO_CATEGORY, msgId: 'force_long_click_on_current_item', }, [Command.FORCE_DOUBLE_CLICK_ON_CURRENT_ITEM]: {category: CommandCategory.NO_CATEGORY}, [Command.READ_LINK_URL]: { - msgId: 'read_link_url', category: CommandCategory.INFORMATION, + msgId: 'read_link_url', }, [Command.READ_CURRENT_TITLE]: { - msgId: 'read_current_title', category: CommandCategory.INFORMATION, + msgId: 'read_current_title', }, [Command.READ_CURRENT_URL]: { - msgId: 'read_current_url', category: CommandCategory.INFORMATION, + msgId: 'read_current_url', }, [Command.FULLY_DESCRIBE]: { - msgId: 'fully_describe', category: CommandCategory.INFORMATION, + msgId: 'fully_describe', }, [Command.SPEAK_TIME_AND_DATE]: { - msgId: 'speak_time_and_date', category: CommandCategory.INFORMATION, + msgId: 'speak_time_and_date', }, [Command.TOGGLE_SELECTION]: { - msgId: 'toggle_selection', category: CommandCategory.ACTIONS, + msgId: 'toggle_selection', }, [Command.TOGGLE_SEARCH_WIDGET]: { - msgId: 'toggle_search_widget', category: CommandCategory.INFORMATION, + msgId: 'toggle_search_widget', }, [Command.TOGGLE_SCREEN]: { - msgId: 'toggle_screen', category: CommandCategory.MODIFIER_KEYS, + msgId: 'toggle_screen', }, - [Command.TOGGLE_BRAILLE_TABLE]: - {msgId: 'toggle_braille_table', category: CommandCategory.HELP_COMMANDS}, - [Command.TOGGLE_KEYBOARD_HELP]: { - msgId: 'show_panel_menu', + [Command.TOGGLE_BRAILLE_TABLE]: { category: CommandCategory.HELP_COMMANDS, + msgId: 'toggle_braille_table', + }, + [Command.TOGGLE_KEYBOARD_HELP]: { + category: CommandCategory.HELP_COMMANDS, + msgId: 'show_panel_menu', }, [Command.SHOW_PANEL_MENU_MOST_RECENT]: { - msgId: 'show_panel_menu', category: CommandCategory.HELP_COMMANDS, + msgId: 'show_panel_menu', }, [Command.HELP]: { - msgId: 'help', category: CommandCategory.HELP_COMMANDS, + msgId: 'help', }, [Command.CONTEXT_MENU]: { - msgId: 'show_context_menu', category: CommandCategory.INFORMATION, + msgId: 'show_context_menu', }, [Command.SHOW_OPTIONS_PAGE]: { - msgId: 'show_options_page', - denySignedOut: true, category: CommandCategory.HELP_COMMANDS, + denySignedOut: true, + msgId: 'show_options_page', }, [Command.SHOW_LOG_PAGE]: { - msgId: 'show_log_page', - denySignedOut: true, category: CommandCategory.HELP_COMMANDS, + denySignedOut: true, + msgId: 'show_log_page', }, [Command.SHOW_LEARN_MODE_PAGE]: { - msgId: 'show_kb_explorer_page', - denySignedOut: true, category: CommandCategory.HELP_COMMANDS, + denySignedOut: true, + msgId: 'show_kb_explorer_page', }, [Command.SHOW_TTS_SETTINGS]: { - msgId: 'show_tts_settings', category: CommandCategory.HELP_COMMANDS, denySignedOut: true, + msgId: 'show_tts_settings', }, [Command.TOGGLE_BRAILLE_CAPTIONS]: { - msgId: 'braille_captions', category: CommandCategory.HELP_COMMANDS, + msgId: 'braille_captions', }, [Command.REPORT_ISSUE]: { + category: CommandCategory.HELP_COMMANDS, denySignedOut: true, msgId: 'panel_menu_item_report_issue', - category: CommandCategory.HELP_COMMANDS, }, [Command.SHOW_FORMS_LIST]: { - msgId: 'show_forms_list', category: CommandCategory.OVERVIEW, + msgId: 'show_forms_list', }, [Command.SHOW_HEADINGS_LIST]: { - msgId: 'show_headings_list', category: CommandCategory.OVERVIEW, + msgId: 'show_headings_list', }, [Command.SHOW_LANDMARKS_LIST]: { - msgId: 'show_landmarks_list', category: CommandCategory.OVERVIEW, + msgId: 'show_landmarks_list', }, [Command.SHOW_LINKS_LIST]: { - msgId: 'show_links_list', category: CommandCategory.OVERVIEW, + msgId: 'show_links_list', }, [Command.SHOW_TABLES_LIST]: { - msgId: 'show_tables_list', category: CommandCategory.OVERVIEW, + msgId: 'show_tables_list', }, [Command.NEXT_ARTICLE]: {category: CommandCategory.NO_CATEGORY}, [Command.NEXT_BUTTON]: { - msgId: 'next_button', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_button', }, [Command.NEXT_CHECKBOX]: { - msgId: 'next_checkbox', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_checkbox', }, [Command.NEXT_COMBO_BOX]: { - msgId: 'next_combo_box', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_combo_box', }, [Command.NEXT_CONTROL]: {category: CommandCategory.NO_CATEGORY}, [Command.NEXT_EDIT_TEXT]: { - msgId: 'next_edit_text', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_edit_text', }, [Command.NEXT_FORM_FIELD]: { - msgId: 'next_form_field', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_form_field', }, [Command.NEXT_GRAPHIC]: { - msgId: 'next_graphic', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_graphic', }, [Command.NEXT_HEADING]: { - msgId: 'next_heading', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_heading', }, [Command.NEXT_HEADING_1]: { - msgId: 'next_heading1', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_heading1', }, [Command.NEXT_HEADING_2]: { - msgId: 'next_heading2', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_heading2', }, [Command.NEXT_HEADING_3]: { - msgId: 'next_heading3', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_heading3', }, [Command.NEXT_HEADING_4]: { - msgId: 'next_heading4', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_heading4', }, [Command.NEXT_HEADING_5]: { - msgId: 'next_heading5', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_heading5', }, [Command.NEXT_HEADING_6]: { - msgId: 'next_heading6', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_heading6', }, [Command.NEXT_LANDMARK]: { - msgId: 'next_landmark', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_landmark', }, [Command.NEXT_LINK]: { - msgId: 'next_link', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_link', }, [Command.NEXT_LIST]: { - msgId: 'next_list', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_list', }, [Command.NEXT_LIST_ITEM]: { - msgId: 'next_list_item', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_list_item', }, [Command.NEXT_MATH]: { - msgId: 'next_math', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_math', }, [Command.NEXT_MEDIA]: { - msgId: 'next_media', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_media', }, [Command.NEXT_RADIO]: { - msgId: 'next_radio', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_radio', }, [Command.NEXT_SECTION]: {category: CommandCategory.NO_CATEGORY}, [Command.NEXT_SLIDER]: {category: CommandCategory.NO_CATEGORY}, [Command.NEXT_TABLE]: { - msgId: 'next_table', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_table', }, [Command.NEXT_VISITED_LINK]: { - msgId: 'next_visited_link', category: CommandCategory.JUMP_COMMANDS, + msgId: 'next_visited_link', }, [Command.PREVIOUS_ARTICLE]: {category: CommandCategory.NO_CATEGORY}, [Command.PREVIOUS_BUTTON]: { - msgId: 'previous_button', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_button', }, [Command.PREVIOUS_CHECKBOX]: { - msgId: 'previous_checkbox', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_checkbox', }, [Command.PREVIOUS_COMBO_BOX]: { - msgId: 'previous_combo_box', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_combo_box', }, [Command.PREVIOUS_CONTROL]: {category: CommandCategory.NO_CATEGORY}, [Command.PREVIOUS_EDIT_TEXT]: { - msgId: 'previous_edit_text', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_edit_text', }, [Command.PREVIOUS_FORM_FIELD]: { - msgId: 'previous_form_field', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_form_field', }, [Command.PREVIOUS_GRAPHIC]: { - msgId: 'previous_graphic', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_graphic', }, [Command.PREVIOUS_HEADING]: { - msgId: 'previous_heading', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_heading', }, [Command.PREVIOUS_HEADING_1]: { - msgId: 'previous_heading1', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_heading1', }, [Command.PREVIOUS_HEADING_2]: { - msgId: 'previous_heading2', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_heading2', }, [Command.PREVIOUS_HEADING_3]: { - msgId: 'previous_heading3', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_heading3', }, [Command.PREVIOUS_HEADING_4]: { - msgId: 'previous_heading4', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_heading4', }, [Command.PREVIOUS_HEADING_5]: { - msgId: 'previous_heading5', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_heading5', }, [Command.PREVIOUS_HEADING_6]: { - msgId: 'previous_heading6', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_heading6', }, [Command.PREVIOUS_LANDMARK]: { - msgId: 'previous_landmark', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_landmark', }, [Command.PREVIOUS_LINK]: { - msgId: 'previous_link', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_link', }, [Command.PREVIOUS_LIST]: { - msgId: 'previous_list', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_list', }, [Command.PREVIOUS_LIST_ITEM]: { - msgId: 'previous_list_item', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_list_item', }, [Command.PREVIOUS_MATH]: { - msgId: 'previous_math', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_math', }, [Command.PREVIOUS_MEDIA]: { - msgId: 'previous_media', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_media', }, [Command.PREVIOUS_RADIO]: { - msgId: 'previous_radio', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_radio', }, [Command.PREVIOUS_SECTION]: {category: CommandCategory.NO_CATEGORY}, [Command.PREVIOUS_SLIDER]: {category: CommandCategory.NO_CATEGORY}, [Command.PREVIOUS_TABLE]: { - msgId: 'previous_table', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_table', }, [Command.PREVIOUS_VISITED_LINK]: { - msgId: 'previous_visited_link', category: CommandCategory.JUMP_COMMANDS, + msgId: 'previous_visited_link', }, // Table Actions. [Command.ANNOUNCE_HEADERS]: { - msgId: 'announce_headers', category: CommandCategory.TABLES, + msgId: 'announce_headers', }, [Command.SPEAK_TABLE_LOCATION]: { - msgId: 'speak_table_location', category: CommandCategory.TABLES, + msgId: 'speak_table_location', }, [Command.GO_TO_FIRST_CELL]: { + category: CommandCategory.TABLES, msgId: 'skip_to_beginning', - category: CommandCategory.TABLES, }, - [Command.GO_TO_LAST_CELL]: - {msgId: 'skip_to_end', category: CommandCategory.TABLES}, - [Command.GO_TO_ROW_FIRST_CELL]: { - msgId: 'skip_to_row_beginning', + [Command.GO_TO_LAST_CELL]: { category: CommandCategory.TABLES, + msgId: 'skip_to_end', + }, + [Command.GO_TO_ROW_FIRST_CELL]: { + category: CommandCategory.TABLES, + msgId: 'skip_to_row_beginning', }, [Command.GO_TO_ROW_LAST_CELL]: { - msgId: 'skip_to_row_end', category: CommandCategory.TABLES, + msgId: 'skip_to_row_end', }, [Command.GO_TO_COL_FIRST_CELL]: { - msgId: 'skip_to_col_beginning', category: CommandCategory.TABLES, + msgId: 'skip_to_col_beginning', }, [Command.GO_TO_COL_LAST_CELL]: { - msgId: 'skip_to_col_end', category: CommandCategory.TABLES, + msgId: 'skip_to_col_end', }, [Command.PREVIOUS_ROW]: { - msgId: 'skip_to_prev_row', category: CommandCategory.TABLES, + msgId: 'skip_to_prev_row', }, [Command.PREVIOUS_COL]: { - msgId: 'skip_to_prev_col', category: CommandCategory.TABLES, + msgId: 'skip_to_prev_col', }, [Command.NEXT_ROW]: { - msgId: 'skip_to_next_row', category: CommandCategory.TABLES, + msgId: 'skip_to_next_row', }, [Command.NEXT_COL]: { - msgId: 'skip_to_next_col', category: CommandCategory.TABLES, + msgId: 'skip_to_next_col', }, // Generic Actions. [Command.ENTER_SHIFTER]: { - msgId: 'enter_content', category: CommandCategory.NAVIGATION, + msgId: 'enter_content', }, [Command.EXIT_SHIFTER]: { - msgId: 'exit_content', category: CommandCategory.NAVIGATION, + msgId: 'exit_content', }, [Command.EXIT_SHIFTER_CONTENT]: {category: CommandCategory.NO_CATEGORY}, [Command.OPEN_LONG_DESC]: { - msgId: 'open_long_desc', category: CommandCategory.INFORMATION, + msgId: 'open_long_desc', }, [Command.PAUSE_ALL_MEDIA]: { - msgId: 'pause_all_media', category: CommandCategory.INFORMATION, + msgId: 'pause_all_media', }, [Command.ANNOUNCE_BATTERY_DESCRIPTION]: { - msgId: 'announce_battery_description', category: CommandCategory.INFORMATION, + msgId: 'announce_battery_description', }, [Command.ANNOUNCE_RICH_TEXT_DESCRIPTION]: { - msgId: 'announce_rich_text_description', category: CommandCategory.INFORMATION, + msgId: 'announce_rich_text_description', }, [Command.READ_PHONETIC_PRONUNCIATION]: { - msgId: 'read_phonetic_pronunciation', category: CommandCategory.INFORMATION, + msgId: 'read_phonetic_pronunciation', }, // Scrolling actions. @@ -884,48 +889,48 @@ // Math specific commands. [Command.TOGGLE_SEMANTICS]: { - msgId: 'toggle_semantics', category: CommandCategory.INFORMATION, + msgId: 'toggle_semantics', }, // Braille specific commands. [Command.ROUTING]: { - msgId: 'braille_routing', category: CommandCategory.BRAILLE, + msgId: 'braille_routing', }, [Command.PAN_LEFT]: { - msgId: 'braille_pan_left', category: CommandCategory.BRAILLE, + msgId: 'braille_pan_left', }, [Command.PAN_RIGHT]: { - msgId: 'braille_pan_right', category: CommandCategory.BRAILLE, + msgId: 'braille_pan_right', }, [Command.LINE_UP]: { - msgId: 'braille_line_up', category: CommandCategory.BRAILLE, + msgId: 'braille_line_up', }, [Command.LINE_DOWN]: { - msgId: 'braille_line_down', category: CommandCategory.BRAILLE, + msgId: 'braille_line_down', }, [Command.TOP]: { - msgId: 'braille_top', category: CommandCategory.BRAILLE, + msgId: 'braille_top', }, [Command.BOTTOM]: { - msgId: 'braille_bottom', category: CommandCategory.BRAILLE, + msgId: 'braille_bottom', }, [Command.VIEW_GRAPHIC_AS_BRAILLE]: { - msgId: 'view_graphic_as_braille', category: CommandCategory.BRAILLE, + msgId: 'view_graphic_as_braille', }, // Developer commands. [Command.ENABLE_CONSOLE_TTS]: { - msgId: 'enable_tts_log', category: CommandCategory.DEVELOPER, + msgId: 'enable_tts_log', }, [Command.START_HISTORY_RECORDING]: {category: CommandCategory.NO_CATEGORY}, [Command.STOP_HISTORY_RECORDING]: {category: CommandCategory.NO_CATEGORY},
diff --git a/chrome/browser/resources/chromeos/login/test_api/test_api.js b/chrome/browser/resources/chromeos/login/test_api/test_api.js index 7d0e218..959056d8 100644 --- a/chrome/browser/resources/chromeos/login/test_api/test_api.js +++ b/chrome/browser/resources/chromeos/login/test_api/test_api.js
@@ -690,19 +690,6 @@ } } -class ArcTosScreenTester extends ScreenElementApi { - constructor() { - super('arc-tos'); - } - - // Note that the Accept Button text key is different depending on whether - // the device in Demo Mode setup. Key for non-demo setup is - // "arcTermsOfServiceAcceptButton" - getArcTosDemoModeAcceptButtonName() { - return loadTimeData.getString('arcTermsOfServiceAcceptAndContinueButton'); - } -} - class GuestTosScreenTester extends ScreenElementApi { constructor() { super('guest-tos'); @@ -924,7 +911,6 @@ ErrorScreen: new ErrorScreenTester(), OfflineLoginScreen: new OfflineLoginScreenTester(), DemoPreferencesScreen: new DemoPreferencesScreenTester(), - ArcTosScreen: new ArcTosScreenTester(), ThemeSelectionScreen: new ThemeSelectionScreenTester(), GestureNavigation: new GestureNavigationScreenTester(), ConsolidatedConsentScreen: new ConsolidatedConsentScreenTester(),
diff --git a/chrome/browser/resources/chromeos/manage_mirrorsync/BUILD.gn b/chrome/browser/resources/chromeos/manage_mirrorsync/BUILD.gn index 89d9fc8..5552bd8 100644 --- a/chrome/browser/resources/chromeos/manage_mirrorsync/BUILD.gn +++ b/chrome/browser/resources/chromeos/manage_mirrorsync/BUILD.gn
@@ -56,7 +56,10 @@ ] composite = true enable_source_maps = true - deps = [ "//ui/webui/resources/mojo:build_ts" ] + deps = [ + "//third_party/polymer/v3_0:library", + "//ui/webui/resources/mojo:build_ts", + ] } resources_grd_file = "$target_gen_dir/resources.grd"
diff --git a/chrome/browser/resources/internals/user_education/BUILD.gn b/chrome/browser/resources/internals/user_education/BUILD.gn index 4e0debc5..dbdbde7a 100644 --- a/chrome/browser/resources/internals/user_education/BUILD.gn +++ b/chrome/browser/resources/internals/user_education/BUILD.gn
@@ -20,6 +20,7 @@ mojo_files = [ "$root_gen_dir/chrome/browser/ui/webui/internals/user_education/user_education_internals.mojom-webui.ts" ] ts_deps = [ + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_components/help_bubble:build_ts", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts",
diff --git a/chrome/browser/resources/media_router/cast_feedback/BUILD.gn b/chrome/browser/resources/media_router/cast_feedback/BUILD.gn index 077ae21..ad6b5e8 100644 --- a/chrome/browser/resources/media_router/cast_feedback/BUILD.gn +++ b/chrome/browser/resources/media_router/cast_feedback/BUILD.gn
@@ -14,6 +14,7 @@ ts_composite = true ts_deps = [ + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", ]
diff --git a/chrome/browser/resources/new_tab_page/app.html b/chrome/browser/resources/new_tab_page/app.html index 9b79cc6..832a587d 100644 --- a/chrome/browser/resources/new_tab_page/app.html +++ b/chrome/browser/resources/new_tab_page/app.html
@@ -26,7 +26,8 @@ } } - @media (min-width: 768px) { + /*A module width of 768px with 18px gaps on each side. */ + @media (min-width: 804px) { :host([wide-modules-enabled_]) { --ntp-module-layout-width: 768px; --ntp-module-width: 768px;
diff --git a/chrome/browser/resources/new_tab_page/modules/history_clusters/module.html b/chrome/browser/resources/new_tab_page/modules/history_clusters/module.html index 6f10100e..716c209 100644 --- a/chrome/browser/resources/new_tab_page/modules/history_clusters/module.html +++ b/chrome/browser/resources/new_tab_page/modules/history_clusters/module.html
@@ -46,7 +46,9 @@ grid-row: 2 / 3; } - @media (max-width: 879px) { + /* At less than 768px + 2*18px side gaps, switch to the one column + presentation. */ + @media (max-width: 803px) { .small-tiles, .secondary-tile, .related-searches-tile {
diff --git a/chrome/browser/resources/new_tab_page/modules/history_clusters/page_favicon.html b/chrome/browser/resources/new_tab_page/modules/history_clusters/page_favicon.html index bb7502fa..11e2b9bd 100644 --- a/chrome/browser/resources/new_tab_page/modules/history_clusters/page_favicon.html +++ b/chrome/browser/resources/new_tab_page/modules/history_clusters/page_favicon.html
@@ -11,4 +11,10 @@ margin-inline: 0 12px; width: 36px; } + + @media (forced-colors: active) { + :host { + forced-color-adjust: none; + } + } </style>
diff --git a/chrome/browser/resources/new_tab_page/modules/history_clusters/suggest_tile.html b/chrome/browser/resources/new_tab_page/modules/history_clusters/suggest_tile.html index 64778966..dd02bac 100644 --- a/chrome/browser/resources/new_tab_page/modules/history_clusters/suggest_tile.html +++ b/chrome/browser/resources/new_tab_page/modules/history_clusters/suggest_tile.html
@@ -55,6 +55,24 @@ font-size: var(--ntp-module-text-size); margin: auto 0; } + + /* Set styles for high contrast mode in Windows. */ + @media (forced-colors: active) { + /* Set focus outline since box-shadow isn't visible in hcm */ + :host-context(.focus-outline-visible) a:focus { + outline: var(--cr-focus-outline-hcm); + } + + /* Set outline since background isn't visible in hcm. */ + a { + outline: var(--cr-border-hcm); + } + + /* Set magnifying class color for hcm. Otherwise, it isn't visible. */ + .icon { + background-color: LinkText; + } + } </style> <div id="content"> <template is="dom-repeat" items="[[relatedSearches]]"
diff --git a/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html b/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html index f25890a0..adec8d62 100644 --- a/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html +++ b/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html
@@ -145,6 +145,20 @@ #dot { line-height: 16px; } + + /* Set styles for high contrast mode in Windows. */ + @media (forced-colors: active) { + /* Set focus outline since box-shadow isn't visible in hcm */ + :host-context(.focus-outline-visible) a:focus { + outline: var(--cr-focus-outline-hcm); + } + + /* Set outline since background isn't visible in hcm */ + a { + border-radius: 12px; + outline: var(--cr-border-hcm); + } + } </style> <a id="content" href="[[visit.normalizedUrl.url]]" aria-label$="[[visit.pageTitle]], [[label_]], [[visit.relativeDate]]">
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.html b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.html index aa29081e..762fd84 100644 --- a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.html +++ b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.html
@@ -18,6 +18,10 @@ --cr-icon-button-margin-end: 0; } + :host-context(body.jelly-enabled) #addManualPrinterIcon { + --cr-icon-button-fill-color: var(--cros-sys-primary); + } + #cloudOffIcon { --iron-icon-fill-color: var(--cros-icon-color-secondary); margin-top: 10px;
diff --git a/chrome/browser/resources/settings/privacy_page/anti_abuse_page.html b/chrome/browser/resources/settings/privacy_page/anti_abuse_page.html index 5d42709..a1a8613 100644 --- a/chrome/browser/resources/settings/privacy_page/anti_abuse_page.html +++ b/chrome/browser/resources/settings/privacy_page/anti_abuse_page.html
@@ -30,10 +30,12 @@ } </style> <settings-toggle-button + id="toggleButton" pref="{{pref_}}" no-set-pref label="$i18n{siteSettingsAntiAbuse}" sub-label="$i18n{siteSettingsAntiAbuseDescription}" + disabled="[[toggleDisabled_]]" on-settings-boolean-control-change="onToggleChange_"> </settings-toggle-button> <div class="info-container">
diff --git a/chrome/browser/resources/settings/privacy_page/anti_abuse_page.ts b/chrome/browser/resources/settings/privacy_page/anti_abuse_page.ts index 24fa032..c681e7e 100644 --- a/chrome/browser/resources/settings/privacy_page/anti_abuse_page.ts +++ b/chrome/browser/resources/settings/privacy_page/anti_abuse_page.ts
@@ -14,15 +14,24 @@ import '../icons.html.js'; import '../settings_shared.css.js'; +import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {SettingsToggleButtonElement} from '../controls/settings_toggle_button.js'; import {ContentSetting, ContentSettingsTypes} from '../site_settings/constants.js'; import {SiteSettingsMixin} from '../site_settings/site_settings_mixin.js'; +import {ContentSettingProvider} from '../site_settings/site_settings_prefs_browser_proxy.js'; import {getTemplate} from './anti_abuse_page.html.js'; -const AntiAbuseElementBase = SiteSettingsMixin(PolymerElement); +export interface SettingsAntiAbusePageElement { + $: { + toggleButton: SettingsToggleButtonElement, + }; +} + +const AntiAbuseElementBase = + SiteSettingsMixin(WebUiListenerMixin(PolymerElement)); export class SettingsAntiAbusePageElement extends AntiAbuseElementBase { static get is() { @@ -45,20 +54,70 @@ return {type: chrome.settingsPrivate.PrefType.BOOLEAN}; }, }, + + toggleDisabled_: Boolean, }; } + static get observers() { + return [ + 'onEnforcementChanged_(pref_.enforcement)', + ]; + } + private pref_: chrome.settingsPrivate.PrefObject<boolean>; + private toggleDisabled_: boolean; override ready() { super.ready(); - this.initializeToggleValue_(); + this.addWebUiListener( + 'contentSettingCategoryChanged', + (category: ContentSettingsTypes) => this.onCategoryChanged_(category)); + + this.updateToggleValue_(); } - private async initializeToggleValue_() { + private onCategoryChanged_(category: ContentSettingsTypes) { + if (category !== ContentSettingsTypes.ANTI_ABUSE) { + return; + } + + this.updateToggleValue_(); + } + + private onEnforcementChanged_(enforcement: + chrome.settingsPrivate.Enforcement) { + this.toggleDisabled_ = + enforcement === chrome.settingsPrivate.Enforcement.ENFORCED; + } + + private async updateToggleValue_() { const defaultValue = await this.browserProxy.getDefaultValueForContentType( ContentSettingsTypes.ANTI_ABUSE); + + if (defaultValue.source !== undefined && + defaultValue.source !== ContentSettingProvider.PREFERENCE) { + this.set( + 'pref_.enforcement', chrome.settingsPrivate.Enforcement.ENFORCED); + let controlledBy = chrome.settingsPrivate.ControlledBy.USER_POLICY; + switch (defaultValue.source) { + case ContentSettingProvider.POLICY: + controlledBy = chrome.settingsPrivate.ControlledBy.DEVICE_POLICY; + break; + case ContentSettingProvider.SUPERVISED_USER: + controlledBy = chrome.settingsPrivate.ControlledBy.PARENT; + break; + case ContentSettingProvider.EXTENSION: + controlledBy = chrome.settingsPrivate.ControlledBy.EXTENSION; + break; + } + this.set('pref_.controlledBy', controlledBy); + } else { + this.set('pref_.enforcement', null); + this.set('pref_.controlledBy', null); + } + this.set('pref_.value', this.computeIsSettingEnabled(defaultValue.setting)); } @@ -66,11 +125,11 @@ * A handler for changing the default permission value for a the anti-abuse * content type. */ - private onToggleChange_(e: Event) { - const target = e.target as SettingsToggleButtonElement; + private onToggleChange_() { this.browserProxy.setDefaultValueForContentType( ContentSettingsTypes.ANTI_ABUSE, - target.checked ? ContentSetting.ALLOW : ContentSetting.BLOCK); + this.$.toggleButton.checked ? ContentSetting.ALLOW : + ContentSetting.BLOCK); } }
diff --git a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.html b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.html index 2f92fa6..522216a 100644 --- a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.html +++ b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.html
@@ -109,7 +109,7 @@ margin: 0 14px; } - .label-row[active-labels] { + .label-row[header-hidden] { margin-bottom: 14px; } @@ -141,12 +141,13 @@ </style> <div class="column" id="powerBookmarksContainer"> - <cr-toolbar-search-field label="$i18n{searchBookmarks}" + <cr-toolbar-search-field id="searchField" label="$i18n{searchBookmarks}" clear-label="$i18n{clearSearch}" on-search-changed="onSearchChanged_" disabled="[[editing_]]" hidden="[[guestMode_]]"> </cr-toolbar-search-field> <div class="label-row" hidden="[[guestMode_]]" - active-labels$="[[hasActiveLabels_(labels_.*)]]"> + header-hidden$="[[shouldHideHeader_( + labels_.*, searchQuery_, shownBookmarks_)]]"> <template is="dom-repeat" items="[[labels_]]"> <sp-filter-chip selected="[[item.active]]" @@ -159,7 +160,9 @@ </div> <div class="sp-card"> - <sp-heading hidden$="[[shouldHideHeader_(labels_.*, shownBookmarks_)]]" + <sp-heading + hidden$="[[shouldHideHeader_( + labels_.*, searchQuery_, shownBookmarks_)]]" back-button-label="[[getBackButtonLabel_(activeFolderPath_.*)]]" on-back-button-click="onBackClicked_" hide-back-button="[[!activeFolderPath_.length]]"
diff --git a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts index 21a384a..4037c67d 100644 --- a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts +++ b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts
@@ -33,6 +33,7 @@ import {CrDialogElement} from '//resources/cr_elements/cr_dialog/cr_dialog.js'; import {CrLazyRenderElement} from '//resources/cr_elements/cr_lazy_render/cr_lazy_render.js'; import {CrToastElement} from '//resources/cr_elements/cr_toast/cr_toast.js'; +import {CrToolbarSearchFieldElement} from '//resources/cr_elements/cr_toolbar/cr_toolbar_search_field.js'; import {loadTimeData} from '//resources/js/load_time_data.js'; import {PluralStringProxyImpl} from '//resources/js/plural_string_proxy.js'; import {listenOnce} from '//resources/js/util_ts.js'; @@ -62,6 +63,7 @@ contextMenu: PowerBookmarksContextMenuElement, deletionToast: CrLazyRenderElement<CrToastElement>, powerBookmarksContainer: HTMLElement, + searchField: CrToolbarSearchFieldElement, shownBookmarksIronList: IronListElement, sortMenu: CrActionMenuElement, editDialog: PowerBookmarksEditDialogElement, @@ -535,6 +537,8 @@ if (!this.editing_) { if (event.detail.bookmark.children) { this.push('activeFolderPath_', event.detail.bookmark); + // Cancel search when changing active folder. + this.$.searchField.setValue(''); } else { this.bookmarksApi_.openBookmark( event.detail.bookmark.id, this.activeFolderPath_.length, { @@ -611,7 +615,8 @@ } private shouldHideHeader_(): boolean { - return this.hasActiveLabels_() || this.hasNoBookmarks_(); + return this.hasActiveLabels_() || !!this.searchQuery_ || + this.hasNoBookmarks_(); } private hasNoBookmarks_(): boolean {
diff --git a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_service.ts b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_service.ts index 0a5febe..5ab1d86 100644 --- a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_service.ts +++ b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_service.ts
@@ -152,12 +152,10 @@ folder.children!)); shownBookmarks = topLevelBookmarks; } - if (searchQuery) { - shownBookmarks = this.applySearchQuery_(searchQuery!, shownBookmarks); + if (searchQuery || labels.find((label) => label.active)) { + shownBookmarks = + this.applySearchQueryAndLabels_(labels, searchQuery, shownBookmarks); } - shownBookmarks = shownBookmarks.filter( - (b: chrome.bookmarks.BookmarkTreeNode) => - this.nodeMatchesContentFilters_(b, labels)); const sortChangedPosition = this.sortBookmarks(shownBookmarks, activeSortIndex); if (sortChangedPosition) { @@ -438,8 +436,8 @@ return expanded; } - private applySearchQuery_( - searchQuery: string, + private applySearchQueryAndLabels_( + labels: Label[], searchQuery: string|undefined, shownBookmarks: chrome.bookmarks.BookmarkTreeNode[]) { let searchSpace: chrome.bookmarks.BookmarkTreeNode[] = []; // Search space should include all descendants of the shown bookmarks, in @@ -449,10 +447,12 @@ }); return searchSpace.filter( (bookmark: chrome.bookmarks.BookmarkTreeNode) => - (bookmark.title && - bookmark.title.toLocaleLowerCase().includes(searchQuery)) || - (bookmark.url && - bookmark.url.toLocaleLowerCase().includes(searchQuery))); + this.nodeMatchesContentFilters_(bookmark, labels) && + (!searchQuery || + (bookmark.title && + bookmark.title.toLocaleLowerCase().includes(searchQuery!)) || + (bookmark.url && + bookmark.url.toLocaleLowerCase().includes(searchQuery!)))); } private nodeMatchesContentFilters_(
diff --git a/chrome/browser/sharing/web_push/json_web_token_util.cc b/chrome/browser/sharing/web_push/json_web_token_util.cc index f13890c7..a14f844 100644 --- a/chrome/browser/sharing/web_push/json_web_token_util.cc +++ b/chrome/browser/sharing/web_push/json_web_token_util.cc
@@ -22,17 +22,12 @@ } // namespace absl::optional<std::string> CreateJSONWebToken( - const base::Value& claims, + const base::Value::Dict& claims, crypto::ECPrivateKey* private_key) { - if (!claims.is_dict()) { - LOG(ERROR) << "claims is not a dictionary"; - return absl::nullopt; - } - // Generate header. - base::Value header(base::Value::Type::DICT); - header.SetKey(kKeyAlg, base::Value(kAlgES256)); - header.SetKey(kKeyTyp, base::Value(kTypJwt)); + base::Value::Dict header; + header.Set(kKeyAlg, base::Value(kAlgES256)); + header.Set(kKeyTyp, base::Value(kTypJwt)); // Serialize header. std::string header_serialized;
diff --git a/chrome/browser/sharing/web_push/json_web_token_util.h b/chrome/browser/sharing/web_push/json_web_token_util.h index 5f37fd4..de412fec 100644 --- a/chrome/browser/sharing/web_push/json_web_token_util.h +++ b/chrome/browser/sharing/web_push/json_web_token_util.h
@@ -23,7 +23,7 @@ // // https://tools.ietf.org/html/rfc7519 absl::optional<std::string> CreateJSONWebToken( - const base::Value& claims, + const base::Value::Dict& claims, crypto::ECPrivateKey* private_key); #endif // CHROME_BROWSER_SHARING_WEB_PUSH_JSON_WEB_TOKEN_UTIL_H_
diff --git a/chrome/browser/sharing/web_push/json_web_token_util_unittest.cc b/chrome/browser/sharing/web_push/json_web_token_util_unittest.cc index 75175d3a..16c304af 100644 --- a/chrome/browser/sharing/web_push/json_web_token_util_unittest.cc +++ b/chrome/browser/sharing/web_push/json_web_token_util_unittest.cc
@@ -38,7 +38,7 @@ base::Value::Dict claims; claims.Set("aud", "https://chromium.org"); absl::optional<std::string> jwt = - CreateJSONWebToken(base::Value(claims.Clone()), private_key.get()); + CreateJSONWebToken(claims.Clone(), private_key.get()); ASSERT_TRUE(jwt); // Decompose JWS into data and signautre.
diff --git a/chrome/browser/sharing/web_push/web_push_sender.cc b/chrome/browser/sharing/web_push/web_push_sender.cc index 550628dd..d8c15ce 100644 --- a/chrome/browser/sharing/web_push/web_push_sender.cc +++ b/chrome/browser/sharing/web_push/web_push_sender.cc
@@ -47,8 +47,8 @@ const char kContentEncodingOctetStream[] = "application/octet-stream"; absl::optional<std::string> GetAuthHeader(crypto::ECPrivateKey* vapid_key) { - base::Value claims(base::Value::Type::DICT); - claims.SetKey(kClaimsKeyAudience, base::Value(kFCMServerAudience)); + base::Value::Dict claims; + claims.Set(kClaimsKeyAudience, base::Value(kFCMServerAudience)); int64_t exp = (base::Time::Now() + kClaimsValidPeriod - base::Time::UnixEpoch()) @@ -57,8 +57,7 @@ if (exp > INT_MAX) return absl::nullopt; - claims.SetKey(kClaimsKeyExpirationTime, - base::Value(static_cast<int32_t>(exp))); + claims.Set(kClaimsKeyExpirationTime, base::Value(static_cast<int32_t>(exp))); absl::optional<std::string> jwt = CreateJSONWebToken(claims, vapid_key); if (!jwt)
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc index dbb07d03..98b6dfbe 100644 --- a/chrome/browser/signin/chrome_signin_client.cc +++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -270,8 +270,7 @@ } #if BUILDFLAG(IS_CHROMEOS_ASH) - ash::DelayNetworkCall(base::Milliseconds(ash::kDefaultNetworkRetryDelayMS), - std::move(callback)); + ash::DelayNetworkCall(std::move(callback)); #else // This queue will be processed in `OnConnectionChanged()`. delayed_callbacks_.push_back(std::move(callback));
diff --git a/chrome/browser/sync/test/integration/single_client_preferences_sync_test.cc b/chrome/browser/sync/test/integration/single_client_preferences_sync_test.cc index e4e8bec..6293601 100644 --- a/chrome/browser/sync/test/integration/single_client_preferences_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_preferences_sync_test.cc
@@ -212,6 +212,33 @@ base::test::ScopedFeatureList feature_list_; }; +IN_PROC_BROWSER_TEST_F(SingleClientPreferencesWithAccountStorageSyncTest, + ShouldPreserveLocalPrefsAndNotUploadToAccountOnSignin) { + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + // Register `sync_preferences::kSyncablePrefForTesting`. + GetRegistry(GetProfile(0)) + ->RegisterStringPref(sync_preferences::kSyncablePrefForTesting, "", + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + ASSERT_FALSE( + GetSyncService(0)->GetActiveDataTypes().Has(syncer::PREFERENCES)); + + preferences_helper::ChangeStringPref( + 0, sync_preferences::kSyncablePrefForTesting, "local value"); + + // Enable Sync. + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(syncer::PREFERENCES)); + + // Local value is preserved as the pref doesn't exist on the account. + EXPECT_EQ(GetPrefs(0)->GetString(sync_preferences::kSyncablePrefForTesting), + "local value"); + // No data is uploaded to the account. + EXPECT_FALSE(preferences_helper::GetPreferenceInFakeServer( + syncer::PREFERENCES, + sync_preferences::kSyncablePrefForTesting, GetFakeServer()) + .has_value()); +} + // ChromeOS does not support signing out of a primary account. #if !BUILDFLAG(IS_CHROMEOS) @@ -288,4 +315,90 @@ "local value"); } +IN_PROC_BROWSER_TEST_F(SingleClientPreferencesWithAccountStorageSyncTest, + ShouldChangeSyncablePrefLocallyAndOnAccount) { + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + // Register `sync_preferences::kSyncablePrefForTesting`. + GetRegistry(GetProfile(0)) + ->RegisterStringPref(sync_preferences::kSyncablePrefForTesting, "", + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + ASSERT_FALSE( + GetSyncService(0)->GetActiveDataTypes().Has(syncer::PREFERENCES)); + + preferences_helper::ChangeStringPref( + 0, sync_preferences::kSyncablePrefForTesting, "local value"); + + InjectPreferenceToFakeServer(syncer::PREFERENCES, + sync_preferences::kSyncablePrefForTesting, + base::Value("account value")); + + // Enable Sync. + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(syncer::PREFERENCES)); + + // Fake server value is synced to the account store and overrides local value. + ASSERT_EQ(GetPrefs(0)->GetString(sync_preferences::kSyncablePrefForTesting), + "account value"); + // Change pref value. + preferences_helper::ChangeStringPref( + 0, sync_preferences::kSyncablePrefForTesting, "new value"); + + // Change is synced to account. + EXPECT_TRUE(FakeServerPrefMatchesValueChecker( + syncer::ModelType::PREFERENCES, + sync_preferences::kSyncablePrefForTesting, + ConvertToSyncedPrefValue(base::Value("new value"))) + .Wait()); + + // Disable syncing preferences. + ASSERT_TRUE(GetClient(0)->DisableSyncForType( + syncer::UserSelectableType::kPreferences)); + ASSERT_FALSE( + GetSyncService(0)->GetActiveDataTypes().Has(syncer::PREFERENCES)); + + // Change was also made to local store. + EXPECT_EQ(GetPrefs(0)->GetString(sync_preferences::kSyncablePrefForTesting), + "new value"); +} + +IN_PROC_BROWSER_TEST_F(SingleClientPreferencesWithAccountStorageSyncTest, + ShouldNotSyncNonSyncablePrefToAccount) { + constexpr char kNonSyncablePref[] = "non-syncable pref"; + + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + // Register prefs. + GetRegistry(GetProfile(0))->RegisterStringPref(kNonSyncablePref, "", 0); + GetRegistry(GetProfile(0)) + ->RegisterStringPref(sync_preferences::kSyncablePrefForTesting, "", + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + ASSERT_FALSE( + GetSyncService(0)->GetActiveDataTypes().Has(syncer::PREFERENCES)); + + preferences_helper::ChangeStringPref(0, kNonSyncablePref, "local value"); + InjectPreferenceToFakeServer(syncer::PREFERENCES, kNonSyncablePref, + base::Value("account value")); + + // Enable Sync. + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(syncer::PREFERENCES)); + + // Update prefs. + preferences_helper::ChangeStringPref(0, kNonSyncablePref, "new local value"); + preferences_helper::ChangeStringPref( + 0, sync_preferences::kSyncablePrefForTesting, "new value"); + + // Change is synced to account. + EXPECT_TRUE(FakeServerPrefMatchesValueChecker( + syncer::ModelType::PREFERENCES, + sync_preferences::kSyncablePrefForTesting, + ConvertToSyncedPrefValue(base::Value("new value"))) + .Wait()); + // Not the right way to test this but the non-syncable pref has not been + // synced to the new value. + EXPECT_TRUE(FakeServerPrefMatchesValueChecker( + syncer::ModelType::PREFERENCES, kNonSyncablePref, + ConvertToSyncedPrefValue(base::Value("account value"))) + .Wait()); +} + } // namespace
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.cc b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.cc index 573d1595..b4c35a4e 100644 --- a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.cc +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.cc
@@ -60,8 +60,9 @@ ContentAutofillDriver& driver) { auto* manager = static_cast<BrowserAutofillManager*>(driver.autofill_manager()); - manager->set_touch_to_fill_delegate( - std::make_unique<TouchToFillDelegateImpl>(manager)); + manager->set_touch_to_fill_delegate(std::make_unique<TouchToFillDelegateImpl>( + manager, + FastCheckoutClient::GetOrCreateForWebContents(factory.web_contents()))); } bool TouchToFillCreditCardController::Show(
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller_unittest.cc b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller_unittest.cc index 537e8ff..964f4b5 100644 --- a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller_unittest.cc +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "chrome/browser/fast_checkout/mock_fast_checkout_client.h" #include "chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.h" #include "chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view.h" #include "chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_controller.h" @@ -56,8 +57,9 @@ class MockTouchToFillDelegateImpl : public TouchToFillDelegateImpl { public: explicit MockTouchToFillDelegateImpl( - MockBrowserAutofillManager* autofill_manager) - : TouchToFillDelegateImpl(autofill_manager) { + MockBrowserAutofillManager* autofill_manager, + MockFastCheckoutClient* fast_checkout_client) + : TouchToFillDelegateImpl(autofill_manager, fast_checkout_client) { ON_CALL(*this, GetManager).WillByDefault(Return(autofill_manager)); ON_CALL(*this, ShouldShowScanCreditCard).WillByDefault(Return(true)); } @@ -101,8 +103,11 @@ NavigateAndCommit(GURL("about:blank")); credit_card_controller_ = std::make_unique<TouchToFillCreditCardController>(&autofill_client()); + fast_checkout_client_ = + std::make_unique<MockFastCheckoutClient>(web_contents()); autofill_manager().set_touch_to_fill_delegate( - std::make_unique<MockTouchToFillDelegateImpl>(&autofill_manager())); + std::make_unique<MockTouchToFillDelegateImpl>( + &autofill_manager(), fast_checkout_client_.get())); mock_view_ = std::make_unique<MockTouchToFillCreditCardViewImpl>(); } @@ -157,6 +162,7 @@ autofill_client_injector_; TestAutofillManagerInjector<MockBrowserAutofillManager> autofill_manager_injector_; + std::unique_ptr<MockFastCheckoutClient> fast_checkout_client_; FormGlobalId some_form_ = test::MakeFormGlobalId(); FieldGlobalId some_field_ = test::MakeFieldGlobalId(); };
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_quality_metrics_unittest.cc b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_quality_metrics_unittest.cc index a5ce630..0d70892c 100644 --- a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_quality_metrics_unittest.cc +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_quality_metrics_unittest.cc
@@ -17,10 +17,35 @@ using ::base::Bucket; using ::base::BucketsAre; +using ::testing::NiceMock; using ::testing::TestWithParam; namespace autofill::autofill_metrics { +class MockFastCheckoutClient : public FastCheckoutClient { + public: + MockFastCheckoutClient() = default; + ~MockFastCheckoutClient() override = default; + MOCK_METHOD(bool, + TryToStart, + (const GURL&, + const autofill::FormData&, + const autofill::FormFieldData&, + base::WeakPtr<autofill::AutofillManager>), + (override)); + MOCK_METHOD(void, Stop, (bool), (override)); + MOCK_METHOD(bool, IsRunning, (), (const, override)); + MOCK_METHOD(bool, IsShowing, (), (const, override)); + MOCK_METHOD(void, OnNavigation, (const GURL&, bool), (override)); + MOCK_METHOD(bool, + IsSupported, + (const autofill::FormData&, + const autofill::FormFieldData&, + const autofill::AutofillManager&), + (override)); + MOCK_METHOD(bool, IsNotShownYet, (), (const, override)); +}; + struct TouchToFillForCreditCardsTestCase { std::vector<ServerFieldType> field_types; std::vector<bool> fields_have_autofilled_values; @@ -38,8 +63,11 @@ .WillByDefault(testing::Return(true)); ON_CALL(*autofill_client_, IsTouchToFillCreditCardSupported) .WillByDefault(testing::Return(true)); + ON_CALL(fast_checkout_client_, IsNotShownYet) + .WillByDefault(testing::Return(true)); autofill_manager().set_touch_to_fill_delegate( - std::make_unique<TouchToFillDelegateImpl>(&autofill_manager())); + std::make_unique<TouchToFillDelegateImpl>(&autofill_manager(), + &fast_checkout_client_)); } void TearDown() override { TearDownHelper(); } @@ -95,6 +123,9 @@ return *static_cast<TouchToFillDelegateImpl*>( autofill_manager().touch_to_fill_delegate()); } + + private: + NiceMock<MockFastCheckoutClient> fast_checkout_client_; }; // The test workflow:
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.cc b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.cc index 4524f3a..864809e19 100644 --- a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.cc +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.cc
@@ -6,6 +6,8 @@ #include "base/feature_list.h" #include "base/metrics/histogram_functions.h" +#include "chrome/browser/fast_checkout/fast_checkout_client.h" +#include "components/autofill/content/browser/content_autofill_client.h" #include "components/autofill/core/browser/autofill_browser_util.h" #include "components/autofill/core/browser/autofill_manager.h" #include "components/autofill/core/browser/autofill_suggestion_generator.h" @@ -33,8 +35,9 @@ TouchToFillDelegateImpl::DryRunResult::~DryRunResult() = default; TouchToFillDelegateImpl::TouchToFillDelegateImpl( - BrowserAutofillManager* manager) - : manager_(manager) { + BrowserAutofillManager* manager, + FastCheckoutClient* fast_checkout_client) + : manager_(manager), fast_checkout_client_(fast_checkout_client) { DCHECK(manager); } @@ -83,7 +86,10 @@ if (!field->IsFocusable() || !SanitizedFieldIsEmpty(field->value)) { return {TriggerOutcome::kFieldNotEmptyOrNotFocusable, {}}; } - + // Trigger only if Fast Checkout was not shown before. + if (!fast_checkout_client_->IsNotShownYet()) { + return {TriggerOutcome::kFastCheckoutWasShown, {}}; + } // Trigger only if there is at least 1 complete valid credit card on file. // Complete = contains number, expiration date and name on card. // Valid = unexpired with valid number format.
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.h b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.h index 0c565dad..3b7fa01 100644 --- a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.h +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.h
@@ -8,6 +8,7 @@ #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" #include "base/timer/timer.h" +#include "chrome/browser/fast_checkout/fast_checkout_client.h" #include "components/autofill/core/browser/autofill_manager.h" #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/form_structure.h" @@ -58,7 +59,9 @@ // TouchToFill is not supported for this field type. This value is not logged // to UMA. kUnsupportedFieldType = 10, - kMaxValue = kUnsupportedFieldType + // Fast Checkout was shown before TouchToFill could be triggered. + kFastCheckoutWasShown = 11, + kMaxValue = kFastCheckoutWasShown }; constexpr const char kUmaTouchToFillCreditCardTriggerOutcome[] = @@ -86,7 +89,8 @@ // TODO(crbug.com/1324900): Consider using more descriptive name. class TouchToFillDelegateImpl : public TouchToFillDelegate { public: - explicit TouchToFillDelegateImpl(BrowserAutofillManager* manager); + TouchToFillDelegateImpl(BrowserAutofillManager* manager, + FastCheckoutClient* fast_checkout_client); TouchToFillDelegateImpl(const TouchToFillDelegateImpl&) = delete; TouchToFillDelegateImpl& operator=(const TouchToFillDelegateImpl&) = delete; ~TouchToFillDelegateImpl() override; @@ -163,6 +167,7 @@ TouchToFillState ttf_credit_card_state_ = TouchToFillState::kShouldShow; const raw_ptr<BrowserAutofillManager> manager_; + const raw_ptr<FastCheckoutClient> fast_checkout_client_; FormData query_form_; FormFieldData query_field_; bool dismissed_by_user_;
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl_unittest.cc b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl_unittest.cc index c3a5d60..311d9ae 100644 --- a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl_unittest.cc +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl_unittest.cc
@@ -32,6 +32,30 @@ namespace { +class MockFastCheckoutClient : public FastCheckoutClient { + public: + MockFastCheckoutClient() = default; + ~MockFastCheckoutClient() override = default; + MOCK_METHOD(bool, + TryToStart, + (const GURL&, + const autofill::FormData&, + const autofill::FormFieldData&, + base::WeakPtr<autofill::AutofillManager>), + (override)); + MOCK_METHOD(void, Stop, (bool), (override)); + MOCK_METHOD(bool, IsRunning, (), (const, override)); + MOCK_METHOD(bool, IsShowing, (), (const, override)); + MOCK_METHOD(void, OnNavigation, (const GURL&, bool), (override)); + MOCK_METHOD(bool, + IsSupported, + (const autofill::FormData&, + const autofill::FormFieldData&, + const autofill::AutofillManager&), + (override)); + MOCK_METHOD(bool, IsNotShownYet, (), (const, override)); +}; + class MockAutofillClient : public TestAutofillClient { public: MockAutofillClient() = default; @@ -141,7 +165,7 @@ autofill_driver_.get(), &autofill_client_); auto touch_to_fill_delegate = std::make_unique<TouchToFillDelegateImpl>( - browser_autofill_manager_.get()); + browser_autofill_manager_.get(), &fast_checkout_client_); touch_to_fill_delegate_ = touch_to_fill_delegate.get(); base::WeakPtr<TouchToFillDelegateImpl> touch_to_fill_delegate_weak = touch_to_fill_delegate->GetWeakPtr(); @@ -169,6 +193,8 @@ delegate->OnDismissed(/*dismissed_by_user=*/false); } }); + ON_CALL(fast_checkout_client_, IsNotShownYet) + .WillByDefault(testing::Return(true)); test::CreateTestCreditCardFormData(&form_, /*is_https=*/true, /*use_month_type=*/false); @@ -195,6 +221,7 @@ base::test::TaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; test::AutofillUnitTestEnvironment autofill_test_environment_; + NiceMock<MockFastCheckoutClient> fast_checkout_client_; NiceMock<MockAutofillClient> autofill_client_; std::unique_ptr<TestAutofillDriver> autofill_driver_; std::unique_ptr<MockBrowserAutofillManager> browser_autofill_manager_; @@ -439,6 +466,17 @@ } TEST_F(TouchToFillDelegateImplUnitTest, + TryToShowTouchToFillFailsIfFastCheckoutWasShown) { + ASSERT_FALSE(touch_to_fill_delegate_->IsShowingTouchToFill()); + EXPECT_CALL(fast_checkout_client_, IsNotShownYet).WillOnce(Return(false)); + + TryToShowTouchToFill(/*expected_success=*/false); + histogram_tester_.ExpectUniqueSample( + kUmaTouchToFillCreditCardTriggerOutcome, + TouchToFillCreditCardTriggerOutcome::kFastCheckoutWasShown, 1); +} + +TEST_F(TouchToFillDelegateImplUnitTest, TryToShowTouchToFillSucceedsIfAtLestOneCardIsValid) { autofill_client_.GetPersonalDataManager()->ClearCreditCards(); CreditCard credit_card = autofill::test::GetCreditCard();
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index fa55e75..299d1a0d7 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -2623,12 +2623,15 @@ <message name="IDS_NOTIFICATION_WEBAPK_INSTALL_FAILED" desc="Indicates that the WebAPK install was unsuccessful."> Couldn’t install <ph name="WEBAPK_NAME">%1$s<ex>Progressive Web Apps</ex></ph>. </message> - <message name="IDS_NOTIFICATION_WEBAPK_INSTALL_FAILED_CONTENTS_GENERAL" desc="Indicates that the WebAPK install was unsuccessful."> + <message name="IDS_NOTIFICATION_WEBAPK_INSTALL_FAILED_CONTENTS_GENERAL" desc="Message content indicates that the WebAPK install was unsuccessful for a general reason."> Something went wrong. </message> - <message name="IDS_WEBAPK_INSTALL_FAILED_ACTION_OPEN" desc="Indicates that the WebAPK install was unsuccessful."> + <message name="IDS_WEBAPK_INSTALL_FAILED_ACTION_OPEN" desc="The label of the button which upon click would open the site user was trying to install as PWA. "> Go back to site </message> + <message name="IDS_WEBAPK_INSTALL_FAILED_ACTION_RETRY" desc="The label of the button which upon click would retry installing the PWA" translateable="false"> + Try again + </message> <message name="IDS_IPH_PWA_INSTALL_AVAILABLE_TEXT" desc="The in-product-help message for PWAs that can be installed to the device."> Install this app </message>
diff --git a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm index b9a767d..106f156 100644 --- a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm
@@ -9,7 +9,7 @@ #include "base/functional/bind.h" #include "base/mac/foundation_util.h" #import "base/mac/scoped_nsobject.h" -#include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" #include "base/notreached.h" #include "base/strings/sys_string_conversions.h" #include "chrome/browser/printing/print_view_manager.h" @@ -62,16 +62,32 @@ // make new tab with properties {URL:"http://google.com"} @property (nonatomic, copy) NSString* tempURL; +- (bool)isJavaScriptEnabled; + @end @implementation TabAppleScript { - raw_ptr<content::WebContents> _webContents; // weak. - - raw_ptr<Profile> _profile; // weak. + // A note about lifetimes: It's not expected that this object will ever be + // deleted behind the back of this class. AppleScript does not hold onto + // objects between script runs; it will retain the object specifier, and if + // needed again, AppleScript will re-iterate over the objects, and look for + // the specified object. However, there's no hard guarantee that a race + // couldn't be made to happen, and in tests things are torn down at odd times, + // so it's best to use a real weak pointer. + base::WeakPtr<content::WebContents> _webContents; } @synthesize tempURL = _tempURL; +- (bool)isJavaScriptEnabled { + if (!_webContents) { + return false; + } + + return chrome::mac::IsJavaScriptEnabledForProfile( + Profile::FromBrowserContext(_webContents->GetBrowserContext())); +} + - (instancetype)init { if ((self = [super init])) { // Holds the SessionID that the new tab is going to get. @@ -93,11 +109,8 @@ } if ((self = [super init])) { - // It is safe to be weak; if a tab goes away (e.g. the user closes a tab) - // the AppleScript runtime calls tabs in AppleScriptWindow and this - // particular tab is never returned. - _webContents = webContents; - _profile = Profile::FromBrowserContext(webContents->GetBrowserContext()); + _webContents = webContents->GetWeakPtr(); + sessions::SessionTabHelper* session_tab_helper = sessions::SessionTabHelper::FromWebContents(webContents); self.uniqueID = [NSString @@ -108,13 +121,10 @@ - (void)setWebContents:(content::WebContents*)webContents { DCHECK(webContents); - // It is safe to be weak; if a tab goes away (e.g. the user closes a tab) - // the AppleScript runtime calls tabs in AppleScriptWindow and this - // particular tab is never returned. - _webContents = webContents; + _webContents = webContents->GetWeakPtr(); + sessions::SessionTabHelper* session_tab_helper = sessions::SessionTabHelper::FromWebContents(webContents); - _profile = Profile::FromBrowserContext(webContents->GetBrowserContext()); self.uniqueID = [NSString stringWithFormat:@"%d", session_tab_helper->session_id().id()]; @@ -136,25 +146,24 @@ return base::SysUTF8ToNSString(url.spec()); } -- (void)setURL:(NSString*)aURL { +- (void)setURL:(NSString*)url { // If a scripter sets a URL before |webContents_| or |profile_| is set, save // it at a temporary location. Once they're set, -setURL: will be call again // with the temporary URL. - if (!_profile || !_webContents) { - self.tempURL = aURL; + if (!_webContents) { + self.tempURL = url; return; } - GURL url(base::SysNSStringToUTF8(aURL)); - if (!chrome::mac::IsJavaScriptEnabledForProfile(_profile) && - url.SchemeIs(url::kJavaScriptScheme)) { + GURL gurl(base::SysNSStringToUTF8(url)); + if (![self isJavaScriptEnabled] && gurl.SchemeIs(url::kJavaScriptScheme)) { AppleScript::SetError(AppleScript::Error::kJavaScriptUnsupported); return; } // Check if the URL is valid; if not, then attempting to open it will trip // a fatal check in navigation. - if (!url.is_valid()) { + if (!gurl.is_valid()) { AppleScript::SetError(AppleScript::Error::kInvalidURL); return; } @@ -164,12 +173,16 @@ return; } - _webContents->OpenURL(OpenURLParams(url, content::Referrer(), + _webContents->OpenURL(OpenURLParams(gurl, content::Referrer(), WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false)); } - (NSString*)title { + if (!_webContents) { + return nil; + } + NavigationEntry* entry = _webContents->GetController().GetActiveEntry(); if (!entry) { return nil; @@ -180,35 +193,67 @@ } - (NSNumber*)loading { + if (!_webContents) { + return nil; + } + BOOL loadingValue = _webContents->IsLoading() ? YES : NO; return @(loadingValue); } - (void)handlesUndoScriptCommand:(NSScriptCommand*)command { + if (!_webContents) { + return; + } + _webContents->Undo(); } - (void)handlesRedoScriptCommand:(NSScriptCommand*)command { + if (!_webContents) { + return; + } + _webContents->Redo(); } - (void)handlesCutScriptCommand:(NSScriptCommand*)command { + if (!_webContents) { + return; + } + _webContents->Cut(); } - (void)handlesCopyScriptCommand:(NSScriptCommand*)command { + if (!_webContents) { + return; + } + _webContents->Copy(); } - (void)handlesPasteScriptCommand:(NSScriptCommand*)command { + if (!_webContents) { + return; + } + _webContents->Paste(); } - (void)handlesSelectAllScriptCommand:(NSScriptCommand*)command { + if (!_webContents) { + return; + } + _webContents->SelectAll(); } - (void)handlesGoBackScriptCommand:(NSScriptCommand*)command { + if (!_webContents) { + return; + } + NavigationController& navigationController = _webContents->GetController(); if (navigationController.CanGoBack()) { navigationController.GoBack(); @@ -216,6 +261,10 @@ } - (void)handlesGoForwardScriptCommand:(NSScriptCommand*)command { + if (!_webContents) { + return; + } + NavigationController& navigationController = _webContents->GetController(); if (navigationController.CanGoForward()) { navigationController.GoForward(); @@ -223,24 +272,41 @@ } - (void)handlesReloadScriptCommand:(NSScriptCommand*)command { + if (!_webContents) { + return; + } + NavigationController& navigationController = _webContents->GetController(); navigationController.Reload(content::ReloadType::NORMAL, /*check_for_repost=*/true); } - (void)handlesStopScriptCommand:(NSScriptCommand*)command { + if (!_webContents) { + return; + } + _webContents->Stop(); } - (void)handlesPrintScriptCommand:(NSScriptCommand*)command { - bool initiated = printing::PrintViewManager::FromWebContents(_webContents) - ->PrintNow(_webContents->GetPrimaryMainFrame()); + if (!_webContents) { + return; + } + + bool initiated = + printing::PrintViewManager::FromWebContents(_webContents.get()) + ->PrintNow(_webContents->GetPrimaryMainFrame()); if (!initiated) { AppleScript::SetError(AppleScript::Error::kInitiatePrinting); } } - (void)handlesSaveScriptCommand:(NSScriptCommand*)command { + if (!_webContents) { + return; + } + NSDictionary* dictionary = command.evaluatedArguments; NSURL* fileURL = dictionary[@"File"]; @@ -276,22 +342,33 @@ } - (void)handlesCloseScriptCommand:(NSScriptCommand*)command { - _webContents->GetDelegate()->CloseContents(_webContents); + if (!_webContents) { + return; + } + + _webContents->GetDelegate()->CloseContents(_webContents.get()); } - (void)handlesViewSourceScriptCommand:(NSScriptCommand*)command { + if (!_webContents) { + return; + } + _webContents->GetPrimaryMainFrame()->ViewSource(); } - (id)handlesExecuteJavascriptScriptCommand:(NSScriptCommand*)command { - if (!chrome::mac::IsJavaScriptEnabledForProfile(_profile)) { + if (!_webContents) { + return nil; + } + + if (![self isJavaScriptEnabled]) { AppleScript::SetError(AppleScript::Error::kJavaScriptUnsupported); return nil; } content::RenderFrameHost* frame = _webContents->GetPrimaryMainFrame(); if (!frame) { - NOTREACHED(); return nil; }
diff --git a/chrome/browser/ui/cocoa/applescript/window_applescript.mm b/chrome/browser/ui/cocoa/applescript/window_applescript.mm index 7976b21..94b4608 100644 --- a/chrome/browser/ui/cocoa/applescript/window_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/window_applescript.mm
@@ -8,7 +8,7 @@ #import "base/mac/foundation_util.h" #import "base/mac/scoped_nsobject.h" -#include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" #include "base/notreached.h" #include "base/strings/sys_string_conversions.h" #include "base/time/time.h" @@ -42,7 +42,14 @@ @end @implementation WindowAppleScript { - raw_ptr<Browser> _browser; // weak. + // A note about lifetimes: It's not expected that this object will ever be + // deleted behind the back of this class. AppleScript does not hold onto + // objects between script runs; it will retain the object specifier, and if + // needed again, AppleScript will re-iterate over the objects, and look for + // the specified object. However, there's no hard guarantee that a race + // couldn't be made to happen, and in tests things are torn down at odd times, + // so it's best to use a real weak pointer. + base::WeakPtr<Browser> _browser; } - (instancetype)init { @@ -89,17 +96,21 @@ [self release]; return nil; } - _browser = Browser::Create(Browser::CreateParams(aProfile, false)); - chrome::NewTab(_browser); - _browser->window()->Show(); + + Browser* browser = Browser::Create( + Browser::CreateParams(aProfile, /*user_gesture=*/false)); + chrome::NewTab(browser); + browser->window()->Show(); + + _browser = browser->AsWeakPtr(); self.uniqueID = [NSString stringWithFormat:@"%d", _browser->session_id().id()]; } return self; } -- (instancetype)initWithBrowser:(Browser*)aBrowser { - if (!aBrowser) { +- (instancetype)initWithBrowser:(Browser*)browser { + if (!browser) { [self release]; return nil; } @@ -108,7 +119,7 @@ // It is safe to be weak, if a window goes away (eg user closing a window) // the AppleScript runtime calls appleScriptWindows in // BrowserCrApplication and this particular window is never returned. - _browser = aBrowser; + _browser = browser->AsWeakPtr(); self.uniqueID = [NSString stringWithFormat:@"%d", _browser->session_id().id()]; } @@ -116,7 +127,11 @@ } - (NSWindow*)nativeHandle { - // window() can be NULL during startup. + if (!_browser) { + return nil; + } + + // window() can be null during startup. if (_browser->window()) { return _browser->window()->GetNativeWindow().GetNativeNSWindow(); } @@ -124,6 +139,10 @@ } - (NSNumber*)activeTabIndex { + if (!_browser) { + return nil; + } + // Note: AppleScript is 1-based, that is lists begin with index 1. int activeTabIndex = _browser->tab_strip_model()->active_index() + 1; if (!activeTabIndex) { @@ -133,6 +152,10 @@ } - (void)setActiveTabIndex:(NSNumber*)anActiveTabIndex { + if (!_browser) { + return; + } + // Note: AppleScript is 1-based, that is lists begin with index 1. int atIndex = anActiveTabIndex.intValue - 1; if (atIndex >= 0 && atIndex < _browser->tab_strip_model()->count()) { @@ -145,14 +168,26 @@ } - (NSString*)givenName { + if (!_browser) { + return nil; + } + return base::SysUTF8ToNSString(_browser->user_title()); } - (void)setGivenName:(NSString*)name { + if (!_browser) { + return; + } + _browser->SetWindowUserTitle(base::SysNSStringToUTF8(name)); } - (NSString*)mode { + if (!_browser) { + return nil; + } + Profile* profile = _browser->profile(); if (profile->IsOffTheRecord()) { return AppleScript::kIncognitoWindowMode; @@ -168,6 +203,10 @@ } - (TabAppleScript*)activeTab { + if (!_browser) { + return nil; + } + TabAppleScript* currentTab = [[[TabAppleScript alloc] initWithWebContents: _browser->tab_strip_model()->GetActiveWebContents()] autorelease]; @@ -177,6 +216,10 @@ } - (NSArray<TabAppleScript*>*)tabs { + if (!_browser) { + return nil; + } + TabStripModel* tabStrip = _browser->tab_strip_model(); NSMutableArray* tabs = [NSMutableArray arrayWithCapacity:tabStrip->count()]; @@ -197,6 +240,10 @@ } - (void)insertInTabs:(TabAppleScript*)aTab { + if (!_browser) { + return; + } + // This method gets called when a new tab is created so // the container and property are set here. [aTab setContainer:self @@ -205,8 +252,7 @@ // Set how long it takes a tab to be created. base::TimeTicks newTabStartTime = base::TimeTicks::Now(); content::WebContents* contents = chrome::AddSelectedTabWithURL( - _browser, - GURL(chrome::kChromeUINewTabURL), + _browser.get(), GURL(chrome::kChromeUINewTabURL), ui::PAGE_TRANSITION_TYPED); CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents); core_tab_helper->set_new_tab_start_time(newTabStartTime); @@ -214,6 +260,10 @@ } - (void)insertInTabs:(TabAppleScript*)aTab atIndex:(int)index { + if (!_browser) { + return; + } + // This method gets called when a new tab is created so // the container and property are set here. [aTab setContainer:self @@ -221,7 +271,7 @@ // Set how long it takes a tab to be created. base::TimeTicks newTabStartTime = base::TimeTicks::Now(); - NavigateParams params(_browser, GURL(chrome::kChromeUINewTabURL), + NavigateParams params(_browser.get(), GURL(chrome::kChromeUINewTabURL), ui::PAGE_TRANSITION_TYPED); params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; params.tabstrip_index = index; @@ -234,6 +284,10 @@ } - (void)removeFromTabsAtIndex:(int)index { + if (!_browser) { + return; + } + if (index < 0 || index >= _browser->tab_strip_model()->count()) { return; } @@ -264,6 +318,10 @@ } - (void)handlesCloseScriptCommand:(NSCloseCommand*)command { + if (!_browser) { + return; + } + // window() can be null during startup. if (_browser->window()) { _browser->window()->Close();
diff --git a/chrome/browser/ui/startup/first_run_service.cc b/chrome/browser/ui/startup/first_run_service.cc index c7a06442..8ee0044 100644 --- a/chrome/browser/ui/startup/first_run_service.cc +++ b/chrome/browser/ui/startup/first_run_service.cc
@@ -409,6 +409,13 @@ GetInstance()->GetServiceForBrowserContext(context, /*create=*/true)); } +// static +FirstRunService* FirstRunServiceFactory::GetForBrowserContextIfExists( + content::BrowserContext* context) { + return static_cast<FirstRunService*>( + GetInstance()->GetServiceForBrowserContext(context, /*create=*/false)); +} + KeyedService* FirstRunServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context);
diff --git a/chrome/browser/ui/startup/first_run_service.h b/chrome/browser/ui/startup/first_run_service.h index 81516c1..f293ad5 100644 --- a/chrome/browser/ui/startup/first_run_service.h +++ b/chrome/browser/ui/startup/first_run_service.h
@@ -171,6 +171,9 @@ static FirstRunService* GetForBrowserContext( content::BrowserContext* context); + static FirstRunService* GetForBrowserContextIfExists( + content::BrowserContext* context); + static FirstRunServiceFactory* GetInstance(); private:
diff --git a/chrome/browser/ui/startup/first_run_service_browsertest.cc b/chrome/browser/ui/startup/first_run_service_browsertest.cc index 1d31d9f9..18f908c 100644 --- a/chrome/browser/ui/startup/first_run_service_browsertest.cc +++ b/chrome/browser/ui/startup/first_run_service_browsertest.cc
@@ -148,6 +148,8 @@ // Also make sure we will do another attempt at creating the service now // that the first run state changed. + ASSERT_FALSE( + FirstRunServiceFactory::GetForBrowserContextIfExists(profile())); FirstRunServiceFactory::GetInstance()->Disassociate(profile()); identity_test_env_adaptor_ = @@ -512,26 +514,15 @@ kStudyTestGroupName1)); } -// Flaky on Mac: crbug.com/1427094 -#if BUILDFLAG(IS_MAC) -#define MAYBE_PRE_PRE_GroupViaPrefs DISABLED_PRE_PRE_GroupViaPrefs -#define MAYBE_PRE_GroupViaPrefs DISABLED_PRE_GroupViaPrefs -#define MAYBE_GroupViaPrefs DISABLED_GroupViaPrefs -#else -#define MAYBE_PRE_PRE_GroupViaPrefs PRE_PRE_GroupViaPrefs -#define MAYBE_PRE_GroupViaPrefs PRE_GroupViaPrefs -#define MAYBE_GroupViaPrefs GroupViaPrefs -#endif IN_PROC_BROWSER_TEST_F(FirstRunServiceCohortBrowserTest, - MAYBE_PRE_PRE_GroupViaPrefs) { + PRE_PRE_GroupViaPrefs) { // Setting the pref, we expect it to get picked up in an upcoming startup. PrefService* local_state = g_browser_process->local_state(); local_state->SetString(prefs::kFirstRunStudyGroup, kStudyTestGroupName2); EXPECT_FALSE(variations::HasSyntheticTrial("ForYouFreSynthetic")); } -IN_PROC_BROWSER_TEST_F(FirstRunServiceCohortBrowserTest, - MAYBE_PRE_GroupViaPrefs) { +IN_PROC_BROWSER_TEST_F(FirstRunServiceCohortBrowserTest, PRE_GroupViaPrefs) { // The synthetic group should not be registered yet since we didn't go through // the FRE. EXPECT_FALSE(variations::HasSyntheticTrial("ForYouFreSynthetic")); @@ -540,7 +531,8 @@ PrefService* local_state = g_browser_process->local_state(); local_state->SetBoolean(prefs::kFirstRunFinished, true); } -IN_PROC_BROWSER_TEST_F(FirstRunServiceCohortBrowserTest, MAYBE_GroupViaPrefs) { +IN_PROC_BROWSER_TEST_F(FirstRunServiceCohortBrowserTest, GroupViaPrefs) { + EXPECT_TRUE(variations::HasSyntheticTrial("ForYouFreSynthetic")); // The registered group is read from the prefs, not from the feature param. EXPECT_TRUE(variations::IsInSyntheticTrialGroup("ForYouFreSynthetic", kStudyTestGroupName2));
diff --git a/chrome/browser/ui/user_education/open_page_and_show_help_bubble.cc b/chrome/browser/ui/user_education/open_page_and_show_help_bubble.cc index ad3e1c8..06a27d5 100644 --- a/chrome/browser/ui/user_education/open_page_and_show_help_bubble.cc +++ b/chrome/browser/ui/user_education/open_page_and_show_help_bubble.cc
@@ -23,6 +23,7 @@ #include "components/user_education/common/help_bubble_params.h" #include "content/public/browser/navigation_handle.h" #include "ui/base/interaction/element_tracker.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/page_transition_types.h" #include "ui/base/window_open_disposition.h" @@ -45,6 +46,11 @@ bubble_params_.body_text = params.bubble_text; bubble_params_.arrow = params.bubble_arrow; + if (params.close_button_alt_text_id) { + bubble_params_.close_button_alt_text = + l10n_util::GetStringUTF16(params.close_button_alt_text_id.value()); + } + anchor_subscription_ = ui::ElementTracker::GetElementTracker() ->AddElementShownInAnyContextCallback(
diff --git a/chrome/browser/ui/user_education/open_page_and_show_help_bubble.h b/chrome/browser/ui/user_education/open_page_and_show_help_bubble.h index 502aebd..d060abf 100644 --- a/chrome/browser/ui/user_education/open_page_and_show_help_bubble.h +++ b/chrome/browser/ui/user_education/open_page_and_show_help_bubble.h
@@ -90,6 +90,11 @@ // The text of the help bubble. std::u16string bubble_text; + // The id of the text that should be used for the accessibility label of the + // help bubble's close button. The localized string will be looked up using + // this identifier. + absl::optional<int> close_button_alt_text_id; + // Callback that notifies whether the page loaded and the bubble was // displayed successfully. Typically used for testing or metrics collection. // If the page load is aborted or the anchor not found within a reasonable
diff --git a/chrome/browser/ui/user_education/open_page_and_show_help_bubble_browsertest.cc b/chrome/browser/ui/user_education/open_page_and_show_help_bubble_browsertest.cc index d58baca2..13b0bdd 100644 --- a/chrome/browser/ui/user_education/open_page_and_show_help_bubble_browsertest.cc +++ b/chrome/browser/ui/user_education/open_page_and_show_help_bubble_browsertest.cc
@@ -2,9 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/ui/user_education/open_page_and_show_help_bubble.h" +#include <string> + +#include "base/functional/bind.h" #include "base/memory/weak_ptr.h" #include "base/run_loop.h" #include "base/test/bind.h" @@ -12,11 +14,15 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_element_identifiers.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/interaction/interactive_browser_test.h" +#include "components/strings/grit/components_strings.h" #include "components/user_education/common/help_bubble_params.h" #include "content/public/test/browser_test.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" namespace { @@ -44,7 +50,7 @@ } // namespace -using OpenPageAndShowHelpBubbleBrowserTest = InProcessBrowserTest; +using OpenPageAndShowHelpBubbleBrowserTest = InteractiveBrowserTest; IN_PROC_BROWSER_TEST_F(OpenPageAndShowHelpBubbleBrowserTest, OpenPageAndDisplayHelpBubbleInNewPage) { @@ -184,3 +190,33 @@ // On failure the object is destroyed immediately. ASSERT_FALSE(handle); } + +IN_PROC_BROWSER_TEST_F(OpenPageAndShowHelpBubbleBrowserTest, + HelpBubbleParamsCanConfigureCloseButtonAltText) { + auto params = GetDefaultParams(); + params.target_url = GURL(kPageWithAnchorURL); + params.overwrite_active_tab = true; + // Set the alt text here and then check that aria-label matches. + params.close_button_alt_text_id = IDS_CLOSE_PROMO; + + DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kBubbleIsVisible); + DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kTabId); + + auto help_bubble_start_callback = + base::BindOnce(base::IgnoreResult(&OpenPageAndShowHelpBubble::Start), + browser(), std::move(params)); + static const DeepQuery kPathToHelpBubbleCloseButton = { + "user-education-internals", "#IPH_WebUiHelpBubbleTest", "help-bubble", + "#close"}; + StateChange bubble_is_visible; + bubble_is_visible.event = kBubbleIsVisible; + bubble_is_visible.where = kPathToHelpBubbleCloseButton; + bubble_is_visible.type = StateChange::Type::kExists; + RunTestSequence( + InstrumentTab(kTabId), Do(std::move(help_bubble_start_callback)), + WaitForWebContentsNavigation(kTabId, GURL(kPageWithAnchorURL)), + WaitForStateChange(kTabId, std::move(bubble_is_visible)), + CheckJsResultAt(kTabId, kPathToHelpBubbleCloseButton, + "(el) => el.getAttribute('aria-label')", + l10n_util::GetStringUTF8(IDS_CLOSE_PROMO))); +}
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_browsertest.cc b/chrome/browser/ui/views/download/bubble/download_bubble_browsertest.cc index 23621250..12b72f7 100644 --- a/chrome/browser/ui/views/download/bubble/download_bubble_browsertest.cc +++ b/chrome/browser/ui/views/download/bubble/download_bubble_browsertest.cc
@@ -16,6 +16,7 @@ #include "components/feature_engagement/public/feature_constants.h" #include "components/feature_engagement/public/tracker.h" #include "components/feature_engagement/test/scoped_iph_feature_list.h" +#include "components/safe_browsing/core/common/features.h" #include "components/user_education/test/feature_promo_test_util.h" #include "content/public/test/browser_test.h" #include "content/public/test/download_test_observer.h" @@ -25,7 +26,9 @@ public: DownloadBubbleTest() { test_features_.InitAndEnableFeatures( - {feature_engagement::kIPHDownloadToolbarButtonFeature}, {}); + {feature_engagement::kIPHDownloadToolbarButtonFeature, + safe_browsing::kDownloadBubble, safe_browsing::kDownloadBubbleV2}, + {}); } void SetUpOnMainThread() override {
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_security_view_unittest.cc b/chrome/browser/ui/views/download/bubble/download_bubble_security_view_unittest.cc index 899db66..3ab25041 100644 --- a/chrome/browser/ui/views/download/bubble/download_bubble_security_view_unittest.cc +++ b/chrome/browser/ui/views/download/bubble/download_bubble_security_view_unittest.cc
@@ -34,7 +34,7 @@ public: explicit MockDownloadBubbleUIController(Browser* browser) : DownloadBubbleUIController(browser) {} - ~MockDownloadBubbleUIController() override = default; + ~MockDownloadBubbleUIController() = default; }; class MockDownloadBubbleNavigationHandler
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 cc8a38a..c89823cf 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
@@ -286,7 +286,7 @@ } bool DownloadToolbarButtonView::IsFullscreenWithParentViewHidden() { - return browser_->window()->IsFullscreen() && + return browser_->window() && browser_->window()->IsFullscreen() && !browser_->window()->IsToolbarVisible(); }
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_mac.mm b/chrome/browser/ui/views/frame/immersive_mode_controller_mac.mm index f655245..6caa6323 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_mac.mm +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_mac.mm
@@ -310,9 +310,6 @@ tab_widget_height_ += static_cast<BrowserNonClientFrameViewMac*>( browser_view->frame()->GetFrameView()) ->GetTopInset(false); - // Without this -1 the tabs sit 1px too high. I assume this is because in - // fullscreen there is no resize handle. - tab_widget_height_ -= 1; // TODO(https://crbug.com/1414521): The |tab_overlay_widget()| draws // underneath the traffic lights via an NSTitlebarViewController with @@ -331,11 +328,16 @@ tab_widget_height_)); browser_view->tab_overlay_widget()->Show(); - // Inset the start of |tab_strip_region_view()| by |kTrafficLightsWidth|. - // This will leave a hole for the traffic light to appear. + // Move the tab strip to the `tab_overlay_widget`, the host of the + // `tab_overlay_view`. browser_view->tab_overlay_view()->AddChildView( browser_view->tab_strip_region_view()); - gfx::Insets insets = gfx::Insets::TLBR(0, kTrafficLightsWidth, 0, 0); + + // Inset the start of |tab_strip_region_view()| by |kTrafficLightsWidth|. + // This will leave a hole for the traffic light to appear. + // Without this +1 top inset the tabs sit 1px too high. I assume this is + // because in fullscreen there is no resize handle. + gfx::Insets insets = gfx::Insets::TLBR(1, kTrafficLightsWidth, 0, 0); browser_view->tab_strip_region_view()->SetBorder( views::CreateEmptyBorder(insets));
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls_bubble_view_browsertest.cc b/chrome/browser/ui/views/location_bar/cookie_controls_bubble_view_browsertest.cc index d871ccfd..d35afb8 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls_bubble_view_browsertest.cc
@@ -46,7 +46,12 @@ } void ShowUi(const std::string& name) override { + content::CookieChangeObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); NavigateToUrlWithThirdPartyCookies(); + if (name == "NotWorkingClicked") { + observer.Wait(); + } ASSERT_TRUE(cookie_controls_icon()->GetVisible()); cookie_controls_icon_->ExecuteForTesting();
diff --git a/chrome/browser/ui/views/site_data/page_specific_site_data_dialog_browsertest.cc b/chrome/browser/ui/views/site_data/page_specific_site_data_dialog_browsertest.cc index 1bf8b5cb..50d0022 100644 --- a/chrome/browser/ui/views/site_data/page_specific_site_data_dialog_browsertest.cc +++ b/chrome/browser/ui/views/site_data/page_specific_site_data_dialog_browsertest.cc
@@ -90,9 +90,14 @@ content::SetupCrossSiteRedirector(https_server()); ASSERT_TRUE(https_server()->Start()); + content::CookieChangeObserver observer( + browser()->tab_strip_model()->GetActiveWebContents(), 2); + // Load a page with cookies. ASSERT_TRUE(ui_test_utils::NavigateToURL( browser(), https_server()->GetURL("a.test", "/cookie1.html"))); + + observer.Wait(); } net::EmbeddedTestServer* https_server() { return https_server_.get(); } @@ -442,10 +447,15 @@ return; } + content::CookieChangeObserver observer( + browser()->tab_strip_model()->GetActiveWebContents(), 8); + ASSERT_TRUE(ui_test_utils::NavigateToURL( browser(), https_server()->GetURL( "a.test", "/third_party_partitioned_cookies.html"))); + observer.Wait(); + auto* dialog = OpenDialog(); ui::ElementContext context = views::ElementTrackerViews::GetContextForWidget(dialog); @@ -502,10 +512,15 @@ prefs::kCookieControlsMode, static_cast<int>(content_settings::CookieControlsMode::kBlockThirdParty)); + content::CookieChangeObserver observer( + browser()->tab_strip_model()->GetActiveWebContents(), 9); + ASSERT_TRUE(ui_test_utils::NavigateToURL( browser(), https_server()->GetURL( "a.test", "/third_party_partitioned_cookies.html"))); + observer.Wait(); + auto* dialog = OpenDialog(); ui::ElementContext context = views::ElementTrackerViews::GetContextForWidget(dialog);
diff --git a/chrome/browser/ui/views/site_data/page_specific_site_data_dialog_interactive_uitest.cc b/chrome/browser/ui/views/site_data/page_specific_site_data_dialog_interactive_uitest.cc index c0e7224..3ca19bb 100644 --- a/chrome/browser/ui/views/site_data/page_specific_site_data_dialog_interactive_uitest.cc +++ b/chrome/browser/ui/views/site_data/page_specific_site_data_dialog_interactive_uitest.cc
@@ -37,6 +37,7 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" #include "net/dns/mock_host_resolver.h" #include "third_party/blink/public/common/features.h" #include "ui/base/interaction/element_identifier.h" @@ -114,12 +115,21 @@ } // Returns a common sequence of setup steps for all tests. - MultiStep NavigateAndOpenDialog(ui::ElementIdentifier section_id) { + MultiStep NavigateAndOpenDialog( + ui::ElementIdentifier section_id, + content::CookieChangeObserver* cookie_observer = nullptr) { const GURL third_party_cookie_page_url = https_server()->GetURL("a.test", GetTestPageRelativeURL()); return Steps( InstrumentTab(kWebContentsElementId), NavigateWebContents(kWebContentsElementId, third_party_cookie_page_url), + Do(base::BindOnce( + [](content::CookieChangeObserver* cookie_observer) { + if (cookie_observer) { + cookie_observer->Wait(); + } + }, + cookie_observer)), PressButton(kLocationIconElementId), PressButton(PageInfoMainView::kCookieButtonElementId), PressButton(PageInfoCookiesContentView::kCookieDialogButton), @@ -189,9 +199,12 @@ IN_PROC_BROWSER_TEST_F(PageSpecificSiteDataDialogInteractiveUiTest, FirstPartyAllowed) { + content::CookieChangeObserver observer( + browser()->tab_strip_model()->GetActiveWebContents(), 6); RunTestSequenceInContext( context(), - NavigateAndOpenDialog(kPageSpecificSiteDataDialogFirstPartySection), + NavigateAndOpenDialog(kPageSpecificSiteDataDialogFirstPartySection, + &observer), // Name the first row in the first-party section. InAnyContext(NameChildView(kPageSpecificSiteDataDialogFirstPartySection, kFirstPartyAllowedRow, 0)), @@ -225,9 +238,12 @@ IN_PROC_BROWSER_TEST_F(PageSpecificSiteDataDialogInteractiveUiTest, ThirdPartyBlocked) { + content::CookieChangeObserver observer( + browser()->tab_strip_model()->GetActiveWebContents(), 6); RunTestSequenceInContext( context(), - NavigateAndOpenDialog(kPageSpecificSiteDataDialogThirdPartySection), + NavigateAndOpenDialog(kPageSpecificSiteDataDialogThirdPartySection, + &observer), // Name the third-party cookies row. InAnyContext(NameChildView(kPageSpecificSiteDataDialogThirdPartySection, kThirdPartyBlockedRow, 2)), @@ -260,9 +276,12 @@ IN_PROC_BROWSER_TEST_F(PageSpecificSiteDataDialogInteractiveUiTest, OnlyPartitionedBlockedThirdPartyCookies) { + content::CookieChangeObserver observer( + browser()->tab_strip_model()->GetActiveWebContents(), 6); RunTestSequenceInContext( context(), - NavigateAndOpenDialog(kPageSpecificSiteDataDialogThirdPartySection), + NavigateAndOpenDialog(kPageSpecificSiteDataDialogThirdPartySection, + &observer), // Find the third party section and name the row with partitioned only // access (b.test). InAnyContext(NameChildView(kPageSpecificSiteDataDialogThirdPartySection, @@ -290,9 +309,12 @@ IN_PROC_BROWSER_TEST_F(PageSpecificSiteDataDialogInteractiveUiTest, MixedPartitionedBlockedThirdPartyCookies) { + content::CookieChangeObserver observer( + browser()->tab_strip_model()->GetActiveWebContents(), 6); RunTestSequenceInContext( context(), - NavigateAndOpenDialog(kPageSpecificSiteDataDialogThirdPartySection), + NavigateAndOpenDialog(kPageSpecificSiteDataDialogThirdPartySection, + &observer), // Find the third party section and name the row with mixed storage // access (c.test). InAnyContext(NameChildView(kPageSpecificSiteDataDialogThirdPartySection,
diff --git a/chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.cc b/chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.cc index bba2de3c..432367d 100644 --- a/chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.cc +++ b/chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.cc
@@ -90,26 +90,6 @@ return browser; } -void IsolatedWebAppBrowserTestHarness::CreateIframe( - content::RenderFrameHost* parent_frame, - const std::string& iframe_id, - const GURL& url, - const std::string& permissions_policy) { - EXPECT_EQ(true, content::EvalJs( - parent_frame, - content::JsReplace(R"( - new Promise(resolve => { - let f = document.createElement('iframe'); - f.id = $1; - f.src = $2; - f.allow = $3; - f.addEventListener('load', () => resolve(true)); - document.body.appendChild(f); - }); - )", - iframe_id, url, permissions_policy))); -} - content::RenderFrameHost* IsolatedWebAppBrowserTestHarness::OpenApp( const AppId& app_id) { return OpenIsolatedWebApp(profile(), app_id); @@ -176,6 +156,25 @@ ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); } +void CreateIframe(content::RenderFrameHost* parent_frame, + const std::string& iframe_id, + const GURL& url, + const std::string& permissions_policy) { + EXPECT_EQ(true, content::EvalJs( + parent_frame, + content::JsReplace(R"( + new Promise(resolve => { + let f = document.createElement('iframe'); + f.id = $1; + f.src = $2; + f.allow = $3; + f.addEventListener('load', () => resolve(true)); + document.body.appendChild(f); + }); + )", + iframe_id, url, permissions_policy))); +} + TestSignedWebBundle::TestSignedWebBundle( std::vector<uint8_t> data, const web_package::SignedWebBundleId& id)
diff --git a/chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h b/chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h index 2266afd..a380cfd 100644 --- a/chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h +++ b/chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h
@@ -75,10 +75,6 @@ WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB); Browser* GetBrowserFromFrame(content::RenderFrameHost* frame); - void CreateIframe(content::RenderFrameHost* parent_frame, - const std::string& iframe_id, - const GURL& url, - const std::string& permissions_policy); }; std::unique_ptr<net::EmbeddedTestServer> CreateAndStartDevServer( @@ -91,6 +87,11 @@ content::RenderFrameHost* OpenIsolatedWebApp(Profile* profile, const AppId& app_id); +void CreateIframe(content::RenderFrameHost* parent_frame, + const std::string& iframe_id, + const GURL& url, + const std::string& permissions_policy); + struct TestSignedWebBundle { TestSignedWebBundle(std::vector<uint8_t> data, const web_package::SignedWebBundleId& id);
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc index 7eb0afbd..e4d2ed8 100644 --- a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc +++ b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
@@ -240,29 +240,32 @@ void UpgradeDetectorImpl::DetectOutdatedInstall() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Time network_time; + base::Time current_time; base::TimeDelta uncertainty; - if (g_browser_process->network_time_tracker()->GetNetworkTime(&network_time, + bool is_network_time = true; + if (g_browser_process->network_time_tracker()->GetNetworkTime(¤t_time, &uncertainty) != network_time::NetworkTimeTracker::NETWORK_TIME_AVAILABLE) { // When network time has not been initialized yet, simply rely on the // machine's current time. - network_time = base::Time::Now(); + is_network_time = false; + current_time = base::Time::Now(); } - if (network_time.is_null() || build_date_.is_null() || - (!simulating_outdated_ && build_date_ > network_time)) { - // TODO(crbug.com/1407664): Figure out why this is failing and either fix it - // and turn the conditional above into a CHECK or document how this can fail - // in the wild and either keep the DumpWithoutCrashing() or remove it. + CHECK(!current_time.is_null()); + CHECK(!build_date_.is_null()); + + if (!simulating_outdated_ && is_network_time && build_date_ > current_time) { base::Time build_date = build_date_; - base::debug::Alias(&network_time); + base::debug::Alias(¤t_time); base::debug::Alias(&build_date); + // TODO(crbug.com/1407664): Once this is shown to no longer be hitting, + // change this to a NOTREACHED_NORETURN(). base::debug::DumpWithoutCrashing(); return; } - if (network_time - build_date_ > kOutdatedBuildAge) { + if (current_time - build_date_ > kOutdatedBuildAge) { UpgradeDetected(is_auto_update_enabled_ ? UPGRADE_NEEDED_OUTDATED_INSTALL : UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU);
diff --git a/chrome/browser/usb/chrome_usb_browsertest.cc b/chrome/browser/usb/chrome_usb_browsertest.cc index 7298628..3d1f42ab 100644 --- a/chrome/browser/usb/chrome_usb_browsertest.cc +++ b/chrome/browser/usb/chrome_usb_browsertest.cc
@@ -652,7 +652,8 @@ content::RenderFrameHost* app_frame = OpenApp(url_info.app_id()); const std::string permissions_policy = ""; - CreateIframe(app_frame, "child", GURL("/index.html"), permissions_policy); + web_app::CreateIframe(app_frame, "child", GURL("/index.html"), + permissions_policy); auto* iframe = ChildFrameAt(app_frame, 0); auto fake_device_info = CreateSmartCardDevice(); @@ -666,7 +667,7 @@ // since it does not specify usb in the allowlist. GURL non_app_url = https_server()->GetURL(kNonAppHost, "/banners/isolated/simple.html"); - CreateIframe(app_frame, "child2", non_app_url, permissions_policy); + web_app::CreateIframe(app_frame, "child2", non_app_url, permissions_policy); iframe = ChildFrameAt(app_frame, 1); EXPECT_THAT(EvalJs(iframe, OpenAndClaimDeviceScript).ExtractString(), @@ -686,7 +687,8 @@ content::RenderFrameHost* app_frame = OpenApp(url_info.app_id()); const std::string permissions_policy = "usb 'self'"; - CreateIframe(app_frame, "child", GURL("/index.html"), permissions_policy); + web_app::CreateIframe(app_frame, "child", GURL("/index.html"), + permissions_policy); auto* iframe = ChildFrameAt(app_frame, 0); auto fake_device_info = CreateSmartCardDevice(); @@ -724,7 +726,7 @@ GURL non_app_url = https_server()->GetURL(kNonAppHost, "/banners/isolated/simple.html"); const std::string permissions_policy = "usb 'src'"; - CreateIframe(app_frame, "child", non_app_url, permissions_policy); + web_app::CreateIframe(app_frame, "child", non_app_url, permissions_policy); auto* iframe = ChildFrameAt(app_frame, 0); auto fake_device_info = CreateSmartCardDevice(); @@ -762,7 +764,8 @@ content::RenderFrameHost* app_frame = OpenApp(url_info.app_id()); const std::string permissions_policy = "usb 'none'"; - CreateIframe(app_frame, "child", GURL("/index.html"), permissions_policy); + web_app::CreateIframe(app_frame, "child", GURL("/index.html"), + permissions_policy); auto* iframe = ChildFrameAt(app_frame, 0); auto fake_device_info = CreateSmartCardDevice(); @@ -792,7 +795,7 @@ https_server()->GetURL(kNonAppHost, "/banners/isolated/simple.html"); const std::string permissions_policy = base::StringPrintf( "usb %s", https_server()->GetURL(kNonAppHost, "/").spec().c_str()); - CreateIframe(app_frame, "child", non_app_url, permissions_policy); + web_app::CreateIframe(app_frame, "child", non_app_url, permissions_policy); auto* iframe = ChildFrameAt(app_frame, 0); auto fake_device_info = CreateSmartCardDevice(); @@ -822,7 +825,7 @@ app_frame = ui_test_utils::NavigateToURL(app_browser, app_url); const std::string permissions_policy = ""; - CreateIframe(app_frame, "child", app_url, permissions_policy); + web_app::CreateIframe(app_frame, "child", app_url, permissions_policy); auto* iframe = ChildFrameAt(app_frame, 0); auto fake_device_info = CreateSmartCardDevice(); @@ -837,7 +840,7 @@ // Create a cross-origin iframe and expect usb to be disabled in that context. GURL non_app_url = https_server()->GetURL( kNonAppHost, "/web_apps/simple_isolated_app/usb_none.html"); - CreateIframe(app_frame, "child2", non_app_url, permissions_policy); + web_app::CreateIframe(app_frame, "child2", non_app_url, permissions_policy); iframe = ChildFrameAt(app_frame, 1); EXPECT_THAT(EvalJs(iframe, OpenAndClaimDeviceScript).ExtractString(), @@ -863,7 +866,7 @@ app_frame = ui_test_utils::NavigateToURL(app_browser, app_url); const std::string permissions_policy = ""; - CreateIframe(app_frame, "child", app_url, permissions_policy); + web_app::CreateIframe(app_frame, "child", app_url, permissions_policy); auto* iframe = ChildFrameAt(app_frame, 0); auto fake_device_info = CreateSmartCardDevice(); @@ -876,7 +879,7 @@ // Create a cross-origin iframe and expect usb to be disabled in that context. GURL non_app_url = https_server()->GetURL( kNonAppHost, "/web_apps/simple_isolated_app/usb_self.html"); - CreateIframe(app_frame, "child2", non_app_url, permissions_policy); + web_app::CreateIframe(app_frame, "child2", non_app_url, permissions_policy); iframe = ChildFrameAt(app_frame, 1); EXPECT_THAT(EvalJs(iframe, OpenAndClaimDeviceScript).ExtractString(), @@ -901,7 +904,7 @@ app_frame = ui_test_utils::NavigateToURL(app_browser, app_url); const std::string permissions_policy = ""; - CreateIframe(app_frame, "child", app_url, permissions_policy); + web_app::CreateIframe(app_frame, "child", app_url, permissions_policy); auto* iframe = ChildFrameAt(app_frame, 0); auto fake_device_info = CreateSmartCardDevice(); @@ -915,7 +918,7 @@ // usb to be enabled in that context. GURL non_app_url = https_server()->GetURL( kNonAppHost, "/web_apps/simple_isolated_app/usb_all.html"); - CreateIframe(app_frame, "child2", non_app_url, "usb"); + web_app::CreateIframe(app_frame, "child2", non_app_url, "usb"); iframe = ChildFrameAt(app_frame, 1); EXPECT_EQ("Success", EvalJs(iframe, OpenAndClaimDeviceScript));
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsertest.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsertest.cc index eec887f..77c0d159 100644 --- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsertest.cc +++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsertest.cc
@@ -409,7 +409,7 @@ content::RenderFrameHost* app_frame = OpenApp(url_info.app_id()); Browser* app_browser = GetBrowserFromFrame(app_frame); app_frame = ui_test_utils::NavigateToURL(app_browser, app_url); - CreateIframe(app_frame, "child", non_app_url, ""); + web_app::CreateIframe(app_frame, "child", non_app_url, ""); const auto& app_cookies = GetCookieHeadersForUrl(app_proxy_url); EXPECT_EQ(1u, app_cookies.size()); @@ -423,7 +423,7 @@ content::RenderFrameHost* app_frame2 = OpenApp(url_info.app_id()); Browser* app_browser2 = GetBrowserFromFrame(app_frame2); app_frame2 = ui_test_utils::NavigateToURL(app_browser2, app_url); - CreateIframe(app_frame2, "child", non_app_url, ""); + web_app::CreateIframe(app_frame2, "child", non_app_url, ""); EXPECT_EQ(2u, app_cookies.size()); EXPECT_TRUE(app_cookies[1].empty());
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index ce0c272..a961e4d 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1679579986-57f8b25fb3eb69479052e852f1209c28d541e85d.profdata +chrome-mac-arm-main-1679587106-e5f9fd8e7367245bbebfa0238f1ab922d38ff078.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 5175f7e..102dace8 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1679572553-303da58159bac9e911605f0fe3dd289efd25a83c.profdata +chrome-win64-main-1679583480-b418af276de905716877ef58e4c2b8ec8b66f8ab.profdata
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 2a73eb9..9fedcfa3 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -674,12 +674,6 @@ // Forces the update menu badge to show. const char kForceShowUpdateMenuBadge[] = "force-show-update-menu-badge"; -// Forces signin FRE flow. -const char kForceEnableSigninFRE[] = "force-enable-signin-fre"; - -// Forces the FRE to go through the legacy sync consent flow for testing. -const char kForceDisableSigninFRE[] = "force-disable-signin-fre"; - // Forces the update menu type to a specific type. const char kForceUpdateMenuType[] = "force-update-menu-type"; @@ -693,6 +687,9 @@ // Sets the market URL for Chrome for use in testing. const char kMarketUrlForTesting[] = "market-url-for-testing"; + +// Force enable user agent overrides to request desktop sites in Clank. +const char kRequestDesktopSites[] = "request-desktop-sites"; #endif // BUILDFLAG(IS_ANDROID) #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index f098b76..704b9dd 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -208,6 +208,7 @@ extern const char kForceUpdateMenuType[]; extern const char kForceHideNonDisplayableAccountEmailFRE[]; extern const char kMarketUrlForTesting[]; +extern const char kRequestDesktopSites[]; #endif // BUILDFLAG(IS_ANDROID) #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/installer/mac/signing/commands.py b/chrome/installer/mac/signing/commands.py index 225717b..ab32b100 100644 --- a/chrome/installer/mac/signing/commands.py +++ b/chrome/installer/mac/signing/commands.py
@@ -71,9 +71,7 @@ def zip(out, path): - shutil.move( - shutil.make_archive('{}.zip.tmp'.format(os.path.basename(out)), 'zip', - path), out) + run_command(['zip', '-9ry', out, '.'], cwd=path) def set_executable(path):
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index cb79a22..12a71f9 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3861,7 +3861,6 @@ "../browser/ash/login/app_mode/test/web_kiosk_base_test.cc", "../browser/ash/login/app_mode/test/web_kiosk_base_test.h", "../browser/ash/login/app_mode/test/web_kiosk_browsertest.cc", - "../browser/ash/login/arc_terms_of_service_browsertest.cc", "../browser/ash/login/ash_hud_login_browsertest.cc", "../browser/ash/login/challenge_response_auth_keys_loader_browsertest.cc", "../browser/ash/login/configuration_based_oobe_browsertest.cc", @@ -3928,8 +3927,6 @@ "../browser/ash/login/screens/lacros_data_migration_screen_browsertest.cc", "../browser/ash/login/screens/management_transition_screen_browsertest.cc", "../browser/ash/login/screens/marketing_opt_in_screen_browsertest.cc", - "../browser/ash/login/screens/mock_arc_terms_of_service_screen.cc", - "../browser/ash/login/screens/mock_arc_terms_of_service_screen.h", "../browser/ash/login/screens/mock_consolidated_consent_screen.cc", "../browser/ash/login/screens/mock_consolidated_consent_screen.h", "../browser/ash/login/screens/mock_demo_preferences_screen.cc", @@ -6662,12 +6659,13 @@ "../browser/fast_checkout/fast_checkout_client_impl_unittest.cc", "../browser/fast_checkout/fast_checkout_personal_data_helper_impl_unittest.cc", "../browser/fast_checkout/fast_checkout_trigger_validator_impl_unittest.cc", + "../browser/fast_checkout/mock_fast_checkout_client.cc", + "../browser/fast_checkout/mock_fast_checkout_client.h", "../browser/feedback/android/family_info_feedback_source_unittest.cc", "../browser/long_screenshots/long_screenshots_tab_service_unittest.cc", "../browser/lookalikes/safety_tip_message_delegate_android_unittest.cc", "../browser/media/android/cdm/media_drm_origin_id_manager_unittest.cc", "../browser/metrics/chrome_android_metrics_provider_unittest.cc", - "../browser/metrics/family_link_user_metrics_provider_unittest.cc", "../browser/notifications/notification_channels_provider_android_unittest.cc", "../browser/optimization_guide/android/optimization_guide_bridge_unittest.cc", "../browser/optimization_guide/android/optimization_guide_tab_url_provider_android_unittest.cc", @@ -9124,6 +9122,11 @@ "//components/supervised_user/core/common", "//components/supervised_user/core/common:buildflags", ] + + if (is_android || is_win || is_mac || is_linux || is_chromeos_lacros) { + sources += + [ "../browser/metrics/family_link_user_metrics_provider_unittest.cc" ] + } } if (safe_browsing_mode == 1 && enable_extensions) { sources += [ "../browser/extensions/blocklist_unittest.cc" ]
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index c9a1671..1c6b7c3c 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -55,7 +55,6 @@ apk_name = "ChromePageControllerTests" sources = [ "javatests/src/org/chromium/chrome/test/pagecontroller/tests/ExampleTest.java", - "javatests/src/org/chromium/chrome/test/pagecontroller/tests/FirstRunControllerTest.java", "javatests/src/org/chromium/chrome/test/pagecontroller/tests/NewTabPageControllerTest.java", "javatests/src/org/chromium/chrome/test/pagecontroller/tests/TabSwitcherControllerTest.java", ]
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/FirstRunControllerTest.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/FirstRunControllerTest.java deleted file mode 100644 index 2499971..0000000 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/FirstRunControllerTest.java +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2019 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.test.pagecontroller.tests; - -import androidx.test.filters.SmallTest; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; -import org.junit.runner.RunWith; - -import org.chromium.base.test.BaseJUnit4ClassRunner; -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; -import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.test.pagecontroller.controllers.first_run.SyncConfirmationViewPageController; -import org.chromium.chrome.test.pagecontroller.controllers.ntp.NewTabPageController; -import org.chromium.chrome.test.pagecontroller.rules.ChromeUiApplicationTestRule; -import org.chromium.chrome.test.pagecontroller.rules.ChromeUiAutomatorTestRule; - -/** - * Test the First Run Experience pre-MICe. The MICe FRE flow is covered by the test - * {@link FirstRunActivitySigninAndSyncTest}. - */ -@SmallTest -@RunWith(BaseJUnit4ClassRunner.class) -@CommandLineFlags.Add({ChromeSwitches.FORCE_DISABLE_SIGNIN_FRE}) -public class FirstRunControllerTest { - public ChromeUiAutomatorTestRule mUiAutomatorRule = new ChromeUiAutomatorTestRule(); - public ChromeUiApplicationTestRule mChromeUiRule = new ChromeUiApplicationTestRule(); - - @Rule - public final TestRule mChain = RuleChain.outerRule(mChromeUiRule).around(mUiAutomatorRule); - - @Rule - public TestRule mCommandLineFlagsRule = CommandLineFlags.getTestRule(); - - @Before - public void setUp() { - mChromeUiRule.launchApplication(); - } - - @DisabledTest(message = "https://crbug.com/1286635") - @Test - public void testFirstRunIsShown() { - Assert.assertTrue("Sync dialog page should be shown.", - SyncConfirmationViewPageController.getInstance().isCurrentPageThis()); - } - - @CommandLineFlags.Add(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE) - @Test - public void testDisableFre() { - Assert.assertTrue(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE + " should work.", - NewTabPageController.getInstance().isCurrentPageThis()); - Assert.assertFalse("Sync dialog page should not be detected.", - SyncConfirmationViewPageController.getInstance().isCurrentPageThis()); - } -}
diff --git a/chrome/test/chromedriver/test/run_webdriver_tests.py b/chrome/test/chromedriver/test/run_webdriver_tests.py index 166acbfc..abb7fa2 100644 --- a/chrome/test/chromedriver/test/run_webdriver_tests.py +++ b/chrome/test/chromedriver/test/run_webdriver_tests.py
@@ -200,7 +200,8 @@ config = { "host": wd_host, "port": wd_port, - "capabilities": wd_capabilities + "capabilities": wd_capabilities, + "timeout_multiplier": 1 } # Port numbers are defined at
diff --git a/chrome/test/data/pdf/BUILD.gn b/chrome/test/data/pdf/BUILD.gn index 6e6fc39c..c994bb1 100644 --- a/chrome/test/data/pdf/BUILD.gn +++ b/chrome/test/data/pdf/BUILD.gn
@@ -83,6 +83,7 @@ deps = [ "../webui:build_ts", "//chrome/browser/resources/pdf:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/js:build_ts", ] }
diff --git a/chrome/test/data/webapps_integration/file_handler/app.js b/chrome/test/data/webapps_integration/file_handler/app.js index 0c095db..cb5ecee7 100644 --- a/chrome/test/data/webapps_integration/file_handler/app.js +++ b/chrome/test/data/webapps_integration/file_handler/app.js
@@ -24,9 +24,8 @@ return element; }; -var resolveLaunchFinished; - var launchFinishedPromise = new Promise(resolve => { + window.addEventListener("load", () => { window.launchQueue.setConsumer(async (launchParams) => { console.log("Launched with: ", launchParams); const viewersContainer = document.getElementById("viewers-container"); @@ -50,5 +49,6 @@ results.push(fileContent.value); } resolve(results); - }) + }); }); +});
diff --git a/chrome/test/data/webapps_integration/file_handler/bar_handler.html b/chrome/test/data/webapps_integration/file_handler/bar_handler.html index 2065c781..dc0816e 100644 --- a/chrome/test/data/webapps_integration/file_handler/bar_handler.html +++ b/chrome/test/data/webapps_integration/file_handler/bar_handler.html
@@ -3,7 +3,7 @@ <head> <title>File Handler - Image Handler</title> <script src="/webapps_integration/test_utils.js"></script> - <script src="/webapps_integration/file_handler/app.js" async></script> + <script src="/webapps_integration/file_handler/app.js"></script> </head> <body> <h1>File Handler - Image Handler</h1>
diff --git a/chrome/test/data/webapps_integration/file_handler/foo_handler.html b/chrome/test/data/webapps_integration/file_handler/foo_handler.html index 6c17882..4a089a6 100644 --- a/chrome/test/data/webapps_integration/file_handler/foo_handler.html +++ b/chrome/test/data/webapps_integration/file_handler/foo_handler.html
@@ -3,7 +3,7 @@ <head> <title>File Handler - Text Handler</title> <script src="/webapps_integration/test_utils.js"></script> - <script src="/webapps_integration/file_handler/app.js" async></script> + <script src="/webapps_integration/file_handler/app.js"></script> </head> <body> <h1>File Handler - Text Handler</h1>
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index b79423f..c27626d 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -417,7 +417,10 @@ ] } - deps = [ "//ui/webui/resources/js:build_ts" ] + deps = [ + "//third_party/polymer/v3_0:library", + "//ui/webui/resources/js:build_ts", + ] if (is_chromeos_ash) { deps += [ "//ash/webui/common/resources:build_ts" ] }
diff --git a/chrome/test/data/webui/app_home/BUILD.gn b/chrome/test/data/webui/app_home/BUILD.gn index 76417ad..39473bc 100644 --- a/chrome/test/data/webui/app_home/BUILD.gn +++ b/chrome/test/data/webui/app_home/BUILD.gn
@@ -18,6 +18,9 @@ [ "chrome://apps/*|" + rebase_path("$root_gen_dir/chrome/browser/resources/app_home/tsc/*", target_gen_dir) ] - ts_deps = [ "//chrome/browser/resources/app_home:build_ts" ] + ts_deps = [ + "//chrome/browser/resources/app_home:build_ts", + "//third_party/polymer/v3_0:library", + ] ts_definitions = [ "//tools/typescript/definitions/metrics_private.d.ts" ] }
diff --git a/chrome/test/data/webui/bookmarks/BUILD.gn b/chrome/test/data/webui/bookmarks/BUILD.gn index 842b351..ca09dc0 100644 --- a/chrome/test/data/webui/bookmarks/BUILD.gn +++ b/chrome/test/data/webui/bookmarks/BUILD.gn
@@ -49,6 +49,7 @@ ] ts_deps = [ "//chrome/browser/resources/bookmarks:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/js:build_ts", ] }
diff --git a/chrome/test/data/webui/chromeos/ash_common/BUILD.gn b/chrome/test/data/webui/chromeos/ash_common/BUILD.gn index 9f066e2..13dc8e40 100644 --- a/chrome/test/data/webui/chromeos/ash_common/BUILD.gn +++ b/chrome/test/data/webui/chromeos/ash_common/BUILD.gn
@@ -25,6 +25,7 @@ deps = [ "../..:build_ts", "//ash/webui/common/resources:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", ]
diff --git a/chrome/test/data/webui/chromeos/emoji_picker/BUILD.gn b/chrome/test/data/webui/chromeos/emoji_picker/BUILD.gn index 95a85cb..8411658 100644 --- a/chrome/test/data/webui/chromeos/emoji_picker/BUILD.gn +++ b/chrome/test/data/webui/chromeos/emoji_picker/BUILD.gn
@@ -12,6 +12,7 @@ target_gen_dir) ] ts_deps = [ "//chrome/browser/resources/chromeos/emoji_picker:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", ]
diff --git a/chrome/test/data/webui/chromeos/personalization_app/BUILD.gn b/chrome/test/data/webui/chromeos/personalization_app/BUILD.gn index ee62547..1396ae7 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/BUILD.gn +++ b/chrome/test/data/webui/chromeos/personalization_app/BUILD.gn
@@ -67,6 +67,7 @@ "../..:build_ts", "//ash/webui/common/resources:build_ts", "//ash/webui/personalization_app/resources:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", "//ui/webui/resources/mojo:build_ts",
diff --git a/chrome/test/data/webui/chromeos/print_management/BUILD.gn b/chrome/test/data/webui/chromeos/print_management/BUILD.gn index 7d20be8..27c94000 100644 --- a/chrome/test/data/webui/chromeos/print_management/BUILD.gn +++ b/chrome/test/data/webui/chromeos/print_management/BUILD.gn
@@ -21,6 +21,7 @@ deps = [ "../..:build_ts", "//ash/webui/print_management/resources:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/js:build_ts", ] }
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/BUILD.gn b/chrome/test/data/webui/chromeos/shortcut_customization/BUILD.gn index 42b7febd..84525e3 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/BUILD.gn +++ b/chrome/test/data/webui/chromeos/shortcut_customization/BUILD.gn
@@ -40,6 +40,7 @@ "../..:build_ts", "//ash/webui/common/resources:build_ts", "//ash/webui/shortcut_customization_ui/resources:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", ]
diff --git a/chrome/test/data/webui/commander/BUILD.gn b/chrome/test/data/webui/commander/BUILD.gn index d81fcf4..07c0f3b 100644 --- a/chrome/test/data/webui/commander/BUILD.gn +++ b/chrome/test/data/webui/commander/BUILD.gn
@@ -18,6 +18,7 @@ target_gen_dir) ] ts_deps = [ "//chrome/browser/resources/commander:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/js:build_ts", ] }
diff --git a/chrome/test/data/webui/cr_components/BUILD.gn b/chrome/test/data/webui/cr_components/BUILD.gn index dd174dcd..21f440b 100644 --- a/chrome/test/data/webui/cr_components/BUILD.gn +++ b/chrome/test/data/webui/cr_components/BUILD.gn
@@ -36,6 +36,7 @@ } ts_deps = [ + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_components/app_management:build_ts", "//ui/webui/resources/cr_components/color_change_listener:build_ts", "//ui/webui/resources/cr_components/customize_themes:build_ts",
diff --git a/chrome/test/data/webui/cr_elements/BUILD.gn b/chrome/test/data/webui/cr_elements/BUILD.gn index a09aa92..9be087b7 100644 --- a/chrome/test/data/webui/cr_elements/BUILD.gn +++ b/chrome/test/data/webui/cr_elements/BUILD.gn
@@ -68,6 +68,7 @@ "//tools/typescript/definitions/settings_private.d.ts", ] ts_deps = [ + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", ]
diff --git a/chrome/test/data/webui/downloads/BUILD.gn b/chrome/test/data/webui/downloads/BUILD.gn index ca20ae1..de58eddd 100644 --- a/chrome/test/data/webui/downloads/BUILD.gn +++ b/chrome/test/data/webui/downloads/BUILD.gn
@@ -20,6 +20,7 @@ target_gen_dir) ] ts_deps = [ "//chrome/browser/resources/downloads:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/js:build_ts", ] }
diff --git a/chrome/test/data/webui/extensions/BUILD.gn b/chrome/test/data/webui/extensions/BUILD.gn index 48a30903..a878dce 100644 --- a/chrome/test/data/webui/extensions/BUILD.gn +++ b/chrome/test/data/webui/extensions/BUILD.gn
@@ -66,6 +66,7 @@ ts_deps = [ "//chrome/browser/resources/extensions:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/js:build_ts", ] ts_definitions = [
diff --git a/chrome/test/data/webui/history/BUILD.gn b/chrome/test/data/webui/history/BUILD.gn index 30ea3914..93760ae 100644 --- a/chrome/test/data/webui/history/BUILD.gn +++ b/chrome/test/data/webui/history/BUILD.gn
@@ -41,6 +41,7 @@ ] ts_deps = [ "//chrome/browser/resources/history:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/js:build_ts", ] }
diff --git a/chrome/test/data/webui/inline_login/BUILD.gn b/chrome/test/data/webui/inline_login/BUILD.gn index 17cfa69..587ec1f 100644 --- a/chrome/test/data/webui/inline_login/BUILD.gn +++ b/chrome/test/data/webui/inline_login/BUILD.gn
@@ -45,6 +45,7 @@ ts_deps = [ "//chrome/browser/resources/inline_login:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/js:build_ts", ] }
diff --git a/chrome/test/data/webui/js/BUILD.gn b/chrome/test/data/webui/js/BUILD.gn index dfd55e4..2aa7dd9 100644 --- a/chrome/test/data/webui/js/BUILD.gn +++ b/chrome/test/data/webui/js/BUILD.gn
@@ -21,6 +21,7 @@ ] ts_definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ] ts_deps = [ + "//third_party/polymer/v3_0:library", "//ui/webui/resources/js:build_ts", "//ui/webui/resources/mojo:build_ts", ]
diff --git a/chrome/test/data/webui/new_tab_page/BUILD.gn b/chrome/test/data/webui/new_tab_page/BUILD.gn index 3b8dceb..ac2b4926 100644 --- a/chrome/test/data/webui/new_tab_page/BUILD.gn +++ b/chrome/test/data/webui/new_tab_page/BUILD.gn
@@ -41,6 +41,7 @@ ts_deps = [ "//chrome/browser/resources/new_tab_page:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_components/customize_themes:build_ts", "//ui/webui/resources/cr_components/help_bubble:build_ts", "//ui/webui/resources/cr_components/history_clusters:build_ts",
diff --git a/chrome/test/data/webui/password_manager/BUILD.gn b/chrome/test/data/webui/password_manager/BUILD.gn index fb2c145..3c2c6a027 100644 --- a/chrome/test/data/webui/password_manager/BUILD.gn +++ b/chrome/test/data/webui/password_manager/BUILD.gn
@@ -35,6 +35,7 @@ ts_deps = [ "//chrome/browser/resources/password_manager:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/js:build_ts", ]
diff --git a/chrome/test/data/webui/print_preview/BUILD.gn b/chrome/test/data/webui/print_preview/BUILD.gn index 2062a4bb..59d2b12 100644 --- a/chrome/test/data/webui/print_preview/BUILD.gn +++ b/chrome/test/data/webui/print_preview/BUILD.gn
@@ -97,6 +97,7 @@ ts_deps = [ "//chrome/browser/resources/pdf:build_ts", "//chrome/browser/resources/print_preview:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", ]
diff --git a/chrome/test/data/webui/privacy_sandbox/BUILD.gn b/chrome/test/data/webui/privacy_sandbox/BUILD.gn index b54261a..9c2dfcae 100644 --- a/chrome/test/data/webui/privacy_sandbox/BUILD.gn +++ b/chrome/test/data/webui/privacy_sandbox/BUILD.gn
@@ -15,6 +15,7 @@ target_gen_dir) ] ts_deps = [ "//chrome/browser/resources/privacy_sandbox:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", ]
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn index eef1306..ccffcfd 100644 --- a/chrome/test/data/webui/settings/BUILD.gn +++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -17,6 +17,7 @@ "about_page_tests.ts", "advanced_page_test.ts", "all_sites_tests.ts", + "anti_abuse_page_test.ts", "appearance_fonts_page_test.ts", "appearance_page_test.ts", "autofill_page_test.ts", @@ -230,6 +231,7 @@ ts_tsconfig_base = "tsconfig_base.json" ts_deps = [ "//chrome/browser/resources/settings:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/js:build_ts", ] }
diff --git a/chrome/test/data/webui/settings/anti_abuse_page_test.ts b/chrome/test/data/webui/settings/anti_abuse_page_test.ts new file mode 100644 index 0000000..85b3a183 --- /dev/null +++ b/chrome/test/data/webui/settings/anti_abuse_page_test.ts
@@ -0,0 +1,131 @@ +// 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. + +// clang-format off +import 'chrome://settings/lazy_load.js'; + +import {ContentSetting, ContentSettingProvider, ContentSettingsTypes, SettingsAntiAbusePageElement, SiteSettingsPrefsBrowserProxyImpl} from 'chrome://settings/lazy_load.js'; +import {assertEquals, assertNotEquals, assertTrue, assertFalse} from 'chrome://webui-test/chai_assert.js'; +import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; + +import {TestSiteSettingsPrefsBrowserProxy} from './test_site_settings_prefs_browser_proxy.js'; +import {createContentSettingTypeToValuePair, createSiteSettingsPrefs, SiteSettingsPref} from './test_util.js'; +// clang-format on + +/** @fileoverview Suite of tests for settings-anti-abuse-page. */ +suite('SettingsAntiAbusePage', function() { + /** + * A settings-anti-abuse-page created before each test. + */ + let testElement: SettingsAntiAbusePageElement; + + /** + * The mock proxy object to use during test. + */ + let browserProxy: TestSiteSettingsPrefsBrowserProxy; + + // Initialize a settings-anti-abuse-page before each test. + setup(function() { + browserProxy = new TestSiteSettingsPrefsBrowserProxy(); + SiteSettingsPrefsBrowserProxyImpl.setInstance(browserProxy); + document.body.innerHTML = window.trustedTypes!.emptyHTML; + testElement = document.createElement('settings-anti-abuse-page'); + document.body.appendChild(testElement); + }); + + /** + * @param contentSetting The preference content setting. + * @return The created preference object. + */ + function createAntiAbusePref(contentSetting: ContentSetting): + SiteSettingsPref { + return createSiteSettingsPrefs( + [ + createContentSettingTypeToValuePair( + ContentSettingsTypes.ANTI_ABUSE, {setting: contentSetting}), + ], + []); + } + /** + * Verifies that the widget works as expected for a given |category|, + * initial |prefs|, and given expectations. + */ + async function testCategoryEnabled( + element: SettingsAntiAbusePageElement, + proxy: TestSiteSettingsPrefsBrowserProxy, prefs: SiteSettingsPref, + expectedEnabled: boolean) { + proxy.reset(); + proxy.setPrefs(prefs); + + const toggleElement = element.$.toggleButton; + + let category = await proxy.whenCalled('getDefaultValueForContentType'); + let categoryEnabled = toggleElement.checked; + assertEquals(category, ContentSettingsTypes.ANTI_ABUSE); + assertEquals(expectedEnabled, categoryEnabled); + assertFalse(toggleElement.disabled); + + + // Click the toggle and verify that the preference value is + // updated correctly. + proxy.resetResolver('setDefaultValueForContentType'); + toggleElement.click(); + + let setting; + [category, setting] = + await proxy.whenCalled('setDefaultValueForContentType'); + + const oppositeSetting = + expectedEnabled ? ContentSetting.BLOCK : ContentSetting.ALLOW; + categoryEnabled = toggleElement.checked; + assertEquals(category, ContentSettingsTypes.ANTI_ABUSE); + assertEquals(oppositeSetting, setting); + assertNotEquals(expectedEnabled, categoryEnabled); + + // Click the toggle again and verify that the preference value + // is set back to the initial state. + proxy.resetResolver('setDefaultValueForContentType'); + toggleElement.click(); + + [category, setting] = + await proxy.whenCalled('setDefaultValueForContentType'); + const initialSetting = + expectedEnabled ? ContentSetting.ALLOW : ContentSetting.BLOCK; + categoryEnabled = toggleElement.checked; + assertEquals(category, ContentSettingsTypes.ANTI_ABUSE); + assertEquals(initialSetting, setting); + assertEquals(expectedEnabled, categoryEnabled); + } + + test('allow anti_abuse disable click triggers update', async function() { + const enabledPref = createAntiAbusePref(ContentSetting.ALLOW); + await testCategoryEnabled(testElement, browserProxy, enabledPref, true); + }); + + + test('toggle is disabled when pref is enforced', async function() { + const enforcedPrefs = createSiteSettingsPrefs( + [createContentSettingTypeToValuePair(ContentSettingsTypes.ANTI_ABUSE, { + setting: ContentSetting.BLOCK, + source: ContentSettingProvider.EXTENSION, + })], + []); + browserProxy.reset(); + browserProxy.setPrefs(enforcedPrefs); + const toggleElement = testElement.$.toggleButton; + + await browserProxy.whenCalled('getDefaultValueForContentType'); + assertFalse(toggleElement.checked); + assertTrue(toggleElement.disabled); + + // Stop enforcement. + const enabledPref = createAntiAbusePref(ContentSetting.ALLOW); + browserProxy.reset(); + browserProxy.setPrefs(enabledPref); + + await flushTasks(); + assertTrue(toggleElement.checked); + assertFalse(toggleElement.disabled); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index 35b831ac..15a9763d 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -251,6 +251,7 @@ "//ash/webui/common/resources:build_ts", "//chrome/browser/resources/settings/chromeos:build_ts", "//chrome/test/data/webui:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_components/app_management:build_ts", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts",
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index a7458e72..6fd10595 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -887,6 +887,7 @@ 'SettingsCategoryDefaultRadioGroup', 'settings_category_default_radio_group_tests.js', ], + ['AntiAbusePage', 'anti_abuse_page_test.js'], ['CategoryDefaultSetting', 'category_default_setting_tests.js'], ['CategorySettingExceptions', 'category_setting_exceptions_tests.js'], ['Checkbox', 'checkbox_tests.js'],
diff --git a/chrome/test/data/webui/settings/test_util.ts b/chrome/test/data/webui/settings/test_util.ts index bd2a239f6..027caeb 100644 --- a/chrome/test/data/webui/settings/test_util.ts +++ b/chrome/test/data/webui/settings/test_util.ts
@@ -119,6 +119,7 @@ defaults[ContentSettingsTypes[type as keyof typeof ContentSettingsTypes]] = createDefaultContentSetting({}); } + defaults[ContentSettingsTypes.ANTI_ABUSE].setting = ContentSetting.ALLOW; defaults[ContentSettingsTypes.COOKIES].setting = ContentSetting.ALLOW; defaults[ContentSettingsTypes.IMAGES].setting = ContentSetting.ALLOW; defaults[ContentSettingsTypes.JAVASCRIPT].setting = ContentSetting.ALLOW;
diff --git a/chrome/test/data/webui/side_panel/BUILD.gn b/chrome/test/data/webui/side_panel/BUILD.gn index c62fd91..8b2d6700 100644 --- a/chrome/test/data/webui/side_panel/BUILD.gn +++ b/chrome/test/data/webui/side_panel/BUILD.gn
@@ -56,6 +56,7 @@ "//chrome/browser/resources/side_panel/read_anything:build_ts", "//chrome/browser/resources/side_panel/reading_list:build_ts", "//chrome/browser/resources/side_panel/user_notes:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_components/image_service:build_ts", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts",
diff --git a/chrome/test/data/webui/side_panel/customize_chrome/BUILD.gn b/chrome/test/data/webui/side_panel/customize_chrome/BUILD.gn index 758d1a7..2451ee6 100644 --- a/chrome/test/data/webui/side_panel/customize_chrome/BUILD.gn +++ b/chrome/test/data/webui/side_panel/customize_chrome/BUILD.gn
@@ -31,6 +31,7 @@ ts_definitions = [ "//tools/typescript/definitions/metrics_private.d.ts" ] ts_deps = [ "//chrome/browser/resources/side_panel/customize_chrome:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_components/help_bubble:build_ts", "//ui/webui/resources/cr_components/managed_dialog:build_ts", "//ui/webui/resources/cr_elements:build_ts",
diff --git a/chrome/test/data/webui/signin/BUILD.gn b/chrome/test/data/webui/signin/BUILD.gn index d15b7b2..2ebab9b8 100644 --- a/chrome/test/data/webui/signin/BUILD.gn +++ b/chrome/test/data/webui/signin/BUILD.gn
@@ -68,6 +68,7 @@ ts_deps = [ "//chrome/browser/resources/signin:build_ts", "//chrome/browser/resources/signin/profile_picker:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", ]
diff --git a/chrome/test/data/webui/support_tool/BUILD.gn b/chrome/test/data/webui/support_tool/BUILD.gn index ab548faa..0ed2b99c 100644 --- a/chrome/test/data/webui/support_tool/BUILD.gn +++ b/chrome/test/data/webui/support_tool/BUILD.gn
@@ -17,6 +17,7 @@ target_gen_dir) ] ts_deps = [ "//chrome/browser/resources/support_tool:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", ]
diff --git a/chrome/test/data/webui/tab_search/BUILD.gn b/chrome/test/data/webui/tab_search/BUILD.gn index d409358..74a960a 100644 --- a/chrome/test/data/webui/tab_search/BUILD.gn +++ b/chrome/test/data/webui/tab_search/BUILD.gn
@@ -31,6 +31,7 @@ ] ts_deps = [ "//chrome/browser/resources/tab_search:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/js:build_ts", "//ui/webui/resources/mojo:build_ts", ]
diff --git a/chrome/test/data/webui/welcome/BUILD.gn b/chrome/test/data/webui/welcome/BUILD.gn index 8194291..c3e18b1 100644 --- a/chrome/test/data/webui/welcome/BUILD.gn +++ b/chrome/test/data/webui/welcome/BUILD.gn
@@ -35,6 +35,7 @@ ts_definitions = [ "//tools/typescript/definitions/bookmarks.d.ts" ] ts_deps = [ "//chrome/browser/resources/welcome:build_ts", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", ]
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index a71c63f0..8571b13 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -15392.0.0 \ No newline at end of file +15393.0.0 \ No newline at end of file
diff --git a/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl.cc b/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl.cc index 9da38a1..4835e86a 100644 --- a/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl.cc +++ b/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl.cc
@@ -271,6 +271,13 @@ NotifyRecentAppsViewUiStateUpdated(); return; } + + if (features::IsEcheNetworkConnectionStateEnabled()) { + ui_state_ = GetUiStateFromConnectionStatus(); + NotifyRecentAppsViewUiStateUpdated(); + return; + } + if (recent_app_metadata_list_.empty()) { bool notifications_enabled = multidevice_setup_client_->GetFeatureState( @@ -282,11 +289,6 @@ ui_state_ = RecentAppsUiState::PLACEHOLDER_VIEW; } } else { - if (features::IsEcheNetworkConnectionStateEnabled()) { - ui_state_ = GetUiStateFromConnectionStatus(); - NotifyRecentAppsViewUiStateUpdated(); - return; - } ui_state_ = RecentAppsUiState::ITEMS_VISIBLE; } NotifyRecentAppsViewUiStateUpdated();
diff --git a/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc b/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc index f2f2eb5b..af418d1 100644 --- a/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc +++ b/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc
@@ -588,7 +588,7 @@ SetAppsAccessStatus(true); SetNotificationAccess(true); - EXPECT_EQ(RecentAppsInteractionHandler::RecentAppsUiState::PLACEHOLDER_VIEW, + EXPECT_EQ(RecentAppsInteractionHandler::RecentAppsUiState::LOADING, handler().ui_state()); } @@ -599,34 +599,34 @@ SetAppsAccessStatus(true); SetNotificationAccess(true); - EXPECT_EQ(RecentAppsInteractionHandler::RecentAppsUiState::PLACEHOLDER_VIEW, + EXPECT_EQ(RecentAppsInteractionHandler::RecentAppsUiState::LOADING, handler().ui_state()); - // Disable notification access permission on the host device. - SetNotificationAccess(false); + // Disable apps access permission on the host device. + SetAppsAccessStatus(false); EXPECT_EQ(RecentAppsInteractionHandler::RecentAppsUiState::HIDDEN, handler().ui_state()); - // Disable notification access permission on the local device. - SetNotificationAccess(true); - SetPhoneHubNotificationsFeatureState(FeatureState::kDisabledByUser); + // Disable apps access permission on the local device. + SetAppsAccessStatus(true); + SetEcheFeatureState(FeatureState::kDisabledByUser); EXPECT_EQ(RecentAppsInteractionHandler::RecentAppsUiState::HIDDEN, handler().ui_state()); - // Disable notification access permission on both devices. - SetNotificationAccess(false); - SetPhoneHubNotificationsFeatureState(FeatureState::kDisabledByUser); + // Disable apps access permission on both devices. + SetAppsAccessStatus(false); + SetEcheFeatureState(FeatureState::kDisabledByUser); EXPECT_EQ(RecentAppsInteractionHandler::RecentAppsUiState::HIDDEN, handler().ui_state()); - // Enable notification access permission back on both devices. - SetNotificationAccess(true); - SetPhoneHubNotificationsFeatureState(FeatureState::kEnabledByUser); + // Enable apps access permission back on both devices. + SetAppsAccessStatus(true); + SetEcheFeatureState(FeatureState::kEnabledByUser); - EXPECT_EQ(RecentAppsInteractionHandler::RecentAppsUiState::PLACEHOLDER_VIEW, + EXPECT_EQ(RecentAppsInteractionHandler::RecentAppsUiState::LOADING, handler().ui_state()); } @@ -693,6 +693,11 @@ TEST_F(RecentAppsInteractionHandlerTest, UiStateChangedToVisibleWhenRecentAppBeAdded) { + feature_list_.Reset(); + feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kEcheSWA}, + /*disabled_features=*/{features::kEcheNetworkConnectionState}); + SetEcheFeatureState(FeatureState::kEnabledByUser); SetPhoneHubNotificationsFeatureState(FeatureState::kEnabledByUser); SetConnectionStatus(ConnectionStatus::kConnectionStatusConnected);
diff --git a/chromeos/ash/services/auth_factor_config/auth_factor_config.cc b/chromeos/ash/services/auth_factor_config/auth_factor_config.cc index d4a9f32f..42d085f2 100644 --- a/chromeos/ash/services/auth_factor_config/auth_factor_config.cc +++ b/chromeos/ash/services/auth_factor_config/auth_factor_config.cc
@@ -41,11 +41,6 @@ void AuthFactorConfig::IsSupported(const std::string& auth_token, mojom::AuthFactor factor, base::OnceCallback<void(bool)> callback) { - if (!features::IsCryptohomeRecoveryEnabled()) { - std::move(callback).Run(false); - return; - } - const auto* user = ::user_manager::UserManager::Get()->GetPrimaryUser(); auto* user_context = quick_unlock_storage_->GetUserContext(user, auth_token); if (!user_context) { @@ -53,25 +48,33 @@ std::move(callback).Run(false); return; } + const cryptohome::AuthFactorsSet cryptohome_supported_factors = + user_context->GetAuthFactorsConfiguration().get_supported_factors(); - const bool is_supported_by_cryptohome = - user_context->GetAuthFactorsConfiguration().get_supported_factors().Has( - cryptohome::AuthFactorType::kRecovery); - std::move(callback).Run(is_supported_by_cryptohome); + switch (factor) { + case mojom::AuthFactor::kRecovery: { + if (!features::IsCryptohomeRecoveryEnabled()) { + std::move(callback).Run(false); + return; + } + + std::move(callback).Run(cryptohome_supported_factors.Has( + cryptohome::AuthFactorType::kRecovery)); + return; + } + case mojom::AuthFactor::kPin: { + std::move(callback).Run( + cryptohome_supported_factors.Has(cryptohome::AuthFactorType::kPin)); + return; + } + } + + NOTREACHED(); } void AuthFactorConfig::IsConfigured(const std::string& auth_token, mojom::AuthFactor factor, base::OnceCallback<void(bool)> callback) { - DCHECK(features::IsCryptohomeRecoveryEnabled()); - - if (factor != mojom::AuthFactor::kRecovery) { - LOG(ERROR) << "AuthFactorConfig::IsConfigured supports recovery only"; - NOTIMPLEMENTED(); - std::move(callback).Run(false); - return; - } - const auto* user = ::user_manager::UserManager::Get()->GetPrimaryUser(); auto* user_context = quick_unlock_storage_->GetUserContext(user, auth_token); if (!user_context) { @@ -79,11 +82,23 @@ std::move(callback).Run(false); return; } - const auto& config = user_context->GetAuthFactorsConfiguration(); - const bool is_configured = - config.HasConfiguredFactor(cryptohome::AuthFactorType::kRecovery); - std::move(callback).Run(is_configured); + + switch (factor) { + case mojom::AuthFactor::kRecovery: { + DCHECK(features::IsCryptohomeRecoveryEnabled()); + std::move(callback).Run( + config.HasConfiguredFactor(cryptohome::AuthFactorType::kRecovery)); + return; + } + case mojom::AuthFactor::kPin: { + std::move(callback).Run( + config.HasConfiguredFactor(cryptohome::AuthFactorType::kPin)); + return; + } + } + + NOTREACHED(); } void AuthFactorConfig::GetManagementType( @@ -125,6 +140,8 @@ return; } } + + NOTREACHED(); } void AuthFactorConfig::IsEditable(const std::string& auth_token, @@ -176,6 +193,8 @@ return; } } + + NOTREACHED(); } } // namespace ash::auth
diff --git a/components/browser_sync/sync_api_component_factory_impl.cc b/components/browser_sync/sync_api_component_factory_impl.cc index f729c35..340b9f6 100644 --- a/components/browser_sync/sync_api_component_factory_impl.cc +++ b/components/browser_sync/sync_api_component_factory_impl.cc
@@ -300,10 +300,11 @@ if (base::FeatureList::IsEnabled(syncer::kSyncAutofillWalletUsageData) && !disabled_types.Has(syncer::AUTOFILL_WALLET_DATA) && !disabled_types.Has(syncer::AUTOFILL_WALLET_USAGE)) { - controllers.push_back(CreateWalletModelTypeController( - syncer::AUTOFILL_WALLET_USAGE, - base::BindRepeating(&AutofillWalletUsageDataDelegateFromDataService), - sync_service)); + controllers.push_back( + CreateWalletModelTypeControllerWithInMemorySupport( + syncer::AUTOFILL_WALLET_USAGE, + base::BindRepeating(&AutofillWalletUsageDataDelegateFromDataService), + sync_service)); } }
diff --git a/components/browsing_data/core/BUILD.gn b/components/browsing_data/core/BUILD.gn index 02996e5..96d8ed0e 100644 --- a/components/browsing_data/core/BUILD.gn +++ b/components/browsing_data/core/BUILD.gn
@@ -48,12 +48,24 @@ } if (is_android) { - java_cpp_enum("browsing_data_utils_java") { + java_cpp_enum("browsing_data_utils_javagen") { + # External code should depend on ":java" instead. + visibility = [ ":*" ] sources = [ "browsing_data_utils.h" ] } - java_cpp_enum("clear_browsing_data_tab_java") { + java_cpp_enum("clear_browsing_data_tab_javagen") { + # External code should depend on ":java" instead. + visibility = [ ":*" ] sources = [ "clear_browsing_data_tab.h" ] } + + android_library("java") { + srcjar_deps = [ + ":browsing_data_utils_javagen", + ":clear_browsing_data_tab_javagen", + ] + deps = [ "//third_party/androidx:androidx_annotation_annotation_java" ] + } } source_set("unit_tests") {
diff --git a/components/browsing_data/core/browsing_data_utils.h b/components/browsing_data/core/browsing_data_utils.h index 7115388..26b7488 100644 --- a/components/browsing_data/core/browsing_data_utils.h +++ b/components/browsing_data/core/browsing_data_utils.h
@@ -52,6 +52,11 @@ // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. +// +// Must be kept in sync with the ClearBrowsingDataAction in enums.xml. +// +// A Java counterpart will be generated for this enum. +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.browsing_data enum class ClearBrowsingDataAction { kClearBrowsingDataDialog = 0, kClearBrowsingDataOnExit = 1,
diff --git a/components/exo/wayland/protocol/aura-shell.xml b/components/exo/wayland/protocol/aura-shell.xml index ad52889..c262516 100644 --- a/components/exo/wayland/protocol/aura-shell.xml +++ b/components/exo/wayland/protocol/aura-shell.xml
@@ -1188,7 +1188,7 @@ </request> </interface> - <interface name="zaura_output_manager" version="1"> + <interface name="zaura_output_manager" version="2"> <description summary="aura shell interface to the output manager"> A global responsible for ensuring clients have a complete view of a given output's state immediately following the bind of wl_output, and @@ -1347,5 +1347,14 @@ <arg name="output" type="object" interface="wl_output" /> <arg name="description" type="string" summary="output description" /> </event> + + <!-- Version 2 additions --> + <event name="activated" since="2"> + <description summary="target display for new windows"> + Notifies that this output is now active output. It is typically used as + a target when a new window is created without specific bounds. + </description> + <arg name="output" type="object" interface="wl_output" /> + </event> </interface> </protocol>
diff --git a/components/exo/wayland/wayland_display_observer.cc b/components/exo/wayland/wayland_display_observer.cc index d48156e..a055aa6 100644 --- a/components/exo/wayland/wayland_display_observer.cc +++ b/components/exo/wayland/wayland_display_observer.cc
@@ -201,7 +201,12 @@ return true; } -void WaylandDisplayHandler::SendActiveDisplay() {} +void WaylandDisplayHandler::SendActiveDisplay() { + wl_client* client = wl_resource_get_client(output_resource_); + if (auto* output_manager = AuraOutputManager::Get(client)) { + output_manager->SendOutputActivated(output_resource_); + } +} void WaylandDisplayHandler::OnOutputDestroyed() { // destroying itself.
diff --git a/components/exo/wayland/zaura_output_manager.cc b/components/exo/wayland/zaura_output_manager.cc index 9eb32e8b..ec3f0b5 100644 --- a/components/exo/wayland/zaura_output_manager.cc +++ b/components/exo/wayland/zaura_output_manager.cc
@@ -110,6 +110,14 @@ return true; } +void AuraOutputManager::SendOutputActivated(wl_resource* output_resource) { + if (wl_resource_get_version(manager_resource_) >= + ZAURA_OUTPUT_MANAGER_ACTIVATED_SINCE_VERSION) { + CHECK_EQ(client_, wl_resource_get_client(output_resource)); + zaura_output_manager_send_activated(manager_resource_, output_resource); + } +} + void bind_aura_output_manager(wl_client* client, void* data, uint32_t version,
diff --git a/components/exo/wayland/zaura_output_manager.h b/components/exo/wayland/zaura_output_manager.h index be3a7c6..86c487d 100644 --- a/components/exo/wayland/zaura_output_manager.h +++ b/components/exo/wayland/zaura_output_manager.h
@@ -44,6 +44,10 @@ const display::Display& display, uint32_t changed_metrics); + // Dispatches the activated event for the `output_resource` to the associated + // client. + void SendOutputActivated(wl_resource* output_resource); + private: raw_ptr<wl_client> client_; raw_ptr<wl_resource> manager_resource_;
diff --git a/components/history_clusters/core/config.cc b/components/history_clusters/core/config.cc index d1de7c6..56e59580 100644 --- a/components/history_clusters/core/config.cc +++ b/components/history_clusters/core/config.cc
@@ -82,6 +82,10 @@ labels_from_entities = GetFieldTrialParamByFeatureAsBool( internal::kJourneysLabels, "labels_from_entities", labels_from_entities); + + labels_from_search_visit_entities = GetFieldTrialParamByFeatureAsBool( + internal::kJourneysLabels, "labels_from_search_visit_entities", + labels_from_search_visit_entities); } // The `kJourneysImages` feature. @@ -280,6 +284,10 @@ content_clustering_enabled = base::FeatureList::IsEnabled( features::kOnDeviceClusteringContentClustering); + content_clustering_search_visits_only = GetFieldTrialParamByFeatureAsBool( + features::kOnDeviceClusteringContentClustering, "search_visits_only", + content_clustering_search_visits_only); + content_clustering_similarity_threshold = GetFieldTrialParamByFeatureAsDouble( features::kOnDeviceClusteringContentClustering,
diff --git a/components/history_clusters/core/config.h b/components/history_clusters/core/config.h index 01f9d3e..72a5730 100644 --- a/components/history_clusters/core/config.h +++ b/components/history_clusters/core/config.h
@@ -79,6 +79,11 @@ // Does nothing if `should_label_clusters` is false. bool labels_from_entities = false; + // Whether to assign labels to clusters from the entities associated with + // search visits within a cluster if there are multiple search visits for the + // cluster. + bool labels_from_search_visit_entities = false; + // The `kJourneysImages` feature and child params. // Whether to attempt to provide images for eligible Journeys (so far just @@ -280,6 +285,10 @@ // should be performed by the clustering backend. bool content_clustering_enabled = false; + // Returns whether content clustering should only be done across clusters that + // contain a search. + bool content_clustering_search_visits_only = false; + // Returns the similarity threshold, between 0 and 1, used to determine if // two clusters are similar enough to be combined into // a single cluster.
diff --git a/components/history_clusters/core/content_annotations_cluster_processor.cc b/components/history_clusters/core/content_annotations_cluster_processor.cc index 1bfbeec..cba31c8d 100644 --- a/components/history_clusters/core/content_annotations_cluster_processor.cc +++ b/components/history_clusters/core/content_annotations_cluster_processor.cc
@@ -249,6 +249,11 @@ const history::Cluster& cluster) { base::flat_map<std::string, float> occurrence_map; for (const auto& visit : cluster.visits) { + if (GetConfig().content_clustering_search_visits_only && + visit.annotated_visit.content_annotations.search_terms.empty()) { + continue; + } + for (const auto& entity : visit.annotated_visit.content_annotations.model_annotations.entities) { auto entity_metadata_it =
diff --git a/components/history_clusters/core/content_annotations_cluster_processor_unittest.cc b/components/history_clusters/core/content_annotations_cluster_processor_unittest.cc index 8320578..4a64483 100644 --- a/components/history_clusters/core/content_annotations_cluster_processor_unittest.cc +++ b/components/history_clusters/core/content_annotations_cluster_processor_unittest.cc
@@ -237,5 +237,96 @@ ElementsAre(testing::VisitResult(10, 1.0)))); } +class ContentAnnotationsSearchVisitsOnlyTest + : public ContentAnnotationsClusterProcessorTest { + public: + ContentAnnotationsSearchVisitsOnlyTest() { + config_.content_clustering_enabled = true; + config_.content_clustering_search_visits_only = true; + SetConfigForTesting(config_); + } + + private: + Config config_; +}; + +TEST_F(ContentAnnotationsSearchVisitsOnlyTest, + NoSearchVisitsShouldNotBeClustered) { + std::vector<history::Cluster> clusters; + + history::AnnotatedVisit visit = + testing::CreateDefaultAnnotatedVisit(1, GURL("https://github.com/")); + visit.content_annotations.model_annotations.entities = {{"github", 1}}; + history::AnnotatedVisit visit2 = + testing::CreateDefaultAnnotatedVisit(2, GURL("https://google.com/")); + visit2.content_annotations.model_annotations.entities = {{"baz", 1}}; + history::AnnotatedVisit visit4 = + testing::CreateDefaultAnnotatedVisit(4, GURL("https://github.com/")); + visit4.content_annotations.model_annotations.entities = {{"otherentity", 1}}; + history::Cluster cluster1; + cluster1.visits = {testing::CreateClusterVisit(visit), + testing::CreateClusterVisit(visit2), + testing::CreateClusterVisit(visit4)}; + clusters.push_back(cluster1); + + // After the context clustering, visit5 will not be in the same cluster as + // visit, visit2, and visit4. Although 2/3 of the entities are the same as the + // first cluster, they are not compliant with the configuration. Hence, the + // bag for visit5 will be empty and this cluster will not be merged. + history::AnnotatedVisit visit5 = testing::CreateDefaultAnnotatedVisit( + 10, GURL("https://nonexistentreferrer.com/")); + visit5.content_annotations.model_annotations.entities = {{"otherentity", 1}, + {"baz", 1}}; + history::Cluster cluster2; + cluster2.visits = {testing::CreateClusterVisit(visit5)}; + clusters.push_back(cluster2); + + ProcessClusters(&clusters); + EXPECT_THAT(testing::ToVisitResults(clusters), + ElementsAre(ElementsAre(testing::VisitResult(1, 1.0), + testing::VisitResult(2, 1.0), + testing::VisitResult(4, 1.0)), + ElementsAre(testing::VisitResult(10, 1.0)))); +} + +TEST_F(ContentAnnotationsSearchVisitsOnlyTest, SearchVisitsShouldBeClustered) { + std::vector<history::Cluster> clusters; + + history::AnnotatedVisit visit = + testing::CreateDefaultAnnotatedVisit(1, GURL("https://github.com/")); + visit.content_annotations.model_annotations.entities = {{"github", 1}}; + history::AnnotatedVisit visit2 = + testing::CreateDefaultAnnotatedVisit(2, GURL("https://google.com/")); + visit2.content_annotations.model_annotations.entities = {{"baz", 1}}; + history::AnnotatedVisit visit4 = + testing::CreateDefaultAnnotatedVisit(4, GURL("https://github.com/")); + visit4.content_annotations.model_annotations.entities = {{"otherentity", 1}}; + visit4.content_annotations.search_terms = u"some search"; + history::Cluster cluster1; + cluster1.visits = {testing::CreateClusterVisit(visit), + testing::CreateClusterVisit(visit2), + testing::CreateClusterVisit(visit4)}; + clusters.push_back(cluster1); + + // After the context clustering, visit5 will not be in the same cluster as + // visit, visit2, and visit4. 1/2 of the entities overlap across search visits + // and should be merged. + history::AnnotatedVisit visit5 = testing::CreateDefaultAnnotatedVisit( + 10, GURL("https://nonexistentreferrer.com/")); + visit5.content_annotations.model_annotations.entities = {{"otherentity", 1}, + {"baz", 1}}; + visit5.content_annotations.search_terms = u"some other search"; + history::Cluster cluster2; + cluster2.visits = {testing::CreateClusterVisit(visit5)}; + clusters.push_back(cluster2); + + ProcessClusters(&clusters); + EXPECT_THAT(testing::ToVisitResults(clusters), + ElementsAre(ElementsAre( + testing::VisitResult(1, 1.0), testing::VisitResult(2, 1.0), + testing::VisitResult(4, 1.0, {}, u"some search"), + testing::VisitResult(10, 1.0, {}, u"some other search")))); +} + } // namespace } // namespace history_clusters
diff --git a/components/history_clusters/core/label_cluster_finalizer.cc b/components/history_clusters/core/label_cluster_finalizer.cc index 8744313..ba301f6 100644 --- a/components/history_clusters/core/label_cluster_finalizer.cc +++ b/components/history_clusters/core/label_cluster_finalizer.cc
@@ -34,15 +34,71 @@ absl::optional<std::u16string> current_highest_scoring_label_unquoted; // First try finding search terms to use as the cluster label. + int num_search_visits = 0; for (const auto& visit : cluster.visits) { - if (!visit.annotated_visit.content_annotations.search_terms.empty() && - visit.score > max_label_score) { + if (!visit.annotated_visit.content_annotations.search_terms.empty()) { + num_search_visits++; + + if (visit.score > max_label_score) { + current_highest_scoring_label_unquoted = + visit.annotated_visit.content_annotations.search_terms; + current_highest_scoring_label = l10n_util::GetStringFUTF16( + IDS_HISTORY_CLUSTERS_CLUSTER_LABEL_SEARCH_TERMS, + *current_highest_scoring_label_unquoted); + max_label_score = visit.score; + } + } + } + + // If there are multiple search visits, find the most common entity. + if (GetConfig().labels_from_search_visit_entities && num_search_visits > 1) { + base::flat_map<std::string, float> entity_to_score; + base::flat_map<std::string, int> entity_to_count; + for (const auto& visit : cluster.visits) { + if (visit.annotated_visit.content_annotations.search_terms.empty()) { + continue; + } + for (const auto& entity : visit.annotated_visit.content_annotations + .model_annotations.entities) { + auto it = entity_to_score.find(entity.id); + float new_score = it != entity_to_score.end() + ? it->second + (entity.weight * visit.score) + : entity.weight * visit.score; + entity_to_score[entity.id] = new_score; + + entity_to_count[entity.id]++; + } + } + + // Get entity most common amongst the search visits and tiebreak using + // score. + int max_count = -1; + max_label_score = -1; + absl::optional<std::string> highest_scoring_entity; + for (const auto& entity_and_count : entity_to_count) { + auto entity_metadata_it = + entity_metadata_map_->find(entity_and_count.first); + if (entity_metadata_it == entity_metadata_map_->end()) { + continue; + } + + if (entity_and_count.second > max_count) { + max_count = entity_and_count.second; + max_label_score = entity_to_score.at(entity_and_count.first); + highest_scoring_entity = entity_metadata_it->second.human_readable_name; + } else if (entity_and_count.second == max_count && + entity_to_score.at(entity_and_count.first) > max_label_score) { + max_label_score = entity_to_score.at(entity_and_count.first); + highest_scoring_entity = entity_metadata_it->second.human_readable_name; + } + } + + if (highest_scoring_entity) { current_highest_scoring_label_unquoted = - visit.annotated_visit.content_annotations.search_terms; + base::UTF8ToUTF16(*highest_scoring_entity); current_highest_scoring_label = l10n_util::GetStringFUTF16( IDS_HISTORY_CLUSTERS_CLUSTER_LABEL_SEARCH_TERMS, *current_highest_scoring_label_unquoted); - max_label_score = visit.score; } }
diff --git a/components/history_clusters/core/label_cluster_finalizer_unittest.cc b/components/history_clusters/core/label_cluster_finalizer_unittest.cc index 7705500..b898d20 100644 --- a/components/history_clusters/core/label_cluster_finalizer_unittest.cc +++ b/components/history_clusters/core/label_cluster_finalizer_unittest.cc
@@ -30,6 +30,9 @@ optimization_guide::EntityMetadata label_md; label_md.human_readable_name = "chosenlabel"; entity_metadata_map_["baz"] = label_md; + optimization_guide::EntityMetadata github_md; + label_md.human_readable_name = "githublabel"; + entity_metadata_map_["github"] = label_md; cluster_finalizer_ = std::make_unique<LabelClusterFinalizer>(&entity_metadata_map_); @@ -134,6 +137,7 @@ Config config; config.labels_from_hostnames = true; config.labels_from_entities = true; + config.labels_from_search_visit_entities = false; SetConfigForTesting(config); history::ClusterVisit visit = @@ -163,5 +167,44 @@ EXPECT_THAT(cluster.label, u"“searchtermlabel”"); } +TEST_F(LabelClusterFinalizerTest, + TakesHighestCountSearchTermIfMultipleSearchVisits) { + // Verify that search terms take precedence even if labels from entities are + // enabled. + Config config; + config.labels_from_hostnames = true; + config.labels_from_entities = true; + config.labels_from_search_visit_entities = true; + SetConfigForTesting(config); + + history::ClusterVisit visit = + testing::CreateClusterVisit(testing::CreateDefaultAnnotatedVisit( + 2, GURL("https://nosearchtermsbuthighscorevisit.com/"))); + visit.engagement_score = 0.9; + visit.annotated_visit.content_annotations.model_annotations.entities = { + {"github", 100}, {"onlyinnoisyvisit", 99}}; + + history::ClusterVisit visit2 = + testing::CreateClusterVisit(testing::CreateDefaultAnnotatedVisit( + 1, GURL("https://lowerscoringsearchterm.com/"))); + visit2.score = 0.6; + visit2.annotated_visit.content_annotations.search_terms = u"lowscore"; + visit2.annotated_visit.content_annotations.model_annotations.entities = { + {"github", 80}, {"commonsearch", 99}}; + + history::ClusterVisit visit3 = testing::CreateClusterVisit( + testing::CreateDefaultAnnotatedVisit(2, GURL("https://baz.com/"))); + visit3.score = 0.8; + visit3.annotated_visit.content_annotations.model_annotations.entities = { + {"github", 80}, {"other", 100}}; + visit3.annotated_visit.content_annotations.search_terms = u"searchtermlabel"; + + history::Cluster cluster; + cluster.visits = {visit, visit2, visit3}; + FinalizeCluster(cluster); + EXPECT_THAT(cluster.raw_label, u"githublabel"); + EXPECT_THAT(cluster.label, u"“githublabel”"); +} + } // namespace } // namespace history_clusters
diff --git a/components/password_manager/core/browser/password_manager_features_util_mobile.cc b/components/password_manager/core/browser/password_manager_features_util_mobile.cc index 03671cd..89a29e44 100644 --- a/components/password_manager/core/browser/password_manager_features_util_mobile.cc +++ b/components/password_manager/core/browser/password_manager_features_util_mobile.cc
@@ -16,11 +16,35 @@ const syncer::SyncService* sync_service) { DCHECK(pref_service); + if (!internal::IsUserEligibleForAccountStorage(sync_service)) { + return false; + } + // On Android and iOS, there is no explicit opt-in - this is handled through // Sync's selected data types instead. - return internal::IsUserEligibleForAccountStorage(sync_service) && - sync_service->GetUserSettings()->GetSelectedTypes().Has( - syncer::UserSelectableType::kPasswords); + if (!sync_service->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kPasswords)) { + return false; + } + + // From this point on, we want to check for encryption errors, which we can + // only do when the engine is initialized. In that meantime, we give it the + // benefit of the doubt and say the user is opted in. + if (!sync_service->IsEngineInitialized()) { + return true; + } + + // Encryption errors mean the account store can't upload data, which is bad. + // Worse: in some cases sign-out might not clear the store. If another user + // signs in later, the leftover data might end up in their account, see + // crbug.com/1426774. + // TODO(crbug.com/1426774): Hook this code to IsTrackingMetadata(). + if (sync_service->GetUserSettings()->IsPassphraseRequired() || + sync_service->GetUserSettings()->IsTrustedVaultKeyRequired()) { + return false; + } + + return true; } bool ShouldShowAccountStorageOptIn(const PrefService* pref_service,
diff --git a/components/remote_cocoa/app_shim/browser_native_widget_window_mac.mm b/components/remote_cocoa/app_shim/browser_native_widget_window_mac.mm index 6e116d6..b31c3be 100644 --- a/components/remote_cocoa/app_shim/browser_native_widget_window_mac.mm +++ b/components/remote_cocoa/app_shim/browser_native_widget_window_mac.mm
@@ -31,16 +31,30 @@ bool overrideTitlebarHeight = false; float titlebarHeight = 0; - if (!_inFullScreen) { - auto* window = base::mac::ObjCCast<NativeWidgetMacNSWindow>([self window]); - remote_cocoa::NativeWidgetNSWindowBridge* bridge = [window bridge]; - if (bridge) { - bridge->host()->GetWindowFrameTitlebarHeight(&overrideTitlebarHeight, - &titlebarHeight); - } + auto* window = base::mac::ObjCCast<NativeWidgetMacNSWindow>([self window]); + remote_cocoa::NativeWidgetNSWindowBridge* bridge = [window bridge]; + if (!bridge) { + return [super _titlebarHeight]; } - if (overrideTitlebarHeight) + + // Ignore the overridden titlebar height when in fullscreen unless + // kImmersiveFullscreenTabs is enabled and the toolbar is visible. The + // toolbar is hidden during content fullscreen. + // In short the titlebar will be the same size during non-fullscreen and + // kImmersiveFullscreenTabs fullscreen. During content fullscreen the toolbar + // is hidden and the titlebar will be smaller default height. + if (!_inFullScreen || + (bridge->ImmersiveFullscreenIsEnabled() && + bridge->ImmersiveFullscreenIsTabbed() && + bridge->ImmersiveFullscreenLastUsedStyle() != + remote_cocoa::mojom::ToolbarVisibilityStyle::kNone)) { + bridge->host()->GetWindowFrameTitlebarHeight(&overrideTitlebarHeight, + &titlebarHeight); + } + + if (overrideTitlebarHeight) { return titlebarHeight; + } return [super _titlebarHeight]; }
diff --git a/components/remote_cocoa/app_shim/immersive_mode_controller.h b/components/remote_cocoa/app_shim/immersive_mode_controller.h index 38b0a163..8acd6c7 100644 --- a/components/remote_cocoa/app_shim/immersive_mode_controller.h +++ b/components/remote_cocoa/app_shim/immersive_mode_controller.h
@@ -39,6 +39,8 @@ virtual ~ImmersiveModeController(); virtual void Enable(); + bool is_enabled() { return enabled_; } + virtual void FullscreenTransitionCompleted(); virtual void OnTopViewBoundsChanged(const gfx::Rect& bounds); virtual void UpdateToolbarVisibility(mojom::ToolbarVisibilityStyle style); @@ -82,6 +84,9 @@ titlebar_fully_visible_ = fully_visible; } + // Returns true if kImmersiveFullscreenTabs is being used. + virtual bool IsTabbed(); + private: // Pin or unpin the titlebar. void SetTitlebarPinned(bool pinned);
diff --git a/components/remote_cocoa/app_shim/immersive_mode_controller.mm b/components/remote_cocoa/app_shim/immersive_mode_controller.mm index 8445bac..ba4d1e8 100644 --- a/components/remote_cocoa/app_shim/immersive_mode_controller.mm +++ b/components/remote_cocoa/app_shim/immersive_mode_controller.mm
@@ -625,4 +625,8 @@ [overlay_window_ setFrameOrigin:point_on_screen]; } +bool ImmersiveModeController::IsTabbed() { + return false; +} + } // namespace remote_cocoa
diff --git a/components/remote_cocoa/app_shim/immersive_mode_tabbed_controller.h b/components/remote_cocoa/app_shim/immersive_mode_tabbed_controller.h index 2d69c64..8f3c8496 100644 --- a/components/remote_cocoa/app_shim/immersive_mode_tabbed_controller.h +++ b/components/remote_cocoa/app_shim/immersive_mode_tabbed_controller.h
@@ -27,6 +27,10 @@ ~ImmersiveModeTabbedController() override; // ImmersiveModeController overrides + // TODO(https://crbug.com/1426944): Enable() does not add the controller. It + // will be added / removed from the view controller tree during + // UpdateToolbarVisibility(). Remove this comment once the bug has been + // resolved. void Enable() override; void FullscreenTransitionCompleted() override; void UpdateToolbarVisibility(mojom::ToolbarVisibilityStyle style) override; @@ -37,14 +41,17 @@ void TitlebarUnlock() override; void OnTitlebarFrameDidChange(NSRect frame) override; void OnChildWindowAdded(NSWindow* child) override; + bool IsTabbed() override; private: void TitlebarReveal(); void TitlebarHide(); + void AddController(); + void RemoveController(); NSWindow* const tab_window_; BridgedContentView* tab_content_view_; - base::scoped_nsobject<TabTitlebarViewController> + base::scoped_nsobject<NSTitlebarAccessoryViewController> tab_titlebar_view_controller_; };
diff --git a/components/remote_cocoa/app_shim/immersive_mode_tabbed_controller.mm b/components/remote_cocoa/app_shim/immersive_mode_tabbed_controller.mm index 718756d..c6b6b94 100644 --- a/components/remote_cocoa/app_shim/immersive_mode_tabbed_controller.mm +++ b/components/remote_cocoa/app_shim/immersive_mode_tabbed_controller.mm
@@ -9,28 +9,6 @@ #import "components/remote_cocoa/app_shim/bridged_content_view.h" #include "components/remote_cocoa/app_shim/immersive_mode_controller.h" -@interface NSWindow (ChromeTitleBarHeight) -// TODO(https://crbug.com/1414521): Support macOS versions older than -// macOS 10.15. -@property double titlebarHeight API_AVAILABLE(macos(10.15)); -@end - -@interface TabTitlebarViewController : NSTitlebarAccessoryViewController -@end - -@implementation TabTitlebarViewController - -- (void)viewWillAppear { - [super viewWillAppear]; - for (NSView* sub_view in self.view.subviews) { - if ([sub_view isKindOfClass:[BridgedContentView class]]) { - [sub_view setFrameSize:self.view.frame.size]; - } - } -} - -@end - namespace remote_cocoa { ImmersiveModeTabbedController::ImmersiveModeTabbedController( @@ -44,7 +22,8 @@ tab_window_(tab_window) { browser_window.titleVisibility = NSWindowTitleHidden; - tab_titlebar_view_controller_.reset([[TabTitlebarViewController alloc] init]); + tab_titlebar_view_controller_.reset( + [[NSTitlebarAccessoryViewController alloc] init]); tab_titlebar_view_controller_.get().view = [[[NSView alloc] init] autorelease]; @@ -79,6 +58,15 @@ tab_titlebar_view_controller_.get().fullScreenMinHeight = tab_window_.frame.size.height; + // Keep the tab content view's size in sync with its parent view. + tab_content_view_.translatesAutoresizingMaskIntoConstraints = NO; + [tab_content_view_.heightAnchor + constraintEqualToAnchor:tab_content_view_.superview.heightAnchor] + .active = YES; + [tab_content_view_.widthAnchor + constraintEqualToAnchor:tab_content_view_.superview.widthAnchor] + .active = YES; + tab_window_.contentView = [[[BridgedContentView alloc] initWithBridge:tab_content_view_.bridge bounds:gfx::Rect()] autorelease]; @@ -88,17 +76,12 @@ // The `overlay_window_` is handled the same way in ImmersiveModeController. // See the comment there for more details. tab_window_.ignoresMouseEvents = YES; - - tab_titlebar_view_controller_.get().hidden = YES; - [browser_window() - addTitlebarAccessoryViewController:tab_titlebar_view_controller_]; } void ImmersiveModeTabbedController::FullscreenTransitionCompleted() { // The presence of a visible NSToolbar causes the titlebar to be revealed. // Keep the titlebar hidden until the fullscreen transition is complete. ImmersiveModeController::FullscreenTransitionCompleted(); - tab_titlebar_view_controller_.get().hidden = NO; NSToolbar* toolbar = [[[NSToolbar alloc] init] autorelease]; toolbar.visible = NO; ImmersiveModeController::browser_window().toolbar = toolbar; @@ -109,18 +92,39 @@ void ImmersiveModeTabbedController::UpdateToolbarVisibility( mojom::ToolbarVisibilityStyle style) { - ImmersiveModeController::UpdateToolbarVisibility(style); + // TODO(https://crbug.com/1426944): A NSTitlebarAccessoryViewController hosted + // in the titlebar, as opposed to above or below it, does not hide/show when + // using the `hidden` property. Instead we must entirely remove the view + // controller to make the view hide. Switch to using the `hidden` property + // once Apple resolves this bug. switch (style) { case mojom::ToolbarVisibilityStyle::kAlways: + AddController(); TitlebarReveal(); break; case mojom::ToolbarVisibilityStyle::kAutohide: + AddController(); TitlebarHide(); break; case mojom::ToolbarVisibilityStyle::kNone: + RemoveController(); TitlebarHide(); break; } + ImmersiveModeController::UpdateToolbarVisibility(style); +} + +void ImmersiveModeTabbedController::AddController() { + NSWindow* browser_window = ImmersiveModeController::browser_window(); + if (![browser_window.titlebarAccessoryViewControllers + containsObject:tab_titlebar_view_controller_]) { + [browser_window + addTitlebarAccessoryViewController:tab_titlebar_view_controller_]; + } +} + +void ImmersiveModeTabbedController::RemoveController() { + [tab_titlebar_view_controller_ removeFromParentViewController]; } void ImmersiveModeTabbedController::OnTopViewBoundsChanged( @@ -134,43 +138,33 @@ } void ImmersiveModeTabbedController::RevealLock() { - ImmersiveModeController::RevealLock(); TitlebarReveal(); + + // Call after TitlebarReveal() for a proper layout. + ImmersiveModeController::RevealLock(); } void ImmersiveModeTabbedController::RevealUnlock() { - ImmersiveModeController::RevealUnlock(); - if (ImmersiveModeController::reveal_lock_count() < 1 && + // The reveal lock count will be updated in + // ImmersiveModeController::RevealUnlock(), count 1 or less here as unlocked. + if (ImmersiveModeController::reveal_lock_count() < 2 && ImmersiveModeController::last_used_style() == mojom::ToolbarVisibilityStyle::kAutohide) { TitlebarHide(); } + + // Call after TitlebarHide() for a proper layout. + ImmersiveModeController::RevealUnlock(); } void ImmersiveModeTabbedController::TitlebarReveal() { - // This -1 hack is needed to make the titlebar visible if it is hidden. - // TODO(https://crbug.com/1414521): Get rid of this shrink hack. NSWindow* browser_window = ImmersiveModeController::browser_window(); - if (@available(macOS 10.15, *)) { - browser_window.titlebarHeight = tab_window_.frame.size.height - 1; - } browser_window.toolbar.visible = YES; - if (@available(macOS 10.15, *)) { - browser_window.titlebarHeight = tab_window_.frame.size.height; - } } void ImmersiveModeTabbedController::TitlebarHide() { - // Similarly this -1 hack will cause the titlebar to hide. - // TODO(https://crbug.com/1414521): Get rid of this shrink hack. NSWindow* browser_window = ImmersiveModeController::browser_window(); - if (@available(macOS 10.15, *)) { - browser_window.titlebarHeight = tab_window_.frame.size.height - 1; - } browser_window.toolbar.visible = NO; - if (@available(macOS 10.15, *)) { - browser_window.titlebarHeight = tab_window_.frame.size.height; - } } // TODO(https://crbug.com/1414521) TitlebarLock and TitlebarUnlock mean @@ -201,4 +195,8 @@ ImmersiveModeController::OnChildWindowAdded(child); } +bool ImmersiveModeTabbedController::IsTabbed() { + return true; +} + } // namespace remote_cocoa
diff --git a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.h b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.h index e7bf48ba..4f071d4a 100644 --- a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.h +++ b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.h
@@ -67,6 +67,10 @@ // window, so this function prevents that if the window is currently inactive. - (void)orderFrontKeepWindowKeyState; +// Overridden to prevent headless windows to be constrained to the physical +// screen bounds. +- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen; + // Identifier for the NativeWidgetMac from which this window was created. This // may be used to look up the NativeWidgetMacNSWindowHost in the browser process // or the NativeWidgetNSWindowBridge in a display process. @@ -78,6 +82,9 @@ // Whether this window functions as a tooltip. @property(assign, nonatomic) BOOL isTooltip; +// Whether this window is headless. +@property(assign, nonatomic) BOOL isHeadless; + // Called whenever a child window is added to the receiver. @property(nonatomic, copy) void (^childWindowAddedHandler)(NSWindow* child); @end
diff --git a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm index ea4db769..5443ddda 100644 --- a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm +++ b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
@@ -166,10 +166,12 @@ BOOL _isEnforcingNeverMadeVisible; BOOL _preventKeyWindow; BOOL _isTooltip; + BOOL _isHeadless; } @synthesize bridgedNativeWidgetId = _bridgedNativeWidgetId; @synthesize bridge = _bridge; @synthesize isTooltip = _isTooltip; +@synthesize isHeadless = _isHeadless; @synthesize childWindowAddedHandler = _childWindowAddedHandler; - (instancetype)initWithContentRect:(NSRect)contentRect @@ -298,6 +300,15 @@ [self orderWindow:NSWindowAbove relativeTo:0]; } +- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen { + // Headless windows should not be constrained within the physical screen. + if (_isHeadless) { + return frameRect; + } + + return [super constrainFrameRect:frameRect toScreen:screen]; +} + // Private methods. - (ViewsNSWindowDelegate*)viewsNSWindowDelegate {
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h index b76efb6e..83a008f7 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h
@@ -308,6 +308,17 @@ void MoveChildrenTo(NativeWidgetNSWindowBridge* target, bool anchored_only = false); + // Is immersive fullscreen enabled. True will be returned at the start of the + // fullscreen transition. + bool ImmersiveFullscreenIsEnabled(); + + // Returns true if kImmersiveFullscreenTabs is being used. + bool ImmersiveFullscreenIsTabbed(); + + // Returns the last style set with `UpdateToolbarVisibility()`. Defaults to + // kAlways. + mojom::ToolbarVisibilityStyle ImmersiveFullscreenLastUsedStyle(); + private: friend class views::test::BridgedNativeWidgetTestApi; @@ -432,8 +443,6 @@ struct HeadlessModeWindow { bool visibility_state = false; bool fullscreen_state = false; - bool initial_bounds_set = false; - gfx::Rect bounds; }; // This is present iff the window has been created in headless mode.
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm index daadfaf..f3373da2 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
@@ -46,7 +46,6 @@ #include "ui/display/screen.h" #include "ui/events/cocoa/cocoa_event_utils.h" #include "ui/gfx/geometry/dip_util.h" -#include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/size_conversions.h" #import "ui/gfx/mac/coordinate_conversion.h" #import "ui/gfx/mac/nswindow_frame_controls.h" @@ -434,6 +433,8 @@ if (params->is_headless_mode_window) headless_mode_window_ = absl::make_optional<HeadlessModeWindow>(); + [window_ setIsHeadless:params->is_headless_mode_window]; + // Register for application hide notifications so that visibility can be // properly tracked. This is not done in the delegate so that the lifetime is // tied to the C++ object, rather than the delegate (which may be reference @@ -498,34 +499,6 @@ void NativeWidgetNSWindowBridge::SetBounds( const gfx::Rect& new_bounds, const gfx::Size& minimum_content_size) { - // In headless mode we keep track of the expected window size and report it to - // the |host_| when it changes. The platform window is positioned only once - // during initialization and may have smaller size than the requested window - // size because Cocoa clamps windows size to the available display area which - // is undesirable for headless mode. - if (headless_mode_window_) { - if (new_bounds != headless_mode_window_->bounds) { - headless_mode_window_->bounds = new_bounds; - base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::BindOnce( - [](WeakPtrNSObject* handle) { - if (auto* bridge = ui::WeakPtrNSObjectFactory< - NativeWidgetNSWindowBridge>::Get(handle)) { - bridge->UpdateWindowGeometry(); - } - }, - ns_weak_factory_.handle())); - } - - if (headless_mode_window_->initial_bounds_set) { - return; - } - - // Fall through to set platform window size once. This ensures that the - // platform window has reasonable size. - headless_mode_window_->initial_bounds_set = true; - } - // -[NSWindow contentMinSize] is only checked by Cocoa for user-initiated // resizes. This is not what toolkit-views expects, so clamp. Note there is // no check for maximum size (consistent with aura::Window::SetBounds()). @@ -1008,6 +981,28 @@ } } +bool NativeWidgetNSWindowBridge::ImmersiveFullscreenIsEnabled() { + if (!immersive_mode_controller_) { + return false; + } + return immersive_mode_controller_->is_enabled(); +} + +bool NativeWidgetNSWindowBridge::ImmersiveFullscreenIsTabbed() { + if (!immersive_mode_controller_) { + return false; + } + return immersive_mode_controller_->IsTabbed(); +} + +mojom::ToolbarVisibilityStyle +NativeWidgetNSWindowBridge::ImmersiveFullscreenLastUsedStyle() { + if (!immersive_mode_controller_) { + return mojom::ToolbarVisibilityStyle::kAlways; + } + return immersive_mode_controller_->last_used_style(); +} + void NativeWidgetNSWindowBridge::SetCanGoBack(bool can_go_back) { can_go_back_ = can_go_back; } @@ -1681,27 +1676,6 @@ gfx::Rect window_in_screen = gfx::ScreenRectFromNSRect([window_ frame]); gfx::Rect content_in_screen = gfx::ScreenRectFromNSRect( [window_ contentRectForFrameRect:[window_ frame]]); - - // In headless mode the platform window dimensions are only used to calculate - // content rectangle inset. The host is reported the expected window size that - // was set in |SetBounds|. - if (headless_mode_window_) { - gfx::Insets insets; - insets.set_left(content_in_screen.x() - window_in_screen.x()); - insets.set_right(window_in_screen.right() - content_in_screen.right()); - insets.set_top(content_in_screen.y() - window_in_screen.y()); - insets.set_bottom(window_in_screen.bottom() - content_in_screen.bottom()); - - // Apply platform window content rectangle insets to the headless bounds - // to find out headless content rectangle. - gfx::Rect headless_content_rect = headless_mode_window_->bounds; - headless_content_rect.Inset(insets); - - host_->OnWindowGeometryChanged(headless_mode_window_->bounds, - headless_content_rect); - return; - } - bool content_resized = content_dip_size_ != content_in_screen.size(); content_dip_size_ = content_in_screen.size();
diff --git a/components/supervised_user/core/browser/supervised_user_error_page.cc b/components/supervised_user/core/browser/supervised_user_error_page.cc index 1fa66028..0c9ab54 100644 --- a/components/supervised_user/core/browser/supervised_user_error_page.cc +++ b/components/supervised_user/core/browser/supervised_user_error_page.cc
@@ -135,9 +135,9 @@ strings.Set("feedbackLink", l10n_util::GetStringUTF8(IDS_BLOCK_INTERSTITIAL_SEND_FEEDBACK)); if (web_filter_interstitial_refresh_enabled) { - strings.Set( - "remoteApprovalsButton", - l10n_util::GetStringUTF8(IDS_BLOCK_INTERSTITIAL_SEND_MESSAGE_BUTTON)); + strings.Set("remoteApprovalsButton", + l10n_util::GetStringUTF8( + IDS_BLOCK_INTERSTITIAL_ASK_IN_A_MESSAGE_BUTTON)); strings.Set("backButton", l10n_util::GetStringUTF8(IDS_REQUEST_SENT_OK)); } else { strings.Set(
diff --git a/components/supervised_user/core/browser/supervised_user_error_page_unittest.cc b/components/supervised_user/core/browser/supervised_user_error_page_unittest.cc index 15135c65..fe9da06d 100644 --- a/components/supervised_user/core/browser/supervised_user_error_page_unittest.cc +++ b/components/supervised_user/core/browser/supervised_user_error_page_unittest.cc
@@ -158,7 +158,7 @@ IDS_BLOCK_INTERSTITIAL_ASK_IN_PERSON_BUTTON))); if (param.is_web_filter_interstitial_refresh_enabled) { EXPECT_THAT(result, testing::HasSubstr(l10n_util::GetStringUTF8( - IDS_BLOCK_INTERSTITIAL_SEND_MESSAGE_BUTTON))); + IDS_BLOCK_INTERSTITIAL_ASK_IN_A_MESSAGE_BUTTON))); EXPECT_THAT(result, testing::HasSubstr( l10n_util::GetStringUTF8(IDS_REQUEST_SENT_OK))); } else {
diff --git a/components/supervised_user_strings.grdp b/components/supervised_user_strings.grdp index 7e60578..fa5beaa 100644 --- a/components/supervised_user_strings.grdp +++ b/components/supervised_user_strings.grdp
@@ -31,8 +31,8 @@ <message name="IDS_BLOCK_INTERSTITIAL_ASK_IN_PERSON_INSTEAD_BUTTON" desc="A button to show a dialog to request access to blocked sites for users who have already asked for permission remotely."> Ask in person instead </message> - <message name="IDS_BLOCK_INTERSTITIAL_SEND_MESSAGE_BUTTON" desc="A button to send a message to request access to blocked sites."> - Send a message + <message name="IDS_BLOCK_INTERSTITIAL_ASK_IN_A_MESSAGE_BUTTON" desc="A button to send a message to request access to blocked sites."> + Ask in a message </message> <message name="IDS_BLOCK_INTERSTITIAL_REQUEST_ACCESS_BUTTON" desc="A button for requesting access to blocked sites."> Ask permission
diff --git a/components/supervised_user_strings_grdp/IDS_BLOCK_INTERSTITIAL_ASK_IN_A_MESSAGE_BUTTON.png.sha1 b/components/supervised_user_strings_grdp/IDS_BLOCK_INTERSTITIAL_ASK_IN_A_MESSAGE_BUTTON.png.sha1 new file mode 100644 index 0000000..26b73c9 --- /dev/null +++ b/components/supervised_user_strings_grdp/IDS_BLOCK_INTERSTITIAL_ASK_IN_A_MESSAGE_BUTTON.png.sha1
@@ -0,0 +1 @@ +4ebc6bb23f326a3eac6b913e47bf48b34385b227 \ No newline at end of file
diff --git a/components/supervised_user_strings_grdp/IDS_BLOCK_INTERSTITIAL_SEND_MESSAGE_BUTTON.png.sha1 b/components/supervised_user_strings_grdp/IDS_BLOCK_INTERSTITIAL_SEND_MESSAGE_BUTTON.png.sha1 deleted file mode 100644 index 81947a0..0000000 --- a/components/supervised_user_strings_grdp/IDS_BLOCK_INTERSTITIAL_SEND_MESSAGE_BUTTON.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e9cf5f7e827dcd20efb00073ac702d561e1424b4 \ No newline at end of file
diff --git a/components/sync/protocol/sync_enums.proto b/components/sync/protocol/sync_enums.proto index 91009ec..d6d0b52 100644 --- a/components/sync/protocol/sync_enums.proto +++ b/components/sync/protocol/sync_enums.proto
@@ -138,8 +138,7 @@ UNKNOWN_ACTION = 5; // This is the default. } - // Please keep in sync with chrome/android/java/.../ForeignSessionHelper.java - // New enums to describe the device type were introduced; OsType and + // New enums to describe the device type were introduced; OsType and // FormFactor. Deprecated 12/2022. // TODO(1395353): Remove deprecated values from DeviceType enum. enum DeviceType {
diff --git a/components/user_education/common/tutorial_description.cc b/components/user_education/common/tutorial_description.cc index efb1d05ef..59a358f5e 100644 --- a/components/user_education/common/tutorial_description.cc +++ b/components/user_education/common/tutorial_description.cc
@@ -21,6 +21,17 @@ arrow(HelpBubbleArrow::kNone) {} TutorialDescription::Step::~Step() = default; +TutorialDescription::Step::Step(ElementSpecifier element_specifier, + ui::InteractionSequence::StepType step_type_, + ui::CustomElementEventType event_type_) + : step_type(step_type_), event_type(event_type_) { + if (auto* id = absl::get_if<ui::ElementIdentifier>(&element_specifier)) { + element_id = *id; + } else { + CHECK(absl::holds_alternative<std::string>(element_specifier)); + element_name = absl::get<std::string>(element_specifier); + } +} TutorialDescription::Step::Step( int title_text_id_, int body_text_id_, @@ -33,12 +44,12 @@ bool transition_only_on_event_, TutorialDescription::NameElementsCallback name_elements_callback_, ContextMode context_mode_) - : title_text_id(title_text_id_), - body_text_id(body_text_id_), + : element_id(element_id_), + element_name(element_name_), step_type(step_type_), event_type(event_type_), - element_id(element_id_), - element_name(element_name_), + title_text_id(title_text_id_), + body_text_id(body_text_id_), arrow(arrow_), must_remain_visible(must_remain_visible_), transition_only_on_event(transition_only_on_event_),
diff --git a/components/user_education/common/tutorial_description.h b/components/user_education/common/tutorial_description.h index 9738752..bec187a 100644 --- a/components/user_education/common/tutorial_description.h +++ b/components/user_education/common/tutorial_description.h
@@ -132,9 +132,15 @@ TutorialDescription& operator=(TutorialDescription&& other); using ContextMode = ui::InteractionSequence::ContextMode; + using ElementSpecifier = absl::variant<ui::ElementIdentifier, std::string>; struct Step { Step(); + explicit Step( + ElementSpecifier element_specifier, + ui::InteractionSequence::StepType step_type_ = + ui::InteractionSequence::StepType::kShown, + ui::CustomElementEventType event_type_ = ui::CustomElementEventType()); Step(int title_text_id_, int body_text_id_, ui::InteractionSequence::StepType step_type_, @@ -150,18 +156,6 @@ Step& operator=(const Step& other); ~Step(); - // The title text to be populated in the bubble. - int title_text_id = 0; - - // The body text to be populated in the bubble. - int body_text_id = 0; - - // The step type for InteractionSequence::Step. - ui::InteractionSequence::StepType step_type; - - // The event type for the step if `step_type` is kCustomEvent. - ui::CustomElementEventType event_type; - // The element used by interaction sequence to observe and attach a bubble. ui::ElementIdentifier element_id; @@ -169,6 +163,19 @@ // to observe and potentially attach a bubble. must be non-empty. std::string element_name; + // The step type for InteractionSequence::Step. + ui::InteractionSequence::StepType step_type = + ui::InteractionSequence::StepType::kShown; + + // The event type for the step if `step_type` is kCustomEvent. + ui::CustomElementEventType event_type = ui::CustomElementEventType(); + + // The title text to be populated in the bubble. + int title_text_id = 0; + + // The body text to be populated in the bubble. + int body_text_id = 0; + // The positioning of the bubble arrow. HelpBubbleArrow arrow = HelpBubbleArrow::kTopRight; @@ -177,7 +184,7 @@ // steps on the same element. if left empty the interaction sequence will // decide what its value should be based on the generated // InteractionSequence::StepBuilder - absl::optional<bool> must_remain_visible; + absl::optional<bool> must_remain_visible = absl::nullopt; // Should the step only be completed when an event like shown or hidden only // happens during current step. for more information on the implementation @@ -197,7 +204,7 @@ // element for naming. The return value is a boolean which controls whether // the Interaction Sequence should continue or not. If false is returned // the tutorial will abort - NameElementsCallback name_elements_callback; + NameElementsCallback name_elements_callback = NameElementsCallback(); // Where to search for the step's target element. Default is the context the // tutorial started in. @@ -206,6 +213,160 @@ // returns true iff all of the required parameters exist to display a // bubble. bool ShouldShowBubble() const; + + Step& AbortIfVisibilityLost(bool must_remain_visible_) { + must_remain_visible = must_remain_visible_; + return *this; + } + + Step& AbortIfNotVisible() { + must_be_visible = true; + return *this; + } + + Step& NameElement(const char name_[]) { + name_elements_callback = base::BindRepeating( + [](const char name[], ui::InteractionSequence* sequence, + ui::TrackedElement* element) { + sequence->NameElement(element, base::StringPiece(name)); + return true; + }, + name_); + return *this; + } + + Step& InAnyContext() { + context_mode = TutorialDescription::ContextMode::kAny; + return *this; + } + + Step& InSameContext() { + context_mode = TutorialDescription::ContextMode::kFromPreviousStep; + return *this; + } + }; + + // TutorialDescription::BubbleStep + // A bubble step is a step which shows a bubble anchored to an element + // This requires that the anchor element be visible, so this is always + // a kShown step. + // + // - A bubble step must be passed an element_id or an element_name + struct BubbleStep : public Step { + // TutorialDescription::BubbleStep(element_id_) + // TutorialDescription::BubbleStep(element_name_) + explicit BubbleStep(ElementSpecifier element_specifier) + : Step(element_specifier, ui::InteractionSequence::StepType::kShown) {} + + BubbleStep& SetBubbleTitleText(int title_text_) { + title_text_id = title_text_; + return *this; + } + + BubbleStep& SetBubbleBodyText(int body_text_) { + body_text_id = body_text_; + return *this; + } + + BubbleStep& SetBubbleArrow(HelpBubbleArrow arrow_) { + arrow = arrow_; + return *this; + } + }; + + // TutorialDescription::HiddenStep + // A hidden step has no bubble and waits for a UI event to occur on + // a particular element. + // + // - A hidden step must be passed an element_id or an element_name + struct HiddenStep : public Step { + // HiddenStep::WaitForShowEvent(element_id_) + // HiddenStep::WaitForShowEvent(element_name_) + // Transition to the next step after a show event occurs + static HiddenStep WaitForShowEvent(ElementSpecifier element_specifier) { + HiddenStep step(element_specifier, + ui::InteractionSequence::StepType::kShown); + step.transition_only_on_event = true; + return step; + } + + // HiddenStep::WaitForHideEvent(element_id_) + // HiddenStep::WaitForHideEvent(element_name_) + // Transition to the next step after a hide event occurs + static HiddenStep WaitForHideEvent(ElementSpecifier element_specifier) { + HiddenStep step(element_specifier, + ui::InteractionSequence::StepType::kHidden); + step.transition_only_on_event = true; + return step; + } + + // HiddenStep::WaitForActivateEvent(element_id_) + // HiddenStep::WaitForActivateEvent(element_name_) + // Transition to the next step after an activation event occurs + static HiddenStep WaitForActivateEvent(ElementSpecifier element_specifier) { + HiddenStep step(element_specifier, + ui::InteractionSequence::StepType::kActivated); + step.transition_only_on_event = true; + return step; + } + + // HiddenStep::WaitForShown(element_id_) + // HiddenStep::WaitForShown(element_name_) + // Transition to the next step if anchor is, or becomes, visible + static HiddenStep WaitForShown(ElementSpecifier element_specifier) { + HiddenStep step(element_specifier, + ui::InteractionSequence::StepType::kShown); + step.transition_only_on_event = false; + return step; + } + + // HiddenStep::WaitForHidden(element_id_) + // HiddenStep::WaitForHidden(element_name_) + // Transition to the next step if anchor is, or becomes, hidden + static HiddenStep WaitForHidden(ElementSpecifier element_specifier) { + HiddenStep step(element_specifier, + ui::InteractionSequence::StepType::kHidden); + step.transition_only_on_event = false; + return step; + } + + // HiddenStep::WaitForActivated(element_id_) + // HiddenStep::WaitForActivated(element_name_) + // Transition to the next step if anchor is, or becomes, activated + static HiddenStep WaitForActivated(ElementSpecifier element_specifier) { + HiddenStep step(element_specifier, + ui::InteractionSequence::StepType::kActivated); + step.transition_only_on_event = false; + return step; + } + + private: + explicit HiddenStep(ElementSpecifier element_specifier, + ui::InteractionSequence::StepType step_type) + : Step(element_specifier, step_type) {} + }; + + // TutorialDescription::EventStep + // An event step is a special case of a HiddenStep that waits for + // a custom event to be fired programmatically. + // + // - This step must be passed an event_id + // - Additionally, you can also pass an element_id or element_name if + // the event should occur specifically on a given element + struct EventStep : public Step { + // TutorialDescription::EventStep(event_id_) + explicit EventStep(ui::CustomElementEventType event_type_) + : Step(ui::ElementIdentifier(), + ui::InteractionSequence::StepType::kCustomEvent, + event_type_) {} + + // TutorialDescription::EventStep(event_id_, element_id_) + // TutorialDescription::EventStep(event_id_, element_name_) + EventStep(ui::CustomElementEventType event_type_, + ElementSpecifier element_specifier) + : Step(element_specifier, + ui::InteractionSequence::StepType::kCustomEvent, + event_type_) {} }; // the list of TutorialDescription steps
diff --git a/components/webapps/browser/features.cc b/components/webapps/browser/features.cc index 475ca86f..d964c55 100644 --- a/components/webapps/browser/features.cc +++ b/components/webapps/browser/features.cc
@@ -51,6 +51,13 @@ "WebApkInstallFailureNotification", base::FEATURE_DISABLED_BY_DEFAULT); +// Allow user to retry install WebAPK with the failure notification if the +// initial install failed. This needs to be used with +// |kWebApkInstallFailureNotification| Enabled. +BASE_FEATURE(kWebApkInstallFailureRetry, + "WebApkInstallFailureRetry", + base::FEATURE_DISABLED_BY_DEFAULT); + // Enables PWA Unique IDs for WebAPKs. BASE_FEATURE(kWebApkUniqueId, "WebApkUniqueId",
diff --git a/components/webapps/browser/features.h b/components/webapps/browser/features.h index e6c951d2..48d960a 100644 --- a/components/webapps/browser/features.h +++ b/components/webapps/browser/features.h
@@ -25,6 +25,7 @@ extern const base::FeatureParam<int> kInstallableAmbientBadgeMessage_ThrottleDomainsCapacity; BASE_DECLARE_FEATURE(kWebApkInstallFailureNotification); +BASE_DECLARE_FEATURE(kWebApkInstallFailureRetry); BASE_DECLARE_FEATURE(kWebApkUniqueId); #endif // BUILDFLAG(IS_ANDROID)
diff --git a/content/browser/attribution_reporting/attribution_config.h b/content/browser/attribution_reporting/attribution_config.h index 43c5c2b7..8bfcb359 100644 --- a/content/browser/attribution_reporting/attribution_config.h +++ b/content/browser/attribution_reporting/attribution_config.h
@@ -84,9 +84,14 @@ // should also be updated. int64_t aggregatable_budget_per_source = 65536; + // Default constants for the report delivery time to be used when declaring + // field trial params. + static constexpr base::TimeDelta kDefaultMinDelay = base::Minutes(10); + static constexpr base::TimeDelta kDefaultDelaySpan = base::Minutes(50); + // Controls the report delivery time. - base::TimeDelta min_delay = base::Minutes(10); - base::TimeDelta delay_span = base::Minutes(50); + base::TimeDelta min_delay = kDefaultMinDelay; + base::TimeDelta delay_span = kDefaultDelaySpan; // When adding new members, the corresponding `Validate()` definition and // `operator==()` definition in `attribution_interop_parser_unittest.cc`
diff --git a/content/browser/attribution_reporting/attribution_debug_report_unittest.cc b/content/browser/attribution_reporting/attribution_debug_report_unittest.cc index 4b3e9e4..777d117 100644 --- a/content/browser/attribution_reporting/attribution_debug_report_unittest.cc +++ b/content/browser/attribution_reporting/attribution_debug_report_unittest.cc
@@ -29,6 +29,7 @@ return ReportBuilder( AttributionInfoBuilder(SourceBuilder(source_time).BuildStored()) .Build()) + .SetReportTime(base::Time::UnixEpoch() + base::Hours(1)) .Build(); }
diff --git a/content/browser/attribution_reporting/attribution_report.cc b/content/browser/attribution_reporting/attribution_report.cc index 9bd461e..84ebaae 100644 --- a/content/browser/attribution_reporting/attribution_report.cc +++ b/content/browser/attribution_reporting/attribution_report.cc
@@ -33,11 +33,13 @@ uint64_t trigger_data, int64_t priority, double randomized_trigger_rate, - Id id) + Id id, + base::Time initial_report_time) : trigger_data(trigger_data), priority(priority), randomized_trigger_rate(randomized_trigger_rate), - id(id) { + id(id), + initial_report_time(initial_report_time) { DCHECK_GE(randomized_trigger_rate, 0); DCHECK_LE(randomized_trigger_rate, 1); } @@ -232,20 +234,11 @@ external_report_id_ = std::move(external_report_id); } +// TODO(tquintanilla): Return `initial_report_time` once field is moved to +// top level. base::Time AttributionReport::OriginalReportTime() const { - return absl::visit( - base::Overloaded{ - [this](const EventLevelData&) { - return ComputeReportTime( - this->attribution_info_.source.common_info(), - this->attribution_info_.source.event_report_window_time(), - this->attribution_info_.time); - }, - [](const AggregatableAttributionData& data) { - return data.initial_report_time; - }, - }, - data_); + return absl::visit([](const auto& v) { return v.initial_report_time; }, + data_); } // static
diff --git a/content/browser/attribution_reporting/attribution_report.h b/content/browser/attribution_reporting/attribution_report.h index 9c51f54..9750d9b 100644 --- a/content/browser/attribution_reporting/attribution_report.h +++ b/content/browser/attribution_reporting/attribution_report.h
@@ -45,7 +45,8 @@ EventLevelData(uint64_t trigger_data, int64_t priority, double randomized_trigger_rate, - Id id); + Id id, + base::Time initial_report_time); EventLevelData(const EventLevelData&); EventLevelData& operator=(const EventLevelData&); EventLevelData(EventLevelData&&); @@ -67,6 +68,10 @@ // Id assigned by storage to uniquely identify a completed conversion. Id id; + // The initial report time scheduled by the browser. + // TODO(tquintanilla): Move to top level with aggregatable equivalent. + base::Time initial_report_time; + // When adding new members, the corresponding `operator==()` definition in // `attribution_test_utils.h` should also be updated. };
diff --git a/content/browser/attribution_reporting/attribution_report_network_sender_unittest.cc b/content/browser/attribution_reporting/attribution_report_network_sender_unittest.cc index 331272f..4079eb6 100644 --- a/content/browser/attribution_reporting/attribution_report_network_sender_unittest.cc +++ b/content/browser/attribution_reporting/attribution_report_network_sender_unittest.cc
@@ -180,6 +180,7 @@ .Build()) .SetTriggerData(5) .SetRandomizedTriggerRate(0.2) + .SetReportTime(base::Time::UnixEpoch() + base::Hours(1)) .Build(); for (const auto& test_case : kTestCases) {
diff --git a/content/browser/attribution_reporting/attribution_report_unittest.cc b/content/browser/attribution_reporting/attribution_report_unittest.cc index a6da225..1f096db 100644 --- a/content/browser/attribution_reporting/attribution_report_unittest.cc +++ b/content/browser/attribution_reporting/attribution_report_unittest.cc
@@ -92,6 +92,7 @@ .Build()) .SetTriggerData(5) .SetRandomizedTriggerRate(0.2) + .SetReportTime(base::Time::UnixEpoch() + base::Hours(1)) .Build(); EXPECT_THAT(report.ReportBody(), IsJson(test_case.expected)); @@ -142,6 +143,7 @@ .BuildStored()) .SetTime(base::Time::UnixEpoch() + base::Seconds(1)) .Build()) + .SetReportTime(base::Time::UnixEpoch() + base::Hours(1)) .Build(); EXPECT_THAT(report.ReportBody(), IsJson(test_case.expected)); @@ -208,6 +210,7 @@ .Build()) .SetTriggerData(5) .SetRandomizedTriggerRate(0.2) + .SetReportTime(base::Time::UnixEpoch() + base::Hours(1)) .Build(); EXPECT_THAT(report.ReportBody(), IsJson(test_case.expected));
diff --git a/content/browser/attribution_reporting/attribution_src_browsertest.cc b/content/browser/attribution_reporting/attribution_src_browsertest.cc index 0bf976b..448af08 100644 --- a/content/browser/attribution_reporting/attribution_src_browsertest.cc +++ b/content/browser/attribution_reporting/attribution_src_browsertest.cc
@@ -332,6 +332,47 @@ // AttributionsBrowserTest. } +// See crbug.com/1426892, where attributionsrc window.open features are +// incorrectly handled if multiple attributionsrc features are specified. +// Multiple attributionsrc features should not issue multiple background +// requests, and we should only handle the last attributionsrc entry to comply +// with +// https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-window-open-features-tokenize +IN_PROC_BROWSER_TEST_F(AttributionSrcBrowserTest, + AttributionSrcWindowOpen_MultipleFeatures_UsesLast) { + // Create a separate server as we cannot register a `ControllableHttpResponse` + // after the server starts. + auto https_server = std::make_unique<net::EmbeddedTestServer>( + net::EmbeddedTestServer::TYPE_HTTPS); + https_server->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES); + https_server->ServeFilesFromSourceDirectory( + "content/test/data/attribution_reporting"); + + auto register_response1 = + std::make_unique<net::test_server::ControllableHttpResponse>( + https_server.get(), "/source1"); + auto register_response2 = + std::make_unique<net::test_server::ControllableHttpResponse>( + https_server.get(), "/source2"); + ASSERT_TRUE(https_server->Start()); + + SourceObserver source_observer(web_contents()); + GURL page_url = + https_server->GetURL("b.test", "/page_with_impression_creator.html"); + ASSERT_TRUE(NavigateToURL(web_contents(), page_url)); + + ASSERT_TRUE(ExecJs(web_contents(), R"( + window.open("page_with_conversion_redirect.html", "_top", + "attributionsrc=/source1 attributionsrc=/source2"); + )")); + + register_response2->WaitForRequest(); + register_response2->Done(); + + // Only the last feature's value should be used. + EXPECT_FALSE(register_response1->has_received_request()); +} + IN_PROC_BROWSER_TEST_F(AttributionSrcBrowserTest, AnchorClickEmptyAttributionSrc_ImpressionReceived) { GURL page_url =
diff --git a/content/browser/attribution_reporting/attribution_storage_delegate_impl.cc b/content/browser/attribution_reporting/attribution_storage_delegate_impl.cc index 64aff8d..0b3eae1 100644 --- a/content/browser/attribution_reporting/attribution_storage_delegate_impl.cc +++ b/content/browser/attribution_reporting/attribution_storage_delegate_impl.cc
@@ -13,6 +13,7 @@ #include "base/cxx17_backports.h" #include "base/guid.h" #include "base/memory/ptr_util.h" +#include "base/metrics/field_trial_params.h" #include "base/rand_util.h" #include "base/time/time.h" #include "components/attribution_reporting/source_type.mojom.h" @@ -24,11 +25,20 @@ #include "content/browser/attribution_reporting/common_source_info.h" #include "content/browser/attribution_reporting/stored_source.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/features.h" namespace content { namespace { +const base::FeatureParam<base::TimeDelta> kAggregateReportMinDelay{ + &blink::features::kConversionMeasurement, "aggregate_report_min_delay", + AttributionConfig::AggregateLimit::kDefaultMinDelay}; + +const base::FeatureParam<base::TimeDelta> kAggregateReportDelaySpan{ + &blink::features::kConversionMeasurement, "aggregate_report_delay_span", + AttributionConfig::AggregateLimit::kDefaultDelaySpan}; + base::Time GetClampedTime(base::TimeDelta time_delta, base::Time source_time) { constexpr base::TimeDelta kMinDeltaTime = base::Days(1); return source_time + base::clamp(time_delta, kMinDeltaTime, @@ -52,7 +62,11 @@ AttributionDelayMode delay_mode) : AttributionStorageDelegateImpl(noise_mode, delay_mode, - AttributionConfig()) {} + AttributionConfig()) { + // TODO(tquintanilla): Investigate techniques to valid these params. + config_.aggregate_limit.min_delay = kAggregateReportMinDelay.Get(); + config_.aggregate_limit.delay_span = kAggregateReportDelaySpan.Get(); +} AttributionStorageDelegateImpl::AttributionStorageDelegateImpl( AttributionNoiseMode noise_mode,
diff --git a/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc b/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc index 9d65e0b..c68c8639 100644 --- a/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc
@@ -10,6 +10,7 @@ #include "base/containers/flat_map.h" #include "base/guid.h" +#include "base/test/scoped_feature_list.h" #include "base/time/time.h" #include "components/attribution_reporting/source_type.mojom.h" #include "content/browser/attribution_reporting/attribution_report.h" @@ -19,9 +20,9 @@ #include "content/browser/attribution_reporting/stored_source.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/features.h" namespace content { - namespace { using ::attribution_reporting::mojom::SourceType; @@ -108,8 +109,6 @@ } } -} // namespace - TEST(AttributionStorageDelegateImplTest, ImmediateConversion_FirstWindowUsed) { base::Time source_time = base::Time::Now(); const AttributionReport report = @@ -565,4 +564,56 @@ declared_expiry, source_time)); } +class AttributionStorageDelegateImplTestFeatureConfigured + : public testing::Test { + public: + AttributionStorageDelegateImplTestFeatureConfigured() { + feature_list_.InitWithFeaturesAndParameters( + {{blink::features::kConversionMeasurement, + {{"first_report_window_deadline", "1d"}, + {"second_report_window_deadline", "5d"}, + {"aggregate_report_min_delay", "1m"}, + {"aggregate_report_delay_span", "29m"}}}}, + /*disabled_features=*/{}); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +TEST_F(AttributionStorageDelegateImplTestFeatureConfigured, + ImmediateConversion_FirstFeatureWindowUsed) { + base::Time source_time = base::Time::Now(); + const AttributionReport report = + GetReport(source_time, /*trigger_time=*/source_time); + EXPECT_EQ( + source_time + base::Days(1) + base::Hours(1), + AttributionStorageDelegateImpl().GetEventLevelReportTime( + report.attribution_info().source, report.attribution_info().time)); +} + +TEST_F(AttributionStorageDelegateImplTestFeatureConfigured, + ConversionImmediatelyAfterWindow_NextFeatureWindowUsed) { + base::Time source_time = base::Time::Now(); + + // The deadline for a window is 1 hour before the window. Use a time just + // after the deadline. + base::Time trigger_time = source_time + base::Days(1) + base::Minutes(1); + const AttributionReport report = GetReport(source_time, trigger_time); + EXPECT_EQ( + source_time + base::Days(5) + base::Hours(1), + AttributionStorageDelegateImpl().GetEventLevelReportTime( + report.attribution_info().source, report.attribution_info().time)); +} + +TEST_F(AttributionStorageDelegateImplTestFeatureConfigured, + GetFeatureAggregatableReportTime) { + base::Time trigger_time = base::Time::Now(); + EXPECT_THAT( + AttributionStorageDelegateImpl().GetAggregatableReportTime(trigger_time), + AllOf(Ge(trigger_time + base::Minutes(1)), + Lt(trigger_time + base::Minutes(30)))); +} + +} // namespace } // namespace content
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc index 76c5a9c1..5ed7ff1 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -1199,7 +1199,7 @@ AttributionReport::EventLevelData( delegate_->SanitizeTriggerData(event_trigger->data, source_type), event_trigger->priority, randomized_response_rate, - AttributionReport::EventLevelData::Id(kUnsetReportId))); + AttributionReport::EventLevelData::Id(kUnsetReportId), report_time)); dedup_key = event_trigger->dedup_key; @@ -1331,19 +1331,20 @@ static constexpr char kStoreReportSql[] = "INSERT INTO event_level_reports" "(source_id,trigger_data,trigger_time,report_time," - "priority,failed_send_attempts,external_report_id,debug_key," - "context_origin)" - "VALUES(?,?,?,?,?,0,?,?,?)"; + "initial_report_time,priority,failed_send_attempts," + "external_report_id,debug_key,context_origin)" + "VALUES(?,?,?,?,?,?,0,?,?,?)"; sql::Statement store_report_statement( db_->GetCachedStatement(SQL_FROM_HERE, kStoreReportSql)); store_report_statement.BindInt64(0, *source_id); store_report_statement.BindInt64(1, SerializeUint64(trigger_data)); store_report_statement.BindTime(2, trigger_time); store_report_statement.BindTime(3, report_time); - store_report_statement.BindInt64(4, priority); - store_report_statement.BindString(5, external_report_id.AsLowercaseString()); - BindUint64OrNull(store_report_statement, 6, trigger_debug_key); - store_report_statement.BindString(7, context_origin.Serialize()); + store_report_statement.BindTime(4, report_time); + store_report_statement.BindInt64(5, priority); + store_report_statement.BindString(6, external_report_id.AsLowercaseString()); + BindUint64OrNull(store_report_statement, 7, trigger_debug_key); + store_report_statement.BindString(8, context_origin.Serialize()); if (!store_report_statement.Run()) { return absl::nullopt; } @@ -1355,7 +1356,7 @@ // ordering of columns used for the input to this function. absl::optional<AttributionReport> AttributionStorageSql::ReadReportFromStatement(sql::Statement& statement) { - DCHECK_EQ(statement.ColumnCount(), kSourceColumnCount + 9); + DCHECK_EQ(statement.ColumnCount(), kSourceColumnCount + 10); absl::optional<StoredSourceData> source_data = ReadSourceFromStatement(statement, *db_); @@ -1373,6 +1374,7 @@ ColumnUint64OrNull(statement, col++); auto context_origin = SuitableOrigin::Deserialize(statement.ColumnString(col++)); + base::Time initial_report_time = statement.ColumnTime(col++); // Ensure data is valid before continuing. This could happen if there is // database corruption. @@ -1390,7 +1392,8 @@ trigger_debug_key, std::move(*context_origin)), report_time, std::move(external_report_id), failed_send_attempts, AttributionReport::EventLevelData(trigger_data, conversion_priority, - randomized_response_rate, report_id)); + randomized_response_rate, report_id, + initial_report_time)); } std::vector<AttributionReport> AttributionStorageSql::GetAttributionReports( @@ -2264,6 +2267,7 @@ "trigger_data INTEGER NOT NULL," "trigger_time INTEGER NOT NULL," "report_time INTEGER NOT NULL," + "initial_report_time INTEGER NOT NULL," "priority INTEGER NOT NULL," "failed_send_attempts INTEGER NOT NULL," "external_report_id TEXT NOT NULL,"
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.h b/content/browser/attribution_reporting/attribution_storage_sql.h index 198d11f..00acedbf 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.h +++ b/content/browser/attribution_reporting/attribution_storage_sql.h
@@ -53,11 +53,11 @@ class CONTENT_EXPORT AttributionStorageSql : public AttributionStorage { public: // Version number of the database. - static constexpr int kCurrentVersionNumber = 47; + static constexpr int kCurrentVersionNumber = 48; // Earliest version which can use a `kCurrentVersionNumber` database // without failing. - static constexpr int kCompatibleVersionNumber = 47; + static constexpr int kCompatibleVersionNumber = 48; // Latest version of the database that cannot be upgraded to // `kCurrentVersionNumber` without razing the database.
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc b/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc index 1b9b9cf..49668edb 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc
@@ -5,12 +5,15 @@ #include "content/browser/attribution_reporting/attribution_storage_sql_migrations.h" #include "base/check.h" +#include "base/containers/span.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 "components/attribution_reporting/source_type.mojom-shared.h" #include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage_sql.h" +#include "content/browser/attribution_reporting/attribution_utils.h" #include "content/browser/attribution_reporting/common_source_info.h" #include "content/browser/attribution_reporting/rate_limit_table.h" #include "sql/database.h" @@ -577,6 +580,107 @@ return true; } +bool To48(sql::Database* db) { + static constexpr char kConversionTableSql[] = + "CREATE TABLE new_event_level_reports(" + "report_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + "source_id INTEGER NOT NULL," + "trigger_data INTEGER NOT NULL," + "trigger_time INTEGER NOT NULL," + "report_time INTEGER NOT NULL," + "initial_report_time INTEGER NOT NULL," + "priority INTEGER NOT NULL," + "failed_send_attempts INTEGER NOT NULL," + "external_report_id TEXT NOT NULL," + "debug_key INTEGER," + "context_origin TEXT NOT NULL)"; + if (!db->Execute(kConversionTableSql)) { + return false; + } + + static constexpr char kInsertReportsSql[] = + "INSERT INTO new_event_level_reports " + "SELECT report_id,source_id,trigger_data,trigger_time," + "report_time,report_time,priority,failed_send_attempts," + "external_report_id," + "debug_key,context_origin " + "FROM event_level_reports"; + if (!db->Execute(kInsertReportsSql)) { + return false; + } + + static constexpr char kRetrieveReportTimes[] = + "SELECT I.source_time,I.event_report_window_time," + "R.trigger_time,I.source_type,R.report_id " + "FROM event_level_reports R " + "JOIN sources I " + "ON I.source_id=R.source_id"; + sql::Statement select_statement(db->GetUniqueStatement(kRetrieveReportTimes)); + + static constexpr char kUpdateOriginalTime[] = + "UPDATE new_event_level_reports SET initial_report_time=? " + "WHERE report_id=?"; + sql::Statement update_statement(db->GetUniqueStatement(kUpdateOriginalTime)); + + while (select_statement.Step()) { + base::Time initial_report_time; + int source_type = select_statement.ColumnInt(3); + base::Time source_time = select_statement.ColumnTime(0); + base::Time event_report_window_time = select_statement.ColumnTime(1); + base::Time trigger_time = select_statement.ColumnTime(2); + switch (source_type) { + case static_cast<int>( + attribution_reporting::mojom::SourceType::kNavigation): + initial_report_time = ComputeReportTime( + source_time, event_report_window_time, trigger_time, + /*early_deadlines=*/ + base::span<const base::TimeDelta>({base::Days(2), base::Days(7)})); + break; + case static_cast<int>(attribution_reporting::mojom::SourceType::kEvent): + initial_report_time = ComputeReportTime( + source_time, event_report_window_time, trigger_time, + /*early_deadlines=*/{}); + break; + default: + continue; + } + + update_statement.Reset(/*clear_bound_vars=*/true); + update_statement.BindTime(0, initial_report_time); + update_statement.BindInt64(1, select_statement.ColumnInt64(4)); + if (!update_statement.Run()) { + return false; + } + } + + if (!db->Execute("DROP TABLE event_level_reports")) { + return false; + } + + static constexpr char kRenameSql[] = + "ALTER TABLE new_event_level_reports " + "RENAME TO event_level_reports"; + if (!db->Execute(kRenameSql)) { + return false; + } + + static constexpr char kConversionReportTimeIndexSql[] = + "CREATE INDEX event_level_reports_by_report_time " + "ON event_level_reports(report_time)"; + if (!db->Execute(kConversionReportTimeIndexSql)) { + return false; + } + + static constexpr char kConversionImpressionIdIndexSql[] = + "CREATE INDEX event_level_reports_by_source_id " + "ON event_level_reports(source_id)"; + if (!db->Execute(kConversionImpressionIdIndexSql)) { + return false; + } + + return true; +} + } // namespace bool UpgradeAttributionStorageSqlSchema(sql::Database* db, @@ -603,12 +707,13 @@ MaybeMigrate(db, meta_table, 43, &To44) && MaybeMigrate(db, meta_table, 44, &To45) && MaybeMigrate(db, meta_table, 45, &To46) && - MaybeMigrate(db, meta_table, 46, &To47); + MaybeMigrate(db, meta_table, 46, &To47) && + MaybeMigrate(db, meta_table, 47, &To48); if (!ok) { return false; } - static_assert(AttributionStorageSql::kCurrentVersionNumber == 47, + static_assert(AttributionStorageSql::kCurrentVersionNumber == 48, "Add migration(s) above."); if (base::ThreadTicks::IsSupported()) {
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_migrations_unittest.cc b/content/browser/attribution_reporting/attribution_storage_sql_migrations_unittest.cc index f738799e..e4fe8bd 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql_migrations_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql_migrations_unittest.cc
@@ -669,11 +669,12 @@ ASSERT_EQ(3, s.ColumnInt(2)); ASSERT_EQ(4, s.ColumnInt(3)); ASSERT_EQ(5, s.ColumnInt(4)); - ASSERT_EQ(6, s.ColumnInt(5)); - ASSERT_EQ(7, s.ColumnInt(6)); - ASSERT_EQ(8, s.ColumnInt(7)); - ASSERT_EQ(9, s.ColumnInt(8)); - ASSERT_EQ("https://d.test", s.ColumnString(9)); + ASSERT_EQ(5, s.ColumnInt(5)); // initial_report_time + ASSERT_EQ(6, s.ColumnInt(6)); + ASSERT_EQ(7, s.ColumnInt(7)); + ASSERT_EQ(8, s.ColumnInt(8)); + ASSERT_EQ(9, s.ColumnInt(9)); + ASSERT_EQ("https://d.test", s.ColumnString(10)); ASSERT_FALSE(s.Step()); } @@ -828,4 +829,64 @@ histograms.ExpectTotalCount("Conversions.Storage.MigrationTime", 1); } +TEST_F(AttributionStorageSqlMigrationsTest, MigrateVersion47ToCurrent) { + base::HistogramTester histograms; + LoadDatabase(GetVersionFilePath(47), DbPath()); + + // Verify pre-conditions. + { + sql::Database db; + ASSERT_TRUE(db.Open(DbPath())); + + sql::Statement s( + db.GetUniqueStatement("SELECT * FROM event_level_reports")); + + ASSERT_TRUE(s.Step()); + ASSERT_EQ(5, s.ColumnInt(4)); + ASSERT_EQ(6, s.ColumnInt(5)); + ASSERT_TRUE(s.Step()); + ASSERT_EQ(6, s.ColumnInt(4)); + ASSERT_EQ(7, s.ColumnInt(5)); + ASSERT_FALSE(s.Step()); + } + + MigrateDatabase(); + + // Verify schema is current. + { + sql::Database db; + ASSERT_TRUE(db.Open(DbPath())); + + CheckVersionNumbers(&db); + + // Compare normalized schemas + EXPECT_EQ(NormalizeSchema(GetCurrentSchema()), + NormalizeSchema(db.GetSchema())); + + // Verify that data is preserved across the migration. + sql::Statement s( + db.GetUniqueStatement("SELECT * FROM event_level_reports")); + + ASSERT_TRUE(s.Step()); + ASSERT_EQ(5, s.ColumnInt(4)); + // navigation source + ASSERT_EQ(base::Time::FromDeltaSinceWindowsEpoch( + base::Milliseconds(1643239183000)), + s.ColumnTime(5)); + ASSERT_EQ(6, s.ColumnInt(6)); + ASSERT_TRUE(s.Step()); + ASSERT_EQ(6, s.ColumnInt(4)); + // event source + ASSERT_EQ(base::Time::FromDeltaSinceWindowsEpoch( + base::Milliseconds(1643239184000)), + s.ColumnTime(5)); + ASSERT_EQ(7, s.ColumnInt(6)); + ASSERT_FALSE(s.Step()); + } + + // DB creation histograms should be recorded. + histograms.ExpectTotalCount("Conversions.Storage.CreationTime", 0); + histograms.ExpectTotalCount("Conversions.Storage.MigrationTime", 1); +} + } // namespace content
diff --git a/content/browser/attribution_reporting/attribution_test_utils.cc b/content/browser/attribution_reporting/attribution_test_utils.cc index a861d70..781a2e1 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.cc +++ b/content/browser/attribution_reporting/attribution_test_utils.cc
@@ -476,7 +476,8 @@ attribution_info_, report_time_, external_report_id_, /*failed_send_attempts=*/0, AttributionReport::EventLevelData(trigger_data_, priority_, - randomized_trigger_rate_, report_id_)); + randomized_trigger_rate_, report_id_, + report_time_)); } AttributionReport ReportBuilder::BuildAggregatableAttribution() const {
diff --git a/content/browser/attribution_reporting/attribution_utils.cc b/content/browser/attribution_reporting/attribution_utils.cc index 5e526f9..69560a22 100644 --- a/content/browser/attribution_reporting/attribution_utils.cc +++ b/content/browser/attribution_reporting/attribution_utils.cc
@@ -8,11 +8,13 @@ #include "base/check_op.h" #include "base/containers/span.h" #include "base/json/json_writer.h" +#include "base/metrics/field_trial_params.h" #include "base/time/time.h" #include "base/values.h" #include "components/attribution_reporting/source_type.mojom.h" #include "content/browser/attribution_reporting/common_source_info.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/features.h" namespace content { @@ -22,10 +24,19 @@ constexpr base::TimeDelta kWindowDeadlineOffset = base::Hours(1); +const base::FeatureParam<base::TimeDelta> kFirstReportWindowDeadline{ + &blink::features::kConversionMeasurement, "first_report_window_deadline", + base::Days(2)}; + +const base::FeatureParam<base::TimeDelta> kSecondReportWindowDeadline{ + &blink::features::kConversionMeasurement, "second_report_window_deadline", + base::Days(7)}; + base::span<const base::TimeDelta> EarlyDeadlines(SourceType source_type) { - static constexpr base::TimeDelta kEarlyDeadlinesNavigation[] = { - base::Days(2), - base::Days(7), + // TODO(tquintanilla): Investigate techniques to valid these params. + static const base::TimeDelta kEarlyDeadlinesNavigation[] = { + kFirstReportWindowDeadline.Get(), + kSecondReportWindowDeadline.Get(), }; switch (source_type) { @@ -51,11 +62,13 @@ } // namespace -base::Time ComputeReportTime(const CommonSourceInfo& source, - base::Time event_report_window_time, - base::Time trigger_time) { +base::Time ComputeReportTime( + base::Time source_time, + base::Time event_report_window_time, + base::Time trigger_time, + base::span<const base::TimeDelta> early_deadlines) { base::TimeDelta expiry_deadline = - ExpiryDeadline(source.source_time(), event_report_window_time); + ExpiryDeadline(source_time, event_report_window_time); // After the initial impression, a schedule of reporting windows and deadlines // associated with that impression begins. The time between impression time @@ -78,17 +91,24 @@ // Given a conversion that happened at `trigger_time`, find the first // applicable reporting window this conversion should be reported at. - for (base::TimeDelta early_deadline : EarlyDeadlines(source.source_type())) { + for (base::TimeDelta early_deadline : early_deadlines) { // If this window is valid for the conversion, use it. // |trigger_time| is roughly ~now. - if (source.source_time() + early_deadline >= trigger_time && + if (source_time + early_deadline >= trigger_time && early_deadline < deadline_to_use) { deadline_to_use = early_deadline; break; } } - return ReportTimeFromDeadline(source.source_time(), deadline_to_use); + return ReportTimeFromDeadline(source_time, deadline_to_use); +} + +base::Time ComputeReportTime(const CommonSourceInfo& source, + base::Time event_report_window_time, + base::Time trigger_time) { + return ComputeReportTime(source.source_time(), event_report_window_time, + trigger_time, EarlyDeadlines(source.source_type())); } int NumReportWindows(SourceType source_type) {
diff --git a/content/browser/attribution_reporting/attribution_utils.h b/content/browser/attribution_reporting/attribution_utils.h index cc22554..cb7d13f 100644 --- a/content/browser/attribution_reporting/attribution_utils.h +++ b/content/browser/attribution_reporting/attribution_utils.h
@@ -7,12 +7,14 @@ #include <string> +#include "base/containers/span.h" #include "components/attribution_reporting/source_type.mojom-forward.h" #include "content/common/content_export.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace base { class Time; +class TimeDelta; class ValueView; } // namespace base @@ -22,6 +24,11 @@ // Calculates the report time for a conversion associated with a given // source. +base::Time ComputeReportTime(base::Time source_time, + base::Time event_report_window_time, + base::Time trigger_time, + base::span<const base::TimeDelta> early_deadlines); + base::Time ComputeReportTime(const CommonSourceInfo& source, base::Time event_report_window_time, base::Time trigger_time);
diff --git a/content/browser/attribution_reporting/sql_queries.h b/content/browser/attribution_reporting/sql_queries.h index 6b028d9..6c6f7606 100644 --- a/content/browser/attribution_reporting/sql_queries.h +++ b/content/browser/attribution_reporting/sql_queries.h
@@ -169,7 +169,7 @@ ATTRIBUTION_SOURCE_COLUMNS_SQL("I.") \ ",C.trigger_data,C.trigger_time,C.report_time,C.report_id," \ "C.priority,C.failed_send_attempts,C.external_report_id,C.debug_key," \ - "C.context_origin " \ + "C.context_origin,C.initial_report_time " \ "FROM event_level_reports C " \ "JOIN sources I ON C.source_id=I.source_id "
diff --git a/content/browser/interest_group/ad_auction_service_impl.h b/content/browser/interest_group/ad_auction_service_impl.h index 81cd0dd0..29f1533 100644 --- a/content/browser/interest_group/ad_auction_service_impl.h +++ b/content/browser/interest_group/ad_auction_service_impl.h
@@ -119,8 +119,6 @@ const url::Origin& origin) const; // Deletes `auction`. - // TODO(crbug.com/1410340): Handle non reserved private aggregation requests, - // which are currently ignored. void OnAuctionComplete( RunAdAuctionCallback callback, GURL urn_uuid,
diff --git a/content/browser/smart_card/smart_card_reader_tracker.cc b/content/browser/smart_card/smart_card_reader_tracker.cc index 2fca304..7e86b0f 100644 --- a/content/browser/smart_card/smart_card_reader_tracker.cc +++ b/content/browser/smart_card/smart_card_reader_tracker.cc
@@ -574,6 +574,20 @@ std::vector<std::string> new_readers = IdentifyNewReaders(current_readers); + if (new_readers.empty()) { + // We already know about all existing readers and their states. + // The cache can be considered still up to date. + while (!pending_get_readers_requests_.empty()) { + tracker_->GetReadersFromCache( + std::move(pending_get_readers_requests_.front())); + pending_get_readers_requests_.pop(); + } + // And we can go straight to Tracking (skipping WaitInitialReaderStatus). + tracker_->ChangeState( + std::make_unique<Tracking>(*tracker_, std::move(context_))); + return; + } + tracker_->ChangeState(std::make_unique<WaitInitialReaderStatus>( *tracker_, std::move(context_), std::move(pending_get_readers_requests_), new_readers));
diff --git a/content/browser/smart_card/smart_card_reader_tracker.h b/content/browser/smart_card/smart_card_reader_tracker.h index c2e862c..3ad8159 100644 --- a/content/browser/smart_card/smart_card_reader_tracker.h +++ b/content/browser/smart_card/smart_card_reader_tracker.h
@@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/supports_user_data.h" +#include "content/common/content_export.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/device/public/mojom/smart_card.mojom.h" #include "third_party/blink/public/mojom/smart_card/smart_card.mojom-forward.h" @@ -26,7 +27,8 @@ // // Translates the winscard.h level constructs involving reader state into the // higher-level `SmartCardReaderInfo`. -class SmartCardReaderTracker : public base::SupportsUserData::Data { +class CONTENT_EXPORT SmartCardReaderTracker + : public base::SupportsUserData::Data { public: // Observer class for changes to smart card readers. class Observer : public base::CheckedObserver {
diff --git a/content/browser/smart_card/smart_card_reader_tracker_unittest.cc b/content/browser/smart_card/smart_card_reader_tracker_unittest.cc new file mode 100644 index 0000000..06446e5 --- /dev/null +++ b/content/browser/smart_card/smart_card_reader_tracker_unittest.cc
@@ -0,0 +1,360 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/smart_card/smart_card_reader_tracker.h" +#include "base/run_loop.h" +#include "base/test/task_environment.h" +#include "base/test/test_future.h" +#include "content/browser/smart_card/mock_smart_card_context_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/smart_card/smart_card.mojom.h" + +using base::test::TestFuture; +using blink::mojom::SmartCardReaderInfo; +using blink::mojom::SmartCardReaderInfoPtr; +using blink::mojom::SmartCardReaderState; +using blink::mojom::SmartCardResponseCode; +using device::mojom::SmartCardContext; +using device::mojom::SmartCardError; +using device::mojom::SmartCardReaderStateFlags; +using device::mojom::SmartCardReaderStateOut; +using device::mojom::SmartCardReaderStateOutPtr; + +using testing::_; +using testing::ElementsAre; +using testing::InSequence; + +bool operator==(const SmartCardReaderInfo& a, const SmartCardReaderInfo& b) { + return a.name == b.name && a.state == b.state && a.atr == b.atr; +} + +MATCHER_P3(IsReaderInfo, name, state, atr, "") { + return !arg.is_null() && arg->name == name && arg->state == state && + arg->atr == atr; +} + +namespace blink::mojom { + +void PrintTo(const SmartCardReaderInfo& reader, std::ostream* os) { + *os << "SmartCardReaderInfo(" << reader.name << ", " << reader.state + << ", ATR{"; + + bool first = true; + for (uint8_t num : reader.atr) { + if (!first) { + *os << ","; + } + // Treat it as a number instead of as a char. + *os << unsigned(num); + first = false; + } + *os << "})"; +} + +void PrintTo(const SmartCardReaderInfoPtr& reader_ptr, std::ostream* os) { + if (!reader_ptr) { + *os << "SmartCardReaderInfoPtr(NULL)"; + return; + } + PrintTo(*reader_ptr, os); +} + +} // namespace blink::mojom + +namespace content { +namespace { + +class SmartCardReaderTrackerTest : public testing::Test { + protected: + base::test::TaskEnvironment task_environment_; +}; + +class MockTrackerObserver : public SmartCardReaderTracker::Observer { + public: + MOCK_METHOD(void, + OnReaderAdded, + (const SmartCardReaderInfo& reader_info), + (override)); + + MOCK_METHOD(void, + OnReaderRemoved, + (const SmartCardReaderInfo& reader_info), + (override)); + + MOCK_METHOD(void, + OnReaderChanged, + (const SmartCardReaderInfo& reader_info), + (override)); + + MOCK_METHOD(void, OnError, (SmartCardResponseCode response_code), (override)); +}; + +TEST_F(SmartCardReaderTrackerTest, ReaderChanged) { + MockSmartCardContextFactory mock_context_factory; + SmartCardReaderTracker tracker(mock_context_factory.GetRemote(), + /*context_supports_reader_added=*/true); + TestFuture<SmartCardContext::GetStatusChangeCallback> + last_get_status_callback; + { + InSequence s; + + // Request what readers are currently available. + EXPECT_CALL(mock_context_factory, ListReaders(_)) + .WillOnce([](SmartCardContext::ListReadersCallback callback) { + std::vector<std::string> readers{"Reader A", "Reader B"}; + auto result = + device::mojom::SmartCardListReadersResult::NewReaders(readers); + std::move(callback).Run(std::move(result)); + }); + + // Request the state of each of those readers. + EXPECT_CALL(mock_context_factory, GetStatusChange(_, _, _)) + .WillOnce( + [](base::TimeDelta timeout, + std::vector<device::mojom::SmartCardReaderStateInPtr> states_in, + SmartCardContext::GetStatusChangeCallback callback) { + ASSERT_EQ(states_in.size(), 2U); + ASSERT_EQ(states_in[0]->reader, "Reader A"); + EXPECT_TRUE(states_in[0]->current_state->unaware); + EXPECT_FALSE(states_in[0]->current_state->ignore); + EXPECT_FALSE(states_in[0]->current_state->changed); + EXPECT_FALSE(states_in[0]->current_state->unknown); + EXPECT_FALSE(states_in[0]->current_state->unavailable); + EXPECT_FALSE(states_in[0]->current_state->empty); + EXPECT_FALSE(states_in[0]->current_state->present); + EXPECT_FALSE(states_in[0]->current_state->exclusive); + EXPECT_FALSE(states_in[0]->current_state->inuse); + EXPECT_FALSE(states_in[0]->current_state->mute); + EXPECT_FALSE(states_in[0]->current_state->unpowered); + + ASSERT_EQ(states_in[1]->reader, "Reader B"); + EXPECT_TRUE(states_in[1]->current_state->unaware); + EXPECT_FALSE(states_in[1]->current_state->ignore); + EXPECT_FALSE(states_in[1]->current_state->changed); + EXPECT_FALSE(states_in[1]->current_state->unknown); + EXPECT_FALSE(states_in[1]->current_state->unavailable); + EXPECT_FALSE(states_in[1]->current_state->empty); + EXPECT_FALSE(states_in[1]->current_state->present); + EXPECT_FALSE(states_in[1]->current_state->exclusive); + EXPECT_FALSE(states_in[1]->current_state->inuse); + EXPECT_FALSE(states_in[1]->current_state->mute); + EXPECT_FALSE(states_in[1]->current_state->unpowered); + + std::vector<SmartCardReaderStateOutPtr> states_out; + + auto state_flags = SmartCardReaderStateFlags::New(); + state_flags->empty = true; + states_out.push_back(SmartCardReaderStateOut::New( + "Reader A", std::move(state_flags), std::vector<uint8_t>())); + + state_flags = SmartCardReaderStateFlags::New(); + state_flags->present = true; + state_flags->inuse = true; + states_out.push_back(SmartCardReaderStateOut::New( + "Reader B", std::move(state_flags), + std::vector<uint8_t>({1u, 2u, 3u, 4u}))); + + auto result = + device::mojom::SmartCardStatusChangeResult::NewReaderStates( + std::move(states_out)); + std::move(callback).Run(std::move(result)); + }); + + // Request to be notified of state changes on those readers and on the + // addition of a new reader. + // SmartCardContext reports that "Reader B" has changed (card was removed, + // thus it's now empty). + EXPECT_CALL(mock_context_factory, GetStatusChange(_, _, _)) + .WillOnce( + [](base::TimeDelta timeout, + std::vector<device::mojom::SmartCardReaderStateInPtr> states_in, + SmartCardContext::GetStatusChangeCallback callback) { + ASSERT_EQ(states_in.size(), 3U); + + EXPECT_EQ(states_in[0]->reader, R"(\\?PnP?\Notification)"); + EXPECT_FALSE(states_in[0]->current_state->unaware); + EXPECT_FALSE(states_in[0]->current_state->ignore); + EXPECT_FALSE(states_in[0]->current_state->changed); + EXPECT_FALSE(states_in[0]->current_state->unknown); + EXPECT_FALSE(states_in[0]->current_state->unavailable); + EXPECT_FALSE(states_in[0]->current_state->empty); + EXPECT_FALSE(states_in[0]->current_state->present); + EXPECT_FALSE(states_in[0]->current_state->exclusive); + EXPECT_FALSE(states_in[0]->current_state->inuse); + EXPECT_FALSE(states_in[0]->current_state->mute); + EXPECT_FALSE(states_in[0]->current_state->unpowered); + + EXPECT_EQ(states_in[1]->reader, "Reader A"); + EXPECT_FALSE(states_in[1]->current_state->unaware); + EXPECT_FALSE(states_in[1]->current_state->ignore); + EXPECT_FALSE(states_in[1]->current_state->changed); + EXPECT_FALSE(states_in[1]->current_state->unknown); + EXPECT_FALSE(states_in[1]->current_state->unavailable); + EXPECT_TRUE(states_in[1]->current_state->empty); + EXPECT_FALSE(states_in[1]->current_state->present); + EXPECT_FALSE(states_in[1]->current_state->exclusive); + EXPECT_FALSE(states_in[1]->current_state->inuse); + EXPECT_FALSE(states_in[1]->current_state->mute); + EXPECT_FALSE(states_in[1]->current_state->unpowered); + + EXPECT_EQ(states_in[2]->reader, "Reader B"); + EXPECT_FALSE(states_in[2]->current_state->unaware); + EXPECT_FALSE(states_in[2]->current_state->ignore); + EXPECT_FALSE(states_in[2]->current_state->changed); + EXPECT_FALSE(states_in[2]->current_state->unknown); + EXPECT_FALSE(states_in[2]->current_state->unavailable); + EXPECT_FALSE(states_in[2]->current_state->empty); + EXPECT_TRUE(states_in[2]->current_state->present); + EXPECT_FALSE(states_in[2]->current_state->exclusive); + EXPECT_TRUE(states_in[2]->current_state->inuse); + EXPECT_FALSE(states_in[2]->current_state->mute); + EXPECT_FALSE(states_in[2]->current_state->unpowered); + + std::vector<SmartCardReaderStateOutPtr> states_out; + + auto state_flags = SmartCardReaderStateFlags::New(); + // Nothing was added or removed (thus all flags are false) + states_out.push_back(SmartCardReaderStateOut::New( + R"(\\?PnP?\Notification)", std::move(state_flags), + std::vector<uint8_t>())); + + state_flags = SmartCardReaderStateFlags::New(); + // Nothing changed for Reader A. + state_flags->empty = true; + states_out.push_back(SmartCardReaderStateOut::New( + "Reader A", std::move(state_flags), std::vector<uint8_t>())); + + state_flags = SmartCardReaderStateFlags::New(); + // Reader be has changed. It's now empty as well. + state_flags->changed = true; + state_flags->empty = true; + states_out.push_back(SmartCardReaderStateOut::New( + "Reader B", std::move(state_flags), std::vector<uint8_t>())); + + auto result = + device::mojom::SmartCardStatusChangeResult::NewReaderStates( + std::move(states_out)); + std::move(callback).Run(std::move(result)); + }); + + //// + // Now rinse and repeat + + // Request what readers are currently available. + // Done just in case a reader was added in between PC/SC calls or their + // processing. Not a water-tight solution but it's the best the tracker can + // do given PC/SC limitations. A tracker user is free to call Start() again + // to force a refresh. + // + // Still the same readers. + EXPECT_CALL(mock_context_factory, ListReaders(_)) + .WillOnce([](SmartCardContext::ListReadersCallback callback) { + std::vector<std::string> readers{"Reader A", "Reader B"}; + auto result = + device::mojom::SmartCardListReadersResult::NewReaders(readers); + std::move(callback).Run(std::move(result)); + }); + + // Since ListReaders did not return any reader unknown to the tracker, + // it will now skip to waiting to be notified on any changes. + EXPECT_CALL(mock_context_factory, GetStatusChange(_, _, _)) + .WillOnce( + [](base::TimeDelta timeout, + std::vector<device::mojom::SmartCardReaderStateInPtr> states_in, + SmartCardContext::GetStatusChangeCallback callback) { + ASSERT_EQ(states_in.size(), 3U); + + EXPECT_EQ(states_in[0]->reader, R"(\\?PnP?\Notification)"); + EXPECT_FALSE(states_in[0]->current_state->unaware); + EXPECT_FALSE(states_in[0]->current_state->ignore); + EXPECT_FALSE(states_in[0]->current_state->changed); + EXPECT_FALSE(states_in[0]->current_state->unknown); + EXPECT_FALSE(states_in[0]->current_state->unavailable); + EXPECT_FALSE(states_in[0]->current_state->empty); + EXPECT_FALSE(states_in[0]->current_state->present); + EXPECT_FALSE(states_in[0]->current_state->exclusive); + EXPECT_FALSE(states_in[0]->current_state->inuse); + EXPECT_FALSE(states_in[0]->current_state->mute); + EXPECT_FALSE(states_in[0]->current_state->unpowered); + + EXPECT_EQ(states_in[1]->reader, "Reader A"); + EXPECT_FALSE(states_in[1]->current_state->unaware); + EXPECT_FALSE(states_in[1]->current_state->ignore); + EXPECT_FALSE(states_in[1]->current_state->changed); + EXPECT_FALSE(states_in[1]->current_state->unknown); + EXPECT_FALSE(states_in[1]->current_state->unavailable); + EXPECT_TRUE(states_in[1]->current_state->empty); + EXPECT_FALSE(states_in[1]->current_state->present); + EXPECT_FALSE(states_in[1]->current_state->exclusive); + EXPECT_FALSE(states_in[1]->current_state->inuse); + EXPECT_FALSE(states_in[1]->current_state->mute); + EXPECT_FALSE(states_in[1]->current_state->unpowered); + + // Note that the tracker now states that Reader B is empty as + // well. + EXPECT_EQ(states_in[2]->reader, "Reader B"); + EXPECT_FALSE(states_in[1]->current_state->unaware); + EXPECT_FALSE(states_in[1]->current_state->ignore); + EXPECT_FALSE(states_in[1]->current_state->changed); + EXPECT_FALSE(states_in[1]->current_state->unknown); + EXPECT_FALSE(states_in[1]->current_state->unavailable); + EXPECT_TRUE(states_in[1]->current_state->empty); + EXPECT_FALSE(states_in[1]->current_state->present); + EXPECT_FALSE(states_in[1]->current_state->exclusive); + EXPECT_FALSE(states_in[1]->current_state->inuse); + EXPECT_FALSE(states_in[1]->current_state->mute); + EXPECT_FALSE(states_in[1]->current_state->unpowered); + + std::vector<SmartCardReaderStateOutPtr> states_out; + + // Let the test code run this callback. + std::move(callback).Run( + device::mojom::SmartCardStatusChangeResult::NewError( + SmartCardError::kNoService)); + }); + } + + MockTrackerObserver observer; + { + InSequence s; + + EXPECT_CALL(observer, OnReaderAdded(SmartCardReaderInfo( + "Reader A", SmartCardReaderState::kEmpty, + std::vector<uint8_t>()))); + + EXPECT_CALL(observer, OnReaderAdded(SmartCardReaderInfo( + "Reader B", SmartCardReaderState::kInuse, + std::vector<uint8_t>({1u, 2u, 3u, 4u})))); + + EXPECT_CALL(observer, OnReaderChanged(SmartCardReaderInfo( + "Reader B", SmartCardReaderState::kEmpty, + std::vector<uint8_t>({})))); + + EXPECT_CALL(observer, OnError(SmartCardResponseCode::kNoService)); + } + + TestFuture<blink::mojom::SmartCardGetReadersResultPtr> start_future; + tracker.Start(&observer, start_future.GetCallback()); + + blink::mojom::SmartCardGetReadersResultPtr result = start_future.Take(); + ASSERT_TRUE(result->is_readers()); + + std::vector<blink::mojom::SmartCardReaderInfoPtr>& readers = + result->get_readers(); + // NB: Ideally would use `testing::UnorderedElementsAre`, but it doesn't work + // with non-copiable types. + // It returns the state of the readers *before* the change. + ASSERT_EQ(readers.size(), 2U); + EXPECT_THAT(readers[0], IsReaderInfo("Reader A", SmartCardReaderState::kEmpty, + std::vector<uint8_t>())); + EXPECT_THAT(readers[1], IsReaderInfo("Reader B", SmartCardReaderState::kInuse, + std::vector<uint8_t>({1u, 2u, 3u, 4u}))); + + base::RunLoop run_loop; + run_loop.RunUntilIdle(); +} + +} // namespace +} // namespace content
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 54fec66..bcd1dcf1 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -4449,6 +4449,36 @@ return web_contents_; } +CookieChangeObserver::CookieChangeObserver(content::WebContents* web_contents, + int num_expected_calls) + : content::WebContentsObserver(web_contents), + run_loop_(base::RunLoop::Type::kNestableTasksAllowed), + num_expected_calls_(num_expected_calls) {} + +CookieChangeObserver::~CookieChangeObserver() = default; + +void CookieChangeObserver::Wait() { + run_loop_.Run(); +} + +void CookieChangeObserver::OnCookiesAccessed( + content::RenderFrameHost* render_frame_host, + const content::CookieAccessDetails& details) { + OnCookieAccessed(); +} + +void CookieChangeObserver::OnCookiesAccessed( + content::NavigationHandle* navigation, + const content::CookieAccessDetails& details) { + OnCookieAccessed(); +} + +void CookieChangeObserver::OnCookieAccessed() { + if (++num_seen_ == num_expected_calls_) { + run_loop_.Quit(); + } +} + base::CallbackListSubscription RegisterWebContentsCreationCallback( base::RepeatingCallback<void(WebContents*)> callback) { return WebContentsImpl::FriendWrapper::AddCreatedCallbackForTesting(callback);
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 52e90a66..b966b74 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -2420,6 +2420,29 @@ int num_new_contents_seen_ = 0; }; +// Waits for the given number of calls to +// WebContentsObserver::OnCookiesAccessed. +class CookieChangeObserver : public content::WebContentsObserver { + public: + explicit CookieChangeObserver(content::WebContents* web_contents, + int num_expected_calls = 1); + ~CookieChangeObserver() override; + + void Wait(); + + private: + void OnCookiesAccessed(content::RenderFrameHost* render_frame_host, + const content::CookieAccessDetails& details) override; + void OnCookiesAccessed(content::NavigationHandle* navigation, + const content::CookieAccessDetails& details) override; + + void OnCookieAccessed(); + + base::RunLoop run_loop_; + int num_seen_ = 0; + int num_expected_calls_; +}; + [[nodiscard]] base::CallbackListSubscription RegisterWebContentsCreationCallback( base::RepeatingCallback<void(WebContents*)> callback);
diff --git a/content/services/auction_worklet/trusted_signals.cc b/content/services/auction_worklet/trusted_signals.cc index 67aa40b..532e1d2d 100644 --- a/content/services/auction_worklet/trusted_signals.cc +++ b/content/services/auction_worklet/trusted_signals.cc
@@ -111,12 +111,16 @@ return out; v8::Local<v8::Value> named_object_value; - // Don't consider the entire object missing a fatal error. + // Don't consider the entire object missing (or values other than objects) a + // fatal error. if (!v8_object ->Get(v8_helper->scratch_context(), v8_helper->CreateStringFromLiteral(name)) .ToLocal(&named_object_value) || - !named_object_value->IsObject()) { + !named_object_value->IsObject() || + // Arrays are considered objects by Javascript, but they're not the object + // type we're looking for. + named_object_value->IsArray()) { return out; } @@ -190,7 +194,10 @@ ->Get(v8_helper->scratch_context(), v8_helper->CreateStringFromLiteral("perInterestGroupData")) .ToLocal(&per_group_data_value) || - !per_group_data_value->IsObject()) { + !per_group_data_value->IsObject() || + // Arrays are considered objects by Javascript, but they're not the object + // type we're looking for. + per_group_data_value->IsArray()) { return {}; } v8::Local<v8::Object> per_group_data_object = @@ -205,7 +212,10 @@ v8::Local<v8::Value> per_interest_group_data_value; if (!per_group_data_object->Get(v8_helper->scratch_context(), v8_name) .ToLocal(&per_interest_group_data_value) || - !per_interest_group_data_value->IsObject()) { + !per_interest_group_data_value->IsObject() || + // Arrays are considered objects by Javascript, but they're not the + // object type we're looking for. + per_group_data_value->IsArray()) { continue; }
diff --git a/content/services/auction_worklet/trusted_signals_unittest.cc b/content/services/auction_worklet/trusted_signals_unittest.cc index 329222ba..d1b840f 100644 --- a/content/services/auction_worklet/trusted_signals_unittest.cc +++ b/content/services/auction_worklet/trusted_signals_unittest.cc
@@ -443,15 +443,36 @@ } TEST_F(TrustedSignalsTest, BiddingSignalsNestedEntriesNotObject) { - scoped_refptr<TrustedSignals::Result> signals = - FetchBiddingSignalsWithResponse( - GURL("https://url.test/" - "?hostname=publisher&keys=key1&interestGroupNames=name1"), - R"({"keys":4.1,"perInterestGroupData":"42"})", {"name1"}, {"key1"}, - kHostname); - ASSERT_TRUE(signals); - EXPECT_EQ(R"({"key1":null})", ExtractBiddingSignals(signals.get(), {"key1"})); - EXPECT_EQ(nullptr, signals->GetPriorityVector("name1")); + const char* kTestCases[] = { + "4", "[3]", + // List with a valid priority vector as the first element, which should + // not be treated as the priority vector of an interest group named "0". + R"([{"priorityVector" : {"a":1}}])", "null", R"("string")"}; + + for (const char* test_case : kTestCases) { + SCOPED_TRACE(test_case); + + scoped_refptr<TrustedSignals::Result> signals = + FetchBiddingSignalsWithResponse( + GURL("https://url.test/?hostname=publisher" + "&keys=0,key1,length" + "&interestGroupNames=0,length,name1"), + base::StringPrintf(R"({"keys":%s,"perInterestGroupData":%s})", + test_case, test_case), + {"name1", "0", "length"}, {"key1", "0", "length"}, kHostname); + ASSERT_TRUE(signals); + EXPECT_EQ(R"({"key1":null})", + ExtractBiddingSignals(signals.get(), {"key1"})); + // These are important to check for the list case. + EXPECT_EQ(R"({"0":null})", ExtractBiddingSignals(signals.get(), {"0"})); + EXPECT_EQ(R"({"length":null})", + ExtractBiddingSignals(signals.get(), {"length"})); + + EXPECT_EQ(nullptr, signals->GetPriorityVector("name1")); + // These are important to check for the list case. + EXPECT_EQ(nullptr, signals->GetPriorityVector("0")); + EXPECT_EQ(nullptr, signals->GetPriorityVector("length")); + } } TEST_F(TrustedSignalsTest, BiddingSignalsInvalidPriorityVectors) {
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index ef594eb8..7bd6fef6 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -780,6 +780,13 @@ ] } + if (is_chromeos) { + sources += [ + "../browser/smart_card/mock_smart_card_context_factory.cc", + "../browser/smart_card/mock_smart_card_context_factory.h", + ] + } + if (is_fuchsia) { public_deps += [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mediacodec:fuchsia.mediacodec_hlcpp" ] } @@ -1018,13 +1025,6 @@ deps += [ "//chromeos/lacros:lacros" ] } - if (is_chromeos) { - sources += [ - "../browser/smart_card/mock_smart_card_context_factory.cc", - "../browser/smart_card/mock_smart_card_context_factory.h", - ] - } - configs += [ "//v8:external_startup_data" ] } @@ -3152,6 +3152,10 @@ } } + if (is_chromeos) { + sources += [ "../browser/smart_card/smart_card_reader_tracker_unittest.cc" ] + } + if (use_aura) { deps += [ "//ui/aura:test_support",
diff --git a/content/test/content_unittests_bundle_data.filelist b/content/test/content_unittests_bundle_data.filelist index c78e5b4..dcd5f08 100644 --- a/content/test/content_unittests_bundle_data.filelist +++ b/content/test/content_unittests_bundle_data.filelist
@@ -54,6 +54,7 @@ data/attribution_reporting/databases/version_45.sql data/attribution_reporting/databases/version_46.sql data/attribution_reporting/databases/version_47.sql +data/attribution_reporting/databases/version_48.sql data/attribution_reporting/interop/aggregatable_budget.json data/attribution_reporting/interop/aggregatable_contributions_creation.json data/attribution_reporting/interop/aggregatable_dedup_key.json
diff --git a/content/test/data/attribution_reporting/databases/version_47.sql b/content/test/data/attribution_reporting/databases/version_47.sql index b85e409..7eb38eb4 100644 --- a/content/test/data/attribution_reporting/databases/version_47.sql +++ b/content/test/data/attribution_reporting/databases/version_47.sql
@@ -48,4 +48,12 @@ CREATE INDEX aggregate_report_time_idx ON aggregatable_report_metadata(report_time); +INSERT INTO sources VALUES +(2,3,4,5,1643235573000000,1643235593000000,1643235583000000,9,10,11,12,0,14,15,16,17,18,19,20), +(3,4,5,6,1643235574000000,1643235594000000,1643235584000000,10,11,12,13,1,15,16,17,18,19,20,21); + +INSERT INTO event_level_reports VALUES +(2,2,3,1643235574000000,5,6,7,8,9,10), +(3,3,3,1643235575000000,6,7,8,9,10,11); + COMMIT;
diff --git a/content/test/data/attribution_reporting/databases/version_48.sql b/content/test/data/attribution_reporting/databases/version_48.sql new file mode 100644 index 0000000..3744d188 --- /dev/null +++ b/content/test/data/attribution_reporting/databases/version_48.sql
@@ -0,0 +1,51 @@ +PRAGMA foreign_keys=OFF; + +BEGIN TRANSACTION; + +CREATE TABLE sources(source_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,source_event_id INTEGER NOT NULL,source_origin TEXT NOT NULL,reporting_origin TEXT NOT NULL,source_time INTEGER NOT NULL,expiry_time INTEGER NOT NULL,event_report_window_time INTEGER NOT NULL,aggregatable_report_window_time INTEGER NOT NULL,num_attributions INTEGER NOT NULL,event_level_active INTEGER NOT NULL,aggregatable_active INTEGER NOT NULL,source_type INTEGER NOT NULL,attribution_logic INTEGER NOT NULL,priority INTEGER NOT NULL,source_site TEXT NOT NULL,debug_key INTEGER,aggregatable_budget_consumed INTEGER NOT NULL,aggregatable_source BLOB NOT NULL,filter_data BLOB NOT NULL); + +CREATE TABLE event_level_reports(report_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,source_id INTEGER NOT NULL,trigger_data INTEGER NOT NULL,trigger_time INTEGER NOT NULL,report_time INTEGER NOT NULL,initial_report_time INTEGER NOT NULL,priority INTEGER NOT NULL,failed_send_attempts INTEGER NOT NULL,external_report_id TEXT NOT NULL,debug_key INTEGER,context_origin TEXT NOT NULL); + +CREATE TABLE rate_limits(id INTEGER PRIMARY KEY NOT NULL,scope INTEGER NOT NULL,source_id INTEGER NOT NULL,source_site TEXT NOT NULL,destination_site TEXT NOT NULL,context_origin TEXT NOT NULL,reporting_origin TEXT NOT NULL,time INTEGER NOT NULL,source_expiry_or_attribution_time INTEGER NOT NULL); + +CREATE TABLE dedup_keys(source_id INTEGER NOT NULL,report_type INTEGER NOT NULL,dedup_key INTEGER NOT NULL,PRIMARY KEY(source_id,report_type,dedup_key))WITHOUT ROWID; + +CREATE TABLE source_destinations(source_id INTEGER NOT NULL,destination_site TEXT NOT NULL,PRIMARY KEY(source_id,destination_site))WITHOUT ROWID; + +CREATE TABLE aggregatable_report_metadata(aggregation_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,source_id INTEGER NOT NULL,trigger_time INTEGER NOT NULL,debug_key INTEGER,external_report_id TEXT NOT NULL,report_time INTEGER NOT NULL,failed_send_attempts INTEGER NOT NULL,initial_report_time INTEGER NOT NULL,aggregation_coordinator INTEGER NOT NULL,attestation_token TEXT,destination_origin TEXT NOT NULL); + +CREATE TABLE aggregatable_contributions(aggregation_id INTEGER NOT NULL,contribution_id INTEGER NOT NULL,key_high_bits INTEGER NOT NULL,key_low_bits INTEGER NOT NULL,value INTEGER NOT NULL,PRIMARY KEY(aggregation_id,contribution_id))WITHOUT ROWID; + +CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); + +INSERT INTO meta VALUES('mmap_status','-1'); +INSERT INTO meta VALUES('version','48'); +INSERT INTO meta VALUES('last_compatible_version','48'); + +CREATE INDEX sources_by_active_reporting_origin ON sources(event_level_active,aggregatable_active,reporting_origin); + +CREATE INDEX sources_by_expiry_time ON sources(expiry_time); + +CREATE INDEX active_sources_by_source_origin ON sources(source_origin)WHERE event_level_active=1 OR aggregatable_active=1; + +CREATE INDEX sources_by_destination_site ON source_destinations(destination_site); + +CREATE INDEX event_level_reports_by_report_time ON event_level_reports(report_time); + +CREATE INDEX event_level_reports_by_source_id ON event_level_reports(source_id); + +CREATE INDEX rate_limit_source_site_reporting_origin_idx ON rate_limits(scope,source_site,reporting_origin); + +CREATE INDEX rate_limit_reporting_origin_idx ON rate_limits(scope,destination_site,source_site); + +CREATE INDEX rate_limit_time_idx ON rate_limits(time); + +CREATE INDEX rate_limit_source_id_idx ON rate_limits(source_id); + +CREATE INDEX aggregate_source_id_idx ON aggregatable_report_metadata(source_id); + +CREATE INDEX aggregate_trigger_time_idx ON aggregatable_report_metadata(trigger_time); + +CREATE INDEX aggregate_report_time_idx ON aggregatable_report_metadata(report_time); + +COMMIT;
diff --git a/fuchsia_web/runners/cast/test/cast_runner_launcher.cc b/fuchsia_web/runners/cast/test/cast_runner_launcher.cc index c4dc2b0..d012e28 100644 --- a/fuchsia_web/runners/cast/test/cast_runner_launcher.cc +++ b/fuchsia_web/runners/cast/test/cast_runner_launcher.cc
@@ -20,11 +20,14 @@ #include <fuchsia/ui/composition/cpp/fidl.h> #include <fuchsia/ui/scenic/cpp/fidl.h> #include <fuchsia/web/cpp/fidl.h> +#include <lib/vfs/cpp/remote_dir.h> #include <memory> #include <utility> #include "base/command_line.h" +#include "base/fuchsia/fuchsia_logging.h" +#include "base/fuchsia/process_context.h" #include "base/run_loop.h" #include "fuchsia_web/common/test/test_realm_support.h" #include "fuchsia_web/runners/cast/fidl/fidl/hlcpp/chromium/cast/cpp/fidl.h" @@ -33,6 +36,7 @@ using ::component_testing::ChildRef; using ::component_testing::Directory; using ::component_testing::DirectoryContents; +using ::component_testing::FrameworkRef; using ::component_testing::ParentRef; using ::component_testing::Protocol; using ::component_testing::RealmBuilder; @@ -41,6 +45,48 @@ namespace test { +namespace { + +// Name and path under which components must define a writable directory +// capability, for DynamicComponentHost to dynamically offer per-component +// service directories from. +constexpr char kDynamicComponentCapabilitiesName[] = + "for_dynamic_component_host"; +constexpr char kDynamicComponentCapabilitiesPath[] = + "/for_dynamic_component_host"; + +class TestProxyLocalComponent : public component_testing::LocalComponentImpl { + public: + TestProxyLocalComponent() = default; + + // LocalComponentImpl implementation. + void OnStart() override { + // Create a new Directory capability serving the contents of the + // "for_dynamic_component_host" sub-directory of the calling process' + // outgoing directory. + vfs::PseudoDir* capability_dir = + base::ComponentContextForProcess()->outgoing()->GetOrCreateDirectory( + kDynamicComponentCapabilitiesName); + fidl::InterfaceHandle<fuchsia::io::Directory> services; + zx_status_t status = + capability_dir->Serve(fuchsia::io::OpenFlags::RIGHT_READABLE | + fuchsia::io::OpenFlags::RIGHT_WRITABLE | + fuchsia::io::OpenFlags::DIRECTORY, + services.NewRequest().TakeChannel()); + ZX_CHECK(status == ZX_OK, status) << "Serve()"; + + // Bind that Directory capability under the same path of this virtual + // component's outgoing-directory, so that attempts to open files under + // it will be routed back to the calling process' outgoing directory. + status = outgoing()->root_dir()->AddEntry( + kDynamicComponentCapabilitiesName, + std::make_unique<vfs::RemoteDir>(std::move(services))); + ZX_CHECK(status == ZX_OK, status) << "AddEntry"; + } +}; + +} // namespace + CastRunnerLauncher::CastRunnerLauncher(CastRunnerFeatures runner_features) : runner_features_(runner_features) {} @@ -56,27 +102,28 @@ std::unique_ptr<sys::ServiceDirectory> CastRunnerLauncher::StartCastRunner() { auto realm_builder = RealmBuilder::Create(); - static constexpr char kCastRunnerService[] = "cast_runner"; - realm_builder.AddChild(kCastRunnerService, "#meta/cast_runner.cm"); + static constexpr char kCastRunnerComponentName[] = "cast_runner"; + realm_builder.AddChild(kCastRunnerComponentName, "#meta/cast_runner.cm"); base::CommandLine command_line = CommandLineFromFeatures(runner_features_); constexpr char const* kSwitchesToCopy[] = {"ozone-platform"}; command_line.CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(), kSwitchesToCopy, std::size(kSwitchesToCopy)); - AppendCommandLineArguments(realm_builder, kCastRunnerService, command_line); + AppendCommandLineArguments(realm_builder, kCastRunnerComponentName, + command_line); // Register the fake fuchsia.feedback service component; plumbing its // protocols to cast_runner. - FakeFeedbackService::RouteToChild(realm_builder, kCastRunnerService); + FakeFeedbackService::RouteToChild(realm_builder, kCastRunnerComponentName); - AddSyslogRoutesFromParent(realm_builder, kCastRunnerService); - AddVulkanRoutesFromParent(realm_builder, kCastRunnerService); + AddSyslogRoutesFromParent(realm_builder, kCastRunnerComponentName); + AddVulkanRoutesFromParent(realm_builder, kCastRunnerComponentName); // Run an isolated font service for cast_runner. - AddFontService(realm_builder, kCastRunnerService); + AddFontService(realm_builder, kCastRunnerComponentName); // Run the test-ui-stack and route the protocols needed by cast_runner to it. - AddTestUiStack(realm_builder, kCastRunnerService); + AddTestUiStack(realm_builder, kCastRunnerComponentName); realm_builder.AddRoute(Route{ .capabilities = @@ -104,7 +151,7 @@ Storage{.name = "cache", .path = "/cache"}, }, .source = ParentRef(), - .targets = {ChildRef{kCastRunnerService}}}); + .targets = {ChildRef{kCastRunnerComponentName}}}); // Provide a fake Cast "agent", providing some necessary services. static constexpr char kFakeCastAgentName[] = "fake-cast-agent"; @@ -125,7 +172,7 @@ Protocol{fuchsia::media::Audio::Name_}, }, .source = ChildRef{kFakeCastAgentName}, - .targets = {ChildRef{kCastRunnerService}}}); + .targets = {ChildRef{kCastRunnerComponentName}}}); // Either route the fake AudioDeviceEnumerator or the system one. if (runner_features_ & kCastRunnerFeaturesFakeAudioDeviceEnumerator) { @@ -138,13 +185,13 @@ Route{.capabilities = {Protocol{ fuchsia::media::AudioDeviceEnumerator::Name_}}, .source = ChildRef{kAudioDeviceEnumerator}, - .targets = {ChildRef{kCastRunnerService}}}); + .targets = {ChildRef{kCastRunnerComponentName}}}); } else { realm_builder.AddRoute( Route{.capabilities = {Protocol{ fuchsia::media::AudioDeviceEnumerator::Name_}}, .source = ParentRef(), - .targets = {ChildRef{kCastRunnerService}}}); + .targets = {ChildRef{kCastRunnerComponentName}}}); } // Route capabilities from the cast_runner back up to the test. @@ -152,9 +199,115 @@ Route{.capabilities = {Protocol{chromium::cast::DataReset::Name_}, Protocol{fuchsia::web::FrameHost::Name_}, Protocol{fuchsia::sys::Runner::Name_}}, - .source = ChildRef{kCastRunnerService}, + .source = ChildRef{kCastRunnerComponentName}, .targets = {ParentRef()}}); + // Define a pseudo-component to bridge from test-scoped outgoing directory + // into the RealmBuilder scope. + static constexpr char kTestProxyName[] = "test_proxy"; + realm_builder.AddLocalChild(kTestProxyName, + std::make_unique<TestProxyLocalComponent>); + + // Define an environment that uses the exposed Resolver and Runner, and a + // child component collection that uses that environment, in the test proxy + // component. + static constexpr char kCastResolverName[] = "cast-resolver"; + static constexpr char kCastRunnerName[] = "cast-runner"; + { + auto test_proxy_decl = realm_builder.GetComponentDecl(kTestProxyName); + + static constexpr char kEnvironmentName[] = "cast-test-environment"; + static constexpr char kCastUrlScheme[] = "cast"; + + fuchsia::component::decl::ResolverRegistration resolver_decl; + resolver_decl.set_resolver(kCastResolverName); + resolver_decl.set_source(fuchsia::component::decl::Ref::WithParent({})); + resolver_decl.set_scheme(kCastUrlScheme); + + fuchsia::component::decl::RunnerRegistration runner_decl; + runner_decl.set_source_name(kCastRunnerName); + runner_decl.set_source(fuchsia::component::decl::Ref::WithParent({})); + runner_decl.set_target_name(kCastRunnerName); + + fuchsia::component::decl::Environment environment_decl; + environment_decl.set_name(kEnvironmentName); + environment_decl.set_extends( + fuchsia::component::decl::EnvironmentExtends::NONE); + environment_decl.set_stop_timeout_ms(1000); // Matches cast_runner.cml + environment_decl.mutable_resolvers()->emplace_back( + std::move(resolver_decl)); + environment_decl.mutable_runners()->emplace_back(std::move(runner_decl)); + test_proxy_decl.mutable_environments()->emplace_back( + std::move(environment_decl)); + + fuchsia::component::decl::Collection collection_decl; + collection_decl.set_name(kTestCollectionName); + collection_decl.set_environment(kEnvironmentName); + collection_decl.set_durability( + fuchsia::component::decl::Durability::TRANSIENT); + collection_decl.set_allowed_offers( + fuchsia::component::decl::AllowedOffers::STATIC_AND_DYNAMIC); + test_proxy_decl.mutable_collections()->emplace_back( + std::move(collection_decl)); + + test_proxy_decl.mutable_capabilities()->emplace_back( + fuchsia::component::decl::Capability::WithDirectory(std::move( + fuchsia::component::decl::Directory() + .set_name(kDynamicComponentCapabilitiesName) + .set_rights(fuchsia::io::RW_STAR_DIR) + .set_source_path(kDynamicComponentCapabilitiesPath)))); + + test_proxy_decl.mutable_exposes()->emplace_back( + fuchsia::component::decl::Expose::WithProtocol(std::move( + fuchsia::component::decl::ExposeProtocol() + .set_source(fuchsia::component::decl::Ref::WithFramework({})) + .set_source_name(fuchsia::component::Realm::Name_) + .set_target(fuchsia::component::decl::Ref::WithParent({})) + .set_target_name(fuchsia::component::Realm::Name_)))); + + realm_builder.ReplaceComponentDecl(kTestProxyName, + std::move(test_proxy_decl)); + } + + // Offer the test-proxy the Cast Resolver and Runner capabilities, and + // expose its framework-provided Realm protocol out to the test. + { + auto realm_decl = realm_builder.GetRealmDecl(); + realm_decl.mutable_exposes()->emplace_back( + fuchsia::component::decl::Expose::WithProtocol(std::move( + fuchsia::component::decl::ExposeProtocol() + .set_source(fuchsia::component::decl::Ref::WithChild( + fuchsia::component::decl::ChildRef{.name = kTestProxyName})) + .set_source_name(fuchsia::component::Realm::Name_) + .set_target(fuchsia::component::decl::Ref::WithParent({})) + .set_target_name(fuchsia::component::Realm::Name_)))); + + realm_decl.mutable_offers()->emplace_back( + fuchsia::component::decl::Offer::WithResolver(std::move( + fuchsia::component::decl::OfferResolver() + .set_source(fuchsia::component::decl::Ref::WithChild( + fuchsia::component::decl::ChildRef{ + .name = kCastRunnerComponentName})) + .set_source_name(kCastResolverName) + .set_target(fuchsia::component::decl::Ref::WithChild( + fuchsia::component::decl::ChildRef{.name = kTestProxyName})) + .set_target_name(kCastResolverName)))); + + realm_decl.mutable_offers()->emplace_back( + fuchsia::component::decl::Offer::WithRunner(std::move( + fuchsia::component::decl::OfferRunner() + .set_source(fuchsia::component::decl::Ref::WithChild( + fuchsia::component::decl::ChildRef{ + .name = kCastRunnerComponentName})) + .set_source_name(kCastRunnerName) + .set_target(fuchsia::component::decl::Ref::WithChild( + fuchsia::component::decl::ChildRef{.name = kTestProxyName})) + .set_target_name(kCastRunnerName)))); + + realm_builder.ReplaceRealmDecl(std::move(realm_decl)); + } + + // Create the test Realm and connect to its exposed services. realm_root_ = realm_builder.Build(); return std::make_unique<sys::ServiceDirectory>( realm_root_->component().CloneExposedDir());
diff --git a/fuchsia_web/runners/cast/test/cast_runner_launcher.h b/fuchsia_web/runners/cast/test/cast_runner_launcher.h index c35db130..360440c1 100644 --- a/fuchsia_web/runners/cast/test/cast_runner_launcher.h +++ b/fuchsia_web/runners/cast/test/cast_runner_launcher.h
@@ -22,6 +22,11 @@ // component_testing.RealmBuilder to start the cast runner component. class CastRunnerLauncher { public: + // Name of a component collection defined under this launcher's `Realm`, + // into which Cast activities may be launched using the `cast_runner` + // managed by this launcher. + static constexpr char kTestCollectionName[] = "cast-test-collection"; + explicit CastRunnerLauncher(CastRunnerFeatures runner_features); CastRunnerLauncher(const CastRunnerLauncher&) = delete; CastRunnerLauncher& operator=(const CastRunnerLauncher&) = delete;
diff --git a/infra/config/OWNERS b/infra/config/OWNERS index 74189c29..22b5f96 100644 --- a/infra/config/OWNERS +++ b/infra/config/OWNERS
@@ -16,4 +16,9 @@ # For Code Coverage configs per-file subprojects/chromium/ci/chromium.coverage.star=jeffyoon@google.com -per-file subprojects/chromium/ci/chromium.coverage.star=pasthana@google.com \ No newline at end of file +per-file subprojects/chromium/ci/chromium.coverage.star=pasthana@google.com + +# Fuchsia owners +per-file subprojects/chromium/ci/chromium.fuchsia.fyi.star=file://build/fuchsia/test/OWNERS +per-file subprojects/chromium/ci/chromium.fuchsia.star=file://build/fuchsia/test/OWNERS +per-file subprojects/chromium/try/tryserver.chromium.fuchsia.star=file://build/fuchsia/test/OWNERS
diff --git a/ios/chrome/browser/metrics/first_user_action_recorder.cc b/ios/chrome/browser/metrics/first_user_action_recorder.cc index 47c5ad01..08036de4 100644 --- a/ios/chrome/browser/metrics/first_user_action_recorder.cc +++ b/ios/chrome/browser/metrics/first_user_action_recorder.cc
@@ -41,7 +41,6 @@ "MobileFirstUserAction_NewTask", "MobileMenuCloseAllTabs", "MobileMenuCloseAllIncognitoTabs", - "MobileMenuCloseTab", "MobileNewTabOpened", "MobileTabClosed", "MobileTabStripCloseTab", @@ -65,7 +64,6 @@ "MobileMenuNewIncognitoTab", "MobileMenuNewTab", "MobileMenuRecentTabs", - "MobileMenuVoiceSearch", "MobileBookmarkManagerEntryOpened", "MobileRecentTabManagerTabFromOtherDeviceOpened", "MobileNTPMostVisited",
diff --git a/ios/chrome/browser/ntp/features.h b/ios/chrome/browser/ntp/features.h index c9ba7d9..aca6c70 100644 --- a/ios/chrome/browser/ntp/features.h +++ b/ios/chrome/browser/ntp/features.h
@@ -119,9 +119,6 @@ // buildflag is not defined. bool IsFeedBackgroundRefreshEnabled(); -// Whether Good Visits metric logging is enabled. -bool IsGoodVisitsMetricEnabled(); - // Saves the current value for feature `kEnableFeedBackgroundRefresh`. This call // DCHECKs on the availability of `base::FeatureList`. void SaveFeedBackgroundRefreshEnabledForNextColdStart();
diff --git a/ios/chrome/browser/ntp/features.mm b/ios/chrome/browser/ntp/features.mm index fe016b9..dd62e17 100644 --- a/ios/chrome/browser/ntp/features.mm +++ b/ios/chrome/browser/ntp/features.mm
@@ -32,10 +32,6 @@ "CreateDiscoverFeedServiceEarly", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kEnableGoodVisitsMetric, - "EnableGoodVisitsMetric", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kEnableFeedBottomSignInPromo, "EnableFeedBottomSignInPromo", base::FEATURE_DISABLED_BY_DEFAULT); @@ -98,10 +94,6 @@ return base::FeatureList::IsEnabled(kCreateDiscoverFeedServiceEarly); } -bool IsGoodVisitsMetricEnabled() { - return base::FeatureList::IsEnabled(kEnableGoodVisitsMetric); -} - bool IsFeedBackgroundRefreshEnabled() { #if !BUILDFLAG(IOS_BACKGROUND_MODE_ENABLED) return false;
diff --git a/ios/chrome/browser/policy/policy_incognito_mode_availability_egtest.mm b/ios/chrome/browser/policy/policy_incognito_mode_availability_egtest.mm index ba94d23..bf23507 100644 --- a/ios/chrome/browser/policy/policy_incognito_mode_availability_egtest.mm +++ b/ios/chrome/browser/policy/policy_incognito_mode_availability_egtest.mm
@@ -156,19 +156,8 @@ [[EarlGrey selectElementWithMatcher:TabGridButton()] performAction:grey_longPress()]; - if ([ChromeEarlGrey isSFSymbolEnabled]) { - AssertItemEnabled(IDS_IOS_TOOLS_MENU_NEW_TAB, /*enabled=*/true); - AssertItemEnabled(IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB, /*enabled=*/true); - } else { - AssertItemEnabledState( - grey_accessibilityID(kToolsMenuNewTabId), - grey_accessibilityID(kPopupMenuTabGridMenuTableViewId), - /*enabled=*/YES); - AssertItemEnabledState( - grey_accessibilityID(kToolsMenuNewIncognitoTabId), - grey_accessibilityID(kPopupMenuTabGridMenuTableViewId), - /*enabled=*/YES); - } + AssertItemEnabled(IDS_IOS_TOOLS_MENU_NEW_TAB, /*enabled=*/true); + AssertItemEnabled(IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB, /*enabled=*/true); } // When the IncognitoModeAvailability policy is set to disabled, the "New @@ -180,19 +169,8 @@ [[EarlGrey selectElementWithMatcher:TabGridButton()] performAction:grey_longPress()]; - if ([ChromeEarlGrey isSFSymbolEnabled]) { - AssertItemEnabled(IDS_IOS_TOOLS_MENU_NEW_TAB, /*enabled=*/true); - AssertItemEnabled(IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB, /*enabled=*/false); - } else { - AssertItemEnabledState( - grey_accessibilityID(kToolsMenuNewTabId), - grey_accessibilityID(kPopupMenuTabGridMenuTableViewId), - /*enabled=*/YES); - AssertItemEnabledState( - grey_accessibilityID(kToolsMenuNewIncognitoTabId), - grey_accessibilityID(kPopupMenuTabGridMenuTableViewId), - /*enabled=*/NO); - } + AssertItemEnabled(IDS_IOS_TOOLS_MENU_NEW_TAB, /*enabled=*/true); + AssertItemEnabled(IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB, /*enabled=*/false); } // When the IncognitoModeAvailability policy is set to forced, the "New Tab" @@ -204,17 +182,8 @@ [[EarlGrey selectElementWithMatcher:TabGridButton()] performAction:grey_longPress()]; - if ([ChromeEarlGrey isSFSymbolEnabled]) { - AssertItemEnabled(IDS_IOS_TOOLS_MENU_NEW_TAB, /*enabled=*/false); - AssertItemEnabled(IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB, /*enabled=*/true); - } else { - AssertItemEnabledState( - grey_accessibilityID(kToolsMenuNewTabId), - grey_accessibilityID(kPopupMenuTabGridMenuTableViewId), NO); - AssertItemEnabledState( - grey_accessibilityID(kToolsMenuNewIncognitoTabId), - grey_accessibilityID(kPopupMenuTabGridMenuTableViewId), YES); - } + AssertItemEnabled(IDS_IOS_TOOLS_MENU_NEW_TAB, /*enabled=*/false); + AssertItemEnabled(IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB, /*enabled=*/true); } // TODO(crbug.com/1165655): Add test to new tab long-press menu.
diff --git a/ios/chrome/browser/push_notification/push_notification_service.h b/ios/chrome/browser/push_notification/push_notification_service.h index a22ee997..587a012 100644 --- a/ios/chrome/browser/push_notification/push_notification_service.h +++ b/ios/chrome/browser/push_notification/push_notification_service.h
@@ -91,7 +91,7 @@ // notification server. virtual void SetPreferences(NSString* account_id, PreferenceMap preference_map, - CompletionHandler completion_handler); + CompletionHandler completion_handler) = 0; private: // The PushNotificationClientManager manages all interactions between the
diff --git a/ios/chrome/browser/shared/public/commands/browser_commands.h b/ios/chrome/browser/shared/public/commands/browser_commands.h index 42c39e3..c368524 100644 --- a/ios/chrome/browser/shared/public/commands/browser_commands.h +++ b/ios/chrome/browser/shared/public/commands/browser_commands.h
@@ -20,11 +20,8 @@ // TODO(crbug.com/1272540): Remove this command. - (void)addToReadingList:(ReadingListAddCommand*)command; -// Preloads voice search on the current BVC. -- (void)preloadVoiceSearch; - -// Prepares the browser to display a popup menu. -- (void)prepareForPopupMenuPresentation:(PopupMenuCommandType)type; +// Prepares the browser to display the overflow menu. +- (void)prepareForOverflowMenuPresentation; @end
diff --git a/ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h b/ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h index 8509104..2046c81 100644 --- a/ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h +++ b/ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h
@@ -95,6 +95,9 @@ // Shows the spotlight debugger. - (void)showSpotlightDebugger; +// Preloads voice search in the current BVC. +- (void)preloadVoiceSearch; + @end #endif // IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_BROWSER_COORDINATOR_COMMANDS_H_
diff --git a/ios/chrome/browser/shared/public/commands/popup_menu_commands.h b/ios/chrome/browser/shared/public/commands/popup_menu_commands.h index 40ec19b..36754f25 100644 --- a/ios/chrome/browser/shared/public/commands/popup_menu_commands.h +++ b/ios/chrome/browser/shared/public/commands/popup_menu_commands.h
@@ -11,25 +11,11 @@ class WebState; } -// Type of a popup menu command. -typedef NS_ENUM(NSInteger, PopupMenuCommandType) { - PopupMenuCommandTypeToolsMenu, - PopupMenuCommandTypeDefault, -}; - // Commands for the popup menu. @protocol PopupMenuCommands -// Shows the navigation history popup containing the back history. -- (void)showNavigationHistoryBackPopupMenu; -// Shows the navigation history popup containing the forward history. -- (void)showNavigationHistoryForwardPopupMenu; // Shows the tools menu. - (void)showToolsMenuPopup; -// Shows the popup for the tab grid button. -- (void)showTabGridButtonPopup; -// Shows the popup for the new tab button. -- (void)showNewTabButtonPopup; // Dismisses the currently presented popup. - (void)dismissPopupMenuAnimated:(BOOL)animated; // Shows a snackbar that allows the user to UNDO its pin/unpin action.
diff --git a/ios/chrome/browser/shared/ui/util/BUILD.gn b/ios/chrome/browser/shared/ui/util/BUILD.gn index 56088e03..751ca0d 100644 --- a/ios/chrome/browser/shared/ui/util/BUILD.gn +++ b/ios/chrome/browser/shared/ui/util/BUILD.gn
@@ -17,8 +17,6 @@ "attributed_string_util.mm", "dynamic_type_util.h", "dynamic_type_util.mm", - "force_touch_long_press_gesture_recognizer.h", - "force_touch_long_press_gesture_recognizer.mm", "keyboard_observer_helper.h", "keyboard_observer_helper.mm", "layout_guide_names.h", @@ -115,7 +113,6 @@ configs += [ "//build/config/compiler:enable_arc" ] testonly = true sources = [ - "force_touch_long_press_gesture_recognizer_unittest.mm", "frame_layout_guide_unittest.mm", "layout_guide_center_unittest.mm", "named_guide_unittest.mm",
diff --git a/ios/chrome/browser/shared/ui/util/force_touch_long_press_gesture_recognizer.h b/ios/chrome/browser/shared/ui/util/force_touch_long_press_gesture_recognizer.h deleted file mode 100644 index ceb1864..0000000 --- a/ios/chrome/browser/shared/ui/util/force_touch_long_press_gesture_recognizer.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_SHARED_UI_UTIL_FORCE_TOUCH_LONG_PRESS_GESTURE_RECOGNIZER_H_ -#define IOS_CHROME_BROWSER_SHARED_UI_UTIL_FORCE_TOUCH_LONG_PRESS_GESTURE_RECOGNIZER_H_ - -#import <UIKit/UIKit.h> - -// Gesture recognizer triggering on LongPress or on ForceTouch. Any of the two -// gesture can trigger the recognizer. The properties of the LongPress are not -// taken into account for the ForceTouch. -@interface ForceTouchLongPressGestureRecognizer : UILongPressGestureRecognizer - -// The threshold at which the force touch should trigger. Must be between 0 and -// 1, based on the maximum force the touch can receive. -@property(nonatomic, assign) CGFloat forceThreshold; - -@end - -#endif // IOS_CHROME_BROWSER_SHARED_UI_UTIL_FORCE_TOUCH_LONG_PRESS_GESTURE_RECOGNIZER_H_
diff --git a/ios/chrome/browser/shared/ui/util/force_touch_long_press_gesture_recognizer.mm b/ios/chrome/browser/shared/ui/util/force_touch_long_press_gesture_recognizer.mm deleted file mode 100644 index f80a982..0000000 --- a/ios/chrome/browser/shared/ui/util/force_touch_long_press_gesture_recognizer.mm +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/shared/ui/util/force_touch_long_press_gesture_recognizer.h" - -#import <UIKit/UIGestureRecognizerSubclass.h> -#import "base/cxx17_backports.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@implementation ForceTouchLongPressGestureRecognizer - -@synthesize forceThreshold = _forceThreshold; - -- (void)setForceThreshold:(CGFloat)forceThreshold { - _forceThreshold = base::clamp<CGFloat>(forceThreshold, 0, 1); -} - -#pragma mark - UIGestureRecognizerSubclass - -- (void)touchesBegan:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event { - [super touchesBegan:touches withEvent:event]; - [self touchesChanged:touches toPhase:UITouchPhaseBegan]; -} - -- (void)touchesMoved:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event { - [super touchesMoved:touches withEvent:event]; - [self touchesChanged:touches toPhase:UITouchPhaseMoved]; -} - -- (void)touchesEnded:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event { - [super touchesEnded:touches withEvent:event]; - [self touchesChanged:touches toPhase:UITouchPhaseEnded]; -} - -- (void)touchesCancelled:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event { - [super touchesCancelled:touches withEvent:event]; - [self touchesChanged:touches toPhase:UITouchPhaseCancelled]; -} - -#pragma mark - Private - -- (void)touchesChanged:(NSSet<UITouch*>*)touches - toPhase:(UITouchPhase)touchPhase { - UITouch* touch = [touches anyObject]; - if (!touch) { - self.state = UIGestureRecognizerStateFailed; - return; - } - - switch (touchPhase) { - case UITouchPhaseCancelled: - self.state = UIGestureRecognizerStateCancelled; - break; - case UITouchPhaseEnded: - self.state = UIGestureRecognizerStateEnded; - break; - case UITouchPhaseBegan: - // Falls through. - case UITouchPhaseMoved: - if (self.state == UIGestureRecognizerStatePossible) { - // Gesture hasn't begun yet. - if (touch.force / touch.maximumPossibleForce >= self.forceThreshold) { - self.state = UIGestureRecognizerStateBegan; - } - } else { - self.state = UIGestureRecognizerStateChanged; - } - break; - default: - break; - } -} - -@end
diff --git a/ios/chrome/browser/shared/ui/util/force_touch_long_press_gesture_recognizer_unittest.mm b/ios/chrome/browser/shared/ui/util/force_touch_long_press_gesture_recognizer_unittest.mm deleted file mode 100644 index fd75e638..0000000 --- a/ios/chrome/browser/shared/ui/util/force_touch_long_press_gesture_recognizer_unittest.mm +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/shared/ui/util/force_touch_long_press_gesture_recognizer.h" - -#import <UIKit/UIGestureRecognizerSubclass.h> - -#import "testing/gtest/include/gtest/gtest.h" -#import "testing/platform_test.h" -#import "third_party/ocmock/OCMock/OCMock.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@interface ForceTouchLongPressGestureRecognizerReceiverForTest : NSObject - -@end - -@implementation ForceTouchLongPressGestureRecognizerReceiverForTest - -- (void)handleGestureRecognizer:(UIGestureRecognizer*)gesture { -} - -@end - -namespace { - -using ForceTouchLongPressGestureRecognizerTest = PlatformTest; - -TEST_F(ForceTouchLongPressGestureRecognizerTest, DetectForceTouch) { - ForceTouchLongPressGestureRecognizerReceiverForTest* testReceiver = - [[ForceTouchLongPressGestureRecognizerReceiverForTest alloc] init]; - - ForceTouchLongPressGestureRecognizer* gestureRecognizer = - [[ForceTouchLongPressGestureRecognizer alloc] - initWithTarget:testReceiver - action:@selector(handleGestureRecognizer:)]; - gestureRecognizer.forceThreshold = 0.6; - - ASSERT_EQ(UIGestureRecognizerStatePossible, gestureRecognizer.state); - - id event = OCMClassMock([UIEvent class]); - - CGFloat maximumForce = 1; - CGFloat currentForce = 0.5; - id touch = OCMClassMock([UITouch class]); - OCMStub([touch maximumPossibleForce]).andReturn(maximumForce); - OCMStub([touch force]).andReturn(currentForce); - [gestureRecognizer touchesBegan:[NSSet setWithObject:touch] withEvent:event]; - [gestureRecognizer touchesMoved:[NSSet setWithObject:touch] withEvent:event]; - - EXPECT_EQ(UIGestureRecognizerStatePossible, gestureRecognizer.state); - - currentForce = 0.7; - - touch = OCMClassMock([UITouch class]); - OCMStub([touch maximumPossibleForce]).andReturn(maximumForce); - OCMStub([touch force]).andReturn(currentForce); - [gestureRecognizer touchesMoved:[NSSet setWithObject:touch] withEvent:event]; - - EXPECT_EQ(UIGestureRecognizerStateBegan, gestureRecognizer.state); - - touch = OCMClassMock([UITouch class]); - OCMStub([touch maximumPossibleForce]).andReturn(maximumForce); - OCMStub([touch force]).andReturn(currentForce); - [gestureRecognizer touchesEnded:[NSSet setWithObject:touch] withEvent:event]; - - EXPECT_EQ(UIGestureRecognizerStateCancelled, gestureRecognizer.state); -} - -} // namespace
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm index e291ba64..e4a80b9 100644 --- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm +++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -770,9 +770,6 @@ // behavior but helps command handler setup below. [self.popupMenuCoordinator start]; - _primaryToolbarCoordinator.longPressDelegate = self.popupMenuCoordinator; - _secondaryToolbarCoordinator.longPressDelegate = self.popupMenuCoordinator; - if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { if (base::FeatureList::IsEnabled(kModernTabStrip)) { _tabStripCoordinator = @@ -780,7 +777,6 @@ } else { _legacyTabStripCoordinator = [[TabStripLegacyCoordinator alloc] initWithBrowser:self.browser]; - _legacyTabStripCoordinator.longPressDelegate = self.popupMenuCoordinator; _legacyTabStripCoordinator.animationWaitDuration = kLegacyFullscreenControllerToolbarAnimationDuration.InSecondsF(); @@ -1107,6 +1103,8 @@ [[CredentialProviderPromoCoordinator alloc] initWithBaseViewController:self.viewController browser:self.browser]; + _credentialProviderPromoCoordinator.promosUIHandler = + _promosManagerCoordinator; [_credentialProviderPromoCoordinator start]; } if (!IsOpenInActivitiesInShareButtonEnabled()) { @@ -1568,6 +1566,12 @@ [self.spotlightDebuggerCoordinator start]; } +- (void)preloadVoiceSearch { + // Preload VoiceSearchController and views and view controllers needed + // for voice search. + [_voiceSearchController prepareToAppear]; +} + #pragma mark - DefaultPromoCommands - (void)showTailoredPromoStaySafe { @@ -1776,6 +1780,10 @@ self.promosManagerCoordinator = [[PromosManagerCoordinator alloc] initWithBaseViewController:self.viewController browser:self.browser]; + // CredentialProviderPromoCoordinator is initialized earlier than this, so + // make sure to set its UI handler. + _credentialProviderPromoCoordinator.promosUIHandler = + self.promosManagerCoordinator; } [self.promosManagerCoordinator start]; @@ -1787,11 +1795,17 @@ [SceneStateBrowserAgent::FromBrowser(self.browser)->GetSceneState() scene]; [SKStoreReviewController requestReviewInScene:scene]; + + // Apple doesn't tell whether the app store review window will show or + // provide a callback for when it is dismissed, so alert the coordinator + // here so it can do any necessary cleanup. + [self.promosManagerCoordinator promoWasDismissed]; } } - (void)showWhatsNewPromo { [self showWhatsNew]; + self.whatsNewCoordinator.promosUIHandler = self.promosManagerCoordinator; self.whatsNewCoordinator.shouldShowBubblePromoOnDismiss = YES; }
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 e187363..4820ecc0 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -1602,15 +1602,24 @@ // Sets up the constraints on the toolbar. - (void)addConstraintsToPrimaryToolbar { NSLayoutYAxisAnchor* topAnchor; - // On iPad, the toolbar is underneath the tab strip. - // On iPhone, it is underneath the top of the screen. - if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { - topAnchor = self.tabStripView.bottomAnchor; - } else { - topAnchor = [self view].topAnchor; - // TODO(crbug.com/1423799): Dcheck added for investigation purposes, remove + // On iPhone, the toolbar is underneath the top of the screen. + // On iPad, it depends: + // - if the window is compact, it is like iPhone, underneath the top of the + // screen. + // - if the window is regular, it is underneath the tab strip. + if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_PHONE || + ![self canShowTabStrip]) { + topAnchor = self.view.topAnchor; + // TODO(crbug.com/1423799): Dchecks added for investigation purposes, remove // once crash root cause is found. - DCHECK(![self canShowTabStrip]); + DCHECK(self.view); + DCHECK(topAnchor); + } else { + topAnchor = self.tabStripView.bottomAnchor; + // TODO(crbug.com/1423799): Dchecks added for investigation purposes, remove + // once crash root cause is found. + DCHECK(self.tabStripView); + DCHECK(topAnchor); } // Only add leading and trailing constraints once as they are never updated. @@ -1631,6 +1640,9 @@ // Create a constraint for the vertical positioning of the toolbar. UIView* primaryView = self.primaryToolbarCoordinator.viewController.view; + // TODO(crbug.com/1423799): Dcheck added for investigation purposes, remove + // once crash root cause is found. + DCHECK(primaryView.topAnchor); self.primaryToolbarOffsetConstraint = [primaryView.topAnchor constraintEqualToAnchor:topAnchor]; @@ -2967,14 +2979,7 @@ [self addURLsToReadingList:command.URLs]; } -// TODO(crbug.com/1329104): Move voice search handling to BrowserCoordinator -- (void)preloadVoiceSearch { - // Preload VoiceSearchController and views and view controllers needed - // for voice search. - [_voiceSearchController prepareToAppear]; -} - -- (void)prepareForPopupMenuPresentation:(PopupMenuCommandType)type { +- (void)prepareForOverflowMenuPresentation { DCHECK(self.browserState); DCHECK(self.visible || self.dismissingModal); @@ -2988,9 +2993,7 @@ // Allow the non-modal promo scheduler to close the promo. [self.nonModalPromoScheduler logPopupMenuEntered]; - if (type == PopupMenuCommandTypeToolsMenu) { - [_bubblePresenter toolsMenuDisplayed]; - } + [_bubblePresenter toolsMenuDisplayed]; } #pragma mark - TabConsumer (Public)
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.h index 9e4971f..c58f9f4 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.h
@@ -12,7 +12,7 @@ #import "ios/chrome/browser/ui/ntp/logo_animation_controller.h" @protocol ApplicationCommands; -@protocol BrowserCommands; +@protocol BrowserCoordinatorCommands; @protocol ContentSuggestionsCommands; @protocol ContentSuggestionsHeaderCommands; @protocol ContentSuggestionsHeaderViewControllerDelegate; @@ -37,7 +37,7 @@ - (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; @property(nonatomic, weak) id<ApplicationCommands, - BrowserCommands, + BrowserCoordinatorCommands, OmniboxCommands, FakeboxFocuser, LensCommands>
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm index 822c597..e3dbee9 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm
@@ -14,7 +14,7 @@ #import "components/strings/grit/components_strings.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h" #import "ios/chrome/browser/shared/public/commands/application_commands.h" -#import "ios/chrome/browser/shared/public/commands/browser_commands.h" +#import "ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h" #import "ios/chrome/browser/shared/public/commands/lens_commands.h" #import "ios/chrome/browser/shared/public/commands/omnibox_commands.h" #import "ios/chrome/browser/shared/public/features/features.h"
diff --git a/ios/chrome/browser/ui/credential_provider_promo/BUILD.gn b/ios/chrome/browser/ui/credential_provider_promo/BUILD.gn index eaa8ddd5..05dca1d 100644 --- a/ios/chrome/browser/ui/credential_provider_promo/BUILD.gn +++ b/ios/chrome/browser/ui/credential_provider_promo/BUILD.gn
@@ -25,6 +25,7 @@ "//ios/chrome/browser/application_context", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/credential_provider_promo:features", + "//ios/chrome/browser/feature_engagement", "//ios/chrome/browser/main:public", "//ios/chrome/browser/prefs:pref_names", "//ios/chrome/browser/promos_manager",
diff --git a/ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_coordinator.h b/ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_coordinator.h index 2638b068..7e88fab 100644 --- a/ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_coordinator.h +++ b/ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_coordinator.h
@@ -9,9 +9,14 @@ #import "ios/chrome/browser/shared/public/commands/credential_provider_promo_commands.h" +@protocol PromosManagerUIHandler; + @interface CredentialProviderPromoCoordinator : ChromeCoordinator <CredentialProviderPromoCommands> +// The promos manager ui handler to alert about UI changes. +@property(nonatomic, weak) id<PromosManagerUIHandler> promosUIHandler; + @end #endif // IOS_CHROME_BROWSER_UI_CREDENTIAL_PROVIDER_PROMO_CREDENTIAL_PROVIDER_PROMO_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_coordinator.mm b/ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_coordinator.mm index d59ed28..46f156f7 100644 --- a/ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_coordinator.mm +++ b/ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_coordinator.mm
@@ -11,11 +11,13 @@ #import "ios/chrome/browser/prefs/pref_names.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" #import "ios/chrome/browser/shared/public/commands/credential_provider_promo_commands.h" +#import "ios/chrome/browser/shared/public/commands/promos_manager_commands.h" #import "ios/chrome/browser/shared/ui/util/top_view_controller.h" #import "ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_constants.h" #import "ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_mediator.h" #import "ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_metrics.h" #import "ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_view_controller.h" +#import "ios/chrome/browser/ui/promos_manager/promos_manager_ui_handler.h" #import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_action_handler.h" #import "ios/public/provider/chrome/browser/password_auto_fill/password_auto_fill_api.h" @@ -24,7 +26,8 @@ #endif @interface CredentialProviderPromoCoordinator () < - ConfirmationAlertActionHandler> + ConfirmationAlertActionHandler, + UIAdaptivePresentationControllerDelegate> // Main mediator for this coordinator. @property(nonatomic, strong) CredentialProviderPromoMediator* mediator; @@ -86,6 +89,7 @@ self.viewController = [[CredentialProviderPromoViewController alloc] init]; self.mediator.consumer = self.viewController; self.viewController.actionHandler = self; + self.viewController.presentationController.delegate = self; self.promoContext = CredentialProviderPromoContext::kFirstStep; [self.mediator configureConsumerWithTrigger:trigger context:self.promoContext]; @@ -114,6 +118,7 @@ // Open iOS settings. ios::provider::PasswordsInOtherAppsOpensSettings(); [self recordAction:IOSCredentialProviderPromoAction::kGoToSettings]; + [self promoWasDismissed]; } } @@ -124,12 +129,21 @@ prefs::kIosCredentialProviderPromoStopPromo, true); [self recordAction:IOSCredentialProviderPromoAction::kNo]; + [self promoWasDismissed]; } - (void)confirmationAlertTertiaryAction { [self hidePromo]; [self.mediator registerPromoWithPromosManager]; [self recordAction:IOSCredentialProviderPromoAction::kRemindMeLater]; + [self promoWasDismissed]; +} + +#pragma mark - UIAdaptivePresentationControllerDelegate + +- (void)presentationControllerDidDismiss: + (UIPresentationController*)presentationController { + [self promoWasDismissed]; } #pragma mark - Private @@ -138,6 +152,7 @@ - (void)presentLearnMore { self.viewController = [[CredentialProviderPromoViewController alloc] init]; self.viewController.actionHandler = self; + self.viewController.presentationController.delegate = self; self.mediator.consumer = self.viewController; self.promoContext = CredentialProviderPromoContext::kLearnMore; [self.mediator configureConsumerWithTrigger:self.trigger @@ -157,6 +172,13 @@ completion:nil]; } +// Does any clean up for when the promo is fully dismissed. +- (void)promoWasDismissed { + if (self.trigger == CredentialProviderPromoTrigger::RemindMeLater) { + [self.promosUIHandler promoWasDismissed]; + } +} + // Help function for metrics. - (void)recordAction:(IOSCredentialProviderPromoAction)action { credential_provider_promo::RecordAction(
diff --git a/ios/chrome/browser/ui/favicon/BUILD.gn b/ios/chrome/browser/ui/favicon/BUILD.gn index 1c9bb2ca..c3acac3 100644 --- a/ios/chrome/browser/ui/favicon/BUILD.gn +++ b/ios/chrome/browser/ui/favicon/BUILD.gn
@@ -10,7 +10,6 @@ "favicon_attributes_with_payload.mm", ] deps = [ - "resources:default_favicon", "resources:default_world_favicon_incognito", "resources:default_world_favicon_regular", "//base",
diff --git a/ios/chrome/browser/ui/favicon/resources/BUILD.gn b/ios/chrome/browser/ui/favicon/resources/BUILD.gn index b44f19c..8a656be 100644 --- a/ios/chrome/browser/ui/favicon/resources/BUILD.gn +++ b/ios/chrome/browser/ui/favicon/resources/BUILD.gn
@@ -21,12 +21,3 @@ "default_world_favicon_regular.imageset/default_world_favicon_regular@3x.png", ] } - -imageset("default_favicon") { - sources = [ - "default_favicon.imageset/Contents.json", - "default_favicon.imageset/default_favicon.png", - "default_favicon.imageset/default_favicon@2x.png", - "default_favicon.imageset/default_favicon@3x.png", - ] -}
diff --git a/ios/chrome/browser/ui/favicon/resources/default_favicon.imageset/Contents.json b/ios/chrome/browser/ui/favicon/resources/default_favicon.imageset/Contents.json deleted file mode 100644 index 13ff41e..0000000 --- a/ios/chrome/browser/ui/favicon/resources/default_favicon.imageset/Contents.json +++ /dev/null
@@ -1,23 +0,0 @@ -{ - "images": [ - { - "idiom": "universal", - "scale": "1x", - "filename": "default_favicon.png" - }, - { - "idiom": "universal", - "scale": "2x", - "filename": "default_favicon@2x.png" - }, - { - "idiom": "universal", - "scale": "3x", - "filename": "default_favicon@3x.png" - } - ], - "info": { - "version": 1, - "author": "xcode" - } -}
diff --git a/ios/chrome/browser/ui/favicon/resources/default_favicon.imageset/default_favicon.png b/ios/chrome/browser/ui/favicon/resources/default_favicon.imageset/default_favicon.png deleted file mode 100644 index c44e0f3..0000000 --- a/ios/chrome/browser/ui/favicon/resources/default_favicon.imageset/default_favicon.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/favicon/resources/default_favicon.imageset/default_favicon@2x.png b/ios/chrome/browser/ui/favicon/resources/default_favicon.imageset/default_favicon@2x.png deleted file mode 100644 index 303bb22..0000000 --- a/ios/chrome/browser/ui/favicon/resources/default_favicon.imageset/default_favicon@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/favicon/resources/default_favicon.imageset/default_favicon@3x.png b/ios/chrome/browser/ui/favicon/resources/default_favicon.imageset/default_favicon@3x.png deleted file mode 100644 index 953e28c..0000000 --- a/ios/chrome/browser/ui/favicon/resources/default_favicon.imageset/default_favicon@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/icons/symbol_helpers.h b/ios/chrome/browser/ui/icons/symbol_helpers.h index d541e18..f17c920 100644 --- a/ios/chrome/browser/ui/icons/symbol_helpers.h +++ b/ios/chrome/browser/ui/icons/symbol_helpers.h
@@ -11,9 +11,6 @@ /// Import `symbols.h` and not this file directly. /// ******* -// Returns YES if the kUseSFSymbols flag is enabled. -bool UseSymbols(); - // Returns YES if the kUseSFSymbolsInOmnibox flag is enabled. bool UseSymbolsInOmnibox();
diff --git a/ios/chrome/browser/ui/icons/symbol_helpers.mm b/ios/chrome/browser/ui/icons/symbol_helpers.mm index 5eeda09..8b745dbe 100644 --- a/ios/chrome/browser/ui/icons/symbol_helpers.mm +++ b/ios/chrome/browser/ui/icons/symbol_helpers.mm
@@ -44,10 +44,6 @@ } // namespace -bool UseSymbols() { - return true; -} - bool UseSymbolsInOmnibox() { return base::FeatureList::IsEnabled(kUseSFSymbolsInOmnibox); }
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm b/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm index 951574b..7cff389 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm
@@ -15,7 +15,7 @@ #import "ios/chrome/browser/infobars/infobar_metrics_recorder.h" #import "ios/chrome/browser/shared/public/commands/activity_service_commands.h" #import "ios/chrome/browser/shared/public/commands/application_commands.h" -#import "ios/chrome/browser/shared/public/commands/browser_commands.h" +#import "ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h" #import "ios/chrome/browser/shared/public/commands/load_query_commands.h" #import "ios/chrome/browser/shared/public/features/features.h" #import "ios/chrome/browser/shared/ui/util/layout_guide_names.h" @@ -146,7 +146,7 @@ } - (void)setDispatcher:(id<ActivityServiceCommands, - BrowserCommands, + BrowserCoordinatorCommands, ApplicationCommands, LoadQueryCommands, OmniboxCommands>)dispatcher {
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm index ef72fa0..b64a01d 100644 --- a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm +++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm
@@ -115,10 +115,8 @@ } - (void)recordFeedScrolled:(int)scrollDistance { - if (IsGoodVisitsMetricEnabled()) { - self.goodVisitScroll = YES; - [self checkEngagementGoodVisitWithInteraction:NO]; - } + self.goodVisitScroll = YES; + [self checkEngagementGoodVisitWithInteraction:NO]; // If neither feed has been scrolled into, log "AllFeeds" scrolled. if (!self.scrolledReportedDiscover && !self.scrolledReportedFollowing) { @@ -172,9 +170,6 @@ asInteraction:NO]; } - if (!IsGoodVisitsMetricEnabled()) { - return; - } NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; if (visible) { NSDate* lastInteractionTimeForGoodVisitsDate = base::mac::ObjCCast<NSDate>( @@ -855,9 +850,6 @@ // Check if actionType warrants a Good Explicit Visit // If actionType is any of the cases below, trigger a Good Explicit // interaction by calling recordEngagementGoodVisit - if (!IsGoodVisitsMetricEnabled()) { - return; - } switch (actionType) { case FeedUserActionType::kAddedToReadLater: case FeedUserActionType::kOpenedNativeContextMenu: @@ -923,7 +915,6 @@ // Checks if a Good Visit should be recorded. `interacted` is YES if it was // triggered by an explicit interaction. (e.g. Opening a new Tab in Incognito.) - (void)checkEngagementGoodVisitWithInteraction:(BOOL)interacted { - DCHECK(IsGoodVisitsMetricEnabled()); // Determine if this interaction is part of a new session. base::Time now = base::Time::Now(); if ((now - self.lastInteractionTimeForGoodVisits) > @@ -1084,7 +1075,6 @@ // Check if the user has previously engaged with the feed in the same // session. // If neither feed has been engaged with, log "AllFeeds" engagement. - DCHECK(IsGoodVisitsMetricEnabled()); if (!self.goodVisitReportedAllFeeds) { // Log for the all feeds aggregate. UMA_HISTOGRAM_ENUMERATION(kAllFeedsEngagementTypeHistogram,
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm index bcb0c6c..694ea4c 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -654,8 +654,8 @@ // TODO(crbug.com/1045047): Use HandlerForProtocol after commands protocol // clean up. self.headerController.dispatcher = - static_cast<id<ApplicationCommands, BrowserCommands, OmniboxCommands, - FakeboxFocuser, LensCommands>>( + static_cast<id<ApplicationCommands, BrowserCoordinatorCommands, + OmniboxCommands, FakeboxFocuser, LensCommands>>( self.browser->GetCommandDispatcher()); self.headerController.commandHandler = self; self.headerController.delegate = self.NTPViewController; @@ -1654,10 +1654,8 @@ // Check if feed is visible before reporting NTP visibility as the feed // needs to be visible in order to use for metrics. // TODO(crbug.com/1373650) Move isFeedVisible check to the metrics recorder - if (IsGoodVisitsMetricEnabled()) { - if ([self isFeedVisible]) { - [self.feedMetricsRecorder recordNTPDidChangeVisibility:visible]; - } + if ([self isFeedVisible]) { + [self.feedMetricsRecorder recordNTPDidChangeVisibility:visible]; } }
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_egtest.mm b/ios/chrome/browser/ui/ntp/new_tab_page_egtest.mm index 7d8ee54..44d9bb9a 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_egtest.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_egtest.mm
@@ -367,14 +367,10 @@ performAction:grey_longPress()]; id<GREYMatcher> menuNewTabButtonMatcher; - if ([ChromeEarlGrey isSFSymbolEnabled]) { - menuNewTabButtonMatcher = grey_allOf( - chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_TOOLS_MENU_NEW_TAB), - grey_ancestor(grey_kindOfClassName(@"UICollectionView")), nil); - } else { - menuNewTabButtonMatcher = grey_accessibilityID(kToolsMenuNewTabId); - } + menuNewTabButtonMatcher = + grey_allOf(chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_TOOLS_MENU_NEW_TAB), + grey_ancestor(grey_kindOfClassName(@"UICollectionView")), nil); [[EarlGrey selectElementWithMatcher:menuNewTabButtonMatcher] performAction:grey_tap()];
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm index 7005693..c103c42 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
@@ -1610,6 +1610,7 @@ - (void)setContentOffset:(CGFloat)offset { self.collectionView.contentOffset = CGPointMake(0, offset); self.scrolledIntoFeed = offset > [self offsetWhenScrolledIntoFeed]; + [self handleStickyElementsForScrollPosition:offset force:YES]; if (self.feedHeaderViewController) { [self.feedHeaderViewController toggleBackgroundBlur:(self.scrolledIntoFeed &&
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h index f5cf985cf..467c9d7e 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h
@@ -8,7 +8,7 @@ #import <UIKit/UIKit.h> @protocol ApplicationCommands; -@protocol BrowserCommands; +@protocol BrowserCoordinatorCommands; @class LayoutGuideCenter; @protocol LensCommands; @class OmniboxTextFieldIOS; @@ -40,7 +40,8 @@ : NSObject <OmniboxAssistiveKeyboardDelegate> @property(nonatomic, weak) id<ApplicationCommands> applicationCommandsHandler; -@property(nonatomic, weak) id<BrowserCommands> browserCommandsHandler; +@property(nonatomic, weak) id<BrowserCoordinatorCommands> + browserCoordinatorCommandsHandler; @property(nonatomic, weak) id<LensCommands> lensCommandsHandler; @property(nonatomic, weak) id<QRScannerCommands> qrScannerCommandsHandler; @property(nonatomic, weak) OmniboxTextFieldIOS* omniboxTextField;
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm index f3e409a3..10132b7 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm
@@ -8,7 +8,7 @@ #import "base/metrics/user_metrics.h" #import "base/metrics/user_metrics_action.h" #import "ios/chrome/browser/shared/public/commands/application_commands.h" -#import "ios/chrome/browser/shared/public/commands/browser_commands.h" +#import "ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h" #import "ios/chrome/browser/shared/public/commands/lens_commands.h" #import "ios/chrome/browser/shared/public/commands/qr_scanner_commands.h" #import "ios/chrome/browser/shared/ui/util/layout_guide_names.h" @@ -25,7 +25,8 @@ @implementation OmniboxAssistiveKeyboardDelegateImpl @synthesize applicationCommandsHandler = _applicationCommandsHandler; -@synthesize browserCommandsHandler = _browserCommandsHandler; +@synthesize browserCoordinatorCommandsHandler = + _browserCoordinatorCommandsHandler; @synthesize layoutGuideCenter = _layoutGuideCenter; @synthesize qrScannerCommandsHandler = _qrScannerCommandsHandler; @synthesize omniboxTextField = _omniboxTextField; @@ -34,7 +35,7 @@ - (void)keyboardAccessoryVoiceSearchTapped:(id)sender { if (ios::provider::IsVoiceSearchEnabled()) { - [self.browserCommandsHandler preloadVoiceSearch]; + [self.browserCoordinatorCommandsHandler preloadVoiceSearch]; base::RecordAction(base::UserMetricsAction("MobileCustomRowVoiceSearch")); // Voice Search will query kVoiceSearchButtonGuide to know from where to // start its animation, so reference the sender under that name. The sender
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm index 045170f9..9c3cba29 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm
@@ -162,8 +162,9 @@ LayoutGuideCenterForBrowser(self.browser); // TODO(crbug.com/1045047): Use HandlerForProtocol after commands protocol // clean up. - self.keyboardDelegate.browserCommandsHandler = - static_cast<id<BrowserCommands>>(self.browser->GetCommandDispatcher()); + self.keyboardDelegate.browserCoordinatorCommandsHandler = + static_cast<id<BrowserCoordinatorCommands>>( + self.browser->GetCommandDispatcher()); self.keyboardDelegate.omniboxTextField = self.textField; self.keyboardAccessoryView = ConfigureAssistiveKeyboardViews( self.textField, kDotComTLD, self.keyboardDelegate, templateURLService);
diff --git a/ios/chrome/browser/ui/popup_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/BUILD.gn index 93e11a0..3fc7e77 100644 --- a/ios/chrome/browser/ui/popup_menu/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/BUILD.gn
@@ -19,7 +19,6 @@ ":constants", "resources:popup_menu_add_bookmark", "resources:popup_menu_bookmarks", - "resources:popup_menu_close_tab", "resources:popup_menu_downloads", "resources:popup_menu_edit_bookmark", "resources:popup_menu_enterprise_icon", @@ -30,9 +29,7 @@ "resources:popup_menu_new_incognito_tab", "resources:popup_menu_new_tab", "resources:popup_menu_new_window", - "resources:popup_menu_paste_and_go", "resources:popup_menu_price_notifications", - "resources:popup_menu_qr_scanner", "resources:popup_menu_read_later", "resources:popup_menu_reading_list", "resources:popup_menu_recent_tabs", @@ -40,14 +37,12 @@ "resources:popup_menu_report_an_issue", "resources:popup_menu_request_desktop_site", "resources:popup_menu_request_mobile_site", - "resources:popup_menu_search", "resources:popup_menu_settings", "resources:popup_menu_site_information", "resources:popup_menu_stop", "resources:popup_menu_text_zoom", "resources:popup_menu_translate", "resources:popup_menu_unfollow", - "resources:popup_menu_voice_search", "//base", "//components/bookmarks/browser", "//components/bookmarks/common",
diff --git a/ios/chrome/browser/ui/popup_menu/cells/BUILD.gn b/ios/chrome/browser/ui/popup_menu/cells/BUILD.gn index ff1863e..37b55b4 100644 --- a/ios/chrome/browser/ui/popup_menu/cells/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/cells/BUILD.gn
@@ -5,8 +5,6 @@ source_set("cells") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ - "popup_menu_navigation_item.h", - "popup_menu_navigation_item.mm", "popup_menu_text_item.h", "popup_menu_text_item.mm", "popup_menu_tools_item.h", @@ -17,7 +15,6 @@ "//ios/chrome/browser/ntp:features", "//ios/chrome/browser/shared/ui/table_view:styler", "//ios/chrome/browser/shared/ui/table_view/cells", - "//ios/chrome/browser/ui/favicon/resources:default_favicon", "//ios/chrome/browser/ui/popup_menu/public:ui_constants", "//ios/chrome/browser/ui/popup_menu/public/cells", "//ios/chrome/browser/ui/reading_list:reading_list_ui",
diff --git a/ios/chrome/browser/ui/popup_menu/cells/popup_menu_navigation_item.h b/ios/chrome/browser/ui/popup_menu/cells/popup_menu_navigation_item.h deleted file mode 100644 index d4b9e2a..0000000 --- a/ios/chrome/browser/ui/popup_menu/cells/popup_menu_navigation_item.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_POPUP_MENU_CELLS_POPUP_MENU_NAVIGATION_ITEM_H_ -#define IOS_CHROME_BROWSER_UI_POPUP_MENU_CELLS_POPUP_MENU_NAVIGATION_ITEM_H_ - -#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_item.h" -#import "ios/chrome/browser/ui/popup_menu/public/cells/popup_menu_item.h" - -namespace web { -class NavigationItem; -} // namespace web - -// Item used to display an item for a navigation menu. -@interface PopupMenuNavigationItem : TableViewItem<PopupMenuItem> -// Title of the navigation item. -@property(nonatomic, copy) NSString* title; -// Favicon to be displayed. Set to nil to display the default favicon. -@property(nonatomic, strong) UIImage* favicon; -// Item used to navigate in the history. -@property(nonatomic, assign) web::NavigationItem* navigationItem; -@end - -// Associated cell for a PopupMenuNavigationItem. -@interface PopupMenuNavigationCell : TableViewCell - -- (void)setTitle:(NSString*)title; -- (void)setFavicon:(UIImage*)favicon; - -// After this is called, the cell is listening for the -// UIContentSizeCategoryDidChangeNotification notification and updates its font -// size to the new category. -- (void)registerForContentSizeUpdates; - -@end - -#endif // IOS_CHROME_BROWSER_UI_POPUP_MENU_CELLS_POPUP_MENU_NAVIGATION_ITEM_H_
diff --git a/ios/chrome/browser/ui/popup_menu/cells/popup_menu_navigation_item.mm b/ios/chrome/browser/ui/popup_menu/cells/popup_menu_navigation_item.mm deleted file mode 100644 index 9fd7bf6..0000000 --- a/ios/chrome/browser/ui/popup_menu/cells/popup_menu_navigation_item.mm +++ /dev/null
@@ -1,183 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/popup_menu/cells/popup_menu_navigation_item.h" - -#import "ios/chrome/browser/shared/ui/table_view/chrome_table_view_styler.h" -#import "ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_constants.h" -#import "ios/chrome/common/ui/colors/semantic_color_names.h" -#import "ios/chrome/common/ui/util/constraints_ui_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { -const CGFloat kImageSize = 16; -const CGFloat kImageCornerRadius = 2; -const CGFloat kFaviconBackgroundSize = 28; -const CGFloat kFaviconBackgroundCornerRadius = 7; -const CGFloat kCellHeight = 44; -const CGFloat kIconTextMargin = 11; -const CGFloat kMargin = 15; -const CGFloat kVerticalMargin = 8; -const CGFloat kMaxHeight = 100; -} // namespace - -@implementation PopupMenuNavigationItem - -@synthesize actionIdentifier = _actionIdentifier; -@synthesize favicon = _favicon; -@synthesize title = _title; -@synthesize navigationItem = _navigationItem; - -- (instancetype)initWithType:(NSInteger)type { - self = [super initWithType:type]; - if (self) { - self.cellClass = [PopupMenuNavigationCell class]; - } - return self; -} - -- (void)configureCell:(PopupMenuNavigationCell*)cell - withStyler:(ChromeTableViewStyler*)styler { - [super configureCell:cell withStyler:styler]; - cell.accessibilityTraits = UIAccessibilityTraitButton; - [cell setFavicon:self.favicon]; - [cell setTitle:self.title]; -} - -#pragma mark - PopupMenuItem - -- (CGSize)cellSizeForWidth:(CGFloat)width { - // TODO(crbug.com/828357): This should be done at the table view level. - static PopupMenuNavigationCell* cell; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - cell = [[PopupMenuNavigationCell alloc] init]; - [cell registerForContentSizeUpdates]; - }); - - [self configureCell:cell withStyler:[[ChromeTableViewStyler alloc] init]]; - cell.frame = CGRectMake(0, 0, width, kMaxHeight); - [cell setNeedsLayout]; - [cell layoutIfNeeded]; - return [cell systemLayoutSizeFittingSize:CGSizeMake(width, kMaxHeight)]; -} - -@end - -#pragma mark - PopupMenuNavigationCell - -@interface PopupMenuNavigationCell () -@property(nonatomic, strong) UILabel* titleLabel; -@property(nonatomic, strong) UIImageView* faviconImageView; -@end - -@implementation PopupMenuNavigationCell - -@synthesize faviconImageView = _faviconImageView; -@synthesize titleLabel = _titleLabel; - -- (instancetype)initWithStyle:(UITableViewCellStyle)style - reuseIdentifier:(NSString*)reuseIdentifier { - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) { - UIView* selectedBackgroundView = [[UIView alloc] init]; - selectedBackgroundView.backgroundColor = - [UIColor colorNamed:kTableViewRowHighlightColor]; - self.selectedBackgroundView = selectedBackgroundView; - - _titleLabel = [[UILabel alloc] init]; - _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; - _titleLabel.font = [self titleFont]; - _titleLabel.adjustsFontForContentSizeCategory = YES; - - UIView* faviconBackground = [[UIView alloc] init]; - faviconBackground.translatesAutoresizingMaskIntoConstraints = NO; - faviconBackground.backgroundColor = - [UIColor colorNamed:kFaviconBackgroundColor]; - faviconBackground.layer.cornerRadius = kFaviconBackgroundCornerRadius; - - _faviconImageView = [[UIImageView alloc] init]; - _faviconImageView.translatesAutoresizingMaskIntoConstraints = NO; - _faviconImageView.layer.cornerRadius = kImageCornerRadius; - _faviconImageView.layer.masksToBounds = YES; - - [faviconBackground addSubview:_faviconImageView]; - - [self.contentView addSubview:_titleLabel]; - [self.contentView addSubview:faviconBackground]; - - ApplyVisualConstraintsWithMetrics( - @[ - @"H:|-(margin)-[favicon(faviconSize)]-(iconText)-[text]-(margin)-|", - @"H:[image(imageSize)]", @"V:[favicon(faviconSize)]", - @"V:[image(imageSize)]", - @"V:|-(verticalMargin)-[text]-(verticalMargin)-|" - ], - @{ - @"image" : _faviconImageView, - @"text" : _titleLabel, - @"favicon" : faviconBackground - }, - @{ - @"margin" : @(kMargin), - @"imageSize" : @(kImageSize), - @"faviconSize" : @(kFaviconBackgroundSize), - @"iconText" : @(kIconTextMargin), - @"verticalMargin" : @(kVerticalMargin), - }); - - [self.contentView.heightAnchor - constraintGreaterThanOrEqualToConstant:kCellHeight] - .active = YES; - AddSameCenterConstraints(_faviconImageView, faviconBackground); - AddSameCenterYConstraint(self.contentView, faviconBackground); - - self.isAccessibilityElement = YES; - } - return self; -} - -- (void)setTitle:(NSString*)title { - self.titleLabel.text = title; -} - -- (void)setFavicon:(UIImage*)favicon { - if (favicon) { - self.faviconImageView.image = favicon; - } else { - self.faviconImageView.image = [UIImage imageNamed:@"default_favicon"]; - } -} - -- (void)registerForContentSizeUpdates { - // This is needed because if the cell is static (used for height), - // adjustsFontForContentSizeCategory isn't working. - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(preferredContentSizeDidChange:) - name:UIContentSizeCategoryDidChangeNotification - object:nil]; -} - -- (void)prepareForReuse { - [super prepareForReuse]; - [self setFavicon:nil]; -} - -#pragma mark - Private - -// Callback when the preferred Content Size change. -- (void)preferredContentSizeDidChange:(NSNotification*)notification { - self.titleLabel.font = [self titleFont]; -} - -// Font to be used for the title. -- (UIFont*)titleFont { - return [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; -} - -@end
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.mm index 95bdfe44..5e02742 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.mm
@@ -172,76 +172,6 @@ [self.delegate recordSettingsMetricsPerProfile]; [self.dispatcher showSettingsFromViewController:self.baseViewController]; break; - case PopupMenuActionCloseTab: - RecordAction(UserMetricsAction("MobileMenuCloseTab")); - [self.browserCoordinatorCommandsHandler closeCurrentTab]; - break; - case PopupMenuActionNavigate: - // No metrics for this item. - [self.delegate navigateToPageForItem:item]; - break; - case PopupMenuActionVoiceSearch: - RecordAction(UserMetricsAction("MobileMenuVoiceSearch")); - [self.dispatcher startVoiceSearch]; - break; - case PopupMenuActionSearch: { - RecordAction(UserMetricsAction("MobileMenuSearch")); - OpenNewTabCommand* command = [OpenNewTabCommand commandWithIncognito:NO]; - command.shouldFocusOmnibox = YES; - [self.dispatcher openURLInNewTab:command]; - break; - } - case PopupMenuActionIncognitoSearch: { - RecordAction(UserMetricsAction("MobileMenuIncognitoSearch")); - OpenNewTabCommand* command = [OpenNewTabCommand commandWithIncognito:YES]; - command.shouldFocusOmnibox = YES; - [self.dispatcher openURLInNewTab:command]; - break; - } - case PopupMenuActionQRCodeSearch: - RecordAction(UserMetricsAction("MobileMenuScanQRCode")); - [self.qrScannerCommandsHandler showQRScanner]; - break; - case PopupMenuActionSearchCopiedImage: { - RecordAction(UserMetricsAction("MobileMenuSearchCopiedImage")); - [self.delegate searchCopiedImage]; - break; - } - case PopupMenuActionLensCopiedImage: { - RecordAction(UserMetricsAction("MobileMenuLensCopiedImage")); - [self.delegate lensCopiedImage]; - break; - } - case PopupMenuActionSearchCopiedText: { - RecordAction(UserMetricsAction("MobileMenuPasteAndGo")); - ClipboardRecentContent* clipboardRecentContent = - ClipboardRecentContent::GetInstance(); - clipboardRecentContent->GetRecentTextFromClipboard( - base::BindOnce(^(absl::optional<std::u16string> optional_text) { - if (!optional_text) { - return; - } - [self.dispatcher - loadQuery:base::SysUTF16ToNSString(optional_text.value()) - immediately:YES]; - })); - break; - } - case PopupMenuActionVisitCopiedLink: { - RecordAction(UserMetricsAction("MobileMenuPasteAndGo")); - ClipboardRecentContent* clipboardRecentContent = - ClipboardRecentContent::GetInstance(); - clipboardRecentContent->GetRecentURLFromClipboard( - base::BindOnce(^(absl::optional<GURL> optional_url) { - if (!optional_url) { - return; - } - [self.dispatcher - loadQuery:base::SysUTF8ToNSString(optional_url.value().spec()) - immediately:YES]; - })); - break; - } case PopupMenuActionEnterpriseInfoMessage: [self.dispatcher openURLInNewTab:[OpenNewTabCommand commandWithURLFromChrome:
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler_delegate.h b/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler_delegate.h index 56e05fe..e8c3387 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler_delegate.h +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler_delegate.h
@@ -17,16 +17,10 @@ @protocol PopupMenuActionHandlerDelegate // Adds the current page to the reading list. - (void)readPageLater; -// Navigates to the page associated with `item`. -- (void)navigateToPageForItem:(TableViewItem<PopupMenuItem>*)item; // Records open settings metric per profile type. - (void)recordSettingsMetricsPerProfile; // Records open downloads metric per profile type. - (void)recordDownloadsMetricsPerProfile; -// Starts a reverse image search for the image currently in the pasteboard. -- (void)searchCopiedImage; -// Starts a Lens search for the image currently in the pasteboard. -- (void)lensCopiedImage; // Toggles the follow status of the on browsing website. Called when the follow // menu option has been tapped. Follows or unfollows the website according to // the current follow status of the website.
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_constants.h b/ios/chrome/browser/ui/popup_menu/popup_menu_constants.h index d83b974f..6c9fb70d 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_constants.h +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_constants.h
@@ -10,8 +10,6 @@ // Accessibility IDs for the table view in various kinds of popup menus. extern NSString* const kPopupMenuToolsMenuTableViewId; extern NSString* const kPopupMenuToolsMenuActionListId; -extern NSString* const kPopupMenuNavigationTableViewId; -extern NSString* const kPopupMenuTabGridMenuTableViewId; // Accessibility IDs for the Tools Menu items. // Downloads item accessibility Identifier. @@ -30,12 +28,6 @@ extern NSString* const kToolsMenuPinTabId; // Unpin Tab item accessibility Identifier. extern NSString* const kToolsMenuUnpinTabId; -// Close all Tabs item accessibility Identifier. -extern NSString* const kToolsMenuCloseAllTabsId; -// Close all incognito Tabs item accessibility Identifier. -extern NSString* const kToolsMenuCloseAllIncognitoTabsId; -// Close the current tab item accessibility Identifier. -extern NSString* const kToolsMenuCloseTabId; // Follow item accessibility Identifier. extern NSString* const kToolsMenuFollowId; // Bookmarks item accessibility Identifier. @@ -62,8 +54,6 @@ extern NSString* const kToolsMenuSettingsActionId; // Help item accessibility Identifier. extern NSString* const kToolsMenuHelpId; -// Lens Copied Image item accessibility Identifier. -extern NSString* const kToolsMenuLensCopiedImage; // Request mobile item accessibility Identifier. extern NSString* const kToolsMenuRequestMobileId; // ReadLater item accessibility Identifier. @@ -74,18 +64,8 @@ extern NSString* const kToolsMenuEditBookmark; // SiteInformation item accessibility Identifier. extern NSString* const kToolsMenuSiteInformation; -// Paste and Go item accessibility Identifier. -extern NSString* const kToolsMenuPasteAndGo; -// Voice Search item accessibility Identifier. -extern NSString* const kToolsMenuVoiceSearch; -// Search item accessibility Identifier. -extern NSString* const kToolsMenuSearch; // Incognito Search item accessibility Identifier. extern NSString* const kToolsMenuIncognitoSearch; -// QR Code Search item accessibility Identifier. -extern NSString* const kToolsMenuQRCodeSearch; -// Copied Image Search item accessibility Identifier. -extern NSString* const kToolsMenuCopiedImageSearch; // Text Zoom item accessibility identifier. extern NSString* const kToolsMenuTextZoom; // Text Enterprise info item accessibility identifier.
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_constants.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_constants.mm index 8f047f0b..dc203f1 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_constants.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_constants.mm
@@ -12,10 +12,6 @@ @"kPopupMenuToolsMenuTableViewId"; NSString* const kPopupMenuToolsMenuActionListId = @"kPopupMenuToolsMenuActionListId"; -NSString* const kPopupMenuNavigationTableViewId = - @"kPopupMenuNavigationTableViewId"; -NSString* const kPopupMenuTabGridMenuTableViewId = - @"kPopupMenuTabGridMenuTableViewId"; NSString* const kToolsMenuDownloadsId = @"kToolsMenuDownloadsId"; NSString* const kToolsMenuReload = @"kToolsMenuReload"; @@ -25,10 +21,6 @@ NSString* const kToolsMenuNewIncognitoTabId = @"kToolsMenuNewIncognitoTabId"; NSString* const kToolsMenuPinTabId = @"kToolsMenuPinTabId"; NSString* const kToolsMenuUnpinTabId = @"kToolsMenuUnpinTabId"; -NSString* const kToolsMenuCloseAllTabsId = @"kToolsMenuCloseAllTabsId"; -NSString* const kToolsMenuCloseAllIncognitoTabsId = - @"kToolsMenuCloseAllIncognitoTabsId"; -NSString* const kToolsMenuCloseTabId = @"kToolsMenuCloseTabId"; NSString* const kToolsMenuFollowId = @"kToolsMenuFollowId"; NSString* const kToolsMenuBookmarksId = @"kToolsMenuBookmarksId"; NSString* const kToolsMenuReadingListId = @"kToolsMenuReadingListId"; @@ -42,18 +34,12 @@ NSString* const kToolsMenuSettingsId = @"kToolsMenuSettingsId"; NSString* const kToolsMenuSettingsActionId = @"kToolsMenuSettingsActionId"; NSString* const kToolsMenuHelpId = @"kToolsMenuHelpId"; -NSString* const kToolsMenuLensCopiedImage = @"kToolsMenuLensCopiedImage"; NSString* const kToolsMenuRequestMobileId = @"kToolsMenuRequestMobileId"; NSString* const kToolsMenuReadLater = @"kToolsMenuReadLater"; NSString* const kToolsMenuAddToBookmarks = @"kToolsMenuAddToBookmarks"; NSString* const kToolsMenuEditBookmark = @"kToolsMenuEditBookmark"; NSString* const kToolsMenuSiteInformation = @"kToolsMenuSiteInformation"; -NSString* const kToolsMenuPasteAndGo = @"kToolsMenuPasteAndGo"; -NSString* const kToolsMenuVoiceSearch = @"kToolsMenuVoiceSearch"; -NSString* const kToolsMenuSearch = @"kToolsMenuSearch"; NSString* const kToolsMenuIncognitoSearch = @"kToolsMenuIncognitoSearch"; -NSString* const kToolsMenuQRCodeSearch = @"kToolsMenuQRCodeSearch"; -NSString* const kToolsMenuCopiedImageSearch = @"kToolsMenuCopiedImageSearch"; NSString* const kToolsMenuTextZoom = @"kToolsMenuTextZoom"; NSString* const kTextMenuEnterpriseInfo = @"kTextMenuEnterpriseInfo"; NSString* const kToolsMenuFollow = @"kToolsMenuFollow";
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h index 4f34768..77fc58d2 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
@@ -8,13 +8,12 @@ #import <UIKit/UIKit.h> #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" -#import "ios/chrome/browser/ui/popup_menu/public/popup_menu_long_press_delegate.h" @class BubblePresenter; @protocol PopupMenuUIUpdating; // Coordinator for the popup menu, handling the commands. -@interface PopupMenuCoordinator : ChromeCoordinator<PopupMenuLongPressDelegate> +@interface PopupMenuCoordinator : ChromeCoordinator // Initializes this Coordinator with its `browser` and a nil base view // controller.
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm index 805efdc..f5798bb 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -72,12 +72,6 @@ using base::UserMetricsAction; namespace { -// Returns the corresponding command type for a Popup menu `type`. -PopupMenuCommandType CommandTypeFromPopupType(PopupMenuType type) { - if (type == PopupMenuTypeToolsMenu) - return PopupMenuCommandTypeToolsMenu; - return PopupMenuCommandTypeDefault; -} // Enum for IOS.OverflowMenu.ActionType histogram. // Entries should not be renumbered and numeric values should never be reused. @@ -183,34 +177,245 @@ #pragma mark - PopupMenuCommands -- (void)showNavigationHistoryBackPopupMenu { - RecordAction(UserMetricsAction("MobileToolbarShowTabHistoryMenu")); - [self presentPopupOfType:PopupMenuTypeNavigationBackward - fromLayoutGuideNamed:kBackButtonGuide]; -} - -- (void)showNavigationHistoryForwardPopupMenu { - RecordAction(UserMetricsAction("MobileToolbarShowTabHistoryMenu")); - [self presentPopupOfType:PopupMenuTypeNavigationForward - fromLayoutGuideNamed:kForwardButtonGuide]; -} - - (void)showToolsMenuPopup { - // The metric is registered at the toolbar level. - [self presentPopupOfType:PopupMenuTypeToolsMenu - fromLayoutGuideNamed:kToolsMenuGuide]; -} + if (self.presenter || self.overflowMenuMediator) { + [self dismissPopupMenuAnimated:YES]; + } -- (void)showTabGridButtonPopup { - RecordAction(UserMetricsAction("MobileToolbarShowTabGridMenu")); - [self presentPopupOfType:PopupMenuTypeTabGrid - fromLayoutGuideNamed:kTabSwitcherGuide]; -} + // TODO(crbug.com/1045047): Use HandlerForProtocol after commands protocol + // clean up. + id<BrowserCommands> callableDispatcher = + static_cast<id<BrowserCommands>>(self.browser->GetCommandDispatcher()); + [callableDispatcher prepareForOverflowMenuPresentation]; -- (void)showNewTabButtonPopup { - RecordAction(UserMetricsAction("MobileToolbarShowNewTabMenu")); - [self presentPopupOfType:PopupMenuTypeNewTab - fromLayoutGuideNamed:kNewTabButtonGuide]; + self.requestStartTime = [NSDate timeIntervalSinceReferenceDate]; + + PopupMenuTableViewController* tableViewController = + [[PopupMenuTableViewController alloc] init]; + tableViewController.baseViewController = self.baseViewController; + tableViewController.tableView.accessibilityIdentifier = + kPopupMenuToolsMenuTableViewId; + + self.viewController = tableViewController; + + BOOL triggerNewIncognitoTabTip = + self.bubblePresenter.incognitoTabTipBubblePresenter.triggerFollowUpAction; + self.bubblePresenter.incognitoTabTipBubblePresenter.triggerFollowUpAction = + NO; + + OverlayPresenter* overlayPresenter = OverlayPresenter::FromBrowser( + self.browser, OverlayModality::kWebContentArea); + self.contentBlockerMediator = [[BrowserContainerMediator alloc] + initWithWebStateList:self.browser->GetWebStateList() + webContentAreaOverlayPresenter:overlayPresenter]; + + // Create the overflow menu mediator first so the popup mediator isn't created + // if not needed. + self.toolsMenuOpenTime = [NSDate timeIntervalSinceReferenceDate]; + self.toolsMenuWasScrolledVertically = NO; + self.toolsMenuWasScrolledHorizontally = NO; + self.toolsMenuUserTookAction = NO; + if (IsNewOverflowMenuEnabled()) { + if (@available(iOS 15, *)) { + self.overflowMenuMediator = [[OverflowMenuMediator alloc] init]; + + CGFloat screenWidth = self.baseViewController.view.frame.size.width; + UIContentSizeCategory contentSizeCategory = + self.baseViewController.traitCollection.preferredContentSizeCategory; + + self.overflowMenuMediator.visibleDestinationsCount = + [OverflowMenuUIConfiguration + numDestinationsVisibleWithoutHorizontalScrollingForScreenWidth: + screenWidth + forContentSizeCategory: + contentSizeCategory]; + + self.overflowMenuMediator.dispatcher = static_cast< + id<ActivityServiceCommands, ApplicationCommands, BrowserCommands, + BrowserCoordinatorCommands, FindInPageCommands, + PriceNotificationsCommands, TextZoomCommands>>( + self.browser->GetCommandDispatcher()); + self.overflowMenuMediator.bookmarksCommandsHandler = HandlerForProtocol( + self.browser->GetCommandDispatcher(), BookmarksCommands); + self.overflowMenuMediator.pageInfoCommandsHandler = HandlerForProtocol( + self.browser->GetCommandDispatcher(), PageInfoCommands); + self.overflowMenuMediator.popupMenuCommandsHandler = HandlerForProtocol( + self.browser->GetCommandDispatcher(), PopupMenuCommands); + self.overflowMenuMediator.webStateList = self.browser->GetWebStateList(); + self.overflowMenuMediator.navigationAgent = + WebNavigationBrowserAgent::FromBrowser(self.browser); + self.overflowMenuMediator.baseViewController = self.baseViewController; + self.overflowMenuMediator.isIncognito = + self.browser->GetBrowserState()->IsOffTheRecord(); + self.overflowMenuMediator.bookmarkModel = + ios::LocalOrSyncableBookmarkModelFactory::GetForBrowserState( + self.browser->GetBrowserState()); + self.overflowMenuMediator.browserStatePrefs = + self.browser->GetBrowserState()->GetPrefs(); + self.overflowMenuMediator.localStatePrefs = + GetApplicationContext()->GetLocalState(); + self.overflowMenuMediator.engagementTracker = + feature_engagement::TrackerFactory::GetForBrowserState( + self.browser->GetBrowserState()); + self.overflowMenuMediator.webContentAreaOverlayPresenter = + overlayPresenter; + self.overflowMenuMediator.browserPolicyConnector = + GetApplicationContext()->GetBrowserPolicyConnector(); + self.overflowMenuMediator.syncService = + SyncServiceFactory::GetForBrowserState( + self.browser->GetBrowserState()); + + if (IsWebChannelsEnabled()) { + self.overflowMenuMediator.followBrowserAgent = + FollowBrowserAgent::FromBrowser(self.browser); + } + + self.contentBlockerMediator.consumer = self.overflowMenuMediator; + + OverflowMenuUIConfiguration* uiConfiguration = + [[OverflowMenuUIConfiguration alloc] + initWithPresentingViewControllerHorizontalSizeClass: + self.baseViewController.traitCollection.horizontalSizeClass + presentingViewControllerVerticalSizeClass: + self.baseViewController.traitCollection + .verticalSizeClass]; + + self.popupMenuHelpCoordinator.uiConfiguration = uiConfiguration; + + UIViewController* menu = [OverflowMenuViewProvider + makeViewControllerWithModel:self.overflowMenuMediator + .overflowMenuModel + uiConfiguration:uiConfiguration + metricsHandler:self]; + + LayoutGuideCenter* layoutGuideCenter = + LayoutGuideCenterForBrowser(self.browser); + UILayoutGuide* layoutGuide = + [layoutGuideCenter makeLayoutGuideNamed:kToolsMenuGuide]; + [self.baseViewController.view addLayoutGuide:layoutGuide]; + + menu.modalPresentationStyle = UIModalPresentationPopover; + + UIPopoverPresentationController* popoverPresentationController = + menu.popoverPresentationController; + popoverPresentationController.sourceView = self.baseViewController.view; + popoverPresentationController.sourceRect = layoutGuide.layoutFrame; + popoverPresentationController.permittedArrowDirections = + UIPopoverArrowDirectionUp; + popoverPresentationController.delegate = self; + popoverPresentationController.backgroundColor = + [UIColor colorNamed:kBackgroundColor]; + + // The adaptive controller adjusts styles based on window size: sheet + // for slim windows on iPhone and iPad, popover for larger windows on + // ipad. + UISheetPresentationController* sheetPresentationController = + popoverPresentationController.adaptiveSheetPresentationController; + if (sheetPresentationController) { + sheetPresentationController.delegate = self; + sheetPresentationController.prefersGrabberVisible = YES; + sheetPresentationController.prefersEdgeAttachedInCompactHeight = YES; + sheetPresentationController + .widthFollowsPreferredContentSizeWhenEdgeAttached = YES; + + NSArray<UISheetPresentationControllerDetent*>* regularDetents = @[ + [UISheetPresentationControllerDetent mediumDetent], + [UISheetPresentationControllerDetent largeDetent] + ]; + + NSArray<UISheetPresentationControllerDetent*>* largeTextDetents = + @[ [UISheetPresentationControllerDetent largeDetent] ]; + + BOOL hasLargeText = UIContentSizeCategoryIsAccessibilityCategory( + menu.traitCollection.preferredContentSizeCategory); + sheetPresentationController.detents = + hasLargeText ? largeTextDetents : regularDetents; + } + + __weak __typeof(self) weakSelf = self; + [self.baseViewController + presentViewController:menu + animated:YES + completion:^{ + [weakSelf.popupMenuHelpCoordinator + showOverflowMenuIPHInViewController:menu]; + }]; + return; + } + } + + self.mediator = [[PopupMenuMediator alloc] + initWithIsIncognito:self.browser->GetBrowserState() + ->IsOffTheRecord() + readingListModel:ReadingListModelFactory::GetForBrowserState( + self.browser->GetBrowserState()) + triggerNewIncognitoTabTip:triggerNewIncognitoTabTip + browserPolicyConnector:GetApplicationContext() + ->GetBrowserPolicyConnector()]; + self.mediator.engagementTracker = + feature_engagement::TrackerFactory::GetForBrowserState( + self.browser->GetBrowserState()); + self.mediator.webStateList = self.browser->GetWebStateList(); + self.mediator.browserCommandsHandler = + HandlerForProtocol(self.browser->GetCommandDispatcher(), BrowserCommands); + self.mediator.lensCommandsHandler = + HandlerForProtocol(self.browser->GetCommandDispatcher(), LensCommands); + self.mediator.bookmarkModel = + ios::LocalOrSyncableBookmarkModelFactory::GetForBrowserState( + self.browser->GetBrowserState()); + self.mediator.prefService = self.browser->GetBrowserState()->GetPrefs(); + self.mediator.templateURLService = + ios::TemplateURLServiceFactory::GetForBrowserState( + self.browser->GetBrowserState()); + self.mediator.popupMenu = tableViewController; + self.mediator.webContentAreaOverlayPresenter = overlayPresenter; + self.mediator.URLLoadingBrowserAgent = + UrlLoadingBrowserAgent::FromBrowser(self.browser); + if (IsWebChannelsEnabled()) { + self.mediator.followBrowserAgent = + FollowBrowserAgent::FromBrowser(self.browser); + } + + self.contentBlockerMediator.consumer = self.mediator; + + self.actionHandler = [[PopupMenuActionHandler alloc] init]; + self.actionHandler.baseViewController = self.baseViewController; + self.actionHandler.dispatcher = static_cast< + id<ApplicationCommands, BrowserCommands, FindInPageCommands, + LoadQueryCommands, PriceNotificationsCommands, TextZoomCommands>>( + self.browser->GetCommandDispatcher()); + self.actionHandler.bookmarksCommandsHandler = HandlerForProtocol( + self.browser->GetCommandDispatcher(), BookmarksCommands); + self.actionHandler.browserCoordinatorCommandsHandler = HandlerForProtocol( + self.browser->GetCommandDispatcher(), BrowserCoordinatorCommands); + self.actionHandler.pageInfoCommandsHandler = HandlerForProtocol( + self.browser->GetCommandDispatcher(), PageInfoCommands); + self.actionHandler.popupMenuCommandsHandler = HandlerForProtocol( + self.browser->GetCommandDispatcher(), PopupMenuCommands); + self.actionHandler.qrScannerCommandsHandler = HandlerForProtocol( + self.browser->GetCommandDispatcher(), QRScannerCommands); + self.actionHandler.delegate = self.mediator; + self.actionHandler.navigationAgent = + WebNavigationBrowserAgent::FromBrowser(self.browser); + tableViewController.delegate = self.actionHandler; + + self.presenter = [[PopupMenuPresenter alloc] init]; + self.presenter.baseViewController = self.baseViewController; + self.presenter.presentedViewController = tableViewController; + LayoutGuideCenter* layoutGuideCenter = + LayoutGuideCenterForBrowser(self.browser); + UILayoutGuide* layoutGuide = + [layoutGuideCenter makeLayoutGuideNamed:kToolsMenuGuide]; + [self.baseViewController.view addLayoutGuide:layoutGuide]; + self.presenter.layoutGuide = layoutGuide; + self.presenter.delegate = self; + + [self.presenter prepareForPresentation]; + [self.presenter presentAnimated:YES]; + + // Scrolls happen during prepareForPresentation, so only attach the metrics + // handler after presentation is done. + tableViewController.metricsHandler = self; } - (void)dismissPopupMenuAnimated:(BOOL)animated { @@ -299,16 +504,6 @@ [snackbarCommandsHandler showSnackbarMessage:message]; } -#pragma mark - PopupMenuLongPressDelegate - -- (void)longPressFocusPointChangedTo:(CGPoint)point { - [self.viewController focusRowAtPoint:point]; -} - -- (void)longPressEndedAtPoint:(CGPoint)point { - [self.viewController selectRowAtPoint:point]; -} - #pragma mark - ContainedPresenterDelegate - (void)containedPresenterDidPresent:(id<ContainedPresenter>)presenter { @@ -368,270 +563,6 @@ #pragma mark - Private -// Presents a popup menu of type `type` with an animation starting from the -// layout named `guideName`. -- (void)presentPopupOfType:(PopupMenuType)type - fromLayoutGuideNamed:(GuideName*)guideName { - if (self.presenter || self.overflowMenuMediator) - [self dismissPopupMenuAnimated:YES]; - - // TODO(crbug.com/1045047): Use HandlerForProtocol after commands protocol - // clean up. - id<BrowserCommands> callableDispatcher = - static_cast<id<BrowserCommands>>(self.browser->GetCommandDispatcher()); - [callableDispatcher - prepareForPopupMenuPresentation:CommandTypeFromPopupType(type)]; - - self.requestStartTime = [NSDate timeIntervalSinceReferenceDate]; - - PopupMenuTableViewController* tableViewController = - [[PopupMenuTableViewController alloc] init]; - tableViewController.baseViewController = self.baseViewController; - if (type == PopupMenuTypeToolsMenu) { - tableViewController.tableView.accessibilityIdentifier = - kPopupMenuToolsMenuTableViewId; - } else if (type == PopupMenuTypeNavigationBackward || - type == PopupMenuTypeNavigationForward) { - tableViewController.tableView.accessibilityIdentifier = - kPopupMenuNavigationTableViewId; - } else if (type == PopupMenuTypeTabGrid) { - tableViewController.tableView.accessibilityIdentifier = - kPopupMenuTabGridMenuTableViewId; - } - - self.viewController = tableViewController; - - BOOL triggerNewIncognitoTabTip = NO; - if (type == PopupMenuTypeToolsMenu) { - triggerNewIncognitoTabTip = - self.bubblePresenter.incognitoTabTipBubblePresenter - .triggerFollowUpAction; - self.bubblePresenter.incognitoTabTipBubblePresenter.triggerFollowUpAction = - NO; - } - - OverlayPresenter* overlayPresenter = OverlayPresenter::FromBrowser( - self.browser, OverlayModality::kWebContentArea); - self.contentBlockerMediator = [[BrowserContainerMediator alloc] - initWithWebStateList:self.browser->GetWebStateList() - webContentAreaOverlayPresenter:overlayPresenter]; - - // Create the overflow menu mediator first so the popup mediator isn't created - // if not needed. - if (type == PopupMenuTypeToolsMenu) { - self.toolsMenuOpenTime = [NSDate timeIntervalSinceReferenceDate]; - self.toolsMenuWasScrolledVertically = NO; - self.toolsMenuWasScrolledHorizontally = NO; - self.toolsMenuUserTookAction = NO; - if (IsNewOverflowMenuEnabled()) { - if (@available(iOS 15, *)) { - self.overflowMenuMediator = [[OverflowMenuMediator alloc] init]; - - CGFloat screenWidth = self.baseViewController.view.frame.size.width; - UIContentSizeCategory contentSizeCategory = - self.baseViewController.traitCollection - .preferredContentSizeCategory; - - self.overflowMenuMediator - .visibleDestinationsCount = [OverflowMenuUIConfiguration - numDestinationsVisibleWithoutHorizontalScrollingForScreenWidth: - screenWidth - forContentSizeCategory: - contentSizeCategory]; - - self.overflowMenuMediator.dispatcher = static_cast< - id<ActivityServiceCommands, ApplicationCommands, BrowserCommands, - BrowserCoordinatorCommands, FindInPageCommands, - PriceNotificationsCommands, TextZoomCommands>>( - self.browser->GetCommandDispatcher()); - self.overflowMenuMediator.bookmarksCommandsHandler = HandlerForProtocol( - self.browser->GetCommandDispatcher(), BookmarksCommands); - self.overflowMenuMediator.pageInfoCommandsHandler = HandlerForProtocol( - self.browser->GetCommandDispatcher(), PageInfoCommands); - self.overflowMenuMediator.popupMenuCommandsHandler = HandlerForProtocol( - self.browser->GetCommandDispatcher(), PopupMenuCommands); - self.overflowMenuMediator.webStateList = - self.browser->GetWebStateList(); - self.overflowMenuMediator.navigationAgent = - WebNavigationBrowserAgent::FromBrowser(self.browser); - self.overflowMenuMediator.baseViewController = self.baseViewController; - self.overflowMenuMediator.isIncognito = - self.browser->GetBrowserState()->IsOffTheRecord(); - self.overflowMenuMediator.bookmarkModel = - ios::LocalOrSyncableBookmarkModelFactory::GetForBrowserState( - self.browser->GetBrowserState()); - self.overflowMenuMediator.browserStatePrefs = - self.browser->GetBrowserState()->GetPrefs(); - self.overflowMenuMediator.localStatePrefs = - GetApplicationContext()->GetLocalState(); - self.overflowMenuMediator.engagementTracker = - feature_engagement::TrackerFactory::GetForBrowserState( - self.browser->GetBrowserState()); - self.overflowMenuMediator.webContentAreaOverlayPresenter = - overlayPresenter; - self.overflowMenuMediator.browserPolicyConnector = - GetApplicationContext()->GetBrowserPolicyConnector(); - self.overflowMenuMediator.syncService = - SyncServiceFactory::GetForBrowserState( - self.browser->GetBrowserState()); - - if (IsWebChannelsEnabled()) { - self.overflowMenuMediator.followBrowserAgent = - FollowBrowserAgent::FromBrowser(self.browser); - } - - self.contentBlockerMediator.consumer = self.overflowMenuMediator; - - OverflowMenuUIConfiguration* uiConfiguration = - [[OverflowMenuUIConfiguration alloc] - initWithPresentingViewControllerHorizontalSizeClass: - self.baseViewController.traitCollection.horizontalSizeClass - presentingViewControllerVerticalSizeClass: - self.baseViewController.traitCollection - .verticalSizeClass]; - - self.popupMenuHelpCoordinator.uiConfiguration = uiConfiguration; - - UIViewController* menu = [OverflowMenuViewProvider - makeViewControllerWithModel:self.overflowMenuMediator - .overflowMenuModel - uiConfiguration:uiConfiguration - metricsHandler:self]; - - LayoutGuideCenter* layoutGuideCenter = - LayoutGuideCenterForBrowser(self.browser); - UILayoutGuide* layoutGuide = - [layoutGuideCenter makeLayoutGuideNamed:guideName]; - [self.baseViewController.view addLayoutGuide:layoutGuide]; - - menu.modalPresentationStyle = UIModalPresentationPopover; - - UIPopoverPresentationController* popoverPresentationController = - menu.popoverPresentationController; - popoverPresentationController.sourceView = self.baseViewController.view; - popoverPresentationController.sourceRect = layoutGuide.layoutFrame; - popoverPresentationController.permittedArrowDirections = - UIPopoverArrowDirectionUp; - popoverPresentationController.delegate = self; - popoverPresentationController.backgroundColor = - [UIColor colorNamed:kBackgroundColor]; - - // The adaptive controller adjusts styles based on window size: sheet - // for slim windows on iPhone and iPad, popover for larger windows on - // ipad. - UISheetPresentationController* sheetPresentationController = - popoverPresentationController.adaptiveSheetPresentationController; - if (sheetPresentationController) { - sheetPresentationController.delegate = self; - sheetPresentationController.prefersGrabberVisible = YES; - sheetPresentationController.prefersEdgeAttachedInCompactHeight = YES; - sheetPresentationController - .widthFollowsPreferredContentSizeWhenEdgeAttached = YES; - - NSArray<UISheetPresentationControllerDetent*>* regularDetents = @[ - [UISheetPresentationControllerDetent mediumDetent], - [UISheetPresentationControllerDetent largeDetent] - ]; - - NSArray<UISheetPresentationControllerDetent*>* largeTextDetents = - @[ [UISheetPresentationControllerDetent largeDetent] ]; - - BOOL hasLargeText = UIContentSizeCategoryIsAccessibilityCategory( - menu.traitCollection.preferredContentSizeCategory); - sheetPresentationController.detents = - hasLargeText ? largeTextDetents : regularDetents; - } - - __weak __typeof(self) weakSelf = self; - [self.baseViewController - presentViewController:menu - animated:YES - completion:^{ - [weakSelf.popupMenuHelpCoordinator - showOverflowMenuIPHInViewController:menu]; - }]; - return; - } - } - } - - self.mediator = [[PopupMenuMediator alloc] - initWithType:type - isIncognito:self.browser->GetBrowserState() - ->IsOffTheRecord() - readingListModel:ReadingListModelFactory::GetForBrowserState( - self.browser->GetBrowserState()) - triggerNewIncognitoTabTip:triggerNewIncognitoTabTip - browserPolicyConnector:GetApplicationContext() - ->GetBrowserPolicyConnector()]; - self.mediator.engagementTracker = - feature_engagement::TrackerFactory::GetForBrowserState( - self.browser->GetBrowserState()); - self.mediator.webStateList = self.browser->GetWebStateList(); - self.mediator.browserCommandsHandler = - HandlerForProtocol(self.browser->GetCommandDispatcher(), BrowserCommands); - self.mediator.lensCommandsHandler = - HandlerForProtocol(self.browser->GetCommandDispatcher(), LensCommands); - self.mediator.bookmarkModel = - ios::LocalOrSyncableBookmarkModelFactory::GetForBrowserState( - self.browser->GetBrowserState()); - self.mediator.prefService = self.browser->GetBrowserState()->GetPrefs(); - self.mediator.templateURLService = - ios::TemplateURLServiceFactory::GetForBrowserState( - self.browser->GetBrowserState()); - self.mediator.popupMenu = tableViewController; - self.mediator.webContentAreaOverlayPresenter = overlayPresenter; - self.mediator.URLLoadingBrowserAgent = - UrlLoadingBrowserAgent::FromBrowser(self.browser); - if (IsWebChannelsEnabled()) { - self.mediator.followBrowserAgent = - FollowBrowserAgent::FromBrowser(self.browser); - } - - self.contentBlockerMediator.consumer = self.mediator; - - self.actionHandler = [[PopupMenuActionHandler alloc] init]; - self.actionHandler.baseViewController = self.baseViewController; - self.actionHandler.dispatcher = static_cast< - id<ApplicationCommands, BrowserCommands, FindInPageCommands, - LoadQueryCommands, PriceNotificationsCommands, TextZoomCommands>>( - self.browser->GetCommandDispatcher()); - self.actionHandler.bookmarksCommandsHandler = HandlerForProtocol( - self.browser->GetCommandDispatcher(), BookmarksCommands); - self.actionHandler.browserCoordinatorCommandsHandler = HandlerForProtocol( - self.browser->GetCommandDispatcher(), BrowserCoordinatorCommands); - self.actionHandler.pageInfoCommandsHandler = HandlerForProtocol( - self.browser->GetCommandDispatcher(), PageInfoCommands); - self.actionHandler.popupMenuCommandsHandler = HandlerForProtocol( - self.browser->GetCommandDispatcher(), PopupMenuCommands); - self.actionHandler.qrScannerCommandsHandler = HandlerForProtocol( - self.browser->GetCommandDispatcher(), QRScannerCommands); - self.actionHandler.delegate = self.mediator; - self.actionHandler.navigationAgent = - WebNavigationBrowserAgent::FromBrowser(self.browser); - tableViewController.delegate = self.actionHandler; - - self.presenter = [[PopupMenuPresenter alloc] init]; - self.presenter.baseViewController = self.baseViewController; - self.presenter.presentedViewController = tableViewController; - LayoutGuideCenter* layoutGuideCenter = - LayoutGuideCenterForBrowser(self.browser); - UILayoutGuide* layoutGuide = - [layoutGuideCenter makeLayoutGuideNamed:guideName]; - [self.baseViewController.view addLayoutGuide:layoutGuide]; - self.presenter.layoutGuide = layoutGuide; - self.presenter.delegate = self; - - [self.presenter prepareForPresentation]; - [self.presenter presentAnimated:YES]; - - // Scrolls happen during prepareForPresentation, so only attach the metrics - // handler after presentation is done. - if (type == PopupMenuTypeToolsMenu) { - tableViewController.metricsHandler = self; - } -} - - (void)trackToolsMenuNoHorizontalScrollOrAction { ChromeBrowserState* browserState = self.browser->GetBrowserState(); if (!browserState) {
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_help_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_help_coordinator.mm index dc8ad6a4..ccb151c3 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_help_coordinator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_help_coordinator.mm
@@ -214,7 +214,7 @@ presentInViewController:self.baseViewController view:self.baseViewController.view anchorPoint:anchorPoint]; - [self.UIUpdater updateUIForIPHDisplayed:PopupMenuTypeToolsMenu]; + [self.UIUpdater updateUIForOverflowMenuIPHDisplayed]; } #pragma mark - Overflow Menu Bubble methods
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.h b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.h index 3a3efa3b2..80f239ab 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.h +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.h
@@ -34,15 +34,15 @@ @interface PopupMenuMediator : NSObject <BrowserContainerConsumer, PopupMenuActionHandlerDelegate> -// Initializes the mediator with a `type` of popup menu, whether it -// `isIncognito`, a `readingListModel` used to display the badge for the reading -// list entry, whether the mediator should `triggerNewIncognitoTabTip`, and a -// `browserPolicyConnector` used to check if the browser is managed by policy. -- (instancetype)initWithType:(PopupMenuType)type - isIncognito:(BOOL)isIncognito - readingListModel:(ReadingListModel*)readingListModel - triggerNewIncognitoTabTip:(BOOL)triggerNewIncognitoTabTip - browserPolicyConnector:(BrowserPolicyConnectorIOS*)browserPolicyConnector +// Initializes the mediator with whether it `isIncognito`, a `readingListModel` +// used to display the badge for the reading list entry, whether the mediator +// should `triggerNewIncognitoTabTip`, and a `browserPolicyConnector` used to +// check if the browser is managed by policy. +- (instancetype)initWithIsIncognito:(BOOL)isIncognito + readingListModel:(ReadingListModel*)readingListModel + triggerNewIncognitoTabTip:(BOOL)triggerNewIncognitoTabTip + browserPolicyConnector: + (BrowserPolicyConnectorIOS*)browserPolicyConnector NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm index 05351d6..53504df 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
@@ -55,7 +55,6 @@ #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_tile_constants.h" #import "ios/chrome/browser/ui/icons/symbols.h" #import "ios/chrome/browser/ui/lens/lens_entrypoint.h" -#import "ios/chrome/browser/ui/popup_menu/cells/popup_menu_navigation_item.h" #import "ios/chrome/browser/ui/popup_menu/cells/popup_menu_text_item.h" #import "ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.h" #import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h" @@ -172,9 +171,6 @@ @property(nonatomic, strong) NSArray<NSArray<TableViewItem<PopupMenuItem>*>*>* items; -// Type of this mediator. -@property(nonatomic, assign) PopupMenuType type; - // The current web state associated with the toolbar. @property(nonatomic, assign) web::WebState* webState; @@ -228,16 +224,14 @@ #pragma mark - Public -- (instancetype)initWithType:(PopupMenuType)type - isIncognito:(BOOL)isIncognito - readingListModel:(ReadingListModel*)readingListModel - triggerNewIncognitoTabTip:(BOOL)triggerNewIncognitoTabTip - browserPolicyConnector: - (BrowserPolicyConnectorIOS*)browserPolicyConnector { +- (instancetype)initWithIsIncognito:(BOOL)isIncognito + readingListModel:(ReadingListModel*)readingListModel + triggerNewIncognitoTabTip:(BOOL)triggerNewIncognitoTabTip + browserPolicyConnector: + (BrowserPolicyConnectorIOS*)browserPolicyConnector { self = [super init]; if (self) { _isIncognito = isIncognito; - _type = type; _readingListMenuNotifier = [[ReadingListMenuNotifier alloc] initWithReadingList:readingListModel]; _webStateObserver = std::make_unique<web::WebStateObserverBridge>(self); @@ -522,37 +516,13 @@ - (NSArray<NSArray<TableViewItem<PopupMenuItem>*>*>*)items { if (!_items) { - switch (self.type) { - case PopupMenuTypeToolsMenu: - [self createToolsMenuItems]; - if (self.webState && self.followItem) { - FollowTabHelper* followTabHelper = - FollowTabHelper::FromWebState(self.webState); - if (followTabHelper) { - followTabHelper->SetFollowMenuUpdater(self); - } - } - break; - case PopupMenuTypeNavigationForward: - DCHECK(!UseSymbols()); - [self createNavigationItemsForType:PopupMenuTypeNavigationForward]; - break; - case PopupMenuTypeNavigationBackward: - DCHECK(!UseSymbols()); - [self createNavigationItemsForType:PopupMenuTypeNavigationBackward]; - break; - case PopupMenuTypeTabGrid: - DCHECK(!UseSymbols()); - [self createTabGridMenuItems]; - break; - case PopupMenuTypeTabStripTabGrid: - DCHECK(!UseSymbols()); - [self createTabGridMenuItems]; - break; - case PopupMenuTypeNewTab: - DCHECK(!UseSymbols()); - [self createSearchMenuItems]; - break; + [self createToolsMenuItems]; + if (self.webState && self.followItem) { + FollowTabHelper* followTabHelper = + FollowTabHelper::FromWebState(self.webState); + if (followTabHelper) { + followTabHelper->SetFollowMenuUpdater(self); + } } NSMutableArray* specificItems = [NSMutableArray array]; if (self.reloadStopItem) @@ -609,18 +579,6 @@ webState); } -- (void)navigateToPageForItem:(TableViewItem<PopupMenuItem>*)item { - if (!self.webState) - return; - - web::NavigationItem* navigationItem = - base::mac::ObjCCastStrict<PopupMenuNavigationItem>(item).navigationItem; - int index = - self.webState->GetNavigationManager()->GetIndexOfItem(navigationItem); - DCHECK_NE(index, -1); - self.webState->GetNavigationManager()->GoToIndex(index); -} - - (void)recordSettingsMetricsPerProfile { profile_metrics::BrowserProfileType type = _isIncognito ? profile_metrics::BrowserProfileType::kIncognito @@ -908,148 +866,6 @@ #pragma mark - Item creation (Private) -- (void)setPopupMenuItemsOnClipboardItemsReceived: - (const std::set<ClipboardContentType>&)types { - NSMutableArray* items = [NSMutableArray array]; - // The consumer is expecting an array of arrays of items. Each sub array - // represent a section in the popup menu. Having one sub array means - // having all the items in the same section. - PopupMenuToolsItem* copiedContentItem = nil; - if (search_engines::SupportsSearchImageWithLens(self.templateURLService) && - ios::provider::IsLensSupported() && - base::FeatureList::IsEnabled(kEnableLensInOmniboxCopiedImage) && - base::Contains(types, ClipboardContentType::Image)) { - copiedContentItem = CreateTableViewItem( - IDS_IOS_TOOLS_MENU_LENS_COPIED_IMAGE, PopupMenuActionLensCopiedImage, - @"popup_menu_paste_and_go", kToolsMenuLensCopiedImage); - } else if (search_engines::SupportsSearchByImage(self.templateURLService) && - base::Contains(types, ClipboardContentType::Image)) { - copiedContentItem = CreateTableViewItem( - IDS_IOS_TOOLS_MENU_SEARCH_COPIED_IMAGE, - PopupMenuActionSearchCopiedImage, @"popup_menu_paste_and_go", - kToolsMenuCopiedImageSearch); - } else if (base::Contains(types, ClipboardContentType::URL)) { - copiedContentItem = CreateTableViewItem( - IDS_IOS_TOOLS_MENU_VISIT_COPIED_LINK, PopupMenuActionVisitCopiedLink, - @"popup_menu_paste_and_go", kToolsMenuPasteAndGo); - } else if (base::Contains(types, ClipboardContentType::Text)) { - copiedContentItem = CreateTableViewItem( - IDS_IOS_TOOLS_MENU_SEARCH_COPIED_TEXT, PopupMenuActionSearchCopiedText, - @"popup_menu_paste_and_go", kToolsMenuPasteAndGo); - } - if (copiedContentItem) { - [items addObject:@[ copiedContentItem ]]; - } - - [items addObject:[self searchMenuStaticItems]]; - self.items = items; - [self.popupMenu setPopupMenuItems:self.items]; -} - -- (void)createNavigationItemsForType:(PopupMenuType)type { - DCHECK(type == PopupMenuTypeNavigationForward || - type == PopupMenuTypeNavigationBackward); - if (!self.webState) - return; - - web::NavigationManager* navigationManager = - self.webState->GetNavigationManager(); - std::vector<web::NavigationItem*> navigationItems; - if (type == PopupMenuTypeNavigationForward) { - navigationItems = navigationManager->GetForwardItems(); - } else { - navigationItems = navigationManager->GetBackwardItems(); - } - NSMutableArray* items = [NSMutableArray array]; - for (web::NavigationItem* navigationItem : navigationItems) { - PopupMenuNavigationItem* item = - [[PopupMenuNavigationItem alloc] initWithType:kItemTypeEnumZero]; - if ([self shouldUseIncognitoNTPResourcesForURL:navigationItem - ->GetVirtualURL()]) { - item.title = l10n_util::GetNSStringWithFixup(IDS_IOS_NEW_INCOGNITO_TAB); - UIImage* image; - if (@available(iOS 15, *)) { - image = SymbolWithPalette( - CustomSymbolWithPointSize(kIncognitoCircleFillSymbol, - kSymbolActionPointSize), - SmallIncognitoPalette()); - } else { - image = [UIImage imageNamed:@"incognito_badge_ios14"]; - } - item.favicon = image; - } else { - item.title = - base::SysUTF16ToNSString(navigationItem->GetTitleForDisplay()); - const gfx::Image& image = navigationItem->GetFaviconStatus().image; - if (!image.IsEmpty()) - item.favicon = image.ToUIImage(); - } - item.actionIdentifier = PopupMenuActionNavigate; - item.navigationItem = navigationItem; - [items addObject:item]; - } - - self.items = @[ items ]; -} - -// Creates the menu items for the tab grid menu. -- (void)createTabGridMenuItems { - PopupMenuToolsItem* closeTab = - CreateTableViewItem(IDS_IOS_TOOLS_MENU_CLOSE_TAB, PopupMenuActionCloseTab, - @"popup_menu_close_tab", kToolsMenuCloseTabId); - closeTab.destructiveAction = YES; - self.items = @[ [self itemsForNewTab], @[ closeTab ] ]; -} - -// Creates the menu items for the search menu. -- (void)createSearchMenuItems { - self.items = @[ [self searchMenuStaticItems] ]; - - ClipboardRecentContent* clipboardRecentContent = - ClipboardRecentContent::GetInstance(); - - std::set<ClipboardContentType> clipboard_types; - clipboard_types.insert(ClipboardContentType::URL); - clipboard_types.insert(ClipboardContentType::Text); - clipboard_types.insert(ClipboardContentType::Image); - - __weak PopupMenuMediator* weakSelf = self; - clipboardRecentContent->HasRecentContentFromClipboard( - clipboard_types, - base::BindOnce(^(std::set<ClipboardContentType> matched_types) { - dispatch_async(dispatch_get_main_queue(), ^{ - [weakSelf setPopupMenuItemsOnClipboardItemsReceived:matched_types]; - }); - })); -} - -// Creates and returns the search menu items that are static (i.e. always in -// the search menu). -- (NSArray<TableViewItem<PopupMenuItem>*>*)searchMenuStaticItems { - PopupMenuToolsItem* QRCodeSearch = CreateTableViewItem( - IDS_IOS_TOOLS_MENU_QR_SCANNER, PopupMenuActionQRCodeSearch, - @"popup_menu_qr_scanner", kToolsMenuQRCodeSearch); - PopupMenuToolsItem* voiceSearch = CreateTableViewItem( - IDS_IOS_TOOLS_MENU_VOICE_SEARCH, PopupMenuActionVoiceSearch, - @"popup_menu_voice_search", kToolsMenuVoiceSearch); - - PopupMenuToolsItem* newSearch = - CreateTableViewItem(IDS_IOS_TOOLS_MENU_NEW_SEARCH, PopupMenuActionSearch, - @"popup_menu_search", kToolsMenuSearch); - // Disable the new search if the incognito mode is forced by enterprise - // policy. - newSearch.enabled = !IsIncognitoModeForced(self.prefService); - - PopupMenuToolsItem* newIncognitoSearch = CreateTableViewItem( - IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_SEARCH, PopupMenuActionIncognitoSearch, - @"popup_menu_new_incognito_tab", kToolsMenuIncognitoSearch); - // Disable the new incognito search if the incognito mode is disabled by - // enterprise policy. - newIncognitoSearch.enabled = !IsIncognitoModeDisabled(self.prefService); - - return @[ newSearch, newIncognitoSearch, voiceSearch, QRCodeSearch ]; -} - // Creates the menu items for the tools menu. - (void)createToolsMenuItems { // Reload or stop page action, created as reload.
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm index 5fd3118..72aa719 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm
@@ -182,28 +182,25 @@ } protected: - PopupMenuMediator* CreateMediator(PopupMenuType type, - BOOL is_incognito, + PopupMenuMediator* CreateMediator(BOOL is_incognito, BOOL trigger_incognito_hint) { - mediator_ = [[PopupMenuMediator alloc] initWithType:type - isIncognito:is_incognito - readingListModel:reading_list_model_ - triggerNewIncognitoTabTip:trigger_incognito_hint - browserPolicyConnector:nil]; + mediator_ = + [[PopupMenuMediator alloc] initWithIsIncognito:is_incognito + readingListModel:reading_list_model_ + triggerNewIncognitoTabTip:trigger_incognito_hint + browserPolicyConnector:nil]; return mediator_; } PopupMenuMediator* CreateMediatorWithBrowserPolicyConnector( - PopupMenuType type, BOOL is_incognito, BOOL trigger_incognito_hint, BrowserPolicyConnectorIOS* browser_policy_connector) { - mediator_ = - [[PopupMenuMediator alloc] initWithType:type - isIncognito:is_incognito - readingListModel:reading_list_model_ - triggerNewIncognitoTabTip:trigger_incognito_hint - browserPolicyConnector:browser_policy_connector]; + mediator_ = [[PopupMenuMediator alloc] + initWithIsIncognito:is_incognito + readingListModel:reading_list_model_ + triggerNewIncognitoTabTip:trigger_incognito_hint + browserPolicyConnector:browser_policy_connector]; return mediator_; } @@ -322,7 +319,7 @@ // Tests that the feature engagement tracker get notified when the mediator is // disconnected and the tracker wants the notification badge displayed. TEST_F(PopupMenuMediatorTest, TestFeatureEngagementDisconnect) { - CreateMediator(PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + CreateMediator(/*is_incognito=*/NO, /*trigger_incognito_hint=*/NO); feature_engagement::test::MockTracker tracker; EXPECT_CALL(tracker, ShouldTriggerHelpUI(testing::_)) @@ -338,7 +335,7 @@ // Tests that the mediator is returning the right number of items and sections // for the Tools Menu type. TEST_F(PopupMenuMediatorTest, TestToolsMenuItemsCount) { - CreateMediator(PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + CreateMediator(/*is_incognito=*/NO, /*trigger_incognito_hint=*/NO); NSUInteger number_of_action_items = 7; if (ios::provider::IsUserFeedbackSupported()) { @@ -366,43 +363,9 @@ ]); } -// Tests that the mediator is returning the right number of items and sections -// for the Tab Grid type, in non-incognito. -TEST_F(PopupMenuMediatorTest, TestTabGridMenuNonIncognito) { - // With symbols this is handled in the ToolbarMediator. - if (UseSymbols()) - return; - - CreateMediator(PopupMenuTypeTabGrid, /*is_incognito=*/NO, - /*trigger_incognito_hint=*/NO); - CheckMediatorSetItems(@[ - // New Tab, New Incognito Tab - @(2), - // Close Tab - @(1) - ]); -} - -// Tests that the mediator is returning the right number of items and sections -// for the Tab Grid type, in incognito. -TEST_F(PopupMenuMediatorTest, TestTabGridMenuIncognito) { - // With symbols this is handled in the ToolbarMediator. - if (UseSymbols()) - return; - - CreateMediator(PopupMenuTypeTabGrid, /*is_incognito=*/YES, - /*trigger_incognito_hint=*/NO); - CheckMediatorSetItems(@[ - // New Tab, New Incognito Tab - @(2), - // Close Tab - @(1) - ]); -} - // Tests that the mediator is asking for an item to be highlighted when asked. TEST_F(PopupMenuMediatorTest, TestNewIncognitoHint) { - CreateMediator(PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + CreateMediator(/*is_incognito=*/NO, /*trigger_incognito_hint=*/YES); mediator_.webStateList = browser_->GetWebStateList(); SetUpActiveWebState(); @@ -413,7 +376,7 @@ // Test that the mediator isn't asking for an highlighted item. TEST_F(PopupMenuMediatorTest, TestNewIncognitoNoHint) { - CreateMediator(PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + CreateMediator(/*is_incognito=*/NO, /*trigger_incognito_hint=*/NO); [[popup_menu_ reject] setItemToHighlight:[OCMArg any]]; mediator_.webStateList = browser_->GetWebStateList(); @@ -421,24 +384,10 @@ mediator_.popupMenu = popup_menu_; } -// Tests that the mediator is asking for an item to be highlighted when asked. -TEST_F(PopupMenuMediatorTest, TestNewIncognitoHintTabGrid) { - if (UseSymbols()) - return; - - CreateMediator(PopupMenuTypeTabGrid, /*is_incognito=*/NO, - /*trigger_incognito_hint=*/YES); - OCMExpect([popup_menu_ setItemToHighlight:[OCMArg isNotNil]]); - mediator_.webStateList = browser_->GetWebStateList(); - SetUpActiveWebState(); - mediator_.popupMenu = popup_menu_; - EXPECT_OCMOCK_VERIFY(popup_menu_); -} - // Tests that the items returned by the mediator are correctly enabled on a // WebPage. TEST_F(PopupMenuMediatorTest, TestItemsStatusOnWebPage) { - CreateMediator(PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + CreateMediator(/*is_incognito=*/NO, /*trigger_incognito_hint=*/NO); mediator_.webStateList = browser_->GetWebStateList(); FakePopupMenuConsumer* consumer = [[FakePopupMenuConsumer alloc] init]; @@ -455,7 +404,7 @@ // Tests that the items returned by the mediator are correctly enabled on the // NTP. TEST_F(PopupMenuMediatorTest, TestItemsStatusOnNTP) { - CreateMediator(PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + CreateMediator(/*is_incognito=*/NO, /*trigger_incognito_hint=*/NO); mediator_.webStateList = browser_->GetWebStateList(); FakePopupMenuConsumer* consumer = [[FakePopupMenuConsumer alloc] init]; @@ -476,7 +425,7 @@ const GURL kUrl("https://chromium.test"); web_state_->SetCurrentURL(kUrl); CreatePrefs(); - CreateMediator(PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + CreateMediator(/*is_incognito=*/NO, /*trigger_incognito_hint=*/NO); mediator_.webStateList = browser_->GetWebStateList(); mediator_.webContentAreaOverlayPresenter = OverlayPresenter::FromBrowser( @@ -505,7 +454,7 @@ // Tests that the "Text Zoom..." button is disabled on non-HTML pages. TEST_F(PopupMenuMediatorTest, TestTextZoomDisabled) { - CreateMediator(PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + CreateMediator(/*is_incognito=*/NO, /*trigger_incognito_hint=*/NO); mediator_.webStateList = browser_->GetWebStateList(); @@ -526,7 +475,7 @@ // Tests that the "Managed by..." item is hidden when none of the policies is // set. TEST_F(PopupMenuMediatorTest, TestEnterpriseInfoHidden) { - CreateMediator(PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + CreateMediator(/*is_incognito=*/NO, /*trigger_incognito_hint=*/NO); mediator_.webStateList = browser_->GetWebStateList(); @@ -555,7 +504,7 @@ enterprise_policy_helper->GetPolicyProvider()->UpdateChromePolicy(map); CreateMediatorWithBrowserPolicyConnector( - PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + /*is_incognito=*/NO, /*trigger_incognito_hint=*/NO, connector); mediator_.webStateList = browser_->GetWebStateList(); @@ -572,7 +521,7 @@ TEST_F(PopupMenuMediatorTest, TestBookmarksToolsMenuButtons) { const GURL url("https://bookmarked.url"); web_state_->SetCurrentURL(url); - CreateMediator(PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + CreateMediator(/*is_incognito=*/NO, /*trigger_incognito_hint=*/NO); CreatePrefs(); SetUpBookmarks(); @@ -597,7 +546,7 @@ // Tests that the bookmark button is disabled when EditBookmarksEnabled pref is // changed to false. TEST_F(PopupMenuMediatorTest, TestDisableBookmarksButton) { - CreateMediator(PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + CreateMediator(/*is_incognito=*/NO, /*trigger_incognito_hint=*/NO); CreatePrefs(); FakePopupMenuConsumer* consumer = [[FakePopupMenuConsumer alloc] init];
diff --git a/ios/chrome/browser/ui/popup_menu/public/BUILD.gn b/ios/chrome/browser/ui/popup_menu/public/BUILD.gn index 1ec91b0..e7c66b1a 100644 --- a/ios/chrome/browser/ui/popup_menu/public/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/public/BUILD.gn
@@ -4,10 +4,7 @@ source_set("public") { configs += [ "//build/config/compiler:enable_arc" ] - sources = [ - "popup_menu_long_press_delegate.h", - "popup_menu_ui_updating.h", - ] + sources = [ "popup_menu_ui_updating.h" ] deps = [ "//base" ] frameworks = [ "UIKit.framework" ] }
diff --git a/ios/chrome/browser/ui/popup_menu/public/cells/popup_menu_item.h b/ios/chrome/browser/ui/popup_menu/public/cells/popup_menu_item.h index b6445c7e..f6688a81 100644 --- a/ios/chrome/browser/ui/popup_menu/public/cells/popup_menu_item.h +++ b/ios/chrome/browser/ui/popup_menu/public/cells/popup_menu_item.h
@@ -35,24 +35,6 @@ PopupMenuActionRecentTabs, PopupMenuActionHistory, PopupMenuActionSettings, - PopupMenuActionCloseTab, - PopupMenuActionNavigate, - PopupMenuActionVoiceSearch, - PopupMenuActionSearch, - PopupMenuActionIncognitoSearch, - PopupMenuActionQRCodeSearch, - PopupMenuActionLensCopiedImage, - PopupMenuActionSearchCopiedImage, - PopupMenuActionSearchCopiedText, - PopupMenuActionVisitCopiedLink, - // Language selection popup menu - PopupMenuActionSelectLanguage, - // Translate option selection popup menu - PopupMenuActionChangeTargetLanguage, - PopupMenuActionAlwaysTranslateSourceLanguage, - PopupMenuActionNeverTranslateSourceLanguage, - PopupMenuActionNeverTranslateSite, - PopupMenuActionChangeSourceLanguage, // Textual popup menu PopupMenuActionEnterpriseInfoMessage, };
diff --git a/ios/chrome/browser/ui/popup_menu/public/popup_menu_long_press_delegate.h b/ios/chrome/browser/ui/popup_menu/public/popup_menu_long_press_delegate.h deleted file mode 100644 index 365a906..0000000 --- a/ios/chrome/browser/ui/popup_menu/public/popup_menu_long_press_delegate.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_POPUP_MENU_PUBLIC_POPUP_MENU_LONG_PRESS_DELEGATE_H_ -#define IOS_CHROME_BROWSER_UI_POPUP_MENU_PUBLIC_POPUP_MENU_LONG_PRESS_DELEGATE_H_ - -#import <UIKit/UIKit.h> - -// Delegate for the object creating popup menu with a long press gesture. -@protocol PopupMenuLongPressDelegate - -// Notifies the popup menu that the focus `point` of the long press gesture has -// changed. `point` should be in window base coordinates. -- (void)longPressFocusPointChangedTo:(CGPoint)point; -// Notifies the popup menu that the long press gesture has ended at `point`. -// `point` should be in window base coordinates. -- (void)longPressEndedAtPoint:(CGPoint)point; - -@end - -#endif // IOS_CHROME_BROWSER_UI_POPUP_MENU_PUBLIC_POPUP_MENU_LONG_PRESS_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.h b/ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.h index fa0e68f..af2a918 100644 --- a/ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.h +++ b/ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.h
@@ -34,13 +34,6 @@ - (instancetype)init NS_DESIGNATED_INITIALIZER; - (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE; -// Selects the row at `point`. This is the same as tapping the row. Point must -// be in window base coordinates. -- (void)selectRowAtPoint:(CGPoint)point; -// Focuses the row at `point`. This adds an highlight to the row. Point must be -// in window base coordinates. -- (void)focusRowAtPoint:(CGPoint)point; - @end #endif // IOS_CHROME_BROWSER_UI_POPUP_MENU_PUBLIC_POPUP_MENU_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.mm b/ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.mm index 265a387..c24d2434 100644 --- a/ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.mm +++ b/ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.mm
@@ -56,45 +56,6 @@ return self; } -- (void)selectRowAtPoint:(CGPoint)point { - NSIndexPath* rowIndexPath = [self indexPathForInnerRowAtPoint:point]; - if (!rowIndexPath) - return; - - UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:rowIndexPath]; - if (!cell.userInteractionEnabled) - return; - - base::RecordAction(base::UserMetricsAction("MobilePopupMenuSwipeToSelect")); - [self.delegate popupMenuTableViewController:self - didSelectItem:[self.tableViewModel - itemAtIndexPath:rowIndexPath] - origin:[cell convertPoint:cell.center - toView:nil]]; -} - -- (void)focusRowAtPoint:(CGPoint)point { - NSIndexPath* rowIndexPath = [self indexPathForInnerRowAtPoint:point]; - - BOOL rowAlreadySelected = NO; - NSArray<NSIndexPath*>* selectedRows = - [self.tableView indexPathsForSelectedRows]; - for (NSIndexPath* selectedIndexPath in selectedRows) { - if (selectedIndexPath == rowIndexPath) { - rowAlreadySelected = YES; - continue; - } - [self.tableView deselectRowAtIndexPath:selectedIndexPath animated:NO]; - } - - if (!rowAlreadySelected && rowIndexPath) { - [self.tableView selectRowAtIndexPath:rowIndexPath - animated:NO - scrollPosition:UITableViewScrollPositionNone]; - TriggerHapticFeedbackForSelectionChange(); - } -} - #pragma mark - PopupMenuConsumer - (void)setItemToHighlight:(TableViewItem<PopupMenuItem>*)itemToHighlight {
diff --git a/ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_updating.h b/ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_updating.h index f7b40f2..89a37a2f 100644 --- a/ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_updating.h +++ b/ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_updating.h
@@ -7,22 +7,12 @@ #import <UIKit/UIKit.h> -// Type of popup menus. -typedef NS_ENUM(NSInteger, PopupMenuType) { - PopupMenuTypeToolsMenu, - PopupMenuTypeNavigationBackward, - PopupMenuTypeNavigationForward, - PopupMenuTypeTabGrid, - PopupMenuTypeNewTab, - PopupMenuTypeTabStripTabGrid, -}; - // Protocol for a class updating the UI to reflect the presentation of a popup // menu. @protocol PopupMenuUIUpdating -// Updates the UI for the presentation of an in-product help of type -// `popupType`. -- (void)updateUIForIPHDisplayed:(PopupMenuType)popupType; +// Updates the UI for the presentation of an in-product help for the overflow +// menu. +- (void)updateUIForOverflowMenuIPHDisplayed; // Updates the UI for the dismissal of an in-product help. - (void)updateUIForIPHDismissed; @end
diff --git a/ios/chrome/browser/ui/popup_menu/resources/BUILD.gn b/ios/chrome/browser/ui/popup_menu/resources/BUILD.gn index 73954bf..c58b4b1 100644 --- a/ios/chrome/browser/ui/popup_menu/resources/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/resources/BUILD.gn
@@ -4,41 +4,6 @@ import("//build/config/ios/asset_catalog.gni") -imageset("popup_menu_search") { - sources = [ - "popup_menu_search.imageset/Contents.json", - "popup_menu_search.imageset/popup_menu_search@2x.png", - "popup_menu_search.imageset/popup_menu_search@3x.png", - ] -} - -imageset("popup_menu_paste_and_go") { - sources = [ - "popup_menu_paste_and_go.imageset/Contents.json", - "popup_menu_paste_and_go.imageset/popup_menu_paste_and_go.png", - "popup_menu_paste_and_go.imageset/popup_menu_paste_and_go@2x.png", - "popup_menu_paste_and_go.imageset/popup_menu_paste_and_go@3x.png", - ] -} - -imageset("popup_menu_qr_scanner") { - sources = [ - "popup_menu_qr_scanner.imageset/Contents.json", - "popup_menu_qr_scanner.imageset/popup_menu_qr_scanner.png", - "popup_menu_qr_scanner.imageset/popup_menu_qr_scanner@2x.png", - "popup_menu_qr_scanner.imageset/popup_menu_qr_scanner@3x.png", - ] -} - -imageset("popup_menu_voice_search") { - sources = [ - "popup_menu_voice_search.imageset/Contents.json", - "popup_menu_voice_search.imageset/popup_menu_voice_search.png", - "popup_menu_voice_search.imageset/popup_menu_voice_search@2x.png", - "popup_menu_voice_search.imageset/popup_menu_voice_search@3x.png", - ] -} - imageset("popup_menu_read_later") { sources = [ "popup_menu_read_later.imageset/Contents.json", @@ -66,15 +31,6 @@ ] } -imageset("popup_menu_close_tab") { - sources = [ - "popup_menu_close_tab.imageset/Contents.json", - "popup_menu_close_tab.imageset/popup_menu_close_tab.png", - "popup_menu_close_tab.imageset/popup_menu_close_tab@2x.png", - "popup_menu_close_tab.imageset/popup_menu_close_tab@3x.png", - ] -} - imageset("popup_menu_site_information") { sources = [ "popup_menu_site_information.imageset/Contents.json",
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_close_tab.imageset/Contents.json b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_close_tab.imageset/Contents.json deleted file mode 100644 index 6ce3d0c1c..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_close_tab.imageset/Contents.json +++ /dev/null
@@ -1,23 +0,0 @@ -{ - "images": [ - { - "idiom": "universal", - "scale": "1x", - "filename": "popup_menu_close_tab.png" - }, - { - "idiom": "universal", - "scale": "2x", - "filename": "popup_menu_close_tab@2x.png" - }, - { - "idiom": "universal", - "scale": "3x", - "filename": "popup_menu_close_tab@3x.png" - } - ], - "info": { - "version": 1, - "author": "xcode" - } -}
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_close_tab.imageset/popup_menu_close_tab.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_close_tab.imageset/popup_menu_close_tab.png deleted file mode 100644 index beacf61..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_close_tab.imageset/popup_menu_close_tab.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_close_tab.imageset/popup_menu_close_tab@2x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_close_tab.imageset/popup_menu_close_tab@2x.png deleted file mode 100644 index baafede8..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_close_tab.imageset/popup_menu_close_tab@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_close_tab.imageset/popup_menu_close_tab@3x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_close_tab.imageset/popup_menu_close_tab@3x.png deleted file mode 100644 index f7757e2..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_close_tab.imageset/popup_menu_close_tab@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_paste_and_go.imageset/Contents.json b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_paste_and_go.imageset/Contents.json deleted file mode 100644 index 826d3df4..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_paste_and_go.imageset/Contents.json +++ /dev/null
@@ -1,23 +0,0 @@ -{ - "images": [ - { - "idiom": "universal", - "scale": "1x", - "filename": "popup_menu_paste_and_go.png" - }, - { - "idiom": "universal", - "scale": "2x", - "filename": "popup_menu_paste_and_go@2x.png" - }, - { - "idiom": "universal", - "scale": "3x", - "filename": "popup_menu_paste_and_go@3x.png" - } - ], - "info": { - "version": 1, - "author": "xcode" - } -}
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_paste_and_go.imageset/popup_menu_paste_and_go.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_paste_and_go.imageset/popup_menu_paste_and_go.png deleted file mode 100644 index 68ea4958..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_paste_and_go.imageset/popup_menu_paste_and_go.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_paste_and_go.imageset/popup_menu_paste_and_go@2x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_paste_and_go.imageset/popup_menu_paste_and_go@2x.png deleted file mode 100644 index b72d3eb..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_paste_and_go.imageset/popup_menu_paste_and_go@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_paste_and_go.imageset/popup_menu_paste_and_go@3x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_paste_and_go.imageset/popup_menu_paste_and_go@3x.png deleted file mode 100644 index 8d576eb..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_paste_and_go.imageset/popup_menu_paste_and_go@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_qr_scanner.imageset/Contents.json b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_qr_scanner.imageset/Contents.json deleted file mode 100644 index 8042e20..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_qr_scanner.imageset/Contents.json +++ /dev/null
@@ -1,23 +0,0 @@ -{ - "images": [ - { - "idiom": "universal", - "scale": "1x", - "filename": "popup_menu_qr_scanner.png" - }, - { - "idiom": "universal", - "scale": "2x", - "filename": "popup_menu_qr_scanner@2x.png" - }, - { - "idiom": "universal", - "scale": "3x", - "filename": "popup_menu_qr_scanner@3x.png" - } - ], - "info": { - "version": 1, - "author": "xcode" - } -}
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_qr_scanner.imageset/popup_menu_qr_scanner.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_qr_scanner.imageset/popup_menu_qr_scanner.png deleted file mode 100644 index c01c916..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_qr_scanner.imageset/popup_menu_qr_scanner.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_qr_scanner.imageset/popup_menu_qr_scanner@2x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_qr_scanner.imageset/popup_menu_qr_scanner@2x.png deleted file mode 100644 index 70b6379..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_qr_scanner.imageset/popup_menu_qr_scanner@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_qr_scanner.imageset/popup_menu_qr_scanner@3x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_qr_scanner.imageset/popup_menu_qr_scanner@3x.png deleted file mode 100644 index 4d1f637..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_qr_scanner.imageset/popup_menu_qr_scanner@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_search.imageset/Contents.json b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_search.imageset/Contents.json deleted file mode 100644 index b4f50a4..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_search.imageset/Contents.json +++ /dev/null
@@ -1,22 +0,0 @@ -{ - "images": [ - { - "idiom": "universal", - "scale": "1x" - }, - { - "idiom": "universal", - "scale": "2x", - "filename": "popup_menu_search@2x.png" - }, - { - "idiom": "universal", - "scale": "3x", - "filename": "popup_menu_search@3x.png" - } - ], - "info": { - "version": 1, - "author": "xcode" - } -}
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_search.imageset/popup_menu_search@2x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_search.imageset/popup_menu_search@2x.png deleted file mode 100644 index 0ab97e59..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_search.imageset/popup_menu_search@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_search.imageset/popup_menu_search@3x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_search.imageset/popup_menu_search@3x.png deleted file mode 100644 index 7c8897e..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_search.imageset/popup_menu_search@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_voice_search.imageset/Contents.json b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_voice_search.imageset/Contents.json deleted file mode 100644 index a9d8a07..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_voice_search.imageset/Contents.json +++ /dev/null
@@ -1,23 +0,0 @@ -{ - "images": [ - { - "idiom": "universal", - "scale": "1x", - "filename": "popup_menu_voice_search.png" - }, - { - "idiom": "universal", - "scale": "2x", - "filename": "popup_menu_voice_search@2x.png" - }, - { - "idiom": "universal", - "scale": "3x", - "filename": "popup_menu_voice_search@3x.png" - } - ], - "info": { - "version": 1, - "author": "xcode" - } -}
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_voice_search.imageset/popup_menu_voice_search.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_voice_search.imageset/popup_menu_voice_search.png deleted file mode 100644 index b8d9a8a..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_voice_search.imageset/popup_menu_voice_search.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_voice_search.imageset/popup_menu_voice_search@2x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_voice_search.imageset/popup_menu_voice_search@2x.png deleted file mode 100644 index db92fff..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_voice_search.imageset/popup_menu_voice_search@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_voice_search.imageset/popup_menu_voice_search@3x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_voice_search.imageset/popup_menu_voice_search@3x.png deleted file mode 100644 index bee2a0f..0000000 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_voice_search.imageset/popup_menu_voice_search@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/promos_manager/BUILD.gn b/ios/chrome/browser/ui/promos_manager/BUILD.gn index adbbef5..f0d8e2b 100644 --- a/ios/chrome/browser/ui/promos_manager/BUILD.gn +++ b/ios/chrome/browser/ui/promos_manager/BUILD.gn
@@ -7,6 +7,7 @@ sources = [ "bannered_promo_view_provider.h", "promo_protocol.h", + "promos_manager_ui_handler.h", "standard_promo_action_handler.h", "standard_promo_alert_handler.h", "standard_promo_alert_provider.h",
diff --git a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.h b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.h index bd62fb88..c330149a 100644 --- a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.h +++ b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.h
@@ -7,8 +7,11 @@ #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" +#import "ios/chrome/browser/ui/promos_manager/promos_manager_ui_handler.h" + // Coordinator for displaying app-wide promos. -@interface PromosManagerCoordinator : ChromeCoordinator +@interface PromosManagerCoordinator : ChromeCoordinator <PromosManagerUIHandler> + @end #endif // IOS_CHROME_BROWSER_UI_PROMOS_MANAGER_PROMOS_MANAGER_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm index 40a2b188..0fbada0 100644 --- a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm +++ b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm
@@ -69,6 +69,9 @@ base::small_map< std::map<promos_manager::Promo, id<StandardPromoAlertProvider>>> _alertProviderPromos; + + // The currently displayed promo, if any. + absl::optional<promos_manager::Promo> current_promo; } // A mediator that observes when it's a good time to display a promo. @@ -118,11 +121,7 @@ #pragma mark - Public - (void)start { - absl::optional<promos_manager::Promo> nextPromoForDisplay = - [self.mediator nextPromoForDisplay]; - - if (nextPromoForDisplay.has_value()) - [self displayPromo:nextPromoForDisplay.value()]; + [self displayPromoIfAvailable]; } - (void)stop { @@ -130,6 +129,15 @@ [self dismissViewControllers]; } +- (void)displayPromoIfAvailable { + absl::optional<promos_manager::Promo> nextPromoForDisplay = + [self.mediator nextPromoForDisplay]; + + if (nextPromoForDisplay.has_value()) { + [self displayPromo:nextPromoForDisplay.value()]; + } +} + - (void)dismissViewControllers { if (self.viewController) { [self.viewController.presentingViewController @@ -144,6 +152,12 @@ completion:nil]; self.banneredViewController = nil; } + + [self promoWasDismissed]; +} + +- (void)promoWasDismissed { + current_promo = absl::nullopt; } - (void)displayPromo:(promos_manager::Promo)promo { @@ -151,6 +165,9 @@ return; } + DCHECK(!current_promo.has_value()); + current_promo = promo; + auto handler_it = _displayHandlerPromos.find(promo); auto provider_it = _viewProviderPromos.find(promo); auto bannered_provider_it = _banneredViewProviderPromos.find(promo); @@ -265,6 +282,8 @@ if ([alertProvider respondsToSelector:@selector (standardPromoAlertDefaultAction)]) [alertProvider standardPromoAlertDefaultAction]; + + [self dismissViewControllers]; }]; UIAlertAction* cancelAction = [UIAlertAction @@ -274,8 +293,8 @@ if ([alertProvider respondsToSelector:@selector (standardPromoAlertCancelAction)]) { [alertProvider standardPromoAlertCancelAction]; - [self dismissViewControllers]; } + [self dismissViewControllers]; }]; [alert addAction:defaultAction];
diff --git a/ios/chrome/browser/ui/promos_manager/promos_manager_ui_handler.h b/ios/chrome/browser/ui/promos_manager/promos_manager_ui_handler.h new file mode 100644 index 0000000..7e7d4e2 --- /dev/null +++ b/ios/chrome/browser/ui/promos_manager/promos_manager_ui_handler.h
@@ -0,0 +1,15 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_PROMOS_MANAGER_PROMOS_MANAGER_UI_HANDLER_H_ +#define IOS_CHROME_BROWSER_UI_PROMOS_MANAGER_PROMOS_MANAGER_UI_HANDLER_H_ + +@protocol PromosManagerUIHandler + +// Alerts that the current promo was dismissed. +- (void)promoWasDismissed; + +@end + +#endif // IOS_CHROME_BROWSER_UI_PROMOS_MANAGER_PROMOS_MANAGER_UI_HANDLER_H_
diff --git a/ios/chrome/browser/ui/reading_list/BUILD.gn b/ios/chrome/browser/ui/reading_list/BUILD.gn index d092eb58..2c2065e 100644 --- a/ios/chrome/browser/ui/reading_list/BUILD.gn +++ b/ios/chrome/browser/ui/reading_list/BUILD.gn
@@ -25,7 +25,6 @@ ] deps = [ ":reading_list_ui", - "resources:distillation_fail_new", "//base", "//components/favicon/core", "//components/feature_engagement", @@ -54,7 +53,6 @@ "//ios/chrome/browser/ui/incognito_reauth:incognito_reauth_scene_agent", "//ios/chrome/browser/ui/main:scene_state_header", "//ios/chrome/browser/ui/menu", - "//ios/chrome/browser/ui/reading_list/resources:distillation_fail_new", "//ios/chrome/browser/ui/sharing", "//ios/chrome/browser/ui/sharing/activity_services", "//ios/chrome/browser/ui/side_swipe", @@ -128,7 +126,6 @@ deps = [ ":reading_list_constants", "resources:reading_list_empty", - "resources:reading_list_empty_state", "//base", "//base:i18n", "//components/prefs",
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_table_view_item.mm b/ios/chrome/browser/ui/reading_list/reading_list_table_view_item.mm index 9c5a33d8..a595171 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_table_view_item.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_table_view_item.mm
@@ -76,10 +76,8 @@ _distillationState = distillationState; switch (_distillationState) { case ReadingListUIDistillationStatusFailure: - self.distillationBadgeImage = - UseSymbols() ? DefaultSymbolTemplateWithPointSize( - kErrorCircleFillSymbol, kSymbolBadgeImagePointSize) - : [UIImage imageNamed:@"distillation_fail_new"]; + self.distillationBadgeImage = DefaultSymbolTemplateWithPointSize( + kErrorCircleFillSymbol, kSymbolBadgeImagePointSize); self.distillationBadgeTintColor = [UIColor colorNamed:kGrey600Color]; break; case ReadingListUIDistillationStatusSuccess: @@ -113,9 +111,7 @@ URLCell.titleLabel.textColor = styler.cellTitleColor; [URLCell.faviconView configureWithAttributes:self.attributes]; URLCell.faviconBadgeView.image = self.distillationBadgeImage; - if (UseSymbols()) { - URLCell.faviconBadgeView.tintColor = self.distillationBadgeTintColor; - } + URLCell.faviconBadgeView.tintColor = self.distillationBadgeTintColor; cell.isAccessibilityElement = YES; cell.accessibilityLabel = GetReadingListCellAccessibilityLabel( self.title, [self hostname], self.distillationState,
diff --git a/ios/chrome/browser/ui/reading_list/resources/BUILD.gn b/ios/chrome/browser/ui/reading_list/resources/BUILD.gn index 0b0fbab..ae6ada1 100644 --- a/ios/chrome/browser/ui/reading_list/resources/BUILD.gn +++ b/ios/chrome/browser/ui/reading_list/resources/BUILD.gn
@@ -4,16 +4,6 @@ import("//build/config/ios/asset_catalog.gni") -imageset("distillation_fail_new") { - sources = [ - "distillation_fail_new.imageset/Contents.json", - "distillation_fail_new.imageset/distillation_fail_new@2x.png", - "distillation_fail_new.imageset/distillation_fail_new@3x.png", - "distillation_fail_new.imageset/distillation_fail_new_dark@2x.png", - "distillation_fail_new.imageset/distillation_fail_new_dark@3x.png", - ] -} - imageset("reading_list_empty") { sources = [ "reading_list_empty.imageset/Contents.json", @@ -21,12 +11,3 @@ "reading_list_empty.imageset/reading_list_empty_dark.pdf", ] } - -imageset("reading_list_empty_state") { - sources = [ - "reading_list_empty_state.imageset/Contents.json", - "reading_list_empty_state.imageset/reading_list_empty_state.png", - "reading_list_empty_state.imageset/reading_list_empty_state@2x.png", - "reading_list_empty_state.imageset/reading_list_empty_state@3x.png", - ] -}
diff --git a/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/Contents.json b/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/Contents.json deleted file mode 100644 index ea33693e..0000000 --- a/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/Contents.json +++ /dev/null
@@ -1,40 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "distillation_fail_new@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "distillation_fail_new_dark@2x.png", - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "distillation_fail_new@3x.png", - "scale" : "3x" - }, - { - "idiom" : "universal", - "filename" : "distillation_fail_new_dark@3x.png", - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -}
diff --git a/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/distillation_fail_new@2x.png b/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/distillation_fail_new@2x.png deleted file mode 100644 index 654dc2f6..0000000 --- a/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/distillation_fail_new@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/distillation_fail_new@3x.png b/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/distillation_fail_new@3x.png deleted file mode 100644 index be6f9427..0000000 --- a/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/distillation_fail_new@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/distillation_fail_new_dark@2x.png b/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/distillation_fail_new_dark@2x.png deleted file mode 100644 index 5297f36b..0000000 --- a/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/distillation_fail_new_dark@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/distillation_fail_new_dark@3x.png b/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/distillation_fail_new_dark@3x.png deleted file mode 100644 index 96c3fe6..0000000 --- a/ios/chrome/browser/ui/reading_list/resources/distillation_fail_new.imageset/distillation_fail_new_dark@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/reading_list/resources/reading_list_empty_state.imageset/Contents.json b/ios/chrome/browser/ui/reading_list/resources/reading_list_empty_state.imageset/Contents.json deleted file mode 100644 index 1a977ad..0000000 --- a/ios/chrome/browser/ui/reading_list/resources/reading_list_empty_state.imageset/Contents.json +++ /dev/null
@@ -1,23 +0,0 @@ -{ - "images": [ - { - "idiom": "universal", - "scale": "1x", - "filename": "reading_list_empty_state.png" - }, - { - "idiom": "universal", - "scale": "2x", - "filename": "reading_list_empty_state@2x.png" - }, - { - "idiom": "universal", - "scale": "3x", - "filename": "reading_list_empty_state@3x.png" - } - ], - "info": { - "version": 1, - "author": "xcode" - } -}
diff --git a/ios/chrome/browser/ui/reading_list/resources/reading_list_empty_state.imageset/reading_list_empty_state.png b/ios/chrome/browser/ui/reading_list/resources/reading_list_empty_state.imageset/reading_list_empty_state.png deleted file mode 100644 index 291570d..0000000 --- a/ios/chrome/browser/ui/reading_list/resources/reading_list_empty_state.imageset/reading_list_empty_state.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/reading_list/resources/reading_list_empty_state.imageset/reading_list_empty_state@2x.png b/ios/chrome/browser/ui/reading_list/resources/reading_list_empty_state.imageset/reading_list_empty_state@2x.png deleted file mode 100644 index f686b5f..0000000 --- a/ios/chrome/browser/ui/reading_list/resources/reading_list_empty_state.imageset/reading_list_empty_state@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/reading_list/resources/reading_list_empty_state.imageset/reading_list_empty_state@3x.png b/ios/chrome/browser/ui/reading_list/resources/reading_list_empty_state.imageset/reading_list_empty_state@3x.png deleted file mode 100644 index 3831f1b..0000000 --- a/ios/chrome/browser/ui/reading_list/resources/reading_list_empty_state.imageset/reading_list_empty_state@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/recent_tabs/BUILD.gn index a6f7737..d88fbaa 100644 --- a/ios/chrome/browser/ui/recent_tabs/BUILD.gn +++ b/ios/chrome/browser/ui/recent_tabs/BUILD.gn
@@ -16,7 +16,6 @@ ] deps = [ ":recent_tabs_ui", - "resources:show_history", "//base", "//components/sessions", "//components/signin/public/identity_manager",
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm index 91d013f..e3877ad 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -373,9 +373,8 @@ [[TableViewImageItem alloc] initWithType:ItemTypeShowFullHistory]; historyItem.title = l10n_util::GetNSString(IDS_HISTORY_SHOWFULLHISTORY_LINK); - historyItem.image = UseSymbols() ? DefaultSymbolWithPointSize( - kHistorySymbol, kSymbolActionPointSize) - : [UIImage imageNamed:@"show_history"]; + historyItem.image = + DefaultSymbolWithPointSize(kHistorySymbol, kSymbolActionPointSize); historyItem.textColor = [UIColor colorNamed:kBlueColor]; historyItem.accessibilityIdentifier = kRecentTabsShowFullHistoryCellAccessibilityIdentifier;
diff --git a/ios/chrome/browser/ui/recent_tabs/resources/BUILD.gn b/ios/chrome/browser/ui/recent_tabs/resources/BUILD.gn index f17888d..e409293 100644 --- a/ios/chrome/browser/ui/recent_tabs/resources/BUILD.gn +++ b/ios/chrome/browser/ui/recent_tabs/resources/BUILD.gn
@@ -11,13 +11,3 @@ "recent_tabs_other_devices_empty.imageset/recent_tabs_other_devices_empty_dark.pdf", ] } - -imageset("show_history") { - sources = [ - "show_history.imageset/Contents.json", - "show_history.imageset/show_history@2x.png", - "show_history.imageset/show_history@3x.png", - "show_history.imageset/show_history_dark@2x.png", - "show_history.imageset/show_history_dark@3x.png", - ] -}
diff --git a/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/Contents.json b/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/Contents.json deleted file mode 100644 index fb5179eb..0000000 --- a/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/Contents.json +++ /dev/null
@@ -1,54 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "scale" : "1x", - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ] - }, - { - "idiom" : "universal", - "filename" : "show_history@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "show_history_dark@2x.png", - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "show_history@3x.png", - "scale" : "3x" - }, - { - "idiom" : "universal", - "filename" : "show_history_dark@3x.png", - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file
diff --git a/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/show_history@2x.png b/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/show_history@2x.png deleted file mode 100644 index 6a9c7512..0000000 --- a/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/show_history@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/show_history@3x.png b/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/show_history@3x.png deleted file mode 100644 index 56321616..0000000 --- a/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/show_history@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/show_history_dark@2x.png b/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/show_history_dark@2x.png deleted file mode 100644 index d6838d5..0000000 --- a/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/show_history_dark@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/show_history_dark@3x.png b/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/show_history_dark@3x.png deleted file mode 100644 index 76c63ed06..0000000 --- a/ios/chrome/browser/ui/recent_tabs/resources/show_history.imageset/show_history_dark@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm index b5205f3f..4cdbe2a01 100644 --- a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm +++ b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
@@ -169,7 +169,8 @@ TableViewImageItem* textImageItem = [[TableViewImageItem alloc] initWithType:ItemTypeTextAccessoryImage]; textImageItem.title = @"Image Item with History Image"; - textImageItem.image = [UIImage imageNamed:@"show_history"]; + textImageItem.image = + DefaultSymbolWithPointSize(kHistorySymbol, kSymbolActionPointSize); [model addItem:textImageItem toSectionWithIdentifier:SectionIdentifierText]; TableViewTabsSearchSuggestedHistoryItem* searchHistorySuggestedItem =
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_layout.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_layout.mm index a8642f9..fa832c5 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_layout.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_layout.mm
@@ -52,4 +52,8 @@ kPinnedCellVerticalLayoutInsets, availableHorizontalLayoutInsets}; } +- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { + return YES; +} + @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.h b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.h index c74bdf5..493e2ae 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.h
@@ -8,7 +8,6 @@ #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" class Browser; -@protocol PopupMenuLongPressDelegate; @protocol TabStripContaining; @class TabStripViewController; @@ -28,9 +27,6 @@ // The TabStrip view owned by the viewcontroller of this coordinator. @property(nonatomic, strong, readonly) UIView<TabStripContaining>* view; -// Delegate for the long press gesture recognizer triggering popup menu. -@property(nonatomic, weak) id<PopupMenuLongPressDelegate> longPressDelegate; - // Hides or shows the tab strip. - (void)hideTabStrip:(BOOL)hidden;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.mm index 76d2552..9063aa6 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.mm
@@ -67,10 +67,6 @@ return self.tabStripViewController; } -- (void)setLongPressDelegate:(id<PopupMenuLongPressDelegate>)longPressDelegate { - _longPressDelegate = longPressDelegate; -} - - (UIView<TabStripContaining>*)view { return static_cast<UIView<TabStripContaining>*>(self.viewController.view); }
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.h b/ios/chrome/browser/ui/tabs/tab_strip_controller.h index 2be9f86..57c2c7e 100644 --- a/ios/chrome/browser/ui/tabs/tab_strip_controller.h +++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.h
@@ -10,7 +10,6 @@ #import "ios/chrome/browser/ui/gestures/view_revealing_animatee.h" #import "ios/chrome/browser/ui/tabs/requirements/tab_strip_constants.h" -@protocol PopupMenuLongPressDelegate; @protocol TabStripContaining; @protocol TabStripPresentation; @class ViewRevealingVerticalPanHandler; @@ -25,9 +24,6 @@ @property(nonatomic, assign) BOOL highlightsSelectedTab; @property(nonatomic, readonly, strong) UIView<TabStripContaining>* view; -// Delegate for the long press gesture recognizer triggering popup menu. -@property(nonatomic, weak) id<PopupMenuLongPressDelegate> longPressDelegate; - // The duration to wait before starting tab strip animations. Used to // synchronize animations. @property(nonatomic, assign) NSTimeInterval animationWaitDuration;
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm index 0139fd22..6379f05 100644 --- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm +++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -50,7 +50,6 @@ #import "ios/chrome/browser/ui/icons/symbols.h" #import "ios/chrome/browser/ui/main/scene_state.h" #import "ios/chrome/browser/ui/main/scene_state_browser_agent.h" -#import "ios/chrome/browser/ui/popup_menu/public/popup_menu_long_press_delegate.h" #import "ios/chrome/browser/ui/tab_switcher/tab_utils.h" #import "ios/chrome/browser/ui/tabs/requirements/tab_strip_constants.h" #import "ios/chrome/browser/ui/tabs/requirements/tab_strip_presentation.h" @@ -466,7 +465,6 @@ @synthesize highlightsSelectedTab = _highlightsSelectedTab; @synthesize tabStripView = _tabStripView; @synthesize view = _view; -@synthesize longPressDelegate = _longPressDelegate; @synthesize presentationProvider = _presentationProvider; @synthesize animationWaitDuration = _animationWaitDuration; @synthesize panGestureHandler = _panGestureHandler;
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h b/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h index c5a6900f..34ed496 100644 --- a/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h +++ b/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h
@@ -11,7 +11,6 @@ #import "ios/chrome/browser/ui/gestures/view_revealing_animatee.h" #import "ios/chrome/browser/ui/tabs/requirements/tab_strip_highlighting.h" -@protocol PopupMenuLongPressDelegate; @protocol TabStripPresentation; @class ViewRevealingVerticalPanHandler; @@ -30,9 +29,6 @@ // TabStripLegacyCoordinator is instantiated before the BrowserViewController. @property(nonatomic, weak, readwrite) UIViewController* baseViewController; -// Delegate for the long press gesture recognizer triggering popup menu. -@property(nonatomic, weak) id<PopupMenuLongPressDelegate> longPressDelegate; - // Provides methods for presenting the tab strip and checking the visibility // of the tab strip in the containing object. @property(nonatomic, weak) id<TabStripPresentation> presentationProvider;
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.mm b/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.mm index 8808ec95..0fed3c8 100644 --- a/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.mm +++ b/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.mm
@@ -21,7 +21,6 @@ @end @implementation TabStripLegacyCoordinator -@synthesize longPressDelegate = _longPressDelegate; @synthesize presentationProvider = _presentationProvider; @synthesize started = _started; @synthesize tabStripController = _tabStripController; @@ -33,11 +32,6 @@ return [super initWithBaseViewController:nil browser:browser]; } -- (void)setLongPressDelegate:(id<PopupMenuLongPressDelegate>)longPressDelegate { - _longPressDelegate = longPressDelegate; - self.tabStripController.longPressDelegate = longPressDelegate; -} - - (UIView<TabStripContaining>*)view { DCHECK(self.started); return [self.tabStripController view]; @@ -88,7 +82,6 @@ style:style]; self.tabStripController.presentationProvider = self.presentationProvider; self.tabStripController.animationWaitDuration = self.animationWaitDuration; - self.tabStripController.longPressDelegate = self.longPressDelegate; [self.presentationProvider showTabStripView:[self.tabStripController view]]; self.started = YES; }
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn index 5f066104..b108472 100644 --- a/ios/chrome/browser/ui/toolbar/BUILD.gn +++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -137,10 +137,7 @@ source_set("unit_tests") { testonly = true - sources = [ - "adaptive_toolbar_view_controller_unittest.mm", - "toolbar_mediator_unittest.mm", - ] + sources = [ "toolbar_mediator_unittest.mm" ] deps = [ ":toolbar", ":toolbar_ui",
diff --git a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_coordinator.h b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_coordinator.h index 94aa574..725897ddf 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_coordinator.h +++ b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_coordinator.h
@@ -13,7 +13,6 @@ @class AdaptiveToolbarViewController; class Browser; -@protocol PopupMenuLongPressDelegate; // Coordinator for the adaptive toolbar. This Coordinator is the super class of // the specific coordinator (primary or secondary). @@ -30,9 +29,6 @@ // The Toolbar view controller owned by this coordinator. @property(nonatomic, strong) AdaptiveToolbarViewController* viewController; -// Delegate for the long press gesture recognizer triggering popup menu. -@property(nonatomic, weak) id<PopupMenuLongPressDelegate> longPressDelegate; - @end #endif // IOS_CHROME_BROWSER_UI_TOOLBAR_ADAPTIVE_TOOLBAR_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_coordinator.mm index f8541616..3b04d7ba 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_coordinator.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_coordinator.mm
@@ -62,7 +62,6 @@ self.started = YES; - self.viewController.longPressDelegate = self.longPressDelegate; self.viewController.overrideUserInterfaceStyle = browser->GetBrowserState()->IsOffTheRecord() ? UIUserInterfaceStyleDark @@ -93,13 +92,6 @@ self.mediator = nil; } -#pragma mark - Properties - -- (void)setLongPressDelegate:(id<PopupMenuLongPressDelegate>)longPressDelegate { - _longPressDelegate = longPressDelegate; - self.viewController.longPressDelegate = longPressDelegate; -} - #pragma mark - SideSwipeToolbarSnapshotProviding - (UIImage*)toolbarSideSwipeSnapshotForWebState:(web::WebState*)webState {
diff --git a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.h b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.h index debeb9a..4f50fcfa 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.h +++ b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.h
@@ -17,7 +17,6 @@ @class LayoutGuideCenter; @protocol OmniboxCommands; @protocol PopupMenuCommands; -@protocol PopupMenuLongPressDelegate; @class ToolbarButton; @class ToolbarButtonFactory; @@ -39,8 +38,6 @@ @property(nonatomic, weak) id<OmniboxCommands> omniboxCommandsHandler; // Popup menu commands handler for the ViewController. @property(nonatomic, weak) id<PopupMenuCommands> popupMenuCommandsHandler; -// Delegate for the long press gesture recognizer triggering popup menu. -@property(nonatomic, weak) id<PopupMenuLongPressDelegate> longPressDelegate; // Provider for the context menus. @property(nonatomic, weak) id<AdaptiveToolbarMenusProvider> menuProvider;
diff --git a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm index 4f34c93..57e80c81 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm
@@ -12,11 +12,9 @@ #import "ios/chrome/browser/shared/public/commands/browser_commands.h" #import "ios/chrome/browser/shared/public/commands/omnibox_commands.h" #import "ios/chrome/browser/shared/ui/util/animation_util.h" -#import "ios/chrome/browser/shared/ui/util/force_touch_long_press_gesture_recognizer.h" #import "ios/chrome/browser/shared/ui/util/layout_guide_names.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h" #import "ios/chrome/browser/ui/icons/symbols.h" -#import "ios/chrome/browser/ui/popup_menu/public/popup_menu_long_press_delegate.h" #import "ios/chrome/browser/ui/toolbar/adaptive_toolbar_menus_provider.h" #import "ios/chrome/browser/ui/toolbar/adaptive_toolbar_view.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_button.h" @@ -56,7 +54,6 @@ @dynamic view; @synthesize buttonFactory = _buttonFactory; -@synthesize longPressDelegate = _longPressDelegate; @synthesize loading = _loading; @synthesize isNTP = _isNTP; @@ -118,22 +115,14 @@ [self addLayoutGuideCenterToButtons]; // Add navigation popup menu triggers. - if (UseSymbols()) { - [self configureMenuProviderForButton:self.view.backButton - buttonType:AdaptiveToolbarButtonTypeBack]; - [self configureMenuProviderForButton:self.view.forwardButton - buttonType:AdaptiveToolbarButtonTypeForward]; - [self configureMenuProviderForButton:self.view.openNewTabButton - buttonType:AdaptiveToolbarButtonTypeNewTab]; - [self configureMenuProviderForButton:self.view.tabGridButton - buttonType:AdaptiveToolbarButtonTypeTabGrid]; - } else { - [self addLongPressGestureToView:self.view.backButton]; - [self addLongPressGestureToView:self.view.forwardButton]; - [self addLongPressGestureToView:self.view.openNewTabButton]; - [self addLongPressGestureToView:self.view.tabGridButton]; - [self addLongPressGestureToView:self.view.toolsMenuButton]; - } + [self configureMenuProviderForButton:self.view.backButton + buttonType:AdaptiveToolbarButtonTypeBack]; + [self configureMenuProviderForButton:self.view.forwardButton + buttonType:AdaptiveToolbarButtonTypeForward]; + [self configureMenuProviderForButton:self.view.openNewTabButton + buttonType:AdaptiveToolbarButtonTypeNewTab]; + [self configureMenuProviderForButton:self.view.tabGridButton + buttonType:AdaptiveToolbarButtonTypeTabGrid]; [self updateLayoutBasedOnTraitCollection]; } @@ -276,30 +265,8 @@ #pragma mark - PopupMenuUIUpdating -- (void)updateUIForIPHDisplayed:(PopupMenuType)popupType { - ToolbarButton* selectedButton = nil; - switch (popupType) { - case PopupMenuTypeNavigationForward: - selectedButton = self.view.forwardButton; - break; - case PopupMenuTypeNavigationBackward: - selectedButton = self.view.backButton; - break; - case PopupMenuTypeNewTab: - selectedButton = self.view.openNewTabButton; - break; - case PopupMenuTypeTabGrid: - selectedButton = self.view.tabGridButton; - break; - case PopupMenuTypeToolsMenu: - selectedButton = self.view.toolsMenuButton; - break; - case PopupMenuTypeTabStripTabGrid: - // ignore - break; - } - - selectedButton.iphHighlighted = YES; +- (void)updateUIForOverflowMenuIPHDisplayed { + self.view.toolsMenuButton.iphHighlighted = YES; } - (void)updateUIForIPHDismissed { @@ -381,41 +348,6 @@ } } -// Adds a LongPressGesture to the `view`, with target on -`handleLongPress:`. -- (void)addLongPressGestureToView:(UIView*)view { - ForceTouchLongPressGestureRecognizer* gestureRecognizer = - [[ForceTouchLongPressGestureRecognizer alloc] - initWithTarget:self - action:@selector(handleGestureRecognizer:)]; - gestureRecognizer.forceThreshold = 0.8; - [view addGestureRecognizer:gestureRecognizer]; -} - -// Handles the gseture recognizer on the views. -- (void)handleGestureRecognizer:(UILongPressGestureRecognizer*)gesture { - if (gesture.state == UIGestureRecognizerStateBegan) { - if (gesture.view == self.view.backButton) { - [self.popupMenuCommandsHandler showNavigationHistoryBackPopupMenu]; - } else if (gesture.view == self.view.forwardButton) { - [self.popupMenuCommandsHandler showNavigationHistoryForwardPopupMenu]; - } else if (gesture.view == self.view.openNewTabButton) { - [self.popupMenuCommandsHandler showNewTabButtonPopup]; - } else if (gesture.view == self.view.tabGridButton) { - [self.popupMenuCommandsHandler showTabGridButtonPopup]; - } else if (gesture.view == self.view.toolsMenuButton) { - base::RecordAction(base::UserMetricsAction("MobileToolbarShowMenu")); - [self.popupMenuCommandsHandler showToolsMenuPopup]; - } - TriggerHapticFeedbackForImpact(UIImpactFeedbackStyleHeavy); - } else if (gesture.state == UIGestureRecognizerStateEnded) { - [self.longPressDelegate - longPressEndedAtPoint:[gesture locationOfTouch:0 inView:nil]]; - } else if (gesture.state == UIGestureRecognizerStateChanged) { - [self.longPressDelegate - longPressFocusPointChangedTo:[gesture locationOfTouch:0 inView:nil]]; - } -} - - (void)updateLayoutBasedOnTraitCollection { [self updateAllButtonsVisibility]; if (IsRegularXRegularSizeClass(self)) {
diff --git a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller_unittest.mm b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller_unittest.mm deleted file mode 100644 index f9c380cd..0000000 --- a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller_unittest.mm +++ /dev/null
@@ -1,131 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.h" - -#import <UIKit/UIGestureRecognizerSubclass.h> - -#import "base/ios/ios_util.h" -#import "base/run_loop.h" -#import "base/test/ios/wait_util.h" -#import "base/test/task_environment.h" -#import "ios/chrome/browser/shared/public/commands/omnibox_commands.h" -#import "ios/chrome/browser/shared/public/commands/popup_menu_commands.h" -#import "ios/chrome/browser/ui/icons/symbols.h" -#import "ios/chrome/browser/ui/popup_menu/public/popup_menu_long_press_delegate.h" -#import "ios/chrome/browser/ui/toolbar/buttons/toolbar_button.h" -#import "ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.h" -#import "ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.h" -#import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" -#import "testing/gtest/include/gtest/gtest.h" -#import "testing/platform_test.h" -#import "third_party/ocmock/OCMock/OCMock.h" -#import "third_party/ocmock/gtest_support.h" -#import "ui/base/device_form_factor.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -UIView* GetTabGridToolbarButton(UIView* parentView) { - if (parentView.accessibilityIdentifier == kToolbarStackButtonIdentifier) - return parentView; - - for (UIView* subview in parentView.subviews) { - UIView* buttonSubview = GetTabGridToolbarButton(subview); - if (buttonSubview) - return buttonSubview; - } - return nil; -} - -class AdaptiveToolbarViewControllerTest : public PlatformTest { - protected: - AdaptiveToolbarViewControllerTest() - : TaskEnvironment_(base::test::TaskEnvironment::MainThreadType::UI) {} - - base::test::TaskEnvironment TaskEnvironment_; -}; - -TEST_F(AdaptiveToolbarViewControllerTest, DetectForceTouch) { - if (UseSymbols()) { - // With SF Symbols, another popup menu is displayed. - return; - } - if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { - // IPad doesn't have force touch. - return; - } - - id omniboxCommandsHandler = OCMProtocolMock(@protocol(OmniboxCommands)); - id popupMenuCommandsHandler = OCMProtocolMock(@protocol(PopupMenuCommands)); - id longPressDelegate = OCMProtocolMock(@protocol(PopupMenuLongPressDelegate)); - ToolbarButtonFactory* factory = - [[ToolbarButtonFactory alloc] initWithStyle:NORMAL]; - - AdaptiveToolbarViewController* toolbar = - [[PrimaryToolbarViewController alloc] init]; - toolbar.buttonFactory = factory; - toolbar.longPressDelegate = longPressDelegate; - toolbar.omniboxCommandsHandler = omniboxCommandsHandler; - toolbar.popupMenuCommandsHandler = popupMenuCommandsHandler; - - UIView* buttonView = GetTabGridToolbarButton(toolbar.view); - - ASSERT_NE(buttonView, nil); - ASSERT_GE(buttonView.gestureRecognizers.count, 1UL); - - UIGestureRecognizer* gestureRecognizer = buttonView.gestureRecognizers[0]; - - id event = OCMClassMock([UIEvent class]); - - CGFloat maximumForce = 1; - CGFloat currentForce = 0.7; - id touch = OCMClassMock([UITouch class]); - OCMStub([touch maximumPossibleForce]).andReturn(maximumForce); - OCMStub([touch force]).andReturn(currentForce); - [gestureRecognizer touchesBegan:[NSSet setWithObject:touch] withEvent:event]; - [gestureRecognizer touchesMoved:[NSSet setWithObject:touch] withEvent:event]; - - // Check that the popupMenuCommandsHandler is called when the force touch is - // detected. - OCMExpect([popupMenuCommandsHandler showTabGridButtonPopup]); - - currentForce = 0.9; - - touch = OCMClassMock([UITouch class]); - OCMStub([touch maximumPossibleForce]).andReturn(maximumForce); - OCMStub([touch force]).andReturn(currentForce); - [gestureRecognizer touchesMoved:[NSSet setWithObject:touch] withEvent:event]; - - base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); - - EXPECT_OCMOCK_VERIFY(popupMenuCommandsHandler); - - // Check that the longPressDelegate is notified when the gesture recognizer - // changes, even with lower force. - [[[longPressDelegate expect] ignoringNonObjectArgs] - longPressFocusPointChangedTo:CGPointZero]; - - touch = OCMClassMock([UITouch class]); - OCMStub([touch maximumPossibleForce]).andReturn(maximumForce); - OCMStub([touch force]).andReturn(currentForce); - [gestureRecognizer touchesMoved:[NSSet setWithObject:touch] withEvent:event]; - - base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); - - EXPECT_OCMOCK_VERIFY(longPressDelegate); - - // Change the state to Ended here, as the long press gesture recognizer isn't - // working on unit test (the state is cancelled). - gestureRecognizer.state = UIGestureRecognizerStateEnded; - - base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05)); - - EXPECT_OCMOCK_VERIFY(longPressDelegate); -} - -} // namespace
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.mm b/ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.mm index 43be2ac4..85d26e2 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.mm +++ b/ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.mm
@@ -83,9 +83,9 @@ #pragma mark - PopupMenuUIUpdating -- (void)updateUIForIPHDisplayed:(PopupMenuType)popupType { +- (void)updateUIForOverflowMenuIPHDisplayed { for (id<ToolbarCoordinatee> coordinator in self.coordinators) { - [coordinator.popupMenuUIUpdater updateUIForIPHDisplayed:popupType]; + [coordinator.popupMenuUIUpdater updateUIForOverflowMenuIPHDisplayed]; } }
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_mediator.mm b/ios/chrome/browser/ui/toolbar/toolbar_mediator.mm index 3fecae5..0cb3b92 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_mediator.mm +++ b/ios/chrome/browser/ui/toolbar/toolbar_mediator.mm
@@ -385,12 +385,7 @@ if (!gfxImage.IsEmpty()) { image = gfxImage.ToUIImage(); } else { - if (UseSymbols()) { - image = - DefaultSymbolWithPointSize(kDocSymbol, kInfobarSymbolPointSize); - } else { - image = [UIImage imageNamed:@"default_favicon"]; - } + image = DefaultSymbolWithPointSize(kDocSymbol, kInfobarSymbolPointSize); } }
diff --git a/ios/chrome/browser/ui/whats_new/BUILD.gn b/ios/chrome/browser/ui/whats_new/BUILD.gn index bab43ce5..9f850cb7 100644 --- a/ios/chrome/browser/ui/whats_new/BUILD.gn +++ b/ios/chrome/browser/ui/whats_new/BUILD.gn
@@ -33,6 +33,7 @@ "//ios/chrome/browser/shared/ui/util", "//ios/chrome/browser/ui/default_promo:utils", "//ios/chrome/browser/ui/elements", + "//ios/chrome/browser/ui/promos_manager:promos", "//ios/chrome/browser/ui/whats_new/cells", "//ios/chrome/browser/ui/whats_new/data_source", "//ios/chrome/browser/url_loading",
diff --git a/ios/chrome/browser/ui/whats_new/whats_new_coordinator.h b/ios/chrome/browser/ui/whats_new/whats_new_coordinator.h index e12f5464..2da4cbb8 100644 --- a/ios/chrome/browser/ui/whats_new/whats_new_coordinator.h +++ b/ios/chrome/browser/ui/whats_new/whats_new_coordinator.h
@@ -8,11 +8,17 @@ #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" #import "ios/chrome/browser/ui/whats_new/whats_new_table_view_delegate.h" +@protocol PromosManagerUIHandler; + @interface WhatsNewCoordinator : ChromeCoordinator <WhatsNewTableViewDelegate> // Whether to show a promo bubble after dismissing What's New. @property(nonatomic, assign) BOOL shouldShowBubblePromoOnDismiss; +// The promos manager ui handler to alert for promo UI changes. Should only be +// set if this coordinator was a promo presented by the PromosManager. +@property(nonatomic, weak) id<PromosManagerUIHandler> promosUIHandler; + @end #endif // IOS_CHROME_BROWSER_UI_WHATS_NEW_WHATS_NEW_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/whats_new/whats_new_coordinator.mm b/ios/chrome/browser/ui/whats_new/whats_new_coordinator.mm index 999528c..e810401 100644 --- a/ios/chrome/browser/ui/whats_new/whats_new_coordinator.mm +++ b/ios/chrome/browser/ui/whats_new/whats_new_coordinator.mm
@@ -12,7 +12,9 @@ #import "ios/chrome/browser/shared/public/commands/application_commands.h" #import "ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" +#import "ios/chrome/browser/shared/public/commands/promos_manager_commands.h" #import "ios/chrome/browser/shared/ui/table_view/table_view_navigation_controller.h" +#import "ios/chrome/browser/ui/promos_manager/promos_manager_ui_handler.h" #import "ios/chrome/browser/ui/whats_new/whats_new_detail_coordinator.h" #import "ios/chrome/browser/ui/whats_new/whats_new_detail_view_controller.h" #import "ios/chrome/browser/ui/whats_new/whats_new_mediator.h" @@ -100,6 +102,8 @@ UmaHistogramMediumTimes("IOS.WhatsNew.TimeSpent", base::TimeTicks::Now() - self.whatsNewStartTime); + [self.promosUIHandler promoWasDismissed]; + if (self.shouldShowBubblePromoOnDismiss) { [self.handler showWhatsNewIPH]; }
diff --git a/ios/chrome/browser/upgrade/BUILD.gn b/ios/chrome/browser/upgrade/BUILD.gn index 94a214030..5b8b6268 100644 --- a/ios/chrome/browser/upgrade/BUILD.gn +++ b/ios/chrome/browser/upgrade/BUILD.gn
@@ -13,7 +13,6 @@ ] deps = [ ":public", - "resources:infobar_update", "//base", "//components/infobars/core", "//components/version_info",
diff --git a/ios/chrome/browser/upgrade/resources/BUILD.gn b/ios/chrome/browser/upgrade/resources/BUILD.gn deleted file mode 100644 index b5765c9..0000000 --- a/ios/chrome/browser/upgrade/resources/BUILD.gn +++ /dev/null
@@ -1,14 +0,0 @@ -# Copyright 2017 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/ios/asset_catalog.gni") - -imageset("infobar_update") { - sources = [ - "infobar_update.imageset/Contents.json", - "infobar_update.imageset/infobar_update.png", - "infobar_update.imageset/infobar_update@2x.png", - "infobar_update.imageset/infobar_update@3x.png", - ] -}
diff --git a/ios/chrome/browser/upgrade/resources/infobar_update.imageset/Contents.json b/ios/chrome/browser/upgrade/resources/infobar_update.imageset/Contents.json deleted file mode 100644 index 0c7057d..0000000 --- a/ios/chrome/browser/upgrade/resources/infobar_update.imageset/Contents.json +++ /dev/null
@@ -1,23 +0,0 @@ -{ - "images": [ - { - "idiom": "universal", - "scale": "1x", - "filename": "infobar_update.png" - }, - { - "idiom": "universal", - "scale": "2x", - "filename": "infobar_update@2x.png" - }, - { - "idiom": "universal", - "scale": "3x", - "filename": "infobar_update@3x.png" - } - ], - "info": { - "version": 1, - "author": "xcode" - } -}
diff --git a/ios/chrome/browser/upgrade/resources/infobar_update.imageset/infobar_update.png b/ios/chrome/browser/upgrade/resources/infobar_update.imageset/infobar_update.png deleted file mode 100644 index 21d508d..0000000 --- a/ios/chrome/browser/upgrade/resources/infobar_update.imageset/infobar_update.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/upgrade/resources/infobar_update.imageset/infobar_update@2x.png b/ios/chrome/browser/upgrade/resources/infobar_update.imageset/infobar_update@2x.png deleted file mode 100644 index a7f7967..0000000 --- a/ios/chrome/browser/upgrade/resources/infobar_update.imageset/infobar_update@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/upgrade/resources/infobar_update.imageset/infobar_update@3x.png b/ios/chrome/browser/upgrade/resources/infobar_update.imageset/infobar_update@3x.png deleted file mode 100644 index b62a76c..0000000 --- a/ios/chrome/browser/upgrade/resources/infobar_update.imageset/infobar_update@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/upgrade/upgrade_center.mm b/ios/chrome/browser/upgrade/upgrade_center.mm index 9fd7a69..f5b5a2e 100644 --- a/ios/chrome/browser/upgrade/upgrade_center.mm +++ b/ios/chrome/browser/upgrade/upgrade_center.mm
@@ -94,10 +94,8 @@ ui::ImageModel GetIcon() const override { if (icon_.IsEmpty()) { - icon_ = gfx::Image(UseSymbols() - ? DefaultSymbolWithPointSize( - kInfoCircleSymbol, kInfobarSymbolPointSize) - : [UIImage imageNamed:@"infobar_update"]); + icon_ = gfx::Image(DefaultSymbolWithPointSize(kInfoCircleSymbol, + kInfobarSymbolPointSize)); } return ui::ImageModel::FromImage(icon_); }
diff --git a/ios/chrome/browser/web/forms_egtest.mm b/ios/chrome/browser/web/forms_egtest.mm index 727dcee..0e053df 100644 --- a/ios/chrome/browser/web/forms_egtest.mm +++ b/ios/chrome/browser/web/forms_egtest.mm
@@ -174,25 +174,6 @@ IDS_HTTP_POST_WARNING_RESEND); } -// Waits for view with Tab History accessibility ID. -- (void)waitForTabHistoryView { - GREYCondition* condition = [GREYCondition - conditionWithName:@"Waiting for Tab History to display." - block:^BOOL { - NSError* error = nil; - id<GREYMatcher> tabHistory = - grey_accessibilityID(kPopupMenuNavigationTableViewId); - [[EarlGrey selectElementWithMatcher:tabHistory] - assertWithMatcher:grey_notNil() - error:&error]; - return error == nil; - }]; - GREYAssert( - [condition waitWithTimeout:base::test::ios::kWaitForUIElementTimeout - .InSecondsF()], - @"Tab History View not displayed."); -} - // Open back navigation history. - (void)openBackHistory { [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] @@ -361,16 +342,10 @@ // internally. It can't be called directly from the EarlGrey 2 test process. NSString* title = base::SysUTF16ToNSString(url_formatter::FormatUrl(destinationURL)); - id<GREYMatcher> historyItem; - - if ([ChromeEarlGrey isSFSymbolEnabled]) { - historyItem = chrome_test_util::ButtonWithAccessibilityLabel(title); - [[EarlGrey selectElementWithMatcher:historyItem] - assertWithMatcher:grey_sufficientlyVisible()]; - } else { - historyItem = grey_text(title); - [self waitForTabHistoryView]; - } + id<GREYMatcher> historyItem = + chrome_test_util::ButtonWithAccessibilityLabel(title); + [[EarlGrey selectElementWithMatcher:historyItem] + assertWithMatcher:grey_sufficientlyVisible()]; [[EarlGrey selectElementWithMatcher:historyItem] performAction:grey_tap()]; [ChromeEarlGrey waitForPageToFinishLoading];
diff --git a/ios/chrome/browser/web/visible_url_egtest.mm b/ios/chrome/browser/web/visible_url_egtest.mm index e2e6b3b..8782f29 100644 --- a/ios/chrome/browser/web/visible_url_egtest.mm +++ b/ios/chrome/browser/web/visible_url_egtest.mm
@@ -46,12 +46,6 @@ const char kPage2Link[] = "page-2"; const char kPage3Link[] = "page-3"; -id<GREYMatcher> ContextMenuMatcherForText(NSString* text) { - return grey_allOf( - grey_ancestor(grey_kindOfClassName(@"PopupMenuNavigationCell")), - grey_text(text), nil); -} - // Response provider which can be paused. When it is paused it buffers all // requests and does not respond to them until `set_paused(false)` is called. class PausableResponseProvider : public HtmlResponseProvider { @@ -234,14 +228,9 @@ [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] performAction:grey_longPress()]; NSString* URL1Title = base::SysUTF8ToNSString(kTestPage1); - if ([ChromeEarlGrey isSFSymbolEnabled]) { - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabel( - URL1Title)] performAction:grey_tap()]; - } else { - [[EarlGrey selectElementWithMatcher:ContextMenuMatcherForText(URL1Title)] - performAction:grey_tap()]; - } + [[EarlGrey + selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabel( + URL1Title)] performAction:grey_tap()]; { // Disables EG synchronization.
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.h b/ios/chrome/test/earl_grey/chrome_earl_grey.h index bd7e865e..5d026c39 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.h
@@ -690,9 +690,6 @@ // Returns whether the Web Channels feature is enabled. - (BOOL)isWebChannelsEnabled; -// Returns whether SF Symbols are used. -- (BOOL)isSFSymbolEnabled; - // Returns whether UIButtonConfiguration changes are enabled. - (BOOL)isUIButtonConfigurationEnabled;
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm index d921509..234f89b 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -1323,10 +1323,6 @@ return [ChromeEarlGreyAppInterface isWebChannelsEnabled]; } -- (BOOL)isSFSymbolEnabled { - return [ChromeEarlGreyAppInterface isSFSymbolEnabled]; -} - - (BOOL)isUIButtonConfigurationEnabled { return [ChromeEarlGreyAppInterface isUIButtonConfigurationEnabled]; }
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h index 088bd4f..a1e2f0d 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h
@@ -545,9 +545,6 @@ // Returns whether the Web Channels feature is enabled. + (BOOL)isWebChannelsEnabled; -// Returns whether SF Symbols are used. -+ (BOOL)isSFSymbolEnabled; - // Returns whether UIButtonConfiguration changes are enabled. + (BOOL)isUIButtonConfigurationEnabled;
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm index 03fc68b..b6be35e 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
@@ -1180,10 +1180,6 @@ return base::FeatureList::IsEnabled(kEnableWebChannels); } -+ (BOOL)isSFSymbolEnabled { - return UseSymbols(); -} - + (BOOL)isUIButtonConfigurationEnabled { return IsUIButtonConfigurationEnabled(); }
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h index d3e11f1..487af90 100644 --- a/media/base/mock_filters.h +++ b/media/base/mock_filters.h
@@ -12,6 +12,7 @@ #include <vector> #include "base/functional/callback.h" +#include "base/memory/weak_ptr.h" #include "base/task/sequenced_task_runner.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" @@ -503,7 +504,8 @@ MOCK_METHOD1(SetWasPlayedWithUserActivation, void(bool)); }; -class MockRenderer : public Renderer { +class MockRenderer : public Renderer, + public base::SupportsWeakPtr<MockRenderer> { public: MockRenderer();
diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc index 4b6e651..cc4023e 100644 --- a/media/base/pipeline_impl_unittest.cc +++ b/media/base/pipeline_impl_unittest.cc
@@ -11,8 +11,8 @@ #include "base/functional/bind.h" #include "base/location.h" -#include "base/memory/raw_ptr.h" #include "base/memory/raw_ptr_exclusion.h" +#include "base/memory/weak_ptr.h" #include "base/run_loop.h" #include "base/task/single_thread_task_runner.h" #include "base/test/gmock_callback_support.h" @@ -105,15 +105,13 @@ }; PipelineImplTest() - : demuxer_(new StrictMock<MockDemuxer>()), - demuxer_host_(nullptr), - scoped_renderer_(new StrictMock<MockRenderer>()), - renderer_(scoped_renderer_.get()), - renderer_client_(nullptr) { + : demuxer_(std::make_unique<StrictMock<MockDemuxer>>()), + scoped_renderer_(std::make_unique<StrictMock<MockRenderer>>()), + renderer_(scoped_renderer_->AsWeakPtr()) { pipeline_ = std::make_unique<PipelineImpl>( task_environment_.GetMainThreadTaskRunner(), task_environment_.GetMainThreadTaskRunner(), - base::BindRepeating(&PipelineImplTest::CreateRenderer, + base::BindRepeating(&PipelineImplTest::TakeRenderer, base::Unretained(this)), &media_log_); @@ -167,9 +165,7 @@ std::unique_ptr<StrictMock<MockDemuxerStream>> CreateStream( DemuxerStream::Type type) { - std::unique_ptr<StrictMock<MockDemuxerStream>> stream( - new StrictMock<MockDemuxerStream>(type)); - return stream; + return std::make_unique<StrictMock<MockDemuxerStream>>(type); } // Sets up expectations to allow the renderer to initialize. @@ -299,7 +295,7 @@ ResetRenderer(); } - std::unique_ptr<Renderer> CreateRenderer( + std::unique_ptr<Renderer> TakeRenderer( absl::optional<RendererType> /* renderer_type */) { return std::move(scoped_renderer_); } @@ -307,7 +303,7 @@ void ResetRenderer() { // |renderer_| has been deleted, replace it. scoped_renderer_ = std::make_unique<StrictMock<MockRenderer>>(); - renderer_ = scoped_renderer_.get(); + renderer_ = scoped_renderer_->AsWeakPtr(); EXPECT_CALL(*renderer_, SetPreservesPitch(_)).Times(AnyNumber()); } @@ -365,15 +361,15 @@ std::unique_ptr<StrictMock<MockDemuxer>> demuxer_; // This field is not a raw_ptr<> because it was filtered by the rewriter for: // #addr-of - RAW_PTR_EXCLUSION DemuxerHost* demuxer_host_; + RAW_PTR_EXCLUSION DemuxerHost* demuxer_host_ = nullptr; std::unique_ptr<StrictMock<MockRenderer>> scoped_renderer_; - raw_ptr<StrictMock<MockRenderer>> renderer_; + base::WeakPtr<MockRenderer> renderer_; std::unique_ptr<StrictMock<MockDemuxerStream>> audio_stream_; std::unique_ptr<StrictMock<MockDemuxerStream>> video_stream_; std::vector<DemuxerStream*> streams_; // This field is not a raw_ptr<> because it was filtered by the rewriter for: // #addr-of - RAW_PTR_EXCLUSION RendererClient* renderer_client_; + RAW_PTR_EXCLUSION RendererClient* renderer_client_ = nullptr; VideoDecoderConfig video_decoder_config_; PipelineMetadata metadata_; base::TimeDelta start_time_;
diff --git a/media/base/video_thumbnail_decoder_unittest.cc b/media/base/video_thumbnail_decoder_unittest.cc index 549c8de..32ecb2a 100644 --- a/media/base/video_thumbnail_decoder_unittest.cc +++ b/media/base/video_thumbnail_decoder_unittest.cc
@@ -76,8 +76,9 @@ base::test::TaskEnvironment task_environment_; - raw_ptr<MockVideoDecoder> mock_video_decoder_; + // Must outlive `mock_video_decoder_`. std::unique_ptr<VideoThumbnailDecoder> thumbnail_decoder_; + raw_ptr<MockVideoDecoder> mock_video_decoder_; // The video frame returned from the thumbnail decoder. scoped_refptr<VideoFrame> frame_;
diff --git a/net/data/ssl/certificates/crlset_blocked_interception_by_intermediate.raw b/net/data/ssl/certificates/crlset_blocked_interception_by_intermediate.raw index f420225..5bac40adb 100644 --- a/net/data/ssl/certificates/crlset_blocked_interception_by_intermediate.raw +++ b/net/data/ssl/certificates/crlset_blocked_interception_by_intermediate.raw Binary files differ
diff --git a/net/data/ssl/certificates/crlset_blocked_interception_by_root.raw b/net/data/ssl/certificates/crlset_blocked_interception_by_root.raw index e202d84..457c750 100644 --- a/net/data/ssl/certificates/crlset_blocked_interception_by_root.raw +++ b/net/data/ssl/certificates/crlset_blocked_interception_by_root.raw Binary files differ
diff --git a/net/data/ssl/certificates/crlset_by_intermediate_serial.raw b/net/data/ssl/certificates/crlset_by_intermediate_serial.raw index 6afcf602..852f28f7 100644 --- a/net/data/ssl/certificates/crlset_by_intermediate_serial.raw +++ b/net/data/ssl/certificates/crlset_by_intermediate_serial.raw Binary files differ
diff --git a/net/data/ssl/certificates/crlset_by_leaf_spki.raw b/net/data/ssl/certificates/crlset_by_leaf_spki.raw index a1b2f59..2d072ff 100644 --- a/net/data/ssl/certificates/crlset_by_leaf_spki.raw +++ b/net/data/ssl/certificates/crlset_by_leaf_spki.raw Binary files differ
diff --git a/net/data/ssl/certificates/crlset_by_leaf_subject_no_spki.raw b/net/data/ssl/certificates/crlset_by_leaf_subject_no_spki.raw index de7a00f..7fcdc37 100644 --- a/net/data/ssl/certificates/crlset_by_leaf_subject_no_spki.raw +++ b/net/data/ssl/certificates/crlset_by_leaf_subject_no_spki.raw Binary files differ
diff --git a/net/data/ssl/certificates/crlset_by_root_serial.raw b/net/data/ssl/certificates/crlset_by_root_serial.raw index 3195847..c530e915 100644 --- a/net/data/ssl/certificates/crlset_by_root_serial.raw +++ b/net/data/ssl/certificates/crlset_by_root_serial.raw Binary files differ
diff --git a/net/data/ssl/certificates/crlset_by_root_spki.raw b/net/data/ssl/certificates/crlset_by_root_spki.raw index a0b50e75..2cf8934 100644 --- a/net/data/ssl/certificates/crlset_by_root_spki.raw +++ b/net/data/ssl/certificates/crlset_by_root_spki.raw Binary files differ
diff --git a/net/data/ssl/certificates/crlset_by_root_subject.raw b/net/data/ssl/certificates/crlset_by_root_subject.raw index 2b76310..dff3162 100644 --- a/net/data/ssl/certificates/crlset_by_root_subject.raw +++ b/net/data/ssl/certificates/crlset_by_root_subject.raw
@@ -1 +1 @@ -{"Version": 0, "ContentType": "CRLSet", "Sequence": 0, "NumParents": 0, "BlockedSPKIs": [], "LimitedSubjects": {"APZW1IJHguCRuMrfLCm88fpiNaGl562lAbs3i6JTQA0=": ["VypP3VWL7OaqTJ7mIBehWYlv8khPuFHpWiearZI2YjI="]}, "KnownInterceptionSPKIs": [], "BlockedInterceptionSPKIs": []} \ No newline at end of file +{"Version": 0, "ContentType": "CRLSet", "Sequence": 1, "NumParents": 0, "BlockedSPKIs": [], "LimitedSubjects": {"APZW1IJHguCRuMrfLCm88fpiNaGl562lAbs3i6JTQA0=": ["VypP3VWL7OaqTJ7mIBehWYlv8khPuFHpWiearZI2YjI="]}, "KnownInterceptionSPKIs": [], "BlockedInterceptionSPKIs": []} \ No newline at end of file
diff --git a/net/data/ssl/certificates/crlset_by_root_subject_no_spki.raw b/net/data/ssl/certificates/crlset_by_root_subject_no_spki.raw index c0e5814..85d6399 100644 --- a/net/data/ssl/certificates/crlset_by_root_subject_no_spki.raw +++ b/net/data/ssl/certificates/crlset_by_root_subject_no_spki.raw Binary files differ
diff --git a/net/data/ssl/certificates/crlset_known_interception_by_root.raw b/net/data/ssl/certificates/crlset_known_interception_by_root.raw index 5a6e03d3..f2a12d058 100644 --- a/net/data/ssl/certificates/crlset_known_interception_by_root.raw +++ b/net/data/ssl/certificates/crlset_known_interception_by_root.raw Binary files differ
diff --git a/net/data/ssl/scripts/crlsetutil.py b/net/data/ssl/scripts/crlsetutil.py index 19e3e08..6cbb512 100755 --- a/net/data/ssl/scripts/crlsetutil.py +++ b/net/data/ssl/scripts/crlsetutil.py
@@ -20,7 +20,7 @@ with the key will be restricted to the set of SPKIs extracted from the files in the values. - Sequence: An optional integer sequence number to use for the CRLSet. If - not present, defaults to 0. + not present, defaults to 1. For example: @@ -288,7 +288,7 @@ header_json = { 'Version': 0, 'ContentType': 'CRLSet', - 'Sequence': int(config.get("Sequence", 0)), + 'Sequence': int(config.get("Sequence", 1)), 'NumParents': len(parents), 'BlockedSPKIs': blocked_spkis, 'LimitedSubjects': limited_subjects,
diff --git a/net/data/ssl/scripts/generate-test-certs.sh b/net/data/ssl/scripts/generate-test-certs.sh index ac4bb58..797f5bf 100755 --- a/net/data/ssl/scripts/generate-test-certs.sh +++ b/net/data/ssl/scripts/generate-test-certs.sh
@@ -678,7 +678,7 @@ "LimitedSubjects": { "../certificates/root_ca_cert.pem": [] }, - "Sequence": 1 + "Sequence": 2 } CRLSETBYROOTSUBJECTNOSPKI
diff --git a/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcImpl.java b/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcImpl.java index ff96c050..4cbd0170 100644 --- a/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcImpl.java +++ b/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcImpl.java
@@ -542,7 +542,7 @@ Log.w(TAG, "Cannot write data to NFC tag. Tag is lost: " + e.getMessage()); pendingPushOperationCompleted(createError(NdefErrorType.IO_ERROR, "Failed to write because the tag is lost: " + e.getMessage())); - } catch (FormatException | IllegalStateException | IOException e) { + } catch (FormatException | IllegalStateException | IOException | SecurityException e) { Log.w(TAG, "Cannot write data to NFC tag: " + e.getMessage()); pendingPushOperationCompleted(createError(NdefErrorType.IO_ERROR, "Failed to write due to an IO error: " + e.getMessage())); @@ -594,7 +594,7 @@ Log.w(TAG, "Cannot make NFC tag read-only. Tag is lost: " + e.getMessage()); pendingMakeReadOnlyOperationCompleted(createError(NdefErrorType.IO_ERROR, "Failed to make read-only because the tag is lost: " + e.getMessage())); - } catch (IOException e) { + } catch (IOException | SecurityException e) { Log.w(TAG, "Cannot make NFC tag read-only: " + e.getMessage()); pendingMakeReadOnlyOperationCompleted(createError(NdefErrorType.IO_ERROR, "Failed to make read-only due to an IO error: " + e.getMessage())); @@ -638,7 +638,7 @@ Log.w(TAG, "Cannot read data from NFC tag. Tag is lost: " + e.getMessage()); notifyErrorToAllWatchers(createError(NdefErrorType.IO_ERROR, "Failed to read because the tag is lost: " + e.getMessage())); - } catch (FormatException | IllegalStateException | IOException e) { + } catch (FormatException | IllegalStateException | IOException | SecurityException e) { Log.w(TAG, "Cannot read data from NFC tag. IO_ERROR: " + e.getMessage()); notifyErrorToAllWatchers(createError(NdefErrorType.IO_ERROR, "Failed to read due to an IO error: " + e.getMessage()));
diff --git a/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcTagHandler.java b/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcTagHandler.java index 4aef8b23..1a7e72d 100644 --- a/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcTagHandler.java +++ b/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcTagHandler.java
@@ -169,7 +169,7 @@ /** * Connects to NFC tag. */ - public void connect() throws IOException, TagLostException { + public void connect() throws IOException, SecurityException, TagLostException { if (!mTech.isConnected()) { mTech.connect(); mWasConnected = true; @@ -217,7 +217,7 @@ public boolean isTagOutOfRange() { try { connect(); - } catch (IOException e) { + } catch (IOException | SecurityException e) { return mWasConnected; } return false;
diff --git a/testing/buildbot/OWNERS b/testing/buildbot/OWNERS index 2280c941..397c57c 100644 --- a/testing/buildbot/OWNERS +++ b/testing/buildbot/OWNERS
@@ -49,11 +49,11 @@ per-file chromium.mac.json=file://infra/config/groups/ios/OWNERS # Fuchsia owners. -per-file chromium.clang.json=chonggu@google.com -per-file chromium.fuchsia.fyi.json=chonggu@google.com -per-file chromium.fuchsia.json=chonggu@google.com -per-file chromium.fyi.json=chonggu@google.com -per-file chromium.perf.fyi.json=chonggu@google.com +per-file chromium.clang.json=file://build/fuchsia/test/OWNERS +per-file chromium.fuchsia.fyi.json=file://build/fuchsia/test/OWNERS +per-file chromium.fuchsia.json=file://build/fuchsia/test/OWNERS +per-file chromium.fyi.json=file://build/fuchsia/test/OWNERS +per-file chromium.perf.fyi.json=file://build/fuchsia/test/OWNERS # Rust owners per-file chromium.rust.json=file://build/rust/OWNERS
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 20d2b68..9b9e7bd 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5886,9 +5886,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "isolate_profile_data": true, "merge": { "args": [], @@ -5900,8 +5900,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [ @@ -6057,9 +6057,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "isolate_profile_data": true, "merge": { "args": [], @@ -6071,8 +6071,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [ @@ -6209,9 +6209,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "isolate_profile_data": true, "merge": { "args": [], @@ -6223,8 +6223,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index 33b3f7b..55c5d64 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -25631,9 +25631,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "isolate_profile_data": true, "merge": { "args": [], @@ -25645,8 +25645,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [ @@ -25802,9 +25802,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "isolate_profile_data": true, "merge": { "args": [], @@ -25816,8 +25816,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [ @@ -25954,9 +25954,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "isolate_profile_data": true, "merge": { "args": [], @@ -25968,8 +25968,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 78e4cb9..9c7680d 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -50174,9 +50174,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -50187,8 +50187,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [ @@ -50345,9 +50345,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -50358,8 +50358,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [ @@ -50497,9 +50497,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -50510,8 +50510,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [ @@ -52017,9 +52017,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -52030,8 +52030,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [ @@ -52188,9 +52188,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -52201,8 +52201,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [ @@ -52340,9 +52340,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -52353,8 +52353,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [ @@ -53108,9 +53108,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -53121,8 +53121,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index de6f0e7..0ae1fc0 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -18414,12 +18414,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "isolate_profile_data": true, "merge": { "args": [], @@ -18431,8 +18431,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [ @@ -18605,12 +18605,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "isolate_profile_data": true, "merge": { "args": [], @@ -18622,8 +18622,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [ @@ -18772,12 +18772,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 113.0.5670.0", + "description": "Run with ash-chrome version 113.0.5671.0", "isolate_profile_data": true, "merge": { "args": [], @@ -18789,8 +18789,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v113.0.5670.0", - "revision": "version:113.0.5670.0" + "location": "lacros_version_skew_tests_v113.0.5671.0", + "revision": "version:113.0.5671.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 658ed0c3..0778a21 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -22,16 +22,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5670.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v113.0.5671.0/test_ash_chrome', ], - 'description': 'Run with ash-chrome version 113.0.5670.0', + 'description': 'Run with ash-chrome version 113.0.5671.0', 'identifier': 'Lacros version skew testing ash canary', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v113.0.5670.0', - 'revision': 'version:113.0.5670.0', + 'location': 'lacros_version_skew_tests_v113.0.5671.0', + 'revision': 'version:113.0.5671.0', }, ], },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 310a581..50f85b4 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -8294,7 +8294,11 @@ "experiments": [ { "name": "AndroidExperiments", - "params": {}, + "params": { + "RepeatableQueriesIgnoreDuplicateVisits": "true", + "RepeatableQueriesMaxAgeDays": "7", + "RepeatableQueriesMinVisitCount": "12" + }, "enable_features": [ "AndroidAuxiliarySearch", "NewTabPageTilesTitleWrapAround",
diff --git a/third_party/android_deps/additional_readme_paths.json b/third_party/android_deps/additional_readme_paths.json index 5cc9ca7..b908059 100644 --- a/third_party/android_deps/additional_readme_paths.json +++ b/third_party/android_deps/additional_readme_paths.json
@@ -125,7 +125,8 @@ "libs/net_bytebuddy_byte_buddy_agent", "libs/net_bytebuddy_byte_buddy_android", "libs/net_ltgt_gradle_incap_incap", - "libs/org_bouncycastle_bcprov_jdk15on", + "libs/net_sf_kxml_kxml2", + "libs/org_bouncycastle_bcprov_jdk18on", "libs/org_ccil_cowan_tagsoup_tagsoup", "libs/org_checkerframework_checker_compat_qual", "libs/org_checkerframework_checker_qual", @@ -154,6 +155,7 @@ "libs/org_robolectric_annotations", "libs/org_robolectric_junit", "libs/org_robolectric_nativeruntime", + "libs/org_robolectric_nativeruntime_dist_compat", "libs/org_robolectric_pluginapi", "libs/org_robolectric_plugins_maven_dependency_resolver", "libs/org_robolectric_resources",
diff --git a/third_party/android_deps/build.gradle b/third_party/android_deps/build.gradle index b92e3eeb..cbffa2da 100644 --- a/third_party/android_deps/build.gradle +++ b/third_party/android_deps/build.gradle
@@ -192,7 +192,7 @@ // Depended on by downstream guava_java rewrite. androidTestCompile "org.checkerframework:checker-qual:3.25.0" - String robolectricVersion = '4.8.1' + String robolectricVersion = '4.10-alpha-1' // Use testCompile to avoid having support_android = true set on // robolectric dependencies. testCompile "org.robolectric:robolectric:${robolectricVersion}"
diff --git a/third_party/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy b/third_party/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy index 655b39483..e081851 100644 --- a/third_party/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy +++ b/third_party/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy
@@ -116,6 +116,11 @@ url: 'https://github.com/bcgit/bc-java', licensePath: 'licenses/Bouncy_Castle-2015.txt', licenseName: 'MIT'), + org_bouncycastle_bcprov_jdk18on: new PropertyOverride( + cpePrefix: 'cpe:/a:bouncycastle:legion-of-the-bouncy-castle:1.68', + url: 'https://github.com/bcgit/bc-java', + licensePath: 'licenses/Bouncy_Castle-2015.txt', + licenseName: 'MIT'), org_codehaus_mojo_animal_sniffer_annotations: new PropertyOverride( url: 'http://www.mojohaus.org/animal-sniffer/animal-sniffer-annotations/', description: 'Animal Sniffer Annotations allow marking methods which Animal Sniffer should ignore ' + @@ -157,6 +162,10 @@ url: 'https://github.com/raphw/byte-buddy', licenseUrl: 'https://raw.githubusercontent.com/raphw/byte-buddy/master/LICENSE', licenseName: 'Apache 2.0'), + net_sf_kxml_kxml2: new PropertyOverride( + url: 'https://github.com/kobjects/kxml2', + licenseUrl: 'https://raw.githubusercontent.com/kobjects/kxml2/master/license.txt', + licenseName: 'The MIT License'), org_checkerframework_checker_compat_qual: new PropertyOverride( licenseUrl: 'https://raw.githubusercontent.com/typetools/checker-framework/master/LICENSE.txt', licenseName: 'GPL v2 with the classpath exception'), @@ -219,6 +228,9 @@ org_robolectric_nativeruntime: new PropertyOverride( licensePath: 'licenses/Codehaus_License-2009.txt', licenseName: 'MIT'), + org_robolectric_nativeruntime_dist_compat: new PropertyOverride( + licensePath: 'licenses/Codehaus_License-2009.txt', + licenseName: 'MIT'), org_robolectric_pluginapi: new PropertyOverride( licensePath: 'licenses/Codehaus_License-2009.txt', licenseName: 'MIT'),
diff --git a/third_party/android_deps/libs/net_sf_kxml_kxml2/3pp/3pp.pb b/third_party/android_deps/libs/net_sf_kxml_kxml2/3pp/3pp.pb new file mode 100644 index 0000000..d743b51b --- /dev/null +++ b/third_party/android_deps/libs/net_sf_kxml_kxml2/3pp/3pp.pb
@@ -0,0 +1,16 @@ +# Copyright 2021 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. + +create { + source { + script { name: "fetch.py" } + } +} + +upload { + pkg_prefix: "chromium/third_party/android_deps/libs" + universal: true +}
diff --git a/third_party/android_deps/libs/net_sf_kxml_kxml2/3pp/fetch.py b/third_party/android_deps/libs/net_sf_kxml_kxml2/3pp/fetch.py new file mode 100755 index 0000000..13a251b --- /dev/null +++ b/third_party/android_deps/libs/net_sf_kxml_kxml2/3pp/fetch.py
@@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +# Copyright 2021 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This is generated, do not edit. Update BuildConfigGenerator.groovy and +# 3ppFetch.template instead. + +import argparse +import json +import os +import re +import urllib.request + +_REPO_URL = 'https://repo.maven.apache.org/maven2' +_GROUP_NAME = 'net/sf/kxml' +_MODULE_NAME = 'kxml2' +_FILE_EXT = 'jar' +_OVERRIDE_LATEST = None +_PATCH_VERSION = 'cr1' + + +def do_latest(): + if _OVERRIDE_LATEST is not None: + print(_OVERRIDE_LATEST + f'.{_PATCH_VERSION}') + return + maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( + _REPO_URL, _GROUP_NAME, _MODULE_NAME) + metadata = urllib.request.urlopen(maven_metadata_url).read().decode( + 'utf-8') + # Do not parse xml with the python included parser since it is susceptible + # to maliciously crafted xmls. Only use regular expression parsing to be + # safe. RE should be enough to handle what we need to extract. + match = re.search('<latest>([^<]+)</latest>', metadata) + if match: + latest = match.group(1) + else: + # if no latest info was found just hope the versions are sorted and the + # last one is the latest (as is commonly the case). + latest = re.findall('<version>([^<]+)</version>', metadata)[-1] + print(latest + f'.{_PATCH_VERSION}') + + +def get_download_url(version): + # Remove the patch version when getting the download url + version_no_patch, patch = version.rsplit('.', 1) + if patch.startswith('cr'): + version = version_no_patch + file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, + _MODULE_NAME, version, + _FILE_EXT) + file_name = file_url.rsplit('/', 1)[-1] + + partial_manifest = { + 'url': [file_url], + 'name': [file_name], + 'ext': '.' + _FILE_EXT, + } + print(json.dumps(partial_manifest)) + + +def main(): + ap = argparse.ArgumentParser() + sub = ap.add_subparsers() + + latest = sub.add_parser('latest') + latest.set_defaults(func=lambda _opts: do_latest()) + + download = sub.add_parser('get_url') + download.set_defaults( + func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) + + opts = ap.parse_args() + opts.func(opts) + + +if __name__ == '__main__': + main()
diff --git a/third_party/android_deps/libs/net_sf_kxml_kxml2/LICENSE b/third_party/android_deps/libs/net_sf_kxml_kxml2/LICENSE new file mode 100644 index 0000000..089de5c --- /dev/null +++ b/third_party/android_deps/libs/net_sf_kxml_kxml2/LICENSE
@@ -0,0 +1,20 @@ +Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + \ No newline at end of file
diff --git a/third_party/android_deps/libs/net_sf_kxml_kxml2/OWNERS b/third_party/android_deps/libs/net_sf_kxml_kxml2/OWNERS new file mode 100644 index 0000000..aea47a05 --- /dev/null +++ b/third_party/android_deps/libs/net_sf_kxml_kxml2/OWNERS
@@ -0,0 +1 @@ +file://third_party/android_deps/OWNERS
diff --git a/third_party/android_deps/libs/net_sf_kxml_kxml2/README.chromium b/third_party/android_deps/libs/net_sf_kxml_kxml2/README.chromium new file mode 100644 index 0000000..a11e608 --- /dev/null +++ b/third_party/android_deps/libs/net_sf_kxml_kxml2/README.chromium
@@ -0,0 +1,14 @@ +Name: kXML 2 is a small XML pull parser based on the common XML pull API +Short Name: kxml2 +URL: https://github.com/kobjects/kxml2 +Version: 2.3.0 +License: The MIT License +License File: NOT_SHIPPED +CPEPrefix: unknown +Security Critical: no + +Description: +kXML is a small XML pull parser, specially designed for constrained environments such as Applets, Personal Java or MIDP devices. In contrast to kXML 1, kXML 2 is based on the common XML pull API. + +Local Modifications: +No modifications.
diff --git a/third_party/android_deps/libs/net_sf_kxml_kxml2/cipd.yaml b/third_party/android_deps/libs/net_sf_kxml_kxml2/cipd.yaml new file mode 100644 index 0000000..6926f880 --- /dev/null +++ b/third_party/android_deps/libs/net_sf_kxml_kxml2/cipd.yaml
@@ -0,0 +1,10 @@ +# Copyright 2018 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# To create CIPD package run the following command. +# cipd create --pkg-def cipd.yaml -tag version:2@2.3.0.cr1 +package: chromium/third_party/android_deps/libs/net_sf_kxml_kxml2 +description: "kXML 2 is a small XML pull parser based on the common XML pull API" +data: +- file: kxml2-2.3.0.jar
diff --git a/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/3pp/3pp.pb b/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/3pp/3pp.pb new file mode 100644 index 0000000..d743b51b --- /dev/null +++ b/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/3pp/3pp.pb
@@ -0,0 +1,16 @@ +# Copyright 2021 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. + +create { + source { + script { name: "fetch.py" } + } +} + +upload { + pkg_prefix: "chromium/third_party/android_deps/libs" + universal: true +}
diff --git a/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/3pp/fetch.py b/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/3pp/fetch.py new file mode 100755 index 0000000..7122ad6 --- /dev/null +++ b/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/3pp/fetch.py
@@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +# Copyright 2021 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This is generated, do not edit. Update BuildConfigGenerator.groovy and +# 3ppFetch.template instead. + +import argparse +import json +import os +import re +import urllib.request + +_REPO_URL = 'https://repo.maven.apache.org/maven2' +_GROUP_NAME = 'org/bouncycastle' +_MODULE_NAME = 'bcprov-jdk18on' +_FILE_EXT = 'jar' +_OVERRIDE_LATEST = None +_PATCH_VERSION = 'cr1' + + +def do_latest(): + if _OVERRIDE_LATEST is not None: + print(_OVERRIDE_LATEST + f'.{_PATCH_VERSION}') + return + maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( + _REPO_URL, _GROUP_NAME, _MODULE_NAME) + metadata = urllib.request.urlopen(maven_metadata_url).read().decode( + 'utf-8') + # Do not parse xml with the python included parser since it is susceptible + # to maliciously crafted xmls. Only use regular expression parsing to be + # safe. RE should be enough to handle what we need to extract. + match = re.search('<latest>([^<]+)</latest>', metadata) + if match: + latest = match.group(1) + else: + # if no latest info was found just hope the versions are sorted and the + # last one is the latest (as is commonly the case). + latest = re.findall('<version>([^<]+)</version>', metadata)[-1] + print(latest + f'.{_PATCH_VERSION}') + + +def get_download_url(version): + # Remove the patch version when getting the download url + version_no_patch, patch = version.rsplit('.', 1) + if patch.startswith('cr'): + version = version_no_patch + file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, + _MODULE_NAME, version, + _FILE_EXT) + file_name = file_url.rsplit('/', 1)[-1] + + partial_manifest = { + 'url': [file_url], + 'name': [file_name], + 'ext': '.' + _FILE_EXT, + } + print(json.dumps(partial_manifest)) + + +def main(): + ap = argparse.ArgumentParser() + sub = ap.add_subparsers() + + latest = sub.add_parser('latest') + latest.set_defaults(func=lambda _opts: do_latest()) + + download = sub.add_parser('get_url') + download.set_defaults( + func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) + + opts = ap.parse_args() + opts.func(opts) + + +if __name__ == '__main__': + main()
diff --git a/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/LICENSE b/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/LICENSE new file mode 100644 index 0000000..77ec4fa --- /dev/null +++ b/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/LICENSE
@@ -0,0 +1,7 @@ +Copyright (c) 2000 - 2015 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/OWNERS b/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/OWNERS new file mode 100644 index 0000000..aea47a05 --- /dev/null +++ b/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/OWNERS
@@ -0,0 +1 @@ +file://third_party/android_deps/OWNERS
diff --git a/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/README.chromium b/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/README.chromium new file mode 100644 index 0000000..950956171 --- /dev/null +++ b/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/README.chromium
@@ -0,0 +1,14 @@ +Name: Bouncy Castle Provider +Short Name: bcprov-jdk18on +URL: https://github.com/bcgit/bc-java +Version: 1.72 +License: MIT +License File: NOT_SHIPPED +CPEPrefix: cpe:/a:bouncycastle:legion-of-the-bouncy-castle:1.68 +Security Critical: no + +Description: +The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for JDK 1.8 and up. + +Local Modifications: +No modifications.
diff --git a/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/cipd.yaml b/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/cipd.yaml new file mode 100644 index 0000000..7051504 --- /dev/null +++ b/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on/cipd.yaml
@@ -0,0 +1,10 @@ +# Copyright 2018 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# To create CIPD package run the following command. +# cipd create --pkg-def cipd.yaml -tag version:2@1.72.cr1 +package: chromium/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on +description: "Bouncy Castle Provider" +data: +- file: bcprov-jdk18on-1.72.jar
diff --git a/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/3pp/3pp.pb b/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/3pp/3pp.pb new file mode 100644 index 0000000..d743b51b --- /dev/null +++ b/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/3pp/3pp.pb
@@ -0,0 +1,16 @@ +# Copyright 2021 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. + +create { + source { + script { name: "fetch.py" } + } +} + +upload { + pkg_prefix: "chromium/third_party/android_deps/libs" + universal: true +}
diff --git a/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/3pp/fetch.py new file mode 100755 index 0000000..8ee89de --- /dev/null +++ b/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/3pp/fetch.py
@@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +# Copyright 2021 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This is generated, do not edit. Update BuildConfigGenerator.groovy and +# 3ppFetch.template instead. + +import argparse +import json +import os +import re +import urllib.request + +_REPO_URL = 'https://repo.maven.apache.org/maven2' +_GROUP_NAME = 'org/robolectric' +_MODULE_NAME = 'nativeruntime-dist-compat' +_FILE_EXT = 'jar' +_OVERRIDE_LATEST = None +_PATCH_VERSION = 'cr1' + + +def do_latest(): + if _OVERRIDE_LATEST is not None: + print(_OVERRIDE_LATEST + f'.{_PATCH_VERSION}') + return + maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( + _REPO_URL, _GROUP_NAME, _MODULE_NAME) + metadata = urllib.request.urlopen(maven_metadata_url).read().decode( + 'utf-8') + # Do not parse xml with the python included parser since it is susceptible + # to maliciously crafted xmls. Only use regular expression parsing to be + # safe. RE should be enough to handle what we need to extract. + match = re.search('<latest>([^<]+)</latest>', metadata) + if match: + latest = match.group(1) + else: + # if no latest info was found just hope the versions are sorted and the + # last one is the latest (as is commonly the case). + latest = re.findall('<version>([^<]+)</version>', metadata)[-1] + print(latest + f'.{_PATCH_VERSION}') + + +def get_download_url(version): + # Remove the patch version when getting the download url + version_no_patch, patch = version.rsplit('.', 1) + if patch.startswith('cr'): + version = version_no_patch + file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, + _MODULE_NAME, version, + _FILE_EXT) + file_name = file_url.rsplit('/', 1)[-1] + + partial_manifest = { + 'url': [file_url], + 'name': [file_name], + 'ext': '.' + _FILE_EXT, + } + print(json.dumps(partial_manifest)) + + +def main(): + ap = argparse.ArgumentParser() + sub = ap.add_subparsers() + + latest = sub.add_parser('latest') + latest.set_defaults(func=lambda _opts: do_latest()) + + download = sub.add_parser('get_url') + download.set_defaults( + func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) + + opts = ap.parse_args() + opts.func(opts) + + +if __name__ == '__main__': + main()
diff --git a/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/LICENSE b/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/LICENSE new file mode 100644 index 0000000..370fb55 --- /dev/null +++ b/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/LICENSE
@@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2009 codehaus.org. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE.
diff --git a/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/OWNERS b/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/OWNERS new file mode 100644 index 0000000..aea47a05 --- /dev/null +++ b/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/OWNERS
@@ -0,0 +1 @@ +file://third_party/android_deps/OWNERS
diff --git a/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/README.chromium b/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/README.chromium new file mode 100644 index 0000000..eff6693b --- /dev/null +++ b/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/README.chromium
@@ -0,0 +1,14 @@ +Name: Robolectric nativeruntime distribution compat +Short Name: nativeruntime-dist-compat +URL: https://robolectric.org +Version: 1.0.0 +License: MIT +License File: NOT_SHIPPED +CPEPrefix: unknown +Security Critical: no + +Description: +Robolectric nativeruntime distribution compat + +Local Modifications: +No modifications.
diff --git a/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/cipd.yaml b/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/cipd.yaml new file mode 100644 index 0000000..72d3ef6 --- /dev/null +++ b/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat/cipd.yaml
@@ -0,0 +1,10 @@ +# Copyright 2018 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# To create CIPD package run the following command. +# cipd create --pkg-def cipd.yaml -tag version:2@1.0.0.cr1 +package: chromium/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat +description: "Robolectric nativeruntime distribution compat" +data: +- file: nativeruntime-dist-compat-1.0.0.jar
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom index dd59d74..df19a8b7 100644 --- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom +++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -3860,6 +3860,9 @@ kV8StorageBucketManager_Delete_Method = 4519, kNavigatorUAData_GetHighEntropyValues = 4520, kSchedulerYield = 4521, + kHtmlClipboardApiUnsanitizedRead = 4522, + kHtmlClipboardApiUnsanitizedWrite = 4523, + kAsyncClipboardAPIUnsanitizedRead = 4524, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index 5660593..e0901c8 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -249,6 +249,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_query_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_permission_descriptor.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_permission_descriptor.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_unsanitized_formats.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_unsanitized_formats.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_close_event_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_close_event_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_collected_client_data.cc",
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index 12c9c7ef..4a04f382c 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -4034,13 +4034,7 @@ } } -#if BUILDFLAG(IS_IOS) -// TODO(crbug.com/1141478) -#define MAYBE_VideoControlsReject DISABLED_VideoControlsReject -#else -#define MAYBE_VideoControlsReject VideoControlsReject -#endif // BUILDFLAG(IS_IOS) -TEST_F(StyleEngineTest, MAYBE_VideoControlsReject) { +TEST_F(StyleEngineTest, VideoControlsReject) { GetDocument().body()->setInnerHTML(R"HTML( <video controls></video> <div id="target"></div>
diff --git a/third_party/blink/renderer/core/frame/use_counter_impl_test.cc b/third_party/blink/renderer/core/frame/use_counter_impl_test.cc index 5cc12f23..0405b2b0 100644 --- a/third_party/blink/renderer/core/frame/use_counter_impl_test.cc +++ b/third_party/blink/renderer/core/frame/use_counter_impl_test.cc
@@ -131,16 +131,10 @@ "http://foo.com", "https://bar.com")); -#if BUILDFLAG(IS_IOS) -// TODO(crbug.com/1141478) -#define MAYBE_ReportOnlyHTTPFamily DISABLED_ReportOnlyHTTPFamily -#else -#define MAYBE_ReportOnlyHTTPFamily ReportOnlyHTTPFamily -#endif // BUILDFLAG(IS_IOS) // UseCounter should not send events to browser when handling page with // Non HTTP Family URLs, as these events will be discarded on the browser side // in |MetricsWebContentsObserver::DoesTimingUpdateHaveError|. -TEST_P(UseCounterImplBrowserReportTest, MAYBE_ReportOnlyHTTPFamily) { +TEST_P(UseCounterImplBrowserReportTest, ReportOnlyHTTPFamily) { KURL url = url_test_helpers::ToKURL(GetParam()); SetURL(url); UseCounterImpl use_counter;
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc index 960b8cb..bf411044 100644 --- a/third_party/blink/renderer/core/frame/web_frame_test.cc +++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -10531,15 +10531,7 @@ frame_test_helpers::PumpPendingRequestsForFrameToLoad(local_frame); } -#if BUILDFLAG(IS_IOS) -// TODO(crbug.com/1141478) -#define MAYBE_SiteForCookiesFromChildWithRemoteMainFrame \ - DISABLED_SiteForCookiesFromChildWithRemoteMainFrame -#else -#define MAYBE_SiteForCookiesFromChildWithRemoteMainFrame \ - SiteForCookiesFromChildWithRemoteMainFrame -#endif // BUILDFLAG(IS_IOS) -TEST_F(WebFrameTest, MAYBE_SiteForCookiesFromChildWithRemoteMainFrame) { +TEST_F(WebFrameTest, SiteForCookiesFromChildWithRemoteMainFrame) { frame_test_helpers::WebViewHelper helper; helper.InitializeRemote(SecurityOrigin::Create(ToKURL(not_base_url_)));
diff --git a/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc b/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc index 8b23304..2bd12736 100644 --- a/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc +++ b/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc
@@ -179,7 +179,7 @@ } } -#if (BUILDFLAG(IS_ANDROID) && defined(ADDRESS_SANITIZER)) || BUILDFLAG(IS_IOS) +#if (BUILDFLAG(IS_ANDROID) && defined(ADDRESS_SANITIZER)) // https://crbug.com/1189511 #define MAYBE_SaveDataEnabledBasic DISABLED_SaveDataEnabledBasic #else
diff --git a/third_party/blink/renderer/core/layout/build.gni b/third_party/blink/renderer/core/layout/build.gni index fe38bf9..e7c98bd 100644 --- a/third_party/blink/renderer/core/layout/build.gni +++ b/third_party/blink/renderer/core/layout/build.gni
@@ -373,6 +373,7 @@ "ng/grid/ng_grid_placement.h", "ng/grid/ng_grid_sizing_tree.cc", "ng/grid/ng_grid_sizing_tree.h", + "ng/grid/ng_grid_subtree.h", "ng/grid/ng_grid_track_collection.cc", "ng/grid/ng_grid_track_collection.h", "ng/inline/empty_offset_mapping_builder.h",
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_data.h b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_data.h index c0af402..afa6a27 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_data.h +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_data.h
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_line_resolver.h" +#include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_subtree.h" #include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -178,57 +179,42 @@ }; // Subgrid layout relies on the root grid to perform the track sizing algorithm -// for every level of nested subgrids. This class is a collection of finalized -// layout data of every grid/subgrid in the entire grid tree, which will be +// for every level of nested subgrids. This class contains the finalized layout +// data of every node in a grid tree (see `ng_grid_subtree.h`), which will be // passed down to the constraint space of a subgrid to perform layout. // -// The tree is represented by two vectors satisfying the following conditions: -// - The nodes in the tree are indexed using preorder traversal. -// - Each subtree is guaranteed to be contained in a single contiguous range. -// - We can iterate over a node's children by skipping over their subtrees; -// i.e., the first child of a node `k` is always at position `k+1`, the next -// sibling comes `subtree_size_[k+1]` positions later, and so on. -// -// (0) -// / \ -// (1) (7) -// / \ / \ -// (2) (5) (8) (9) -// / \ \ -// (3) (4) (6) (0) -// (1) (7) -// (2) (5) (8)(9) -// (3)(4) (6) -// subtree_size_ = [10, 6, 3, 1, 1, 2, 1, 3, 1, 1] -// // Note that this class allows subtrees to be compared for equality; this is // important because when we store this tree within a constraint space we want // to be able to invalidate the cached layout result of a subgrid based on // whether the provided subtree's track were sized exactly the same. class NGGridLayoutTree : public RefCounted<NGGridLayoutTree> { public: - explicit NGGridLayoutTree(wtf_size_t size = 1) { - subtree_size_.ReserveInitialCapacity(size); - layout_data_.ReserveInitialCapacity(size); + struct GridTreeNode { + NGGridLayoutData layout_data; + wtf_size_t subtree_size; + }; + + explicit NGGridLayoutTree(wtf_size_t initial_capacity) { + tree_data_.ReserveInitialCapacity(initial_capacity); + } + + void Append(const NGGridLayoutData& layout_data, wtf_size_t subtree_size) { + GridTreeNode grid_node_data{layout_data, subtree_size}; + tree_data_.emplace_back(std::move(grid_node_data)); } bool AreSubtreesEqual(wtf_size_t subtree_root, const NGGridLayoutTree& other, wtf_size_t other_subtree_root) const { - DCHECK_LT(other_subtree_root, other.subtree_size_.size()); - DCHECK_LT(subtree_root, subtree_size_.size()); + const wtf_size_t subtree_size = SubtreeSize(subtree_root); - const wtf_size_t subtree_size = subtree_size_[subtree_root]; - if (subtree_size != other.subtree_size_[other_subtree_root]) { + if (subtree_size != other.SubtreeSize(other_subtree_root)) { return false; } - DCHECK_LE(other_subtree_root + subtree_size, other.layout_data_.size()); - DCHECK_LE(subtree_root + subtree_size, layout_data_.size()); - for (wtf_size_t i = 0; i < subtree_size; ++i) { - if (other.layout_data_[other_subtree_root + i] != - layout_data_[subtree_root + i]) { + if (other.LayoutData(other_subtree_root + i) != + LayoutData(subtree_root + i)) { return false; } } @@ -236,58 +222,27 @@ } const NGGridLayoutData& LayoutData(wtf_size_t index) const { - DCHECK_LT(index, layout_data_.size()); - return layout_data_[index]; + DCHECK_LT(index, tree_data_.size()); + return tree_data_[index].layout_data; } - wtf_size_t Size() const { - DCHECK_EQ(layout_data_.size(), subtree_size_.size()); - return layout_data_.size(); - } + wtf_size_t Size() const { return tree_data_.size(); } wtf_size_t SubtreeSize(wtf_size_t index) const { - DCHECK_LT(index, subtree_size_.size()); - return subtree_size_[index]; - } - - void Append(const NGGridLayoutData& layout_data, wtf_size_t subtree_size) { - subtree_size_.emplace_back(subtree_size); - layout_data_.emplace_back(layout_data); + DCHECK_LT(index, tree_data_.size()); + return tree_data_[index].subtree_size; } private: - // Holds the finalized layout data of each grid in the tree. - Vector<NGGridLayoutData, 16> layout_data_; - - // The size of the subtree rooted at each grid node. For a given index `k`, - // this means that the range [k, k + subtree_size_[k]) in both vectors - // represent the data of the subtree rooted at grid node `k`. - Vector<wtf_size_t, 16> subtree_size_; + Vector<GridTreeNode, 16> tree_data_; }; // This class represents a subtree in a `NGGridLayoutTree` and mostly serves two // purposes: provide seamless iteration over the tree structure and compare // input subtrees to invalidate a subgrid's cached layout result. -// -// A subtree is represented by a pointer to the original layout tree's data (see -// `NGGridLayoutTree` description) and the index of the subtree's root. However, -// in order to iterate over the siblings of a given subtree we need to store the -// index of the next sibling of its parent, aka the parent's end index, so that -// the iterator doesn't traverse outside of the parent's subtree, e.g.: -// -// (0) -// (1) (7) -// (2) (5) (8)(9) -// (3)(4) (6) -// layout_tree_.subtree_size_ = [10, 6, 3, 1, 1, 2, 1, 3, 1, 1] -// -// We can compute the next sibling of a subtree rooted at index 2 by adding the -// subtree size at that index (2 + 3 = 5). On the other hand, when we want to -// compute the next sibling for the subtree at index 5, adding the subtree size -// (5 + 2) it's equal to its parent's next sibling (aka parent's end index), so -// we can determine that such subtree doesn't have a next sibling. - -class NGGridLayoutSubtree { +class NGGridLayoutSubtree + : public NGGridSubtree<NGGridLayoutSubtree, + scoped_refptr<const NGGridLayoutTree>> { DISALLOW_NEW(); public: @@ -295,73 +250,31 @@ explicit NGGridLayoutSubtree( scoped_refptr<const NGGridLayoutTree>&& layout_tree) - : layout_tree_(std::move(layout_tree)), subtree_root_(0) { - DCHECK(layout_tree_); - parent_end_index_ = layout_tree_->Size(); - } + : NGGridSubtree(std::move(layout_tree)) {} - NGGridLayoutSubtree(const scoped_refptr<const NGGridLayoutTree>& layout_tree, - wtf_size_t parent_end_index, - wtf_size_t subtree_root) { - DCHECK(layout_tree); - DCHECK_LE(parent_end_index, layout_tree->Size()); - DCHECK_LE(subtree_root, parent_end_index); - - // If the subtree root is beyond the parent's end index, we will keep this - // instance as a null subtree to indicate the end iterator for siblings. - if (subtree_root < parent_end_index) { - layout_tree_ = layout_tree; - parent_end_index_ = parent_end_index; - subtree_root_ = subtree_root; - } - } - - explicit operator bool() const { return static_cast<bool>(layout_tree_); } + NGGridLayoutSubtree(wtf_size_t parent_end_index, + wtf_size_t subtree_root, + const scoped_refptr<const NGGridLayoutTree>& layout_tree) + : NGGridSubtree(parent_end_index, subtree_root, layout_tree) {} // This method is meant to be used for layout invalidation, so we only care // about comparing the layout data of both subtrees. bool operator==(const NGGridLayoutSubtree& other) const { - return (layout_tree_ && other.layout_tree_) - ? layout_tree_->AreSubtreesEqual( - subtree_root_, *other.layout_tree_, other.subtree_root_) - : !layout_tree_ && !other.layout_tree_; - } - - // First child is always at `subtree_root_ + 1` (see `NGGridLayoutTree`). - NGGridLayoutSubtree FirstChild() const { - return NGGridLayoutSubtree(layout_tree_, - /* parent_end_index */ NextSiblingIndex(), - /* subtree_root */ subtree_root_ + 1); - } - - NGGridLayoutSubtree NextSibling() const { - return NGGridLayoutSubtree(layout_tree_, - /* parent_end_index */ parent_end_index_, - /* subtree_root */ NextSiblingIndex()); + return (grid_tree_ && other.grid_tree_) + ? grid_tree_->AreSubtreesEqual(subtree_root_, *other.grid_tree_, + other.subtree_root_) + : !grid_tree_ && !other.grid_tree_; } const NGGridLayoutData& LayoutData() const { - DCHECK(layout_tree_); - return layout_tree_->LayoutData(subtree_root_); + DCHECK(grid_tree_); + return grid_tree_->LayoutData(subtree_root_); } - - private: - wtf_size_t NextSiblingIndex() const { - DCHECK(layout_tree_); - return subtree_root_ + layout_tree_->SubtreeSize(subtree_root_); - } - - // Pointer to the layout tree data shared by multiple subtree instances. - scoped_refptr<const NGGridLayoutTree> layout_tree_; - - // Index of the next sibling of this subtree's parent; used to avoid iterating - // outside of the parent's subtree when computing this subtree's next sibling. - wtf_size_t parent_end_index_{kNotFound}; - - // Index of this subtree's root node. - wtf_size_t subtree_root_{kNotFound}; }; } // namespace blink +WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS( + blink::NGGridLayoutTree::GridTreeNode) + #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_DATA_H_
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_subtree.h b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_subtree.h new file mode 100644 index 0000000..85a824e5 --- /dev/null +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_subtree.h
@@ -0,0 +1,101 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_SUBTREE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_SUBTREE_H_ + +#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" + +namespace blink { + +// A grid tree is represented by a vector satisfying the following conditions: +// - The nodes in the tree are indexed using preorder traversal. +// - Each position in the vector represents a grid node in the tree and it +// stores the size of the subtree rooted at that node. +// - Each subtree is guaranteed to be contained in a single contiguous range; +// i.e., for a given index `k`, the range [k, k + subtree_size[k]) in the +// vector represents the data of the subtree rooted at grid node `k`. +// - We can iterate over a node's children by skipping over their subtrees; +// i.e., the first child of a node `k` is always at position `k+1`, the next +// sibling comes `subtree_size[k+1]` positions later, and so on. +// +// (0) +// / \ +// (1) (7) +// / \ / \ +// (2) (5) (8) (9) +// / \ \ +// (3) (4) (6) (0) +// (1) (7) +// (2) (5) (8)(9) +// (3)(4) (6) +// subtree_size = [10, 6, 3, 1, 1, 2, 1, 3, 1, 1] +// +// A subtree is represented by a pointer to the entire grid tree and the index +// of the subtree's root. In order to iterate over the siblings of a subtree we +// need to store the index of the next sibling of its parent, aka the parent's +// end index, so that we don't traverse outside of the parent's subtree. +// +// In the example above, we can compute the next sibling of a subtree rooted at +// index 2 by adding its subtree size (2 + 3 = 5). However, when we compute the +// next sibling for the subtree at index 5, by adding its subtree size (5 + 2) +// it's equal to its parent's next sibling (aka parent's end index), so we can +// determine that such subtree doesn't have a next sibling. +template <typename SubtreeType, typename GridTreePtr> +class NGGridSubtree { + public: + explicit operator bool() const { return static_cast<bool>(grid_tree_); } + + SubtreeType FirstChild() const { + return SubtreeType(/* parent_end_index */ NextSiblingIndex(), + /* subtree_root */ subtree_root_ + 1, grid_tree_); + } + + SubtreeType NextSibling() const { + return SubtreeType(/* parent_end_index */ parent_end_index_, + /* subtree_root */ NextSiblingIndex(), grid_tree_); + } + + protected: + NGGridSubtree() = default; + + NGGridSubtree(GridTreePtr grid_tree) + : grid_tree_(std::move(grid_tree)), subtree_root_(0) { + DCHECK(grid_tree_); + parent_end_index_ = grid_tree_->Size(); + } + + NGGridSubtree(wtf_size_t parent_end_index, + wtf_size_t subtree_root, + GridTreePtr grid_tree) { + DCHECK_LE(subtree_root, parent_end_index); + + // If the subtree root is beyond the parent's end index, we will keep this + // instance as a null subtree to indicate the end iterator for siblings. + if (subtree_root < parent_end_index) { + grid_tree_ = std::move(grid_tree); + parent_end_index_ = parent_end_index; + subtree_root_ = subtree_root; + } + } + + // Pointer to the tree shared by multiple subtree instances. + GridTreePtr grid_tree_{nullptr}; + + // Index of this subtree's root node. + wtf_size_t subtree_root_{kNotFound}; + + private: + wtf_size_t NextSiblingIndex() const { + return subtree_root_ + grid_tree_->SubtreeSize(subtree_root_); + } + + // Index of the next sibling of this subtree's parent; used to avoid iterating + // outside of the parent's subtree when computing this subtree's next sibling. + wtf_size_t parent_end_index_{kNotFound}; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_SUBTREE_H_
diff --git a/third_party/blink/renderer/core/page/create_window.cc b/third_party/blink/renderer/core/page/create_window.cc index 40e87ca..894a712 100644 --- a/third_party/blink/renderer/core/page/create_window.cc +++ b/third_party/blink/renderer/core/page/create_window.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/page/create_window.h" +#include "base/check.h" #include "base/check_op.h" #include "base/feature_list.h" #include "services/metrics/public/cpp/ukm_builders.h" @@ -89,6 +90,7 @@ PopupState popup_state = PopupState::kUnknown; unsigned key_begin, key_end; unsigned value_begin, value_end; + String attributionsrc; const String buffer = feature_string.LowerASCII(); const unsigned length = buffer.length(); @@ -219,28 +221,30 @@ // attributionsrc values are encoded in order to support embedded special // characters, such as '='. - const String decoded = DecodeURLEscapeSequences( + attributionsrc = DecodeURLEscapeSequences( original_case_value_string.ToString(), DecodeURLMode::kUTF8); + } + } - if (!decoded.empty()) { - window_features.impression = - dom_window->GetFrame() - ->GetAttributionSrcLoader() - ->RegisterNavigation( - dom_window->CompleteURL(decoded), - mojom::blink::AttributionNavigationType::kWindowOpen); - } + if (!attributionsrc.IsNull()) { + DCHECK(attribution_reporting_enabled); - // If the impression could not be set, or if the value was empty, mark - // attribution eligibility by adding an impression. - if (!window_features.impression && - dom_window->GetFrame()->GetAttributionSrcLoader()->CanRegister( - url, - /*element=*/nullptr, - /*request_id=*/absl::nullopt)) { - window_features.impression = blink::Impression{ - .nav_type = mojom::blink::AttributionNavigationType::kWindowOpen}; - } + if (!attributionsrc.empty()) { + window_features.impression = + dom_window->GetFrame()->GetAttributionSrcLoader()->RegisterNavigation( + dom_window->CompleteURL(attributionsrc), + mojom::blink::AttributionNavigationType::kWindowOpen); + } + + // If the impression could not be set, or if the value was empty, mark + // attribution eligibility by adding an impression. + if (!window_features.impression && + dom_window->GetFrame()->GetAttributionSrcLoader()->CanRegister( + url, + /*element=*/nullptr, + /*request_id=*/absl::nullopt)) { + window_features.impression = blink::Impression{ + .nav_type = mojom::blink::AttributionNavigationType::kWindowOpen}; } }
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard.cc b/third_party/blink/renderer/modules/clipboard/clipboard.cc index 84647aa3..a76c5ff 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard.cc
@@ -28,8 +28,10 @@ Clipboard::Clipboard(Navigator& navigator) : Supplement<Navigator>(navigator) {} -ScriptPromise Clipboard::read(ScriptState* script_state) { - return ClipboardPromise::CreateForRead(GetExecutionContext(), script_state); +ScriptPromise Clipboard::read(ScriptState* script_state, + ClipboardUnsanitizedFormats* formats) { + return ClipboardPromise::CreateForRead(GetExecutionContext(), script_state, + formats); } ScriptPromise Clipboard::readText(ScriptState* script_state) {
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard.h b/third_party/blink/renderer/modules/clipboard/clipboard.h index 158f2aa..8a12ce3 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard.h +++ b/third_party/blink/renderer/modules/clipboard/clipboard.h
@@ -15,6 +15,7 @@ class Navigator; class ScriptState; +class ClipboardUnsanitizedFormats; class Clipboard : public EventTargetWithInlineData, public Supplement<Navigator> { @@ -28,7 +29,8 @@ Clipboard(const Clipboard&) = delete; Clipboard& operator=(const Clipboard&) = delete; - ScriptPromise read(ScriptState*); + ScriptPromise read(ScriptState*, + ClipboardUnsanitizedFormats* formats = nullptr); ScriptPromise readText(ScriptState*); ScriptPromise write(ScriptState*, const HeapVector<Member<ClipboardItem>>&);
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard.idl b/third_party/blink/renderer/modules/clipboard/clipboard.idl index 4d9f72c..4bda310 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard.idl +++ b/third_party/blink/renderer/modules/clipboard/clipboard.idl
@@ -4,6 +4,11 @@ // https://w3c.github.io/clipboard-apis/#clipboard-interface +[RuntimeEnabled=ClipboardUnsanitizedContent] +dictionary ClipboardUnsanitizedFormats { + sequence<DOMString> unsanitized; +}; + [ SecureContext, Exposed=Window @@ -12,6 +17,11 @@ CallWith=ScriptState ] Promise<sequence<ClipboardItem>> read(); + [MeasureAs=AsyncClipboardAPIUnsanitizedRead, + RuntimeEnabled=ClipboardUnsanitizedContent, + CallWith=ScriptState + ] Promise<sequence<ClipboardItem>> read(ClipboardUnsanitizedFormats formats); + [MeasureAs=AsyncClipboardAPIReadText, CallWith=ScriptState ] Promise<DOMString> readText();
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc index 131b13db..92b72c5 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -15,6 +15,7 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_clipboard_unsanitized_formats.h" #include "third_party/blink/renderer/core/clipboard/clipboard_mime_types.h" #include "third_party/blink/renderer/core/clipboard/system_clipboard.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -114,15 +115,18 @@ }; // static -ScriptPromise ClipboardPromise::CreateForRead(ExecutionContext* context, - ScriptState* script_state) { +ScriptPromise ClipboardPromise::CreateForRead( + ExecutionContext* context, + ScriptState* script_state, + ClipboardUnsanitizedFormats* formats) { if (!script_state->ContextIsValid()) return ScriptPromise(); ClipboardPromise* clipboard_promise = MakeGarbageCollected<ClipboardPromise>(context, script_state); clipboard_promise->GetTaskRunner()->PostTask( FROM_HERE, WTF::BindOnce(&ClipboardPromise::HandleRead, - WrapPersistent(clipboard_promise))); + WrapPersistent(clipboard_promise), + WrapPersistent(formats))); return clipboard_promise->script_promise_resolver_->Promise(); } @@ -231,8 +235,30 @@ clipboard_item_data_[clipboard_representation_index_].first + ".")); } -void ClipboardPromise::HandleRead() { +void ClipboardPromise::HandleRead(ClipboardUnsanitizedFormats* formats) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (RuntimeEnabledFeatures::ClipboardUnsanitizedContentEnabled() && formats && + formats->hasUnsanitized() && !formats->unsanitized().empty()) { + Vector<String> unsanitized_formats = formats->unsanitized(); + if (unsanitized_formats.size() > 1) { + script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNotAllowedError, + "Support to read multiple unsanitized formats is not implemented.")); + return; + } + if (unsanitized_formats[0] != kMimeTypeTextHTML) { + script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNotAllowedError, "The unsanitized type " + + unsanitized_formats[0] + + " is not supported.")); + return; + } + // HTML is the only standard format that can have an unsanitized read for + // now. + will_read_unsanitized_html_ = true; + } + RequestPermission(mojom::blink::PermissionName::CLIPBOARD_READ, /*will_be_sanitized=*/ !RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled(), @@ -383,7 +409,8 @@ ClipboardReader* clipboard_reader = ClipboardReader::Create( GetLocalFrame()->GetSystemClipboard(), - clipboard_item_data_[clipboard_representation_index_].first, this); + clipboard_item_data_[clipboard_representation_index_].first, this, + /*sanitize_html=*/!will_read_unsanitized_html_); if (!clipboard_reader) { OnRead(nullptr); return;
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h index f013ef9..43c6d542 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h +++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
@@ -27,12 +27,15 @@ class LocalFrame; class ExecutionContext; class ClipboardItemOptions; +class ClipboardUnsanitizedFormats; class ClipboardPromise final : public GarbageCollected<ClipboardPromise>, public ExecutionContextLifecycleObserver { public: // Creates promise to execute Clipboard API functions off the main thread. - static ScriptPromise CreateForRead(ExecutionContext*, ScriptState*); + static ScriptPromise CreateForRead(ExecutionContext*, + ScriptState*, + ClipboardUnsanitizedFormats*); static ScriptPromise CreateForReadText(ExecutionContext*, ScriptState*); static ScriptPromise CreateForWrite(ExecutionContext*, ScriptState*, @@ -69,7 +72,7 @@ void WriteNextRepresentation(); // Checks Read/Write permission (interacting with PermissionService). - void HandleRead(); + void HandleRead(ClipboardUnsanitizedFormats*); void HandleReadText(); void HandleWrite(HeapVector<Member<ClipboardItem>>*); void HandleWriteText(const String&); @@ -104,6 +107,9 @@ // Checks for Read and Write permission. HeapMojoRemote<mojom::blink::PermissionService> permission_service_; + // Indicates whether unsanitized HTML content will be read from the clipboard. + bool will_read_unsanitized_html_ = false; + // Only for use in writeText(). String plain_text_; HeapVector<std::pair<String, Member<Blob>>> clipboard_item_data_;
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc b/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc index 88e9cb5..bbdc530 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
@@ -127,15 +127,18 @@ class ClipboardHtmlReader final : public ClipboardReader { public: explicit ClipboardHtmlReader(SystemClipboard* system_clipboard, - ClipboardPromise* promise) - : ClipboardReader(system_clipboard, promise) {} + ClipboardPromise* promise, + bool sanitize_html) + : ClipboardReader(system_clipboard, promise), + sanitize_html_(sanitize_html) {} ~ClipboardHtmlReader() override = default; void Read() override { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); promise_->GetExecutionContext()->CountUse( - WebFeature::kHtmlClipboardApiRead); + sanitize_html_ ? WebFeature::kHtmlClipboardApiRead + : WebFeature::kHtmlClipboardApiUnsanitizedRead); system_clipboard()->ReadHTML( WTF::BindOnce(&ClipboardHtmlReader::OnRead, WrapPersistent(this))); } @@ -153,21 +156,31 @@ return; } - // Now sanitize the HTML string. - // This must be called on the main thread because HTML DOM nodes can - // only be used on the main thread. - String sanitized_html = CreateSanitizedMarkupWithContext( - *frame->GetDocument(), html_string, fragment_start, fragment_end, url, - kIncludeNode, kResolveAllURLs); - - if (sanitized_html.empty()) { + String serialized_html; + if (sanitize_html_) { + // Sanitize the HTML string. + // This must be called on the main thread because HTML DOM nodes can only + // be used on the main thread. + serialized_html = CreateSanitizedMarkupWithContext( + *frame->GetDocument(), html_string, fragment_start, fragment_end, url, + kIncludeNode, kResolveAllURLs); + } else { + // Similarly to reading sanitized HTML from the clipboard, we need to + // extract the fragment using the `fragment_start` and `fragment_end` + // calculated by the browser process. The browser process already removes + // the CF_HTML headers, but we have to go through this removal step in + // Blink because the markup isn't going through a sanitization process. + serialized_html = + html_string.Substring(fragment_start, fragment_end - fragment_start); + } + if (serialized_html.empty()) { NextRead(Vector<uint8_t>()); return; } worker_pool::PostTask( FROM_HERE, CrossThreadBindOnce( &ClipboardHtmlReader::EncodeOnBackgroundThread, - std::move(sanitized_html), MakeCrossThreadHandle(this), + std::move(serialized_html), MakeCrossThreadHandle(this), std::move(clipboard_task_runner_))); } @@ -199,6 +212,8 @@ } promise_->OnRead(blob); } + + bool sanitize_html_ = true; }; // Reads SVG from the System Clipboard as a Blob with image/svg+xml content. @@ -313,7 +328,8 @@ // static ClipboardReader* ClipboardReader::Create(SystemClipboard* system_clipboard, const String& mime_type, - ClipboardPromise* promise) { + ClipboardPromise* promise, + bool sanitize_html) { DCHECK(ClipboardWriter::IsValidType(mime_type)); // If this is a web custom format then read the unsanitized version. if (RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() && @@ -325,14 +341,18 @@ system_clipboard, promise, mime_type); } - if (mime_type == kMimeTypeImagePng) + if (mime_type == kMimeTypeImagePng) { return MakeGarbageCollected<ClipboardPngReader>(system_clipboard, promise); + } - if (mime_type == kMimeTypeTextPlain) + if (mime_type == kMimeTypeTextPlain) { return MakeGarbageCollected<ClipboardTextReader>(system_clipboard, promise); + } - if (mime_type == kMimeTypeTextHTML) - return MakeGarbageCollected<ClipboardHtmlReader>(system_clipboard, promise); + if (mime_type == kMimeTypeTextHTML) { + return MakeGarbageCollected<ClipboardHtmlReader>(system_clipboard, promise, + sanitize_html); + } if (mime_type == kMimeTypeImageSvg && RuntimeEnabledFeatures::ClipboardSvgEnabled()) {
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_reader.h b/third_party/blink/renderer/modules/clipboard/clipboard_reader.h index 6c7a4030..f3e3ee0 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_reader.h +++ b/third_party/blink/renderer/modules/clipboard/clipboard_reader.h
@@ -44,7 +44,8 @@ // ClipboardWriter::IsValidType() must return true for `mime_type`. static ClipboardReader* Create(SystemClipboard* system_clipboard, const String& mime_type, - ClipboardPromise* promise); + ClipboardPromise* promise, + bool sanitize_html); virtual ~ClipboardReader(); // Reads from the system clipboard and encodes on a background thread.
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc index 50f980d..480455bc 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
@@ -161,7 +161,10 @@ if (!local_frame || !execution_context) { return; } - execution_context->CountUse(WebFeature::kHtmlClipboardApiWrite); + execution_context->CountUse( + RuntimeEnabledFeatures::ClipboardUnsanitizedContentEnabled() + ? WebFeature::kHtmlClipboardApiUnsanitizedWrite + : WebFeature::kHtmlClipboardApiWrite); String html_string = String::FromUTF8(reinterpret_cast<const LChar*>(html_data->Data()),
diff --git a/third_party/blink/renderer/modules/webcodecs/background_readback.cc b/third_party/blink/renderer/modules/webcodecs/background_readback.cc index 657b8399..e5a712f 100644 --- a/third_party/blink/renderer/modules/webcodecs/background_readback.cc +++ b/third_party/blink/renderer/modules/webcodecs/background_readback.cc
@@ -51,13 +51,6 @@ return nullptr; } -// Controls how asyc VideoFrame.copyTo() works -// Enabled - RI::ReadbackARGBPixelsAsync() -// Disabled - simply call sync readback on a separate thread. -BASE_FEATURE(kTrullyAsyncRgbVideoFrameCopyTo, - "TrullyAsyncRgbVideoFrameCopyTo", - base::FEATURE_ENABLED_BY_DEFAULT); - } // namespace namespace WTF { @@ -148,8 +141,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(txt_frame); - if (base::FeatureList::IsEnabled(kTrullyAsyncRgbVideoFrameCopyTo) && - CanUseRgbReadback(*txt_frame)) { + if (CanUseRgbReadback(*txt_frame)) { ReadbackRGBTextureBackedFrameToBuffer(txt_frame, src_rect, dest_layout, dest_buffer, std::move(done_cb)); return;
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame.cc b/third_party/blink/renderer/modules/webcodecs/video_frame.cc index f97a886..2ed55cf0 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_frame.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
@@ -79,11 +79,6 @@ namespace { -// Controls if VideoFrame.copyTo() reads GPU frames asynchronously -BASE_FEATURE(kVideoFrameAsyncCopyTo, - "VideoFrameAsyncCopyTo", - base::FEATURE_ENABLED_BY_DEFAULT); - media::VideoPixelFormat ToMediaPixelFormat(V8VideoPixelFormat::Enum fmt) { switch (fmt) { case V8VideoPixelFormat::Enum::kI420: @@ -1133,11 +1128,9 @@ } else { DCHECK(local_frame->HasTextures()); - if (base::FeatureList::IsEnabled(kVideoFrameAsyncCopyTo)) { - if (auto* resolver = CopyToAsync(script_state, local_frame, src_rect, - destination, dest_layout)) { - return resolver->Promise(); - } + if (auto* resolver = CopyToAsync(script_state, local_frame, src_rect, + destination, dest_layout)) { + return resolver->Promise(); } if (!CopyTexturablePlanes(*local_frame, src_rect, dest_layout, buffer)) {
diff --git a/third_party/blink/tools/run_wpt_tests.py b/third_party/blink/tools/run_wpt_tests.py index 520e6fc..9afcf8f 100755 --- a/third_party/blink/tools/run_wpt_tests.py +++ b/third_party/blink/tools/run_wpt_tests.py
@@ -995,6 +995,7 @@ yield def update_options(self): + super().update_options() self._options.device_serial.extend(sorted(self.devices)) self._options.package_name = (self._options.package_name or self.get_browser_package_name())
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index cd281cf..8ecdd86 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3515,7 +3515,7 @@ crbug.com/618969 external/wpt/css/css-grid/subgrid/orthogonal-writing-mode-004.html [ Failure ] crbug.com/618969 external/wpt/css/css-grid/subgrid/repeat-auto-fill-003.html [ Failure ] crbug.com/618969 external/wpt/css/css-grid/subgrid/repeat-auto-fill-006.html [ Failure ] -crbug.com/618969 external/wpt/css/css-grid/subgrid/subgrid-baseline-001.html [ Failure Crash ] +crbug.com/618969 external/wpt/css/css-grid/subgrid/subgrid-baseline-001.html [ Crash Failure ] crbug.com/618969 external/wpt/css/css-grid/subgrid/subgrid-baseline-002.html [ Crash Failure Timeout ] crbug.com/618969 external/wpt/css/css-grid/subgrid/subgrid-baseline-003.html [ Crash ] crbug.com/618969 external/wpt/css/css-grid/subgrid/subgrid-baseline-004.html [ Crash ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index d298fc6..44a0949 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -81526,7 +81526,7 @@ ] ], "border-image-repeat-round.html": [ - "7cf645d62f07762d687c1c01e78243957fd17c36", + "5171eef5fd4f78903c0872d164dd7cc15ec0fe71", [ null, [ @@ -81542,11 +81542,11 @@ [ [ 0, - 25 + 92 ], [ 0, - 2984 + 3435 ] ] ] @@ -81775,7 +81775,7 @@ ] ], "border-image-round-and-stretch.html": [ - "6833b562da23d6270249efbe2b92ed85b4546de1", + "73909c1d0b77d17e6c84a53287c2af2b70b219cb", [ null, [ @@ -81791,11 +81791,11 @@ [ [ 0, - 25 + 66 ], [ 0, - 4192 + 4781 ] ] ] @@ -81940,7 +81940,7 @@ ] ], "border-image-slice-percentage.html": [ - "000a96ac01e7073fe059b868b2491ddd41444b1e", + "d4d2bdbfb94605138f462ef7624bc0cb6ffbf91b", [ null, [ @@ -81956,11 +81956,11 @@ [ [ 0, - 7 + 92 ], [ 0, - 944 + 3435 ] ] ] @@ -81969,7 +81969,7 @@ ] ], "border-image-space-001.html": [ - "9e125675e79213116b2675c7d2bfa95676a7585b", + "7af66db7bf9305fffb48960a483a8971e4974c23", [ null, [ @@ -81985,11 +81985,11 @@ [ [ 0, - 12 + 36 ], [ 0, - 1152 + 1728 ] ] ] @@ -95880,7 +95880,7 @@ ] ], "oklch-010.html": [ - "425f4d820183c24168049dc41c66a37f3b2366d3", + "091b760bea29bed450a21c9620eec2b0823bdc84", [ null, [ @@ -266532,11 +266532,11 @@ "support": { ".cache": { "gitignore2.json": [ - "f56b8266b3a334a8d54b5e66d7d8581e124db11f", + "59fd380c2fe9369d66270c0b27cd7dc6d496dec5", [] ], "mtime.json": [ - "dd1fae8c9015a698546ce60e10dd6094dff475f8", + "d3a3571dd7fd0cef7e2c9d5da342e87e724bb0b1", [] ] }, @@ -266901,7 +266901,7 @@ ], "derive_bits_keys": { "cfrg_curves_bits.https.any-expected.txt": [ - "32999787a6e6eeea41713dcf37165a15a65c3bb8", + "45b2187a094d707caab9d9b51f6e24a0896f6fa5", [] ], "cfrg_curves_bits.https.any.js.ini": [ @@ -266909,27 +266909,31 @@ [] ], "cfrg_curves_bits.https.any.worker-expected.txt": [ - "32999787a6e6eeea41713dcf37165a15a65c3bb8", + "45b2187a094d707caab9d9b51f6e24a0896f6fa5", [] ], "cfrg_curves_bits.js": [ - "463f687f1652e4e135f5f06d4650563191b41ebf", + "4e12ca0eb711fae5168eb1a17db756588ef4eab6", + [] + ], + "cfrg_curves_bits_fixtures.js": [ + "ffdeb51eab97005bb7e7927cb25e37491027285a", [] ], "cfrg_curves_keys.https.any-expected.txt": [ - "d4e119ef5ed45df8760b4c49e7cd911c8529a1f5", + "a7623cea11ac7c3d3c499cd6c29bb1e31629da63", [] ], "cfrg_curves_keys.https.any.js.ini": [ - "4743316507c0964ea1c1efda5d0a79ed034d2d3d", + "4b4b460c0c9807aaf1951e7f841f043c8c66bca9", [] ], "cfrg_curves_keys.https.any.worker-expected.txt": [ - "d4e119ef5ed45df8760b4c49e7cd911c8529a1f5", + "a7623cea11ac7c3d3c499cd6c29bb1e31629da63", [] ], "cfrg_curves_keys.js": [ - "3c53697ce3c49bd57c38cab01e4117ffc9011236", + "81244ba05a876614cf2777528fdaf5deac7298aa", [] ], "ecdh_bits.https.any-expected.txt": [ @@ -270432,7 +270436,7 @@ [] ], "generate.py": [ - "176e0ebbebc07ac44cbf735c67a1b50ea028d0d7", + "409b4f195ff72c0427e51c523940302586243636", [] ], "spec.src.json": [ @@ -270440,7 +270444,7 @@ [] ], "spec_validator.py": [ - "3ac3f530169e5461ae070a7568aaff2cdba9c398", + "f8a1390ef0d440d21986c8c34803dd34c5dcb815", [] ], "template": { @@ -270462,7 +270466,7 @@ ] }, "util.py": [ - "72541c781429be479a02809bef14532a7c1900b3", + "5da06f9d51eb084770340c39d826079d2126b52a", [] ] }, @@ -273575,7 +273579,7 @@ [] ], "set-cookie.py": [ - "1163531564f45f4a33af1fea0f5d85e1b7283b70", + "59b5b8006a0b24b0dfc90365c203e2bf6689bffa", [] ], "set.py": [ @@ -285751,44 +285755,60 @@ [] ], "parsing": { - "color-computed-color-function-expected.txt": [ - "bfe2d14914b1ad7d5088ed25a82bd7dcbdec37e3", + "color-computed-lab-expected.txt": [ + "7d4cde8e3a678b16c9f7f08f7d23cea29b2b713d", [] ], - "color-computed-color-function.html.ini": [ - "861db3c4de759afbfe2e403b5a43dd208264bc8e", + "color-computed-lab.html.ini": [ + "0b52cae9bb1c8c548f7ed0e56b02878d8eac6bdf", [] ], "color-computed-relative-color-expected.txt": [ - "60fb88f5196851c220e91ea8c78d282de0c9fa92", + "be758f7252ef8c9d11323f1bdf07440132acb172", [] ], "color-computed-relative-color.html.ini": [ - "4963d6a165e72c527b212f520538a8cc3182b650", + "cd52a07975a7b0d3aaba0c37a1d2f8eef7b47142", [] ], "color-valid-color-mix-function-expected.txt": [ - "c34ec180860c8d0276ee06bbaec4b8a1aa99b964", + "c763f87ab3d82da77f865ef6532ec200d6ef5d22", [] ], "color-valid-color-mix-function.html.ini": [ "a6532b8e209afedbab2c65756d1690a0a18e7b82", [] ], + "color-valid-lab-expected.txt": [ + "d41facc992652d5766bf20bd808d050ee7102982", + [] + ], + "color-valid-lab.html.ini": [ + "a9e44253ed847993bb514449302bf6cabda21bc1", + [] + ], "color-valid-relative-color-expected.txt": [ - "5bf4e6a04c36ce0bdc421bb588d5e07dd14b92a4", + "ff73eaaad050a55ba85ffbfe5b802b46f463710e", [] ], "color-valid-relative-color.html.ini": [ - "7f284781cf34b40d6609cf7a6eaec925da418719", + "9e2a1e0b92143c20ee0bf7c2260fa6ebd7109509", + [] + ], + "color-valid-system-color-expected.txt": [ + "0ab1033c4e9a82659ec136f2084d572ab442298d", + [] + ], + "color-valid-system-color.html.ini": [ + "9746564795a98a36656d108bb6192c291276cd04", [] ], "gamut-mapping-expected.txt": [ - "6a01179e5abd2129a4edf54b4998a6010dfebced", + "b1d458ab96ce2aaae9cb9ac09d6e157c9f4850a0", [] ], "gamut-mapping.html.ini": [ - "167c8d0b8bb67a85092762eac612e4c7fabbbbde", + "63eda371a277d27272e23788fdc523dd6b7ca170", [] ] }, @@ -298897,7 +298917,7 @@ [] ], "makegsubfonts.py": [ - "e519b4936de26e9819419d91d5cc8c3254a4f783", + "b46fa0e632b0ca903513c2694e505ff7fb930863", [] ], "pass.woff": [ @@ -300895,6 +300915,10 @@ "69e071c758b65724d49af23ecd7d3d77d1970e3c", [] ], + "abs-pos-002.html.ini": [ + "959f11477c246997efab04b43f115c04f753df4b", + [] + ], "auto-track-sizing-001-ref.html": [ "800f87e5d00a767f1cb5e5816ffd46110fbd4e80", [] @@ -300915,6 +300939,10 @@ "c98740b4e5af28da380e28d19f905efcfce560d8", [] ], + "baseline-001.html.ini": [ + "a20c5862f445060ac235a6fc9ef0f4992aa3482b", + [] + ], "grid-gap-001-ref.html": [ "e7909fc2064e4d3498ab90da179cf4ad0d0e9c79", [] @@ -301023,6 +301051,10 @@ "ee99c02410c303b378c5ef78b6052f5e24cee4cd", [] ], + "grid-gap-normal-001.html.ini": [ + "abe76ae6f7770bd656eb617fce8a84ed78f6561a", + [] + ], "grid-gap-smaller-001-ref.html": [ "fcd6851e2f84c2ec33a76b86ba4b15a70d36f7e8", [] @@ -301208,7 +301240,7 @@ [] ], "subgrid-baseline-001.html.ini": [ - "f4293eb2d8ab90dd2ba320cdc343be0eea607bdf", + "714bf4bc043e6d3a1114a38a1655cb32f33eac16", [] ], "subgrid-baseline-002-ref.html": [ @@ -301223,14 +301255,26 @@ "d6da254d8879d2f67ed262b1fe043f29af06b1eb", [] ], + "subgrid-baseline-003.html.ini": [ + "0eae8d4ea54436e92dcdd8d90c0d373a52952abe", + [] + ], "subgrid-baseline-004-ref.html": [ "4240df1659e408bcb48607c6233c42a897873a5c", [] ], + "subgrid-baseline-004.html.ini": [ + "312f662181f0251d67dd3049ff1f1db036e465bf", + [] + ], "subgrid-item-block-size-001-ref.html": [ "d264a3455a6c580976d2519ab4e0eb206b1164bf", [] ], + "subgrid-item-block-size-001.html.ini": [ + "a31d6682f10c7a35368249b9c6a8de407edfebc5", + [] + ], "subgrid-stretch-ref.html": [ "33e8669da01787826ea27895323f17b5b3a6a2c9", [] @@ -302635,30 +302679,6 @@ "08d03f0a537f8e54ee1edc2f6afcc0d366cd4f46", [] ], - "generate-object-fit-and-position-canvas-tests.sh": [ - "aeeee5284cd71e8c601f8b2420456813ce138344", - [] - ], - "generate-object-fit-png-tests.sh": [ - "af20d0212ad9f2159ef90e7c10b6b20f690541de", - [] - ], - "generate-object-fit-svg-tests.sh": [ - "c4d51877e0e69a41b2bb6b0c8a30736ab493c9ab", - [] - ], - "generate-object-position-png-tests.sh": [ - "4763fabf7ff7f3098877ab9cdd8838ecc3458b20", - [] - ], - "generate-object-position-svg-tests.sh": [ - "e00385a4748c535bed5e7af0892d18399db894ce", - [] - ], - "generate_object_view_box_tests.py": [ - "ccc5e4d14507fd911337f99135aed551ad84665b", - [] - ], "import-green.css": [ "537104e663364492c6ef388e4afce190e9c5bc58", [] @@ -302675,46 +302695,6 @@ "833e6e36cdf316be9e4f54dc68732712afe11ba2", [] ], - "object-view-box-fit-contain-ref-template.html": [ - "2f11249570dfdfe2a1d220cd43bf96d7b9a8fcfd", - [] - ], - "object-view-box-fit-contain-template.html": [ - "f874e65b88dd1c48bcc26fdccdabc743156d99cd", - [] - ], - "object-view-box-fit-cover-ref-template.html": [ - "2e830c0bae29e719376c36feedd946924f2b8f62", - [] - ], - "object-view-box-fit-cover-template.html": [ - "85664a20b2608e88e284df8d9b8a0ec611d365a9", - [] - ], - "object-view-box-fit-fill-ref-template.html": [ - "574e29128600a4e5298c663928debb25a3ac8875", - [] - ], - "object-view-box-fit-fill-template.html": [ - "ee2d83e8f201d5eb669ab5a87a5efdc5d952741a", - [] - ], - "object-view-box-fit-none-ref-template.html": [ - "861d9230a38709d61c82c056b2b77abfb3c3d619", - [] - ], - "object-view-box-fit-none-template.html": [ - "ab0c083d2194289550aeb3909905683792e51956", - [] - ], - "object-view-box-writing-mode-ref-template.html": [ - "764ba985fd7b8666e901fd2a4b23f7df1f7ee6e7", - [] - ], - "object-view-box-writing-mode-template.html": [ - "a8c1189a96c0c5db9b91b7b423b4167cdef1c570", - [] - ], "pattern-grg-rgr-grg.png": [ "6fcfeb4883edea810f880fabb861e09df7871695", [] @@ -302801,22 +302781,6 @@ "1591aa0e2e274854ed836cf582235ea0202f9c8e", [] ], - "template-object-fit-ref.html": [ - "068c74b4e41aa34cb19478e7441dda90215e5175", - [] - ], - "template-object-fit-test.html": [ - "8ec4664db92420386327f9d22d3ddbdda0edc25d", - [] - ], - "template-object-position-ref.html": [ - "19661f41f6fb0b5b8fd979c1c0b2902b1d559260", - [] - ], - "template-object-position-test.html": [ - "fb4b3ad3c7aeab61f44c394926735a97a8767d3c", - [] - ], "test-bl.png": [ "904e24e996a3e5da93bef89e10c49e24c07d0ed2", [] @@ -302861,7 +302825,89 @@ "tiled-radial-gradients-ref.html": [ "30046e4f2c0331d5d87ad44b6ea04cabb2213a9f", [] - ] + ], + "tools": { + "generate-object-fit-and-position-canvas-tests.sh": [ + "aeeee5284cd71e8c601f8b2420456813ce138344", + [] + ], + "generate-object-fit-png-tests.sh": [ + "af20d0212ad9f2159ef90e7c10b6b20f690541de", + [] + ], + "generate-object-fit-svg-tests.sh": [ + "c4d51877e0e69a41b2bb6b0c8a30736ab493c9ab", + [] + ], + "generate-object-position-png-tests.sh": [ + "4763fabf7ff7f3098877ab9cdd8838ecc3458b20", + [] + ], + "generate-object-position-svg-tests.sh": [ + "e00385a4748c535bed5e7af0892d18399db894ce", + [] + ], + "generate_object_view_box_tests.py": [ + "452e87bab1a98d3fe548e7b93f4949bb5c8a4d7c", + [] + ], + "object-view-box-fit-contain-ref-template.html": [ + "2f11249570dfdfe2a1d220cd43bf96d7b9a8fcfd", + [] + ], + "object-view-box-fit-contain-template.html": [ + "f874e65b88dd1c48bcc26fdccdabc743156d99cd", + [] + ], + "object-view-box-fit-cover-ref-template.html": [ + "2e830c0bae29e719376c36feedd946924f2b8f62", + [] + ], + "object-view-box-fit-cover-template.html": [ + "85664a20b2608e88e284df8d9b8a0ec611d365a9", + [] + ], + "object-view-box-fit-fill-ref-template.html": [ + "574e29128600a4e5298c663928debb25a3ac8875", + [] + ], + "object-view-box-fit-fill-template.html": [ + "ee2d83e8f201d5eb669ab5a87a5efdc5d952741a", + [] + ], + "object-view-box-fit-none-ref-template.html": [ + "861d9230a38709d61c82c056b2b77abfb3c3d619", + [] + ], + "object-view-box-fit-none-template.html": [ + "ab0c083d2194289550aeb3909905683792e51956", + [] + ], + "object-view-box-writing-mode-ref-template.html": [ + "764ba985fd7b8666e901fd2a4b23f7df1f7ee6e7", + [] + ], + "object-view-box-writing-mode-template.html": [ + "a8c1189a96c0c5db9b91b7b423b4167cdef1c570", + [] + ], + "template-object-fit-ref.html": [ + "068c74b4e41aa34cb19478e7441dda90215e5175", + [] + ], + "template-object-fit-test.html": [ + "8ec4664db92420386327f9d22d3ddbdda0edc25d", + [] + ], + "template-object-position-ref.html": [ + "19661f41f6fb0b5b8fd979c1c0b2902b1d559260", + [] + ], + "template-object-position-test.html": [ + "fb4b3ad3c7aeab61f44c394926735a97a8767d3c", + [] + ] + } }, "css-inline": { "META.yml": [ @@ -315273,7 +315319,7 @@ ], "tools": { "generate-segment-break-transformation-rules-tests.py": [ - "fc894161bda1b4e3f5b643b6e668a6d1d0bcc614", + "6689ef5f18259e5b6e9fc6864db862825ac61691", [] ] } @@ -316732,7 +316778,7 @@ [] ], "text-transform-capitalize-007.html.ini": [ - "4dd4f078df482979aef56a6f67251ad514fe3ad0", + "59933dbf456a7ffd32f3db8b49c5342f05034449", [] ], "text-transform-capitalize-014.html.ini": [ @@ -316760,7 +316806,7 @@ [] ], "text-transform-capitalize-030.html.ini": [ - "c3e6d0fc941b942b35af00cf0986f758e875a3b3", + "6d9f4066b71eb66ba29307c156b16e6a9c9f634b", [] ], "text-transform-capitalize-033-ref.html": [ @@ -319434,15 +319480,15 @@ ], "tools": { "generate-text-emphasis-line-height-tests.py": [ - "12fb6a3ad850b357808c47a90a818dd73be2de5b", + "e2a4457f38e4659534fc35c794d2000e3c61635f", [] ], "generate-text-emphasis-position-property-tests.py": [ - "527959068762f5a7185bf11bdc2536054d2db258", + "f2baf023325ad45c7793d30a5eafcf2fde84bf06", [] ], "generate-text-emphasis-ruby-tests.py": [ - "fdbaec052e4e4bdfdcad1e9fc9731bf26a518509", + "f1158f5f843fcabda15aed4e2f6155303f8252a6", [] ], "generate-text-emphasis-style-property-010-tests.sh": [ @@ -319450,7 +319496,7 @@ [] ], "generate-text-emphasis-style-property-tests.py": [ - "1b1d6fc16f24b91eef28cd99c428f426cc61c349", + "b6ad1f7291b2b91cc22f0096c169b7b844e295ed", [] ] } @@ -321058,10 +321104,6 @@ "f72f11dccae5e8b63de6148573723f86fbb4c708", [] ], - "all-with-discrete.tentative.html.ini": [ - "30ee9a0e03e0aa855be9aef1eb2ac53e04b56616", - [] - ], "animations": { "transition-timing-function.html.ini": [ "9b89222a1852c831fbbf38790aef8e9c31b7937c", @@ -322368,6 +322410,10 @@ "a585f5cf7aee9eb09b6076d663b42a63d20c4afb", [] ], + "appearance-listbox-001.html.ini": [ + "2131756c61ad815531882044808c8ff719612d46", + [] + ], "appearance-progress-bar-002-ref.html": [ "d243f0c75c75f57e6fd1ca629ccf0d3d924a0c13", [] @@ -322465,6 +322511,10 @@ "304d4c2af7e769febddfd16955e7f7c7f07a9f4f", [] ], + "kind-of-widget-fallback-color-input-border-block-start-width-001.html.ini": [ + "c3109afb3faa3d56f44ed019dfe2262ad57059fc", + [] + ], "kind-of-widget-fallback-color-input-border-bottom-style-001.html.ini": [ "781e3a390720e3062919d91b8b872054bbd0548f", [] @@ -322477,6 +322527,10 @@ "98578348b16a63fb19f718b1b4c8ee2cf87e6d7a", [] ], + "kind-of-widget-fallback-color-input-border-left-width-001.html.ini": [ + "790ec0a2515cffe6f8324353c2a9273a6a1ebb11", + [] + ], "kind-of-widget-fallback-color-input-border-right-width-001.html.ini": [ "3bc7206ff029796da08852980f2e65ceb93e446f", [] @@ -322589,6 +322643,10 @@ "a77c2a52473f072692f12cb1890ce62b405e519d", [] ], + "kind-of-widget-fallback-input-search-text-border-bottom-left-radius-001.html.ini": [ + "9d37fdd0c88c9339108a74b2db534e9f58bb6697", + [] + ], "kind-of-widget-fallback-input-search-text-border-bottom-style-001.html.ini": [ "97d3e9abbd45580da8e8d11ceb56891c87c8ee75", [] @@ -322750,11 +322808,11 @@ [] ], "kind-of-widget-fallback-input-text-border-inline-end-color-001.html.ini": [ - "4293acf88c44bca78f7d40c8cf946b7bcf715860", + "2f8610f765b8b3da9d3a04556548003a9c1528f2", [] ], "kind-of-widget-fallback-input-text-border-inline-end-style-001.html.ini": [ - "ba3ab64bc391f1ff58ab4a64581a5f3134dc4e22", + "6fe71adadefcd5c0b4ea8078dd06c199b1f5e60a", [] ], "kind-of-widget-fallback-input-text-border-inline-end-width-001.html.ini": [ @@ -322769,6 +322827,10 @@ "c15fb2013c626f2c52316722bae7976f9b3f6d3c", [] ], + "kind-of-widget-fallback-input-text-border-left-color-001.html.ini": [ + "adb2eec9f2b02a3b661a3e4d4fc811cfcadb761a", + [] + ], "kind-of-widget-fallback-input-text-border-right-color-001.html.ini": [ "5bc373383d5976f2a3ac4ad63256a3003a52ab54", [] @@ -324396,14 +324458,6 @@ "b5b4997f42dd1b10d7c29534546ec7443f7a5316", [] ], - "calc-catch-divide-by-0-expected.txt": [ - "3a574bd555bda29e331c5f2df6d4fb4854e24fd0", - [] - ], - "calc-catch-divide-by-0.html.ini": [ - "5889c085afa6f75b7628dbcaeda8868df5459db6", - [] - ], "calc-ch-ex-lang-ref.html": [ "e0ac1ead1e5247c7c1d5fb2dffdf9ee0b08dd497", [] @@ -324433,7 +324487,7 @@ [] ], "calc-infinity-nan-serialize-angle-expected.txt": [ - "2a30fc3dbb5d09b26a58abe08641a38a6204b70d", + "3dfd64ddf2dda313347848c41af2b86a03b2f03f", [] ], "calc-infinity-nan-serialize-angle.html.ini": [ @@ -324441,7 +324495,7 @@ [] ], "calc-infinity-nan-serialize-length-expected.txt": [ - "4de867c762691798f1c53ea59c58ccceab083bb3", + "56ac7eedc3014f41277191537c026a91971e6f88", [] ], "calc-infinity-nan-serialize-length.html.ini": [ @@ -324457,7 +324511,7 @@ [] ], "calc-infinity-nan-serialize-time-expected.txt": [ - "9f3251a6ab969d3cc8b62962a0c544f607faf57b", + "43afde95b517c8dc93cce4ce80feb453c669f765", [] ], "calc-infinity-nan-serialize-time.html.ini": [ @@ -324640,14 +324694,6 @@ "7f4ecb1646a1ded87280ef34881e786e47fc2d7f", [] ], - "minmax-angle-serialize-expected.txt": [ - "8f56a1de89b32088e7f0cc5bb09c190f42d67620", - [] - ], - "minmax-angle-serialize.html.ini": [ - "37309303f1ed3007809559877294a9d409d7070c", - [] - ], "minmax-length-percent-serialize-expected.txt": [ "80ddc300e532ee012c8bc7f034a3d270e6c44d46", [] @@ -324664,14 +324710,6 @@ "3467297c31badc8b6768d2d44eb7d914bdc158a6", [] ], - "minmax-number-serialize-expected.txt": [ - "68dc883aa6123ea113fd8520932dd072b4620f05", - [] - ], - "minmax-number-serialize.html.ini": [ - "a19cd6e676912e9a18645b61ede75d4c3bf4174e", - [] - ], "minmax-percentage-serialize-expected.txt": [ "a25b56c10bb709e56feaec784bde34303cba8ebd", [] @@ -324680,14 +324718,6 @@ "b9f7b50a6a3edd2baf5ed57f5f2e79aee36e10ab", [] ], - "minmax-time-serialize-expected.txt": [ - "4f03477c6103376605575e87875c86529b60a11e", - [] - ], - "minmax-time-serialize.html.ini": [ - "29d0471f588d9a2addc6e35b50b62c8ab7bc02c7", - [] - ], "negative-calc-to-non-negative-integer-ref.html": [ "446809160733b6881ec97157a35451de38e517d6", [] @@ -330054,6 +330084,10 @@ "643d084cecde6353a993013eaba93455bd9bd899", [] ], + "css-backdrop-filters-animation-blur.html.ini": [ + "823e83d6411ca87184ad847d27a5c4098e5daa30", + [] + ], "css-backdrop-filters-animation-brightness-ref.html": [ "bf894ac57822a2e030ed91f8ac27765f0d2738f0", [] @@ -332692,7 +332726,7 @@ [] ], "requirements.txt": [ - "0ad8484f60b3f16d7318f6ad8983501d81f67eea", + "589a98eaa2ab33b4d330b5e355eb8b0bdc43d31f", [] ], "reviewing-tests": { @@ -333328,7 +333362,7 @@ [] ], "scroll_support.js": [ - "74b531cd3dfedfe8409f1918afebdff7b73e48fa", + "f561b6995344432c7030790ba98417fafae3e590", [] ], "scrollend-event-fired-after-sequence-of-scrolls.tentative.html.ini": [ @@ -333540,7 +333574,7 @@ [] ], "generate.py": [ - "a0bca546c75fdba873b5a99d2e593acdda2e5499", + "20c866bee80b94d36863cbd724a7e4abfc1ff635", [] ], "mathml.html": [ @@ -337023,7 +337057,7 @@ [] ], "make-polyfill-tests.py": [ - "532037e2a33226e31309a5838f4d7afd2c51227d", + "97c6fc74e93ba0f89f34c75cab3d4fb6ad183626", [] ] }, @@ -338011,25 +338045,9 @@ "c928fc36a1aea86c6d409aff651730def242d36b", [] ], - "response-null-body.any-expected.txt": [ - "fa818f443d303b3903069f46bc8824dd2bf8bb27", - [] - ], "response-null-body.any.js.ini": [ "1a623948a5e63fba491dd628a8272d1ee3d95768", [] - ], - "response-null-body.any.serviceworker-expected.txt": [ - "fa818f443d303b3903069f46bc8824dd2bf8bb27", - [] - ], - "response-null-body.any.sharedworker-expected.txt": [ - "fa818f443d303b3903069f46bc8824dd2bf8bb27", - [] - ], - "response-null-body.any.worker-expected.txt": [ - "fa818f443d303b3903069f46bc8824dd2bf8bb27", - [] ] }, "body": { @@ -339566,7 +339584,7 @@ [] ], "support.sub.js": [ - "c07fd2c2acee68967c57826fd093abb013b05761", + "0cf3d2532e7ffd5ff24d9dd3d1653cf60b62c071", [] ], "worker-blob-fetcher.html": [ @@ -340269,15 +340287,15 @@ }, "range": { "blob.any-expected.txt": [ - "6810b952a28178341af7babb9c282f2711bc9613", + "f48ee4fe6fe56fd51532ec00f59ff15dab7be807", [] ], "blob.any.js.ini": [ - "b25774bd386099148d9589d5ff9dce638c9969e1", + "a760cbe7a512fbcc6845c299a5002169775a363b", [] ], "blob.any.worker-expected.txt": [ - "6810b952a28178341af7babb9c282f2711bc9613", + "f48ee4fe6fe56fd51532ec00f59ff15dab7be807", [] ], "general.any.js.ini": [ @@ -340470,6 +340488,76 @@ ] } }, + "fledge": { + "tentative": { + "TODO": [ + "839d286b38882f94bf97f0f6d749a33aa165cf46", + [] + ], + "join-leave-ad-interest-group.https.sub.window-expected.txt": [ + "d9d724768adf81aa75f646b4eef3e58493c5072d", + [] + ], + "join-leave-ad-interest-group.https.sub.window.js.ini": [ + "6fb36dbb886c62417135af78966cf4611255938f", + [] + ], + "no-winner.https.sub.window-expected.txt": [ + "07b58b7fd822009fcc9b325d17004a82b32bc80f", + [] + ], + "no-winner.https.sub.window.js.ini": [ + "9ca0bf8eaf56a354b8608be269c7edb14421e00f", + [] + ], + "register-ad-beacon.https.sub.window-expected.txt": [ + "480b7e760f345614bd1abb00d316f53b8d1b0db9", + [] + ], + "register-ad-beacon.https.sub.window.js.ini": [ + "786171f5c148b4d59ad0528cca8a5d0a9ed42339", + [] + ], + "reporting-arguments.https.sub.window-expected.txt": [ + "ff7c8c4bb0e9319837b92f2008e0e4dc9c192f54", + [] + ], + "reporting-arguments.https.sub.window.js.ini": [ + "e43b6d50259584613fe24189c36a97bff27d1e76", + [] + ], + "resources": { + "bidding-logic.sub.py": [ + "dfc4d86be359d22783da86c2c38aa97b3f8060b8", + [] + ], + "decision-logic.sub.py": [ + "8d5303ac5a41c3540b6b1289346b3cd2d3cc6147", + [] + ], + "fenced-frame.sub.py": [ + "c29bb6fecccf5dc47ef82e4dc2fda4991b993f85", + [] + ], + "fledge-util.js": [ + "6432752e075c156f715970b13a714011d2cae423", + [] + ], + "request_tracker.py": [ + "46da796f30102e0e32a82a4dab96fa9217154306", + [] + ] + }, + "send-report-to.https.sub.window-expected.txt": [ + "843c347afb0407fedc8d1f5fd6aed3a4c5bcac3b", + [] + ], + "send-report-to.https.sub.window.js.ini": [ + "d3ca367206691d352d62c79cb310abb55ae0d02b", + [] + ] + } + }, "focus": { "activeelement-after-calling-window-focus.sub-expected.txt": [ "fb0ba66be4bb093e9207e5d998a493c4d2fb1fd1", @@ -342155,7 +342243,7 @@ [] ], "FileSystemBaseHandle-buckets.js": [ - "98261995f9659b939027d914d9f9ce0d3c2a980e", + "01c41231808e2c18d707c0b4413c03d825918578", [] ], "FileSystemBaseHandle-getUniqueId.js": [ @@ -346272,6 +346360,10 @@ "f3fed99ed12c51b8ef31df6d28a3bd0e1c35e0e5", [] ], + "2d.drawImage.svg.html.ini": [ + "1a3fc37e1e658c02f96935be17d1d8f0fc228366", + [] + ], "2d.drawImage.transform.html.ini": [ "1f76e3507603b3deff7a598af11fe90c7d0ff199", [] @@ -347106,7 +347198,7 @@ [] ], "canvas-display-p3-drawImage-ImageBitmap-cloned.html.ini": [ - "cb417bf5d09e6aae7811ce293f27f8764aa02b5e", + "1aea5841a28671029a240bc83b634ae08be3ff39", [] ], "canvas-display-p3-drawImage-ImageBitmap-image-expected.txt": [ @@ -348807,6 +348899,10 @@ "a19f4400cea33a60c99807330704a23ee363b146", [] ], + "popup-same-origin-unsafe-allow-outgoing-with-cross-origin.https.html.ini": [ + "da1992e875f4b4b66c82c8a9be845a4ef6f6445c", + [] + ], "popup-same-origin-unsafe-allow-outgoing-with-same-origin.https.html.headers": [ "a19f4400cea33a60c99807330704a23ee363b146", [] @@ -361759,7 +361855,7 @@ [] ], "update_html5lib_tests.py": [ - "f1a99416fc8a4a5cd4fd3b32b92cd23b72b521ce", + "7ad9bc6f862b724f73a32e688327f7f8206146b8", [] ] }, @@ -362653,10 +362749,6 @@ "2ff648a04905f9090df637f2140c1c092cc3a247", [] ], - "cicp.png": [ - "8fa0ce2123c4f876a71b1ca80e04931614f3b87f", - [] - ], "clear-100x50.png": [ "eeedd0ff05889ffd4468bf19a2e8e9e0a094201c", [] @@ -362807,10 +362899,6 @@ "55f8e69325bc61ff83f769a6524f7f9c3310be1f", [] ], - "trns.png": [ - "4e309a89a8a27a9f7afb6eee6a4a604a3ef7c249", - [] - ], "undecodable.png": [ "f2581017b43d44664e7137a78c0803554b50f3b1", [] @@ -363106,7 +363194,7 @@ }, "tools": { "ahem-generate-table.py": [ - "8790da02e2793664f7e1f0808f8d2b998718d54a", + "314279f67105958badfa56b37a4bcc2625797f5d", [] ] } @@ -365527,6 +365615,10 @@ "91c07f9fd3f3097367f2ad87a2ebb0d98b11d4e2", [] ], + "longtask-attributes.html.ini": [ + "8b52ce00823e87883cd3ca00e821daabd90b5e2d", + [] + ], "resources": { "makelongtask.js": [ "75de5453b5856deee20188afabee6e69f8426cb7", @@ -369961,6 +370053,10 @@ "c71611defdc8352e0788705b5627521b5cc51755", [] ], + "pending_post_beacon-cors.tentative.https.window.js.ini": [ + "9aa002cc7aac07035cfda9c963035d92518ce970", + [] + ], "resources": { "get_beacon.py": [ "32cb9a9ba30638bf0e5c7e54655ae87e7085978d", @@ -370812,7 +370908,17 @@ "cicp-chunk.html.ini": [ "8cd2af7f0d196f73721f166bfa1ef0ed578c7dd8", [] - ] + ], + "support": { + "cicp-display-p3.png": [ + "8fa0ce2123c4f876a71b1ca80e04931614f3b87f", + [] + ], + "trns-high-bits-set.png": [ + "4e309a89a8a27a9f7afb6eee6a4a604a3ef7c249", + [] + ] + } }, "pointerevents": { "DIR_METADATA": [ @@ -373767,6 +373873,10 @@ "de3c0b201c62b6317a1fc7cb95d9bc3e56094f6d", [] ], + "deadline-max-rAF-dynamic.html.ini": [ + "ed0c58e56bbb645adfea1d01737cd774539e3d47", + [] + ], "deadline-max-rAF.html.ini": [ "0f79d879bb1af7cd30b14c1c07eb46432e4bedfb", [] @@ -374680,7 +374790,15 @@ "OWNERS": [ "b2e83ff43cbd1ec9192337d7bd7cee3852375d44", [] - ] + ], + "tentative": { + "yield": { + "yield-priority-idle-callbacks.html.ini": [ + "946451eb83df1b1dc5cc5a0edc7c6c1b7b290469", + [] + ] + } + } }, "screen-capture": { "DIR_METADATA": [ @@ -379660,7 +379778,7 @@ [] ], "presentation-request.html": [ - "62829556bb438c1396a0f17c7e3b45456f2bdad9", + "18475a3d67f7d8688269ee7b433617e1fbb5c6e6", [] ], "prompt-by-before-unload-inner-frame.html": [ @@ -379912,10 +380030,6 @@ "00e171547a6cb114f8a31c0101be65e4dbc9df1b", [] ], - "restriction-presentation-request.https-expected.txt": [ - "8b137891791fe96927ad78e64b0aad7bded08bdc", - [] - ], "restriction-presentation-request.https.html.ini": [ "014edcaea08187b72dc82def14525b5fd1c194e8", [] @@ -380120,13 +380234,17 @@ [] ], "SpeechSynthesis-speak-twice.html.ini": [ - "510f9958af5de7ce1c940986f274eadca803eb26", + "dbd8c1d044f02a1c2b132c110ff98502d138b010", [] ], "SpeechSynthesis-speak-without-activation-fails.tentative.html.ini": [ "9cb5880aa39ca83ee43e24622c2f18c6970a01e0", [] ], + "SpeechSynthesisEvent-properties.html.ini": [ + "60593d65b8df5c1c2b53a34d351b8f73e8e1f8c8", + [] + ], "historical-expected.txt": [ "126cd0d91f1118a67579f553b521c2f77302e989", [] @@ -380169,7 +380287,13 @@ "META.yml": [ "4f215060f5abf6ba31f55e1fbe5a41b1daaa7a47", [] - ] + ], + "resources": { + "util.js": [ + "50abce14cdc520f81178d452d6f165e9401bfbd0", + [] + ] + } }, "helpers.js": [ "b524c1b82cfb7b7f8810d1150ff3df8b98f31017", @@ -380224,7 +380348,7 @@ [] ], "requestStorageAccess-cross-origin-iframe.sub.https.window.js.ini": [ - "9338e277c5e3acc519e00d0e07c910be491c624d", + "ddc96049415f4d6dd4d71403bf51dd1e032908b9", [] ], "requestStorageAccess-cross-site-iframe.sub.https.window.js.ini": [ @@ -380236,7 +380360,7 @@ [] ], "requestStorageAccess-nested-cross-origin-iframe.sub.https.window.js.ini": [ - "2c7ca81c4f6de2259926175d94159f88372afcfc", + "4b233c658f17836f950eaeb891c17919b412597c", [] ], "requestStorageAccess-nested-cross-site-iframe.sub.https.window.js.ini": [ @@ -380286,7 +380410,7 @@ ] }, "storage-access-permission.sub.https.window.js.ini": [ - "a64a86608ec6a5b7bd38863a718f7b06a9ff431c", + "48133200ffb2a76673c1e4b941fe3fea12caba2c", [] ], "storageAccess.testdriver.sub.html.ini": [ @@ -380621,11 +380745,11 @@ ], "tools": { "generate_javascript.py": [ - "300e1703b177765ea3df7c35fbbfae3d0aa8817a", + "fed3e5445fe86ac5869b7b30e912be7ecdd08df3", [] ], "list_hashes.py": [ - "5f189ce44b2260ea2187a5b880868efd7f793542", + "52f46ffd74788e5940afebb3b8b8ba93fc0123b7", [] ] } @@ -382249,7 +382373,7 @@ [] ], "requestStorageAccessFor.sub.https.window.js.ini": [ - "2dcb8bc3bb8d869ecf9ffb16f41fea137a92f7d1", + "f0f925ab226be3b289538a664f8d1504a01c5a15", [] ], "resources": { @@ -386424,7 +386548,7 @@ [] ], "helpers.py": [ - "e79a31448a323d06f583d35c6ffc9cbeef6d6f44", + "b0c065dca1189b711c44d23454760fde0181244c", [] ], "html": { @@ -386462,10 +386586,18 @@ "62067dd1667cd5535d4f90d35ae21474d4481666", [] ], + "cached.py": [ + "a43410f8856a861c8ad4633e40ea3ba298a5e31c", + [] + ], "headers.py": [ "ddae62dc6afabfaa9ceca93f5215d4afc5d002ed", [] ], + "must-revalidate.py": [ + "94f5a795a294c8b17aefb4e29e64cacb5c8e5ddf", + [] + ], "redirect.py": [ "f2fd1ebd51d4ad5f4ef0582510600eb3731fd2c7", [] @@ -388008,7 +388140,7 @@ [] ], "RTCRtpTransceiver-headerExtensionControl.html.ini": [ - "9b46e02b534528c26b52f463ca5d665ae0db1922", + "0b2d13f50acfdd71a61057fead139c22ce16f17f", [] ], "transfer-datachannel-service-worker.https.html.ini": [ @@ -395705,7 +395837,7 @@ ] ], "back-forward-cache-open-connection.window.js": [ - "084e7f73b9ed81fabd73d2f1fd938499a9e6058f", + "0021857d8b52509c309385f81aa3d7ea42476431", [ "IndexedDB/back-forward-cache-open-connection.window.html", { @@ -395733,13 +395865,18 @@ [ "script", "/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js" + ], + [ + "timeout", + "long" ] - ] + ], + "timeout": "long" } ] ], "back-forward-cache-open-transaction.window.js": [ - "bee3d017afeedb7fcaab5ce3af3025f3c59769c7", + "50d3c1f0d121d75604deb12433b28525679aa64f", [ "IndexedDB/back-forward-cache-open-transaction.window.html", { @@ -395763,8 +395900,13 @@ [ "script", "/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js" + ], + [ + "timeout", + "long" ] - ] + ], + "timeout": "long" } ] ], @@ -399461,7 +399603,7 @@ ] ], "storage-buckets.https.any.js": [ - "24923ffcf8d7f224a525a34d1f110011370c8aee", + "4271722a425b7b52f50e53cb99dfa2d512f24d09", [ "IndexedDB/storage-buckets.https.any.html", { @@ -399477,6 +399619,10 @@ [ "script", "resources/support-promises.js" + ], + [ + "script", + "/storage/buckets/resources/util.js" ] ] } @@ -399496,6 +399642,10 @@ [ "script", "resources/support-promises.js" + ], + [ + "script", + "/storage/buckets/resources/util.js" ] ] } @@ -399515,6 +399665,10 @@ [ "script", "resources/support-promises.js" + ], + [ + "script", + "/storage/buckets/resources/util.js" ] ] } @@ -399534,6 +399688,10 @@ [ "script", "resources/support-promises.js" + ], + [ + "script", + "/storage/buckets/resources/util.js" ] ] } @@ -400531,7 +400689,7 @@ ], "derive_bits_keys": { "cfrg_curves_bits.https.any.js": [ - "afa7db845faaeeb03108d0e69fb45fc3cb33872a", + "c1837591ee85d40d7ccf98b6ef56285369f0d7fd", [ "WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.html", { @@ -400542,6 +400700,10 @@ ], [ "script", + "cfrg_curves_bits_fixtures.js" + ], + [ + "script", "cfrg_curves_bits.js" ] ] @@ -400557,6 +400719,10 @@ ], [ "script", + "cfrg_curves_bits_fixtures.js" + ], + [ + "script", "cfrg_curves_bits.js" ] ] @@ -400564,7 +400730,7 @@ ] ], "cfrg_curves_keys.https.any.js": [ - "71fe87d9a874b7d2235e390f4b692c4b29490c62", + "96658a56e81da986a50863124109d71b91d9c571", [ "WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.html", { @@ -400575,6 +400741,10 @@ ], [ "script", + "cfrg_curves_bits_fixtures.js" + ], + [ + "script", "cfrg_curves_keys.js" ] ] @@ -400590,6 +400760,10 @@ ], [ "script", + "cfrg_curves_bits_fixtures.js" + ], + [ + "script", "cfrg_curves_keys.js" ] ] @@ -431450,6 +431624,27 @@ null, {} ] + ], + "table-parts-offsets-vertical-lr.tentative.html": [ + "bdac1f40607d2f63dee3cb8aadf6ac93f450a58c", + [ + null, + {} + ] + ], + "table-parts-offsets-vertical-rl.tentative.html": [ + "9d4a472d4382825c13af35114acc48a3b5face2a", + [ + null, + {} + ] + ], + "table-parts-offsets.tentative.html": [ + "265d761ffb30fd3e99214927a34ee33e3811f977", + [ + null, + {} + ] ] }, "transform-010.html": [ @@ -431938,14 +432133,14 @@ ] ], "color-computed-color-function.html": [ - "530a605bc9292f061dca5a053eb61f77349534ee", + "58a09971faa5ed1e269fd87baf070a678b9655d0", [ null, {} ] ], "color-computed-color-mix-function.html": [ - "1da6aa49e32f5879208941d2bdce1160695393a0", + "f000ed6a4541269966e22fba6f3e48661f09ab72", [ null, {} @@ -431973,7 +432168,7 @@ ] ], "color-computed-lab.html": [ - "45a1f9a010b27c0efb01b8dfc32671d4d95e388e", + "c25e12534393f11e483c387ef0850b26cd6dc658", [ null, {} @@ -431987,7 +432182,7 @@ ] ], "color-computed-relative-color.html": [ - "0587d09bd742fcf2278e088b6b53acecf177d7ca", + "44e0d8de7804eb6e4dcc278fa9e1bd8231aa6631", [ null, {} @@ -432099,7 +432294,7 @@ ] ], "color-valid-color-mix-function.html": [ - "cc23659caa524b39d6f67d7cc12fdcfc297eaf23", + "6e5a129fa0a883cebca2f45b1714dbb6314cfab4", [ null, {} @@ -432120,14 +432315,14 @@ ] ], "color-valid-lab.html": [ - "3a5d661712f9cd2a72df5d367de9c61fb1f4a29f", + "601a0ffb641c14757752112d84fa35de56ba0a56", [ null, {} ] ], "color-valid-relative-color.html": [ - "b5c8ddfca1c57ace348d789a3ed95ab4fbb78fb1", + "a1c9461d2ee9bff374fd91e8027eaf92c945fba4", [ null, {} @@ -432155,7 +432350,7 @@ ] ], "gamut-mapping.html": [ - "cfc1d1b946a729d4e7ca3fe2fd765aee3e53c8f9", + "02133acced21478aa311f8e66f8cca52236deaf0", [ null, {} @@ -442757,7 +442952,7 @@ }, "css-nesting": { "cssom.html": [ - "b7948f81bc147997d02929b5447765d193920032", + "b5bd80d1b46e3cda7714f4e047737a3057c35fac", [ null, {} @@ -452395,7 +452590,7 @@ ] ], "all-with-discrete.tentative.html": [ - "f12c14e4c55285fd0d5a4c541c7b8b37146165b0", + "a048bc7a1cc3958f5b2758369d30b3472771c388", [ null, {} @@ -453459,7 +453654,7 @@ ] ], "parse.tentative.html": [ - "f8a3412488c348a791120e2ad29c48ba87fc78f7", + "a453ef0488c719195b763cd27e697ff3af66ba0e", [ null, {} @@ -455519,10 +455714,14 @@ ] }, "appearance-cssom-001.html": [ - "1618c2b8a2825381661d470435f0dae4c3a40b8c", + "2da20a0ac923ea5bd975577c67976d63c82afe3b", [ null, {} + ], + [ + "css/css-ui/appearance-cssom-001.html?exclude=Invalid", + {} ] ], "appearance-initial-value-001.html": [ @@ -496056,7 +496255,7 @@ ] ], "redirect.https.window.js": [ - "f8a53ad1889e61712b98e0794de398307385b299", + "edbd5a19fbc963c7b37dedac88e31829d9268421", [ "fetch/local-network-access/redirect.https.window.html", { @@ -497561,7 +497760,7 @@ }, "range": { "blob.any.js": [ - "2f1bf5c2536d2246c8bea100d7c196ac0ce1b7a6", + "1db3b248f6c3657cc7a54bc9f941016ae6787f59", [ "fetch/range/blob.any.html", { @@ -498062,6 +498261,135 @@ ] ] }, + "fledge": { + "tentative": { + "join-leave-ad-interest-group.https.sub.window.js": [ + "e967d92618cfce83ad01c421202164bbe49f7a3a", + [ + "fledge/tentative/join-leave-ad-interest-group.https.sub.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testdriver.js" + ], + [ + "script", + "/common/utils.js" + ], + [ + "script", + "resources/fledge-util.js" + ] + ] + } + ] + ], + "no-winner.https.sub.window.js": [ + "4d24b5738eaaed58c9ef809a291d0a20021fc972", + [ + "fledge/tentative/no-winner.https.sub.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testdriver.js" + ], + [ + "script", + "/common/utils.js" + ], + [ + "script", + "resources/fledge-util.js" + ] + ] + } + ] + ], + "register-ad-beacon.https.sub.window.js": [ + "3df6b408a57068aaee91b7f6bb772a523f94d82b", + [ + "fledge/tentative/register-ad-beacon.https.sub.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testdriver.js" + ], + [ + "script", + "/common/utils.js" + ], + [ + "script", + "resources/fledge-util.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ], + "reporting-arguments.https.sub.window.js": [ + "69b7d2fddda4e2a12f42b9549da8177c5dc0ccf3", + [ + "fledge/tentative/reporting-arguments.https.sub.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testdriver.js" + ], + [ + "script", + "/common/utils.js" + ], + [ + "script", + "resources/fledge-util.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ], + "send-report-to.https.sub.window.js": [ + "bb0e7873a7024a562794d257441b038e5256f853", + [ + "fledge/tentative/send-report-to.https.sub.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testdriver.js" + ], + [ + "script", + "/common/utils.js" + ], + [ + "script", + "resources/fledge-util.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ] + } + }, "focus": { "activeelement-after-calling-window-focus.sub.html": [ "34579fb2a6301bacdc5e069e214d833f59564c59", @@ -498627,7 +498955,7 @@ ] ], "FileSystemBaseHandle-buckets.https.any.js": [ - "6bb7d7711949de6fdbe014dc38b5a8f3cb77adff", + "cd78c5a9508d13912bd8420e52067dd9a1a71701", [ "fs/FileSystemBaseHandle-buckets.https.any.html", { @@ -498642,6 +498970,10 @@ ], [ "script", + "/storage/buckets/resources/util.js" + ], + [ + "script", "script-tests/FileSystemBaseHandle-buckets.js" ] ] @@ -498661,6 +498993,10 @@ ], [ "script", + "/storage/buckets/resources/util.js" + ], + [ + "script", "script-tests/FileSystemBaseHandle-buckets.js" ] ] @@ -542463,6 +542799,13 @@ {} ] ], + "selectmenu-value-option.tentative.html": [ + "bf58630816addcb025ad7ac4e59c5ccfe16aa74f", + [ + null, + {} + ] + ], "selectmenu-value-selectedOption.tentative.html": [ "3ba7da6b5a2f893f0b5ec71ad25b4b8b5479c729", [ @@ -543454,7 +543797,7 @@ ] ], "popover-anchor-idl-property.html": [ - "1e255339f8107161a0ff105eae9f7f1547599f22", + "7b497ce09e6e192619b675b01b0ee21caa18a3e5", [ null, {} @@ -543608,7 +543951,7 @@ ] ], "popover-target-element-disabled.html": [ - "92c28a4b6c58d6726533e0c59f580e01448fc06c", + "59392f428ae3eacaa476dc0376069dce3831c459", [ null, {} @@ -557771,7 +558114,7 @@ ] ], "loaf-event-listener.html": [ - "6349c28b3202262c444aaefc558620c7baa19ff3", + "f866a1dfd83b7af311e3ab9c03be6d19074ab901", [ null, { @@ -557780,7 +558123,7 @@ ] ], "loaf-first-ui-event.html": [ - "f2d8dac3f1179f2ba3d56295d6a44652728f55e6", + "b30b645d2fab262e77b922c0d0d075b23d1f844d", [ null, { @@ -570082,14 +570425,14 @@ }, "png": { "cicp-chunk.html": [ - "4afc262dcf5ead61423a5bea21ae6e6f998a401c", + "8add5d602ea0c3478b27fd627e9ad5e9eb465083", [ null, {} ] ], "trns-chunk.html": [ - "652cda0e32089b7ade4e41c0f69a9637177bd9dd", + "3a24753382b20b4a1d5803ee64c730427dd62c54", [ null, {} @@ -587791,6 +588134,13 @@ {} ] ], + "yield-priority-idle-callbacks.html": [ + "d47e8c5eba2ed6eca2df695e93a4f1bb7a324b0b", + [ + null, + {} + ] + ], "yield-priority-posttask.any.js": [ "0700094dcf3679d18099204705c885005e070f74", [ @@ -591799,7 +592149,7 @@ ] ], "cache-storage-buckets.https.any.js": [ - "0b5ef7b298df64d9df1a79fa7e1fe3cd00178333", + "fd59ba464db0305de210fc2935d739b2469ec4ae", [ "service-workers/cache-storage/cache-storage-buckets.https.any.html", { @@ -591818,7 +592168,11 @@ ], [ "script", - "./resources/test-helpers.js" + "resources/test-helpers.js" + ], + [ + "script", + "/storage/buckets/resources/util.js" ], [ "timeout", @@ -591846,7 +592200,11 @@ ], [ "script", - "./resources/test-helpers.js" + "resources/test-helpers.js" + ], + [ + "script", + "/storage/buckets/resources/util.js" ], [ "timeout", @@ -591874,7 +592232,11 @@ ], [ "script", - "./resources/test-helpers.js" + "resources/test-helpers.js" + ], + [ + "script", + "/storage/buckets/resources/util.js" ], [ "timeout", @@ -591902,7 +592264,11 @@ ], [ "script", - "./resources/test-helpers.js" + "resources/test-helpers.js" + ], + [ + "script", + "/storage/buckets/resources/util.js" ], [ "timeout", @@ -597961,7 +598327,7 @@ ] ], "SpeechSynthesis-speak-events.html": [ - "c559da1f92965d00c7532bfdad6e0cccad80c83a", + "cc28b822f39bcb15f62353d609d80720ab79e371", [ null, { @@ -597970,7 +598336,7 @@ ] ], "SpeechSynthesis-speak-twice.html": [ - "3e0388b9cf37cae2075380faf48414a48b4092e9", + "2f9a401fc433f8d1d6d4acc4c407925623ac6094", [ null, { @@ -597979,7 +598345,7 @@ ] ], "SpeechSynthesis-speak-without-activation-fails.tentative.html": [ - "1b86552a1cbd8dabaf8b50f928823e743e4b46cb", + "676fe05d132bfdf3c82110e937129f4b70f95c7c", [ null, {} @@ -597999,6 +598365,15 @@ {} ] ], + "SpeechSynthesisEvent-properties.html": [ + "f6c8f5fc321d8dca382205c741de742711225212", + [ + null, + { + "testdriver": true + } + ] + ], "SpeechSynthesisUtterance-basics.https.html": [ "2fd394150e941ccbeb8d63b99e598cc53e55446d", [ @@ -598040,7 +598415,7 @@ "storage": { "buckets": { "buckets_storage_policy.tentative.https.any.js": [ - "4aaa02e4be464a34ff02294ba2f6d5898b5904e2", + "d6dce3675d0bca18a379518c6ecf2c7ec1310930", [ "storage/buckets/buckets_storage_policy.tentative.https.any.html", { @@ -598050,6 +598425,10 @@ "Buckets API: Tests for bucket storage policies." ], [ + "script", + "/storage/buckets/resources/util.js" + ], + [ "global", "window,worker" ] @@ -598065,6 +598444,10 @@ "Buckets API: Tests for bucket storage policies." ], [ + "script", + "/storage/buckets/resources/util.js" + ], + [ "global", "window,worker" ] @@ -598080,6 +598463,10 @@ "Buckets API: Tests for bucket storage policies." ], [ + "script", + "/storage/buckets/resources/util.js" + ], + [ "global", "window,worker" ] @@ -598095,6 +598482,10 @@ "Buckets API: Tests for bucket storage policies." ], [ + "script", + "/storage/buckets/resources/util.js" + ], + [ "global", "window,worker" ] @@ -598803,7 +599194,7 @@ ] ], "storage-access-permission.sub.https.window.js": [ - "82794061bd013ced4d8a42f3337fddd6a53d6d0a", + "f0aadf4828dcb549c0d66ef4745b1e190d56f8d6", [ "storage-access-api/storage-access-permission.sub.https.window.html", { @@ -599424,7 +599815,7 @@ ] ], "general.any.js": [ - "bec3480f65394461dea9cbdda84a5fe4c21e8ed5", + "faeb8e321af208543472e2d212c0701faeb09eb6", [ "streams/piping/general.any.html", { @@ -606312,7 +606703,7 @@ ] ], "requestStorageAccessFor.sub.https.window.js": [ - "9e16740cd2adfc8e04cac4504079fa2908013de1", + "4475098251e2172554048ef22d1c95a4cb44e679", [ "top-level-storage-access-api/tentative/requestStorageAccessFor.sub.https.window.html", { @@ -617360,7 +617751,7 @@ ] ], "storage-buckets.tentative.https.any.js": [ - "73cc0ac3725c36929357b702360035edb780c064", + "a6b4f59a95d715aaff638a3c2b3a6c9ab3532ab8", [ "web-locks/storage-buckets.tentative.https.any.html", { @@ -617374,6 +617765,10 @@ "resources/helpers.js" ], [ + "script", + "/storage/buckets/resources/util.js" + ], + [ "global", "window,dedicatedworker,sharedworker,serviceworker" ] @@ -617393,6 +617788,10 @@ "resources/helpers.js" ], [ + "script", + "/storage/buckets/resources/util.js" + ], + [ "global", "window,dedicatedworker,sharedworker,serviceworker" ] @@ -617412,6 +617811,10 @@ "resources/helpers.js" ], [ + "script", + "/storage/buckets/resources/util.js" + ], + [ "global", "window,dedicatedworker,sharedworker,serviceworker" ] @@ -617431,6 +617834,10 @@ "resources/helpers.js" ], [ + "script", + "/storage/buckets/resources/util.js" + ], + [ "global", "window,dedicatedworker,sharedworker,serviceworker" ]
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any-expected.txt index 3299978..45b2187 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any-expected.txt
@@ -6,11 +6,11 @@ PASS X25519 key derivation checks for all-zero value result with a key of order p-1 (order 2) PASS X25519 key derivation checks for all-zero value result with a key of order p (=0, order 4) PASS X25519 key derivation checks for all-zero value result with a key of order p+1 (=1, order 1) -FAIL X448 key derivation checks for all-zero value result with a key of order 0 promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'importKey' on 'SubtleCrypto': Algorithm: Unrecognized name" -FAIL X448 key derivation checks for all-zero value result with a key of order 1 promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'importKey' on 'SubtleCrypto': Algorithm: Unrecognized name" -FAIL X448 key derivation checks for all-zero value result with a key of order p-1 (order 2) promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'importKey' on 'SubtleCrypto': Algorithm: Unrecognized name" -FAIL X448 key derivation checks for all-zero value result with a key of order p (=0, order 4) promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'importKey' on 'SubtleCrypto': Algorithm: Unrecognized name" -FAIL X448 key derivation checks for all-zero value result with a key of order p+1 (=1, order 1) promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'importKey' on 'SubtleCrypto': Algorithm: Unrecognized name" +FAIL X448 key derivation checks for all-zero value result with a key of order 0 assert_false: Private key should be valid. expected false got true +FAIL X448 key derivation checks for all-zero value result with a key of order 1 assert_false: Private key should be valid. expected false got true +FAIL X448 key derivation checks for all-zero value result with a key of order p-1 (order 2) assert_false: Private key should be valid. expected false got true +FAIL X448 key derivation checks for all-zero value result with a key of order p (=0, order 4) assert_false: Private key should be valid. expected false got true +FAIL X448 key derivation checks for all-zero value result with a key of order p+1 (=1, order 1) assert_false: Private key should be valid. expected false got true PASS X25519 good parameters PASS X25519 mixed case parameters PASS X25519 with null length
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.js b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.js index afa7db84..c183759 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.js +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.js
@@ -1,4 +1,5 @@ // META: title=WebCryptoAPI: deriveBits() Using ECDH with CFRG Elliptic Curves +// META: script=cfrg_curves_bits_fixtures.js // META: script=cfrg_curves_bits.js // Define subtests from a `promise_test` to ensure the harness does not
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.worker-expected.txt index 3299978..45b2187 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.worker-expected.txt
@@ -6,11 +6,11 @@ PASS X25519 key derivation checks for all-zero value result with a key of order p-1 (order 2) PASS X25519 key derivation checks for all-zero value result with a key of order p (=0, order 4) PASS X25519 key derivation checks for all-zero value result with a key of order p+1 (=1, order 1) -FAIL X448 key derivation checks for all-zero value result with a key of order 0 promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'importKey' on 'SubtleCrypto': Algorithm: Unrecognized name" -FAIL X448 key derivation checks for all-zero value result with a key of order 1 promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'importKey' on 'SubtleCrypto': Algorithm: Unrecognized name" -FAIL X448 key derivation checks for all-zero value result with a key of order p-1 (order 2) promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'importKey' on 'SubtleCrypto': Algorithm: Unrecognized name" -FAIL X448 key derivation checks for all-zero value result with a key of order p (=0, order 4) promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'importKey' on 'SubtleCrypto': Algorithm: Unrecognized name" -FAIL X448 key derivation checks for all-zero value result with a key of order p+1 (=1, order 1) promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'importKey' on 'SubtleCrypto': Algorithm: Unrecognized name" +FAIL X448 key derivation checks for all-zero value result with a key of order 0 assert_false: Private key should be valid. expected false got true +FAIL X448 key derivation checks for all-zero value result with a key of order 1 assert_false: Private key should be valid. expected false got true +FAIL X448 key derivation checks for all-zero value result with a key of order p-1 (order 2) assert_false: Private key should be valid. expected false got true +FAIL X448 key derivation checks for all-zero value result with a key of order p (=0, order 4) assert_false: Private key should be valid. expected false got true +FAIL X448 key derivation checks for all-zero value result with a key of order p+1 (=1, order 1) assert_false: Private key should be valid. expected false got true PASS X25519 good parameters PASS X25519 mixed case parameters PASS X25519 with null length
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js index 463f687..4e12ca0e 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js
@@ -3,44 +3,6 @@ // May want to test prefixed implementations. var subtle = self.crypto.subtle; - var pkcs8 = { - "X25519": new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 110, 4, 34, 4, 32, 200, 131, 142, 118, 208, 87, 223, 183, 216, 201, 90, 105, 225, 56, 22, 10, 221, 99, 115, 253, 113, 164, 210, 118, 187, 86, 227, 168, 27, 100, 255, 97]), - "X448": new Uint8Array([48, 70, 2, 1, 0, 48, 5, 6, 3, 43, 101, 111, 4, 58, 4, 56, 88, 199, 210, 154, 62, 181, 25, 178, 157, 0, 207, 177, 145, 187, 100, 252, 109, 138, 66, 216, 241, 113, 118, 39, 43, 137, 242, 39, 45, 24, 25, 41, 92, 101, 37, 192, 130, 150, 113, 176, 82, 239, 7, 39, 83, 15, 24, 142, 49, 208, 204, 83, 191, 38, 146, 158]) - }; - - var spki = { - "X25519": new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 28, 242, 177, 230, 2, 46, 197, 55, 55, 30, 215, 245, 62, 84, 250, 17, 84, 216, 62, 152, 235, 100, 234, 81, 250, 229, 179, 48, 124, 254, 151, 6]), - "X448": new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 182, 4, 161, 209, 165, 205, 29, 148, 38, 213, 97, 239, 99, 10, 158, 177, 108, 190, 105, 213, 185, 202, 97, 94, 220, 83, 99, 62, 251, 82, 234, 49, 230, 230, 160, 161, 219, 172, 198, 231, 108, 188, 230, 72, 45, 126, 75, 163, 213, 93, 158, 128, 39, 101, 206, 111]) - }; - - var sizes = { - "X25519": 32, - "X448": 56 - }; - - var derivations = { - "X25519": new Uint8Array([39, 104, 64, 157, 250, 185, 158, 194, 59, 140, 137, 185, 63, 245, 136, 2, 149, 247, 97, 118, 8, 143, 137, 228, 61, 254, 190, 126, 161, 149, 0, 8]), - "X448": new Uint8Array([240, 246, 197, 241, 127, 148, 244, 41, 30, 171, 113, 120, 134, 109, 55, 236, 137, 6, 221, 108, 81, 65, 67, 220, 133, 190, 124, 242, 141, 239, 243, 155, 114, 110, 15, 109, 207, 129, 14, 181, 148, 220, 169, 123, 72, 130, 189, 68, 196, 62, 167, 220, 103, 244, 154, 78]) - }; - - var kSmallOrderPoint = { - "X25519": [ - { order: "0", vector : new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }, - { order: "1", vector : new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }, - { order: "8", vector : new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 224, 235, 122, 124, 59, 65, 184, 174, 22, 86, 227, 250, 241, 159, 196, 106, 218, 9, 141, 235, 156, 50, 177, 253, 134, 98, 5, 22, 95, 73, 184, 0]) }, - { order: "p-1 (order 2)", vector : new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 236, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127]) }, - { order: "p (=0, order 4)", vector : new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 237, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127]) }, - { order: "p+1 (=1, order 1)", vector : new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127]) }, - ], - "X448": [ - { order: "0", vector : new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }, - { order: "1", vector : new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }, - { order: "p-1 (order 2)", vector : new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]) }, - { order: "p (=0, order 4)", vector : new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]) }, - { order: "p+1 (=1, order 1)", vector : new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]) }, - ] - }; - // Verify the derive functions perform checks against the all-zero value results, // ensuring small-order points are rejected. // https://www.rfc-editor.org/rfc/rfc7748#section-6.1 @@ -50,16 +12,16 @@ kSmallOrderPoint[algorithmName].forEach(function(test) { promise_test(async() => { let derived; - let privateKey = await subtle.importKey("pkcs8", pkcs8[algorithmName], + let privateKey; + let publicKey; + try { + privateKey = await subtle.importKey("pkcs8", pkcs8[algorithmName], {name: algorithmName}, false, ["deriveBits", "deriveKey"]); - let publicKey = await subtle.importKey("spki", test.vector, + publicKey = await subtle.importKey("spki", test.vector, {name: algorithmName}, false, []) - try { - derived = await subtle.deriveKey({name: algorithmName, public: publicKey}, privateKey, - {name: "HMAC", hash: "SHA-256", length: 256}, true, - ["sign", "verify"]); + derived = await subtle.deriveBits({name: algorithmName, public: publicKey}, privateKey, 8 * sizes[algorithmName]); } catch (err) { assert_false(privateKey === undefined, "Private key should be valid."); assert_false(publicKey === undefined, "Public key should be valid.");
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_fixtures.js b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_fixtures.js new file mode 100644 index 0000000..ffdeb51e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_fixtures.js
@@ -0,0 +1,37 @@ +var pkcs8 = { + "X25519": new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 110, 4, 34, 4, 32, 200, 131, 142, 118, 208, 87, 223, 183, 216, 201, 90, 105, 225, 56, 22, 10, 221, 99, 115, 253, 113, 164, 210, 118, 187, 86, 227, 168, 27, 100, 255, 97]), + "X448": new Uint8Array([48, 70, 2, 1, 0, 48, 5, 6, 3, 43, 101, 111, 4, 58, 4, 56, 88, 199, 210, 154, 62, 181, 25, 178, 157, 0, 207, 177, 145, 187, 100, 252, 109, 138, 66, 216, 241, 113, 118, 39, 43, 137, 242, 39, 45, 24, 25, 41, 92, 101, 37, 192, 130, 150, 113, 176, 82, 239, 7, 39, 83, 15, 24, 142, 49, 208, 204, 83, 191, 38, 146, 158]) +}; + +var spki = { + "X25519": new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 28, 242, 177, 230, 2, 46, 197, 55, 55, 30, 215, 245, 62, 84, 250, 17, 84, 216, 62, 152, 235, 100, 234, 81, 250, 229, 179, 48, 124, 254, 151, 6]), + "X448": new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 182, 4, 161, 209, 165, 205, 29, 148, 38, 213, 97, 239, 99, 10, 158, 177, 108, 190, 105, 213, 185, 202, 97, 94, 220, 83, 99, 62, 251, 82, 234, 49, 230, 230, 160, 161, 219, 172, 198, 231, 108, 188, 230, 72, 45, 126, 75, 163, 213, 93, 158, 128, 39, 101, 206, 111]) +}; + +var sizes = { + "X25519": 32, + "X448": 56 +}; + +var derivations = { + "X25519": new Uint8Array([39, 104, 64, 157, 250, 185, 158, 194, 59, 140, 137, 185, 63, 245, 136, 2, 149, 247, 97, 118, 8, 143, 137, 228, 61, 254, 190, 126, 161, 149, 0, 8]), + "X448": new Uint8Array([240, 246, 197, 241, 127, 148, 244, 41, 30, 171, 113, 120, 134, 109, 55, 236, 137, 6, 221, 108, 81, 65, 67, 220, 133, 190, 124, 242, 141, 239, 243, 155, 114, 110, 15, 109, 207, 129, 14, 181, 148, 220, 169, 123, 72, 130, 189, 68, 196, 62, 167, 220, 103, 244, 154, 78]) +}; + +var kSmallOrderPoint = { + "X25519": [ + { order: "0", vector : new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }, + { order: "1", vector : new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }, + { order: "8", vector : new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 224, 235, 122, 124, 59, 65, 184, 174, 22, 86, 227, 250, 241, 159, 196, 106, 218, 9, 141, 235, 156, 50, 177, 253, 134, 98, 5, 22, 95, 73, 184, 0]) }, + { order: "p-1 (order 2)", vector : new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 236, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127]) }, + { order: "p (=0, order 4)", vector : new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 237, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127]) }, + { order: "p+1 (=1, order 1)", vector : new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127]) }, + ], + "X448": [ + { order: "0", vector : new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }, + { order: "1", vector : new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }, + { order: "p-1 (order 2)", vector : new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]) }, + { order: "p (=0, order 4)", vector : new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]) }, + { order: "p+1 (=1, order 1)", vector : new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]) }, + ] +};
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any-expected.txt index d4e119e..a7623cea 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any-expected.txt
@@ -1,5 +1,16 @@ This is a testharness.js-based test. PASS setup - define tests +PASS X25519 deriveBits checks for all-zero value result with a key of order 0 +PASS X25519 deriveBits checks for all-zero value result with a key of order 1 +PASS X25519 deriveBits checks for all-zero value result with a key of order 8 +PASS X25519 deriveBits checks for all-zero value result with a key of order p-1 (order 2) +PASS X25519 deriveBits checks for all-zero value result with a key of order p (=0, order 4) +PASS X25519 deriveBits checks for all-zero value result with a key of order p+1 (=1, order 1) +FAIL X448 deriveBits checks for all-zero value result with a key of order 0 assert_false: Private key should be valid. expected false got true +FAIL X448 deriveBits checks for all-zero value result with a key of order 1 assert_false: Private key should be valid. expected false got true +FAIL X448 deriveBits checks for all-zero value result with a key of order p-1 (order 2) assert_false: Private key should be valid. expected false got true +FAIL X448 deriveBits checks for all-zero value result with a key of order p (=0, order 4) assert_false: Private key should be valid. expected false got true +FAIL X448 deriveBits checks for all-zero value result with a key of order p+1 (=1, order 1) assert_false: Private key should be valid. expected false got true PASS Key derivation using a X25519 generated keys. FAIL Key derivation using a X448 generated keys. assert_unreached: Threw an unexpected error: NotSupportedError: Failed to execute 'generateKey' on 'SubtleCrypto': Algorithm: Unrecognized name - Reached unreachable code PASS X25519 good parameters
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.js b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.js index 71fe87d..96658a5 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.js +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.js
@@ -1,4 +1,5 @@ // META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves +// META: script=cfrg_curves_bits_fixtures.js // META: script=cfrg_curves_keys.js // Define subtests from a `promise_test` to ensure the harness does not
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.js.ini b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.js.ini index 4743316..4b4b460 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.js.ini +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.js.ini
@@ -8,6 +8,21 @@ [X448 base key is not a private key] expected: FAIL + [X448 deriveBits checks for all-zero value result with a key of order 0] + expected: FAIL + + [X448 deriveBits checks for all-zero value result with a key of order 1] + expected: FAIL + + [X448 deriveBits checks for all-zero value result with a key of order p (=0, order 4)] + expected: FAIL + + [X448 deriveBits checks for all-zero value result with a key of order p+1 (=1, order 1)] + expected: FAIL + + [X448 deriveBits checks for all-zero value result with a key of order p-1 (order 2)] + expected: FAIL + [X448 good parameters] expected: FAIL @@ -37,6 +52,21 @@ [X448 base key is not a private key] expected: FAIL + [X448 deriveBits checks for all-zero value result with a key of order 0] + expected: FAIL + + [X448 deriveBits checks for all-zero value result with a key of order 1] + expected: FAIL + + [X448 deriveBits checks for all-zero value result with a key of order p (=0, order 4)] + expected: FAIL + + [X448 deriveBits checks for all-zero value result with a key of order p+1 (=1, order 1)] + expected: FAIL + + [X448 deriveBits checks for all-zero value result with a key of order p-1 (order 2)] + expected: FAIL + [X448 good parameters] expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.worker-expected.txt index d4e119e..a7623cea 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.worker-expected.txt
@@ -1,5 +1,16 @@ This is a testharness.js-based test. PASS setup - define tests +PASS X25519 deriveBits checks for all-zero value result with a key of order 0 +PASS X25519 deriveBits checks for all-zero value result with a key of order 1 +PASS X25519 deriveBits checks for all-zero value result with a key of order 8 +PASS X25519 deriveBits checks for all-zero value result with a key of order p-1 (order 2) +PASS X25519 deriveBits checks for all-zero value result with a key of order p (=0, order 4) +PASS X25519 deriveBits checks for all-zero value result with a key of order p+1 (=1, order 1) +FAIL X448 deriveBits checks for all-zero value result with a key of order 0 assert_false: Private key should be valid. expected false got true +FAIL X448 deriveBits checks for all-zero value result with a key of order 1 assert_false: Private key should be valid. expected false got true +FAIL X448 deriveBits checks for all-zero value result with a key of order p-1 (order 2) assert_false: Private key should be valid. expected false got true +FAIL X448 deriveBits checks for all-zero value result with a key of order p (=0, order 4) assert_false: Private key should be valid. expected false got true +FAIL X448 deriveBits checks for all-zero value result with a key of order p+1 (=1, order 1) assert_false: Private key should be valid. expected false got true PASS Key derivation using a X25519 generated keys. FAIL Key derivation using a X448 generated keys. assert_unreached: Threw an unexpected error: NotSupportedError: Failed to execute 'generateKey' on 'SubtleCrypto': Algorithm: Unrecognized name - Reached unreachable code PASS X25519 good parameters
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js index 3c53697..81244ba 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js
@@ -3,25 +3,36 @@ // May want to test prefixed implementations. var subtle = self.crypto.subtle; - var pkcs8 = { - "X25519": new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 110, 4, 34, 4, 32, 200, 131, 142, 118, 208, 87, 223, 183, 216, 201, 90, 105, 225, 56, 22, 10, 221, 99, 115, 253, 113, 164, 210, 118, 187, 86, 227, 168, 27, 100, 255, 97]), - "X448": new Uint8Array([48, 70, 2, 1, 0, 48, 5, 6, 3, 43, 101, 111, 4, 58, 4, 56, 88, 199, 210, 154, 62, 181, 25, 178, 157, 0, 207, 177, 145, 187, 100, 252, 109, 138, 66, 216, 241, 113, 118, 39, 43, 137, 242, 39, 45, 24, 25, 41, 92, 101, 37, 192, 130, 150, 113, 176, 82, 239, 7, 39, 83, 15, 24, 142, 49, 208, 204, 83, 191, 38, 146, 158]) - }; - - var spki = { - "X25519": new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 28, 242, 177, 230, 2, 46, 197, 55, 55, 30, 215, 245, 62, 84, 250, 17, 84, 216, 62, 152, 235, 100, 234, 81, 250, 229, 179, 48, 124, 254, 151, 6]), - "X448": new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 182, 4, 161, 209, 165, 205, 29, 148, 38, 213, 97, 239, 99, 10, 158, 177, 108, 190, 105, 213, 185, 202, 97, 94, 220, 83, 99, 62, 251, 82, 234, 49, 230, 230, 160, 161, 219, 172, 198, 231, 108, 188, 230, 72, 45, 126, 75, 163, 213, 93, 158, 128, 39, 101, 206, 111]) - }; - - var sizes = { - "X25519": 32, - "X448": 56 - }; - - var derivations = { - "X25519": new Uint8Array([39, 104, 64, 157, 250, 185, 158, 194, 59, 140, 137, 185, 63, 245, 136, 2, 149, 247, 97, 118, 8, 143, 137, 228, 61, 254, 190, 126, 161, 149, 0, 8]), - "X448": new Uint8Array([240, 246, 197, 241, 127, 148, 244, 41, 30, 171, 113, 120, 134, 109, 55, 236, 137, 6, 221, 108, 81, 65, 67, 220, 133, 190, 124, 242, 141, 239, 243, 155, 114, 110, 15, 109, 207, 129, 14, 181, 148, 220, 169, 123, 72, 130, 189, 68, 196, 62, 167, 220, 103, 244, 154, 78]) - }; + // Verify the derive functions perform checks against the all-zero value results, + // ensuring small-order points are rejected. + // https://www.rfc-editor.org/rfc/rfc7748#section-6.1 + // TODO: The spec states that the check must be done on use, but there is discussion about doing it on import. + // https://github.com/WICG/webcrypto-secure-curves/pull/13 + Object.keys(kSmallOrderPoint).forEach(function(algorithmName) { + kSmallOrderPoint[algorithmName].forEach(function(test) { + promise_test(async() => { + let derived; + let privateKey; + let publicKey; + try { + privateKey = await subtle.importKey("pkcs8", pkcs8[algorithmName], + {name: algorithmName}, + false, ["deriveBits", "deriveKey"]); + publicKey = await subtle.importKey("spki", test.vector, + {name: algorithmName}, + false, []) + derived = await subtle.deriveKey({name: algorithmName, public: publicKey}, privateKey, + {name: "HMAC", hash: "SHA-256", length: 256}, true, + ["sign", "verify"]); + } catch (err) { + assert_false(privateKey === undefined, "Private key should be valid."); + assert_false(publicKey === undefined, "Public key should be valid."); + assert_equals(err.name, "OperationError", "Should throw correct error, not " + err.name + ": " + err.message + "."); + } + assert_equals(derived, undefined, "Operation succeeded, but should not have."); + }, algorithmName + " deriveBits checks for all-zero value result with a key of order " + test.order); + }); + }); // Ensure the keys generated by each algorithm are valid for key derivation. Object.keys(sizes).forEach(function(algorithmName) {
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-standard-html-formats-write-read.tentative.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-standard-html-formats-write-read.tentative.https.html new file mode 100644 index 0000000..f6313c1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-standard-html-formats-write-read.tentative.https.html
@@ -0,0 +1,64 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Async Clipboard unsanitized HTML write -> Async Clipboard unsanitized HTML read test</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> +'use strict'; + +// This function removes extra spaces between tags in html. For example, the +// following html: "<p> Hello </p> <body> World </body>" would turn into this +// html: "<p> Hello </p> <body> World </body>" +// We remove the extra spaces because in html they are considered equivalent, +// but when we are comparing for equality the spaces make a difference. +function reformatHtml(html) { + const parser = new DOMParser(); + const htmlString = + parser.parseFromString(html, 'text/html').documentElement.innerHTML; + const reformattedString = htmlString.replace(/\>\s*\</g, '> <'); + return reformattedString; +} + +// Writes a payload with HTML content and checks to ensure the correct data +// was written successfully. +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + // Create and write unsanitized version of standard HTML format. + const format1 = 'text/html'; + // The string must be concatenated in this way because the html parser + // will recognize a script tag even in quotes as a real script tag. By + // splitting it up in this way we avoid that error. + const html_script = '<script>const a = 5;</scr' + + 'ipt> <p>Hello World</p>'; + const textInput = '<head><style>color:blue</style><head>' + + '<body><p>Hello</p>' + html_script + '</body>'; + const blobInput1 = new Blob([textInput], {type: format1}); + const clipboardItemInput = new ClipboardItem({[format1]: blobInput1}); + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItemInput]); + + // Read unsanitized version of HTML format. + await waitForUserActivation(); + const clipboardItems = + await navigator.clipboard.read({unsanitized: ["text/html"]}); + assert_equals(clipboardItems.length, 1); + const clipboardItem = clipboardItems[0]; + assert_true(clipboardItem instanceof ClipboardItem); + + const blobOutput1 = await clipboardItem.getType(format1); + assert_equals(blobOutput1.type, format1); + + const data1 = await (new Response(blobOutput1)).text(); + const outputHtml = reformatHtml(data1); + const expectedHtml = '<html>' + textInput + '</html>'; + const unsanitizedExpectedHtml = reformatHtml(expectedHtml); + assert_equals(outputHtml, unsanitizedExpectedHtml); +}, 'Verify write and read unsanitized content to the clipboard given text/html format as input'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-standard-html-read-fail.tentative.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-standard-html-read-fail.tentative.https.html new file mode 100644 index 0000000..e7ddbb0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-standard-html-read-fail.tentative.https.html
@@ -0,0 +1,46 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Async Clipboard unsanitized HTML read validation tests</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> +'use strict'; + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.read({unsanitized: ['text/html', 'text/plain']})); +}, 'navigator.clipboard.read() fails for multiple unsanitized formats requested.'); + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.read({unsanitized: ['text/plain']})); +}, 'navigator.clipboard.read() fails for unsanitized text/plain requested.'); + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.read({unsanitized: ['image/png']})); +}, 'navigator.clipboard.read() fails for unsanitized image/png requested.'); + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.read({unsanitized: ['image/svg+xml']})); +}, 'navigator.clipboard.read() fails for unsanitized image/svg+xml requested.'); + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/common/security-features/tools/generate.py b/third_party/blink/web_tests/external/wpt/common/security-features/tools/generate.py index 176e0eb..409b4f19 100755 --- a/third_party/blink/web_tests/external/wpt/common/security-features/tools/generate.py +++ b/third_party/blink/web_tests/external/wpt/common/security-features/tools/generate.py
@@ -1,7 +1,5 @@ #!/usr/bin/env python3 -from __future__ import print_function - import argparse import collections import copy
diff --git a/third_party/blink/web_tests/external/wpt/common/security-features/tools/spec_validator.py b/third_party/blink/web_tests/external/wpt/common/security-features/tools/spec_validator.py index 3ac3f53..f8a1390 100755 --- a/third_party/blink/web_tests/external/wpt/common/security-features/tools/spec_validator.py +++ b/third_party/blink/web_tests/external/wpt/common/security-features/tools/spec_validator.py
@@ -1,7 +1,5 @@ #!/usr/bin/env python3 -from __future__ import print_function - import json, sys
diff --git a/third_party/blink/web_tests/external/wpt/common/security-features/tools/util.py b/third_party/blink/web_tests/external/wpt/common/security-features/tools/util.py index 72541c781..5da06f9d 100644 --- a/third_party/blink/web_tests/external/wpt/common/security-features/tools/util.py +++ b/third_party/blink/web_tests/external/wpt/common/security-features/tools/util.py
@@ -1,5 +1,3 @@ -from __future__ import print_function - import os, sys, json, json5, re import collections
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/visufx/animation/visibility-interpolation.html b/third_party/blink/web_tests/external/wpt/css/CSS2/visufx/animation/visibility-interpolation.html deleted file mode 100644 index 683b393a..0000000 --- a/third_party/blink/web_tests/external/wpt/css/CSS2/visufx/animation/visibility-interpolation.html +++ /dev/null
@@ -1,70 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<title>visibility interpolation</title> -<link rel="help" href="https://www.w3.org/TR/CSS2/visufx.html#visibility"> -<meta name="assert" content="visibility supports"> - -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/css/support/interpolation-testcommon.js"></script> - -<body> -<script> -test_interpolation({ - property: 'visibility', - from: 'visible', - to: 'visible' -}, [ - {at: -1, expect: 'visible'}, - {at: 0, expect: 'visible'}, - {at: 0.5, expect: 'visible'}, - {at: 1, expect: 'visible'}, - {at: 1.5, expect: 'visible'}, -]); - -test_interpolation({ - property: 'visibility', - from: 'visible', - to: 'hidden' -}, [ - {at: -1, expect: 'visible'}, - {at: 0, expect: 'visible'}, - {at: 0.1, expect: 'visible'}, - {at: 0.9, expect: 'visible'}, - {at: 1, expect: 'hidden'}, - {at: 1.5, expect: 'hidden'}, -]); - -test_interpolation({ - property: 'visibility', - from: 'hidden', - to: 'visible' -}, [ - {at: -1, expect: 'hidden'}, - {at: 0, expect: 'hidden'}, - {at: 0.1, expect: 'visible'}, - {at: 0.9, expect: 'visible'}, - {at: 1, expect: 'visible'}, - {at: 1.5, expect: 'visible'}, -]); - -test_interpolation({ - property: 'visibility', - from: 'collapse', - to: 'visible' -}, [ - {at: -1, expect: 'collapse'}, - {at: 0, expect: 'collapse'}, - {at: 0.1, expect: 'visible'}, - {at: 0.9, expect: 'visible'}, - {at: 1, expect: 'visible'}, - {at: 1.5, expect: 'visible'}, -]); - -test_no_interpolation({ - property: 'visibility', - from: 'collapse', - to: 'hidden' -}); -</script> -</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-round.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-round.html index 7cf645d..5171eef 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-round.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-round.html
@@ -6,7 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/css3-background/#border-images"> <link rel="match" href="reference/border-image-repeat-round-ref.html"> <meta name="assert" content="diamonds in corners should be red, and other diamonds should be orange, it should be 4 orange diamonds on each side."> - <meta name="fuzzy" content="0-25; 0-2984"> + <meta name="fuzzy" content="maxDifference=0-92;totalPixels=0-3435"> <style type="text/css"> .container { border: double red 1em;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-round-and-stretch.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-round-and-stretch.html index 6833b56..73909c1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-round-and-stretch.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-round-and-stretch.html
@@ -6,7 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/css3-background/#border-images"> <link rel="match" href="reference/border-image-round-and-stretch-ref.html"> <meta name="assert" content="orange diamonds on top and bottom border should be repeated 12 times, and orange diamonds on left and right border should be stretched, diamonds in corners should be red, and other diamonds should be orange."> - <meta name="fuzzy" content="0-25; 0-4192"> + <meta name="fuzzy" content="maxDifference=0-66;totalPixels=0-4781"> <style type="text/css"> .container { border: double red 1em;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-percentage.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-percentage.html index 000a96a..d4d2bdb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-percentage.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-percentage.html
@@ -6,7 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/css3-background/#border-images"> <link rel="match" href="reference/border-image-repeat-round-ref.html"> <meta name="assert" content="diamonds in corners should be red, and other diamonds should be orange, it should be 4 orange diamonds on each side."> - <meta name="fuzzy" content="0-7; 0-944"> + <meta name="fuzzy" content="maxDifference=0-92;totalPixels=0-3435"> <style type="text/css"> .container { border: double red 1em;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-space-001.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-space-001.html index 9e12567..7af66db7 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-space-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-space-001.html
@@ -6,7 +6,7 @@ <link rel="author" title="Levi Weintraub" href="mailto:leviw@chromium.org"> <link rel="help" href="http://www.w3.org/TR/css3-background/#the-border-image-repeat"> <meta name="assert" content="border-image-repeat: space property spaces out background image that doesn't fit an even number of times."> - <meta name="fuzzy" content="0-12; 0-1152"> + <meta name="fuzzy" content="maxDifference=0-36;totalPixels=0-1728"> <link rel="match" href="reference/border-image-space-001-ref.html"> <style> .borderContainer {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/oklch-010.html b/third_party/blink/web_tests/external/wpt/css/css-color/oklch-010.html index 425f4d8..091b760 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/oklch-010.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/oklch-010.html
@@ -8,7 +8,7 @@ <meta name="assert" content="oklch() with no alpha"> <style> .test { background-color: hsl(120, 100%, 50%); width: 12em; height: 12em; } - .test { background-color: oklch(0% 110 60); } /* l = 0% should always be black */ + .test { background-color: oklch(0% 1.1 60); } /* l = 0% should always be black */ </style> <body> <p>Test passes if you see a black square, and no green.</p>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-color-mix-function.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-color-mix-function.html index 1da6aa4..f000ed6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-color-mix-function.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-color-mix-function.html
@@ -224,70 +224,70 @@ test_computed_value(`color`, `color-mix(in lch, lch(10 20 30deg / none), lch(50 60 70deg / none))`, `lch(30 40 50 / none)`); // oklch() - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg), oklch(50 60 70deg))`, `oklch(30 40 50)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg) 25%, oklch(50 60 70deg))`, `oklch(40 50 60)`); - test_computed_value(`color`, `color-mix(in oklch, 25% oklch(10 20 30deg), oklch(50 60 70deg))`, `oklch(40 50 60)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg), 25% oklch(50 60 70deg))`, `oklch(20 30 40)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg), oklch(50 60 70deg) 25%)`, `oklch(20 30 40)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg) 25%, oklch(50 60 70deg) 75%)`, `oklch(40 50 60)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg) 30%, oklch(50 60 70deg) 90%)`, `oklch(40 50 60)`); // Scale down > 100% sum. - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg) 12.5%, oklch(50 60 70deg) 37.5%)`, `oklch(40 50 60 / 0.5)`); // Scale up < 100% sum, causes alpha multiplication. - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg) 0%, oklch(50 60 70deg))`, `oklch(50 60 70)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(0.5 0.6 70deg))`, `oklch(0.3 0.4 50)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg) 25%, oklch(0.5 0.6 70deg))`, `oklch(0.4 0.5 60)`); + test_computed_value(`color`, `color-mix(in oklch, 25% oklch(0.1 0.2 30deg), oklch(0.5 0.6 70deg))`, `oklch(0.4 0.5 60)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg), 25% oklch(0.5 0.6 70deg))`, `oklch(0.2 0.3 40)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(0.5 0.6 70deg) 25%)`, `oklch(0.2 0.3 40)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg) 25%, oklch(0.5 0.6 70deg) 75%)`, `oklch(0.4 0.5 60)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg) 30%, oklch(0.5 0.6 70deg) 90%)`, `oklch(0.4 0.5 60)`); // Scale down > 100% sum. + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg) 12.5%, oklch(0.5 0.6 70deg) 37.5%)`, `oklch(0.4 0.5 60 / 0.5)`); // Scale up < 100% sum, causes alpha multiplication. + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg) 0%, oklch(0.5 0.6 70deg))`, `oklch(0.5 0.6 70)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4), oklch(50 60 70deg / .8))`, `oklch(36.666664 46.666664 50 / 0.6)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4) 25%, oklch(50 60 70deg / .8))`, `oklch(44.285713 54.285717 60 / 0.7)`); - test_computed_value(`color`, `color-mix(in oklch, 25% oklch(10 20 30deg / .4), oklch(50 60 70deg / .8))`, `oklch(44.285713 54.285717 60 / 0.7)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4), 25% oklch(50 60 70deg / .8))`, `oklch(26 36 40 / 0.5)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4), oklch(50 60 70deg / .8) 25%)`, `oklch(26 36 40 / 0.5)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4) 25%, oklch(50 60 70deg / .8) 75%)`, `oklch(44.285713 54.285717 60 / 0.7)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4) 30%, oklch(50 60 70deg / .8) 90%)`, `oklch(44.285713 54.285717 60 / 0.7)`); // Scale down > 100% sum. - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4) 12.5%, oklch(50 60 70deg / .8) 37.5%)`, `oklch(44.285713 54.285717 60 / 0.35)`); // Scale up < 100% sum, causes alpha multiplication. - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4) 0%, oklch(50 60 70deg / .8))`, `oklch(50 60 70 / 0.8)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4), oklch(0.5 0.6 70deg / .8))`, `oklch(0.36666664 0.46666664 50 / 0.6)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 25%, oklch(0.5 0.6 70deg / .8))`, `oklch(0.44285713 0.54285717 60 / 0.7)`); + test_computed_value(`color`, `color-mix(in oklch, 25% oklch(0.1 0.2 30deg / .4), oklch(0.5 0.6 70deg / .8))`, `oklch(0.44285713 0.54285717 60 / 0.7)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4), 25% oklch(0.5 0.6 70deg / .8))`, `oklch(0.26 0.36 40 / 0.5)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4), oklch(0.5 0.6 70deg / .8) 25%)`, `oklch(0.26 0.36 40 / 0.5)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 25%, oklch(0.5 0.6 70deg / .8) 75%)`, `oklch(0.44285713 0.54285717 60 / 0.7)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 30%, oklch(0.5 0.6 70deg / .8) 90%)`, `oklch(0.44285713 0.54285717 60 / 0.7)`); // Scale down > 100% sum. + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 12.5%, oklch(0.5 0.6 70deg / .8) 37.5%)`, `oklch(0.44285713 0.54285717 60 / 0.35)`); // Scale up < 100% sum, causes alpha multiplication. + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 0%, oklch(0.5 0.6 70deg / .8))`, `oklch(0.5 0.6 70 / 0.8)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(100 0 40deg), oklch(100 0 60deg))`, `oklch(100 0 50)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(100 0 60deg), oklch(100 0 40deg))`, `oklch(100 0 50)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(100 0 50deg), oklch(100 0 330deg))`, `oklch(100 0 10)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(100 0 330deg), oklch(100 0 50deg))`, `oklch(100 0 10)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(100 0 20deg), oklch(100 0 320deg))`, `oklch(100 0 350)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(100 0 320deg), oklch(100 0 20deg))`, `oklch(100 0 350)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(1 0 40deg), oklch(1 0 60deg))`, `oklch(1 0 50)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(1 0 60deg), oklch(1 0 40deg))`, `oklch(1 0 50)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(1 0 50deg), oklch(1 0 330deg))`, `oklch(1 0 10)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(1 0 330deg), oklch(1 0 50deg))`, `oklch(1 0 10)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(1 0 20deg), oklch(1 0 320deg))`, `oklch(1 0 350)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(1 0 320deg), oklch(1 0 20deg))`, `oklch(1 0 350)`); - test_computed_value(`color`, `color-mix(in oklch shorter hue, oklch(100 0 40deg), oklch(100 0 60deg))`, `oklch(100 0 50)`); - test_computed_value(`color`, `color-mix(in oklch shorter hue, oklch(100 0 60deg), oklch(100 0 40deg))`, `oklch(100 0 50)`); - test_computed_value(`color`, `color-mix(in oklch shorter hue, oklch(100 0 50deg), oklch(100 0 330deg))`, `oklch(100 0 10)`); - test_computed_value(`color`, `color-mix(in oklch shorter hue, oklch(100 0 330deg), oklch(100 0 50deg))`, `oklch(100 0 10)`); - test_computed_value(`color`, `color-mix(in oklch shorter hue, oklch(100 0 20deg), oklch(100 0 320deg))`, `oklch(100 0 350)`); - test_computed_value(`color`, `color-mix(in oklch shorter hue, oklch(100 0 320deg), oklch(100 0 20deg))`, `oklch(100 0 350)`); + test_computed_value(`color`, `color-mix(in oklch shorter hue, oklch(1 0 40deg), oklch(1 0 60deg))`, `oklch(1 0 50)`); + test_computed_value(`color`, `color-mix(in oklch shorter hue, oklch(1 0 60deg), oklch(1 0 40deg))`, `oklch(1 0 50)`); + test_computed_value(`color`, `color-mix(in oklch shorter hue, oklch(1 0 50deg), oklch(1 0 330deg))`, `oklch(1 0 10)`); + test_computed_value(`color`, `color-mix(in oklch shorter hue, oklch(1 0 330deg), oklch(1 0 50deg))`, `oklch(1 0 10)`); + test_computed_value(`color`, `color-mix(in oklch shorter hue, oklch(1 0 20deg), oklch(1 0 320deg))`, `oklch(1 0 350)`); + test_computed_value(`color`, `color-mix(in oklch shorter hue, oklch(1 0 320deg), oklch(1 0 20deg))`, `oklch(1 0 350)`); - test_computed_value(`color`, `color-mix(in oklch longer hue, oklch(100 0 40deg), oklch(100 0 60deg))`, `oklch(100 0 230)`); - test_computed_value(`color`, `color-mix(in oklch longer hue, oklch(100 0 60deg), oklch(100 0 40deg))`, `oklch(100 0 230)`); - test_computed_value(`color`, `color-mix(in oklch longer hue, oklch(100 0 50deg), oklch(100 0 330deg))`, `oklch(100 0 190)`); - test_computed_value(`color`, `color-mix(in oklch longer hue, oklch(100 0 330deg), oklch(100 0 50deg))`, `oklch(100 0 190)`); - test_computed_value(`color`, `color-mix(in oklch longer hue, oklch(100 0 20deg), oklch(100 0 320deg))`, `oklch(100 0 170)`); - test_computed_value(`color`, `color-mix(in oklch longer hue, oklch(100 0 320deg), oklch(100 0 20deg))`, `oklch(100 0 170)`); + test_computed_value(`color`, `color-mix(in oklch longer hue, oklch(1 0 40deg), oklch(1 0 60deg))`, `oklch(1 0 230)`); + test_computed_value(`color`, `color-mix(in oklch longer hue, oklch(1 0 60deg), oklch(1 0 40deg))`, `oklch(1 0 230)`); + test_computed_value(`color`, `color-mix(in oklch longer hue, oklch(1 0 50deg), oklch(1 0 330deg))`, `oklch(1 0 190)`); + test_computed_value(`color`, `color-mix(in oklch longer hue, oklch(1 0 330deg), oklch(1 0 50deg))`, `oklch(1 0 190)`); + test_computed_value(`color`, `color-mix(in oklch longer hue, oklch(1 0 20deg), oklch(1 0 320deg))`, `oklch(1 0 170)`); + test_computed_value(`color`, `color-mix(in oklch longer hue, oklch(1 0 320deg), oklch(1 0 20deg))`, `oklch(1 0 170)`); - test_computed_value(`color`, `color-mix(in oklch increasing hue, oklch(100 0 40deg), oklch(100 0 60deg))`, `oklch(100 0 50)`); - test_computed_value(`color`, `color-mix(in oklch increasing hue, oklch(100 0 60deg), oklch(100 0 40deg))`, `oklch(100 0 230)`); - test_computed_value(`color`, `color-mix(in oklch increasing hue, oklch(100 0 50deg), oklch(100 0 330deg))`, `oklch(100 0 190)`); - test_computed_value(`color`, `color-mix(in oklch increasing hue, oklch(100 0 330deg), oklch(100 0 50deg))`, `oklch(100 0 10)`); - test_computed_value(`color`, `color-mix(in oklch increasing hue, oklch(100 0 20deg), oklch(100 0 320deg))`, `oklch(100 0 170)`); - test_computed_value(`color`, `color-mix(in oklch increasing hue, oklch(100 0 320deg), oklch(100 0 20deg))`, `oklch(100 0 350)`); + test_computed_value(`color`, `color-mix(in oklch increasing hue, oklch(1 0 40deg), oklch(1 0 60deg))`, `oklch(1 0 50)`); + test_computed_value(`color`, `color-mix(in oklch increasing hue, oklch(1 0 60deg), oklch(1 0 40deg))`, `oklch(1 0 230)`); + test_computed_value(`color`, `color-mix(in oklch increasing hue, oklch(1 0 50deg), oklch(1 0 330deg))`, `oklch(1 0 190)`); + test_computed_value(`color`, `color-mix(in oklch increasing hue, oklch(1 0 330deg), oklch(1 0 50deg))`, `oklch(1 0 10)`); + test_computed_value(`color`, `color-mix(in oklch increasing hue, oklch(1 0 20deg), oklch(1 0 320deg))`, `oklch(1 0 170)`); + test_computed_value(`color`, `color-mix(in oklch increasing hue, oklch(1 0 320deg), oklch(1 0 20deg))`, `oklch(1 0 350)`); - test_computed_value(`color`, `color-mix(in oklch decreasing hue, oklch(100 0 40deg), oklch(100 0 60deg))`, `oklch(100 0 230)`); - test_computed_value(`color`, `color-mix(in oklch decreasing hue, oklch(100 0 60deg), oklch(100 0 40deg))`, `oklch(100 0 50)`); - test_computed_value(`color`, `color-mix(in oklch decreasing hue, oklch(100 0 50deg), oklch(100 0 330deg))`, `oklch(100 0 10)`); - test_computed_value(`color`, `color-mix(in oklch decreasing hue, oklch(100 0 330deg), oklch(100 0 50deg))`, `oklch(100 0 190)`); - test_computed_value(`color`, `color-mix(in oklch decreasing hue, oklch(100 0 20deg), oklch(100 0 320deg))`, `oklch(100 0 350)`); - test_computed_value(`color`, `color-mix(in oklch decreasing hue, oklch(100 0 320deg), oklch(100 0 20deg))`, `oklch(100 0 170)`); + test_computed_value(`color`, `color-mix(in oklch decreasing hue, oklch(1 0 40deg), oklch(1 0 60deg))`, `oklch(1 0 230)`); + test_computed_value(`color`, `color-mix(in oklch decreasing hue, oklch(1 0 60deg), oklch(1 0 40deg))`, `oklch(1 0 50)`); + test_computed_value(`color`, `color-mix(in oklch decreasing hue, oklch(1 0 50deg), oklch(1 0 330deg))`, `oklch(1 0 10)`); + test_computed_value(`color`, `color-mix(in oklch decreasing hue, oklch(1 0 330deg), oklch(1 0 50deg))`, `oklch(1 0 190)`); + test_computed_value(`color`, `color-mix(in oklch decreasing hue, oklch(1 0 20deg), oklch(1 0 320deg))`, `oklch(1 0 350)`); + test_computed_value(`color`, `color-mix(in oklch decreasing hue, oklch(1 0 320deg), oklch(1 0 20deg))`, `oklch(1 0 170)`); test_computed_value(`color`, `color-mix(in oklch, oklch(none none none), oklch(none none none))`, `oklch(none none none)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(none none none), oklch(50 60 70deg))`, `oklch(50 60 70)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg), oklch(none none none))`, `oklch(10 20 30)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 none), oklch(50 60 70deg))`, `oklch(30 40 70)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg), oklch(50 60 none))`, `oklch(30 40 30)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(none 20 30deg), oklch(50 none 70deg))`, `oklch(50 20 50)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / none), oklch(50 60 70deg))`, `oklch(30 40 50)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / none), oklch(50 60 70deg / 0.5))`, `oklch(30 40 50 / 0.5)`); - test_computed_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / none), oklch(50 60 70deg / none))`, `oklch(30 40 50 / none)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(none none none), oklch(0.5 0.6 70deg))`, `oklch(0.5 0.6 70)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(none none none))`, `oklch(0.1 0.2 30)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 none), oklch(0.5 0.6 70deg))`, `oklch(0.3 0.4 70)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(0.5 0.6 none))`, `oklch(0.3 0.4 30)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(none 0.2 30deg), oklch(0.5 none 70deg))`, `oklch(0.5 0.2 50)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / none), oklch(0.5 0.6 70deg))`, `oklch(0.3 0.4 50)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / none), oklch(0.5 0.6 70deg / 0.5))`, `oklch(0.3 0.4 50 / 0.5)`); + test_computed_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / none), oklch(0.5 0.6 70deg / none))`, `oklch(0.3 0.4 50 / none)`); // lab() test_computed_value(`color`, `color-mix(in lab, lab(10 20 30), lab(50 60 70))`, `lab(30 40 50)`); @@ -321,35 +321,35 @@ test_computed_value(`color`, `color-mix(in lab, lab(10 20 30 / none), lab(50 60 70 / none))`, `lab(30 40 50 / none)`); // oklab() - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30), oklab(50 60 70))`, `oklab(30 40 50)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30) 25%, oklab(50 60 70))`, `oklab(40 50 60)`); - test_computed_value(`color`, `color-mix(in oklab, 25% oklab(10 20 30), oklab(50 60 70))`, `oklab(40 50 60)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30), 25% oklab(50 60 70))`, `oklab(20 30 40)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30), oklab(50 60 70) 25%)`, `oklab(20 30 40)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30) 25%, oklab(50 60 70) 75%)`, `oklab(40 50 60)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30) 30%, oklab(50 60 70) 90%)`, `oklab(40 50 60)`); // Scale down > 100% sum. - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30) 12.5%, oklab(50 60 70) 37.5%)`, `oklab(40 50 60 / 0.5)`); // Scale up < 100% sum, causes alpha multiplication. - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30) 0%, oklab(50 60 70))`, `oklab(50 60 70)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7))`, `oklab(0.3 0.4 0.5)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 25%, oklab(0.5 0.6 0.7))`, `oklab(0.4 0.5 0.6)`); + test_computed_value(`color`, `color-mix(in oklab, 25% oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7))`, `oklab(0.4 0.5 0.6)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3), 25% oklab(0.5 0.6 0.7))`, `oklab(0.2 0.3 0.4)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7) 25%)`, `oklab(0.2 0.3 0.4)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 25%, oklab(0.5 0.6 0.7) 75%)`, `oklab(0.4 0.5 0.6)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 30%, oklab(0.5 0.6 0.7) 90%)`, `oklab(0.4 0.5 0.6)`); // Scale down > 100% sum. + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 12.5%, oklab(0.5 0.6 0.7) 37.5%)`, `oklab(0.4 0.5 0.6 / 0.5)`); // Scale up < 100% sum, causes alpha multiplication. + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 0%, oklab(0.5 0.6 0.7))`, `oklab(0.5 0.6 0.7)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4), oklab(50 60 70 / .8))`, `oklab(36.666664 46.666664 56.666664 / 0.6)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4) 25%, oklab(50 60 70 / .8))`, `oklab(44.285713 54.285717 64.28571 / 0.7)`); - test_computed_value(`color`, `color-mix(in oklab, 25% oklab(10 20 30 / .4), oklab(50 60 70 / .8))`, `oklab(44.285713 54.285717 64.28571 / 0.7)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4), 25% oklab(50 60 70 / .8))`, `oklab(26 36 46 / 0.5)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4), oklab(50 60 70 / .8) 25%)`, `oklab(26 36 46 / 0.5)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4) 25%, oklab(50 60 70 / .8) 75%)`, `oklab(44.285713 54.285717 64.28571 / 0.7)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4) 30%, oklab(50 60 70 / .8) 90%)`, `oklab(44.285713 54.285717 64.28571 / 0.7)`); // Scale down > 100% sum. - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4) 12.5%, oklab(50 60 70 / .8) 37.5%)`, `oklab(44.285713 54.285717 64.28571 / 0.35)`); // Scale up < 100% sum, causes alpha multiplication. - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4) 0%, oklab(50 60 70 / .8))`, `oklab(50 60 70 / 0.8)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4), oklab(0.5 0.6 0.7 / .8))`, `oklab(0.36666664 0.46666664 0.56666664 / 0.6)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 25%, oklab(0.5 0.6 0.7 / .8))`, `oklab(0.44285713 0.54285717 0.6428571 / 0.7)`); + test_computed_value(`color`, `color-mix(in oklab, 25% oklab(0.1 0.2 0.3 / .4), oklab(0.5 0.6 0.7 / .8))`, `oklab(0.44285713 0.54285717 0.6428571 / 0.7)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4), 25% oklab(0.5 0.6 0.7 / .8))`, `oklab(0.26 0.36 0.46 / 0.5)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4), oklab(0.5 0.6 0.7 / .8) 25%)`, `oklab(0.26 0.36 0.46 / 0.5)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 25%, oklab(0.5 0.6 0.7 / .8) 75%)`, `oklab(0.44285713 0.54285717 0.6428571 / 0.7)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 30%, oklab(0.5 0.6 0.7 / .8) 90%)`, `oklab(0.44285713 0.54285717 0.6428571 / 0.7)`); // Scale down > 100% sum. + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 12.5%, oklab(0.5 0.6 0.7 / .8) 37.5%)`, `oklab(0.44285713 0.54285717 0.6428571 / 0.35)`); // Scale up < 100% sum, causes alpha multiplication. + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 0%, oklab(0.5 0.6 0.7 / .8))`, `oklab(0.5 0.6 0.7 / 0.8)`); test_computed_value(`color`, `color-mix(in oklab, oklab(none none none), oklab(none none none))`, `oklab(none none none)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(none none none), oklab(50 60 70))`, `oklab(50 60 70)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30), oklab(none none none))`, `oklab(10 20 30)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 none), oklab(50 60 70))`, `oklab(30 40 70)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30), oklab(50 60 none))`, `oklab(30 40 30)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(none 20 30), oklab(50 none 70))`, `oklab(50 20 50)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30 / none), oklab(50 60 70))`, `oklab(30 40 50)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30 / none), oklab(50 60 70 / 0.5))`, `oklab(30 40 50 / 0.5)`); - test_computed_value(`color`, `color-mix(in oklab, oklab(10 20 30 / none), oklab(50 60 70 / none))`, `oklab(30 40 50 / none)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(none none none), oklab(0.5 0.6 0.7))`, `oklab(0.5 0.6 0.7)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(none none none))`, `oklab(0.1 0.2 0.3)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 none), oklab(0.5 0.6 0.7))`, `oklab(0.3 0.4 0.7)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 none))`, `oklab(0.3 0.4 0.3)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(none 0.2 0.3), oklab(0.5 none 0.7))`, `oklab(0.5 0.2 0.5)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7))`, `oklab(0.3 0.4 0.5)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7 / 0.5))`, `oklab(0.3 0.4 0.5 / 0.5)`); + test_computed_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7 / none))`, `oklab(0.3 0.4 0.5 / none)`); for (const colorSpace of [ "srgb", "srgb-linear", "xyz", "xyz-d50", "xyz-d65" ]) {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-lab-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-lab-expected.txt new file mode 100644 index 0000000..7d4cde8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-lab-expected.txt
@@ -0,0 +1,100 @@ +This is a testharness.js-based test. +Found 96 tests; 90 PASS, 6 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS Property color value 'lab(0 0 0)' +PASS Property color value 'lab(0 0 0 / 1)' +PASS Property color value 'lab(0 0 0 / 0.5)' +PASS Property color value 'lab(20 0 10/0.5)' +PASS Property color value 'lab(20 0 10/50%)' +FAIL Property color value 'lab(400 0 10/50%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 100 +/- 0.0001, expected 100 but got 400 +PASS Property color value 'lab(50 -160 160)' +PASS Property color value 'lab(50 -200 200)' +PASS Property color value 'lab(0 0 0 / -10%)' +PASS Property color value 'lab(0 0 0 / 110%)' +PASS Property color value 'lab(0 0 0 / 300%)' +PASS Property color value 'lab(-40 0 0)' +PASS Property color value 'lab(50 -20 0)' +PASS Property color value 'lab(50 0 -20)' +FAIL Property color value 'lab(calc(50 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 100 +/- 0.0001, expected 100 but got 150 +PASS Property color value 'lab(calc(-50 * 3) calc(0.5 + 1) calc(-1.5) / calc(-0.5 * 2))' +PASS Property color value 'lab(none none none / none)' +PASS Property color value 'lab(none none none)' +PASS Property color value 'lab(20 none none / none)' +PASS Property color value 'lab(none none none / 0.5)' +PASS Property color value 'lab(0 0 0 / none)' +PASS Property color value 'oklab(0 0 0)' +PASS Property color value 'oklab(0 0 0 / 1)' +PASS Property color value 'oklab(0 0 0 / 0.5)' +PASS Property color value 'oklab(0.2 0 0.1/0.5)' +PASS Property color value 'oklab(0.2 0 0.1/50%)' +FAIL Property color value 'oklab(4 0 0.1/50%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 1 +/- 0.0001, expected 1 but got 4 +PASS Property color value 'oklab(0.5 -1.6 1.6)' +PASS Property color value 'oklab(0.5 -2 2)' +PASS Property color value 'oklab(0 0 0 / -10%)' +PASS Property color value 'oklab(0 0 0 / 110%)' +PASS Property color value 'oklab(0 0 0 / 300%)' +PASS Property color value 'oklab(-0.4 0 0)' +PASS Property color value 'oklab(0.5 -0.2 0)' +PASS Property color value 'oklab(0.5 0 -0.2)' +FAIL Property color value 'oklab(calc(0.5 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 1 +/- 0.0001, expected 1 but got 1.5 +PASS Property color value 'oklab(calc(-0.5 * 3) calc(0.5 + 1) calc(-1.5) / calc(-0.5 * 2))' +PASS Property color value 'oklab(none none none / none)' +PASS Property color value 'oklab(none none none)' +PASS Property color value 'oklab(0.2 none none / none)' +PASS Property color value 'oklab(none none none / 0.5)' +PASS Property color value 'oklab(0 0 0 / none)' +PASS Property color value 'lab(20% 0 10/0.5)' +PASS Property color value 'oklab(20% 0 0.1/0.5)' +PASS Property color value 'lch(0 0 0deg)' +PASS Property color value 'lch(0 0 0deg / 1)' +PASS Property color value 'lch(0 0 0deg / 0.5)' +PASS Property color value 'lch(100 230 0deg / 0.5)' +PASS Property color value 'lch(20 50 20deg/0.5)' +PASS Property color value 'lch(20 50 20deg/50%)' +PASS Property color value 'lch(10 20 20deg / -10%)' +PASS Property color value 'lch(10 20 20deg / 110%)' +PASS Property color value 'lch(10 20 1.28rad)' +PASS Property color value 'lch(10 20 380deg)' +PASS Property color value 'lch(10 20 -340deg)' +PASS Property color value 'lch(10 20 740deg)' +PASS Property color value 'lch(10 20 -700deg)' +PASS Property color value 'lch(-40 0 0)' +PASS Property color value 'lch(20 -20 0)' +PASS Property color value 'lch(0 0 0 / 0.5)' +PASS Property color value 'lch(10 20 20 / 110%)' +PASS Property color value 'lch(10 20 -700)' +FAIL Property color value 'lch(calc(50 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 100 +/- 0.0001, expected 100 but got 150 +PASS Property color value 'lch(calc(-50 * 3) calc(0.5 + 1) calc(-20deg * 2) / calc(-0.5 * 2))' +PASS Property color value 'lch(none none none / none)' +PASS Property color value 'lch(none none none)' +PASS Property color value 'lch(20 none none / none)' +PASS Property color value 'lch(none none none / 0.5)' +PASS Property color value 'lch(0 0 0 / none)' +PASS Property color value 'oklch(0 0 0deg)' +PASS Property color value 'oklch(0 0 0deg / 1)' +PASS Property color value 'oklch(0 0 0deg / 0.5)' +PASS Property color value 'oklch(1 2.3 0deg / 0.5)' +PASS Property color value 'oklch(0.2 0.5 20deg/0.5)' +PASS Property color value 'oklch(0.2 0.5 20deg/50%)' +PASS Property color value 'oklch(0.1 0.2 20deg / -10%)' +PASS Property color value 'oklch(0.1 0.2 20deg / 110%)' +PASS Property color value 'oklch(0.1 0.2 1.28rad)' +PASS Property color value 'oklch(0.1 0.2 380deg)' +PASS Property color value 'oklch(0.1 0.2 -340deg)' +PASS Property color value 'oklch(0.1 0.2 740deg)' +PASS Property color value 'oklch(0.1 0.2 -700deg)' +PASS Property color value 'oklch(-0.4 0 0)' +PASS Property color value 'oklch(0.2 -0.2 0)' +PASS Property color value 'oklch(0 0 0 / 0.5)' +PASS Property color value 'oklch(0.1 0.2 20 / 110%)' +PASS Property color value 'oklch(0.1 0.2 -700)' +FAIL Property color value 'oklch(calc(0.5 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 1 +/- 0.0001, expected 1 but got 1.5 +PASS Property color value 'oklch(calc(-0.5 * 3) calc(0.5 + 1) calc(-20deg * 2) / calc(-0.5 * 2))' +PASS Property color value 'oklch(none none none / none)' +PASS Property color value 'oklch(none none none)' +PASS Property color value 'oklch(0.2 none none / none)' +PASS Property color value 'oklch(none none none / 0.5)' +PASS Property color value 'oklch(0 0 0 / none)' +PASS Property color value 'lch(20% 0 10/0.5)' +PASS Property color value 'oklch(20% 0 10/0.5)' +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-lab.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-lab.html index 45a1f9a..c25e1253 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-lab.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-lab.html
@@ -29,7 +29,7 @@ test_computed_value("color", "lab(0 0 0 / 0.5)", "lab(0 0 0 / 0.5)"); test_computed_value("color", "lab(20 0 10/0.5)", "lab(20 0 10 / 0.5)"); test_computed_value("color", "lab(20 0 10/50%)", "lab(20 0 10 / 0.5)"); -test_computed_value("color", "lab(400 0 10/50%)", "lab(400 0 10 / 0.5)"); +test_computed_value("color", "lab(400 0 10/50%)", "lab(100 0 10 / 0.5)"); test_computed_value("color", "lab(50 -160 160)", "lab(50 -160 160)"); test_computed_value("color", "lab(50 -200 200)", "lab(50 -200 200)"); test_computed_value("color", "lab(0 0 0 / -10%)", "lab(0 0 0 / 0)"); @@ -38,7 +38,7 @@ test_computed_value("color", "lab(-40 0 0)", "lab(0 0 0)"); test_computed_value("color", "lab(50 -20 0)", "lab(50 -20 0)"); test_computed_value("color", "lab(50 0 -20)", "lab(50 0 -20)"); -test_computed_value("color", "lab(calc(50 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))", "lab(150 -0.5 1.5 / 0.5)"); +test_computed_value("color", "lab(calc(50 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))", "lab(100 -0.5 1.5 / 0.5)"); test_computed_value("color", "lab(calc(-50 * 3) calc(0.5 + 1) calc(-1.5) / calc(-0.5 * 2))", "lab(0 1.5 -1.5 / 0)"); test_computed_value("color", "lab(none none none / none)", "lab(none none none / none)"); @@ -51,29 +51,29 @@ test_computed_value("color", "oklab(0 0 0)", "oklab(0 0 0)"); test_computed_value("color", "oklab(0 0 0 / 1)", "oklab(0 0 0)"); test_computed_value("color", "oklab(0 0 0 / 0.5)", "oklab(0 0 0 / 0.5)"); -test_computed_value("color", "oklab(20 0 10/0.5)", "oklab(20 0 10 / 0.5)"); -test_computed_value("color", "oklab(20 0 10/50%)", "oklab(20 0 10 / 0.5)"); -test_computed_value("color", "oklab(400 0 10/50%)", "oklab(400 0 10 / 0.5)"); -test_computed_value("color", "oklab(50 -160 160)", "oklab(50 -160 160)"); -test_computed_value("color", "oklab(50 -200 200)", "oklab(50 -200 200)"); +test_computed_value("color", "oklab(0.2 0 0.1/0.5)", "oklab(0.2 0 0.1 / 0.5)"); +test_computed_value("color", "oklab(0.2 0 0.1/50%)", "oklab(0.2 0 0.1 / 0.5)"); +test_computed_value("color", "oklab(4 0 0.1/50%)", "oklab(1 0 0.1 / 0.5)"); +test_computed_value("color", "oklab(0.5 -1.6 1.6)", "oklab(0.5 -1.6 1.6)"); +test_computed_value("color", "oklab(0.5 -2 2)", "oklab(0.5 -2 2)"); test_computed_value("color", "oklab(0 0 0 / -10%)", "oklab(0 0 0 / 0)"); test_computed_value("color", "oklab(0 0 0 / 110%)", "oklab(0 0 0)"); test_computed_value("color", "oklab(0 0 0 / 300%)", "oklab(0 0 0)"); -test_computed_value("color", "oklab(-40 0 0)", "oklab(0 0 0)"); -test_computed_value("color", "oklab(50 -20 0)", "oklab(50 -20 0)"); -test_computed_value("color", "oklab(50 0 -20)", "oklab(50 0 -20)"); -test_computed_value("color", "oklab(calc(50 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))", "oklab(150 -0.5 1.5 / 0.5)"); -test_computed_value("color", "oklab(calc(-50 * 3) calc(0.5 + 1) calc(-1.5) / calc(-0.5 * 2))", "oklab(0 1.5 -1.5 / 0)"); +test_computed_value("color", "oklab(-0.4 0 0)", "oklab(0 0 0)"); +test_computed_value("color", "oklab(0.5 -0.2 0)", "oklab(0.5 -0.2 0)"); +test_computed_value("color", "oklab(0.5 0 -0.2)", "oklab(0.5 0 -0.2)"); +test_computed_value("color", "oklab(calc(0.5 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))", "oklab(1 -0.5 1.5 / 0.5)"); +test_computed_value("color", "oklab(calc(-0.5 * 3) calc(0.5 + 1) calc(-1.5) / calc(-0.5 * 2))", "oklab(0 1.5 -1.5 / 0)"); test_computed_value("color", "oklab(none none none / none)", "oklab(none none none / none)"); test_computed_value("color", "oklab(none none none)", "oklab(none none none)"); -test_computed_value("color", "oklab(20 none none / none)", "oklab(20 none none / none)"); +test_computed_value("color", "oklab(0.2 none none / none)", "oklab(0.2 none none / none)"); test_computed_value("color", "oklab(none none none / 0.5)", "oklab(none none none / 0.5)"); test_computed_value("color", "oklab(0 0 0 / none)", "oklab(0 0 0 / none)"); // These tests validate that lab lightness range is 0-100 and oklab lightness range is 0.0-1.0. test_computed_value("color", "lab(20% 0 10/0.5)", "lab(20 0 10 / 0.5)"); -test_computed_value("color", "oklab(20% 0 10/0.5)", "oklab(0.2 0 10 / 0.5)"); +test_computed_value("color", "oklab(20% 0 0.1/0.5)", "oklab(0.2 0 0.1 / 0.5)"); // lch() test_computed_value("color", "lch(0 0 0deg)", "lch(0 0 0)"); @@ -94,7 +94,7 @@ test_computed_value("color", "lch(0 0 0 / 0.5)", "lch(0 0 0 / 0.5)"); test_computed_value("color", "lch(10 20 20 / 110%)", "lch(10 20 20)"); test_computed_value("color", "lch(10 20 -700)", "lch(10 20 20)"); -test_computed_value("color", "lch(calc(50 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))", "lch(150 0 40 / 0.5)"); +test_computed_value("color", "lch(calc(50 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))", "lch(100 0 40 / 0.5)"); test_computed_value("color", "lch(calc(-50 * 3) calc(0.5 + 1) calc(-20deg * 2) / calc(-0.5 * 2))", "lch(0 1.5 320 / 0)"); test_computed_value("color", "lch(none none none / none)", "lch(none none none / none)"); @@ -107,27 +107,27 @@ test_computed_value("color", "oklch(0 0 0deg)", "oklch(0 0 0)"); test_computed_value("color", "oklch(0 0 0deg / 1)", "oklch(0 0 0)"); test_computed_value("color", "oklch(0 0 0deg / 0.5)", "oklch(0 0 0 / 0.5)"); -test_computed_value("color", "oklch(100 230 0deg / 0.5)", "oklch(100 230 0 / 0.5)"); -test_computed_value("color", "oklch(20 50 20deg/0.5)", "oklch(20 50 20 / 0.5)"); -test_computed_value("color", "oklch(20 50 20deg/50%)", "oklch(20 50 20 / 0.5)"); -test_computed_value("color", "oklch(10 20 20deg / -10%)", "oklch(10 20 20 / 0)"); -test_computed_value("color", "oklch(10 20 20deg / 110%)", "oklch(10 20 20)"); -test_computed_value("color", "oklch(10 20 1.28rad)", "oklch(10 20 73.3386)"); -test_computed_value("color", "oklch(10 20 380deg)", "oklch(10 20 20)"); -test_computed_value("color", "oklch(10 20 -340deg)", "oklch(10 20 20)"); -test_computed_value("color", "oklch(10 20 740deg)", "oklch(10 20 20)"); -test_computed_value("color", "oklch(10 20 -700deg)", "oklch(10 20 20)"); -test_computed_value("color", "oklch(-40 0 0)", "oklch(0 0 0)"); -test_computed_value("color", "oklch(20 -20 0)", "oklch(20 0 0)"); +test_computed_value("color", "oklch(1 2.3 0deg / 0.5)", "oklch(1 2.3 0 / 0.5)"); +test_computed_value("color", "oklch(0.2 0.5 20deg/0.5)", "oklch(0.2 0.5 20 / 0.5)"); +test_computed_value("color", "oklch(0.2 0.5 20deg/50%)", "oklch(0.2 0.5 20 / 0.5)"); +test_computed_value("color", "oklch(0.1 0.2 20deg / -10%)", "oklch(0.1 0.2 20 / 0)"); +test_computed_value("color", "oklch(0.1 0.2 20deg / 110%)", "oklch(0.1 0.2 20)"); +test_computed_value("color", "oklch(0.1 0.2 1.28rad)", "oklch(0.1 0.2 73.3386)"); +test_computed_value("color", "oklch(0.1 0.2 380deg)", "oklch(0.1 0.2 20)"); +test_computed_value("color", "oklch(0.1 0.2 -340deg)", "oklch(0.1 0.2 20)"); +test_computed_value("color", "oklch(0.1 0.2 740deg)", "oklch(0.1 0.2 20)"); +test_computed_value("color", "oklch(0.1 0.2 -700deg)", "oklch(0.1 0.2 20)"); +test_computed_value("color", "oklch(-0.4 0 0)", "oklch(0 0 0)"); +test_computed_value("color", "oklch(0.2 -0.2 0)", "oklch(0.2 0 0)"); test_computed_value("color", "oklch(0 0 0 / 0.5)", "oklch(0 0 0 / 0.5)"); -test_computed_value("color", "oklch(10 20 20 / 110%)", "oklch(10 20 20)"); -test_computed_value("color", "oklch(10 20 -700)", "oklch(10 20 20)"); -test_computed_value("color", "oklch(calc(50 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))", "oklch(150 0 40 / 0.5)"); -test_computed_value("color", "oklch(calc(-50 * 3) calc(0.5 + 1) calc(-20deg * 2) / calc(-0.5 * 2))", "oklch(0 1.5 320 / 0)"); +test_computed_value("color", "oklch(0.1 0.2 20 / 110%)", "oklch(0.1 0.2 20)"); +test_computed_value("color", "oklch(0.1 0.2 -700)", "oklch(0.1 0.2 20)"); +test_computed_value("color", "oklch(calc(0.5 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))", "oklch(1 0 40 / 0.5)"); +test_computed_value("color", "oklch(calc(-0.5 * 3) calc(0.5 + 1) calc(-20deg * 2) / calc(-0.5 * 2))", "oklch(0 1.5 320 / 0)"); test_computed_value("color", "oklch(none none none / none)", "oklch(none none none / none)"); test_computed_value("color", "oklch(none none none)", "oklch(none none none)"); -test_computed_value("color", "oklch(20 none none / none)", "oklch(20 none none / none)"); +test_computed_value("color", "oklch(0.2 none none / none)", "oklch(0.2 none none / none)"); test_computed_value("color", "oklch(none none none / 0.5)", "oklch(none none none / 0.5)"); test_computed_value("color", "oklch(0 0 0 / none)", "oklch(0 0 0 / none)");
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-lab.html.ini b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-lab.html.ini new file mode 100644 index 0000000..0b52cae --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-lab.html.ini
@@ -0,0 +1,18 @@ +[color-computed-lab.html] + [Property color value 'lab(400 0 10/50%)'] + expected: FAIL + + [Property color value 'lab(calc(50 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))'] + expected: FAIL + + [Property color value 'lch(calc(50 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))'] + expected: FAIL + + [Property color value 'oklab(4 0 0.1/50%)'] + expected: FAIL + + [Property color value 'oklab(calc(0.5 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))'] + expected: FAIL + + [Property color value 'oklch(calc(0.5 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))'] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color-expected.txt index 60fb88f5..be758f7 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color-expected.txt
@@ -10,9 +10,9 @@ FAIL Property color value 'rgb(from lab(0 104.3 -50.9) r g b)' assert_true: 'rgb(from lab(0 104.3 -50.9) r g b)' is a supported value for color. expected true got false FAIL Property color value 'rgb(from lch(100 116 334) r g b)' assert_true: 'rgb(from lch(100 116 334) r g b)' is a supported value for color. expected true got false FAIL Property color value 'rgb(from lch(0 116 334) r g b)' assert_true: 'rgb(from lch(0 116 334) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from oklab(100 0.365 -0.16) r g b)' assert_true: 'rgb(from oklab(100 0.365 -0.16) r g b)' is a supported value for color. expected true got false +FAIL Property color value 'rgb(from oklab(1 0.365 -0.16) r g b)' assert_true: 'rgb(from oklab(1 0.365 -0.16) r g b)' is a supported value for color. expected true got false FAIL Property color value 'rgb(from oklab(0 0.365 -0.16) r g b)' assert_true: 'rgb(from oklab(0 0.365 -0.16) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from oklch(100 0.399 336.3) r g b)' assert_true: 'rgb(from oklch(100 0.399 336.3) r g b)' is a supported value for color. expected true got false +FAIL Property color value 'rgb(from oklch(1 0.399 336.3) r g b)' assert_true: 'rgb(from oklch(1 0.399 336.3) r g b)' is a supported value for color. expected true got false FAIL Property color value 'rgb(from oklch(0 0.399 336.3) r g b)' assert_true: 'rgb(from oklch(0 0.399 336.3) r g b)' is a supported value for color. expected true got false FAIL Property color value 'rgb(from rebeccapurple 0 0 0)' assert_true: 'rgb(from rebeccapurple 0 0 0)' is a supported value for color. expected true got false FAIL Property color value 'rgb(from rebeccapurple 0 0 0 / 0)' assert_true: 'rgb(from rebeccapurple 0 0 0 / 0)' is a supported value for color. expected true got false @@ -87,9 +87,9 @@ FAIL Property color value 'hsl(from lab(0 104.3 -50.9) h s l)' assert_true: 'hsl(from lab(0 104.3 -50.9) h s l)' is a supported value for color. expected true got false FAIL Property color value 'hsl(from lch(100 116 334) h s l)' assert_true: 'hsl(from lch(100 116 334) h s l)' is a supported value for color. expected true got false FAIL Property color value 'hsl(from lch(0 116 334) h s l)' assert_true: 'hsl(from lch(0 116 334) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from oklab(100 0.365 -0.16) h s l)' assert_true: 'hsl(from oklab(100 0.365 -0.16) h s l)' is a supported value for color. expected true got false +FAIL Property color value 'hsl(from oklab(1 0.365 -0.16) h s l)' assert_true: 'hsl(from oklab(1 0.365 -0.16) h s l)' is a supported value for color. expected true got false FAIL Property color value 'hsl(from oklab(0 0.365 -0.16) h s l)' assert_true: 'hsl(from oklab(0 0.365 -0.16) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from oklch(100 0.399 336.3) h s l)' assert_true: 'hsl(from oklch(100 0.399 336.3) h s l)' is a supported value for color. expected true got false +FAIL Property color value 'hsl(from oklch(1 0.399 336.3) h s l)' assert_true: 'hsl(from oklch(1 0.399 336.3) h s l)' is a supported value for color. expected true got false FAIL Property color value 'hsl(from oklch(0 0.399 336.3) h s l)' assert_true: 'hsl(from oklch(0 0.399 336.3) h s l)' is a supported value for color. expected true got false FAIL Property color value 'hsl(from rebeccapurple 0 0% 0%)' assert_true: 'hsl(from rebeccapurple 0 0% 0%)' is a supported value for color. expected true got false FAIL Property color value 'hsl(from rebeccapurple 0deg 0% 0%)' assert_true: 'hsl(from rebeccapurple 0deg 0% 0%)' is a supported value for color. expected true got false @@ -149,9 +149,9 @@ FAIL Property color value 'hwb(from lab(0 104.3 -50.9) h w b)' assert_true: 'hwb(from lab(0 104.3 -50.9) h w b)' is a supported value for color. expected true got false FAIL Property color value 'hwb(from lch(100 116 334) h w b)' assert_true: 'hwb(from lch(100 116 334) h w b)' is a supported value for color. expected true got false FAIL Property color value 'hwb(from lch(0 116 334) h w b)' assert_true: 'hwb(from lch(0 116 334) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from oklab(100 0.365 -0.16) h w b)' assert_true: 'hwb(from oklab(100 0.365 -0.16) h w b)' is a supported value for color. expected true got false +FAIL Property color value 'hwb(from oklab(1 0.365 -0.16) h w b)' assert_true: 'hwb(from oklab(1 0.365 -0.16) h w b)' is a supported value for color. expected true got false FAIL Property color value 'hwb(from oklab(0 0.365 -0.16) h w b)' assert_true: 'hwb(from oklab(0 0.365 -0.16) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from oklch(100 0.399 336.3) h w b)' assert_true: 'hwb(from oklch(100 0.399 336.3) h w b)' is a supported value for color. expected true got false +FAIL Property color value 'hwb(from oklch(1 0.399 336.3) h w b)' assert_true: 'hwb(from oklch(1 0.399 336.3) h w b)' is a supported value for color. expected true got false FAIL Property color value 'hwb(from oklch(0 0.399 336.3) h w b)' assert_true: 'hwb(from oklch(0 0.399 336.3) h w b)' is a supported value for color. expected true got false FAIL Property color value 'hwb(from rebeccapurple 0 0% 0%)' assert_true: 'hwb(from rebeccapurple 0 0% 0%)' is a supported value for color. expected true got false FAIL Property color value 'hwb(from rebeccapurple 0deg 0% 0%)' assert_true: 'hwb(from rebeccapurple 0deg 0% 0%)' is a supported value for color. expected true got false @@ -245,62 +245,62 @@ FAIL Property color value 'lab(from lab(none none none / none) l a b / alpha)' assert_true: 'lab(from lab(none none none / none) l a b / alpha)' is a supported value for color. expected true got false FAIL Property color value 'lab(from lab(25 none 50) l a b)' assert_true: 'lab(from lab(25 none 50) l a b)' is a supported value for color. expected true got false FAIL Property color value 'lab(from lab(25 20 50 / none) l a b / alpha)' assert_true: 'lab(from lab(25 20 50 / none) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l a b)' assert_true: 'oklab(from oklab(25 20 50) l a b)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l a b / alpha)' assert_true: 'oklab(from oklab(25 20 50) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) l a b / alpha)' assert_true: 'oklab(from oklab(25 20 50 / 40%) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(200 300 400 / 500%) l a b / alpha)' assert_true: 'oklab(from oklab(200 300 400 / 500%) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(-200 -300 -400 / -500%) l a b / alpha)' assert_true: 'oklab(from oklab(-200 -300 -400 / -500%) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(from oklab(25 20 50) l a b) l a b)' assert_true: 'oklab(from oklab(from oklab(25 20 50) l a b) l a b)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a b)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(2 3 4 / 500%) l a b / alpha)' assert_true: 'oklab(from oklab(2 3 4 / 500%) l a b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(-2 -3 -4 / -500%) l a b / alpha)' assert_true: 'oklab(from oklab(-2 -3 -4 / -500%) l a b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(from oklab(0.25 0.2 0.5) l a b) l a b)' assert_true: 'oklab(from oklab(from oklab(0.25 0.2 0.5) l a b) l a b)' is a supported value for color. expected true got false FAIL Property color value 'oklab(from color(display-p3 0 0 0) l a b / alpha)' assert_true: 'oklab(from color(display-p3 0 0 0) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) 0 0 0)' assert_true: 'oklab(from oklab(25 20 50) 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) 0 0 0 / 0)' assert_true: 'oklab(from oklab(25 20 50) 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) 0 a b / alpha)' assert_true: 'oklab(from oklab(25 20 50) 0 a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l 0 b / alpha)' assert_true: 'oklab(from oklab(25 20 50) l 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l a 0 / alpha)' assert_true: 'oklab(from oklab(25 20 50) l a 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l a b / 0)' assert_true: 'oklab(from oklab(25 20 50) l a b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) 0 a b / alpha)' assert_true: 'oklab(from oklab(25 20 50 / 40%) 0 a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) l 0 b / alpha)' assert_true: 'oklab(from oklab(25 20 50 / 40%) l 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) l a 0 / alpha)' assert_true: 'oklab(from oklab(25 20 50 / 40%) l a 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) l a b / 0)' assert_true: 'oklab(from oklab(25 20 50 / 40%) l a b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) 35 a b / alpha)' assert_true: 'oklab(from oklab(25 20 50) 35 a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l 35 b / alpha)' assert_true: 'oklab(from oklab(25 20 50) l 35 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l a 35 / alpha)' assert_true: 'oklab(from oklab(25 20 50) l a 35 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l a b / .35)' assert_true: 'oklab(from oklab(25 20 50) l a b / .35)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) 35 a b / alpha)' assert_true: 'oklab(from oklab(25 20 50 / 40%) 35 a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) l 35 b / alpha)' assert_true: 'oklab(from oklab(25 20 50 / 40%) l 35 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) l a 35 / alpha)' assert_true: 'oklab(from oklab(25 20 50 / 40%) l a 35 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) l a b / .35)' assert_true: 'oklab(from oklab(25 20 50 / 40%) l a b / .35)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.7 45 30 / 40%) 200 300 400 / 500)' assert_true: 'oklab(from oklab(0.7 45 30 / 40%) 200 300 400 / 500)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.7 45 30 / 40%) -200 -300 -400 / -500)' assert_true: 'oklab(from oklab(0.7 45 30 / 40%) -200 -300 -400 / -500)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l b a)' assert_true: 'oklab(from oklab(25 20 50) l b a)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l a a / a)' assert_true: 'oklab(from oklab(25 20 50) l a a / a)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) l b a)' assert_true: 'oklab(from oklab(25 20 50 / 40%) l b a)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) l a a / a)' assert_true: 'oklab(from oklab(25 20 50 / 40%) l a a / a)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) calc(l) calc(a) calc(b))' assert_true: 'oklab(from oklab(25 20 50) calc(l) calc(a) calc(b))' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))' assert_true: 'oklab(from oklab(25 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) none none none)' assert_true: 'oklab(from oklab(25 20 50) none none none)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) none none none / none)' assert_true: 'oklab(from oklab(25 20 50) none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l a none)' assert_true: 'oklab(from oklab(25 20 50) l a none)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l a none / alpha)' assert_true: 'oklab(from oklab(25 20 50) l a none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50) l a b / none)' assert_true: 'oklab(from oklab(25 20 50) l a b / none)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) l a none / alpha)' assert_true: 'oklab(from oklab(25 20 50 / 40%) l a none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / 40%) l a b / none)' assert_true: 'oklab(from oklab(25 20 50 / 40%) l a b / none)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) 0 0 0)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) 0 0 0)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) 0 0 0 / 0)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) 0 0 0 / 0)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) 0 a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) 0 a b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l 0 b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l 0 b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a 0 / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a 0 / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / 0)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a b / 0)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) 0 a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) 0 a b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l 0 b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l 0 b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0 / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0 / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / 0)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / 0)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) 0.35 a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) 0.35 a b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l 0.35 b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l 0.35 b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a 0.35 / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a 0.35 / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / .35)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a b / .35)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) 0.35 a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) 0.35 a b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l 0.35 b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l 0.35 b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0.35 / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0.35 / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / .35)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / .35)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.7 0.45 0.3 / 40%) 2 3 4 / 500)' assert_true: 'oklab(from oklab(0.7 0.45 0.3 / 40%) 2 3 4 / 500)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.7 0.45 0.3 / 40%) -2 -3 -4 / -500)' assert_true: 'oklab(from oklab(0.7 0.45 0.3 / 40%) -2 -3 -4 / -500)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l b a)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l b a)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a a / a)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a a / a)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l b a)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l b a)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a a / a)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a a / a)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))' assert_true: 'oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) none none none)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) none none none)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) none none none / none)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) none none none / none)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a none)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a none)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a none / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a none / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / none)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a b / none)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a none / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a none / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / none)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / none)' is a supported value for color. expected true got false FAIL Property color value 'oklab(from oklab(none none none) l a b)' assert_true: 'oklab(from oklab(none none none) l a b)' is a supported value for color. expected true got false FAIL Property color value 'oklab(from oklab(none none none / none) l a b / alpha)' assert_true: 'oklab(from oklab(none none none / none) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 none 50) l a b)' assert_true: 'oklab(from oklab(25 none 50) l a b)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(25 20 50 / none) l a b / alpha)' assert_true: 'oklab(from oklab(25 20 50 / none) l a b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 none 0.5) l a b)' assert_true: 'oklab(from oklab(0.25 none 0.5) l a b)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / none) l a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / none) l a b / alpha)' is a supported value for color. expected true got false FAIL Property color value 'lab(from lab(.7 45 30) alpha b a / l)' assert_true: 'lab(from lab(.7 45 30) alpha b a / l)' is a supported value for color. expected true got false FAIL Property color value 'lab(from lab(.7 45 30) alpha a b / alpha)' assert_true: 'lab(from lab(.7 45 30) alpha a b / alpha)' is a supported value for color. expected true got false FAIL Property color value 'lab(from lab(.7 45 30) alpha a a / alpha)' assert_true: 'lab(from lab(.7 45 30) alpha a a / alpha)' is a supported value for color. expected true got false FAIL Property color value 'lab(from lab(.7 45 30 / 40%) alpha b a / l)' assert_true: 'lab(from lab(.7 45 30 / 40%) alpha b a / l)' is a supported value for color. expected true got false FAIL Property color value 'lab(from lab(.7 45 30 / 40%) alpha a b / alpha)' assert_true: 'lab(from lab(.7 45 30 / 40%) alpha a b / alpha)' is a supported value for color. expected true got false FAIL Property color value 'lab(from lab(.7 45 30 / 40%) alpha a a / alpha)' assert_true: 'lab(from lab(.7 45 30 / 40%) alpha a a / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(.7 45 30) alpha b a / l)' assert_true: 'oklab(from oklab(.7 45 30) alpha b a / l)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(.7 45 30) alpha a b / alpha)' assert_true: 'oklab(from oklab(.7 45 30) alpha a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(.7 45 30) alpha a a / alpha)' assert_true: 'oklab(from oklab(.7 45 30) alpha a a / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(.7 45 30 / 40%) alpha b a / l)' assert_true: 'oklab(from oklab(.7 45 30 / 40%) alpha b a / l)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(.7 45 30 / 40%) alpha a b / alpha)' assert_true: 'oklab(from oklab(.7 45 30 / 40%) alpha a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(.7 45 30 / 40%) alpha a a / alpha)' assert_true: 'oklab(from oklab(.7 45 30 / 40%) alpha a a / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(.7 0.45 0.3) alpha b a / l)' assert_true: 'oklab(from oklab(.7 0.45 0.3) alpha b a / l)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(.7 0.45 0.3) alpha a b / alpha)' assert_true: 'oklab(from oklab(.7 0.45 0.3) alpha a b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(.7 0.45 0.3) alpha a a / alpha)' assert_true: 'oklab(from oklab(.7 0.45 0.3) alpha a a / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha b a / l)' assert_true: 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha b a / l)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha a b / alpha)' assert_true: 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha a b / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha a a / alpha)' assert_true: 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha a a / alpha)' is a supported value for color. expected true got false FAIL Property color value 'lch(from lch(0.7 45 30) l c h)' assert_true: 'lch(from lch(0.7 45 30) l c h)' is a supported value for color. expected true got false FAIL Property color value 'lch(from lch(0.7 45 30) l c h / alpha)' assert_true: 'lch(from lch(0.7 45 30) l c h / alpha)' is a supported value for color. expected true got false FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) l c h / alpha)' assert_true: 'lch(from lch(0.7 45 30 / 40%) l c h / alpha)' is a supported value for color. expected true got false @@ -352,69 +352,69 @@ FAIL Property color value 'lch(from lch(none none none / none) l c h / alpha)' assert_true: 'lch(from lch(none none none / none) l c h / alpha)' is a supported value for color. expected true got false FAIL Property color value 'lch(from lch(0.7 none 30) l c h)' assert_true: 'lch(from lch(0.7 none 30) l c h)' is a supported value for color. expected true got false FAIL Property color value 'lch(from lch(0.7 45 30 / none) l c h / alpha)' assert_true: 'lch(from lch(0.7 45 30 / none) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l c h)' assert_true: 'oklch(from oklch(0.7 45 30) l c h)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l c h / alpha)' assert_true: 'oklch(from oklch(0.7 45 30) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c h / alpha)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(200 300 400 / 500%) l c h / alpha)' assert_true: 'oklch(from oklch(200 300 400 / 500%) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(-200 -300 -400 / -500%) l c h / alpha)' assert_true: 'oklch(from oklch(-200 -300 -400 / -500%) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(from oklch(0.7 45 30) l c h) l c h)' assert_true: 'oklch(from oklch(from oklch(0.7 45 30) l c h) l c h)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c h)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c h)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(2 3 400 / 500%) l c h / alpha)' assert_true: 'oklch(from oklch(2 3 400 / 500%) l c h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(-2 -3 -400 / -500%) l c h / alpha)' assert_true: 'oklch(from oklch(-2 -3 -400 / -500%) l c h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(from oklch(0.7 0.45 30) l c h) l c h)' assert_true: 'oklch(from oklch(from oklch(0.7 0.45 30) l c h) l c h)' is a supported value for color. expected true got false FAIL Property color value 'oklch(from color(display-p3 0 0 0) l c h / alpha)' assert_true: 'oklch(from color(display-p3 0 0 0) l c h / alpha)' is a supported value for color. expected true got false FAIL Property color value 'oklch(from oklab(0.7 45 30) l c h / alpha)' assert_true: 'oklch(from oklab(0.7 45 30) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) 0 0 0)' assert_true: 'oklch(from oklch(0.7 45 30) 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) 0 0 0deg)' assert_true: 'oklch(from oklch(0.7 45 30) 0 0 0deg)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) 0 0 0 / 0)' assert_true: 'oklch(from oklch(0.7 45 30) 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) 0 0 0deg / 0)' assert_true: 'oklch(from oklch(0.7 45 30) 0 0 0deg / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) 0 c h / alpha)' assert_true: 'oklch(from oklch(0.7 45 30) 0 c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l 0 h / alpha)' assert_true: 'oklch(from oklch(0.7 45 30) l 0 h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l c 0 / alpha)' assert_true: 'oklch(from oklch(0.7 45 30) l c 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l c 0deg / alpha)' assert_true: 'oklch(from oklch(0.7 45 30) l c 0deg / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l c h / 0)' assert_true: 'oklch(from oklch(0.7 45 30) l c h / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) 0 c h / alpha)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) 0 c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) l 0 h / alpha)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) l 0 h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c 0 / alpha)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) l c 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c 0deg / alpha)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) l c 0deg / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c h / 0)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) l c h / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) 25 c h / alpha)' assert_true: 'oklch(from oklch(0.7 45 30) 25 c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l 25 h / alpha)' assert_true: 'oklch(from oklch(0.7 45 30) l 25 h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l c 25 / alpha)' assert_true: 'oklch(from oklch(0.7 45 30) l c 25 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l c 25deg / alpha)' assert_true: 'oklch(from oklch(0.7 45 30) l c 25deg / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l c h / .25)' assert_true: 'oklch(from oklch(0.7 45 30) l c h / .25)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) 25 c h / alpha)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) 25 c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) l 25 h / alpha)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) l 25 h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c 25 / alpha)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) l c 25 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c 25deg / alpha)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) l c 25deg / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c h / .25)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) l c h / .25)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) 200 300 400 / 500)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) 200 300 400 / 500)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) -200 -300 -400 / -500)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) -200 -300 -400 / -500)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) 50 120 400deg / 500)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) 50 120 400deg / 500)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) 50 120 -400deg / -500)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) 50 120 -400deg / -500)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 45 30) l c c / alpha)' assert_true: 'oklch(from oklch(.7 45 30) l c c / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 45 30 / 40%) l c c / alpha)' assert_true: 'oklch(from oklch(.7 45 30 / 40%) l c c / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) calc(l) calc(c) calc(h))' assert_true: 'oklch(from oklch(0.7 45 30) calc(l) calc(c) calc(h))' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) none none none)' assert_true: 'oklch(from oklch(0.7 45 30) none none none)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) none none none / none)' assert_true: 'oklch(from oklch(0.7 45 30) none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l c none)' assert_true: 'oklch(from oklch(0.7 45 30) l c none)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l c none / alpha)' assert_true: 'oklch(from oklch(0.7 45 30) l c none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30) l c h / none)' assert_true: 'oklch(from oklch(0.7 45 30) l c h / none)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c none / alpha)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) l c none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c h / none)' assert_true: 'oklch(from oklch(0.7 45 30 / 40%) l c h / none)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0)' assert_true: 'oklch(from oklch(0.7 0.45 30) 0 0 0)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0deg)' assert_true: 'oklch(from oklch(0.7 0.45 30) 0 0 0deg)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0 / 0)' assert_true: 'oklch(from oklch(0.7 0.45 30) 0 0 0 / 0)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0deg / 0)' assert_true: 'oklch(from oklch(0.7 0.45 30) 0 0 0deg / 0)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) 0 c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) 0 c h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l 0 h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l 0 h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c 0 / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c 0 / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c 0deg / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c 0deg / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c h / 0)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c h / 0)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0 c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) 0 c h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l 0 h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l 0 h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 0 / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c 0 / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 0deg / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c 0deg / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / 0)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / 0)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) 0.25 c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) 0.25 c h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l 0.25 h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l 0.25 h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c 25 / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c 25 / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c 25deg / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c 25deg / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c h / .25)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c h / .25)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0.25 c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) 0.25 c h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l 0.25 h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l 0.25 h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 25 / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c 25 / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 25deg / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c 25deg / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / .25)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / .25)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 2 3 400 / 500)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) 2 3 400 / 500)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) -2 -3 -400 / -500)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) -2 -3 -400 / -500)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 400deg / 500)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 400deg / 500)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 -400deg / -500)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 -400deg / -500)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(.7 0.45 30) l c c / alpha)' assert_true: 'oklch(from oklch(.7 0.45 30) l c c / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(.7 0.45 30 / 40%) l c c / alpha)' assert_true: 'oklch(from oklch(.7 0.45 30 / 40%) l c c / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) calc(l) calc(c) calc(h))' assert_true: 'oklch(from oklch(0.7 0.45 30) calc(l) calc(c) calc(h))' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) none none none)' assert_true: 'oklch(from oklch(0.7 0.45 30) none none none)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) none none none / none)' assert_true: 'oklch(from oklch(0.7 0.45 30) none none none / none)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c none)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c none)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c none / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c none / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c h / none)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c h / none)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c none / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c none / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / none)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / none)' is a supported value for color. expected true got false FAIL Property color value 'oklch(from oklch(none none none) l c h)' assert_true: 'oklch(from oklch(none none none) l c h)' is a supported value for color. expected true got false FAIL Property color value 'oklch(from oklch(none none none / none) l c h / alpha)' assert_true: 'oklch(from oklch(none none none / none) l c h / alpha)' is a supported value for color. expected true got false FAIL Property color value 'oklch(from oklch(0.7 none 30) l c h)' assert_true: 'oklch(from oklch(0.7 none 30) l c h)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 45 30 / none) l c h / alpha)' assert_true: 'oklch(from oklch(0.7 45 30 / none) l c h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / none) l c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / none) l c h / alpha)' is a supported value for color. expected true got false FAIL Property color value 'lch(from lch(.7 45 30) alpha c h / l)' assert_true: 'lch(from lch(.7 45 30) alpha c h / l)' is a supported value for color. expected true got false FAIL Property color value 'lch(from lch(.7 45 30) alpha c h / alpha)' assert_true: 'lch(from lch(.7 45 30) alpha c h / alpha)' is a supported value for color. expected true got false FAIL Property color value 'lch(from lch(.7 45 30) alpha c c / alpha)' assert_true: 'lch(from lch(.7 45 30) alpha c c / alpha)' is a supported value for color. expected true got false FAIL Property color value 'lch(from lch(.7 45 30 / 40%) alpha c h / l)' assert_true: 'lch(from lch(.7 45 30 / 40%) alpha c h / l)' is a supported value for color. expected true got false FAIL Property color value 'lch(from lch(.7 45 30 / 40%) alpha c h / alpha)' assert_true: 'lch(from lch(.7 45 30 / 40%) alpha c h / alpha)' is a supported value for color. expected true got false FAIL Property color value 'lch(from lch(.7 45 30 / 40%) alpha c c / alpha)' assert_true: 'lch(from lch(.7 45 30 / 40%) alpha c c / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 45 30) alpha c h / l)' assert_true: 'oklch(from oklch(.7 45 30) alpha c h / l)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 45 30) alpha c h / alpha)' assert_true: 'oklch(from oklch(.7 45 30) alpha c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 45 30) alpha c c / alpha)' assert_true: 'oklch(from oklch(.7 45 30) alpha c c / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 45 30 / 40%) alpha c h / l)' assert_true: 'oklch(from oklch(.7 45 30 / 40%) alpha c h / l)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 45 30 / 40%) alpha c h / alpha)' assert_true: 'oklch(from oklch(.7 45 30 / 40%) alpha c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 45 30 / 40%) alpha c c / alpha)' assert_true: 'oklch(from oklch(.7 45 30 / 40%) alpha c c / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(.7 0.45 30) alpha c h / l)' assert_true: 'oklch(from oklch(.7 0.45 30) alpha c h / l)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(.7 0.45 30) alpha c h / alpha)' assert_true: 'oklch(from oklch(.7 0.45 30) alpha c h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(.7 0.45 30) alpha c c / alpha)' assert_true: 'oklch(from oklch(.7 0.45 30) alpha c c / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(.7 0.45 30 / 40%) alpha c h / l)' assert_true: 'oklch(from oklch(.7 0.45 30 / 40%) alpha c h / l)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(.7 0.45 30 / 40%) alpha c h / alpha)' assert_true: 'oklch(from oklch(.7 0.45 30 / 40%) alpha c h / alpha)' is a supported value for color. expected true got false +FAIL Property color value 'oklch(from oklch(.7 0.45 30 / 40%) alpha c c / alpha)' assert_true: 'oklch(from oklch(.7 0.45 30 / 40%) alpha c c / alpha)' is a supported value for color. expected true got false FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g b)' is a supported value for color. expected true got false FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / alpha)' is a supported value for color. expected true got false FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b)' is a supported value for color. expected true got false
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color.html index 0587d09..44e0d8d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color.html
@@ -40,9 +40,9 @@ test_computed_value(`color`, `rgb(from lab(0 104.3 -50.9) r g b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, test_computed_value(`color`, `rgb(from lch(100 116 334) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). test_computed_value(`color`, `rgb(from lch(0 116 334) r g b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, - test_computed_value(`color`, `rgb(from oklab(100 0.365 -0.16) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). + test_computed_value(`color`, `rgb(from oklab(1 0.365 -0.16) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). test_computed_value(`color`, `rgb(from oklab(0 0.365 -0.16) r g b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). - test_computed_value(`color`, `rgb(from oklch(100 0.399 336.3) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). + test_computed_value(`color`, `rgb(from oklch(1 0.399 336.3) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). test_computed_value(`color`, `rgb(from oklch(0 0.399 336.3) r g b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). // Testing replacement with 0. @@ -146,9 +146,9 @@ test_computed_value(`color`, `hsl(from lab(0 104.3 -50.9) h s l)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, test_computed_value(`color`, `hsl(from lch(100 116 334) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). test_computed_value(`color`, `hsl(from lch(0 116 334) h s l)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, - test_computed_value(`color`, `hsl(from oklab(100 0.365 -0.16) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). + test_computed_value(`color`, `hsl(from oklab(1 0.365 -0.16) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). test_computed_value(`color`, `hsl(from oklab(0 0.365 -0.16) h s l)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). - test_computed_value(`color`, `hsl(from oklch(100 0.399 336.3) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). + test_computed_value(`color`, `hsl(from oklch(1 0.399 336.3) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). test_computed_value(`color`, `hsl(from oklch(0 0.399 336.3) h s l)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). // Testing replacement with 0. @@ -227,9 +227,9 @@ test_computed_value(`color`, `hwb(from lab(0 104.3 -50.9) h w b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, test_computed_value(`color`, `hwb(from lch(100 116 334) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). test_computed_value(`color`, `hwb(from lch(0 116 334) h w b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, - test_computed_value(`color`, `hwb(from oklab(100 0.365 -0.16) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). + test_computed_value(`color`, `hwb(from oklab(1 0.365 -0.16) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). test_computed_value(`color`, `hwb(from oklab(0 0.365 -0.16) h w b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). - test_computed_value(`color`, `hwb(from oklch(100 0.399 336.3) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). + test_computed_value(`color`, `hwb(from oklch(1 0.399 336.3) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). test_computed_value(`color`, `hwb(from oklch(0 0.399 336.3) h w b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). // Testing replacement with 0. @@ -357,66 +357,65 @@ // oklab() // Testing no modifications. - test_computed_value(`color`, `oklab(from oklab(25 20 50) l a b)`, `oklab(25 20 50)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) l a b / alpha)`, `oklab(25 20 50)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a b / alpha)`, `oklab(25 20 50 / 0.4)`); - test_computed_value(`color`, `oklab(from oklab(200 300 400 / 500%) l a b / alpha)`, `oklab(200 300 400)`); - test_computed_value(`color`, `oklab(from oklab(-200 -300 -400 / -500%) l a b / alpha)`, `oklab(0 -300 -400 / 0)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a b)`, `oklab(0.25 0.2 0.5)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a b / alpha)`, `oklab(0.25 0.2 0.5)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / alpha)`, `oklab(0.25 0.2 0.5 / 0.4)`); + test_computed_value(`color`, `oklab(from oklab(2 3 4 / 500%) l a b / alpha)`, `oklab(1 3 4)`); + test_computed_value(`color`, `oklab(from oklab(-2 -3 -4 / -500%) l a b / alpha)`, `oklab(0 -3 -4 / 0)`); // Test nesting relative colors. - test_computed_value(`color`, `oklab(from oklab(from oklab(25 20 50) l a b) l a b)`, `oklab(25 20 50)`); + test_computed_value(`color`, `oklab(from oklab(from oklab(0.25 0.2 0.5) l a b) l a b)`, `oklab(0.25 0.2 0.5)`); // Testing non-oklab origin to see conversion. test_computed_value(`color`, `oklab(from color(display-p3 0 0 0) l a b / alpha)`, `oklab(0 0 0)`); // Testing replacement with 0. - test_computed_value(`color`, `oklab(from oklab(25 20 50) 0 0 0)`, `oklab(0 0 0)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) 0 0 0 / 0)`, `oklab(0 0 0 / 0)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) 0 a b / alpha)`, `oklab(0 20 50)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) l 0 b / alpha)`, `oklab(25 0 50)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) l a 0 / alpha)`, `oklab(25 20 0)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) l a b / 0)`, `oklab(25 20 50 / 0)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) 0 a b / alpha)`, `oklab(0 20 50 / 0.4)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) l 0 b / alpha)`, `oklab(25 0 50 / 0.4)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a 0 / alpha)`, `oklab(25 20 0 / 0.4)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a b / 0)`, `oklab(25 20 50 / 0)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) 0 0 0)`, `oklab(0 0 0)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) 0 0 0 / 0)`, `oklab(0 0 0 / 0)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) 0 a b / alpha)`, `oklab(0 0.2 0.5)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l 0 b / alpha)`, `oklab(0.25 0 0.5)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a 0 / alpha)`, `oklab(0.25 0.2 0)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a b / 0)`, `oklab(0.25 0.2 0.5 / 0)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) 0 a b / alpha)`, `oklab(0 0.2 0.5 / 0.4)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l 0 b / alpha)`, `oklab(0.25 0 0.5 / 0.4)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0 / alpha)`, `oklab(0.25 0.2 0 / 0.4)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / 0)`, `oklab(0.25 0.2 0.5 / 0)`); // Testing replacement with a constant. - test_computed_value(`color`, `oklab(from oklab(25 20 50) 35 a b / alpha)`, `oklab(35 20 50)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) l 35 b / alpha)`, `oklab(25 35 50)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) l a 35 / alpha)`, `oklab(25 20 35)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) l a b / .35)`, `oklab(25 20 50 / 0.35)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) 35 a b / alpha)`, `oklab(35 20 50 / 0.4)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) l 35 b / alpha)`, `oklab(25 35 50 / 0.4)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a 35 / alpha)`, `oklab(25 20 35 / 0.4)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a b / .35)`, `oklab(25 20 50 / 0.35)`); - test_computed_value(`color`, `oklab(from oklab(0.7 45 30 / 40%) 200 300 400 / 500)`, `oklab(200 300 400)`); - test_computed_value(`color`, `oklab(from oklab(0.7 45 30 / 40%) -200 -300 -400 / -500)`, `oklab(0 -300 -400 / 0)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) 0.35 a b / alpha)`, `oklab(0.35 0.2 0.5)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l 0.35 b / alpha)`, `oklab(0.25 0.35 0.5)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a 0.35 / alpha)`, `oklab(0.25 0.2 0.35)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a b / .35)`, `oklab(0.25 0.2 0.5 / 0.35)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) 0.35 a b / alpha)`, `oklab(0.35 0.2 0.5 / 0.4)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l 0.35 b / alpha)`, `oklab(0.25 0.35 0.5 / 0.4)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0.35 / alpha)`, `oklab(0.25 0.2 0.35 / 0.4)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / .35)`, `oklab(0.25 0.2 0.5 / 0.35)`); + test_computed_value(`color`, `oklab(from oklab(0.7 0.45 0.3 / 40%) 2 3 4 / 500)`, `oklab(1 3 4)`); + test_computed_value(`color`, `oklab(from oklab(0.7 0.45 0.3 / 40%) -2 -3 -4 / -500)`, `oklab(0 -3 -4 / 0)`); // Testing valid permutation (types match). - test_computed_value(`color`, `oklab(from oklab(25 20 50) l b a)`, `oklab(25 50 20)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) l a a / a)`, `oklab(25 20 20)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) l b a)`, `oklab(25 50 20)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a a / a)`, `oklab(25 20 20)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l b a)`, `oklab(0.25 0.5 0.2)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a a / a)`, `oklab(0.25 0.2 0.2 / 0.2)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l b a)`, `oklab(0.25 0.5 0.2)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a a / a)`, `oklab(0.25 0.2 0.2 / 0.2)`); // Testing with calc(). - test_computed_value(`color`, `oklab(from oklab(25 20 50) calc(l) calc(a) calc(b))`, `oklab(25 20 50)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))`, `oklab(25 20 50 / 0.4)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))`, `oklab(0.25 0.2 0.5)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))`, `oklab(0.25 0.2 0.5 / 0.4)`); // Testing with 'none'. - test_computed_value(`color`, `oklab(from oklab(25 20 50) none none none)`, `oklab(none none none)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) none none none / none)`, `oklab(none none none / none)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) l a none)`, `oklab(25 20 none)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) l a none / alpha)`, `oklab(25 20 none)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50) l a b / none)`, `oklab(25 20 50 / none)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a none / alpha)`, `oklab(25 20 none / 0.4)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a b / none)`, `oklab(25 20 50 / none)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) none none none)`, `oklab(none none none)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) none none none / none)`, `oklab(none none none / none)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a none)`, `oklab(0.25 0.2 none)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a none / alpha)`, `oklab(0.25 0.2 none)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a b / none)`, `oklab(0.25 0.2 0.5 / none)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a none / alpha)`, `oklab(0.25 0.2 none / 0.4)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / none)`, `oklab(0.25 0.2 0.5 / none)`); // FIXME: Clarify with spec editors if 'none' should pass through to the constants. test_computed_value(`color`, `oklab(from oklab(none none none) l a b)`, `oklab(0 0 0)`); test_computed_value(`color`, `oklab(from oklab(none none none / none) l a b / alpha)`, `oklab(0 0 0 / 0)`); - test_computed_value(`color`, `oklab(from oklab(25 none 50) l a b)`, `oklab(25 0 50)`); - test_computed_value(`color`, `oklab(from oklab(25 20 50 / none) l a b / alpha)`, `oklab(25 20 50 / 0)`); - + test_computed_value(`color`, `oklab(from oklab(0.25 none 0.5) l a b)`, `oklab(0.25 0 0.5)`); + test_computed_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / none) l a b / alpha)`, `oklab(0.25 0.2 0.5 / 0)`); // lab and oklab tests that require different results due to percent scaling differences. test_computed_value(`color`, `lab(from lab(.7 45 30) alpha b a / l)`, `lab(100 30 45 / 0.7)`); @@ -426,12 +425,12 @@ test_computed_value(`color`, `lab(from lab(.7 45 30 / 40%) alpha a b / alpha)`, `lab(40 45 30 / 0.4)`); test_computed_value(`color`, `lab(from lab(.7 45 30 / 40%) alpha a a / alpha)`, `lab(40 45 45 / 0.4)`); - test_computed_value(`color`, `oklab(from oklab(.7 45 30) alpha b a / l)`, `oklab(1 30 45 / 0.7)`); - test_computed_value(`color`, `oklab(from oklab(.7 45 30) alpha a b / alpha)`, `oklab(1 45 30)`); - test_computed_value(`color`, `oklab(from oklab(.7 45 30) alpha a a / alpha)`, `oklab(1 45 45)`); - test_computed_value(`color`, `oklab(from oklab(.7 45 30 / 40%) alpha b a / l)`, `oklab(0.4 30 45 / 0.7)`); - test_computed_value(`color`, `oklab(from oklab(.7 45 30 / 40%) alpha a b / alpha)`, `oklab(0.4 45 30 / 0.4)`); - test_computed_value(`color`, `oklab(from oklab(.7 45 30 / 40%) alpha a a / alpha)`, `oklab(0.4 45 45 / 0.4)`); + test_computed_value(`color`, `oklab(from oklab(.7 0.45 0.3) alpha b a / l)`, `oklab(1 0.3 0.45 / 0.7)`); + test_computed_value(`color`, `oklab(from oklab(.7 0.45 0.3) alpha a b / alpha)`, `oklab(1 0.45 0.3)`); + test_computed_value(`color`, `oklab(from oklab(.7 0.45 0.3) alpha a a / alpha)`, `oklab(1 0.45 0.45)`); + test_computed_value(`color`, `oklab(from oklab(.7 0.45 0.3 / 40%) alpha b a / l)`, `oklab(0.4 0.3 0.45 / 0.7)`); + test_computed_value(`color`, `oklab(from oklab(.7 0.45 0.3 / 40%) alpha a b / alpha)`, `oklab(0.4 0.45 0.3 / 0.4)`); + test_computed_value(`color`, `oklab(from oklab(.7 0.45 0.3 / 40%) alpha a a / alpha)`, `oklab(0.4 0.45 0.45 / 0.4)`); // lch() @@ -507,73 +506,74 @@ // oklch() // Testing no modifications. - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l c h)`, `oklch(0.7 45 30)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l c h / alpha)`, `oklch(0.7 45 30)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c h / alpha)`, `oklch(0.7 45 30 / 0.4)`); - test_computed_value(`color`, `oklch(from oklch(200 300 400 / 500%) l c h / alpha)`, `oklch(200 300 40)`); - test_computed_value(`color`, `oklch(from oklch(-200 -300 -400 / -500%) l c h / alpha)`, `oklch(0 0 320 / 0)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l c h)`, `oklch(0.7 0.45 30)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l c h / alpha)`, `oklch(0.7 0.45 30)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c h / alpha)`, `oklch(0.7 0.45 30 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(2 3 400 / 500%) l c h / alpha)`, `oklch(1 3 40)`); + test_computed_value(`color`, `oklch(from oklch(-2 -3 -400 / -500%) l c h / alpha)`, `oklch(0 0 320 / 0)`); // Test nesting relative colors. - test_computed_value(`color`, `oklch(from oklch(from oklch(0.7 45 30) l c h) l c h)`, `oklch(0.7 45 30)`); + test_computed_value(`color`, `oklch(from oklch(from oklch(0.7 0.45 30) l c h) l c h)`, `oklch(0.7 0.45 30)`); // Testing non-sRGB origin colors (no gamut mapping will happen since the destination is not a bounded RGB color space). test_computed_value(`color`, `oklch(from color(display-p3 0 0 0) l c h / alpha)`, `oklch(0 0 0)`); + // TODO: redo conversion with oklab(0.7 0.45 0.3) test_computed_value(`color`, `oklch(from oklab(0.7 45 30) l c h / alpha)`, `oklch(0.7 54.08327 33.690067)`); // Testing replacement with 0. - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) 0 0 0)`, `oklch(0 0 0)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) 0 0 0deg)`, `oklch(0 0 0)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) 0 0 0 / 0)`, `oklch(0 0 0 / 0)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) 0 0 0deg / 0)`, `oklch(0 0 0 / 0)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) 0 c h / alpha)`, `oklch(0 45 30)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l 0 h / alpha)`, `oklch(0.7 0 30)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l c 0 / alpha)`, `oklch(0.7 45 0)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l c 0deg / alpha)`, `oklch(0.7 45 0)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l c h / 0)`, `oklch(0.7 45 30 / 0)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) 0 c h / alpha)`, `oklch(0 45 30 / 0.4)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l 0 h / alpha)`, `oklch(0.7 0 30 / 0.4)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c 0 / alpha)`, `oklch(0.7 45 0 / 0.4)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c 0deg / alpha)`, `oklch(0.7 45 0 / 0.4)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c h / 0)`, `oklch(0.7 45 30 / 0)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) 0 0 0)`, `oklch(0 0 0)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) 0 0 0deg)`, `oklch(0 0 0)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) 0 0 0 / 0)`, `oklch(0 0 0 / 0)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) 0 0 0deg / 0)`, `oklch(0 0 0 / 0)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) 0 c h / alpha)`, `oklch(0 0.45 30)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l 0 h / alpha)`, `oklch(0.7 0 30)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l c 0 / alpha)`, `oklch(0.7 0.45 0)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l c 0deg / alpha)`, `oklch(0.7 0.45 0)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l c h / 0)`, `oklch(0.7 0.45 30 / 0)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) 0 c h / alpha)`, `oklch(0 0.45 30 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l 0 h / alpha)`, `oklch(0.7 0 30 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c 0 / alpha)`, `oklch(0.7 0.45 0 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c 0deg / alpha)`, `oklch(0.7 0.45 0 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c h / 0)`, `oklch(0.7 0.45 30 / 0)`); // Testing replacement with a constant. - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) 25 c h / alpha)`, `oklch(25 45 30)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l 25 h / alpha)`, `oklch(0.7 25 30)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l c 25 / alpha)`, `oklch(0.7 45 25)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l c 25deg / alpha)`, `oklch(0.7 45 25)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l c h / .25)`, `oklch(0.7 45 30 / 0.25)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) 25 c h / alpha)`, `oklch(25 45 30 / 0.4)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l 25 h / alpha)`, `oklch(0.7 25 30 / 0.4)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c 25 / alpha)`, `oklch(0.7 45 25 / 0.4)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c 25deg / alpha)`, `oklch(0.7 45 25 / 0.4)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c h / .25)`, `oklch(0.7 45 30 / 0.25)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) 200 300 400 / 500)`, `oklch(200 300 40)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) -200 -300 -400 / -500)`, `oklch(0 0 320 / 0)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) 50 120 400deg / 500)`, `oklch(50 120 40)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) 50 120 -400deg / -500)`, `oklch(50 120 320 / 0)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) 0.25 c h / alpha)`, `oklch(0.25 0.45 30)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l 0.25 h / alpha)`, `oklch(0.7 0.25 30)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l c 25 / alpha)`, `oklch(0.7 0.45 25)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l c 25deg / alpha)`, `oklch(0.7 0.45 25)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l c h / .25)`, `oklch(0.7 0.45 30 / 0.25)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) 0.25 c h / alpha)`, `oklch(0.25 0.45 30 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l 0.25 h / alpha)`, `oklch(0.7 0.25 30 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c 25 / alpha)`, `oklch(0.7 0.45 25 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c 25deg / alpha)`, `oklch(0.7 0.45 25 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c h / .25)`, `oklch(0.7 0.45 30 / 0.25)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) 2 3 400 / 500)`, `oklch(1 3 40)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) -2 -3 -400 / -500)`, `oklch(0 0 320 / 0)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 400deg / 500)`, `oklch(0.5 1.2 40)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 -400deg / -500)`, `oklch(0.5 1.2 320 / 0)`); // Testing valid permutation (types match). // NOTE: 'c' is a vaild hue, as hue is <angle>|<number>. - test_computed_value(`color`, `oklch(from oklch(.7 45 30) l c c / alpha)`, `oklch(0.7 45 45)`); - test_computed_value(`color`, `oklch(from oklch(.7 45 30 / 40%) l c c / alpha)`, `oklch(0.7 45 45 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(.7 0.45 30) l c c / alpha)`, `oklch(0.7 0.45 0.45)`); + test_computed_value(`color`, `oklch(from oklch(.7 0.45 30 / 40%) l c c / alpha)`, `oklch(0.7 0.45 0.45 / 0.4)`); // Testing with calc(). - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) calc(l) calc(c) calc(h))`, `oklch(0.7 45 30)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))`, `oklch(0.7 45 30 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) calc(l) calc(c) calc(h))`, `oklch(0.7 0.45 30)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))`, `oklch(0.7 0.45 30 / 0.4)`); // Testing with 'none'. - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) none none none)`, `oklch(none none none)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) none none none / none)`, `oklch(none none none / none)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l c none)`, `oklch(0.7 45 none)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l c none / alpha)`, `oklch(0.7 45 none)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30) l c h / none)`, `oklch(0.7 45 30 / none)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c none / alpha)`, `oklch(0.7 45 none / 0.4)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c h / none)`, `oklch(0.7 45 30 / none)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) none none none)`, `oklch(none none none)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) none none none / none)`, `oklch(none none none / none)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l c none)`, `oklch(0.7 0.45 none)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l c none / alpha)`, `oklch(0.7 0.45 none)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30) l c h / none)`, `oklch(0.7 0.45 30 / none)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c none / alpha)`, `oklch(0.7 0.45 none / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c h / none)`, `oklch(0.7 0.45 30 / none)`); // FIXME: Clarify with spec editors if 'none' should pass through to the constants. test_computed_value(`color`, `oklch(from oklch(none none none) l c h)`, `oklch(0 0 0)`); test_computed_value(`color`, `oklch(from oklch(none none none / none) l c h / alpha)`, `oklch(0 0 0 / 0)`); test_computed_value(`color`, `oklch(from oklch(0.7 none 30) l c h)`, `oklch(0.7 0 30)`); - test_computed_value(`color`, `oklch(from oklch(0.7 45 30 / none) l c h / alpha)`, `oklch(0.7 45 30 / 0)`); + test_computed_value(`color`, `oklch(from oklch(0.7 0.45 30 / none) l c h / alpha)`, `oklch(0.7 0.45 30 / 0)`); // lch and oklch tests that require different results due to percent scaling differences. test_computed_value(`color`, `lch(from lch(.7 45 30) alpha c h / l)`, `lch(100 45 30 / 0.7)`); @@ -583,12 +583,12 @@ test_computed_value(`color`, `lch(from lch(.7 45 30 / 40%) alpha c h / alpha)`, `lch(40 45 30 / 0.4)`); test_computed_value(`color`, `lch(from lch(.7 45 30 / 40%) alpha c c / alpha)`, `lch(40 45 45 / 0.4)`); - test_computed_value(`color`, `oklch(from oklch(.7 45 30) alpha c h / l)`, `oklch(1 45 30 / 0.7)`); - test_computed_value(`color`, `oklch(from oklch(.7 45 30) alpha c h / alpha)`, `oklch(1 45 30)`); - test_computed_value(`color`, `oklch(from oklch(.7 45 30) alpha c c / alpha)`, `oklch(1 45 45)`); - test_computed_value(`color`, `oklch(from oklch(.7 45 30 / 40%) alpha c h / l)`, `oklch(0.4 45 30 / 0.7)`); - test_computed_value(`color`, `oklch(from oklch(.7 45 30 / 40%) alpha c h / alpha)`, `oklch(0.4 45 30 / 0.4)`); - test_computed_value(`color`, `oklch(from oklch(.7 45 30 / 40%) alpha c c / alpha)`, `oklch(0.4 45 45 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(.7 0.45 30) alpha c h / l)`, `oklch(1 0.45 30 / 0.7)`); + test_computed_value(`color`, `oklch(from oklch(.7 0.45 30) alpha c h / alpha)`, `oklch(1 0.45 30)`); + test_computed_value(`color`, `oklch(from oklch(.7 0.45 30) alpha c c / alpha)`, `oklch(1 0.45 0.45)`); + test_computed_value(`color`, `oklch(from oklch(.7 0.45 30 / 40%) alpha c h / l)`, `oklch(0.4 0.45 30 / 0.7)`); + test_computed_value(`color`, `oklch(from oklch(.7 0.45 30 / 40%) alpha c h / alpha)`, `oklch(0.4 0.45 30 / 0.4)`); + test_computed_value(`color`, `oklch(from oklch(.7 0.45 30 / 40%) alpha c c / alpha)`, `oklch(0.4 0.45 0.45 / 0.4)`); for (const colorSpace of [ "srgb", "srgb-linear", "a98-rgb", "rec2020", "prophoto-rgb", "display-p3" ]) {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color.html.ini b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color.html.ini index 4963d6a1..cd52a07 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color.html.ini +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color.html.ini
@@ -1643,13 +1643,13 @@ [Property color value 'hsl(from oklab(0 0.365 -0.16) h s l)'] expected: FAIL - [Property color value 'hsl(from oklab(100 0.365 -0.16) h s l)'] + [Property color value 'hsl(from oklab(1 0.365 -0.16) h s l)'] expected: FAIL [Property color value 'hsl(from oklch(0 0.399 336.3) h s l)'] expected: FAIL - [Property color value 'hsl(from oklch(100 0.399 336.3) h s l)'] + [Property color value 'hsl(from oklch(1 0.399 336.3) h s l)'] expected: FAIL [Property color value 'hsl(from rebeccapurple 0 0% 0% / 0)'] @@ -1832,13 +1832,13 @@ [Property color value 'hwb(from oklab(0 0.365 -0.16) h w b)'] expected: FAIL - [Property color value 'hwb(from oklab(100 0.365 -0.16) h w b)'] + [Property color value 'hwb(from oklab(1 0.365 -0.16) h w b)'] expected: FAIL [Property color value 'hwb(from oklch(0 0.399 336.3) h w b)'] expected: FAIL - [Property color value 'hwb(from oklch(100 0.399 336.3) h w b)'] + [Property color value 'hwb(from oklch(1 0.399 336.3) h w b)'] expected: FAIL [Property color value 'hwb(from rebeccapurple 0 0% 0% / 0)'] @@ -2321,145 +2321,145 @@ [Property color value 'oklab(from color(display-p3 0 0 0) l a b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(-200 -300 -400 / -500%) l a b / alpha)'] + [Property color value 'oklab(from oklab(-2 -3 -4 / -500%) l a b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(.7 45 30 / 40%) alpha a a / alpha)'] + [Property color value 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha a a / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(.7 45 30 / 40%) alpha a b / alpha)'] + [Property color value 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha a b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(.7 45 30 / 40%) alpha b a / l)'] + [Property color value 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha b a / l)'] expected: FAIL - [Property color value 'oklab(from oklab(.7 45 30) alpha a a / alpha)'] + [Property color value 'oklab(from oklab(.7 0.45 0.3) alpha a a / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(.7 45 30) alpha a b / alpha)'] + [Property color value 'oklab(from oklab(.7 0.45 0.3) alpha a b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(.7 45 30) alpha b a / l)'] + [Property color value 'oklab(from oklab(.7 0.45 0.3) alpha b a / l)'] expected: FAIL - [Property color value 'oklab(from oklab(0.7 45 30 / 40%) -200 -300 -400 / -500)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) 0 a b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(0.7 45 30 / 40%) 200 300 400 / 500)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) 0.35 a b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(200 300 400 / 500%) l a b / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) 0 a b / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l 0 b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) 35 a b / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l 0.35 b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0 / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) l 0 b / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0.35 / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) l 35 b / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a a / a)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) l a 0 / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / .35)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) l a 35 / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / 0)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) l a a / a)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) l a b / .35)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / none)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) l a b / 0)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a none / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) l a b / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l b a)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) l a b / none)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5 / none) l a b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) l a none / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) 0 0 0 / 0)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / 40%) l b a)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) 0 0 0)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50 / none) l a b / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) 0 a b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) 0 0 0 / 0)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) 0.35 a b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) 0 0 0)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) 0 a b / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l 0 b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) 35 a b / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l 0.35 b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) calc(l) calc(a) calc(b))'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l a 0 / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l 0 b / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l a 0.35 / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l 35 b / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l a a / a)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l a 0 / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / .35)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l a 35 / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / 0)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l a a / a)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l a b / .35)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / none)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l a b / 0)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l a b / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l a none / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l a b / none)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l a none)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l a b)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) l b a)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l a none / alpha)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) none none none / none)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l a none)'] + [Property color value 'oklab(from oklab(0.25 0.2 0.5) none none none)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) l b a)'] + [Property color value 'oklab(from oklab(0.25 none 0.5) l a b)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) none none none / none)'] + [Property color value 'oklab(from oklab(0.7 0.45 0.3 / 40%) -2 -3 -4 / -500)'] expected: FAIL - [Property color value 'oklab(from oklab(25 20 50) none none none)'] + [Property color value 'oklab(from oklab(0.7 0.45 0.3 / 40%) 2 3 4 / 500)'] expected: FAIL - [Property color value 'oklab(from oklab(25 none 50) l a b)'] + [Property color value 'oklab(from oklab(2 3 4 / 500%) l a b / alpha)'] expected: FAIL - [Property color value 'oklab(from oklab(from oklab(25 20 50) l a b) l a b)'] + [Property color value 'oklab(from oklab(from oklab(0.25 0.2 0.5) l a b) l a b)'] expected: FAIL [Property color value 'oklab(from oklab(none none none / none) l a b / alpha)'] @@ -2474,163 +2474,163 @@ [Property color value 'oklch(from oklab(0.7 45 30) l c h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(-200 -300 -400 / -500%) l c h / alpha)'] + [Property color value 'oklch(from oklch(-2 -3 -400 / -500%) l c h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(.7 45 30 / 40%) alpha c c / alpha)'] + [Property color value 'oklch(from oklch(.7 0.45 30 / 40%) alpha c c / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(.7 45 30 / 40%) alpha c h / alpha)'] + [Property color value 'oklch(from oklch(.7 0.45 30 / 40%) alpha c h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(.7 45 30 / 40%) alpha c h / l)'] + [Property color value 'oklch(from oklch(.7 0.45 30 / 40%) alpha c h / l)'] expected: FAIL - [Property color value 'oklch(from oklch(.7 45 30 / 40%) l c c / alpha)'] + [Property color value 'oklch(from oklch(.7 0.45 30 / 40%) l c c / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(.7 45 30) alpha c c / alpha)'] + [Property color value 'oklch(from oklch(.7 0.45 30) alpha c c / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(.7 45 30) alpha c h / alpha)'] + [Property color value 'oklch(from oklch(.7 0.45 30) alpha c h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(.7 45 30) alpha c h / l)'] + [Property color value 'oklch(from oklch(.7 0.45 30) alpha c h / l)'] expected: FAIL - [Property color value 'oklch(from oklch(.7 45 30) l c c / alpha)'] + [Property color value 'oklch(from oklch(.7 0.45 30) l c c / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) -200 -300 -400 / -500)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) -2 -3 -400 / -500)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) 0 c h / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0 c h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) 200 300 400 / 500)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0.25 c h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) 25 c h / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 -400deg / -500)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) 50 120 -400deg / -500)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 400deg / 500)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) 50 120 400deg / 500)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 2 3 400 / 500)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) l 0 h / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l 0 h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) l 25 h / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l 0.25 h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c 0 / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 0 / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c 0deg / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 0deg / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c 25 / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 25 / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c 25deg / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 25deg / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c h / .25)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / .25)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c h / 0)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / 0)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c h / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c h / none)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / none)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / 40%) l c none / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c none / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30 / none) l c h / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30 / none) l c h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) 0 0 0 / 0)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0 / 0)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) 0 0 0)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) 0 0 0deg / 0)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0deg / 0)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) 0 0 0deg)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0deg)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) 0 c h / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) 0 c h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) 25 c h / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) 0.25 c h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) calc(l) calc(c) calc(h))'] + [Property color value 'oklch(from oklch(0.7 0.45 30) calc(l) calc(c) calc(h))'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l 0 h / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l 0 h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l 25 h / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l 0.25 h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l c 0 / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l c 0 / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l c 0deg / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l c 0deg / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l c 25 / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l c 25 / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l c 25deg / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l c 25deg / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l c h / .25)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l c h / .25)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l c h / 0)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l c h / 0)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l c h / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l c h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l c h / none)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l c h / none)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l c h)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l c h)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l c none / alpha)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l c none / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) l c none)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) l c none)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) none none none / none)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) none none none / none)'] expected: FAIL - [Property color value 'oklch(from oklch(0.7 45 30) none none none)'] + [Property color value 'oklch(from oklch(0.7 0.45 30) none none none)'] expected: FAIL [Property color value 'oklch(from oklch(0.7 none 30) l c h)'] expected: FAIL - [Property color value 'oklch(from oklch(200 300 400 / 500%) l c h / alpha)'] + [Property color value 'oklch(from oklch(2 3 400 / 500%) l c h / alpha)'] expected: FAIL - [Property color value 'oklch(from oklch(from oklch(0.7 45 30) l c h) l c h)'] + [Property color value 'oklch(from oklch(from oklch(0.7 0.45 30) l c h) l c h)'] expected: FAIL [Property color value 'oklch(from oklch(none none none / none) l c h / alpha)'] @@ -2663,13 +2663,13 @@ [Property color value 'rgb(from oklab(0 0.365 -0.16) r g b)'] expected: FAIL - [Property color value 'rgb(from oklab(100 0.365 -0.16) r g b)'] + [Property color value 'rgb(from oklab(1 0.365 -0.16) r g b)'] expected: FAIL [Property color value 'rgb(from oklch(0 0.399 336.3) r g b)'] expected: FAIL - [Property color value 'rgb(from oklch(100 0.399 336.3) r g b)'] + [Property color value 'rgb(from oklch(1 0.399 336.3) r g b)'] expected: FAIL [Property color value 'rgb(from rebeccapurple 0 0 0 / 0)']
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt index c34ec18..c763f87 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt
@@ -69,9 +69,9 @@ PASS e.style['color'] = "color-mix(in hsl, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)" should set the property value PASS e.style['color'] = "color-mix(in hsl, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)" should set the property value PASS e.style['color'] = "color-mix(in hsl, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)" should set the property value -PASS e.style['color'] = "color-mix(in hsl, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value +PASS e.style['color'] = "color-mix(in hsl, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value PASS e.style['color'] = "color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value -PASS e.style['color'] = "color-mix(in hsl, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value +PASS e.style['color'] = "color-mix(in hsl, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value PASS e.style['color'] = "color-mix(in hsl, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))" should set the property value PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%))" should set the property value @@ -135,9 +135,9 @@ PASS e.style['color'] = "color-mix(in hwb, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)" should set the property value PASS e.style['color'] = "color-mix(in hwb, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)" should set the property value PASS e.style['color'] = "color-mix(in hwb, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)" should set the property value -PASS e.style['color'] = "color-mix(in hwb, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value +PASS e.style['color'] = "color-mix(in hwb, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value PASS e.style['color'] = "color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value -PASS e.style['color'] = "color-mix(in hwb, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value +PASS e.style['color'] = "color-mix(in hwb, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value PASS e.style['color'] = "color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg), lch(50 60 70deg))" should set the property value PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg) 25%, lch(50 60 70deg))" should set the property value @@ -196,63 +196,63 @@ PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / none), lch(50 60 70deg))" should set the property value PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / none), lch(50 60 70deg / 0.5))" should set the property value PASS e.style['color'] = "color-mix(in lch, lch(10 20 30deg / none), lch(50 60 70deg / none))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg), oklch(50 60 70deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg) 25%, oklch(50 60 70deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, 25% oklch(10 20 30deg), oklch(50 60 70deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg), 25% oklch(50 60 70deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg), oklch(50 60 70deg) 25%)" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg) 25%, oklch(50 60 70deg) 75%)" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg) 30%, oklch(50 60 70deg) 90%)" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg) 12.5%, oklch(50 60 70deg) 37.5%)" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg) 0%, oklch(50 60 70deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg / .4), oklch(50 60 70deg / .8))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg / .4) 25%, oklch(50 60 70deg / .8))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, 25% oklch(10 20 30deg / .4), oklch(50 60 70deg / .8))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg / .4), 25% oklch(50 60 70deg / .8))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg / .4), oklch(50 60 70deg / .8) 25%)" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg / .4) 25%, oklch(50 60 70deg / .8) 75%)" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg / .4) 30%, oklch(50 60 70deg / .8) 90%)" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg / .4) 12.5%, oklch(50 60 70deg / .8) 37.5%)" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg / .4) 0%, oklch(50 60 70deg / .8))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(100 0 40deg), oklch(100 0 60deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(100 0 60deg), oklch(100 0 40deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(100 0 50deg), oklch(100 0 330deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(100 0 330deg), oklch(100 0 50deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(100 0 20deg), oklch(100 0 320deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(100 0 320deg), oklch(100 0 20deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(100 0 40deg), oklch(100 0 60deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(100 0 60deg), oklch(100 0 40deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(100 0 50deg), oklch(100 0 330deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(100 0 330deg), oklch(100 0 50deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(100 0 20deg), oklch(100 0 320deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(100 0 320deg), oklch(100 0 20deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(100 0 40deg), oklch(100 0 60deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(100 0 60deg), oklch(100 0 40deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(100 0 50deg), oklch(100 0 330deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(100 0 330deg), oklch(100 0 50deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(100 0 20deg), oklch(100 0 320deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(100 0 320deg), oklch(100 0 20deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(100 0 40deg), oklch(100 0 60deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(100 0 60deg), oklch(100 0 40deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(100 0 50deg), oklch(100 0 330deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(100 0 330deg), oklch(100 0 50deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(100 0 20deg), oklch(100 0 320deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(100 0 320deg), oklch(100 0 20deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(100 0 40deg), oklch(100 0 60deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(100 0 60deg), oklch(100 0 40deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(100 0 50deg), oklch(100 0 330deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(100 0 330deg), oklch(100 0 50deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(100 0 20deg), oklch(100 0 320deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(100 0 320deg), oklch(100 0 20deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(0.5 0.6 70deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg) 25%, oklch(0.5 0.6 70deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, 25% oklch(0.1 0.2 30deg), oklch(0.5 0.6 70deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg), 25% oklch(0.5 0.6 70deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(0.5 0.6 70deg) 25%)" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg) 25%, oklch(0.5 0.6 70deg) 75%)" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg) 30%, oklch(0.5 0.6 70deg) 90%)" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg) 12.5%, oklch(0.5 0.6 70deg) 37.5%)" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg) 0%, oklch(0.5 0.6 70deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4), oklch(0.5 0.6 70deg / .8))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 25%, oklch(0.5 0.6 70deg / .8))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, 25% oklch(0.1 0.2 30deg / .4), oklch(0.5 0.6 70deg / .8))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4), 25% oklch(0.5 0.6 70deg / .8))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4), oklch(0.5 0.6 70deg / .8) 25%)" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 25%, oklch(0.5 0.6 70deg / .8) 75%)" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 30%, oklch(0.5 0.6 70deg / .8) 90%)" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 12.5%, oklch(0.5 0.6 70deg / .8) 37.5%)" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 0%, oklch(0.5 0.6 70deg / .8))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(1 0 40deg), oklch(1 0 60deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(1 0 60deg), oklch(1 0 40deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(1 0 50deg), oklch(1 0 330deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(1 0 330deg), oklch(1 0 50deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(1 0 20deg), oklch(1 0 320deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(1 0 320deg), oklch(1 0 20deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(1 0 40deg), oklch(1 0 60deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(1 0 60deg), oklch(1 0 40deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(1 0 50deg), oklch(1 0 330deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(1 0 330deg), oklch(1 0 50deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(1 0 20deg), oklch(1 0 320deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch shorter hue, oklch(1 0 320deg), oklch(1 0 20deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(1 0 40deg), oklch(1 0 60deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(1 0 60deg), oklch(1 0 40deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(1 0 50deg), oklch(1 0 330deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(1 0 330deg), oklch(1 0 50deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(1 0 20deg), oklch(1 0 320deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch longer hue, oklch(1 0 320deg), oklch(1 0 20deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(1 0 40deg), oklch(1 0 60deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(1 0 60deg), oklch(1 0 40deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(1 0 50deg), oklch(1 0 330deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(1 0 330deg), oklch(1 0 50deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(1 0 20deg), oklch(1 0 320deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch increasing hue, oklch(1 0 320deg), oklch(1 0 20deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(1 0 40deg), oklch(1 0 60deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(1 0 60deg), oklch(1 0 40deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(1 0 50deg), oklch(1 0 330deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(1 0 330deg), oklch(1 0 50deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(1 0 20deg), oklch(1 0 320deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch decreasing hue, oklch(1 0 320deg), oklch(1 0 20deg))" should set the property value PASS e.style['color'] = "color-mix(in oklch, oklch(none none none), oklch(none none none))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(none none none), oklch(50 60 70deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg), oklch(none none none))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 none), oklch(50 60 70deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg), oklch(50 60 none))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(none 20 30deg), oklch(50 none 70deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg / none), oklch(50 60 70deg))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg / none), oklch(50 60 70deg / 0.5))" should set the property value -PASS e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg / none), oklch(50 60 70deg / none))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(none none none), oklch(0.5 0.6 70deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(none none none))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 none), oklch(0.5 0.6 70deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(0.5 0.6 none))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(none 0.2 30deg), oklch(0.5 none 70deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / none), oklch(0.5 0.6 70deg))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / none), oklch(0.5 0.6 70deg / 0.5))" should set the property value +PASS e.style['color'] = "color-mix(in oklch, oklch(0.1 0.2 30deg / none), oklch(0.5 0.6 70deg / none))" should set the property value PASS e.style['color'] = "color-mix(in lab, lab(10 20 30), lab(50 60 70))" should set the property value PASS e.style['color'] = "color-mix(in lab, lab(10 20 30) 25%, lab(50 60 70))" should set the property value PASS e.style['color'] = "color-mix(in lab, 25% lab(10 20 30), lab(50 60 70))" should set the property value @@ -280,33 +280,33 @@ PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / none), lab(50 60 70))" should set the property value PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / none), lab(50 60 70 / 0.5))" should set the property value PASS e.style['color'] = "color-mix(in lab, lab(10 20 30 / none), lab(50 60 70 / none))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30), oklab(50 60 70))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30) 25%, oklab(50 60 70))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, 25% oklab(10 20 30), oklab(50 60 70))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30), 25% oklab(50 60 70))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30), oklab(50 60 70) 25%)" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30) 25%, oklab(50 60 70) 75%)" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30) 30%, oklab(50 60 70) 90%)" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30) 12.5%, oklab(50 60 70) 37.5%)" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30) 0%, oklab(50 60 70))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30 / .4), oklab(50 60 70 / .8))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30 / .4) 25%, oklab(50 60 70 / .8))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, 25% oklab(10 20 30 / .4), oklab(50 60 70 / .8))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30 / .4), 25% oklab(50 60 70 / .8))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30 / .4), oklab(50 60 70 / .8) 25%)" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30 / .4) 25%, oklab(50 60 70 / .8) 75%)" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30 / .4) 30%, oklab(50 60 70 / .8) 90%)" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30 / .4) 12.5%, oklab(50 60 70 / .8) 37.5%)" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30 / .4) 0%, oklab(50 60 70 / .8))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3) 25%, oklab(0.5 0.6 0.7))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, 25% oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3), 25% oklab(0.5 0.6 0.7))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7) 25%)" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3) 25%, oklab(0.5 0.6 0.7) 75%)" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3) 30%, oklab(0.5 0.6 0.7) 90%)" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3) 12.5%, oklab(0.5 0.6 0.7) 37.5%)" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3) 0%, oklab(0.5 0.6 0.7))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4), oklab(0.5 0.6 0.7 / .8))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 25%, oklab(0.5 0.6 0.7 / .8))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, 25% oklab(0.1 0.2 0.3 / .4), oklab(0.5 0.6 0.7 / .8))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4), 25% oklab(0.5 0.6 0.7 / .8))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4), oklab(0.5 0.6 0.7 / .8) 25%)" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 25%, oklab(0.5 0.6 0.7 / .8) 75%)" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 30%, oklab(0.5 0.6 0.7 / .8) 90%)" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 12.5%, oklab(0.5 0.6 0.7 / .8) 37.5%)" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 0%, oklab(0.5 0.6 0.7 / .8))" should set the property value PASS e.style['color'] = "color-mix(in oklab, oklab(none none none), oklab(none none none))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(none none none), oklab(50 60 70))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30), oklab(none none none))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 none), oklab(50 60 70))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30), oklab(50 60 none))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(none 20 30), oklab(50 none 70))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30 / none), oklab(50 60 70))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30 / none), oklab(50 60 70 / 0.5))" should set the property value -PASS e.style['color'] = "color-mix(in oklab, oklab(10 20 30 / none), oklab(50 60 70 / none))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(none none none), oklab(0.5 0.6 0.7))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(none none none))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 none), oklab(0.5 0.6 0.7))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 none))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(none 0.2 0.3), oklab(0.5 none 0.7))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7 / 0.5))" should set the property value +PASS e.style['color'] = "color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7 / none))" should set the property value PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3), color(srgb .5 .6 .7))" should set the property value PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3) 25%, color(srgb .5 .6 .7))" should set the property value PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3), color(srgb .5 .6 .7) 25%)" should set the property value
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function.html index cc23659c..6e5a129 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function.html
@@ -95,9 +95,9 @@ test_valid_value(`color`, `color-mix(in hsl, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`); test_valid_value(`color`, `color-mix(in hsl, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)`); test_valid_value(`color`, `color-mix(in hsl, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)`); - test_valid_value(`color`, `color-mix(in hsl, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`); + test_valid_value(`color`, `color-mix(in hsl, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`); test_valid_value(`color`, `color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`); - test_valid_value(`color`, `color-mix(in hsl, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`); + test_valid_value(`color`, `color-mix(in hsl, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`); test_valid_value(`color`, `color-mix(in hsl, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hsl, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`); test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))`, `color-mix(in hwb, rgb(26, 204, 26), rgb(153, 115, 77))`); @@ -170,9 +170,9 @@ test_valid_value(`color`, `color-mix(in hwb, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`); test_valid_value(`color`, `color-mix(in hwb, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)`); test_valid_value(`color`, `color-mix(in hwb, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)`); - test_valid_value(`color`, `color-mix(in hwb, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`); + test_valid_value(`color`, `color-mix(in hwb, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`); test_valid_value(`color`, `color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`); - test_valid_value(`color`, `color-mix(in hwb, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`); + test_valid_value(`color`, `color-mix(in hwb, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`); test_valid_value(`color`, `color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`); // lch() @@ -242,70 +242,70 @@ test_valid_value(`color`, `color-mix(in lch, lch(10 20 30deg / none), lch(50 60 70deg / none))`, `color-mix(in lch, lch(10 20 30 / none), lch(50 60 70 / none))`); // oklch() - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg), oklch(50 60 70deg))`, `color-mix(in oklch, oklch(10 20 30), oklch(50 60 70))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg) 25%, oklch(50 60 70deg))`, `color-mix(in oklch, oklch(10 20 30) 25%, oklch(50 60 70))`); - test_valid_value(`color`, `color-mix(in oklch, 25% oklch(10 20 30deg), oklch(50 60 70deg))`, `color-mix(in oklch, oklch(10 20 30) 25%, oklch(50 60 70))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg), 25% oklch(50 60 70deg))`, `color-mix(in oklch, oklch(10 20 30), oklch(50 60 70) 25%)`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg), oklch(50 60 70deg) 25%)`, `color-mix(in oklch, oklch(10 20 30), oklch(50 60 70) 25%)`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg) 25%, oklch(50 60 70deg) 75%)`, `color-mix(in oklch, oklch(10 20 30) 25%, oklch(50 60 70) 75%)`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg) 30%, oklch(50 60 70deg) 90%)`, `color-mix(in oklch, oklch(10 20 30) 30%, oklch(50 60 70) 90%)`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg) 12.5%, oklch(50 60 70deg) 37.5%)`, `color-mix(in oklch, oklch(10 20 30) 12.5%, oklch(50 60 70) 37.5%)`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg) 0%, oklch(50 60 70deg))`, `color-mix(in oklch, oklch(10 20 30) 0%, oklch(50 60 70))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(0.5 0.6 70deg))`, `color-mix(in oklch, oklch(0.1 0.2 30), oklch(0.5 0.6 70))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg) 25%, oklch(0.5 0.6 70deg))`, `color-mix(in oklch, oklch(0.1 0.2 30) 25%, oklch(0.5 0.6 70))`); + test_valid_value(`color`, `color-mix(in oklch, 25% oklch(0.1 0.2 30deg), oklch(0.5 0.6 70deg))`, `color-mix(in oklch, oklch(0.1 0.2 30) 25%, oklch(0.5 0.6 70))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg), 25% oklch(0.5 0.6 70deg))`, `color-mix(in oklch, oklch(0.1 0.2 30), oklch(0.5 0.6 70) 25%)`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(0.5 0.6 70deg) 25%)`, `color-mix(in oklch, oklch(0.1 0.2 30), oklch(0.5 0.6 70) 25%)`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg) 25%, oklch(0.5 0.6 70deg) 75%)`, `color-mix(in oklch, oklch(0.1 0.2 30) 25%, oklch(0.5 0.6 70) 75%)`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg) 30%, oklch(0.5 0.6 70deg) 90%)`, `color-mix(in oklch, oklch(0.1 0.2 30) 30%, oklch(0.5 0.6 70) 90%)`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg) 12.5%, oklch(0.5 0.6 70deg) 37.5%)`, `color-mix(in oklch, oklch(0.1 0.2 30) 12.5%, oklch(0.5 0.6 70) 37.5%)`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg) 0%, oklch(0.5 0.6 70deg))`, `color-mix(in oklch, oklch(0.1 0.2 30) 0%, oklch(0.5 0.6 70))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4), oklch(50 60 70deg / .8))`, `color-mix(in oklch, oklch(10 20 30 / 0.4), oklch(50 60 70 / 0.8))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4) 25%, oklch(50 60 70deg / .8))`, `color-mix(in oklch, oklch(10 20 30 / 0.4) 25%, oklch(50 60 70 / 0.8))`); - test_valid_value(`color`, `color-mix(in oklch, 25% oklch(10 20 30deg / .4), oklch(50 60 70deg / .8))`, `color-mix(in oklch, oklch(10 20 30 / 0.4) 25%, oklch(50 60 70 / 0.8))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4), 25% oklch(50 60 70deg / .8))`, `color-mix(in oklch, oklch(10 20 30 / 0.4), oklch(50 60 70 / 0.8) 25%)`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4), oklch(50 60 70deg / .8) 25%)`, `color-mix(in oklch, oklch(10 20 30 / 0.4), oklch(50 60 70 / 0.8) 25%)`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4) 25%, oklch(50 60 70deg / .8) 75%)`, `color-mix(in oklch, oklch(10 20 30 / 0.4) 25%, oklch(50 60 70 / 0.8) 75%)`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4) 30%, oklch(50 60 70deg / .8) 90%)`, `color-mix(in oklch, oklch(10 20 30 / 0.4) 30%, oklch(50 60 70 / 0.8) 90%)`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4) 12.5%, oklch(50 60 70deg / .8) 37.5%)`, `color-mix(in oklch, oklch(10 20 30 / 0.4) 12.5%, oklch(50 60 70 / 0.8) 37.5%)`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / .4) 0%, oklch(50 60 70deg / .8))`, `color-mix(in oklch, oklch(10 20 30 / 0.4) 0%, oklch(50 60 70 / 0.8))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4), oklch(0.5 0.6 70deg / .8))`, `color-mix(in oklch, oklch(0.1 0.2 30 / 0.4), oklch(0.5 0.6 70 / 0.8))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 25%, oklch(0.5 0.6 70deg / .8))`, `color-mix(in oklch, oklch(0.1 0.2 30 / 0.4) 25%, oklch(0.5 0.6 70 / 0.8))`); + test_valid_value(`color`, `color-mix(in oklch, 25% oklch(0.1 0.2 30deg / .4), oklch(0.5 0.6 70deg / .8))`, `color-mix(in oklch, oklch(0.1 0.2 30 / 0.4) 25%, oklch(0.5 0.6 70 / 0.8))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4), 25% oklch(0.5 0.6 70deg / .8))`, `color-mix(in oklch, oklch(0.1 0.2 30 / 0.4), oklch(0.5 0.6 70 / 0.8) 25%)`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4), oklch(0.5 0.6 70deg / .8) 25%)`, `color-mix(in oklch, oklch(0.1 0.2 30 / 0.4), oklch(0.5 0.6 70 / 0.8) 25%)`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 25%, oklch(0.5 0.6 70deg / .8) 75%)`, `color-mix(in oklch, oklch(0.1 0.2 30 / 0.4) 25%, oklch(0.5 0.6 70 / 0.8) 75%)`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 30%, oklch(0.5 0.6 70deg / .8) 90%)`, `color-mix(in oklch, oklch(0.1 0.2 30 / 0.4) 30%, oklch(0.5 0.6 70 / 0.8) 90%)`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 12.5%, oklch(0.5 0.6 70deg / .8) 37.5%)`, `color-mix(in oklch, oklch(0.1 0.2 30 / 0.4) 12.5%, oklch(0.5 0.6 70 / 0.8) 37.5%)`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / .4) 0%, oklch(0.5 0.6 70deg / .8))`, `color-mix(in oklch, oklch(0.1 0.2 30 / 0.4) 0%, oklch(0.5 0.6 70 / 0.8))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(100 0 40deg), oklch(100 0 60deg))`, `color-mix(in oklch, oklch(100 0 40), oklch(100 0 60))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(100 0 60deg), oklch(100 0 40deg))`, `color-mix(in oklch, oklch(100 0 60), oklch(100 0 40))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(100 0 50deg), oklch(100 0 330deg))`, `color-mix(in oklch, oklch(100 0 50), oklch(100 0 330))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(100 0 330deg), oklch(100 0 50deg))`, `color-mix(in oklch, oklch(100 0 330), oklch(100 0 50))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(100 0 20deg), oklch(100 0 320deg))`, `color-mix(in oklch, oklch(100 0 20), oklch(100 0 320))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(100 0 320deg), oklch(100 0 20deg))`, `color-mix(in oklch, oklch(100 0 320), oklch(100 0 20))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(1 0 40deg), oklch(1 0 60deg))`, `color-mix(in oklch, oklch(1 0 40), oklch(1 0 60))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(1 0 60deg), oklch(1 0 40deg))`, `color-mix(in oklch, oklch(1 0 60), oklch(1 0 40))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(1 0 50deg), oklch(1 0 330deg))`, `color-mix(in oklch, oklch(1 0 50), oklch(1 0 330))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(1 0 330deg), oklch(1 0 50deg))`, `color-mix(in oklch, oklch(1 0 330), oklch(1 0 50))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(1 0 20deg), oklch(1 0 320deg))`, `color-mix(in oklch, oklch(1 0 20), oklch(1 0 320))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(1 0 320deg), oklch(1 0 20deg))`, `color-mix(in oklch, oklch(1 0 320), oklch(1 0 20))`); - test_valid_value(`color`, `color-mix(in oklch shorter hue, oklch(100 0 40deg), oklch(100 0 60deg))`, `color-mix(in oklch, oklch(100 0 40), oklch(100 0 60))`); - test_valid_value(`color`, `color-mix(in oklch shorter hue, oklch(100 0 60deg), oklch(100 0 40deg))`, `color-mix(in oklch, oklch(100 0 60), oklch(100 0 40))`); - test_valid_value(`color`, `color-mix(in oklch shorter hue, oklch(100 0 50deg), oklch(100 0 330deg))`, `color-mix(in oklch, oklch(100 0 50), oklch(100 0 330))`); - test_valid_value(`color`, `color-mix(in oklch shorter hue, oklch(100 0 330deg), oklch(100 0 50deg))`, `color-mix(in oklch, oklch(100 0 330), oklch(100 0 50))`); - test_valid_value(`color`, `color-mix(in oklch shorter hue, oklch(100 0 20deg), oklch(100 0 320deg))`, `color-mix(in oklch, oklch(100 0 20), oklch(100 0 320))`); - test_valid_value(`color`, `color-mix(in oklch shorter hue, oklch(100 0 320deg), oklch(100 0 20deg))`, `color-mix(in oklch, oklch(100 0 320), oklch(100 0 20))`); + test_valid_value(`color`, `color-mix(in oklch shorter hue, oklch(1 0 40deg), oklch(1 0 60deg))`, `color-mix(in oklch, oklch(1 0 40), oklch(1 0 60))`); + test_valid_value(`color`, `color-mix(in oklch shorter hue, oklch(1 0 60deg), oklch(1 0 40deg))`, `color-mix(in oklch, oklch(1 0 60), oklch(1 0 40))`); + test_valid_value(`color`, `color-mix(in oklch shorter hue, oklch(1 0 50deg), oklch(1 0 330deg))`, `color-mix(in oklch, oklch(1 0 50), oklch(1 0 330))`); + test_valid_value(`color`, `color-mix(in oklch shorter hue, oklch(1 0 330deg), oklch(1 0 50deg))`, `color-mix(in oklch, oklch(1 0 330), oklch(1 0 50))`); + test_valid_value(`color`, `color-mix(in oklch shorter hue, oklch(1 0 20deg), oklch(1 0 320deg))`, `color-mix(in oklch, oklch(1 0 20), oklch(1 0 320))`); + test_valid_value(`color`, `color-mix(in oklch shorter hue, oklch(1 0 320deg), oklch(1 0 20deg))`, `color-mix(in oklch, oklch(1 0 320), oklch(1 0 20))`); - test_valid_value(`color`, `color-mix(in oklch longer hue, oklch(100 0 40deg), oklch(100 0 60deg))`, `color-mix(in oklch longer hue, oklch(100 0 40), oklch(100 0 60))`); - test_valid_value(`color`, `color-mix(in oklch longer hue, oklch(100 0 60deg), oklch(100 0 40deg))`, `color-mix(in oklch longer hue, oklch(100 0 60), oklch(100 0 40))`); - test_valid_value(`color`, `color-mix(in oklch longer hue, oklch(100 0 50deg), oklch(100 0 330deg))`, `color-mix(in oklch longer hue, oklch(100 0 50), oklch(100 0 330))`); - test_valid_value(`color`, `color-mix(in oklch longer hue, oklch(100 0 330deg), oklch(100 0 50deg))`, `color-mix(in oklch longer hue, oklch(100 0 330), oklch(100 0 50))`); - test_valid_value(`color`, `color-mix(in oklch longer hue, oklch(100 0 20deg), oklch(100 0 320deg))`, `color-mix(in oklch longer hue, oklch(100 0 20), oklch(100 0 320))`); - test_valid_value(`color`, `color-mix(in oklch longer hue, oklch(100 0 320deg), oklch(100 0 20deg))`, `color-mix(in oklch longer hue, oklch(100 0 320), oklch(100 0 20))`); + test_valid_value(`color`, `color-mix(in oklch longer hue, oklch(1 0 40deg), oklch(1 0 60deg))`, `color-mix(in oklch longer hue, oklch(1 0 40), oklch(1 0 60))`); + test_valid_value(`color`, `color-mix(in oklch longer hue, oklch(1 0 60deg), oklch(1 0 40deg))`, `color-mix(in oklch longer hue, oklch(1 0 60), oklch(1 0 40))`); + test_valid_value(`color`, `color-mix(in oklch longer hue, oklch(1 0 50deg), oklch(1 0 330deg))`, `color-mix(in oklch longer hue, oklch(1 0 50), oklch(1 0 330))`); + test_valid_value(`color`, `color-mix(in oklch longer hue, oklch(1 0 330deg), oklch(1 0 50deg))`, `color-mix(in oklch longer hue, oklch(1 0 330), oklch(1 0 50))`); + test_valid_value(`color`, `color-mix(in oklch longer hue, oklch(1 0 20deg), oklch(1 0 320deg))`, `color-mix(in oklch longer hue, oklch(1 0 20), oklch(1 0 320))`); + test_valid_value(`color`, `color-mix(in oklch longer hue, oklch(1 0 320deg), oklch(1 0 20deg))`, `color-mix(in oklch longer hue, oklch(1 0 320), oklch(1 0 20))`); - test_valid_value(`color`, `color-mix(in oklch increasing hue, oklch(100 0 40deg), oklch(100 0 60deg))`, `color-mix(in oklch increasing hue, oklch(100 0 40), oklch(100 0 60))`); - test_valid_value(`color`, `color-mix(in oklch increasing hue, oklch(100 0 60deg), oklch(100 0 40deg))`, `color-mix(in oklch increasing hue, oklch(100 0 60), oklch(100 0 40))`); - test_valid_value(`color`, `color-mix(in oklch increasing hue, oklch(100 0 50deg), oklch(100 0 330deg))`, `color-mix(in oklch increasing hue, oklch(100 0 50), oklch(100 0 330))`); - test_valid_value(`color`, `color-mix(in oklch increasing hue, oklch(100 0 330deg), oklch(100 0 50deg))`, `color-mix(in oklch increasing hue, oklch(100 0 330), oklch(100 0 50))`); - test_valid_value(`color`, `color-mix(in oklch increasing hue, oklch(100 0 20deg), oklch(100 0 320deg))`, `color-mix(in oklch increasing hue, oklch(100 0 20), oklch(100 0 320))`); - test_valid_value(`color`, `color-mix(in oklch increasing hue, oklch(100 0 320deg), oklch(100 0 20deg))`, `color-mix(in oklch increasing hue, oklch(100 0 320), oklch(100 0 20))`); + test_valid_value(`color`, `color-mix(in oklch increasing hue, oklch(1 0 40deg), oklch(1 0 60deg))`, `color-mix(in oklch increasing hue, oklch(1 0 40), oklch(1 0 60))`); + test_valid_value(`color`, `color-mix(in oklch increasing hue, oklch(1 0 60deg), oklch(1 0 40deg))`, `color-mix(in oklch increasing hue, oklch(1 0 60), oklch(1 0 40))`); + test_valid_value(`color`, `color-mix(in oklch increasing hue, oklch(1 0 50deg), oklch(1 0 330deg))`, `color-mix(in oklch increasing hue, oklch(1 0 50), oklch(1 0 330))`); + test_valid_value(`color`, `color-mix(in oklch increasing hue, oklch(1 0 330deg), oklch(1 0 50deg))`, `color-mix(in oklch increasing hue, oklch(1 0 330), oklch(1 0 50))`); + test_valid_value(`color`, `color-mix(in oklch increasing hue, oklch(1 0 20deg), oklch(1 0 320deg))`, `color-mix(in oklch increasing hue, oklch(1 0 20), oklch(1 0 320))`); + test_valid_value(`color`, `color-mix(in oklch increasing hue, oklch(1 0 320deg), oklch(1 0 20deg))`, `color-mix(in oklch increasing hue, oklch(1 0 320), oklch(1 0 20))`); - test_valid_value(`color`, `color-mix(in oklch decreasing hue, oklch(100 0 40deg), oklch(100 0 60deg))`, `color-mix(in oklch decreasing hue, oklch(100 0 40), oklch(100 0 60))`); - test_valid_value(`color`, `color-mix(in oklch decreasing hue, oklch(100 0 60deg), oklch(100 0 40deg))`, `color-mix(in oklch decreasing hue, oklch(100 0 60), oklch(100 0 40))`); - test_valid_value(`color`, `color-mix(in oklch decreasing hue, oklch(100 0 50deg), oklch(100 0 330deg))`, `color-mix(in oklch decreasing hue, oklch(100 0 50), oklch(100 0 330))`); - test_valid_value(`color`, `color-mix(in oklch decreasing hue, oklch(100 0 330deg), oklch(100 0 50deg))`, `color-mix(in oklch decreasing hue, oklch(100 0 330), oklch(100 0 50))`); - test_valid_value(`color`, `color-mix(in oklch decreasing hue, oklch(100 0 20deg), oklch(100 0 320deg))`, `color-mix(in oklch decreasing hue, oklch(100 0 20), oklch(100 0 320))`); - test_valid_value(`color`, `color-mix(in oklch decreasing hue, oklch(100 0 320deg), oklch(100 0 20deg))`, `color-mix(in oklch decreasing hue, oklch(100 0 320), oklch(100 0 20))`); + test_valid_value(`color`, `color-mix(in oklch decreasing hue, oklch(1 0 40deg), oklch(1 0 60deg))`, `color-mix(in oklch decreasing hue, oklch(1 0 40), oklch(1 0 60))`); + test_valid_value(`color`, `color-mix(in oklch decreasing hue, oklch(1 0 60deg), oklch(1 0 40deg))`, `color-mix(in oklch decreasing hue, oklch(1 0 60), oklch(1 0 40))`); + test_valid_value(`color`, `color-mix(in oklch decreasing hue, oklch(1 0 50deg), oklch(1 0 330deg))`, `color-mix(in oklch decreasing hue, oklch(1 0 50), oklch(1 0 330))`); + test_valid_value(`color`, `color-mix(in oklch decreasing hue, oklch(1 0 330deg), oklch(1 0 50deg))`, `color-mix(in oklch decreasing hue, oklch(1 0 330), oklch(1 0 50))`); + test_valid_value(`color`, `color-mix(in oklch decreasing hue, oklch(1 0 20deg), oklch(1 0 320deg))`, `color-mix(in oklch decreasing hue, oklch(1 0 20), oklch(1 0 320))`); + test_valid_value(`color`, `color-mix(in oklch decreasing hue, oklch(1 0 320deg), oklch(1 0 20deg))`, `color-mix(in oklch decreasing hue, oklch(1 0 320), oklch(1 0 20))`); test_valid_value(`color`, `color-mix(in oklch, oklch(none none none), oklch(none none none))`, `color-mix(in oklch, oklch(none none none), oklch(none none none))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(none none none), oklch(50 60 70deg))`, `color-mix(in oklch, oklch(none none none), oklch(50 60 70))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg), oklch(none none none))`, `color-mix(in oklch, oklch(10 20 30), oklch(none none none))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 none), oklch(50 60 70deg))`, `color-mix(in oklch, oklch(10 20 none), oklch(50 60 70))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg), oklch(50 60 none))`, `color-mix(in oklch, oklch(10 20 30), oklch(50 60 none))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(none 20 30deg), oklch(50 none 70deg))`, `color-mix(in oklch, oklch(none 20 30), oklch(50 none 70))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / none), oklch(50 60 70deg))`, `color-mix(in oklch, oklch(10 20 30 / none), oklch(50 60 70))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / none), oklch(50 60 70deg / 0.5))`, `color-mix(in oklch, oklch(10 20 30 / none), oklch(50 60 70 / 0.5))`); - test_valid_value(`color`, `color-mix(in oklch, oklch(10 20 30deg / none), oklch(50 60 70deg / none))`, `color-mix(in oklch, oklch(10 20 30 / none), oklch(50 60 70 / none))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(none none none), oklch(0.5 0.6 70deg))`, `color-mix(in oklch, oklch(none none none), oklch(0.5 0.6 70))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(none none none))`, `color-mix(in oklch, oklch(0.1 0.2 30), oklch(none none none))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 none), oklch(0.5 0.6 70deg))`, `color-mix(in oklch, oklch(0.1 0.2 none), oklch(0.5 0.6 70))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg), oklch(0.5 0.6 none))`, `color-mix(in oklch, oklch(0.1 0.2 30), oklch(0.5 0.6 none))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(none 0.2 30deg), oklch(0.5 none 70deg))`, `color-mix(in oklch, oklch(none 0.2 30), oklch(0.5 none 70))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / none), oklch(0.5 0.6 70deg))`, `color-mix(in oklch, oklch(0.1 0.2 30 / none), oklch(0.5 0.6 70))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / none), oklch(0.5 0.6 70deg / 0.5))`, `color-mix(in oklch, oklch(0.1 0.2 30 / none), oklch(0.5 0.6 70 / 0.5))`); + test_valid_value(`color`, `color-mix(in oklch, oklch(0.1 0.2 30deg / none), oklch(0.5 0.6 70deg / none))`, `color-mix(in oklch, oklch(0.1 0.2 30 / none), oklch(0.5 0.6 70 / none))`); // lab() test_valid_value(`color`, `color-mix(in lab, lab(10 20 30), lab(50 60 70))`, `color-mix(in lab, lab(10 20 30), lab(50 60 70))`); @@ -339,35 +339,35 @@ test_valid_value(`color`, `color-mix(in lab, lab(10 20 30 / none), lab(50 60 70 / none))`, `color-mix(in lab, lab(10 20 30 / none), lab(50 60 70 / none))`); // oklab() - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30), oklab(50 60 70))`, `color-mix(in oklab, oklab(10 20 30), oklab(50 60 70))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30) 25%, oklab(50 60 70))`, `color-mix(in oklab, oklab(10 20 30) 25%, oklab(50 60 70))`); - test_valid_value(`color`, `color-mix(in oklab, 25% oklab(10 20 30), oklab(50 60 70))`, `color-mix(in oklab, oklab(10 20 30) 25%, oklab(50 60 70))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30), 25% oklab(50 60 70))`, `color-mix(in oklab, oklab(10 20 30), oklab(50 60 70) 25%)`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30), oklab(50 60 70) 25%)`, `color-mix(in oklab, oklab(10 20 30), oklab(50 60 70) 25%)`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30) 25%, oklab(50 60 70) 75%)`, `color-mix(in oklab, oklab(10 20 30) 25%, oklab(50 60 70) 75%)`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30) 30%, oklab(50 60 70) 90%)`, `color-mix(in oklab, oklab(10 20 30) 30%, oklab(50 60 70) 90%)`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30) 12.5%, oklab(50 60 70) 37.5%)`, `color-mix(in oklab, oklab(10 20 30) 12.5%, oklab(50 60 70) 37.5%)`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30) 0%, oklab(50 60 70))`, `color-mix(in oklab, oklab(10 20 30) 0%, oklab(50 60 70))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7))`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 25%, oklab(0.5 0.6 0.7))`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 25%, oklab(0.5 0.6 0.7))`); + test_valid_value(`color`, `color-mix(in oklab, 25% oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7))`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 25%, oklab(0.5 0.6 0.7))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3), 25% oklab(0.5 0.6 0.7))`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7) 25%)`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7) 25%)`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 0.7) 25%)`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 25%, oklab(0.5 0.6 0.7) 75%)`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 25%, oklab(0.5 0.6 0.7) 75%)`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 30%, oklab(0.5 0.6 0.7) 90%)`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 30%, oklab(0.5 0.6 0.7) 90%)`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 12.5%, oklab(0.5 0.6 0.7) 37.5%)`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 12.5%, oklab(0.5 0.6 0.7) 37.5%)`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 0%, oklab(0.5 0.6 0.7))`, `color-mix(in oklab, oklab(0.1 0.2 0.3) 0%, oklab(0.5 0.6 0.7))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4), oklab(50 60 70 / .8))`, `color-mix(in oklab, oklab(10 20 30 / 0.4), oklab(50 60 70 / 0.8))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4) 25%, oklab(50 60 70 / .8))`, `color-mix(in oklab, oklab(10 20 30 / 0.4) 25%, oklab(50 60 70 / 0.8))`); - test_valid_value(`color`, `color-mix(in oklab, 25% oklab(10 20 30 / .4), oklab(50 60 70 / .8))`, `color-mix(in oklab, oklab(10 20 30 / 0.4) 25%, oklab(50 60 70 / 0.8))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4), 25% oklab(50 60 70 / .8))`, `color-mix(in oklab, oklab(10 20 30 / 0.4), oklab(50 60 70 / 0.8) 25%)`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4), oklab(50 60 70 / .8) 25%)`, `color-mix(in oklab, oklab(10 20 30 / 0.4), oklab(50 60 70 / 0.8) 25%)`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4) 25%, oklab(50 60 70 / .8) 75%)`, `color-mix(in oklab, oklab(10 20 30 / 0.4) 25%, oklab(50 60 70 / 0.8) 75%)`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4) 30%, oklab(50 60 70 / .8) 90%)`, `color-mix(in oklab, oklab(10 20 30 / 0.4) 30%, oklab(50 60 70 / 0.8) 90%)`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4) 12.5%, oklab(50 60 70 / .8) 37.5%)`, `color-mix(in oklab, oklab(10 20 30 / 0.4) 12.5%, oklab(50 60 70 / 0.8) 37.5%)`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30 / .4) 0%, oklab(50 60 70 / .8))`, `color-mix(in oklab, oklab(10 20 30 / 0.4) 0%, oklab(50 60 70 / 0.8))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4), oklab(0.5 0.6 0.7 / .8))`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / 0.4), oklab(0.5 0.6 0.7 / 0.8))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 25%, oklab(0.5 0.6 0.7 / .8))`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / 0.4) 25%, oklab(0.5 0.6 0.7 / 0.8))`); + test_valid_value(`color`, `color-mix(in oklab, 25% oklab(0.1 0.2 0.3 / .4), oklab(0.5 0.6 0.7 / .8))`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / 0.4) 25%, oklab(0.5 0.6 0.7 / 0.8))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4), 25% oklab(0.5 0.6 0.7 / .8))`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / 0.4), oklab(0.5 0.6 0.7 / 0.8) 25%)`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4), oklab(0.5 0.6 0.7 / .8) 25%)`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / 0.4), oklab(0.5 0.6 0.7 / 0.8) 25%)`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 25%, oklab(0.5 0.6 0.7 / .8) 75%)`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / 0.4) 25%, oklab(0.5 0.6 0.7 / 0.8) 75%)`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 30%, oklab(0.5 0.6 0.7 / .8) 90%)`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / 0.4) 30%, oklab(0.5 0.6 0.7 / 0.8) 90%)`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 12.5%, oklab(0.5 0.6 0.7 / .8) 37.5%)`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / 0.4) 12.5%, oklab(0.5 0.6 0.7 / 0.8) 37.5%)`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / .4) 0%, oklab(0.5 0.6 0.7 / .8))`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / 0.4) 0%, oklab(0.5 0.6 0.7 / 0.8))`); test_valid_value(`color`, `color-mix(in oklab, oklab(none none none), oklab(none none none))`, `color-mix(in oklab, oklab(none none none), oklab(none none none))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(none none none), oklab(50 60 70))`, `color-mix(in oklab, oklab(none none none), oklab(50 60 70))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30), oklab(none none none))`, `color-mix(in oklab, oklab(10 20 30), oklab(none none none))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 none), oklab(50 60 70))`, `color-mix(in oklab, oklab(10 20 none), oklab(50 60 70))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30), oklab(50 60 none))`, `color-mix(in oklab, oklab(10 20 30), oklab(50 60 none))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(none 20 30), oklab(50 none 70))`, `color-mix(in oklab, oklab(none 20 30), oklab(50 none 70))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30 / none), oklab(50 60 70))`, `color-mix(in oklab, oklab(10 20 30 / none), oklab(50 60 70))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30 / none), oklab(50 60 70 / 0.5))`, `color-mix(in oklab, oklab(10 20 30 / none), oklab(50 60 70 / 0.5))`); - test_valid_value(`color`, `color-mix(in oklab, oklab(10 20 30 / none), oklab(50 60 70 / none))`, `color-mix(in oklab, oklab(10 20 30 / none), oklab(50 60 70 / none))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(none none none), oklab(0.5 0.6 0.7))`, `color-mix(in oklab, oklab(none none none), oklab(0.5 0.6 0.7))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(none none none))`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(none none none))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 none), oklab(0.5 0.6 0.7))`, `color-mix(in oklab, oklab(0.1 0.2 none), oklab(0.5 0.6 0.7))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 none))`, `color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(0.5 0.6 none))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(none 0.2 0.3), oklab(0.5 none 0.7))`, `color-mix(in oklab, oklab(none 0.2 0.3), oklab(0.5 none 0.7))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7))`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7 / 0.5))`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7 / 0.5))`); + test_valid_value(`color`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7 / none))`, `color-mix(in oklab, oklab(0.1 0.2 0.3 / none), oklab(0.5 0.6 0.7 / none))`); for (const colorSpace of [ "srgb", "srgb-linear", "xyz", "xyz-d50", "xyz-d65" ]) { const resultColorSpace = colorSpace == "xyz" ? "xyz-d65" : colorSpace;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-lab-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-lab-expected.txt new file mode 100644 index 0000000..d41facc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-lab-expected.txt
@@ -0,0 +1,96 @@ +This is a testharness.js-based test. +Found 92 tests; 86 PASS, 6 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS e.style['color'] = "lab(0 0 0)" should set the property value +PASS e.style['color'] = "lab(0 0 0 / 1)" should set the property value +PASS e.style['color'] = "lab(0 0 0 / 0.5)" should set the property value +PASS e.style['color'] = "lab(20 0 10/0.5)" should set the property value +PASS e.style['color'] = "lab(20 0 10/50%)" should set the property value +FAIL e.style['color'] = "lab(400 0 10/50%)" should set the property value assert_equals: serialization should be canonical expected "lab(100 0 10 / 0.5)" but got "lab(400 0 10 / 0.5)" +PASS e.style['color'] = "lab(50 -160 160)" should set the property value +PASS e.style['color'] = "lab(50 -200 200)" should set the property value +PASS e.style['color'] = "lab(0 0 0 / -10%)" should set the property value +PASS e.style['color'] = "lab(0 0 0 / 110%)" should set the property value +PASS e.style['color'] = "lab(0 0 0 / 300%)" should set the property value +PASS e.style['color'] = "lab(-40 0 0)" should set the property value +PASS e.style['color'] = "lab(50 -20 0)" should set the property value +PASS e.style['color'] = "lab(50 0 -20)" should set the property value +FAIL e.style['color'] = "lab(calc(50 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))" should set the property value assert_equals: serialization should be canonical expected "lab(100 -0.5 1.5 / 0.5)" but got "lab(150 -0.5 1.5 / 0.5)" +PASS e.style['color'] = "lab(calc(-50 * 3) calc(0.5 + 1) calc(-1.5) / calc(-0.5 * 2))" should set the property value +PASS e.style['color'] = "lab(none none none / none)" should set the property value +PASS e.style['color'] = "lab(none none none)" should set the property value +PASS e.style['color'] = "lab(20 none none / none)" should set the property value +PASS e.style['color'] = "lab(none none none / 0.5)" should set the property value +PASS e.style['color'] = "lab(0 0 0 / none)" should set the property value +PASS e.style['color'] = "oklab(0 0 0)" should set the property value +PASS e.style['color'] = "oklab(0 0 0 / 1)" should set the property value +PASS e.style['color'] = "oklab(0 0 0 / 0.5)" should set the property value +PASS e.style['color'] = "oklab(0.2 0 0.1/0.5)" should set the property value +PASS e.style['color'] = "oklab(0.2 0 0.1/50%)" should set the property value +FAIL e.style['color'] = "oklab(4 0 0.1/50%)" should set the property value assert_equals: serialization should be canonical expected "oklab(1 0 0.1 / 0.5)" but got "oklab(4 0 0.1 / 0.5)" +PASS e.style['color'] = "oklab(0.5 -1.6 1.6)" should set the property value +PASS e.style['color'] = "oklab(0.5 -2 2)" should set the property value +PASS e.style['color'] = "oklab(0 0 0 / -10%)" should set the property value +PASS e.style['color'] = "oklab(0 0 0 / 110%)" should set the property value +PASS e.style['color'] = "oklab(0 0 0 / 300%)" should set the property value +PASS e.style['color'] = "oklab(-0.4 0 0)" should set the property value +PASS e.style['color'] = "oklab(0.5 -2 0)" should set the property value +PASS e.style['color'] = "oklab(0.5 0 -2)" should set the property value +FAIL e.style['color'] = "oklab(calc(0.5 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))" should set the property value assert_equals: serialization should be canonical expected "oklab(1 -0.5 1.5 / 0.5)" but got "oklab(1.5 -0.5 1.5 / 0.5)" +PASS e.style['color'] = "oklab(calc(-0.5 * 3) calc(0.5 + 1) calc(-1.5) / calc(-0.5 * 2))" should set the property value +PASS e.style['color'] = "oklab(none none none / none)" should set the property value +PASS e.style['color'] = "oklab(none none none)" should set the property value +PASS e.style['color'] = "oklab(0.2 none none / none)" should set the property value +PASS e.style['color'] = "oklab(none none none / 0.5)" should set the property value +PASS e.style['color'] = "oklab(0 0 0 / none)" should set the property value +PASS e.style['color'] = "lch(0 0 0deg)" should set the property value +PASS e.style['color'] = "lch(0 0 0deg / 1)" should set the property value +PASS e.style['color'] = "lch(0 0 0deg / 0.5)" should set the property value +PASS e.style['color'] = "lch(100 230 0deg / 0.5)" should set the property value +PASS e.style['color'] = "lch(20 50 20deg/0.5)" should set the property value +PASS e.style['color'] = "lch(20 50 20deg/50%)" should set the property value +PASS e.style['color'] = "lch(10 20 20deg / -10%)" should set the property value +PASS e.style['color'] = "lch(10 20 20deg / 110%)" should set the property value +PASS e.style['color'] = "lch(10 20 1.28rad)" should set the property value +PASS e.style['color'] = "lch(10 20 380deg)" should set the property value +PASS e.style['color'] = "lch(10 20 -340deg)" should set the property value +PASS e.style['color'] = "lch(10 20 740deg)" should set the property value +PASS e.style['color'] = "lch(10 20 -700deg)" should set the property value +PASS e.style['color'] = "lch(-40 0 0)" should set the property value +PASS e.style['color'] = "lch(20 -20 0)" should set the property value +PASS e.style['color'] = "lch(0 0 0 / 0.5)" should set the property value +PASS e.style['color'] = "lch(10 20 20 / 110%)" should set the property value +PASS e.style['color'] = "lch(10 20 -700)" should set the property value +FAIL e.style['color'] = "lch(calc(50 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))" should set the property value assert_equals: serialization should be canonical expected "lch(100 0 40 / 0.5)" but got "lch(150 0 40 / 0.5)" +PASS e.style['color'] = "lch(calc(-50 * 3) calc(0.5 + 1) calc(-20deg * 2) / calc(-0.5 * 2))" should set the property value +PASS e.style['color'] = "lch(none none none / none)" should set the property value +PASS e.style['color'] = "lch(none none none)" should set the property value +PASS e.style['color'] = "lch(20 none none / none)" should set the property value +PASS e.style['color'] = "lch(none none none / 0.5)" should set the property value +PASS e.style['color'] = "lch(0 0 0 / none)" should set the property value +PASS e.style['color'] = "oklch(0 0 0deg)" should set the property value +PASS e.style['color'] = "oklch(0 0 0deg / 1)" should set the property value +PASS e.style['color'] = "oklch(0 0 0deg / 0.5)" should set the property value +PASS e.style['color'] = "oklch(1 2.3 0deg / 0.5)" should set the property value +PASS e.style['color'] = "oklch(0.2 0.5 20deg/0.5)" should set the property value +PASS e.style['color'] = "oklch(0.2 0.5 20deg/50%)" should set the property value +PASS e.style['color'] = "oklch(0.1 0.2 20deg / -10%)" should set the property value +PASS e.style['color'] = "oklch(0.1 0.2 20deg / 110%)" should set the property value +PASS e.style['color'] = "oklch(0.1 0.2 1.28rad)" should set the property value +PASS e.style['color'] = "oklch(0.1 0.2 380deg)" should set the property value +PASS e.style['color'] = "oklch(0.1 0.2 -340deg)" should set the property value +PASS e.style['color'] = "oklch(0.1 0.2 740deg)" should set the property value +PASS e.style['color'] = "oklch(0.1 0.2 -700deg)" should set the property value +PASS e.style['color'] = "oklch(-4 0 0)" should set the property value +PASS e.style['color'] = "oklch(0.2 -0.2 0)" should set the property value +PASS e.style['color'] = "oklch(0 0 0 / 0.5)" should set the property value +PASS e.style['color'] = "oklch(0.1 0.2 20 / 110%)" should set the property value +PASS e.style['color'] = "oklch(0.1 0.2 -700)" should set the property value +FAIL e.style['color'] = "oklch(calc(0.5 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))" should set the property value assert_equals: serialization should be canonical expected "oklch(1 0 40 / 0.5)" but got "oklch(1.5 0 40 / 0.5)" +PASS e.style['color'] = "oklch(calc(-0.5 * 3) calc(0.5 + 1) calc(-20deg * 2) / calc(-0.5 * 2))" should set the property value +PASS e.style['color'] = "oklch(none none none / none)" should set the property value +PASS e.style['color'] = "oklch(none none none)" should set the property value +PASS e.style['color'] = "oklch(0.2 none none / none)" should set the property value +PASS e.style['color'] = "oklch(none none none / 0.5)" should set the property value +PASS e.style['color'] = "oklch(0 0 0 / none)" should set the property value +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-lab.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-lab.html index 3a5d6617..601a0ffb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-lab.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-lab.html
@@ -21,7 +21,7 @@ test_valid_value("color", "lab(0 0 0 / 0.5)", "lab(0 0 0 / 0.5)"); test_valid_value("color", "lab(20 0 10/0.5)", "lab(20 0 10 / 0.5)"); test_valid_value("color", "lab(20 0 10/50%)", "lab(20 0 10 / 0.5)"); -test_valid_value("color", "lab(400 0 10/50%)", "lab(400 0 10 / 0.5)"); +test_valid_value("color", "lab(400 0 10/50%)", "lab(100 0 10 / 0.5)"); test_valid_value("color", "lab(50 -160 160)", "lab(50 -160 160)"); test_valid_value("color", "lab(50 -200 200)", "lab(50 -200 200)"); test_valid_value("color", "lab(0 0 0 / -10%)", "lab(0 0 0 / 0)"); @@ -30,7 +30,7 @@ test_valid_value("color", "lab(-40 0 0)", "lab(0 0 0)"); test_valid_value("color", "lab(50 -20 0)", "lab(50 -20 0)"); test_valid_value("color", "lab(50 0 -20)", "lab(50 0 -20)"); -test_valid_value("color", "lab(calc(50 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))", "lab(150 -0.5 1.5 / 0.5)"); +test_valid_value("color", "lab(calc(50 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))", "lab(100 -0.5 1.5 / 0.5)"); test_valid_value("color", "lab(calc(-50 * 3) calc(0.5 + 1) calc(-1.5) / calc(-0.5 * 2))", "lab(0 1.5 -1.5 / 0)"); test_valid_value("color", "lab(none none none / none)", "lab(none none none / none)"); @@ -43,23 +43,23 @@ test_valid_value("color", "oklab(0 0 0)", "oklab(0 0 0)"); test_valid_value("color", "oklab(0 0 0 / 1)", "oklab(0 0 0)"); test_valid_value("color", "oklab(0 0 0 / 0.5)", "oklab(0 0 0 / 0.5)"); -test_valid_value("color", "oklab(20 0 10/0.5)", "oklab(20 0 10 / 0.5)"); -test_valid_value("color", "oklab(20 0 10/50%)", "oklab(20 0 10 / 0.5)"); -test_valid_value("color", "oklab(400 0 10/50%)", "oklab(400 0 10 / 0.5)"); -test_valid_value("color", "oklab(50 -160 160)", "oklab(50 -160 160)"); -test_valid_value("color", "oklab(50 -200 200)", "oklab(50 -200 200)"); +test_valid_value("color", "oklab(0.2 0 0.1/0.5)", "oklab(0.2 0 0.1 / 0.5)"); +test_valid_value("color", "oklab(0.2 0 0.1/50%)", "oklab(0.2 0 0.1 / 0.5)"); +test_valid_value("color", "oklab(4 0 0.1/50%)", "oklab(1 0 0.1 / 0.5)"); +test_valid_value("color", "oklab(0.5 -1.6 1.6)", "oklab(0.5 -1.6 1.6)"); +test_valid_value("color", "oklab(0.5 -2 2)", "oklab(0.5 -2 2)"); test_valid_value("color", "oklab(0 0 0 / -10%)", "oklab(0 0 0 / 0)"); test_valid_value("color", "oklab(0 0 0 / 110%)", "oklab(0 0 0)"); test_valid_value("color", "oklab(0 0 0 / 300%)", "oklab(0 0 0)"); -test_valid_value("color", "oklab(-40 0 0)", "oklab(0 0 0)"); -test_valid_value("color", "oklab(50 -20 0)", "oklab(50 -20 0)"); -test_valid_value("color", "oklab(50 0 -20)", "oklab(50 0 -20)"); -test_valid_value("color", "oklab(calc(50 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))", "oklab(150 -0.5 1.5 / 0.5)"); -test_valid_value("color", "oklab(calc(-50 * 3) calc(0.5 + 1) calc(-1.5) / calc(-0.5 * 2))", "oklab(0 1.5 -1.5 / 0)"); +test_valid_value("color", "oklab(-0.4 0 0)", "oklab(0 0 0)"); +test_valid_value("color", "oklab(0.5 -2 0)", "oklab(0.5 -2 0)"); +test_valid_value("color", "oklab(0.5 0 -2)", "oklab(0.5 0 -2)"); +test_valid_value("color", "oklab(calc(0.5 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))", "oklab(1 -0.5 1.5 / 0.5)"); +test_valid_value("color", "oklab(calc(-0.5 * 3) calc(0.5 + 1) calc(-1.5) / calc(-0.5 * 2))", "oklab(0 1.5 -1.5 / 0)"); test_valid_value("color", "oklab(none none none / none)", "oklab(none none none / none)"); test_valid_value("color", "oklab(none none none)", "oklab(none none none)"); -test_valid_value("color", "oklab(20 none none / none)", "oklab(20 none none / none)"); +test_valid_value("color", "oklab(0.2 none none / none)", "oklab(0.2 none none / none)"); test_valid_value("color", "oklab(none none none / 0.5)", "oklab(none none none / 0.5)"); test_valid_value("color", "oklab(0 0 0 / none)", "oklab(0 0 0 / none)"); @@ -82,7 +82,7 @@ test_valid_value("color", "lch(0 0 0 / 0.5)", "lch(0 0 0 / 0.5)"); test_valid_value("color", "lch(10 20 20 / 110%)", "lch(10 20 20)"); test_valid_value("color", "lch(10 20 -700)", "lch(10 20 20)"); -test_valid_value("color", "lch(calc(50 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))", "lch(150 0 40 / 0.5)"); +test_valid_value("color", "lch(calc(50 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))", "lch(100 0 40 / 0.5)"); test_valid_value("color", "lch(calc(-50 * 3) calc(0.5 + 1) calc(-20deg * 2) / calc(-0.5 * 2))", "lch(0 1.5 320 / 0)"); test_valid_value("color", "lch(none none none / none)", "lch(none none none / none)"); @@ -95,27 +95,27 @@ test_valid_value("color", "oklch(0 0 0deg)", "oklch(0 0 0)"); test_valid_value("color", "oklch(0 0 0deg / 1)", "oklch(0 0 0)"); test_valid_value("color", "oklch(0 0 0deg / 0.5)", "oklch(0 0 0 / 0.5)"); -test_valid_value("color", "oklch(100 230 0deg / 0.5)", "oklch(100 230 0 / 0.5)"); -test_valid_value("color", "oklch(20 50 20deg/0.5)", "oklch(20 50 20 / 0.5)"); -test_valid_value("color", "oklch(20 50 20deg/50%)", "oklch(20 50 20 / 0.5)"); -test_valid_value("color", "oklch(10 20 20deg / -10%)", "oklch(10 20 20 / 0)"); -test_valid_value("color", "oklch(10 20 20deg / 110%)", "oklch(10 20 20)"); -test_valid_value("color", "oklch(10 20 1.28rad)", "oklch(10 20 73.3386)"); -test_valid_value("color", "oklch(10 20 380deg)", "oklch(10 20 20)"); -test_valid_value("color", "oklch(10 20 -340deg)", "oklch(10 20 20)"); -test_valid_value("color", "oklch(10 20 740deg)", "oklch(10 20 20)"); -test_valid_value("color", "oklch(10 20 -700deg)", "oklch(10 20 20)"); -test_valid_value("color", "oklch(-40 0 0)", "oklch(0 0 0)"); -test_valid_value("color", "oklch(20 -20 0)", "oklch(20 0 0)"); +test_valid_value("color", "oklch(1 2.3 0deg / 0.5)", "oklch(1 2.3 0 / 0.5)"); +test_valid_value("color", "oklch(0.2 0.5 20deg/0.5)", "oklch(0.2 0.5 20 / 0.5)"); +test_valid_value("color", "oklch(0.2 0.5 20deg/50%)", "oklch(0.2 0.5 20 / 0.5)"); +test_valid_value("color", "oklch(0.1 0.2 20deg / -10%)", "oklch(0.1 0.2 20 / 0)"); +test_valid_value("color", "oklch(0.1 0.2 20deg / 110%)", "oklch(0.1 0.2 20)"); +test_valid_value("color", "oklch(0.1 0.2 1.28rad)", "oklch(0.1 0.2 73.3386)"); +test_valid_value("color", "oklch(0.1 0.2 380deg)", "oklch(0.1 0.2 20)"); +test_valid_value("color", "oklch(0.1 0.2 -340deg)", "oklch(0.1 0.2 20)"); +test_valid_value("color", "oklch(0.1 0.2 740deg)", "oklch(0.1 0.2 20)"); +test_valid_value("color", "oklch(0.1 0.2 -700deg)", "oklch(0.1 0.2 20)"); +test_valid_value("color", "oklch(-4 0 0)", "oklch(0 0 0)"); +test_valid_value("color", "oklch(0.2 -0.2 0)", "oklch(0.2 0 0)"); test_valid_value("color", "oklch(0 0 0 / 0.5)", "oklch(0 0 0 / 0.5)"); -test_valid_value("color", "oklch(10 20 20 / 110%)", "oklch(10 20 20)"); -test_valid_value("color", "oklch(10 20 -700)", "oklch(10 20 20)"); -test_valid_value("color", "oklch(calc(50 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))", "oklch(150 0 40 / 0.5)"); -test_valid_value("color", "oklch(calc(-50 * 3) calc(0.5 + 1) calc(-20deg * 2) / calc(-0.5 * 2))", "oklch(0 1.5 320 / 0)"); +test_valid_value("color", "oklch(0.1 0.2 20 / 110%)", "oklch(0.1 0.2 20)"); +test_valid_value("color", "oklch(0.1 0.2 -700)", "oklch(0.1 0.2 20)"); +test_valid_value("color", "oklch(calc(0.5 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))", "oklch(1 0 40 / 0.5)"); +test_valid_value("color", "oklch(calc(-0.5 * 3) calc(0.5 + 1) calc(-20deg * 2) / calc(-0.5 * 2))", "oklch(0 1.5 320 / 0)"); test_valid_value("color", "oklch(none none none / none)", "oklch(none none none / none)"); test_valid_value("color", "oklch(none none none)", "oklch(none none none)"); -test_valid_value("color", "oklch(20 none none / none)", "oklch(20 none none / none)"); +test_valid_value("color", "oklch(0.2 none none / none)", "oklch(0.2 none none / none)"); test_valid_value("color", "oklch(none none none / 0.5)", "oklch(none none none / 0.5)"); test_valid_value("color", "oklch(0 0 0 / none)", "oklch(0 0 0 / none)"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-lab.html.ini b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-lab.html.ini new file mode 100644 index 0000000..a9e4425 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-lab.html.ini
@@ -0,0 +1,18 @@ +[color-valid-lab.html] + [e.style['color'\] = "lab(400 0 10/50%)" should set the property value] + expected: FAIL + + [e.style['color'\] = "lab(calc(50 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))" should set the property value] + expected: FAIL + + [e.style['color'\] = "lch(calc(50 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))" should set the property value] + expected: FAIL + + [e.style['color'\] = "oklab(4 0 0.1/50%)" should set the property value] + expected: FAIL + + [e.style['color'\] = "oklab(calc(0.5 * 3) calc(0.5 - 1) calc(1.5) / calc(-0.5 + 1))" should set the property value] + expected: FAIL + + [e.style['color'\] = "oklch(calc(0.5 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))" should set the property value] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color-expected.txt index 5bf4e6a..ff73eaa 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color-expected.txt
@@ -10,9 +10,9 @@ FAIL e.style['color'] = "rgb(from lab(0 104.3 -50.9) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "rgb(from lch(100 116 334) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "rgb(from lch(0 116 334) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from oklab(100 0.365 -0.16) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "rgb(from oklab(1 0.365 -0.16) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "rgb(from oklab(0 0.365 -0.16) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from oklch(100 0.399 336.3) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "rgb(from oklch(1 0.399 336.3) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "rgb(from oklch(0 0.399 336.3) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "rgb(from rebeccapurple 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "rgb(from rebeccapurple 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" @@ -87,9 +87,9 @@ FAIL e.style['color'] = "hsl(from lab(0 104.3 -50.9) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "hsl(from lch(100 116 334) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "hsl(from lch(0 116 334) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from oklab(100 0.365 -0.16) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "hsl(from oklab(1 0.365 -0.16) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "hsl(from oklab(0 0.365 -0.16) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from oklch(100 0.399 336.3) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "hsl(from oklch(1 0.399 336.3) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "hsl(from oklch(0 0.399 336.3) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "hsl(from rebeccapurple 0 0% 0%)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "hsl(from rebeccapurple 0deg 0% 0%)" should set the property value assert_not_equals: property should be set got disallowed value "" @@ -149,9 +149,9 @@ FAIL e.style['color'] = "hwb(from lab(0 104.3 -50.9) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "hwb(from lch(100 116 334) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "hwb(from lch(0 116 334) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from oklab(100 0.365 -0.16) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "hwb(from oklab(1 0.365 -0.16) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "hwb(from oklab(0 0.365 -0.16) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from oklch(100 0.399 336.3) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "hwb(from oklch(1 0.399 336.3) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "hwb(from oklch(0 0.399 336.3) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "hwb(from rebeccapurple 0 0% 0%)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "hwb(from rebeccapurple 0deg 0% 0%)" should set the property value assert_not_equals: property should be set got disallowed value "" @@ -245,62 +245,62 @@ FAIL e.style['color'] = "lab(from lab(none none none / none) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lab(from lab(25 none 50) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lab(from lab(25 20 50 / none) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(200 300 400 / 500%) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(-200 -300 -400 / -500%) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(from oklab(25 20 50) l a b) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(2 3 4 / 500%) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(-2 -3 -4 / -500%) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(from oklab(0.25 0.2 0.5) l a b) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "oklab(from color(display-p3 0 0 0) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) 0 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l a 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l a b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) 0 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) l 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) l a 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) l a b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) 35 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l 35 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l a 35 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l a b / .35)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) 35 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) l 35 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) l a 35 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) l a b / .35)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.7 45 30 / 40%) 200 300 400 / 500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.7 45 30 / 40%) -200 -300 -400 / -500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l b a)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l a a / a)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) l b a)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) l a a / a)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) calc(l) calc(a) calc(b))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l a none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l a none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50) l a b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) l a none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / 40%) l a b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) 0 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) 0 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) 0.35 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l 0.35 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a 0.35 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b / .35)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) 0.35 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l 0.35 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0.35 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / .35)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.7 0.45 0.3 / 40%) 2 3 4 / 500)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.7 0.45 0.3 / 40%) -2 -3 -4 / -500)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l b a)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a a / a)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l b a)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a a / a)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a none)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "oklab(from oklab(none none none) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "oklab(from oklab(none none none / none) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 none 50) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(25 20 50 / none) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 none 0.5) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / none) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lab(from lab(.7 45 30) alpha b a / l)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lab(from lab(.7 45 30) alpha a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lab(from lab(.7 45 30) alpha a a / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lab(from lab(.7 45 30 / 40%) alpha b a / l)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lab(from lab(.7 45 30 / 40%) alpha a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lab(from lab(.7 45 30 / 40%) alpha a a / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(.7 45 30) alpha b a / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(.7 45 30) alpha a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(.7 45 30) alpha a a / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(.7 45 30 / 40%) alpha b a / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(.7 45 30 / 40%) alpha a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(.7 45 30 / 40%) alpha a a / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3) alpha b a / l)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3) alpha a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3) alpha a a / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3 / 40%) alpha b a / l)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3 / 40%) alpha a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3 / 40%) alpha a a / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" @@ -352,69 +352,69 @@ FAIL e.style['color'] = "lch(from lch(none none none / none) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lch(from lch(0.7 none 30) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lch(from lch(0.7 45 30 / none) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(200 300 400 / 500%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(-200 -300 -400 / -500%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(from oklch(0.7 45 30) l c h) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(2 3 400 / 500%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(-2 -3 -400 / -500%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(from oklch(0.7 0.45 30) l c h) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "oklch(from color(display-p3 0 0 0) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "oklch(from oklab(0.7 45 30) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) 0 0 0deg)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) 0 0 0deg / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) 0 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l 0 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l c 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l c 0deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l c h / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) 0 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) l 0 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) l c 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) l c 0deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) l c h / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) 25 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l 25 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l c 25 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l c 25deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l c h / .25)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) 25 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) l 25 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) l c 25 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) l c 25deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) l c h / .25)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) 200 300 400 / 500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) -200 -300 -400 / -500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) 50 120 400deg / 500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) 50 120 -400deg / -500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 45 30) l c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 45 30 / 40%) l c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) calc(l) calc(c) calc(h))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l c none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l c none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30) l c h / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) l c none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / 40%) l c h / none)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 0 0deg)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 0 0deg / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l 0 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c 0deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 0 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l 0 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 0deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0.25 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l 0.25 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c 0.25 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c 25deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h / .25)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 0.25 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l 0.25 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 0.25 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 25deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / .25)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 2 3 400 / 500)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) -2 -3 -400 / -500)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 400deg / 500)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 -400deg / -500)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30) l c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30 / 40%) l c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) calc(l) calc(c) calc(h))" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c none)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h / none)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / none)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "oklch(from oklch(none none none) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "oklch(from oklch(none none none / none) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "oklch(from oklch(0.7 none 30) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 45 30 / none) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / none) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lch(from lch(.7 45 30) alpha c h / l)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lch(from lch(.7 45 30) alpha c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lch(from lch(.7 45 30) alpha c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lch(from lch(.7 45 30 / 40%) alpha c h / l)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lch(from lch(.7 45 30 / 40%) alpha c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "lch(from lch(.7 45 30 / 40%) alpha c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 45 30) alpha c h / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 45 30) alpha c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 45 30) alpha c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 45 30 / 40%) alpha c h / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 45 30 / 40%) alpha c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 45 30 / 40%) alpha c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30) alpha c h / l)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30) alpha c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30) alpha c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30 / 40%) alpha c h / l)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30 / 40%) alpha c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30 / 40%) alpha c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value ""
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color.html index b5c8ddf..a1c9461 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color.html
@@ -39,9 +39,9 @@ test_valid_value(`color`, `rgb(from lab(0 104.3 -50.9) r g b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, test_valid_value(`color`, `rgb(from lch(100 116 334) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). test_valid_value(`color`, `rgb(from lch(0 116 334) r g b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, - test_valid_value(`color`, `rgb(from oklab(100 0.365 -0.16) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). + test_valid_value(`color`, `rgb(from oklab(1 0.365 -0.16) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). test_valid_value(`color`, `rgb(from oklab(0 0.365 -0.16) r g b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). - test_valid_value(`color`, `rgb(from oklch(100 0.399 336.3) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). + test_valid_value(`color`, `rgb(from oklch(1 0.399 336.3) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). test_valid_value(`color`, `rgb(from oklch(0 0.399 336.3) r g b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). // Testing replacement with 0. @@ -145,9 +145,9 @@ test_valid_value(`color`, `hsl(from lab(0 104.3 -50.9) h s l)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, test_valid_value(`color`, `hsl(from lch(100 116 334) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). test_valid_value(`color`, `hsl(from lch(0 116 334) h s l)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, - test_valid_value(`color`, `hsl(from oklab(100 0.365 -0.16) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). + test_valid_value(`color`, `hsl(from oklab(1 0.365 -0.16) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). test_valid_value(`color`, `hsl(from oklab(0 0.365 -0.16) h s l)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). - test_valid_value(`color`, `hsl(from oklch(100 0.399 336.3) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). + test_valid_value(`color`, `hsl(from oklch(1 0.399 336.3) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). test_valid_value(`color`, `hsl(from oklch(0 0.399 336.3) h s l)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). // Testing replacement with 0. @@ -226,9 +226,9 @@ test_valid_value(`color`, `hwb(from lab(0 104.3 -50.9) h w b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, test_valid_value(`color`, `hwb(from lch(100 116 334) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). test_valid_value(`color`, `hwb(from lch(0 116 334) h w b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, - test_valid_value(`color`, `hwb(from oklab(100 0.365 -0.16) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). + test_valid_value(`color`, `hwb(from oklab(1 0.365 -0.16) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). test_valid_value(`color`, `hwb(from oklab(0 0.365 -0.16) h w b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). - test_valid_value(`color`, `hwb(from oklch(100 0.399 336.3) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). + test_valid_value(`color`, `hwb(from oklch(1 0.399 336.3) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). test_valid_value(`color`, `hwb(from oklch(0 0.399 336.3) h w b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). // Testing replacement with 0. @@ -296,7 +296,7 @@ test_valid_value(`color`, `lab(from lab(25 20 50) l a b)`, `lab(25 20 50)`); test_valid_value(`color`, `lab(from lab(25 20 50) l a b / alpha)`, `lab(25 20 50)`); test_valid_value(`color`, `lab(from lab(25 20 50 / 40%) l a b / alpha)`, `lab(25 20 50 / 0.4)`); - test_valid_value(`color`, `lab(from lab(200 300 400 / 500%) l a b / alpha)`, `lab(200 300 400)`); + test_valid_value(`color`, `lab(from lab(200 300 400 / 500%) l a b / alpha)`, `lab(100 300 400)`); test_valid_value(`color`, `lab(from lab(-200 -300 -400 / -500%) l a b / alpha)`, `lab(0 -300 -400 / 0)`); // Test nesting relative colors. @@ -356,65 +356,65 @@ // oklab() // Testing no modifications. - test_valid_value(`color`, `oklab(from oklab(25 20 50) l a b)`, `oklab(25 20 50)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) l a b / alpha)`, `oklab(25 20 50)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a b / alpha)`, `oklab(25 20 50 / 0.4)`); - test_valid_value(`color`, `oklab(from oklab(200 300 400 / 500%) l a b / alpha)`, `oklab(200 300 400)`); - test_valid_value(`color`, `oklab(from oklab(-200 -300 -400 / -500%) l a b / alpha)`, `oklab(0 -300 -400 / 0)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a b)`, `oklab(0.25 0.2 0.5)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a b / alpha)`, `oklab(0.25 0.2 0.5)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / alpha)`, `oklab(0.25 0.2 0.5 / 0.4)`); + test_valid_value(`color`, `oklab(from oklab(2 3 4 / 500%) l a b / alpha)`, `oklab(1 3 4)`); + test_valid_value(`color`, `oklab(from oklab(-2 -3 -4 / -500%) l a b / alpha)`, `oklab(0 -3 -4 / 0)`); // Test nesting relative colors. - test_valid_value(`color`, `oklab(from oklab(from oklab(25 20 50) l a b) l a b)`, `oklab(25 20 50)`); + test_valid_value(`color`, `oklab(from oklab(from oklab(0.25 0.2 0.5) l a b) l a b)`, `oklab(0.25 0.2 0.5)`); // Testing non-oklab origin to see conversion. test_valid_value(`color`, `oklab(from color(display-p3 0 0 0) l a b / alpha)`, `oklab(0 0 0)`); // Testing replacement with 0. - test_valid_value(`color`, `oklab(from oklab(25 20 50) 0 0 0)`, `oklab(0 0 0)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) 0 0 0 / 0)`, `oklab(0 0 0 / 0)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) 0 a b / alpha)`, `oklab(0 20 50)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) l 0 b / alpha)`, `oklab(25 0 50)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) l a 0 / alpha)`, `oklab(25 20 0)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) l a b / 0)`, `oklab(25 20 50 / 0)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) 0 a b / alpha)`, `oklab(0 20 50 / 0.4)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) l 0 b / alpha)`, `oklab(25 0 50 / 0.4)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a 0 / alpha)`, `oklab(25 20 0 / 0.4)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a b / 0)`, `oklab(25 20 50 / 0)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) 0 0 0)`, `oklab(0 0 0)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) 0 0 0 / 0)`, `oklab(0 0 0 / 0)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) 0 a b / alpha)`, `oklab(0 0.2 0.5)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l 0 b / alpha)`, `oklab(0.25 0 0.5)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a 0 / alpha)`, `oklab(0.25 0.2 0)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a b / 0)`, `oklab(0.25 0.2 0.5 / 0)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) 0 a b / alpha)`, `oklab(0 0.2 0.5 / 0.4)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l 0 b / alpha)`, `oklab(0.25 0 0.5 / 0.4)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0 / alpha)`, `oklab(0.25 0.2 0 / 0.4)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / 0)`, `oklab(0.25 0.2 0.5 / 0)`); // Testing replacement with a constant. - test_valid_value(`color`, `oklab(from oklab(25 20 50) 35 a b / alpha)`, `oklab(35 20 50)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) l 35 b / alpha)`, `oklab(25 35 50)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) l a 35 / alpha)`, `oklab(25 20 35)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) l a b / .35)`, `oklab(25 20 50 / 0.35)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) 35 a b / alpha)`, `oklab(35 20 50 / 0.4)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) l 35 b / alpha)`, `oklab(25 35 50 / 0.4)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a 35 / alpha)`, `oklab(25 20 35 / 0.4)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a b / .35)`, `oklab(25 20 50 / 0.35)`); - test_valid_value(`color`, `oklab(from oklab(0.7 45 30 / 40%) 200 300 400 / 500)`, `oklab(200 300 400)`); - test_valid_value(`color`, `oklab(from oklab(0.7 45 30 / 40%) -200 -300 -400 / -500)`, `oklab(0 -300 -400 / 0)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) 0.35 a b / alpha)`, `oklab(0.35 0.2 0.5)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l 0.35 b / alpha)`, `oklab(0.25 0.35 0.5)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a 0.35 / alpha)`, `oklab(0.25 0.2 0.35)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a b / .35)`, `oklab(0.25 0.2 0.5 / 0.35)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) 0.35 a b / alpha)`, `oklab(0.35 0.2 0.5 / 0.4)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l 0.35 b / alpha)`, `oklab(0.25 0.35 0.5 / 0.4)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0.35 / alpha)`, `oklab(0.25 0.2 0.35 / 0.4)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / .35)`, `oklab(0.25 0.2 0.5 / 0.35)`); + test_valid_value(`color`, `oklab(from oklab(0.7 0.45 0.3 / 40%) 2 3 4 / 500)`, `oklab(1 3 4)`); + test_valid_value(`color`, `oklab(from oklab(0.7 0.45 0.3 / 40%) -2 -3 -4 / -500)`, `oklab(0 -3 -4 / 0)`); // Testing valid permutation (types match). - test_valid_value(`color`, `oklab(from oklab(25 20 50) l b a)`, `oklab(25 50 20)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) l a a / a)`, `oklab(25 20 20)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) l b a)`, `oklab(25 50 20)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a a / a)`, `oklab(25 20 20)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l b a)`, `oklab(0.25 0.5 0.2)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a a / a)`, `oklab(0.25 0.2 0.2 / 0.2)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l b a)`, `oklab(0.25 0.5 0.2)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a a / a)`, `oklab(0.25 0.2 0.2 / 0.2)`); // Testing with calc(). - test_valid_value(`color`, `oklab(from oklab(25 20 50) calc(l) calc(a) calc(b))`, `oklab(25 20 50)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))`, `oklab(25 20 50 / 0.4)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))`, `oklab(0.25 0.2 0.5)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))`, `oklab(0.25 0.2 0.5 / 0.4)`); // Testing with 'none'. - test_valid_value(`color`, `oklab(from oklab(25 20 50) none none none)`, `oklab(none none none)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) none none none / none)`, `oklab(none none none / none)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) l a none)`, `oklab(25 20 none)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) l a none / alpha)`, `oklab(25 20 none)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50) l a b / none)`, `oklab(25 20 50 / none)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a none / alpha)`, `oklab(25 20 none / 0.4)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / 40%) l a b / none)`, `oklab(25 20 50 / none)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) none none none)`, `oklab(none none none)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) none none none / none)`, `oklab(none none none / none)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a none)`, `oklab(0.25 0.2 none)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a none / alpha)`, `oklab(0.25 0.2 none)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5) l a b / none)`, `oklab(0.25 0.2 0.5 / none)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a none / alpha)`, `oklab(0.25 0.2 none / 0.4)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / none)`, `oklab(0.25 0.2 0.5 / none)`); // FIXME: Clarify with spec editors if 'none' should pass through to the constants. test_valid_value(`color`, `oklab(from oklab(none none none) l a b)`, `oklab(0 0 0)`); test_valid_value(`color`, `oklab(from oklab(none none none / none) l a b / alpha)`, `oklab(0 0 0 / 0)`); - test_valid_value(`color`, `oklab(from oklab(25 none 50) l a b)`, `oklab(25 0 50)`); - test_valid_value(`color`, `oklab(from oklab(25 20 50 / none) l a b / alpha)`, `oklab(25 20 50 / 0)`); + test_valid_value(`color`, `oklab(from oklab(0.25 none 0.5) l a b)`, `oklab(0.25 0 0.5)`); + test_valid_value(`color`, `oklab(from oklab(0.25 0.2 0.5 / none) l a b / alpha)`, `oklab(0.25 0.2 0.5 / 0)`); // lab and oklab tests that require different results due to percent scaling differences. test_valid_value(`color`, `lab(from lab(.7 45 30) alpha b a / l)`, `lab(100 30 45 / 0.7)`); @@ -424,12 +424,12 @@ test_valid_value(`color`, `lab(from lab(.7 45 30 / 40%) alpha a b / alpha)`, `lab(40 45 30 / 0.4)`); test_valid_value(`color`, `lab(from lab(.7 45 30 / 40%) alpha a a / alpha)`, `lab(40 45 45 / 0.4)`); - test_valid_value(`color`, `oklab(from oklab(.7 45 30) alpha b a / l)`, `oklab(1 30 45 / 0.7)`); - test_valid_value(`color`, `oklab(from oklab(.7 45 30) alpha a b / alpha)`, `oklab(1 45 30)`); - test_valid_value(`color`, `oklab(from oklab(.7 45 30) alpha a a / alpha)`, `oklab(1 45 45)`); - test_valid_value(`color`, `oklab(from oklab(.7 45 30 / 40%) alpha b a / l)`, `oklab(0.4 30 45 / 0.7)`); - test_valid_value(`color`, `oklab(from oklab(.7 45 30 / 40%) alpha a b / alpha)`, `oklab(0.4 45 30 / 0.4)`); - test_valid_value(`color`, `oklab(from oklab(.7 45 30 / 40%) alpha a a / alpha)`, `oklab(0.4 45 45 / 0.4)`); + test_valid_value(`color`, `oklab(from oklab(.7 0.45 0.3) alpha b a / l)`, `oklab(1 0.3 0.45 / 0.7)`); + test_valid_value(`color`, `oklab(from oklab(.7 0.45 0.3) alpha a b / alpha)`, `oklab(1 0.45 0.3)`); + test_valid_value(`color`, `oklab(from oklab(.7 0.45 0.3) alpha a a / alpha)`, `oklab(1 0.45 0.45)`); + test_valid_value(`color`, `oklab(from oklab(.7 0.45 0.3 / 40%) alpha b a / l)`, `oklab(0.4 0.3 0.45 / 0.7)`); + test_valid_value(`color`, `oklab(from oklab(.7 0.45 0.3 / 40%) alpha a b / alpha)`, `oklab(0.4 0.45 0.3 / 0.4)`); + test_valid_value(`color`, `oklab(from oklab(.7 0.45 0.3 / 40%) alpha a a / alpha)`, `oklab(0.4 0.45 0.45 / 0.4)`); // lch() @@ -437,7 +437,7 @@ test_valid_value(`color`, `lch(from lch(0.7 45 30) l c h)`, `lch(0.7 45 30)`); test_valid_value(`color`, `lch(from lch(0.7 45 30) l c h / alpha)`, `lch(0.7 45 30)`); test_valid_value(`color`, `lch(from lch(0.7 45 30 / 40%) l c h / alpha)`, `lch(0.7 45 30 / 0.4)`); - test_valid_value(`color`, `lch(from lch(200 300 400 / 500%) l c h / alpha)`, `lch(200 300 40)`); + test_valid_value(`color`, `lch(from lch(200 300 400 / 500%) l c h / alpha)`, `lch(100 300 40)`); test_valid_value(`color`, `lch(from lch(-200 -300 -400 / -500%) l c h / alpha)`, `lch(0 0 320 / 0)`); // Test nesting relative colors. @@ -474,7 +474,7 @@ test_valid_value(`color`, `lch(from lch(0.7 45 30 / 40%) l c 25 / alpha)`, `lch(0.7 45 25 / 0.4)`); test_valid_value(`color`, `lch(from lch(0.7 45 30 / 40%) l c 25deg / alpha)`, `lch(0.7 45 25 / 0.4)`); test_valid_value(`color`, `lch(from lch(0.7 45 30 / 40%) l c h / .25)`, `lch(0.7 45 30 / 0.25)`); - test_valid_value(`color`, `lch(from lch(0.7 45 30 / 40%) 200 300 400 / 500)`, `lch(200 300 40)`); + test_valid_value(`color`, `lch(from lch(0.7 45 30 / 40%) 200 300 400 / 500)`, `lch(100 300 40)`); test_valid_value(`color`, `lch(from lch(0.7 45 30 / 40%) -200 -300 -400 / -500)`, `lch(0 0 320 / 0)`); test_valid_value(`color`, `lch(from lch(0.7 45 30 / 40%) 50 120 400deg / 500)`, `lch(50 120 40)`); test_valid_value(`color`, `lch(from lch(0.7 45 30 / 40%) 50 120 -400deg / -500)`, `lch(50 120 320 / 0)`); @@ -505,73 +505,74 @@ // oklch() // Testing no modifications. - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l c h)`, `oklch(0.7 45 30)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l c h / alpha)`, `oklch(0.7 45 30)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c h / alpha)`, `oklch(0.7 45 30 / 0.4)`); - test_valid_value(`color`, `oklch(from oklch(200 300 400 / 500%) l c h / alpha)`, `oklch(200 300 40)`); - test_valid_value(`color`, `oklch(from oklch(-200 -300 -400 / -500%) l c h / alpha)`, `oklch(0 0 320 / 0)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l c h)`, `oklch(0.7 0.45 30)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l c h / alpha)`, `oklch(0.7 0.45 30)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c h / alpha)`, `oklch(0.7 0.45 30 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(2 3 400 / 500%) l c h / alpha)`, `oklch(1 3 40)`); + test_valid_value(`color`, `oklch(from oklch(-2 -3 -400 / -500%) l c h / alpha)`, `oklch(0 0 320 / 0)`); // Test nesting relative colors. - test_valid_value(`color`, `oklch(from oklch(from oklch(0.7 45 30) l c h) l c h)`, `oklch(0.7 45 30)`); + test_valid_value(`color`, `oklch(from oklch(from oklch(0.7 0.45 30) l c h) l c h)`, `oklch(0.7 0.45 30)`); // Testing non-sRGB origin colors (no gamut mapping will happen since the destination is not a bounded RGB color space). test_valid_value(`color`, `oklch(from color(display-p3 0 0 0) l c h / alpha)`, `oklch(0 0 0)`); + // TODO: redo conversion with oklab(0.7 0.45 0.3) test_valid_value(`color`, `oklch(from oklab(0.7 45 30) l c h / alpha)`, `oklch(0.7 54.08327 33.690067)`); // Testing replacement with 0. - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) 0 0 0)`, `oklch(0 0 0)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) 0 0 0deg)`, `oklch(0 0 0)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) 0 0 0 / 0)`, `oklch(0 0 0 / 0)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) 0 0 0deg / 0)`, `oklch(0 0 0 / 0)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) 0 c h / alpha)`, `oklch(0 45 30)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l 0 h / alpha)`, `oklch(0.7 0 30)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l c 0 / alpha)`, `oklch(0.7 45 0)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l c 0deg / alpha)`, `oklch(0.7 45 0)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l c h / 0)`, `oklch(0.7 45 30 / 0)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) 0 c h / alpha)`, `oklch(0 45 30 / 0.4)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l 0 h / alpha)`, `oklch(0.7 0 30 / 0.4)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c 0 / alpha)`, `oklch(0.7 45 0 / 0.4)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c 0deg / alpha)`, `oklch(0.7 45 0 / 0.4)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c h / 0)`, `oklch(0.7 45 30 / 0)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) 0 0 0)`, `oklch(0 0 0)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) 0 0 0deg)`, `oklch(0 0 0)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) 0 0 0 / 0)`, `oklch(0 0 0 / 0)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) 0 0 0deg / 0)`, `oklch(0 0 0 / 0)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) 0 c h / alpha)`, `oklch(0 0.45 30)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l 0 h / alpha)`, `oklch(0.7 0 30)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l c 0 / alpha)`, `oklch(0.7 0.45 0)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l c 0deg / alpha)`, `oklch(0.7 0.45 0)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l c h / 0)`, `oklch(0.7 0.45 30 / 0)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) 0 c h / alpha)`, `oklch(0 0.45 30 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l 0 h / alpha)`, `oklch(0.7 0 30 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c 0 / alpha)`, `oklch(0.7 0.45 0 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c 0deg / alpha)`, `oklch(0.7 0.45 0 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c h / 0)`, `oklch(0.7 0.45 30 / 0)`); // Testing replacement with a constant. - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) 25 c h / alpha)`, `oklch(25 45 30)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l 25 h / alpha)`, `oklch(0.7 25 30)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l c 25 / alpha)`, `oklch(0.7 45 25)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l c 25deg / alpha)`, `oklch(0.7 45 25)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l c h / .25)`, `oklch(0.7 45 30 / 0.25)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) 25 c h / alpha)`, `oklch(25 45 30 / 0.4)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l 25 h / alpha)`, `oklch(0.7 25 30 / 0.4)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c 25 / alpha)`, `oklch(0.7 45 25 / 0.4)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c 25deg / alpha)`, `oklch(0.7 45 25 / 0.4)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c h / .25)`, `oklch(0.7 45 30 / 0.25)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) 200 300 400 / 500)`, `oklch(200 300 40)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) -200 -300 -400 / -500)`, `oklch(0 0 320 / 0)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) 50 120 400deg / 500)`, `oklch(50 120 40)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) 50 120 -400deg / -500)`, `oklch(50 120 320 / 0)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) 0.25 c h / alpha)`, `oklch(0.25 0.45 30)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l 0.25 h / alpha)`, `oklch(0.7 0.25 30)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l c 0.25 / alpha)`, `oklch(0.7 0.45 0.25)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l c 25deg / alpha)`, `oklch(0.7 0.45 25)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l c h / .25)`, `oklch(0.7 0.45 30 / 0.25)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) 0.25 c h / alpha)`, `oklch(0.25 0.45 30 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l 0.25 h / alpha)`, `oklch(0.7 0.25 30 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c 0.25 / alpha)`, `oklch(0.7 0.45 0.25 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c 25deg / alpha)`, `oklch(0.7 0.45 25 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c h / .25)`, `oklch(0.7 0.45 30 / 0.25)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) 2 3 400 / 500)`, `oklch(2 3 40)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) -2 -3 -400 / -500)`, `oklch(0 0 320 / 0)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 400deg / 500)`, `oklch(0.5 1.2 40)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 -400deg / -500)`, `oklch(0.5 1.2 320 / 0)`); // Testing valid permutation (types match). // NOTE: 'c' is a vaild hue, as hue is <angle>|<number>. - test_valid_value(`color`, `oklch(from oklch(.7 45 30) l c c / alpha)`, `oklch(0.7 45 45)`); - test_valid_value(`color`, `oklch(from oklch(.7 45 30 / 40%) l c c / alpha)`, `oklch(0.7 45 45 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(.7 0.45 30) l c c / alpha)`, `oklch(0.7 0.45 0.45)`); + test_valid_value(`color`, `oklch(from oklch(.7 0.45 30 / 40%) l c c / alpha)`, `oklch(0.7 0.45 0.45 / 0.4)`); // Testing with calc(). - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) calc(l) calc(c) calc(h))`, `oklch(0.7 45 30)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))`, `oklch(0.7 45 30 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) calc(l) calc(c) calc(h))`, `oklch(0.7 0.45 30)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))`, `oklch(0.7 0.45 30 / 0.4)`); // Testing with 'none'. - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) none none none)`, `oklch(none none none)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) none none none / none)`, `oklch(none none none / none)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l c none)`, `oklch(0.7 45 none)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l c none / alpha)`, `oklch(0.7 45 none)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30) l c h / none)`, `oklch(0.7 45 30 / none)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c none / alpha)`, `oklch(0.7 45 none / 0.4)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / 40%) l c h / none)`, `oklch(0.7 45 30 / none)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) none none none)`, `oklch(none none none)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) none none none / none)`, `oklch(none none none / none)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l c none)`, `oklch(0.7 0.45 none)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l c none / alpha)`, `oklch(0.7 0.45 none)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30) l c h / none)`, `oklch(0.7 0.45 30 / none)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c none / alpha)`, `oklch(0.7 0.45 none / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / 40%) l c h / none)`, `oklch(0.7 0.45 30 / none)`); // FIXME: Clarify with spec editors if 'none' should pass through to the constants. test_valid_value(`color`, `oklch(from oklch(none none none) l c h)`, `oklch(0 0 0)`); test_valid_value(`color`, `oklch(from oklch(none none none / none) l c h / alpha)`, `oklch(0 0 0 / 0)`); test_valid_value(`color`, `oklch(from oklch(0.7 none 30) l c h)`, `oklch(0.7 0 30)`); - test_valid_value(`color`, `oklch(from oklch(0.7 45 30 / none) l c h / alpha)`, `oklch(0.7 45 30 / 0)`); + test_valid_value(`color`, `oklch(from oklch(0.7 0.45 30 / none) l c h / alpha)`, `oklch(0.7 0.45 30 / 0)`); // lch and oklch tests that require different results due to percent scaling differences. test_valid_value(`color`, `lch(from lch(.7 45 30) alpha c h / l)`, `lch(100 45 30 / 0.7)`); @@ -581,12 +582,12 @@ test_valid_value(`color`, `lch(from lch(.7 45 30 / 40%) alpha c h / alpha)`, `lch(40 45 30 / 0.4)`); test_valid_value(`color`, `lch(from lch(.7 45 30 / 40%) alpha c c / alpha)`, `lch(40 45 45 / 0.4)`); - test_valid_value(`color`, `oklch(from oklch(.7 45 30) alpha c h / l)`, `oklch(1 45 30 / 0.7)`); - test_valid_value(`color`, `oklch(from oklch(.7 45 30) alpha c h / alpha)`, `oklch(1 45 30)`); - test_valid_value(`color`, `oklch(from oklch(.7 45 30) alpha c c / alpha)`, `oklch(1 45 45)`); - test_valid_value(`color`, `oklch(from oklch(.7 45 30 / 40%) alpha c h / l)`, `oklch(0.4 45 30 / 0.7)`); - test_valid_value(`color`, `oklch(from oklch(.7 45 30 / 40%) alpha c h / alpha)`, `oklch(0.4 45 30 / 0.4)`); - test_valid_value(`color`, `oklch(from oklch(.7 45 30 / 40%) alpha c c / alpha)`, `oklch(0.4 45 45 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(.7 0.45 30) alpha c h / l)`, `oklch(1 0.45 30 / 0.7)`); + test_valid_value(`color`, `oklch(from oklch(.7 0.45 30) alpha c h / alpha)`, `oklch(1 0.45 30)`); + test_valid_value(`color`, `oklch(from oklch(.7 0.45 30) alpha c c / alpha)`, `oklch(1 0.45 0.45)`); + test_valid_value(`color`, `oklch(from oklch(.7 0.45 30 / 40%) alpha c h / l)`, `oklch(0.4 0.45 30 / 0.7)`); + test_valid_value(`color`, `oklch(from oklch(.7 0.45 30 / 40%) alpha c h / alpha)`, `oklch(0.4 0.45 30 / 0.4)`); + test_valid_value(`color`, `oklch(from oklch(.7 0.45 30 / 40%) alpha c c / alpha)`, `oklch(0.4 0.45 0.45 / 0.4)`); for (const colorSpace of [ "srgb", "srgb-linear", "a98-rgb", "rec2020", "prophoto-rgb", "display-p3" ]) {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color.html.ini b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color.html.ini index 7f28478..9e2a1e0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color.html.ini +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color.html.ini
@@ -1640,13 +1640,13 @@ [e.style['color'\] = "hsl(from oklab(0 0.365 -0.16) h s l)" should set the property value] expected: FAIL - [e.style['color'\] = "hsl(from oklab(100 0.365 -0.16) h s l)" should set the property value] + [e.style['color'\] = "hsl(from oklab(1 0.365 -0.16) h s l)" should set the property value] expected: FAIL [e.style['color'\] = "hsl(from oklch(0 0.399 336.3) h s l)" should set the property value] expected: FAIL - [e.style['color'\] = "hsl(from oklch(100 0.399 336.3) h s l)" should set the property value] + [e.style['color'\] = "hsl(from oklch(1 0.399 336.3) h s l)" should set the property value] expected: FAIL [e.style['color'\] = "hsl(from rebeccapurple 0 0% 0% / 0)" should set the property value] @@ -1826,13 +1826,13 @@ [e.style['color'\] = "hwb(from oklab(0 0.365 -0.16) h w b)" should set the property value] expected: FAIL - [e.style['color'\] = "hwb(from oklab(100 0.365 -0.16) h w b)" should set the property value] + [e.style['color'\] = "hwb(from oklab(1 0.365 -0.16) h w b)" should set the property value] expected: FAIL [e.style['color'\] = "hwb(from oklch(0 0.399 336.3) h w b)" should set the property value] expected: FAIL - [e.style['color'\] = "hwb(from oklch(100 0.399 336.3) h w b)" should set the property value] + [e.style['color'\] = "hwb(from oklch(1 0.399 336.3) h w b)" should set the property value] expected: FAIL [e.style['color'\] = "hwb(from rebeccapurple 0 0% 0% / 0)" should set the property value] @@ -2291,145 +2291,145 @@ [e.style['color'\] = "oklab(from color(display-p3 0 0 0) l a b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(-200 -300 -400 / -500%) l a b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(-2 -3 -4 / -500%) l a b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(.7 45 30 / 40%) alpha a a / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(.7 0.45 0.3 / 40%) alpha a a / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(.7 45 30 / 40%) alpha a b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(.7 0.45 0.3 / 40%) alpha a b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(.7 45 30 / 40%) alpha b a / l)" should set the property value] + [e.style['color'\] = "oklab(from oklab(.7 0.45 0.3 / 40%) alpha b a / l)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(.7 45 30) alpha a a / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(.7 0.45 0.3) alpha a a / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(.7 45 30) alpha a b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(.7 0.45 0.3) alpha a b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(.7 45 30) alpha b a / l)" should set the property value] + [e.style['color'\] = "oklab(from oklab(.7 0.45 0.3) alpha b a / l)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(0.7 45 30 / 40%) -200 -300 -400 / -500)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) 0 a b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(0.7 45 30 / 40%) 200 300 400 / 500)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) 0.35 a b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(200 300 400 / 500%) l a b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) 0 a b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l 0 b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) 35 a b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l 0.35 b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0 / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) l 0 b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0.35 / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) l 35 b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a a / a)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) l a 0 / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / .35)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) l a 35 / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / 0)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) l a a / a)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) l a b / .35)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / none)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) l a b / 0)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a none / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) l a b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l b a)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) l a b / none)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5 / none) l a b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) l a none / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) 0 0 0 / 0)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / 40%) l b a)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) 0 0 0)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50 / none) l a b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) 0 a b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) 0 0 0 / 0)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) 0.35 a b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) 0 0 0)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) 0 a b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l 0 b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) 35 a b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l 0.35 b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) calc(l) calc(a) calc(b))" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l a 0 / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l 0 b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l a 0.35 / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l 35 b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l a a / a)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l a 0 / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l a b / .35)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l a 35 / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l a b / 0)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l a a / a)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l a b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l a b / .35)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l a b / none)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l a b / 0)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l a b)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l a b / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l a none / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l a b / none)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l a none)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l a b)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) l b a)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l a none / alpha)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) none none none / none)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l a none)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 0.2 0.5) none none none)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) l b a)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.25 none 0.5) l a b)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) none none none / none)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.7 0.45 0.3 / 40%) -2 -3 -4 / -500)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 20 50) none none none)" should set the property value] + [e.style['color'\] = "oklab(from oklab(0.7 0.45 0.3 / 40%) 2 3 4 / 500)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(25 none 50) l a b)" should set the property value] + [e.style['color'\] = "oklab(from oklab(2 3 4 / 500%) l a b / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklab(from oklab(from oklab(25 20 50) l a b) l a b)" should set the property value] + [e.style['color'\] = "oklab(from oklab(from oklab(0.25 0.2 0.5) l a b) l a b)" should set the property value] expected: FAIL [e.style['color'\] = "oklab(from oklab(none none none / none) l a b / alpha)" should set the property value] @@ -2444,163 +2444,163 @@ [e.style['color'\] = "oklch(from oklab(0.7 45 30) l c h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(-200 -300 -400 / -500%) l c h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(-2 -3 -400 / -500%) l c h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(.7 45 30 / 40%) alpha c c / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(.7 0.45 30 / 40%) alpha c c / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(.7 45 30 / 40%) alpha c h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(.7 0.45 30 / 40%) alpha c h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(.7 45 30 / 40%) alpha c h / l)" should set the property value] + [e.style['color'\] = "oklch(from oklch(.7 0.45 30 / 40%) alpha c h / l)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(.7 45 30 / 40%) l c c / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(.7 0.45 30 / 40%) l c c / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(.7 45 30) alpha c c / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(.7 0.45 30) alpha c c / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(.7 45 30) alpha c h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(.7 0.45 30) alpha c h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(.7 45 30) alpha c h / l)" should set the property value] + [e.style['color'\] = "oklch(from oklch(.7 0.45 30) alpha c h / l)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(.7 45 30) l c c / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(.7 0.45 30) l c c / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) -200 -300 -400 / -500)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) -2 -3 -400 / -500)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) 0 c h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) 0 c h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) 200 300 400 / 500)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) 0.25 c h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) 25 c h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 -400deg / -500)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) 50 120 -400deg / -500)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 400deg / 500)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) 50 120 400deg / 500)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) 2 3 400 / 500)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) l 0 h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) l 0 h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) l 25 h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) l 0.25 h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) l c 0 / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 0 / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) l c 0deg / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 0.25 / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) l c 25 / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 0deg / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) l c 25deg / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 25deg / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) l c h / .25)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / .25)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) l c h / 0)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / 0)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) l c h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) l c h / none)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / none)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / 40%) l c none / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / 40%) l c none / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30 / none) l c h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30 / none) l c h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) 0 0 0 / 0)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) 0 0 0 / 0)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) 0 0 0)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) 0 0 0)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) 0 0 0deg / 0)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) 0 0 0deg / 0)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) 0 0 0deg)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) 0 0 0deg)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) 0 c h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) 0 c h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) 25 c h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) 0.25 c h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) calc(l) calc(c) calc(h))" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) calc(l) calc(c) calc(h))" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l 0 h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l 0 h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l 25 h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l 0.25 h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l c 0 / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l c 0 / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l c 0deg / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l c 0.25 / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l c 25 / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l c 0deg / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l c 25deg / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l c 25deg / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l c h / .25)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l c h / .25)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l c h / 0)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l c h / 0)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l c h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l c h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l c h / none)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l c h / none)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l c h)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l c h)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l c none / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l c none / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) l c none)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) l c none)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) none none none / none)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) none none none / none)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(0.7 45 30) none none none)" should set the property value] + [e.style['color'\] = "oklch(from oklch(0.7 0.45 30) none none none)" should set the property value] expected: FAIL [e.style['color'\] = "oklch(from oklch(0.7 none 30) l c h)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(200 300 400 / 500%) l c h / alpha)" should set the property value] + [e.style['color'\] = "oklch(from oklch(2 3 400 / 500%) l c h / alpha)" should set the property value] expected: FAIL - [e.style['color'\] = "oklch(from oklch(from oklch(0.7 45 30) l c h) l c h)" should set the property value] + [e.style['color'\] = "oklch(from oklch(from oklch(0.7 0.45 30) l c h) l c h)" should set the property value] expected: FAIL [e.style['color'\] = "oklch(from oklch(none none none / none) l c h / alpha)" should set the property value] @@ -2633,13 +2633,13 @@ [e.style['color'\] = "rgb(from oklab(0 0.365 -0.16) r g b)" should set the property value] expected: FAIL - [e.style['color'\] = "rgb(from oklab(100 0.365 -0.16) r g b)" should set the property value] + [e.style['color'\] = "rgb(from oklab(1 0.365 -0.16) r g b)" should set the property value] expected: FAIL [e.style['color'\] = "rgb(from oklch(0 0.399 336.3) r g b)" should set the property value] expected: FAIL - [e.style['color'\] = "rgb(from oklch(100 0.399 336.3) r g b)" should set the property value] + [e.style['color'\] = "rgb(from oklch(1 0.399 336.3) r g b)" should set the property value] expected: FAIL [e.style['color'\] = "rgb(from rebeccapurple 0 0 0 / 0)" should set the property value]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-system-color.html.ini b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-system-color.html.ini new file mode 100644 index 0000000..9746564 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-system-color.html.ini
@@ -0,0 +1,6 @@ +[color-valid-system-color.html] + [e.style['color'\] = "AccentColor" should set the property value] + expected: FAIL + + [e.style['color'\] = "AccentColorText" should set the property value] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/gamut-mapping-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/gamut-mapping-expected.txt index 6a01179e5..b1d458ab 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/gamut-mapping-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/gamut-mapping-expected.txt
@@ -4,18 +4,18 @@ FAIL Property color value 'color-mix(in hsl, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 42 +/- 1, expected 42 but got 90 FAIL Property color value 'color-mix(in hsl, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 150 FAIL Property color value 'color-mix(in hsl, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 42 +/- 1, expected 42 but got 90 -PASS Property color value 'color-mix(in hsl, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)' +FAIL Property color value 'color-mix(in hsl, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 92 FAIL Property color value 'color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0 +/- 1, expected 0 but got 19 -PASS Property color value 'color-mix(in hsl, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)' +FAIL Property color value 'color-mix(in hsl, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 91 FAIL Property color value 'color-mix(in hsl, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0 +/- 1, expected 0 but got 20 FAIL Property color value 'color-mix(in hwb, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 249 +/- 1, expected 249 but got 255 FAIL Property color value 'color-mix(in hwb, lab(100 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 150 FAIL Property color value 'color-mix(in hwb, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 42 +/- 1, expected 42 but got 90 FAIL Property color value 'color-mix(in hwb, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 150 FAIL Property color value 'color-mix(in hwb, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 42 +/- 1, expected 42 but got 90 -PASS Property color value 'color-mix(in hwb, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)' +FAIL Property color value 'color-mix(in hwb, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 92 FAIL Property color value 'color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0 +/- 1, expected 0 but got 19 -PASS Property color value 'color-mix(in hwb, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)' +FAIL Property color value 'color-mix(in hwb, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 91 FAIL Property color value 'color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0 +/- 1, expected 0 but got 20 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/gamut-mapping.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/gamut-mapping.html index cfc1d1b..02133ac 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/gamut-mapping.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/gamut-mapping.html
@@ -20,9 +20,9 @@ test_computed_value(`color`, `color-mix(in hsl, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, test_computed_value(`color`, `color-mix(in hsl, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). test_computed_value(`color`, `color-mix(in hsl, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, - test_computed_value(`color`, `color-mix(in hsl, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). + test_computed_value(`color`, `color-mix(in hsl, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). test_computed_value(`color`, `color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). - test_computed_value(`color`, `color-mix(in hsl, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). + test_computed_value(`color`, `color-mix(in hsl, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). test_computed_value(`color`, `color-mix(in hsl, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). test_computed_value(`color`, `color-mix(in hwb, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 249, 66)`); // Naive clip based mapping would give rgb(0, 255, 0). @@ -30,9 +30,9 @@ test_computed_value(`color`, `color-mix(in hwb, lab(0 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, test_computed_value(`color`, `color-mix(in hwb, lch(100 116 334) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). test_computed_value(`color`, `color-mix(in hwb, lch(0 116 334) 100%, rgb(0, 0, 0) 0%)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, - test_computed_value(`color`, `color-mix(in hwb, oklab(100 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). + test_computed_value(`color`, `color-mix(in hwb, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). test_computed_value(`color`, `color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). - test_computed_value(`color`, `color-mix(in hwb, oklch(100 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). + test_computed_value(`color`, `color-mix(in hwb, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). test_computed_value(`color`, `color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/gamut-mapping.html.ini b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/gamut-mapping.html.ini index 167c8d0..63eda37 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/gamut-mapping.html.ini +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/gamut-mapping.html.ini
@@ -17,9 +17,15 @@ [Property color value 'color-mix(in hsl, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)'] expected: FAIL + [Property color value 'color-mix(in hsl, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)'] + expected: FAIL + [Property color value 'color-mix(in hsl, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)'] expected: FAIL + [Property color value 'color-mix(in hsl, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)'] + expected: FAIL + [Property color value 'color-mix(in hwb, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)'] expected: FAIL @@ -38,5 +44,11 @@ [Property color value 'color-mix(in hwb, oklab(0 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)'] expected: FAIL + [Property color value 'color-mix(in hwb, oklab(1 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)'] + expected: FAIL + [Property color value 'color-mix(in hwb, oklch(0 0.399 336.3) 100%, rgb(0, 0, 0) 0%)'] expected: FAIL + + [Property color value 'color-mix(in hwb, oklch(1 0.399 336.3) 100%, rgb(0, 0, 0) 0%)'] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/support/fonts/makegsubfonts.py b/third_party/blink/web_tests/external/wpt/css/css-fonts/support/fonts/makegsubfonts.py index e519b49..b46fa0e6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/support/fonts/makegsubfonts.py +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/support/fonts/makegsubfonts.py
@@ -1,5 +1,3 @@ -from __future__ import print_function - import os import textwrap from xml.etree import ElementTree
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/abs-pos-002.html.ini b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/abs-pos-002.html.ini new file mode 100644 index 0000000..959f114 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/abs-pos-002.html.ini
@@ -0,0 +1,2 @@ +[abs-pos-002.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/baseline-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/baseline-001.html.ini new file mode 100644 index 0000000..a20c5862 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/baseline-001.html.ini
@@ -0,0 +1,2 @@ +[baseline-001.html] + expected: CRASH
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-normal-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-normal-001.html.ini new file mode 100644 index 0000000..abe76ae --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-normal-001.html.ini
@@ -0,0 +1,2 @@ +[grid-gap-normal-001.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-001.html.ini index f4293eb2..714bf4b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-001.html.ini +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-001.html.ini
@@ -1,2 +1,2 @@ [subgrid-baseline-001.html] - expected: FAIL + expected: CRASH
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-003.html.ini b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-003.html.ini new file mode 100644 index 0000000..0eae8d4e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-003.html.ini
@@ -0,0 +1,2 @@ +[subgrid-baseline-003.html] + expected: CRASH
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-004.html.ini b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-004.html.ini new file mode 100644 index 0000000..312f6621 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-004.html.ini
@@ -0,0 +1,2 @@ +[subgrid-baseline-004.html] + expected: CRASH
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-item-block-size-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-item-block-size-001.html.ini new file mode 100644 index 0000000..a31d668 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-item-block-size-001.html.ini
@@ -0,0 +1,2 @@ +[subgrid-item-block-size-001.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/generate-object-fit-and-position-canvas-tests.sh b/third_party/blink/web_tests/external/wpt/css/css-images/tools/generate-object-fit-and-position-canvas-tests.sh similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/generate-object-fit-and-position-canvas-tests.sh rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/generate-object-fit-and-position-canvas-tests.sh
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/generate-object-fit-png-tests.sh b/third_party/blink/web_tests/external/wpt/css/css-images/tools/generate-object-fit-png-tests.sh similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/generate-object-fit-png-tests.sh rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/generate-object-fit-png-tests.sh
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/generate-object-fit-svg-tests.sh b/third_party/blink/web_tests/external/wpt/css/css-images/tools/generate-object-fit-svg-tests.sh similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/generate-object-fit-svg-tests.sh rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/generate-object-fit-svg-tests.sh
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/generate-object-position-png-tests.sh b/third_party/blink/web_tests/external/wpt/css/css-images/tools/generate-object-position-png-tests.sh similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/generate-object-position-png-tests.sh rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/generate-object-position-png-tests.sh
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/generate-object-position-svg-tests.sh b/third_party/blink/web_tests/external/wpt/css/css-images/tools/generate-object-position-svg-tests.sh similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/generate-object-position-svg-tests.sh rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/generate-object-position-svg-tests.sh
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/generate_object_view_box_tests.py b/third_party/blink/web_tests/external/wpt/css/css-images/tools/generate_object_view_box_tests.py similarity index 70% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/generate_object_view_box_tests.py rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/generate_object_view_box_tests.py index ccc5e4d14..452e87ba 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-images/support/generate_object_view_box_tests.py +++ b/third_party/blink/web_tests/external/wpt/css/css-images/tools/generate_object_view_box_tests.py
@@ -1,18 +1,18 @@ +import os import sys +HERE = os.path.abspath(os.path.dirname(__file__)) def generate_file(source, destination, tag, name, image_source): - file = open(source) - lines = file.read() - file.close() + with open(os.path.join(HERE, source)) as file: + lines = file.read() replaced_lines = lines.replace('__TAG__', tag).replace('__NAME__', name).replace( '__IMAGE_SOURCE__', image_source) replaced_lines = '<!-- This is an autogen file. Run support/generate_object_view_box_tests.py to update -->\n' + replaced_lines - new_file = open(destination, "w") - new_file.write(replaced_lines) - new_file.close() + with open(os.path.join(HERE, destination), "w") as new_file: + new_file.write(replaced_lines) def generate_for_object_fit(object_fit): @@ -24,14 +24,12 @@ ] for i in range(len(names)): - source = 'object-view-box-fit-' + object_fit + '-template.html' - destination = '../object-view-box-fit-' + object_fit + '-' + names[ - i] + '.html' + source = f'object-view-box-fit-{object_fit}-template.html' + destination = f'../object-view-box-fit-{object_fit}-{names[i]}.html' generate_file(source, destination, tags[i], names[i], image_sources[i]) - source = 'object-view-box-fit-' + object_fit + '-ref-template.html' - destination = '../object-view-box-fit-' + object_fit + '-' + names[ - i] + '-ref.html' + source = f'object-view-box-fit-{object_fit}-ref-template.html' + destination = f'../object-view-box-fit-{object_fit}-{names[i]}-ref.html' generate_file(source, destination, tags[i], names[i], image_sources[i]) @@ -45,12 +43,11 @@ for i in range(len(names)): source = 'object-view-box-writing-mode-template.html' - destination = '../object-view-box-writing-mode-' + names[i] + '.html' + destination = f'../object-view-box-writing-mode-{names[i]}.html' generate_file(source, destination, tags[i], names[i], image_sources[i]) source = 'object-view-box-writing-mode-ref-template.html' - destination = '../object-view-box-writing-mode-' + names[ - i] + '-ref.html' + destination = f'../object-view-box-writing-mode-{names[i]}-ref.html' generate_file(source, destination, tags[i], names[i], image_sources[i])
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-contain-ref-template.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-contain-ref-template.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-contain-ref-template.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-contain-ref-template.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-contain-template.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-contain-template.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-contain-template.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-contain-template.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-cover-ref-template.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-cover-ref-template.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-cover-ref-template.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-cover-ref-template.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-cover-template.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-cover-template.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-cover-template.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-cover-template.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-fill-ref-template.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-fill-ref-template.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-fill-ref-template.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-fill-ref-template.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-fill-template.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-fill-template.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-fill-template.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-fill-template.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-none-ref-template.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-none-ref-template.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-none-ref-template.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-none-ref-template.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-none-template.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-none-template.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-fit-none-template.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-fit-none-template.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-writing-mode-ref-template.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-writing-mode-ref-template.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-writing-mode-ref-template.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-writing-mode-ref-template.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-writing-mode-template.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-writing-mode-template.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/object-view-box-writing-mode-template.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/object-view-box-writing-mode-template.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/template-object-fit-ref.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/template-object-fit-ref.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/template-object-fit-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/template-object-fit-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/template-object-fit-test.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/template-object-fit-test.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/template-object-fit-test.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/template-object-fit-test.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/template-object-position-ref.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/template-object-position-ref.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/template-object-position-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/template-object-position-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/support/template-object-position-test.html b/third_party/blink/web_tests/external/wpt/css/css-images/tools/template-object-position-test.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-images/support/template-object-position-test.html rename to third_party/blink/web_tests/external/wpt/css/css-images/tools/template-object-position-test.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-line-height-tests.py b/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-line-height-tests.py index 12fb6a3a..e2a4457 100755 --- a/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-line-height-tests.py +++ b/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-line-height-tests.py
@@ -8,8 +8,6 @@ reftest.list to the stdout. """ -from __future__ import unicode_literals, print_function, absolute_import - TEST_FILE = 'text-emphasis-line-height-{:03}{}.html' TEST_TEMPLATE = '''<!DOCTYPE html> <meta charset="utf-8">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-position-property-tests.py b/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-position-property-tests.py index 5279590..f2baf02 100755 --- a/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-position-property-tests.py +++ b/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-position-property-tests.py
@@ -9,8 +9,6 @@ tests it generated in the format of Mozilla reftest.list to the stdout. """ -from __future__ import unicode_literals, print_function, absolute_import - import itertools TEST_FILE = 'text-emphasis-position-property-{:03}{}.html'
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-ruby-tests.py b/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-ruby-tests.py index fdbaec0..f1158f5 100755 --- a/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-ruby-tests.py +++ b/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-ruby-tests.py
@@ -7,8 +7,6 @@ tests it generated in the format of Mozilla reftest.list to the stdout. """ -from __future__ import unicode_literals, print_function, absolute_import - TEST_FILE = 'text-emphasis-ruby-{:03}{}.html' TEST_TEMPLATE = '''<!DOCTYPE html> <meta charset="utf-8">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-style-property-tests.py b/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-style-property-tests.py index 1b1d6fc1..b6ad1f72 100755 --- a/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-style-property-tests.py +++ b/third_party/blink/web_tests/external/wpt/css/css-text-decor/tools/generate-text-emphasis-style-property-tests.py
@@ -8,8 +8,6 @@ tests it generated in the format of Mozilla reftest.list to the stdout. """ -from __future__ import unicode_literals, print_function, absolute_import - TEST_FILE = 'text-emphasis-style-property-{:03}{}.html' TEST_TEMPLATE = '''<!DOCTYPE html> <meta charset="utf-8">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/tools/generate-segment-break-transformation-rules-tests.py b/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/tools/generate-segment-break-transformation-rules-tests.py index fc894161..6689ef5 100755 --- a/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/tools/generate-segment-break-transformation-rules-tests.py +++ b/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/tools/generate-segment-break-transformation-rules-tests.py
@@ -18,8 +18,6 @@ tests it generated in the format of Mozilla reftest.list to the stdout. """ -from __future__ import unicode_literals, print_function, absolute_import - TEST_FILE = 'segment-break-transformation-rules-{:03}.html' TEST_TEMPLATE = '''<!DOCTYPE html> <meta charset="utf-8">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-capitalize-007.html.ini b/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-capitalize-007.html.ini index 4dd4f07..59933dbf 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-capitalize-007.html.ini +++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-capitalize-007.html.ini
@@ -1,3 +1,4 @@ [text-transform-capitalize-007.html] expected: + if (product == "content_shell") and (os == "win") and (port == "win11"): FAIL if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-capitalize-030.html.ini b/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-capitalize-030.html.ini index c3e6d0f..6d9f4066 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-capitalize-030.html.ini +++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-capitalize-030.html.ini
@@ -1,3 +1,4 @@ [text-transform-capitalize-030.html] expected: if (product == "content_shell") and (os == "win") and (port == "win10.20h2"): FAIL + if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/appearance-cssom-001.html b/third_party/blink/web_tests/external/wpt/css/css-ui/appearance-cssom-001.html index 1618c2b..2da20a0a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-ui/appearance-cssom-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/appearance-cssom-001.html
@@ -2,8 +2,11 @@ <title>CSS Basic User Interface Test: appearance CSSOM</title> <link rel="help" href="https://drafts.csswg.org/css-ui-4/#appearance-switching"> <meta name="assert" content="CSSOM for the appearance/-webkit-appearance property is correct."> +<meta name="variant" content=""> +<meta name="variant" content="?exclude=Invalid"> <script src=/resources/testharness.js></script> <script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests-by-key.js"></script> <button id=button>Test</button> <script> const button = document.getElementById('button'); @@ -191,7 +194,7 @@ } for (const prop of ["-webkit-appearance", "appearance"]) { for (const value of values) { - test(() => { + subsetTestByKey(`Values`, test, () => { button.removeAttribute('style'); button.style.setProperty(prop, value); assert_style_for_prop(button.style, prop, value); @@ -204,7 +207,7 @@ } for (const value of compat_values) { - test(() => { + subsetTestByKey(`Compat`, test, () => { button.removeAttribute('style'); button.style.setProperty(prop, value); assert_style_for_prop(button.style, prop, [value, ""]); @@ -217,7 +220,7 @@ } for (const value of invalid_values) { - test(() => { + subsetTestByKey(`Invalid`, test, () => { button.removeAttribute('style'); button.style.setProperty(prop, value); assert_style_for_prop(button.style, prop, ""); @@ -245,7 +248,7 @@ "-tc-", ]) { const prop = `${prefix}appearance`; - test(() => { + subsetTestByKey(`Prefixes`, test, () => { button.removeAttribute('style'); button.style.setProperty(prop, 'none'); assert_equals(button.style.getPropertyValue(prop), '');
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/appearance-listbox-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/appearance-listbox-001.html.ini new file mode 100644 index 0000000..2131756c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/appearance-listbox-001.html.ini
@@ -0,0 +1,3 @@ +[appearance-listbox-001.html] + expected: + if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-border-block-start-width-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-border-block-start-width-001.html.ini new file mode 100644 index 0000000..c3109af --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-border-block-start-width-001.html.ini
@@ -0,0 +1,3 @@ +[kind-of-widget-fallback-color-input-border-block-start-width-001.html] + expected: + if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-border-left-width-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-border-left-width-001.html.ini new file mode 100644 index 0000000..790ec0a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-border-left-width-001.html.ini
@@ -0,0 +1,3 @@ +[kind-of-widget-fallback-color-input-border-left-width-001.html] + expected: + if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-bottom-left-radius-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-bottom-left-radius-001.html.ini new file mode 100644 index 0000000..9d37fdd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-bottom-left-radius-001.html.ini
@@ -0,0 +1,3 @@ +[kind-of-widget-fallback-input-search-text-border-bottom-left-radius-001.html] + expected: + if (product == "content_shell") and (os == "mac"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-inline-end-color-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-inline-end-color-001.html.ini index 4293acf..2f8610f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-inline-end-color-001.html.ini +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-inline-end-color-001.html.ini
@@ -1,3 +1,4 @@ [kind-of-widget-fallback-input-text-border-inline-end-color-001.html] expected: + if (product == "content_shell") and (os == "win") and (port == "win11"): FAIL if (product == "content_shell") and (os == "linux"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-inline-end-style-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-inline-end-style-001.html.ini index ba3ab64bc..6fe71ad 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-inline-end-style-001.html.ini +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-inline-end-style-001.html.ini
@@ -1,3 +1,4 @@ [kind-of-widget-fallback-input-text-border-inline-end-style-001.html] expected: + if (product == "content_shell") and (os == "linux"): FAIL if (product == "content_shell") and (os == "mac"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-left-color-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-left-color-001.html.ini new file mode 100644 index 0000000..adb2eec9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-left-color-001.html.ini
@@ -0,0 +1,3 @@ +[kind-of-widget-fallback-input-text-border-left-color-001.html] + expected: + if (product == "content_shell") and (os == "win") and (port == "win10.20h2"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-view-transitions/input-blocked-when-rendering-suppressed.html.ini b/third_party/blink/web_tests/external/wpt/css/css-view-transitions/input-blocked-when-rendering-suppressed.html.ini deleted file mode 100644 index 7deeaa4..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-view-transitions/input-blocked-when-rendering-suppressed.html.ini +++ /dev/null
@@ -1,3 +0,0 @@ -[input-blocked-when-rendering-suppressed.html] - [Input when rendering suppressed is ignored] - expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/css-backdrop-filters-animation-blur.html.ini b/third_party/blink/web_tests/external/wpt/css/filter-effects/css-backdrop-filters-animation-blur.html.ini new file mode 100644 index 0000000..823e83d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/css-backdrop-filters-animation-blur.html.ini
@@ -0,0 +1,3 @@ +[css-backdrop-filters-animation-blur.html] + expected: + if (product == "content_shell") and (os == "mac"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/docs/requirements.txt b/third_party/blink/web_tests/external/wpt/docs/requirements.txt index 0ad8484..589a98ea 100644 --- a/third_party/blink/web_tests/external/wpt/docs/requirements.txt +++ b/third_party/blink/web_tests/external/wpt/docs/requirements.txt
@@ -1,5 +1,5 @@ recommonmark==0.7.1 -sphinx-argparse==0.3.1 +sphinx-argparse==0.3.2 sphinx-autobuild==2021.3.14 sphinx-js==3.2.1 sphinx==4.4.0
diff --git a/third_party/blink/web_tests/external/wpt/dom/nodes/Document-createElement-namespace-tests/generate.py b/third_party/blink/web_tests/external/wpt/dom/nodes/Document-createElement-namespace-tests/generate.py index a0bca54..20c866b 100755 --- a/third_party/blink/web_tests/external/wpt/dom/nodes/Document-createElement-namespace-tests/generate.py +++ b/third_party/blink/web_tests/external/wpt/dom/nodes/Document-createElement-namespace-tests/generate.py
@@ -1,7 +1,5 @@ #!/usr/bin/python -from __future__ import print_function - import os import sys
diff --git a/third_party/blink/web_tests/external/wpt/encrypted-media/polyfill/make-polyfill-tests.py b/third_party/blink/web_tests/external/wpt/encrypted-media/polyfill/make-polyfill-tests.py index 532037e..97c6fc7 100755 --- a/third_party/blink/web_tests/external/wpt/encrypted-media/polyfill/make-polyfill-tests.py +++ b/third_party/blink/web_tests/external/wpt/encrypted-media/polyfill/make-polyfill-tests.py
@@ -1,7 +1,5 @@ #!/usr/bin/python -from __future__ import print_function - import os, re, os.path, glob head = re.compile( r"^(\s*</head>)", re.MULTILINE )
diff --git a/third_party/blink/web_tests/external/wpt/fetch/range/blob.any-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/range/blob.any-expected.txt index 6810b95..f48ee4f 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/range/blob.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/fetch/range/blob.any-expected.txt
@@ -4,9 +4,14 @@ PASS A blob range request with no start. PASS A simple blob range request with whitespace. PASS Blob content with short content and a large range end +PASS Blob content with short content and a range end matching content length PASS Blob range with whitespace before and after hyphen PASS Blob range with whitespace after hyphen -FAIL Blob range with whitespace around equals sign assert_equals: HTTP status is 206 expected 206 but got 200 +PASS Blob range with whitespace around equals sign +FAIL Blob range with no value assert_unreached: Should have rejected: undefined Reached unreachable code +FAIL Blob range with incorrect range header assert_unreached: Should have rejected: undefined Reached unreachable code +FAIL Blob range with incorrect range header #2 assert_unreached: Should have rejected: undefined Reached unreachable code +FAIL Blob range with incorrect range header #3 assert_unreached: Should have rejected: undefined Reached unreachable code PASS Blob range request with multiple range values PASS Blob range request with multiple range values and whitespace FAIL Blob range request with trailing comma assert_unreached: Should have rejected: undefined Reached unreachable code @@ -19,5 +24,6 @@ FAIL Blob range should include '=' assert_unreached: Should have rejected: undefined Reached unreachable code FAIL Blob range should include 'bytes=' assert_unreached: Should have rejected: undefined Reached unreachable code PASS Blob content with short content and a large range start +PASS Blob content with short content and a range start matching the content length Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/fetch/range/blob.any.js b/third_party/blink/web_tests/external/wpt/fetch/range/blob.any.js index 2f1bf5c..1db3b24 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/range/blob.any.js +++ b/third_party/blink/web_tests/external/wpt/fetch/range/blob.any.js
@@ -47,6 +47,15 @@ result: "much here", }, { + name: "Blob content with short content and a range end matching content length", + data: ["Not much here"], + type: "text/plain", + range: "bytes=4-13", + content_length: 9, + content_range: "bytes 4-12/13", + result: "much here", + }, + { name: "Blob range with whitespace before and after hyphen", data: ["Valid whitespace #1"], type: "text/plain", @@ -68,7 +77,7 @@ name: "Blob range with whitespace around equals sign", data: ["Valid whitespace #3"], type: "text/plain", - range: "bytes \t =\t 6", + range: "bytes \t =\t 6-", content_length: 13, content_range: "bytes 6-18/19", result: "whitespace #3", @@ -77,100 +86,106 @@ const unsupportedBlobRange = [ { + name: "Blob range with no value", + data: ["Blob range should have a value"], + type: "text/plain", + range: "", + }, + { + name: "Blob range with incorrect range header", + data: ["A"], + type: "text/plain", + range: "byte=0-" + }, + { + name: "Blob range with incorrect range header #2", + data: ["A"], + type: "text/plain", + range: "bytes" + }, + { + name: "Blob range with incorrect range header #3", + data: ["A"], + type: "text/plain", + range: "bytes\t \t" + }, + { name: "Blob range request with multiple range values", data: ["Multiple ranges are not currently supported"], type: "text/plain", - headers: { - "Range": "bytes=0-5,15-" - } + range: "bytes=0-5,15-", }, { name: "Blob range request with multiple range values and whitespace", data: ["Multiple ranges are not currently supported"], type: "text/plain", - headers: { - "Range": "bytes=0-5, 15-" - } + range: "bytes=0-5, 15-", }, { name: "Blob range request with trailing comma", data: ["Range with invalid trailing comma"], type: "text/plain", - headers: { - "Range": "bytes=0-5," - } + range: "bytes=0-5,", }, { name: "Blob range with no start or end", data: ["Range with no start or end"], type: "text/plain", - headers: { - "Range": "bytes=-" - } + range: "bytes=-", }, { name: "Blob range request with short range end", data: ["Range end should be greater than range start"], - type: "text/plain" , - headers: { - "Range": "bytes=10-5" - } + type: "text/plain", + range: "bytes=10-5", }, { name: "Blob range start should be an ASCII digit", data: ["Range start must be an ASCII digit"], - type: "text/plain" , - headers: { - "Range": "bytes=x-5" - } + type: "text/plain", + range: "bytes=x-5", }, { name: "Blob range should have a dash", data: ["Blob range should have a dash"], - type: "text/plain" , - headers: { - "Range": "bytes=5" - } + type: "text/plain", + range: "bytes=5", }, { name: "Blob range end should be an ASCII digit", data: ["Range end must be an ASCII digit"], - type: "text/plain" , - headers: { - "Range": "bytes=5-x" - } + type: "text/plain", + range: "bytes=5-x", }, { name: "Blob range should include '-'", data: ["Range end must include '-'"], - type: "text/plain" , - headers: { - "Range": "bytes=x" - } + type: "text/plain", + range: "bytes=x", }, { name: "Blob range should include '='", data: ["Range end must include '='"], - type: "text/plain" , - headers: { - "Range": "bytes 5-" - } + type: "text/plain", + range: "bytes 5-", }, { name: "Blob range should include 'bytes='", data: ["Range end must include 'bytes='"], - type: "text/plain" , - headers: { - "Range": "5-" - } + type: "text/plain", + range: "5-", }, { name: "Blob content with short content and a large range start", data: ["Not much here"], type: "text/plain", - headers: { - "Range": "bytes=100000-", - } + range: "bytes=100000-", + }, + { + name: "Blob content with short content and a range start matching the content length", + data: ["Not much here"], + type: "text/plain", + range: "bytes=13-", }, ]; @@ -179,30 +194,30 @@ const blob = new Blob(data, { "type" : type }); const blobURL = URL.createObjectURL(blob); t.add_cleanup(() => URL.revokeObjectURL(blobURL)); - return fetch(blobURL, { + const resp = await fetch(blobURL, { "headers": { "Range": range } - }).then(function(resp) { - assert_equals(resp.status, 206, "HTTP status is 206"); - assert_equals(resp.type, "basic", "response type is basic"); - assert_equals(resp.headers.get("Content-Type"), type, "Content-Type is " + resp.headers.get("Content-Type")); - assert_equals(resp.headers.get("Content-Length"), content_length.toString(), "Content-Length is " + resp.headers.get("Content-Length")); - assert_equals(resp.headers.get("Content-Range"), content_range, "Content-Range is " + resp.headers.get("Content-Range")); - return resp.text(); - }).then(function(text) { - assert_equals(text, result, "Response's body is correct"); }); + assert_equals(resp.status, 206, "HTTP status is 206"); + assert_equals(resp.type, "basic", "response type is basic"); + assert_equals(resp.headers.get("Content-Type"), type, "Content-Type is " + resp.headers.get("Content-Type")); + assert_equals(resp.headers.get("Content-Length"), content_length.toString(), "Content-Length is " + resp.headers.get("Content-Length")); + assert_equals(resp.headers.get("Content-Range"), content_range, "Content-Range is " + resp.headers.get("Content-Range")); + const text = await resp.text(); + assert_equals(text, result, "Response's body is correct"); }, name); }); -unsupportedBlobRange.forEach(({ name, data, type, headers }) => { +unsupportedBlobRange.forEach(({ name, data, type, range }) => { promise_test(t => { const blob = new Blob(data, { "type" : type }); const blobURL = URL.createObjectURL(blob); t.add_cleanup(() => URL.revokeObjectURL(blobURL)); const promise = fetch(blobURL, { - "headers": headers, + "headers": { + "Range": range + } }); return promise_rejects_js(t, TypeError, promise); }, name);
diff --git a/third_party/blink/web_tests/external/wpt/fetch/range/blob.any.js.ini b/third_party/blink/web_tests/external/wpt/fetch/range/blob.any.js.ini index b25774b..a760cbe 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/range/blob.any.js.ini +++ b/third_party/blink/web_tests/external/wpt/fetch/range/blob.any.js.ini
@@ -23,10 +23,19 @@ [Blob range start should be an ASCII digit] expected: FAIL + [Blob range with incorrect range header] + expected: FAIL + + [Blob range with incorrect range header #2] + expected: FAIL + + [Blob range with incorrect range header #3] + expected: FAIL + [Blob range with no start or end] expected: FAIL - [Blob range with whitespace around equals sign] + [Blob range with no value] expected: FAIL @@ -55,8 +64,17 @@ [Blob range start should be an ASCII digit] expected: FAIL + [Blob range with incorrect range header] + expected: FAIL + + [Blob range with incorrect range header #2] + expected: FAIL + + [Blob range with incorrect range header #3] + expected: FAIL + [Blob range with no start or end] expected: FAIL - [Blob range with whitespace around equals sign] + [Blob range with no value] expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/fetch/range/blob.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/range/blob.any.worker-expected.txt index 6810b95..f48ee4f 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/range/blob.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/fetch/range/blob.any.worker-expected.txt
@@ -4,9 +4,14 @@ PASS A blob range request with no start. PASS A simple blob range request with whitespace. PASS Blob content with short content and a large range end +PASS Blob content with short content and a range end matching content length PASS Blob range with whitespace before and after hyphen PASS Blob range with whitespace after hyphen -FAIL Blob range with whitespace around equals sign assert_equals: HTTP status is 206 expected 206 but got 200 +PASS Blob range with whitespace around equals sign +FAIL Blob range with no value assert_unreached: Should have rejected: undefined Reached unreachable code +FAIL Blob range with incorrect range header assert_unreached: Should have rejected: undefined Reached unreachable code +FAIL Blob range with incorrect range header #2 assert_unreached: Should have rejected: undefined Reached unreachable code +FAIL Blob range with incorrect range header #3 assert_unreached: Should have rejected: undefined Reached unreachable code PASS Blob range request with multiple range values PASS Blob range request with multiple range values and whitespace FAIL Blob range request with trailing comma assert_unreached: Should have rejected: undefined Reached unreachable code @@ -19,5 +24,6 @@ FAIL Blob range should include '=' assert_unreached: Should have rejected: undefined Reached unreachable code FAIL Blob range should include 'bytes=' assert_unreached: Should have rejected: undefined Reached unreachable code PASS Blob content with short content and a large range start +PASS Blob content with short content and a range start matching the content length Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/TODO b/third_party/blink/web_tests/external/wpt/fledge/tentative/TODO index 839d286..d1d39308 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/TODO +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/TODO
@@ -25,7 +25,7 @@ * In fencedframes window.fence.setReportEventDataForAutomaticBeacons() * Calling leaveAdInterestGroup() in the frame of a winning ad (and one of its component ads) -* Network errors / timeouts. +* Network timeouts. If possible: * Aggregate reporting.
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/join-leave-ad-interest-group.https.sub.window.js.ini b/third_party/blink/web_tests/external/wpt/fledge/tentative/join-leave-ad-interest-group.https.sub.window.js.ini new file mode 100644 index 0000000..6fb36db --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/join-leave-ad-interest-group.https.sub.window.js.ini
@@ -0,0 +1,249 @@ +[join-leave-ad-interest-group.https.sub.window.html] + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":false,"interestGroup":null}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":false,"interestGroup":{"name":"default name"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":false,"interestGroup":{"owner":"http://web-platform.test:8444","name":"default name"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":false,"interestGroup":{"owner":"https://web-platform.test:8444"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":false,"interestGroup":{"owner":"wss://web-platform.test:8444","name":"default name"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":false,"interestGroup":{"owner":"www.web-platform.test","name":"default name"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":false,"interestGroup":{"owner":null,"name":"default name"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":false,"interestGroup":{}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","adComponents":5}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","adComponents":[{"1":[2,3\],"metadata":[{"a":"b"},"c"\]}\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","adComponents":[{}\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","adComponents":null}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","adComponents":{}}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","ads":5}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","ads":[{"1":[2,3\],"metadata":[{"a":"b"},"c"\]}\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","ads":[{}\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","ads":null}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","ads":{}}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicUrl":"data:text/javascript,Foo"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicUrl":"https://www.web-platform.test/foo.js"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingWasmHelperUrl":"data:application/wasm,Foo"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingWasmHelperUrl":"https://www.web-platform.test/foo.js"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","dailyUpdateUrl":"data:application/wasm,Foo"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","dailyUpdateUrl":"https://www.web-platform.test/foo.js"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","prioritySignalsOverrides":1}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","prioritySignalsOverrides":null}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","prioritySignalsOverrides":{"a":"apple"}}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","priorityVector":1}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","priorityVector":null}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","priorityVector":{"a":"apple"}}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","trustedBiddingSignalsKeys":null}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","trustedBiddingSignalsKeys":{}}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","trustedBiddingSignalsUrl":"data:application/json,{}"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","trustedBiddingSignalsUrl":"https://www.web-platform.test/foo.js"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":""}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","adComponents":[\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","adComponents":[{"renderUrl":"https://somewhere.test/","metadata":null,"someOtherField":"foo"}\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","adComponents":[{"renderUrl":"https://somewhere.test/","metadata":null}\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","adComponents":[{"renderUrl":"https://somewhere.test/"},{"renderUrl":"https://elsewhere.test/"}\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","adComponents":[{"renderUrl":"https://somewhere.test/"}\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","ads":[\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","ads":[{"renderUrl":"https://somewhere.test/","metadata":null,"someOtherField":"foo"}\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","ads":[{"renderUrl":"https://somewhere.test/","metadata":null}\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","ads":[{"renderUrl":"https://somewhere.test/"},{"renderUrl":"https://somewhere-else.test/"}\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","ads":[{"renderUrl":"https://somewhere.test/"}\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicUrl":"https://web-platform.test:8444/foo.js"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicUrl":"relative/path"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicUrl":null}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingWasmHelperUrl":"https://web-platform.test:8444/foo.js"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingWasmHelperUrl":"relative/path"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingWasmHelperUrl":null}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","dailyUpdateUrl":"https://web-platform.test:8444/foo.js"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","dailyUpdateUrl":"relative/path"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","dailyUpdateUrl":null}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","enableBiddingSignalsPrioritization":false}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","enableBiddingSignalsPrioritization":true}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","executionMode":"compatibility"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","executionMode":"groupByOrigin"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","executionMode":"unknownValuesAreValid"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","extra":false,"fields":{"do":"not"},"matter":"at","all":[3,4,5\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","priority":-1.5}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","priority":0}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","priority":1}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","prioritySignalsOverrides":{"a":1,"b":-4.5,"a.b":0}}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","prioritySignalsOverrides":{"a":1}}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","prioritySignalsOverrides":{}}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","priorityVector":{"a":1,"b":-4.5,"a.b":0}}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","priorityVector":{"a":1}}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","priorityVector":{}}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","trustedBiddingSignalsKeys":["a",4,"Foo"\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","trustedBiddingSignalsKeys":[\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","trustedBiddingSignalsUrl":"https://web-platform.test:8444/foo.js"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","trustedBiddingSignalsUrl":"relative/path"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","trustedBiddingSignalsUrl":null}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","userBiddingSignals":"foo"}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","userBiddingSignals":15}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","userBiddingSignals":[5,"foo",[-6.4,{"a":"b"}\]\]}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","userBiddingSignals":null}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","userBiddingSignals":{"a":[5,"foo",{"b":-6.4}\]}}}] + expected: FAIL + + [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name"}}] + expected: FAIL + + [Join same interest group overwrites old matching group.] + expected: FAIL + + [Leave an interest group that was never joined.] + expected: FAIL + + [Leaving interest group actually leaves interest group.] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window-expected.txt b/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window-expected.txt index 07b58b7..f8a3f883 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window-expected.txt
@@ -1,4 +1,5 @@ This is a testharness.js-based test. +FAIL Bidding logic script: error=close-connection promise_test: Unhandled rejection with value: object "TypeError: navigator.joinAdInterestGroup is not a function" FAIL Bidding logic script: error=http-error promise_test: Unhandled rejection with value: object "TypeError: navigator.joinAdInterestGroup is not a function" FAIL Bidding logic script: error=no-content-type promise_test: Unhandled rejection with value: object "TypeError: navigator.joinAdInterestGroup is not a function" FAIL Bidding logic script: error=wrong-content-type promise_test: Unhandled rejection with value: object "TypeError: navigator.joinAdInterestGroup is not a function" @@ -18,6 +19,7 @@ FAIL Bidding logic script: generateBid=return {render: interestGroup.ads[0].renderUrl}; promise_test: Unhandled rejection with value: object "TypeError: navigator.joinAdInterestGroup is not a function" FAIL Bidding logic script: generateBid=return {bid:0, render: interestGroup.ads[0].renderUrl}; promise_test: Unhandled rejection with value: object "TypeError: navigator.joinAdInterestGroup is not a function" FAIL Bidding logic script: generateBid=return {bid:-1, render: interestGroup.ads[0].renderUrl}; promise_test: Unhandled rejection with value: object "TypeError: navigator.joinAdInterestGroup is not a function" +FAIL Decision logic script: error=close-connection promise_test: Unhandled rejection with value: object "TypeError: navigator.joinAdInterestGroup is not a function" FAIL Decision logic script: error=http-error promise_test: Unhandled rejection with value: object "TypeError: navigator.joinAdInterestGroup is not a function" FAIL Decision logic script: error=no-content-type promise_test: Unhandled rejection with value: object "TypeError: navigator.joinAdInterestGroup is not a function" FAIL Decision logic script: error=wrong-content-type promise_test: Unhandled rejection with value: object "TypeError: navigator.joinAdInterestGroup is not a function"
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window.js index 4d24b573..a944b860 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window.js +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window.js
@@ -1,6 +1,7 @@ // META: script=/resources/testdriver.js // META: script=/common/utils.js // META: script=resources/fledge-util.js +// META: timeout=long // The tests in this file focus on simple auctions (one bidder, one seller, one // origin, one frame) which have no winning bid, either due to errors or due to @@ -10,6 +11,7 @@ // appended to script URLs to make the python scripts that generate bidding // logic and decision logic scripts with errors. const COMMON_SCRIPT_ERRORS = [ + 'error=close-connection', 'error=http-error', 'error=no-content-type', 'error=wrong-content-type',
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window.js.ini b/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window.js.ini new file mode 100644 index 0000000..9ca0bf8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window.js.ini
@@ -0,0 +1,108 @@ +[no-winner.https.sub.window.html] + [Bidding logic script: error=bad-allow-fledge] + expected: FAIL + + [Bidding logic script: error=fledge-not-allowed] + expected: FAIL + + [Bidding logic script: error=http-error] + expected: FAIL + + [Bidding logic script: error=no-allow-fledge] + expected: FAIL + + [Bidding logic script: error=no-body] + expected: FAIL + + [Bidding logic script: error=no-content-type] + expected: FAIL + + [Bidding logic script: error=no-generateBid] + expected: FAIL + + [Bidding logic script: error=wrong-content-type] + expected: FAIL + + [Bidding logic script: generateBid=This does not compile] + expected: FAIL + + [Bidding logic script: generateBid=return "Foo";] + expected: FAIL + + [Bidding logic script: generateBid=return 5;] + expected: FAIL + + [Bidding logic script: generateBid=return interestGroup.ads[0\].renderUrl;] + expected: FAIL + + [Bidding logic script: generateBid=return {bid: 1, render: "https://not-in-ads-array.test/"};] + expected: FAIL + + [Bidding logic script: generateBid=return {bid: 1};] + expected: FAIL + + [Bidding logic script: generateBid=return {bid:-1, render: interestGroup.ads[0\].renderUrl};] + expected: FAIL + + [Bidding logic script: generateBid=return {bid:0, render: interestGroup.ads[0\].renderUrl};] + expected: FAIL + + [Bidding logic script: generateBid=return {render: interestGroup.ads[0\].renderUrl};] + expected: FAIL + + [Bidding logic script: generateBid=throw 1;] + expected: FAIL + + [Bidding logic script: generateBid=while(1);] + expected: FAIL + + [Decision logic script: error=bad-allow-fledge] + expected: FAIL + + [Decision logic script: error=fledge-not-allowed] + expected: FAIL + + [Decision logic script: error=http-error] + expected: FAIL + + [Decision logic script: error=no-allow-fledge] + expected: FAIL + + [Decision logic script: error=no-body] + expected: FAIL + + [Decision logic script: error=no-content-type] + expected: FAIL + + [Decision logic script: error=no-scoreAd] + expected: FAIL + + [Decision logic script: error=wrong-content-type] + expected: FAIL + + [Decision logic script: scoreAd=This does not compile] + expected: FAIL + + [Decision logic script: scoreAd=return "Foo";] + expected: FAIL + + [Decision logic script: scoreAd=return -1;] + expected: FAIL + + [Decision logic script: scoreAd=return 0;] + expected: FAIL + + [Decision logic script: scoreAd=return {desirability: "Foo"};] + expected: FAIL + + [Decision logic script: scoreAd=return {desirability: -1};] + expected: FAIL + + [Decision logic script: scoreAd=return {desirability: 0};] + expected: FAIL + + [Decision logic script: scoreAd=throw 1;] + expected: FAIL + + [Decision logic script: scoreAd=while(1);] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/register-ad-beacon.https.sub.window.js.ini b/third_party/blink/web_tests/external/wpt/fledge/tentative/register-ad-beacon.https.sub.window.js.ini new file mode 100644 index 0000000..786171f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/register-ad-beacon.https.sub.window.js.ini
@@ -0,0 +1,36 @@ +[register-ad-beacon.https.sub.window.html] + [Buyer calls registerAdBeacon() multiple times.] + expected: FAIL + + [Buyer calls registerAdBeacon() with multiple beacons.] + expected: FAIL + + [Buyer calls registerAdBeacon(), beacon sent with body.] + expected: FAIL + + [Buyer calls registerAdBeacon().] + expected: FAIL + + [Buyer calls registerAdBeacon(). reportEvent() called twice.] + expected: FAIL + + [Seller and buyer call registerAdBeacon() with separate reportEvent() calls.] + expected: FAIL + + [Seller and buyer call registerAdBeacon() with shared reportEvent() call.] + expected: FAIL + + [Seller calls registerAdBeacon() multiple times.] + expected: FAIL + + [Seller calls registerAdBeacon() with multiple beacons.] + expected: FAIL + + [Seller calls registerAdBeacon(), beacon sent with body.] + expected: FAIL + + [Seller calls registerAdBeacon().] + expected: FAIL + + [Seller calls registerAdBeacon(). reportEvent() called twice.] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/reporting-arguments.https.sub.window.js.ini b/third_party/blink/web_tests/external/wpt/fledge/tentative/reporting-arguments.https.sub.window.js.ini new file mode 100644 index 0000000..e43b6d5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/reporting-arguments.https.sub.window.js.ini
@@ -0,0 +1,60 @@ +[reporting-arguments.https.sub.window.html] + [Seller passes array to bidder.] + expected: FAIL + + [Seller passes number to bidder.] + expected: FAIL + + [Seller passes object to bidder.] + expected: FAIL + + [Seller passes string to bidder.] + expected: FAIL + + [browserSignals.bid test.] + expected: FAIL + + [browserSignals.dataVersion test.] + expected: FAIL + + [browserSignals.desirability test.] + expected: FAIL + + [browserSignals.highestScoringOtherBid with no other interest groups test.] + expected: FAIL + + [browserSignals.highestScoringOtherBid with other bids.] + expected: FAIL + + [browserSignals.highestScoringOtherBid with other groups that do not bid.] + expected: FAIL + + [browserSignals.interestGroupName test.] + expected: FAIL + + [browserSignals.madeHighestScoringOtherBid with group that did not bid.] + expected: FAIL + + [browserSignals.madeHighestScoringOtherBid with no other bids.] + expected: FAIL + + [browserSignals.madeHighestScoringOtherBid with other bid.] + expected: FAIL + + [browserSignals.modifiedBid test.] + expected: FAIL + + [browserSignals.renderUrl test.] + expected: FAIL + + [browserSignals.seller test.] + expected: FAIL + + [browserSignals.topLevelSeller and browserSignals.componentSeller test.] + expected: FAIL + + [browserSignals.topLevelSellerSignals test.] + expected: FAIL + + [browserSignals.topWindowHostname test.] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/bidding-logic.sub.py b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/bidding-logic.sub.py index dfc4d86..6b4e179 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/bidding-logic.sub.py +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/bidding-logic.sub.py
@@ -6,6 +6,13 @@ def main(request, response): error = request.GET.first(b"error", None) + if error == b"close-connection": + # Close connection without writing anything, to simulate a network + # error. The write call is needed to avoid writing the default headers. + response.writer.write("") + response.close_connection = True + return + if error == b"http-error": response.status = (404, b"OK") else:
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/decision-logic.sub.py b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/decision-logic.sub.py index 8d5303a..9a97d45b 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/decision-logic.sub.py +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/decision-logic.sub.py
@@ -6,6 +6,13 @@ def main(request, response): error = request.GET.first(b"error", None) + if error == b"close-connection": + # Close connection without writing anything, to simulate a network + # error. The write call is needed to avoid writing the default headers. + response.writer.write("") + response.close_connection = True + return + if error == b"http-error": response.status = (404, b"OK") else:
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.js index 6432752..738764f6 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.js +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.js
@@ -238,7 +238,7 @@ await joinInterestGroup(test, uuid, testConfig.interestGroupOverrides); let result = await runBasicFledgeAuction( test, uuid, testConfig.auctionConfigOverrides); - assert_equals(result, null, 'Auction unexpectedly had a winner'); + assert_true(result === null, 'Auction unexpectedly had a winner'); } // Test helper for report phase of auctions that lets the caller specify the
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/send-report-to.https.sub.window.js.ini b/third_party/blink/web_tests/external/wpt/fledge/tentative/send-report-to.https.sub.window.js.ini new file mode 100644 index 0000000..d3ca367 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/send-report-to.https.sub.window.js.ini
@@ -0,0 +1,30 @@ +[send-report-to.https.sub.window.html] + [Bidder calls sendReportTo() twice, which throws an exception.] + expected: FAIL + + [Both send reports, seller passes nothing to bidder.] + expected: FAIL + + [Only bidder sends a report] + expected: FAIL + + [Only bidder sends a report, seller has no reportResult() method] + expected: FAIL + + [Only bidder sends a report, seller passes a message to bidder] + expected: FAIL + + [Only bidder sends a report, seller throws an exception] + expected: FAIL + + [Only seller sends a report] + expected: FAIL + + [Only seller sends a report, bidder has no reportWin() method] + expected: FAIL + + [Only seller sends a report, bidder throws an exception] + expected: FAIL + + [Seller calls sendReportTo() twice, which throws an exception.] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.svg.html.ini b/third_party/blink/web_tests/external/wpt/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.svg.html.ini new file mode 100644 index 0000000..1a3fc37e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.svg.html.ini
@@ -0,0 +1,3 @@ +[2d.drawImage.svg.html] + expected: + if product == "chrome": [ERROR, OK]
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html.ini b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html.ini index cb417bf5..1aea5841 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html.ini +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html.ini
@@ -1,4 +1,6 @@ [canvas-display-p3-drawImage-ImageBitmap-cloned.html] + expected: + if (product == "content_shell") and (os == "mac"): TIMEOUT [Adobe-RGB-FF0000CC.png, Context display-p3, ImageData srgb, cropSource=false] expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/historical/popup-same-origin-unsafe-allow-outgoing-with-cross-origin.https.html.ini b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/historical/popup-same-origin-unsafe-allow-outgoing-with-cross-origin.https.html.ini new file mode 100644 index 0000000..da1992e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/historical/popup-same-origin-unsafe-allow-outgoing-with-cross-origin.https.html.ini
@@ -0,0 +1,3 @@ +[popup-same-origin-unsafe-allow-outgoing-with-cross-origin.https.html] + expected: + if product == "chrome": [ERROR, OK]
diff --git a/third_party/blink/web_tests/external/wpt/html/tools/update_html5lib_tests.py b/third_party/blink/web_tests/external/wpt/html/tools/update_html5lib_tests.py index f1a99416..7ad9bc6 100644 --- a/third_party/blink/web_tests/external/wpt/html/tools/update_html5lib_tests.py +++ b/third_party/blink/web_tests/external/wpt/html/tools/update_html5lib_tests.py
@@ -1,5 +1,3 @@ -from __future__ import print_function - import glob import hashlib import itertools
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/assumptions/tools/ahem-generate-table.py b/third_party/blink/web_tests/external/wpt/infrastructure/assumptions/tools/ahem-generate-table.py index 8790da02..314279f6 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/assumptions/tools/ahem-generate-table.py +++ b/third_party/blink/web_tests/external/wpt/infrastructure/assumptions/tools/ahem-generate-table.py
@@ -1,5 +1,3 @@ -from __future__ import print_function, unicode_literals - import itertools import unicodedata
diff --git a/third_party/blink/web_tests/external/wpt/longtask-timing/longtask-attributes.html.ini b/third_party/blink/web_tests/external/wpt/longtask-timing/longtask-attributes.html.ini new file mode 100644 index 0000000..8b52ce0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/longtask-timing/longtask-attributes.html.ini
@@ -0,0 +1,4 @@ +[longtask-attributes.html] + [Performance longtask entries are observable.] + expected: + if (product == "content_shell") and (os == "win") and (port == "win11"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/pending-beacon/pending_post_beacon-cors.tentative.https.window.js.ini b/third_party/blink/web_tests/external/wpt/pending-beacon/pending_post_beacon-cors.tentative.https.window.js.ini new file mode 100644 index 0000000..9aa002cc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pending-beacon/pending_post_beacon-cors.tentative.https.window.js.ini
@@ -0,0 +1,3 @@ +[pending_post_beacon-cors.tentative.https.window.html] + expected: + if (product == "content_shell") and (os == "mac"): TIMEOUT
diff --git a/third_party/blink/web_tests/external/wpt/png/cicp-chunk.html b/third_party/blink/web_tests/external/wpt/png/cicp-chunk.html index 4afc262..8add5d60 100644 --- a/third_party/blink/web_tests/external/wpt/png/cicp-chunk.html +++ b/third_party/blink/web_tests/external/wpt/png/cicp-chunk.html
@@ -36,5 +36,5 @@ assert_approx_equals(pixel[3], pixel_expected[3], epsilon); }, {colorSpace: "display-p3"}); }; -img.src = "./images/cicp.png"; +img.src = "support/cicp-display-p3.png"; </script>
diff --git a/third_party/blink/web_tests/external/wpt/images/cicp.png b/third_party/blink/web_tests/external/wpt/png/support/cicp-display-p3.png similarity index 100% rename from third_party/blink/web_tests/external/wpt/images/cicp.png rename to third_party/blink/web_tests/external/wpt/png/support/cicp-display-p3.png Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/images/trns.png b/third_party/blink/web_tests/external/wpt/png/support/trns-high-bits-set.png similarity index 100% rename from third_party/blink/web_tests/external/wpt/images/trns.png rename to third_party/blink/web_tests/external/wpt/png/support/trns-high-bits-set.png Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/png/trns-chunk.html b/third_party/blink/web_tests/external/wpt/png/trns-chunk.html index 652cda0..3a24753 100644 --- a/third_party/blink/web_tests/external/wpt/png/trns-chunk.html +++ b/third_party/blink/web_tests/external/wpt/png/trns-chunk.html
@@ -33,5 +33,5 @@ assert_approx_equals(pixel[3], pixel_expected[3], epsilon); }); }; -img.src = "../images/trns.png"; +img.src = "support/trns-high-bits-set.png"; </script>
diff --git a/third_party/blink/web_tests/external/wpt/requestidlecallback/deadline-max-rAF-dynamic.html.ini b/third_party/blink/web_tests/external/wpt/requestidlecallback/deadline-max-rAF-dynamic.html.ini new file mode 100644 index 0000000..ed0c58e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/requestidlecallback/deadline-max-rAF-dynamic.html.ini
@@ -0,0 +1,3 @@ +[deadline-max-rAF-dynamic.html] + expected: + if (product == "content_shell") and (os == "mac"): [TIMEOUT, OK]
diff --git a/third_party/blink/web_tests/external/wpt/scheduler/tentative/yield/yield-priority-idle-callbacks.html.ini b/third_party/blink/web_tests/external/wpt/scheduler/tentative/yield/yield-priority-idle-callbacks.html.ini new file mode 100644 index 0000000..946451e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scheduler/tentative/yield/yield-priority-idle-callbacks.html.ini
@@ -0,0 +1,4 @@ +[yield-priority-idle-callbacks.html] + expected: + if product == "chrome": OK + TIMEOUT
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-events.html b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-events.html index c559da1..cc28b82 100644 --- a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-events.html +++ b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-events.html
@@ -8,7 +8,7 @@ async function runStartEndTest(t, utterance) { const eventWatcher = new EventWatcher(t, utterance, ['start', 'end', 'error']); await test_driver.bless('speechSynthesis.speak', - () => speechSynthesis.speak(utterance)); + () => { speechSynthesis.speak(utterance) }); await eventWatcher.wait_for(['start', 'end']); } promise_test(async (t) => {
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-twice.html b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-twice.html index 3e0388b9..2f9a401 100644 --- a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-twice.html +++ b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-twice.html
@@ -11,6 +11,7 @@ test_driver.bless('speechSynthesis.speak', t.step_func(() => { // the utterance is short to make the test faster const utter = new SpeechSynthesisUtterance('1'); + utter.onerror = t.unreached_func('error event'); speechSynthesis.speak(utter); utter.onend = t.step_func(() => { speechSynthesis.speak(utter);
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-twice.html.ini b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-twice.html.ini index 510f995..dbd8c1d0 100644 --- a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-twice.html.ini +++ b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-twice.html.ini
@@ -1,4 +1,8 @@ [SpeechSynthesis-speak-twice.html] - expected: TIMEOUT + expected: + if product == "chrome": OK + TIMEOUT [Using the same SpeechSynthesisUtterance twice for speechSynthesis.speak()] - expected: TIMEOUT + expected: + if product == "chrome": FAIL + TIMEOUT
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-without-activation-fails.tentative.html b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-without-activation-fails.tentative.html index 1b86552..676fe05 100644 --- a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-without-activation-fails.tentative.html +++ b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-without-activation-fails.tentative.html
@@ -10,7 +10,7 @@ utter.onerror = t.step_func_done((e) => { assert_equals(e.error, "not-allowed"); }); - utter.onend = t.step_func_done(() => assert_unreached()); + utter.onend = t.unreached_func('end event'); speechSynthesis.speak(utter); }, 'speechSynthesis.speak requires user activation'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-properties.html b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-properties.html new file mode 100644 index 0000000..f6c8f5f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-properties.html
@@ -0,0 +1,25 @@ +<!doctype html> +<title>Properties of SpeechSynthesisEvent</title> +<link rel="help" href="https://wicg.github.io/speech-api/#utterance-events"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<body> +<script> +// Written for https://github.com/WICG/speech-api/issues/103 +promise_test(async (t) => { + const utterance = new SpeechSynthesisUtterance('test'); + const eventWatcher = new EventWatcher(t, utterance, ['start', 'end', 'error']); + await test_driver.bless('speechSynthesis.speak', + () => { speechSynthesis.speak(utterance) }); + const events = await eventWatcher.wait_for(['start', 'end'], { record: 'all' }); + assert_equals(events.length, 2, 'number of events'); + for (const event of events) { + assert_true(event instanceof SpeechSynthesisEvent, 'is SpeechSynthesisEvent'); + assert_false(event.bubbles, 'bubbles'); + assert_false(event.cancelable, 'cancelable'); + assert_equals(event.utterance, utterance, 'utterance'); + } +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-properties.html.ini b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-properties.html.ini new file mode 100644 index 0000000..60593d65 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesisEvent-properties.html.ini
@@ -0,0 +1,4 @@ +[SpeechSynthesisEvent-properties.html] + [Properties of SpeechSynthesisEvent] + expected: + if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-ABA.tentative.sub.https.window.js b/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-ABA.tentative.sub.https.window.js new file mode 100644 index 0000000..428053f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-ABA.tentative.sub.https.window.js
@@ -0,0 +1,9 @@ +// META: script=helpers.js +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +'use strict'; + +// Create a test with a nested iframe that is same-site to the top-level frame +// but has cross-site frame in between. +RunTestsInIFrame( + 'https://{{hosts[alt][]}}:{{ports[https][0]}}/storage-access-api/resources/requestStorageAccess-ABA-iframe.https.html');
diff --git a/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-cross-origin-iframe.sub.https.window.js b/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-cross-origin-iframe.sub.https.window.js deleted file mode 100644 index 9183832..0000000 --- a/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-cross-origin-iframe.sub.https.window.js +++ /dev/null
@@ -1,9 +0,0 @@ -// META: script=helpers.js -// META: script=/resources/testdriver.js -// META: script=/resources/testdriver-vendor.js -'use strict'; - -(async function() { - // Create a test with a single-child cross-origin iframe. - RunTestsInIFrame('https://{{domains[www]}}:{{ports[https][0]}}/storage-access-api/resources/requestStorageAccess-iframe.https.html?testCase=cross-origin-frame'); -})();
diff --git a/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-cross-origin-iframe.sub.https.window.js.ini b/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-cross-origin-iframe.sub.https.window.js.ini index 9338e27..ddc9604 100644 --- a/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-cross-origin-iframe.sub.https.window.js.ini +++ b/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-cross-origin-iframe.sub.https.window.js.ini
@@ -1,17 +1,9 @@ [requestStorageAccess-cross-origin-iframe.sub.https.window.html] [[cross-origin-frame\] document.requestStorageAccess() should be rejected with a NotAllowedError with denied permission] - expected: - if product == "chrome": PASS - FAIL - - [[cross-origin-frame\] document.requestStorageAccess() should be rejected with a NotAllowedError without permission grant] - expected: - if product == "chrome": PASS - FAIL - - [[cross-origin-frame\] document.requestStorageAccess() should be resolved when called properly with a user gesture, and should allow cookie access] expected: FAIL - [[cross-origin-frame\] document.requestStorageAccess() should be resolved with no user gesture when a permission grant exists, and should allow cookie access] - expected: - if product == "chrome": FAIL + [[cross-origin-frame\] document.requestStorageAccess() should be rejected with a NotAllowedError without permission grant] + expected: FAIL + + [[cross-origin-frame\] document.requestStorageAccess() should resolve in top-level frame or same-origin iframe, otherwise reject with a NotAllowedError with no user gesture.] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-nested-cross-origin-iframe.sub.https.window.js.ini b/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-nested-cross-origin-iframe.sub.https.window.js.ini index 2c7ca81..4b233c6 100644 --- a/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-nested-cross-origin-iframe.sub.https.window.js.ini +++ b/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-nested-cross-origin-iframe.sub.https.window.js.ini
@@ -1,17 +1,9 @@ [requestStorageAccess-nested-cross-origin-iframe.sub.https.window.html] [[nested-cross-origin-frame\] document.requestStorageAccess() should be rejected with a NotAllowedError with denied permission] - expected: - if product == "chrome": PASS - FAIL - - [[nested-cross-origin-frame\] document.requestStorageAccess() should be rejected with a NotAllowedError without permission grant] - expected: - if product == "chrome": PASS - FAIL - - [[nested-cross-origin-frame\] document.requestStorageAccess() should be resolved when called properly with a user gesture, and should allow cookie access] expected: FAIL - [[nested-cross-origin-frame\] document.requestStorageAccess() should be resolved with no user gesture when a permission grant exists, and should allow cookie access] - expected: - if product == "chrome": FAIL + [[nested-cross-origin-frame\] document.requestStorageAccess() should be rejected with a NotAllowedError without permission grant] + expected: FAIL + + [[nested-cross-origin-frame\] document.requestStorageAccess() should resolve in top-level frame or same-origin iframe, otherwise reject with a NotAllowedError with no user gesture.] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-same-origin-iframe.sub.https.window.js b/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-same-origin-iframe.sub.https.window.js deleted file mode 100644 index f406ea16..0000000 --- a/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-same-origin-iframe.sub.https.window.js +++ /dev/null
@@ -1,7 +0,0 @@ -// META: script=helpers.js -// META: script=/resources/testdriver.js -// META: script=/resources/testdriver-vendor.js -'use strict'; - -// Create a test with a single-child same-origin iframe. -RunTestsInIFrame('resources/requestStorageAccess-iframe.https.html?testCase=same-origin-frame');
diff --git a/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-same-site-iframe.sub.https.window.js b/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-same-site-iframe.sub.https.window.js new file mode 100644 index 0000000..f646444e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess-same-site-iframe.sub.https.window.js
@@ -0,0 +1,8 @@ +// META: script=helpers.js +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +'use strict'; + +// Create a test with a single-child cross-origin same-site iframe. +RunTestsInIFrame( + 'https://{{domains[www]}}:{{ports[https][0]}}/storage-access-api/resources/requestStorageAccess-iframe.https.html?testCase=same-site-frame');
diff --git a/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess.sub.https.window.js b/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess.sub.https.window.js index 6a9d5f4e..306bf46 100644 --- a/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess.sub.https.window.js +++ b/third_party/blink/web_tests/external/wpt/storage-access-api/requestStorageAccess.sub.https.window.js
@@ -29,15 +29,20 @@ { name: 'storage-access' }, 'prompt'); }); -promise_test(async t => { - if (topLevelDocument || testPrefix.includes('same-origin')) { - await document.requestStorageAccess() - .catch(t.unreached_func("document.requestStorageAccess() call should resolve in top-level frame or same-origin iframe.")); - } else { - return promise_rejects_dom(t, "NotAllowedError", document.requestStorageAccess(), - "document.requestStorageAccess() call without user gesture."); - } -}, "[" + testPrefix + "] document.requestStorageAccess() should resolve in top-level frame or same-origin iframe, otherwise reject with a NotAllowedError with no user gesture."); +promise_test( + async t => { + if (topLevelDocument || !testPrefix.includes('cross-site') || + testPrefix.includes('ABA')) { + await document.requestStorageAccess().catch(t.unreached_func( + 'document.requestStorageAccess() call should resolve in top-level frame or same-site iframe.')); + } else { + return promise_rejects_dom( + t, "NotAllowedError", document.requestStorageAccess(), + "document.requestStorageAccess() call without user gesture."); + } + }, + '[' + testPrefix + + '] document.requestStorageAccess() should resolve in top-level frame or same-site iframe, otherwise reject with a NotAllowedError with no user gesture.'); promise_test( async (t) => { @@ -60,7 +65,7 @@ '] document.requestStorageAccess() should be resolved with no user gesture when a permission grant exists, and ' + 'should allow cookie access'); -if (!topLevelDocument && !testPrefix.includes('same-origin')) { +if (testPrefix.includes('cross-site')) { promise_test( async t => { await RunCallbackWithGesture(() => {
diff --git a/third_party/blink/web_tests/external/wpt/storage-access-api/resources/requestStorageAccess-ABA-iframe.https.html b/third_party/blink/web_tests/external/wpt/storage-access-api/resources/requestStorageAccess-ABA-iframe.https.html new file mode 100644 index 0000000..7452ff8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/storage-access-api/resources/requestStorageAccess-ABA-iframe.https.html
@@ -0,0 +1,7 @@ +<!doctype html> +<meta charset=utf-8> + +<script src="/resources/testharness.js"></script> +<script src="/storage-access-api/helpers.js"></script> +<body> +<script src="/storage-access-api/resources/requestStorageAccess-ABA-iframe.sub.https.window.js"></script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/storage-access-api/resources/requestStorageAccess-ABA-iframe.sub.https.window.js b/third_party/blink/web_tests/external/wpt/storage-access-api/resources/requestStorageAccess-ABA-iframe.sub.https.window.js new file mode 100644 index 0000000..8bfef802 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/storage-access-api/resources/requestStorageAccess-ABA-iframe.sub.https.window.js
@@ -0,0 +1,12 @@ +// META: script=../helpers.js +'use strict'; + +// This expects to be run in an iframe that is cross-site to the top-level +// frame. +(async function() { + // Create a test with a single-child iframe that is same-site to the top-level + // frame but cross-site to the iframe that is being created here, for the + // purpose of testing requestStorageAccess in an A(B(A)) frame tree setting. + RunTestsInIFrame( + 'https://{{domains[www]}}:{{ports[https][0]}}/storage-access-api/resources/requestStorageAccess-iframe.https.html?testCase=ABA'); +})();
diff --git a/third_party/blink/web_tests/external/wpt/storage-access-api/storage-access-permission.sub.https.window.js.ini b/third_party/blink/web_tests/external/wpt/storage-access-api/storage-access-permission.sub.https.window.js.ini index a64a866..4813320 100644 --- a/third_party/blink/web_tests/external/wpt/storage-access-api/storage-access-permission.sub.https.window.js.ini +++ b/third_party/blink/web_tests/external/wpt/storage-access-api/storage-access-permission.sub.https.window.js.ini
@@ -11,3 +11,7 @@ [Permissions grants are observable across same-origin iframes] expected: if product == "chrome": TIMEOUT + + [Permissions grants are observable across same-site iframes] + expected: + if product == "chrome": NOTRUN
diff --git a/third_party/blink/web_tests/external/wpt/streams/piping/general.any.js b/third_party/blink/web_tests/external/wpt/streams/piping/general.any.js index bec3480..faeb8e3 100644 --- a/third_party/blink/web_tests/external/wpt/streams/piping/general.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/piping/general.any.js
@@ -209,3 +209,16 @@ return rs.pipeTo(ws, null); }, 'pipeTo() promise should resolve if null is passed'); + +promise_test(async t => { + /** @type {ReadableStreamDefaultController} */ + var con; + let synchronous = false; + new ReadableStream({ start(c) { con = c }}, { highWaterMark: 0 }).pipeTo( + new WritableStream({ write() { synchronous = true; } }) + ) + // wait until start algorithm finishes + await Promise.resolve(); + con.enqueue(); + assert_false(synchronous, 'write algorithm must not run synchronously'); +}, "enqueue() must not synchronously call write algorithm");
diff --git a/third_party/blink/web_tests/external/wpt/subresource-integrity/tools/generate_javascript.py b/third_party/blink/web_tests/external/wpt/subresource-integrity/tools/generate_javascript.py index 300e170..fed3e54 100644 --- a/third_party/blink/web_tests/external/wpt/subresource-integrity/tools/generate_javascript.py +++ b/third_party/blink/web_tests/external/wpt/subresource-integrity/tools/generate_javascript.py
@@ -1,5 +1,3 @@ -from __future__ import print_function - from os import path, listdir from hashlib import sha512, sha256, md5 from base64 import b64encode
diff --git a/third_party/blink/web_tests/external/wpt/subresource-integrity/tools/list_hashes.py b/third_party/blink/web_tests/external/wpt/subresource-integrity/tools/list_hashes.py index 5f189ce..52f46ff 100644 --- a/third_party/blink/web_tests/external/wpt/subresource-integrity/tools/list_hashes.py +++ b/third_party/blink/web_tests/external/wpt/subresource-integrity/tools/list_hashes.py
@@ -1,5 +1,3 @@ -from __future__ import print_function - from os import path, listdir from hashlib import sha512, sha384, sha256, md5 from base64 import b64encode
diff --git a/third_party/blink/web_tests/external/wpt/top-level-storage-access-api/tentative/requestStorageAccessFor.sub.https.window.js.ini b/third_party/blink/web_tests/external/wpt/top-level-storage-access-api/tentative/requestStorageAccessFor.sub.https.window.js.ini index 2dcb8bc..f0f925ab2 100644 --- a/third_party/blink/web_tests/external/wpt/top-level-storage-access-api/tentative/requestStorageAccessFor.sub.https.window.js.ini +++ b/third_party/blink/web_tests/external/wpt/top-level-storage-access-api/tentative/requestStorageAccessFor.sub.https.window.js.ini
@@ -5,6 +5,10 @@ expected: if product == "chrome": FAIL + [[same-origin-frame\] Existing top-level storage access permission should not allow cookie access for the cross-site subresource requests made in a non-top-level context.] + expected: + if product == "chrome": NOTRUN + [[same-origin-frame\] document.requestStorageAccessFor() should be rejected when called in an iframe] expected: if product == "chrome": NOTRUN
diff --git a/third_party/blink/web_tests/external/wpt/trust-tokens/trust-token-parameter-validation-xhr.tentative.https.html b/third_party/blink/web_tests/external/wpt/trust-tokens/trust-token-parameter-validation-xhr.tentative.https.html index 56ac7f0e..73af463 100644 --- a/third_party/blink/web_tests/external/wpt/trust-tokens/trust-token-parameter-validation-xhr.tentative.https.html +++ b/third_party/blink/web_tests/external/wpt/trust-tokens/trust-token-parameter-validation-xhr.tentative.https.html
@@ -1,6 +1,6 @@ <!DOCTYPE html> <meta charset="utf-8"> -<title>JavaScript: the Trust Token API XHR interface correctly validates its parameters</title> +<title>JavaScript: the Private Token API XHR interface correctly validates its parameters</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script> @@ -9,101 +9,117 @@ test(() => { assert_throws_dom("InvalidStateError", () => { let request = new XMLHttpRequest(); - request.setTrustToken({ - type: 'token-request' + request.setPrivateToken({ + type: 'private-state-token', + version: 1, + operation: 'token-request' }); }); - }, 'Setting XHR Trust Tokens parameters requires that the XHR request be open.'); + }, 'Setting XHR Private Token parameters requires that the XHR request be open.'); test(() => { assert_throws_dom("InvalidStateError", () => { let request = new XMLHttpRequest(); - request.open('GET', 'https://trusttoken.example'); + request.open('GET', 'https://privatetoken.example'); request.send(); - request.setTrustToken({ - type: 'token-request' + request.setPrivateToken({ + type: 'private-state-token', + version: 1, + operation: 'token-request' }); }); - }, 'Setting XHR Trust Tokens parameters requires that the XHR request not have been sent.'); + }, 'Setting XHR Private Token parameters requires that the XHR request not have been sent.'); test(() => { assert_throws_js(TypeError, () => { let request = new XMLHttpRequest(); - request.open('GET', 'https://trusttoken.example'); - request.setTrustToken({}); + request.open('GET', 'https://privatetoken.example'); + request.setPrivateToken({}); }); - }, 'Trust Tokens operations require present `type` values.'); + }, 'Private Token operations require present `type` values.'); test(() => { assert_throws_js(TypeError, () => { let request = new XMLHttpRequest(); - request.open('GET', 'https://trusttoken.example'); - request.setTrustToken({ + request.open('GET', 'https://privatetoken.example'); + request.setPrivateToken({ type: "invalid" }); }); - }, 'Trust Tokens operations require valid `type` values.'); + }, 'Private Token operations require valid `type` values.'); test(() => { assert_throws_js(TypeError, () => { let request = new XMLHttpRequest(); - request.open('GET', 'https://trusttoken.example'); - request.setTrustToken({ - type: "token-request", + request.open('GET', 'https://privatetoken.example'); + request.setPrivateToken({ + type: "private-state-token", + version: 1, + operation: "token-request", refreshPolicy: "not a member of the refreshPolicy enum", }); }); - }, 'Trust Tokens operations require valid `refreshPolicy:` values, if provided.'); + }, 'Private Token operations require valid `refreshPolicy:` values, if provided.'); test(() => { assert_throws_js(TypeError, () => { let request = new XMLHttpRequest(); - request.open('GET', 'https://trusttoken.example'); - request.setTrustToken({ - type: "send-redemption-record", + request.open('GET', 'https://privatetoken.example'); + request.setPrivateToken({ + type: "private-state-token", + version: 1, + operation: "send-redemption-record", issuers: [] }); }); - }, 'Trust Tokens signing operations require at least one issuer URL.'); + }, 'Private Token signing operations require at least one issuer URL.'); test(() => { assert_throws_js(TypeError, () => { let request = new XMLHttpRequest(); - request.open('GET', 'https://trusttoken.example'); - request.setTrustToken({ - type: "send-redemption-record", + request.open('GET', 'https://privatetoken.example'); + request.setPrivateToken({ + type: "private-state-token", + version: 1, + operation: "send-redemption-record", issuers: [3] }); }); - }, 'Trust Tokens operations require string issuer URLs, if provided.'); + }, 'Private Token operations require string issuer URLs, if provided.'); test(() => { assert_throws_js(TypeError, () => { let request = new XMLHttpRequest(); - request.open('GET', 'https://trusttoken.example'); - request.setTrustToken({ - type: "send-redemption-record", + request.open('GET', 'https://privatetoken.example'); + request.setPrivateToken({ + type: "private-state-token", + version: 1, + operation: "send-redemption-record", issuers: ["not a valid URL"] }); }); - }, 'Trust Tokens operations require valid issuer URLs, if provided.'); + }, 'Private Token operations require valid issuer URLs, if provided.'); test(() => { assert_throws_js(TypeError, () => { let request = new XMLHttpRequest(); - request.open('GET', 'https://trusttoken.example'); - request.setTrustToken({ - type: "send-redemption-record", + request.open('GET', 'https://privatetoken.example'); + request.setPrivateToken({ + type: "private-state-token", + version: 1, + operation: "send-redemption-record", issuers: ["http://not-secure.com"] }); }); - }, 'Trust Tokens operations require secure issuer URLs, if provided.'); + }, 'Private Token operations require secure issuer URLs, if provided.'); test(() => { let request = new XMLHttpRequest(); - request.open('GET', 'https://trusttoken.example'); - request.setTrustToken({ - type: "send-redemption-record", + request.open('GET', 'https://privatetoken.example'); + request.setPrivateToken({ + type: "private-state-token", + version: 1, + operation: "send-redemption-record", issuers: ["http://localhost"] }); }, 'Since localhost URLs are potentially trustworthy, setting an issuer to localhost should succeed.');
diff --git a/third_party/blink/web_tests/external/wpt/trust-tokens/trust-token-parameter-validation.tentative.https.html b/third_party/blink/web_tests/external/wpt/trust-tokens/trust-token-parameter-validation.tentative.https.html index 5f01e552..e2ab079 100644 --- a/third_party/blink/web_tests/external/wpt/trust-tokens/trust-token-parameter-validation.tentative.https.html +++ b/third_party/blink/web_tests/external/wpt/trust-tokens/trust-token-parameter-validation.tentative.https.html
@@ -1,6 +1,6 @@ <!DOCTYPE html> <meta charset="utf-8"> -<title>JavaScript: the Trust Token API Fetch method correctly validates its parameters</title> +<title>JavaScript: the Private Token API Fetch method correctly validates its parameters</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script> @@ -9,80 +9,92 @@ test(() => { assert_throws_js(TypeError, () => { new Request('https://example.com', { - trustToken: {} + privateToken: {} }); }); - }, 'Trust Tokens fetches require present `type` values.'); + }, 'Private Token fetches require present `type` values.'); test(() => { assert_throws_js(TypeError, () => { new Request('https://example.com', { - trustToken: { + privateToken: { type: "invalid" } }); }); - }, 'Trust Tokens fetches require valid `type` values.'); + }, 'Private Token fetches require valid `type` values.'); test(() => { assert_throws_js(TypeError, () => { new Request('https://example.com', { - trustToken: { - type: "token-request", + privateToken: { + type: "private-state-token", + version: 1, + operation: "token-request", refreshPolicy: "not a member of the refreshPolicy enum", } }); }); - }, 'Trust Tokens fetches require valid `refreshPolicy:` values, if provided.'); + }, 'Private Token fetches require valid `refreshPolicy:` values, if provided.'); test(() => { assert_throws_js(TypeError, () => { new Request('https://example.com', { - trustToken: { - type: "send-redemption-record", + privateToken: { + type: "private-state-token", + version: 1, + operation: "send-redemption-record", issuers: [] } }); }); - }, 'Trust Tokens signing operations require at least one issuer URL'); + }, 'Private Token signing operations require at least one issuer URL'); test(() => { assert_throws_js(TypeError, () => { new Request('https://example.com', { - trustToken: { - type: "send-redemption-record", + privateToken: { + type: "private-state-token", + version: 1, + operation: "send-redemption-record", issuers: [3] } }); }); - }, 'Trust Tokens signing operations require string issuer URLs, if provided.'); + }, 'Private Token signing operations require string issuer URLs, if provided.'); test(() => { assert_throws_js(TypeError, () => { new Request('https://example.com', { - trustToken: { - type: "send-redemption-record", + privateToken: { + type: "private-state-token", + version: 1, + operation: "send-redemption-record", issuers: ["not a valid URL"] } }); }); - }, 'Trust Tokens signing operations require valid issuer URLs, if provided.'); + }, 'Private Token signing operations require valid issuer URLs, if provided.'); test(() => { assert_throws_js(TypeError, () => { new Request('https://example.com', { - trustToken: { - type: "send-redemption-record", + privateToken: { + type: "private-state-token", + version: 1, + operation: "send-redemption-record", issuers: ["http://not-secure.com"] } }); }); - }, 'Trust Tokens fetches require secure issuer URLs, if provided.'); + }, 'Private Token fetches require secure issuer URLs, if provided.'); test(() => { new Request('https://example.com', { - trustToken: { - type: "send-redemption-record", + privateToken: { + type: "private-state-token", + version: 1, + operation: "send-redemption-record", issuers: ["http://localhost"] } });
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures.py index 7fff07b..d0a0869 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures.py
@@ -2,8 +2,8 @@ import json import os -import asyncio import pytest +import pytest_asyncio import webdriver from urllib.parse import urlunsplit @@ -14,14 +14,13 @@ from tests.support.http_request import HTTPRequest +SCRIPT_TIMEOUT = 1 +PAGE_LOAD_TIMEOUT = 3 +IMPLICIT_WAIT_TIMEOUT = 0 + # The webdriver session can outlive a pytest session _current_session = None -# The event loop needs to outlive the webdriver session -_event_loop = None - -_custom_session = False - def pytest_configure(config): # register the capabilities marker @@ -53,16 +52,6 @@ metafunc.parametrize("capabilities", marker.args, ids=None) -@pytest.fixture(scope="session") -def event_loop(): - """Change event_loop fixture to global.""" - global _event_loop - - if _event_loop is None: - _event_loop = asyncio.get_event_loop_policy().new_event_loop() - return _event_loop - - @pytest.fixture def http(configuration): return HTTPRequest(configuration["host"], configuration["port"]) @@ -75,6 +64,7 @@ host - WebDriver server host. port - WebDriver server port. capabilites - Capabilites passed when creating the WebDriver session + timeout_multiplier - Multiplier for timeout values webdriver - Dict with keys `binary`: path to webdriver binary, and `args`: Additional command line arguments passed to the webdriver binary. This doesn't include all the required arguments e.g. the @@ -117,7 +107,7 @@ _current_session = None -@pytest.fixture(scope="function") +@pytest_asyncio.fixture(scope="function") async def session(capabilities, configuration): """Create and start a session for a test that does not itself test session creation. @@ -149,12 +139,18 @@ _current_session.window.size = defaults.WINDOW_SIZE _current_session.window.position = defaults.WINDOW_POSITION + # Set default timeouts + multiplier = configuration["timeout_multiplier"] + _current_session.timeouts.implicit = IMPLICIT_WAIT_TIMEOUT * multiplier + _current_session.timeouts.page_load = PAGE_LOAD_TIMEOUT * multiplier + _current_session.timeouts.script = SCRIPT_TIMEOUT * multiplier + yield _current_session cleanup_session(_current_session) -@pytest.fixture(scope="function") +@pytest_asyncio.fixture(scope="function") async def bidi_session(capabilities, configuration): """Create and start a bidi session. @@ -250,14 +246,14 @@ return iframe - @pytest.fixture def get_test_page(iframe, inline): def get_test_page( as_frame=False, frame_doc=None, shadow_doc=None, - nested_shadow_dom=False + nested_shadow_dom=False, + shadow_root_mode="open" ): if frame_doc is None: frame_doc = """<div id="in-frame"><input type="checkbox"/></div>""" @@ -272,7 +268,7 @@ class extends HTMLElement {{ constructor() {{ super(); - this.attachShadow({{mode: "open"}}).innerHTML = ` + this.attachShadow({{mode: "{shadow_root_mode}"}}).innerHTML = ` {shadow_doc} `; }} @@ -320,7 +316,11 @@ class extends HTMLElement {{ constructor() {{ super(); - this.attachShadow({{mode: "open"}}).innerHTML = `{shadow_doc}`; + const shadowRoot = this.attachShadow({{mode: "{shadow_root_mode}"}}); + shadowRoot.innerHTML = `{shadow_doc}`; + + // Save shadow root on window to access it in case of `closed` mode. + window._shadowRoot = shadowRoot; }} }} ); @@ -336,6 +336,53 @@ @pytest.fixture +def test_origin(url): + return url("") + + +@pytest.fixture +def test_alt_origin(url): + return url("", domain="alt") + + +@pytest.fixture +def test_page(inline): + return inline("<div>foo</div>") + + +@pytest.fixture +def test_page2(inline): + return inline("<div>bar</div>") + + +@pytest.fixture +def test_page_cross_origin(inline): + return inline("<div>bar</div>", domain="alt") + + +@pytest.fixture +def test_page_multiple_frames(inline, test_page, test_page2): + return inline( + f"<iframe src='{test_page}'></iframe><iframe src='{test_page2}'></iframe>" + ) + + +@pytest.fixture +def test_page_nested_frames(inline, test_page_same_origin_frame): + return inline(f"<iframe src='{test_page_same_origin_frame}'></iframe>") + + +@pytest.fixture +def test_page_cross_origin_frame(inline, test_page_cross_origin): + return inline(f"<iframe src='{test_page_cross_origin}'></iframe>") + + +@pytest.fixture +def test_page_same_origin_frame(inline, test_page): + return inline(f"<iframe src='{test_page}'></iframe>") + + +@pytest.fixture def test_page_with_pdf_js(inline): """Prepare an url to load a PDF document in the browser using pdf.js""" def test_page_with_pdf_js(encoded_pdf_data): @@ -362,7 +409,7 @@ return test_page_with_pdf_js -@pytest.fixture +@pytest_asyncio.fixture async def top_context(bidi_session): contexts = await bidi_session.browsing_context.get_tree() return contexts[0]
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures_bidi.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures_bidi.py index 627bbfb5..2c8f5a0 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures_bidi.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures_bidi.py
@@ -5,7 +5,7 @@ from typing import Any, Mapping import pytest -import webdriver +import pytest_asyncio from webdriver.bidi.error import ( InvalidArgumentException, NoSuchFrameException, @@ -14,7 +14,7 @@ from webdriver.bidi.modules.script import ContextTarget -@pytest.fixture +@pytest_asyncio.fixture async def add_preload_script(bidi_session): preload_scripts_ids = [] @@ -37,7 +37,7 @@ pass -@pytest.fixture +@pytest_asyncio.fixture async def subscribe_events(bidi_session): subscriptions = []; async def subscribe_events(events, contexts = None): @@ -55,7 +55,7 @@ pass -@pytest.fixture +@pytest_asyncio.fixture async def new_tab(bidi_session): """Open and focus a new tab to run the test in a foreground tab.""" new_tab = await bidi_session.browsing_context.create(type_hint='tab')
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/helpers.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/helpers.py index e79a314..b0c065d 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/helpers.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/helpers.py
@@ -1,5 +1,3 @@ -from __future__ import print_function - import collections import math import sys
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/http_handlers/cached.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/http_handlers/cached.py new file mode 100644 index 0000000..a43410f8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/http_handlers/cached.py
@@ -0,0 +1,14 @@ +def main(request, response): + """Simple handler that returns a response with Cache-Control max-age=3600. + """ + + status = int(request.GET.get(b"status", None)) + # For redirects, a "location" get parameter can indicate the redirected url + if status == 301 and b"location" in request.GET: + response.headers.set(b"Location", request.GET.first(b"location")) + + response.status = status + response.headers.set(b"Content-Type", "text/plain") + response.headers.set(b"Expires", "Thu, 01 Dec 2100 20:00:00 GMT") + response.headers.set(b"Cache-Control", "max-age=3600") + return "Cached HTTP Response"
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/http_handlers/must-revalidate.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/http_handlers/must-revalidate.py new file mode 100644 index 0000000..94f5a79 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/http_handlers/must-revalidate.py
@@ -0,0 +1,17 @@ +def main(request, response): + """Simple handler that returns a response with Cache-Control max-age=0 and + must-revalidate. + The request can include a return-304 header to trigger the handler to return + a 304 instead of a 200. + """ + response.headers.set(b"Content-Type", "text/plain") + + if b"true" == request.headers.get(b"return-304", None): + # instruct the browser that the response was not modified and the cache + # can be used. + response.status = 304 + return "" + else: + response.headers.set(b"Cache-Control", b"max-age=0, must-revalidate") + response.status = 200 + return "must-revalidate HTTP Response"
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpTransceiver-headerExtensionControl.html.ini b/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpTransceiver-headerExtensionControl.html.ini index 9b46e02..0b2d13f 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpTransceiver-headerExtensionControl.html.ini +++ b/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpTransceiver-headerExtensionControl.html.ini
@@ -1,5 +1,3 @@ [RTCRtpTransceiver-headerExtensionControl.html] - [setHeaderExtensionsToNegotiate throws NotSupported on encountering unknown URI] - expected: - if (product == "content_shell") and (os == "linux") and (flag_specific == "highdpi"): PASS - FAIL + [the set of negotiated extensions is the set of unstopped extensions] + expected: FAIL
diff --git a/third_party/blink/web_tests/virtual/fledge/external/wpt/fledge/tentative/no-winner.https.sub.window-expected.txt b/third_party/blink/web_tests/virtual/fledge/external/wpt/fledge/tentative/no-winner.https.sub.window-expected.txt index 9729c5a7..dee82964 100644 --- a/third_party/blink/web_tests/virtual/fledge/external/wpt/fledge/tentative/no-winner.https.sub.window-expected.txt +++ b/third_party/blink/web_tests/virtual/fledge/external/wpt/fledge/tentative/no-winner.https.sub.window-expected.txt
@@ -1,4 +1,5 @@ This is a testharness.js-based test. +PASS Bidding logic script: error=close-connection PASS Bidding logic script: error=http-error PASS Bidding logic script: error=no-content-type PASS Bidding logic script: error=wrong-content-type @@ -18,6 +19,7 @@ PASS Bidding logic script: generateBid=return {render: interestGroup.ads[0].renderUrl}; PASS Bidding logic script: generateBid=return {bid:0, render: interestGroup.ads[0].renderUrl}; PASS Bidding logic script: generateBid=return {bid:-1, render: interestGroup.ads[0].renderUrl}; +PASS Decision logic script: error=close-connection PASS Decision logic script: error=http-error PASS Decision logic script: error=no-content-type PASS Decision logic script: error=wrong-content-type
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/can-load-api.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/can-load-api.https.html.ini index 085e075..27b4eb4 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/can-load-api.https.html.ini +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/can-load-api.https.html.ini
@@ -13,10 +13,14 @@ expected: NOTRUN [canLoadOpaqueURL returns false inside an default fenced frame] - expected: NOTRUN + expected: + if product == "chrome": TIMEOUT + NOTRUN [canLoadOpaqueURL returns true for all 3 fenced-frame-src allowed values] expected: NOTRUN [canLoadOpaqueURL returns true inside an opaque-ads fenced frame] - expected: TIMEOUT + expected: + if product == "chrome": FAIL + TIMEOUT
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/config-installation-triggers-navigation-of-navigated-fenced-frame.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/config-installation-triggers-navigation-of-navigated-fenced-frame.https.html.ini index c92c9eab..bc20678 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/config-installation-triggers-navigation-of-navigated-fenced-frame.https.html.ini +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/config-installation-triggers-navigation-of-navigated-fenced-frame.https.html.ini
@@ -1,3 +1,4 @@ [config-installation-triggers-navigation-of-navigated-fenced-frame.https.html] + expected: TIMEOUT [Installing an inner config to a fenced frame that has navigated triggers] - expected: FAIL + expected: TIMEOUT
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/config-with-empty-url-installation-unloads-navigated-fenced-frame.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/config-with-empty-url-installation-unloads-navigated-fenced-frame.https.html.ini index d36ba4d4..238abaf 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/config-with-empty-url-installation-unloads-navigated-fenced-frame.https.html.ini +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/config-with-empty-url-installation-unloads-navigated-fenced-frame.https.html.ini
@@ -1,3 +1,4 @@ [config-with-empty-url-installation-unloads-navigated-fenced-frame.https.html] + expected: TIMEOUT [Installing a config with empty url to a navigated fenced unloads ] - expected: FAIL + expected: TIMEOUT
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-allow-all.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-allow-all.https.html.ini index 26eaf13..081dc89 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-allow-all.https.html.ini +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-allow-all.https.html.ini
@@ -1,7 +1,6 @@ [default-enabled-features-allow-all.https.html] - expected: TIMEOUT [Cross-origin fenced frame loads when feature policies are *] - expected: NOTRUN + expected: FAIL [Same-origin fenced frame loads when feature policies are *] - expected: TIMEOUT + expected: FAIL
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-allow-none.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-allow-none.https.html.ini new file mode 100644 index 0000000..048a754a --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-allow-none.https.html.ini
@@ -0,0 +1,6 @@ +[default-enabled-features-allow-none.https.html] + [Cross-origin fenced frame does not load when feature policies are none] + expected: FAIL + + [Same-origin fenced frame does not load when feature policies are none] + expected: FAIL
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-allow-self.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-allow-self.https.html.ini index 1983317..83398434 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-allow-self.https.html.ini +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-allow-self.https.html.ini
@@ -1,13 +1,12 @@ [default-enabled-features-allow-self.https.html] - expected: TIMEOUT [A fenced frame redirected to a page that does not allow feature policies does not navigate] - expected: NOTRUN + expected: FAIL [Cross-origin fenced frame does not load when feature policies are self] - expected: NOTRUN + expected: FAIL [Fenced frames default feature policies are set to allow *] - expected: NOTRUN + expected: FAIL [Same-origin fenced frame loads when feature policies are self] - expected: TIMEOUT + expected: FAIL
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribute-allow.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribute-allow.https.html.ini index 53de219a..14cb6c3 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribute-allow.https.html.ini +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribute-allow.https.html.ini
@@ -1,10 +1,16 @@ [default-enabled-features-attribute-allow.https.html] expected: TIMEOUT [Cross-origin fenced frame with allow attribute enabling required features] - expected: NOTRUN + expected: + if product == "chrome": FAIL + NOTRUN [Delivered policies can further restrict permissions of a fenced frame] - expected: NOTRUN + expected: + if product == "chrome": TIMEOUT + NOTRUN [Same-origin fenced frame with allow attribute enabling required features] - expected: TIMEOUT + expected: + if product == "chrome": FAIL + TIMEOUT
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribute-change.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribute-change.https.html.ini index 5a8ea47a..72feb9f 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribute-change.https.html.ini +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribute-change.https.html.ini
@@ -1,7 +1,6 @@ [default-enabled-features-attribute-change.https.html] - expected: TIMEOUT [Changing the allow attribute is a no-op for frame-initiated navigations] - expected: NOTRUN + expected: FAIL [Changing the allow attribute is a no-op for the current navigation] - expected: TIMEOUT + expected: FAIL
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribute-disallow.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribute-disallow.https.html.ini new file mode 100644 index 0000000..edf9d6d --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribute-disallow.https.html.ini
@@ -0,0 +1,6 @@ +[default-enabled-features-attribute-disallow.https.html] + [Cross-origin fenced frame with allow attribute disabling required feature] + expected: FAIL + + [Same-origin fenced frame with allow attribute disabling required feature] + expected: FAIL
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribution-disabled.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribution-disabled.https.html.ini new file mode 100644 index 0000000..31e286e --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-attribution-disabled.https.html.ini
@@ -0,0 +1,6 @@ +[default-enabled-features-attribution-disabled.https.html] + [Cross-origin fenced frame with allow attribute enabling required feature but page disabling feature.] + expected: FAIL + + [Same-origin fenced frame with allow attribute enabling required feature but page disabling feature.] + expected: FAIL
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-unset.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-unset.https.html.ini index 2986965..221cd47 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-unset.https.html.ini +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/default-enabled-features-unset.https.html.ini
@@ -1,7 +1,6 @@ [default-enabled-features-unset.https.html] - expected: TIMEOUT [Cross-origin fenced frame loads when feature policies are unset] - expected: NOTRUN + expected: FAIL [Same-origin fenced frame loads when feature policies are unset] - expected: TIMEOUT + expected: FAIL
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/set-automatic-beacon.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/set-automatic-beacon.https.html.ini index b6cd0b9..5b4f7a1 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/set-automatic-beacon.https.html.ini +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/set-automatic-beacon.https.html.ini
@@ -1,10 +1,9 @@ [set-automatic-beacon.https.html] - expected: TIMEOUT [setReportEventDataForAutomaticBeacons fails for invalid destination] - expected: NOTRUN + expected: FAIL [setReportEventDataForAutomaticBeacons fails over the size limit] - expected: NOTRUN + expected: FAIL [setReportEventDataForAutomaticBeacons works at the size limit] - expected: TIMEOUT + expected: FAIL
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/unfenced-top.https.html.ini b/third_party/blink/web_tests/wpt_internal/fenced_frame/unfenced-top.https.html.ini index 373821b..5a743c43 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/unfenced-top.https.html.ini +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/unfenced-top.https.html.ini
@@ -1,25 +1,45 @@ [unfenced-top.https.html] expected: TIMEOUT [_unfencedTop :blob URL failure] - expected: NOTRUN + expected: + if product == "chrome": FAIL + NOTRUN [_unfencedTop :javascript URL failure] - expected: NOTRUN + expected: + if product == "chrome": FAIL + NOTRUN [_unfencedTop fragment navigation] - expected: NOTRUN + expected: + if product == "chrome": FAIL + NOTRUN [_unfencedTop in default fenced frame] - expected: NOTRUN + expected: + if product == "chrome": TIMEOUT + NOTRUN + + [_unfencedTop in opaque-ads -> default fenced frame] + expected: + if product == "chrome": NOTRUN [_unfencedTop opaque-ads nested iframe success case] - expected: NOTRUN + expected: + if product == "chrome": FAIL + NOTRUN [_unfencedTop opaque-ads non-refresh success case] - expected: TIMEOUT + expected: + if product == "chrome": FAIL + TIMEOUT [_unfencedTop opaque-ads refresh success case] - expected: NOTRUN + expected: + if product == "chrome": FAIL + NOTRUN [_unfencedTop outside a fenced frame] - expected: NOTRUN + expected: + if product == "chrome": PASS + NOTRUN
diff --git a/third_party/breakpad/BUILD.gn b/third_party/breakpad/BUILD.gn index 40bc4a09..d7ab10b 100644 --- a/third_party/breakpad/BUILD.gn +++ b/third_party/breakpad/BUILD.gn
@@ -983,6 +983,8 @@ "breakpad/src/client/ios/handler/ios_exception_minidump_generator.mm", "breakpad/src/client/mac/crash_generation/ConfigFile.h", "breakpad/src/client/mac/crash_generation/ConfigFile.mm", + "breakpad/src/common/mac/arch_utilities.cc", + "breakpad/src/common/mac/arch_utilities.h", "breakpad/src/client/mac/handler/breakpad_nlist_64.cc", "breakpad/src/client/mac/handler/breakpad_nlist_64.h", "breakpad/src/client/mac/handler/dynamic_images.cc",
diff --git a/tools/android/avd/proto/generic_android32_foldable.textpb b/tools/android/avd/proto/generic_android32_foldable.textpb index ecf12a1..6c796cb0 100644 --- a/tools/android/avd/proto/generic_android32_foldable.textpb +++ b/tools/android/avd/proto/generic_android32_foldable.textpb
@@ -6,20 +6,20 @@ emulator_package { package_name: "chromium/third_party/android_sdk/public/emulator" - version: "0EgkhrUNQp2T1opBdG5kmtrz6b-fKKwfeivwy73nGicC" # 31.3.10 + version: "vr0Vf27dh76-6sz87fx6tF-3br8crNIgxByTaYayuX4C" # 32.1.12 dest_path: "generic_android32_foldable" } system_image_package { package_name: "chromium/third_party/android_sdk/public/system-images/android-32/google_apis/x86_64" - version: "KjjO5uts0yb_xXLds-ChSenU5VebO2OkXkSdt5eBuYAC" # r3, S2B2.211203.006 + version: "WhbaU7Z2Is60EoZ3jB-5QHnlFy-mXeUekoUgrLa_BqcC" # r5, SE1B.220616.004 dest_path: "generic_android32_foldable" } system_image_name: "system-images;android-32;google_apis;x86_64" avd_package { package_name: "chromium/third_party/android_sdk/public/avds/android-32/google_apis/x86_64" - version: "m2cKpiBfbWwenESoCjZwFuryEQ6ivPb16Z4ZTg-EWcQC" + version: "Xw-9YOMCifPCpA-GtAK2PCxPs9BWsTmAkyBZny8DaooC" dest_path: "generic_android32_foldable" } avd_name: "android_32_foldable_google_apis_x86_64"
diff --git a/tools/android/avd/proto/generic_android33.textpb b/tools/android/avd/proto/generic_android33.textpb index d87de2da..7d735a1 100644 --- a/tools/android/avd/proto/generic_android33.textpb +++ b/tools/android/avd/proto/generic_android33.textpb
@@ -6,20 +6,20 @@ emulator_package { package_name: "chromium/third_party/android_sdk/public/emulator" - version: "ZjmabmwvcQ8kZtLsnx6rj40RlCglPwP-PDPEb5fWrEAC" # 31.3.14 + version: "vr0Vf27dh76-6sz87fx6tF-3br8crNIgxByTaYayuX4C" # 32.1.12 dest_path: "generic_android33" } system_image_package { package_name: "chromium/third_party/android_sdk/public/system-images/android-33/google_apis/x86_64" - version: "8KxiJ6WNnLxlTmM-HntbcSidjUl31gWt6lnAbngsfx0C" # r8, TE1A.220922.012 + version: "1TealwPsZ5QUC9ZhKI9-nbMjZ1cFouZQ-CzOv0varQcC" # r9, TE1A.220922.021 dest_path: "generic_android33" } system_image_name: "system-images;android-33;google_apis;x86_64" avd_package { package_name: "chromium/third_party/android_sdk/public/avds/android-33/google_apis/x86_64" - version: "BZfE-H-QdGvbcX3PhfnI98VgeCzr6wUxBU2mlJOAFCkC" + version: "ArHSre6lDRPRC_WDP8x-NbgbAHM_ig0uTg54ireSpJoC" dest_path: "generic_android33" } avd_name: "android_33_google_apis_x86_64"
diff --git a/tools/android/avd/proto/generic_playstore_android33.textpb b/tools/android/avd/proto/generic_playstore_android33.textpb index 2836f96..9e4d40417 100644 --- a/tools/android/avd/proto/generic_playstore_android33.textpb +++ b/tools/android/avd/proto/generic_playstore_android33.textpb
@@ -6,20 +6,20 @@ emulator_package { package_name: "chromium/third_party/android_sdk/public/emulator" - version: "9lGp8nTUCRRWGMnI_96HcKfzjnxEJKUcfvfwmA3wXNkC" # 31.2.10 + version: "vr0Vf27dh76-6sz87fx6tF-3br8crNIgxByTaYayuX4C" # 32.1.12 dest_path: "generic_playstore_android33" } system_image_package { package_name: "chromium/third_party/android_sdk/public/system-images/android-33/google_apis_playstore/x86_64" - version: "ndvYifhxEbUfsJ0FagczmGFFLE0Lp9ZxBif9P8seZS8C" # beta 3 + version: "zNsYsNmjunAoNpRur3d0lbIaUAbnPHy4xqojAFG5gHMC" # r7, TE1A.220922.010 dest_path: "generic_playstore_android33" } system_image_name: "system-images;android-33;google_apis_playstore;x86_64" avd_package { package_name: "chromium/third_party/android_sdk/public/avds/android-33/google_apis_playstore/x86_64" - version: "DXAJN39V-2S5Q3-Aq0klEo8A1L4SA9wxYah1BR7NacgC" # created in bb_id 8803446658592087201 + version: "WCt8yn3D9-RDU0mAYNIJvSA-G26X8Or1fBlKuAsTPDoC" dest_path: "generic_playstore_android33" } avd_name: "android_33_google_apis_playstore_x86_64"
diff --git a/tools/clang/scripts/upload_revision.py b/tools/clang/scripts/upload_revision.py index 696c3c4..8fb6a94a 100755 --- a/tools/clang/scripts/upload_revision.py +++ b/tools/clang/scripts/upload_revision.py
@@ -195,10 +195,9 @@ def PatchRustStage0(): - verify_stage0 = subprocess.run( - [BUILD_RUST_PY_PATH, '--verify-stage0-hash', '--skip-checkout'], - capture_output=True, - text=True) + verify_stage0 = subprocess.run([BUILD_RUST_PY_PATH, '--verify-stage0-hash'], + capture_output=True, + text=True) if verify_stage0.returncode == 0: return
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 85fb90b..d87ff26e 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -19574,6 +19574,7 @@ </action> <action name="MobileMenuIncognitoSearch"> + <obsolete>Deprecated as of 3/2023</obsolete> <owner>gambard@chromium.org</owner> <description> The user tapped the "Incognito Search" button in the mobile menu @@ -19582,6 +19583,7 @@ </action> <action name="MobileMenuLensCopiedImage"> + <obsolete>Deprecated as of 3/2023</obsolete> <owner>hujasonx@google.com</owner> <owner>schechter@google.com</owner> <description>User pressed 'Lens Copied Image' in the app menu.</description> @@ -19639,6 +19641,7 @@ </action> <action name="MobileMenuPasteAndGo"> + <obsolete>Deprecated as of 3/2023</obsolete> <owner>gambard@chromium.org</owner> <description>User pressed 'Paste and Go' in the app menu.</description> </action> @@ -19710,11 +19713,13 @@ </action> <action name="MobileMenuScanQRCode"> + <obsolete>Deprecated as of 3/2023</obsolete> <owner>gambard@chromium.org</owner> <description>User pressed 'Scan QR Code' in the app menu.</description> </action> <action name="MobileMenuSearch"> + <obsolete>Deprecated as of 3/2023</obsolete> <owner>gambard@chromium.org</owner> <description> The user tapped the "New Search" button in the mobile menu @@ -19723,6 +19728,7 @@ </action> <action name="MobileMenuSearchCopiedImage"> + <obsolete>Deprecated as of 3/2023</obsolete> <owner>rkgibson@google.com</owner> <description>User pressed 'Search Copied Image' in the app menu.</description> </action> @@ -19800,6 +19806,7 @@ </action> <action name="MobileMenuVoiceSearch"> + <obsolete>Deprecated as of 3/2023</obsolete> <owner>gambard@chromium.org</owner> <description>User pressed 'Voice Search' in the app menu.</description> </action> @@ -20368,6 +20375,7 @@ </action> <action name="MobilePopupMenuSwipeToSelect"> + <obsolete>Deprecated as of 3/2023</obsolete> <owner>gambard@chromium.org</owner> <description> The user selected an option in the Popup Menu without lifting the finger @@ -21823,6 +21831,7 @@ </action> <action name="MobileToolbarShowNewTabMenu"> + <obsolete>Deprecated as of 3/2023</obsolete> <owner>gambard@chromium.org</owner> <description> The user long-pressed on the NewTab button in the toolbar @@ -21843,6 +21852,7 @@ </action> <action name="MobileToolbarShowTabGridMenu"> + <obsolete>Deprecated as of 3/2023</obsolete> <owner>gambard@chromium.org</owner> <description> User long pressed the Tab Grid button to display the menu associated with @@ -21851,6 +21861,7 @@ </action> <action name="MobileToolbarShowTabHistoryMenu"> + <obsolete>Deprecated as of 3/2023</obsolete> <owner>gambard@chromium.org</owner> <description> User long pressed the toolbar navigation buttons to display the tab history
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 240ecff..b081b2c5 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -37313,6 +37313,7 @@ <int value="0" label="Other Not Supervised"/> <int value="1" label="Policy Enabled Supervision"/> <int value="2" label="User Enabled Supervision"/> + <int value="3" label="Mixed Profile"/> </enum> <enum name="FamilyLinkUserParentAccessWidgetError"> @@ -42595,6 +42596,9 @@ <int value="4519" label="V8StorageBucketManager_Delete_Method"/> <int value="4520" label="NavigatorUAData_GetHighEntropyValues"/> <int value="4521" label="SchedulerYield"/> + <int value="4522" label="HtmlClipboardApiUnsanitizedRead"/> + <int value="4523" label="HtmlClipboardApiUnsanitizedWrite"/> + <int value="4524" label="AsyncClipboardAPIUnsanitizedRead"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -100950,6 +100954,8 @@ <int value="23" label="Media notification seek backward button."/> <int value="24" label="Price drop notification visit site button."/> <int value="25" label="Price drop notification turn off alert button."/> + <int value="28" label="WebApk install notification 'Back to site' button."/> + <int value="29" label="WebApk install notification retry button."/> </enum> <enum name="SystemNotificationType"> @@ -102013,6 +102019,10 @@ label="Not shown: tried to display the sheet, but failed due to unknown reason"/> <int value="7" label="Not shown: incomplete form"/> + <int value="8" label="Not shown: unknown form"/> + <int value="9" label="Not shown: unknown field"/> + <int value="10" label="Not shown: unsupported field type"/> + <int value="11" label="Not shown: Fast Checkout was shown"/> </enum> <enum name="TouchToFill.Outcome">
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index d3da869..f8f7bae 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -438,6 +438,18 @@ </summary> </histogram> +<histogram name="Ash.BrowserDataBackMigrator.ElapsedTimeBetweenDataMigrations" + units="ms" expires_after="2023-12-01"> + <owner>janagrill@google.com</owner> + <owner>artyomchen@google.com</owner> + <summary> + The time elapsed from the completion of a successful forward migration to + the start of a backward migration, with a maximum of 24 days. Recorded every + time backward migration is started, if forward migration was performed prior + to it. + </summary> +</histogram> + <histogram name="Ash.BrowserDataBackMigrator.ElapsedTimeDeleteAshItems" units="ms" expires_after="2023-12-01"> <owner>janagrill@google.com</owner> @@ -948,6 +960,16 @@ </summary> </histogram> +<histogram name="Ash.Calendar.EventsDisplayedToUser" enum="Boolean" + expires_after="2024-03-23"> + <owner>samcackett@google.com</owner> + <owner>cros-status-area-eng@google.com</owner> + <summary> + Recorded whenever a user sees any calendar event in the CalendarView. + Recorded once per lifetime of the calendar view. + </summary> +</histogram> + <histogram name="Ash.Calendar.FetchEvents.FetchDuration" units="ms" expires_after="2023-09-18"> <owner>rtinkoff@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml index 60df99e..058aa08f 100644 --- a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml +++ b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
@@ -187,6 +187,7 @@ enum="CustomTabsConnection" expires_after="2023-07-16"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> + <owner>cct-team@google.com</owner> <summary> Android: Recorded whenever user closes the custom tab by hitting the close button or back to return to the caller app. Keeps track of the connection @@ -197,9 +198,10 @@ </histogram> <histogram name="CustomTabs.ConnectionStatusOnReturn.NonGSA" - enum="CustomTabsConnection" expires_after="M114"> + enum="CustomTabsConnection" expires_after="2023-07-16"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> + <owner>cct-team@google.com</owner> <summary> Android: Recorded whenever user closes the custom tab by hitting the close button or back to return to the caller app. Keeps track of the connection
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml index 7e67422..63dca2e 100644 --- a/tools/metrics/histograms/metadata/media/histograms.xml +++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -2960,7 +2960,7 @@ </histogram> <histogram name="Media.GlobalMediaControls.MediaCastMode.{Action}" - enum="GlobalMediaControlsCastMode" expires_after="2023-05-01"> + enum="GlobalMediaControlsCastMode" expires_after="2023-09-20"> <owner>muyaoxu@google.com</owner> <owner>openscreen-eng@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index bcd7505..5cc35e4 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -5426,6 +5426,26 @@ </summary> </histogram> +<histogram name="Eche.NetworkCheck.FailureReason" enum="ConnectionFailReason" + expires_after="2023-08-20"> + <owner>jonmann@google.com</owner> + <owner>nayebi@google.com</owner> + <summary> + Failure reason emitted by EcheSignaler on background connect attempt + failures. + </summary> +</histogram> + +<histogram name="Eche.NetworkCheck.Result" enum="BooleanSuccess" + expires_after="2023-08-27"> + <owner>jonmann@google.com</owner> + <owner>nayebi@google.com</owner> + <summary> + Emitted on success or failure of a background network connection attempt. + Triggered when Phone Hub first connects, and on each bubble opened event. + </summary> +</histogram> + <histogram name="Eche.NotificationClicked" enum="EcheNotificationInteraction" expires_after="2023-04-16"> <obsolete> @@ -5485,6 +5505,33 @@ </summary> </histogram> +<histogram + name="Eche.StreamEvent.FromNotification.PreviousNetworkCheckFailed.ConnectionFail" + enum="ConnectionFailReason" expires_after="2023-09-20"> + <owner>pushi@google.com</owner> + <owner>jonmann@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Events logged the root cause of Eche connection failure. when triggered from + notificaiton and failed in last network connection check. Records when + signaling timeout on EcheSignaler or the tablet mode check on EcheTray + Separate from normal Eche.StreamEvent.ConnectionFail. + </summary> +</histogram> + +<histogram + name="Eche.StreamEvent.FromNotification.PreviousNetworkCheckFailed.Result" + enum="StreamState" expires_after="2023-09-20"> + <owner>pushi@google.com</owner> + <owner>jonmann@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the success rate of app streaming when triggered from notificaiton + and failed in last network connection check. Separate from normal + Eche.StreamEvent histogram. + </summary> +</histogram> + <histogram name="Eche.UniqueAppsStreamed.PerDay" units="count" expires_after="2023-08-08"> <owner>crisrael@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/permissions/histograms.xml b/tools/metrics/histograms/metadata/permissions/histograms.xml index b4a575a..219a2e3 100644 --- a/tools/metrics/histograms/metadata/permissions/histograms.xml +++ b/tools/metrics/histograms/metadata/permissions/histograms.xml
@@ -430,25 +430,28 @@ </histogram> <histogram name="Permissions.DSE.AutoPermissionRevertTransition" - enum="AutoDSEPermissionRevertTransition" expires_after="2023-03-19"> + enum="AutoDSEPermissionRevertTransition" expires_after="2024-03-01"> <owner>andypaicu@chromium.org</owner> <owner>src/components/permissions/PERMISSIONS_OWNERS</owner> <summary> Recorded when the Default Search Engine automatic permission grant is reverted. It tracks the transition that the settings for the DSE origin takes when this happens. Suffixed by `PermissionTypes` to provide - information per permission type. + information per permission type. Only recorded for Android as that is the + only platform where the DSE permissions were enabled. </summary> </histogram> <histogram name="Permissions.DSE.EffectiveSetting" enum="ContentSetting" - expires_after="2023-03-19"> + expires_after="2024-03-01"> <owner>andypaicu@chromium.org</owner> <owner>src/components/permissions/PERMISSIONS_OWNERS</owner> <summary> Recorded at initialization and when the Default Search Engine origin is changed. Tracks the setting for the Default Search Engine origin. Suffixed - by `PermissionTypes` to provide information per permission type. + by `PermissionTypes` to provide information per permission type. Only + recorded for Android as that is the only platform where the DSE permissions + were enabled. </summary> </histogram>
diff --git a/tools/perf/cross_device_test_config.py b/tools/perf/cross_device_test_config.py index ae83f0e9..3c08cc3 100644 --- a/tools/perf/cross_device_test_config.py +++ b/tools/perf/cross_device_test_config.py
@@ -95,6 +95,9 @@ 'speedometer2': { 'Speedometer2': 20, }, + 'speedometer2-minormc': { + 'Speedometer2': 20, + }, }, 'win-10_laptop_low_end-perf': { 'jetstream2': { @@ -142,6 +145,9 @@ 'speedometer2': { 'Speedometer2': 20, }, + 'speedometer2-minormc': { + 'Speedometer2': 20, + }, }, 'mac-m1_mini_2020-perf-pgo': { 'jetstream2': {
diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java index 0233dcc..5ac061e 100644 --- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java +++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java
@@ -12,6 +12,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.database.Cursor; import android.net.Uri; import android.os.Build; @@ -32,6 +33,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.FileUtils; import org.chromium.base.Log; +import org.chromium.base.PackageManagerUtils; import org.chromium.base.StrictModeContext; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; @@ -1323,20 +1325,28 @@ "Android.MediaPickerShown", value, SHOWING_ENUM_COUNT); } + private static String resolvePackageNameFromIntent(Intent intent) { + String packageName = ""; + ResolveInfo resolveInfo = PackageManagerUtils.resolveActivity(intent, 0); + if (resolveInfo != null && resolveInfo.activityInfo != null + && resolveInfo.activityInfo.applicationInfo != null + && resolveInfo.activityInfo.applicationInfo.packageName != null) { + packageName = resolveInfo.activityInfo.applicationInfo.packageName; + } + return packageName; + } + private static boolean showPhotoPicker(WindowAndroid windowAndroid, WindowAndroid.IntentCallback intentCallback, PhotoPickerListener listener, boolean allowMultiple, List<String> mimeTypes) { if (preferAndroidMediaPickerViaGetContent()) { - logMediaPickerShown(SHOWING_ANDROID_PICKER_INDIRECT); return showAndroidMediaPickerIndirect( windowAndroid, intentCallback, allowMultiple, mimeTypes); } else if (preferAndroidMediaPickerViaPickImage() || preferAndroidMediaPickerViaPickImagePlus()) { - logMediaPickerShown(SHOWING_ANDROID_PICKER_DIRECT); return showAndroidMediaPickerDirect( windowAndroid, intentCallback, allowMultiple, mimeTypes); } else { - logMediaPickerShown(SHOWING_CHROME_PICKER); return showChromeMediaPicker(windowAndroid, listener, allowMultiple, mimeTypes); } } @@ -1377,6 +1387,7 @@ return false; } + logMediaPickerShown(SHOWING_ANDROID_PICKER_DIRECT); return true; } @@ -1394,11 +1405,21 @@ intent.setType("*/*"); intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes.toArray(new String[0])); + // When relying on the indirect way of launching the Android Media Picker, we want to be + // sure that the Android Media Picker is the one handling the request and not something + // random. + String packageNameForGetContent = resolvePackageNameFromIntent(intent); + if (!"com.google.android.providers.media.module".equals(packageNameForGetContent)) { + return showAndroidMediaPickerDirect( + windowAndroid, intentCallback, allowMultiple, mimeTypes); + } + if (!windowAndroid.showIntent( intent, intentCallback, /* errorId= */ R.string.opening_android_media_picker)) { return false; } + logMediaPickerShown(SHOWING_ANDROID_PICKER_INDIRECT); return true; } @@ -1408,6 +1429,7 @@ assert sPhotoPicker == null; sPhotoPicker = sPhotoPickerDelegate.showPhotoPicker( windowAndroid, listener, allowMultiple, mimeTypes); + logMediaPickerShown(SHOWING_CHROME_PICKER); return true; }
diff --git a/ui/file_manager/BUILD.gn b/ui/file_manager/BUILD.gn index 2b152a5..ad2004a 100644 --- a/ui/file_manager/BUILD.gn +++ b/ui/file_manager/BUILD.gn
@@ -141,6 +141,7 @@ deps = [ "//ash/webui/common/resources:build_ts", "//third_party/material_web_components:library", + "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", ]
diff --git a/ui/views/badge_painter.cc b/ui/views/badge_painter.cc index 4322124..5284e79 100644 --- a/ui/views/badge_painter.cc +++ b/ui/views/badge_painter.cc
@@ -23,23 +23,6 @@ namespace { -// Returns the appropriate font to use for the badge based on the font -// currently being used to render the title of the menu item. -gfx::FontList DeriveBadgeFont(const gfx::FontList& primary_font) { - if (features::IsChromeRefresh2023()) { - return views::style::GetFont(views::style::CONTEXT_BADGE, - views::style::STYLE_SECONDARY); - } - - // Preferred font is slightly smaller and slightly more bold than the title - // font. The size change is required to make it look correct in the badge; we - // add a small degree of bold to prevent color smearing/blurring due to font - // smoothing. This ensures readability on all platforms and in both light and - // dark modes. - return primary_font.Derive(BadgePainter::kBadgeFontSizeAdjustment, - gfx::Font::NORMAL, gfx::Font::Weight::MEDIUM); -} - // Returns the highlight rect for the badge given the font and text rect // for the badge text. gfx::Rect GetBadgeRectOutsetAroundText(const gfx::FontList& badge_font, @@ -59,7 +42,7 @@ int text_top_y, const std::u16string& text, const gfx::FontList& primary_font) { - gfx::FontList badge_font = DeriveBadgeFont(primary_font); + gfx::FontList badge_font = GetBadgeFont(primary_font); // Calculate bounding box for badge text. unmirrored_badge_left_x += kBadgeInternalPadding; @@ -91,9 +74,24 @@ // static gfx::Size BadgePainter::GetBadgeSize(const std::u16string& text, const gfx::FontList& primary_font) { - gfx::FontList badge_font = DeriveBadgeFont(primary_font); + gfx::FontList badge_font = GetBadgeFont(primary_font); const gfx::Size text_size = gfx::GetStringSize(text, badge_font); return GetBadgeRectOutsetAroundText(badge_font, gfx::Rect(text_size)).size(); } +gfx::FontList BadgePainter::GetBadgeFont(const gfx::FontList& context_font) { + if (features::IsChromeRefresh2023()) { + return views::style::GetFont(views::style::CONTEXT_BADGE, + views::style::STYLE_SECONDARY); + } + + // Preferred font is slightly smaller and slightly more bold than the title + // font. The size change is required to make it look correct in the badge; we + // add a small degree of bold to prevent color smearing/blurring due to font + // smoothing. This ensures readability on all platforms and in both light and + // dark modes. + return context_font.Derive(BadgePainter::kBadgeFontSizeAdjustment, + gfx::Font::NORMAL, gfx::Font::Weight::MEDIUM); +} + } // namespace views
diff --git a/ui/views/badge_painter.h b/ui/views/badge_painter.h index 6f8bff58..e807b33 100644 --- a/ui/views/badge_painter.h +++ b/ui/views/badge_painter.h
@@ -47,6 +47,10 @@ static gfx::Size GetBadgeSize(const std::u16string& text, const gfx::FontList& primary_font); + // Returns the appropriate font to use for the badge based on the font + // currently being used to render the surrounding text. + static gfx::FontList GetBadgeFont(const gfx::FontList& context_font); + // Layout Constants // // Note that there are a few differences between Views and Mac constants here @@ -63,9 +67,6 @@ // Highlight padding around text. static constexpr int kBadgeInternalPadding = 4; static constexpr int kBadgeInternalPaddingTopMac = 1; - - // The baseline offset of the badge image to the menu text baseline. - static constexpr int kBadgeBaselineOffsetMac = -4; }; } // namespace views
diff --git a/ui/views/cocoa/immersive_mode_controller_unittest.mm b/ui/views/cocoa/immersive_mode_controller_unittest.mm index a61947a1..d028047 100644 --- a/ui/views/cocoa/immersive_mode_controller_unittest.mm +++ b/ui/views/cocoa/immersive_mode_controller_unittest.mm
@@ -365,7 +365,18 @@ &view_will_appear_ran)); immersive_mode_controller->Enable(); EXPECT_TRUE(view_will_appear_ran); + + // TODO(https://crbug.com/1426944): Enable() does not add the controller. It + // will be added / removed from the view controller tree during + // UpdateToolbarVisibility(). Remove this comment and update the test once the + // bug has been resolved. + EXPECT_EQ(browser().titlebarAccessoryViewControllers.count, 2u); + immersive_mode_controller->UpdateToolbarVisibility( + mojom::ToolbarVisibilityStyle::kAlways); EXPECT_EQ(browser().titlebarAccessoryViewControllers.count, 3u); + immersive_mode_controller->UpdateToolbarVisibility( + mojom::ToolbarVisibilityStyle::kNone); + EXPECT_EQ(browser().titlebarAccessoryViewControllers.count, 2u); } // Test ImmersiveModeTabbedController construction and destruction.
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index c63eeec3..c46a94f 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -2196,9 +2196,11 @@ params.do_capture = do_capture; params.native_view_for_gestures = native_view_for_gestures_; params.owned_window_anchor = anchor; - if (item->GetParentMenuItem()) { - params.context = state_.item->GetWidget(); + params.context = item->GetWidget(); + // (crbug.com/1414232) The item to be open is a submenu. Make sure + // params.context is set. + DCHECK(params.context); params.menu_type = ui::MenuType::kChildMenu; } else if (state_.context_menu) { if (!menu_stack_.empty()) { @@ -2900,6 +2902,10 @@ MenuItemView* item = pending_state_.item; if (!item->HasSubmenu() || !item->GetEnabled()) return; + + // Show the sub-menu. + SetSelection(item, SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); + MenuItemView* to_select = nullptr; if (!item->GetSubmenu()->GetMenuItems().empty()) to_select = FindInitialSelectableMenuItem(item, INCREMENT_SELECTION_DOWN); @@ -2909,10 +2915,7 @@ if (item->type_ == MenuItemView::Type::kActionableSubMenu) item->SetSelectionOfActionableSubmenu(true); SetSelection(to_select, SELECTION_UPDATE_IMMEDIATELY); - return; } - // No menu items, just show the sub-menu. - SetSelection(item, SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); } void MenuController::CloseSubmenu() {
diff --git a/ui/views/controls/menu/menu_controller_cocoa_delegate_impl.mm b/ui/views/controls/menu/menu_controller_cocoa_delegate_impl.mm index 50b9c675..2f69fea 100644 --- a/ui/views/controls/menu/menu_controller_cocoa_delegate_impl.mm +++ b/ui/views/controls/menu/menu_controller_cocoa_delegate_impl.mm
@@ -18,6 +18,7 @@ #include "ui/gfx/platform_font_mac.h" #include "ui/strings/grit/ui_strings.h" #include "ui/views/badge_painter.h" +#include "ui/views/controls/menu/menu_config.h" #include "ui/views/layout/layout_provider.h" namespace { @@ -36,10 +37,9 @@ // badge; we add a small degree of bold to prevent color smearing/blurring // due to font smoothing. This ensures readability on all platforms and in // both light and dark modes. - gfx::Font badge_font = gfx::Font( - new gfx::PlatformFontMac(gfx::PlatformFontMac::SystemFontType::kMenu)); - badge_font = badge_font.Derive(views::BadgePainter::kBadgeFontSizeAdjustment, - gfx::Font::NORMAL, gfx::Font::Weight::MEDIUM); + gfx::Font badge_font = + views::BadgePainter::GetBadgeFont(views::MenuConfig::instance().font_list) + .GetPrimaryFont(); DCHECK(color_provider); NSColor* badge_text_color = skia::SkColorToSRGBNSColor( @@ -161,7 +161,9 @@ } - (NSPoint)cellBaselineOffset { - return NSMakePoint(0, views::BadgePainter::kBadgeBaselineOffsetMac); + // The baseline offset of the badge image to the menu text baseline. + const int kBadgeBaselineOffset = features::IsChromeRefresh2023() ? -2 : -4; + return NSMakePoint(0, kBadgeBaselineOffset); } - (NSSize)cellSize {
diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc index 6f33144..4a7c3d0 100644 --- a/ui/views/controls/menu/menu_controller_unittest.cc +++ b/ui/views/controls/menu/menu_controller_unittest.cc
@@ -3351,6 +3351,26 @@ } #endif +TEST_F(MenuControllerTest, SubmenuOpenByKey) { + // Create a submenu. + MenuItemView* const child_menu = menu_item()->GetSubmenu()->GetMenuItemAt(0); + SubmenuView* sub_menu = child_menu->CreateSubmenu(); + child_menu->AppendMenuItem(5, u"Five"); + child_menu->AppendMenuItem(6, u"Six"); + + // Open the menu and select the menu item that has a submenu. + OpenMenu(menu_item()); + SetPendingStateItem(child_menu); + SetState(child_menu); + EXPECT_EQ(1, pending_state_item()->GetCommand()); + EXPECT_EQ(nullptr, sub_menu->host()); + + // Dispatch a key to open the submenu. + DispatchKey(ui::VKEY_RIGHT); + EXPECT_EQ(5, pending_state_item()->GetCommand()); + EXPECT_NE(nullptr, sub_menu->host()); +} + class ExecuteCommandWithoutClosingMenuTest : public MenuControllerTest { public: void SetUp() override {
diff --git a/ui/views/view.cc b/ui/views/view.cc index 38101ba..3108f05 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc
@@ -1980,8 +1980,11 @@ ax::mojom::IntAttribute::kNameFrom))); } -void View::SetAccessibleName(const std::u16string& name, +void View::SetAccessibleName(std::u16string name, ax::mojom::NameFrom name_from) { + // Allow subclasses to adjust the name. + AdjustAccessibleName(name, name_from); + // Ensure we have a current `name_from` value. For instance, the name might // still be an empty string, but a view is now indicating that this is by // design by setting `NameFrom::kAttributeExplicitlyEmpty`.
diff --git a/ui/views/view.h b/ui/views/view.h index 2053b66..d43db49 100644 --- a/ui/views/view.h +++ b/ui/views/view.h
@@ -1476,8 +1476,7 @@ // on a view which may or may not have a name depending on circumstances. Also // please seek review from accessibility OWNERs when removing the name, // especially for views which are focusable or otherwise interactive. - void SetAccessibleName(const std::u16string& name, - ax::mojom::NameFrom name_from); + void SetAccessibleName(std::u16string name, ax::mojom::NameFrom name_from); // Sets the accessible name of this view to that of `naming_view`. Often // `naming_view` is a `views::Label`, but any view with an accessible name @@ -1603,6 +1602,13 @@ // Called when the accessible name of the View changed. virtual void OnAccessibleNameChanged(const std::u16string& new_name) {} + // Called by `SetAccessibleName` to allow subclasses to adjust the new name. + // Potential use cases include setting the accessible name to the tooltip + // text when the new name is empty and prepending/appending additional text + // to the new name. + virtual void AdjustAccessibleName(std::u16string& new_name, + ax::mojom::NameFrom& name_from) {} + // Size and disposition ------------------------------------------------------ // Calculates the natural size for the View, to be taken into consideration @@ -2397,7 +2403,7 @@ VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleName, const std::u16string&) VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleName, View*) VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleName, - const std::u16string&, + std::u16string, ax::mojom::NameFrom) VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleDescription, const std::u16string&) VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleDescription, View*)
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc index 5153899c..62520a0e 100644 --- a/ui/views/view_unittest.cc +++ b/ui/views/view_unittest.cc
@@ -299,7 +299,32 @@ } ~A11yTestView() override = default; + + // Overridden from views::View: + void AdjustAccessibleName(std::u16string& new_name, + ax::mojom::NameFrom& name_from) override { + if (name_prefix_.has_value()) { + new_name.insert(0, name_prefix_.value()); + } + + if (name_from_.has_value()) { + name_from = name_from_.value(); + } + } + + void SetAccessibleNamePrefix(absl::optional<std::u16string> name_prefix) { + name_prefix_ = std::move(name_prefix); + } + + void SetAccessibleNameFrom(absl::optional<ax::mojom::NameFrom> name_from) { + name_from_ = std::move(name_from); + } + + private: + absl::optional<std::u16string> name_prefix_; + absl::optional<ax::mojom::NameFrom> name_from_; }; + //////////////////////////////////////////////////////////////////////////////// // Metadata //////////////////////////////////////////////////////////////////////////////// @@ -547,6 +572,26 @@ EXPECT_EQ(v.last_a11y_event_, ax::mojom::Event::kTextChanged); } +TEST_F(ViewTest, AdjustAccessibleNameStringWithRoleAlreadySet) { + A11yTestView v(ax::mojom::Role::kButton); + v.SetAccessibleNamePrefix(u"Prefix: "); + + ui::AXNodeData data; + v.GetAccessibleNodeData(&data); + EXPECT_EQ(v.GetAccessibleName(), u""); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), u""); + + v.last_a11y_event_ = ax::mojom::Event::kNone; + data = ui::AXNodeData(); + + v.SetAccessibleName(u"Name"); + v.GetAccessibleNodeData(&data); + EXPECT_EQ(v.GetAccessibleName(), u"Prefix: Name"); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + u"Prefix: Name"); + EXPECT_EQ(v.last_a11y_event_, ax::mojom::Event::kTextChanged); +} + TEST_F(ViewTest, SetAccessibleNameToLabelWithRoleAlreadySet) { TestView label; label.SetAccessibleName(u"Label's Name"); @@ -580,6 +625,62 @@ EXPECT_EQ(v.last_a11y_event_, ax::mojom::Event::kTextChanged); } +TEST_F(ViewTest, AdjustAccessibleNameFrom) { + A11yTestView v(ax::mojom::Role::kTextField); + v.SetAccessibleNameFrom(ax::mojom::NameFrom::kPlaceholder); + + ui::AXNodeData data = ui::AXNodeData(); + v.GetAccessibleNodeData(&data); + EXPECT_EQ(v.GetAccessibleName(), u""); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), u""); + + v.last_a11y_event_ = ax::mojom::Event::kNone; + data = ui::AXNodeData(); + + v.SetAccessibleName(u"Name"); + v.GetAccessibleNodeData(&data); + EXPECT_EQ(v.GetAccessibleName(), u"Name"); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + u"Name"); + EXPECT_EQ(static_cast<ax::mojom::NameFrom>( + data.GetIntAttribute(ax::mojom::IntAttribute::kNameFrom)), + ax::mojom::NameFrom::kPlaceholder); + EXPECT_EQ(v.last_a11y_event_, ax::mojom::Event::kTextChanged); +} + +TEST_F(ViewTest, AdjustAccessibleNameFromLabelWithRoleAlreadySet) { + TestView label; + label.SetAccessibleName(u"Label's Name"); + + A11yTestView v(ax::mojom::Role::kButton); + v.SetAccessibleNamePrefix(u"Prefix: "); + + ui::AXNodeData data = ui::AXNodeData(); + v.GetAccessibleNodeData(&data); + EXPECT_EQ(v.GetAccessibleName(), u""); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), u""); + EXPECT_EQ(static_cast<ax::mojom::NameFrom>( + data.GetIntAttribute(ax::mojom::IntAttribute::kNameFrom)), + ax::mojom::NameFrom::kNone); + EXPECT_FALSE( + data.HasIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds)); + + v.last_a11y_event_ = ax::mojom::Event::kNone; + data = ui::AXNodeData(); + + v.SetAccessibleName(&label); + v.GetAccessibleNodeData(&data); + EXPECT_EQ(v.GetAccessibleName(), u"Prefix: Label's Name"); + EXPECT_TRUE( + data.HasIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds)); + EXPECT_EQ(static_cast<ax::mojom::NameFrom>( + data.GetIntAttribute(ax::mojom::IntAttribute::kNameFrom)), + ax::mojom::NameFrom::kRelatedElement); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + u"Prefix: Label's Name"); + EXPECT_EQ(v.last_a11y_event_, ax::mojom::Event::kTextChanged); +} + TEST_F(ViewTest, SetAccessibleNameExplicitlyEmpty) { TestView v; ui::AXNodeData data = ui::AXNodeData();
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn index 5341322..eea0223d 100644 --- a/ui/webui/resources/cr_elements/BUILD.gn +++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -114,6 +114,9 @@ ts_out_dir = "$root_gen_dir/ui/webui/resources/tsc/cr_elements" ts_composite = true ts_deps = [ "../js:build_ts" ] + if (include_polymer) { + ts_deps += [ "//third_party/polymer/v3_0:library" ] + } ts_definitions = [ "//tools/typescript/definitions/pending.d.ts", "//tools/typescript/definitions/settings_private.d.ts",