diff --git a/AUTHORS b/AUTHORS index e963dae..d4f4090d 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -892,6 +892,7 @@ Swati Jaiswal <swa.jaiswal@samsung.com> Sylvain Zimmer <sylvinus@gmail.com> Sylvestre Ledru <sylvestre.ledru@gmail.com> +Synthia Islam <synthia.is@samsung.com> Szabolcs David <davidsz@inf.u-szeged.hu> Szymon Piechowicz <szymonpiechowicz@o2.pl> Taeheon Kim <skyrabbits1@gmail.com>
diff --git a/DEPS b/DEPS index 76dd9e4b1..37c93de 100644 --- a/DEPS +++ b/DEPS
@@ -145,11 +145,11 @@ # 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': '105c9d507045dc700d0e2f25854e9f86913069ba', + 'skia_revision': '4da34bf74723a55b0549f6fae960748a7685e64e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'e78b7c050e0ba8f74bdab2579bba2ab535ef7c04', + 'v8_revision': '11c60ffe95375a400b5465b615f1157901dc197a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -157,11 +157,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': '70cded6ac635c4bc0250f1b3166572043bc4eb73', + 'angle_revision': '2613cdba80a3aca0f131b55af3c41cc62a43a31c', # 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': 'e671a6937e36f80caf46d4490134cd45535a649d', + 'swiftshader_revision': 'fa0175c0988dd542f008257232207a8b87ad6c63', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -208,7 +208,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': '7c54fa2d4559d5e06af253a2fae4a6cea18d0a51', + 'catapult_revision': 'e73fe02a406e7951c59fe328f63b29fb885d5d6d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -264,7 +264,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. - 'spv_tools_revision': '9559cdbdf011c487f67f89e2d694bd4a18d5c1e0', + 'spv_tools_revision': 'ac3d131054ac17d42e388d7e0e321c2c13bc2f13', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -284,7 +284,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. - 'quiche_revision': '753002daef6045500f08066b132da7fd71ab4ca9', + 'quiche_revision': '7deaf37e9442e433e4d90d11c940f59cdbb184cc', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -1207,7 +1207,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'ae9673f68e841dba8f7c2a027264dbfc68ed3454', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '968d1d819bc0146de28db8de796c98bf9d2a621f', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1416,7 +1416,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b24e912d9bae913bf476a6143d8d53d528f2ab8b', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@42f9ab2813ad4a1515bbf7ec22c4dca3f678b61b', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_feature_list.cc b/android_webview/browser/aw_feature_list.cc index 50acf01..d5001eec 100644 --- a/android_webview/browser/aw_feature_list.cc +++ b/android_webview/browser/aw_feature_list.cc
@@ -24,7 +24,6 @@ // in other locations in the code base (e.g. content/, components/, etc). const base::Feature* kFeaturesExposedToJava[] = { &features::kWebViewConnectionlessSafeBrowsing, - &features::kWebViewPageStartedOnCommit, }; const base::Feature* FindFeatureExposedToJava(const std::string& feature_name) { @@ -52,11 +51,6 @@ const base::Feature kWebViewConnectionlessSafeBrowsing{ "WebViewConnectionlessSafeBrowsing", base::FEATURE_DISABLED_BY_DEFAULT}; -// Kill switch for feature to call onPageFinished for browser-initiated -// navigations when the navigation commits. -const base::Feature kWebViewPageStartedOnCommit{ - "WebViewPageStartedOnCommit", base::FEATURE_ENABLED_BY_DEFAULT}; - // Enable raster in wide color gamut for apps that use webview in a wide color // gamut activity. const base::Feature kWebViewWideColorGamutSupport{
diff --git a/android_webview/browser/aw_feature_list.h b/android_webview/browser/aw_feature_list.h index f98fc23..5768d5033 100644 --- a/android_webview/browser/aw_feature_list.h +++ b/android_webview/browser/aw_feature_list.h
@@ -16,7 +16,6 @@ // Alphabetical: extern const base::Feature kWebViewBrotliSupport; extern const base::Feature kWebViewConnectionlessSafeBrowsing; -extern const base::Feature kWebViewPageStartedOnCommit; extern const base::Feature kWebViewWideColorGamutSupport; } // namespace features
diff --git a/android_webview/java/src/org/chromium/android_webview/AwFeatureList.java b/android_webview/java/src/org/chromium/android_webview/AwFeatureList.java index 829c7a8..bf9eb01b2 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwFeatureList.java +++ b/android_webview/java/src/org/chromium/android_webview/AwFeatureList.java
@@ -25,7 +25,6 @@ private static Boolean sPageStartedOnCommitForBrowserNavigations; private static boolean computePageStartedOnCommitForBrowserNavigations() { - if (!nativeIsEnabled(WEBVIEW_PAGE_STARTED_ON_COMMIT)) return false; if (GMS_PACKAGE.equals(ContextUtils.getApplicationContext().getPackageName())) { try { PackageInfo gmsPackage = @@ -66,7 +65,6 @@ // Alphabetical: public static final String WEBVIEW_CONNECTIONLESS_SAFE_BROWSING = "WebViewConnectionlessSafeBrowsing"; - public static final String WEBVIEW_PAGE_STARTED_ON_COMMIT = "WebViewPageStartedOnCommit"; private static native boolean nativeIsEnabled(String featureName); }
diff --git a/ash/accelerators/accelerator_controller_impl.cc b/ash/accelerators/accelerator_controller_impl.cc index 299464d7..253b8a5 100644 --- a/ash/accelerators/accelerator_controller_impl.cc +++ b/ash/accelerators/accelerator_controller_impl.cc
@@ -316,9 +316,11 @@ /*going_left=*/accelerator.key_code() == ui::VKEY_OEM_4); } - desks_controller->MoveWindowFromActiveDeskTo( - window_to_move, target_desk, - DesksMoveWindowFromActiveDeskSource::kShortcut); + if (!desks_controller->MoveWindowFromActiveDeskTo( + window_to_move, target_desk, + DesksMoveWindowFromActiveDeskSource::kShortcut)) { + return; + } if (in_overview) { // We should not exit overview as a result of this shortcut.
diff --git a/ash/app_list/views/apps_container_view.cc b/ash/app_list/views/apps_container_view.cc index eb91a88..b0f99cb 100644 --- a/ash/app_list/views/apps_container_view.cc +++ b/ash/app_list/views/apps_container_view.cc
@@ -132,6 +132,7 @@ } void AppsContainerView::ResetForShowApps() { + UpdateSuggestionChips(); SetShowState(SHOW_APPS, false); DisableFocusForShowingActiveFolder(false); }
diff --git a/ash/dbus/ash_dbus_helper.cc b/ash/dbus/ash_dbus_helper.cc index a57f5dc..ba27720 100644 --- a/ash/dbus/ash_dbus_helper.cc +++ b/ash/dbus/ash_dbus_helper.cc
@@ -6,6 +6,7 @@ #include "base/command_line.h" #include "base/memory/ptr_util.h" +#include "base/message_loop/message_pump_type.h" #include "base/system/sys_info.h" #include "base/threading/thread.h" #include "chromeos/dbus/constants/dbus_switches.h" @@ -47,7 +48,7 @@ // Create the D-Bus thread. base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; dbus_thread_ = std::make_unique<base::Thread>("D-Bus thread"); dbus_thread_->StartWithOptions(thread_options);
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn index cb5621cd..3abd5451 100644 --- a/ash/resources/vector_icons/BUILD.gn +++ b/ash/resources/vector_icons/BUILD.gn
@@ -157,7 +157,6 @@ "system_menu_audio_output.icon", "system_menu_add_connection.icon", "system_menu_arrow_back.icon", - "system_menu_arrow_right.icon", "system_menu_bluetooth.icon", "system_menu_bluetooth_connected.icon", "system_menu_bluetooth_disabled.icon",
diff --git a/ash/resources/vector_icons/system_menu_arrow_right.icon b/ash/resources/vector_icons/system_menu_arrow_right.icon deleted file mode 100644 index f15761f9..0000000 --- a/ash/resources/vector_icons/system_menu_arrow_right.icon +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -CANVAS_DIMENSIONS, 40, -MOVE_TO, 16, 28, -R_LINE_TO, 8, -8, -R_LINE_TO, -8, -8, -CLOSE - -CANVAS_DIMENSIONS, 20, -MOVE_TO, 8, 14, -R_LINE_TO, 4, -4, -R_LINE_TO, -4, -4, -CLOSE
diff --git a/ash/system/accessibility/autoclick_menu_view.cc b/ash/system/accessibility/autoclick_menu_view.cc index 5af60e4..7b04fb3 100644 --- a/ash/system/accessibility/autoclick_menu_view.cc +++ b/ash/system/accessibility/autoclick_menu_view.cc
@@ -31,7 +31,6 @@ const int kPanelPositionButtonSize = 36; const int kPanelPositionButtonPadding = 14; const int kSeparatorHeight = 16; -const SkColor kSeparatorColor = SkColorSetARGB(0x1A, 255, 255, 255); const SkColor kAutoclickMenuButtonColorActive = SkColorSetRGB(138, 180, 248); const SkColor kAutoclickMenuButtonIconColorActive = SkColorSetRGB(32, 33, 36); @@ -119,11 +118,11 @@ SetImage(views::Button::STATE_NORMAL, gfx::CreateVectorIcon( *icon_, toggled_ ? kAutoclickMenuButtonIconColorActive - : kUnifiedMenuIconColor)); + : kIconOnDarkBackgroundColor)); SetImage(views::Button::STATE_DISABLED, gfx::CreateVectorIcon( *icon_, toggled_ ? kAutoclickMenuButtonIconColorActive - : kUnifiedMenuIconColor)); + : kIconOnDarkBackgroundColor)); } const gfx::VectorIcon* icon_; @@ -214,7 +213,7 @@ AddChildView(action_button_container); views::Separator* separator = new views::Separator(); - separator->SetColor(kSeparatorColor); + separator->SetColor(kSeparatorOnDarkBackgroundColor); separator->SetPreferredHeight(kSeparatorHeight); int total_height = kUnifiedTopShortcutSpacing * 2 + kTrayItemSize; int separator_spacing = (total_height - kSeparatorHeight) / 2;
diff --git a/ash/system/accessibility/autoclick_scroll_view.cc b/ash/system/accessibility/autoclick_scroll_view.cc index 0f3b3fc..3ff87daf 100644 --- a/ash/system/accessibility/autoclick_scroll_view.cc +++ b/ash/system/accessibility/autoclick_scroll_view.cc
@@ -50,8 +50,9 @@ EnableCanvasFlippingForRTLUI(false); SetPreferredSize( gfx::Size(kScrollButtonCloseSizeDips, kScrollButtonCloseSizeDips)); - SetImage(views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(kAutoclickCloseIcon, kUnifiedMenuIconColor)); + SetImage( + views::Button::STATE_NORMAL, + gfx::CreateVectorIcon(kAutoclickCloseIcon, kIconOnDarkBackgroundColor)); } ~AutoclickScrollCloseButton() override = default; @@ -130,7 +131,7 @@ base::BindRepeating(&AutoclickScrollButton::DoScrollAction, base::Unretained(this))); SetImage(views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(icon, kUnifiedMenuIconColor)); + gfx::CreateVectorIcon(icon, kIconOnDarkBackgroundColor)); if (action_ == AutoclickController::ScrollPadAction::kScrollLeft || action_ == AutoclickController::ScrollPadAction::kScrollRight) { size_ = gfx::Size(kScrollPadButtonHypotenuseDips / 2,
diff --git a/ash/system/audio/unified_volume_view.cc b/ash/system/audio/unified_volume_view.cc index 62b30c3..db513db 100644 --- a/ash/system/audio/unified_volume_view.cc +++ b/ash/system/audio/unified_volume_view.cc
@@ -68,8 +68,8 @@ auto* headset = new views::ImageView(); headset->set_can_process_events_within_subtree(false); - headset->SetImage( - CreateVectorIcon(vector_icons::kHeadsetIcon, kUnifiedMenuIconColor)); + headset->SetImage(CreateVectorIcon(vector_icons::kHeadsetIcon, + kIconOnDarkBackgroundColor)); AddChildView(headset); auto* more = new views::ImageView(); @@ -78,7 +78,7 @@ ? SkBitmapOperations::ROTATION_270_CW : SkBitmapOperations::ROTATION_90_CW; more->SetImage(gfx::ImageSkiaOperations::CreateRotatedImage( - CreateVectorIcon(kUnifiedMenuExpandIcon, kUnifiedMenuIconColor), + CreateVectorIcon(kUnifiedMenuExpandIcon, kIconOnDarkBackgroundColor), icon_rotation)); AddChildView(more); @@ -110,13 +110,13 @@ std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override { return TrayPopupUtils::CreateInkDropRipple( TrayPopupInkDropStyle::FILL_BOUNDS, this, - GetInkDropCenterBasedOnLastEvent(), kUnifiedMenuIconColor); + GetInkDropCenterBasedOnLastEvent(), kIconOnDarkBackgroundColor); } std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() const override { return TrayPopupUtils::CreateInkDropHighlight( - TrayPopupInkDropStyle::FILL_BOUNDS, this, kUnifiedMenuIconColor); + TrayPopupInkDropStyle::FILL_BOUNDS, this, kIconOnDarkBackgroundColor); } std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override {
diff --git a/ash/system/ime/tray_ime_chromeos.cc b/ash/system/ime/tray_ime_chromeos.cc index 65d70f5e..05a96f6 100644 --- a/ash/system/ime/tray_ime_chromeos.cc +++ b/ash/system/ime/tray_ime_chromeos.cc
@@ -65,8 +65,8 @@ void IMEDetailedView::CreateExtraTitleRowButtons() { if (ime_controller_->managed_by_policy()) { controlled_setting_icon_ = TrayPopupUtils::CreateMainImageView(); - controlled_setting_icon_->SetImage( - gfx::CreateVectorIcon(kSystemMenuBusinessIcon, kMenuIconColor)); + controlled_setting_icon_->SetImage(gfx::CreateVectorIcon( + kSystemMenuBusinessIcon, kIconOnLightBackgroundColor)); controlled_setting_icon_->set_tooltip_text( l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_IME_MANAGED)); tri_view()->AddView(TriView::Container::END, controlled_setting_icon_);
diff --git a/ash/system/ime_menu/ime_list_view.cc b/ash/system/ime_menu/ime_list_view.cc index a981f209..5db375d 100644 --- a/ash/system/ime_menu/ime_list_view.cc +++ b/ash/system/ime_menu/ime_list_view.cc
@@ -158,8 +158,9 @@ // The on-screen keyboard image button. views::ImageView* keyboard_image = TrayPopupUtils::CreateMainImageView(); - keyboard_image->SetImage(gfx::CreateVectorIcon( - kImeMenuOnScreenKeyboardIcon, kMenuIconSize, kMenuIconColor)); + keyboard_image->SetImage( + gfx::CreateVectorIcon(kImeMenuOnScreenKeyboardIcon, kMenuIconSize, + kIconOnLightBackgroundColor)); tri_view->AddView(TriView::Container::START, keyboard_image); // The on-screen keyboard label ('On-screen keyboard'). @@ -280,7 +281,8 @@ for (size_t i = 0; i < property_list.size(); i++) { ImeListItemView* property_view = new ImeListItemView( this, base::string16(), property_list[i].label, - property_list[i].checked, kMenuIconColor, use_unified_theme_); + property_list[i].checked, kIconOnLightBackgroundColor, + use_unified_theme_); scroll_content()->AddChildView(property_view); property_map_[property_view] = property_list[i].key; }
diff --git a/ash/system/ime_menu/ime_menu_tray.cc b/ash/system/ime_menu/ime_menu_tray.cc index 2b5df0a6..fdc3073 100644 --- a/ash/system/ime_menu/ime_menu_tray.cc +++ b/ash/system/ime_menu/ime_menu_tray.cc
@@ -128,7 +128,7 @@ explicit ImeTitleView(bool show_settings_button) : settings_button_(nullptr) { SetBorder(views::CreatePaddedBorder( views::CreateSolidSidedBorder(0, 0, kMenuSeparatorWidth, 0, - kMenuSeparatorColor), + kSeparatorOnLightBackgroundColor), gfx::Insets(kMenuSeparatorVerticalPadding - kMenuSeparatorWidth, 0))); auto box_layout = std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kHorizontal); @@ -231,7 +231,7 @@ SetLayoutManager(std::move(box_layout)); SetBorder(views::CreatePaddedBorder( views::CreateSolidSidedBorder(kMenuSeparatorWidth, 0, 0, 0, - kMenuSeparatorColor), + kSeparatorOnLightBackgroundColor), gfx::Insets(kMenuSeparatorVerticalPadding - kMenuSeparatorWidth, kMenuExtraMarginFromLeftEdge))); @@ -533,7 +533,7 @@ if (chromeos::extension_ime_util::IsArcIME(current_ime.id)) { CreateImageView(); image_view_->SetImage( - gfx::CreateVectorIcon(kShelfGlobeIcon, kTrayIconColor)); + gfx::CreateVectorIcon(kShelfGlobeIcon, kIconOnDarkBackgroundColor)); return; }
diff --git a/ash/system/message_center/notifier_settings_view.cc b/ash/system/message_center/notifier_settings_view.cc index ef60e13..f4274aea 100644 --- a/ash/system/message_center/notifier_settings_view.cc +++ b/ash/system/message_center/notifier_settings_view.cc
@@ -322,8 +322,9 @@ void NotifierSettingsView::NotifierButton::UpdateIconImage( const gfx::ImageSkia& icon) { if (icon.isNull()) { - icon_view_->SetImage(gfx::CreateVectorIcon( - message_center::kProductIcon, kEntryIconSize, kUnifiedMenuIconColor)); + icon_view_->SetImage(gfx::CreateVectorIcon(message_center::kProductIcon, + kEntryIconSize, + kIconOnDarkBackgroundColor)); } else { icon_view_->SetImage(icon); icon_view_->SetImageSize(gfx::Size(kEntryIconSize, kEntryIconSize)); @@ -391,7 +392,7 @@ if (!GetEnabled()) { auto policy_enforced_icon = std::make_unique<views::ImageView>(); policy_enforced_icon->SetImage(gfx::CreateVectorIcon( - kSystemMenuBusinessIcon, kEntryIconSize, kUnifiedMenuIconColor)); + kSystemMenuBusinessIcon, kEntryIconSize, kIconOnDarkBackgroundColor)); cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, GridLayout::FIXED, kEntryIconSize, 0); layout->AddView(std::move(policy_enforced_icon)); @@ -498,11 +499,11 @@ if (is_quiet_mode) { quiet_mode_icon_->SetImage( gfx::CreateVectorIcon(kNotificationCenterDoNotDisturbOnIcon, - kMenuIconSize, kUnifiedMenuIconColor)); + kMenuIconSize, kIconOnDarkBackgroundColor)); } else { - quiet_mode_icon_->SetImage( - gfx::CreateVectorIcon(kNotificationCenterDoNotDisturbOffIcon, - kMenuIconSize, kUnifiedMenuIconColorDisabled)); + quiet_mode_icon_->SetImage(gfx::CreateVectorIcon( + kNotificationCenterDoNotDisturbOffIcon, kMenuIconSize, + kIconOnDarkBackgroundColorDisabled)); } }
diff --git a/ash/system/message_center/unified_message_center_view.cc b/ash/system/message_center/unified_message_center_view.cc index bd962c2..b7c2e152 100644 --- a/ash/system/message_center/unified_message_center_view.cc +++ b/ash/system/message_center/unified_message_center_view.cc
@@ -239,7 +239,7 @@ canvas->DrawSharpLine( gfx::PointF(bounds.bottom_left() - gfx::Vector2d(0, 1)), gfx::PointF(bounds.bottom_right() - gfx::Vector2d(0, 1)), - kStackingNotificationCounterBorderColor); + kSeparatorOnLightBackgroundColor); } const char* StackingNotificationCounterView::GetClassName() const {
diff --git a/ash/system/message_center/unified_message_list_view.cc b/ash/system/message_center/unified_message_list_view.cc index 12a7ac49..409c5c7 100644 --- a/ash/system/message_center/unified_message_list_view.cc +++ b/ash/system/message_center/unified_message_list_view.cc
@@ -90,7 +90,7 @@ is_bottom ? views::NullBorder() : views::CreateSolidSidedBorder( 0, 0, kUnifiedNotificationSeparatorThickness, 0, - kUnifiedNotificationSeparatorColor)); + kSeparatorOnLightBackgroundColor)); const int top_radius = is_top ? kUnifiedTrayCornerRadius : 0; const int bottom_radius = is_bottom ? kUnifiedTrayCornerRadius : 0; message_view_->UpdateCornerRadius(top_radius, bottom_radius);
diff --git a/ash/system/network/active_network_icon.cc b/ash/system/network/active_network_icon.cc index de1f4e7..4a99f03 100644 --- a/ash/system/network/active_network_icon.cc +++ b/ash/system/network/active_network_icon.cc
@@ -39,14 +39,6 @@ icon_type == network_icon::ICON_TYPE_TRAY_OOBE; } -SkColor GetDefaultColorForIconType(network_icon::IconType icon_type) { - if (icon_type == network_icon::ICON_TYPE_TRAY_REGULAR) - return kTrayIconColor; - if (icon_type == network_icon::ICON_TYPE_TRAY_OOBE) - return kOobeTrayIconColor; - return kUnifiedMenuIconColor; -} - } // namespace ActiveNetworkIcon::ActiveNetworkIcon(service_manager::Connector* connector, @@ -212,8 +204,9 @@ // TODO(902409): Show proper technology badges. if (animating) *animating = false; - return gfx::CreateVectorIcon(kNetworkBadgeTechnologyLteIcon, - GetDefaultColorForIconType(icon_type)); + return gfx::CreateVectorIcon( + kNetworkBadgeTechnologyLteIcon, + network_icon::GetDefaultColorForIconType(icon_type)); } // If Cellular is connecting, use the active non cellular network. return GetDefaultImageImpl(model_->active_non_cellular(), icon_type,
diff --git a/ash/system/network/network_icon.cc b/ash/system/network/network_icon.cc index 3159a91..7072865 100644 --- a/ash/system/network/network_icon.cc +++ b/ash/system/network/network_icon.cc
@@ -135,14 +135,6 @@ icon_type == ICON_TYPE_TRAY_OOBE; } -SkColor GetDefaultColorForIconType(IconType icon_type) { - if (icon_type == ICON_TYPE_TRAY_REGULAR) - return kTrayIconColor; - if (icon_type == ICON_TYPE_TRAY_OOBE) - return kOobeTrayIconColor; - return kUnifiedMenuIconColor; -} - bool IconTypeIsDark(IconType icon_type) { // Dark icon is used for OOBE tray icon because the background is white. return icon_type == ICON_TYPE_TRAY_OOBE; @@ -235,7 +227,8 @@ kNetworkVpnIcon, gfx::Tween::ColorValueBetween( floored_animation_value, - SkColorSetA(kMenuIconColor, kConnectingImageAlpha), kMenuIconColor)); + SkColorSetA(kIconOnLightBackgroundColor, kConnectingImageAlpha), + kIconOnLightBackgroundColor)); } int StrengthIndex(int strength) { @@ -447,6 +440,12 @@ //------------------------------------------------------------------------------ // Public interface +SkColor GetDefaultColorForIconType(IconType icon_type) { + if (icon_type == network_icon::ICON_TYPE_TRAY_OOBE) + return kIconOnLightBackgroundColor; + return kIconOnDarkBackgroundColor; +} + const gfx::ImageSkia GetBasicImage(IconType icon_type, NetworkType network_type, bool connected) {
diff --git a/ash/system/network/network_icon.h b/ash/system/network/network_icon.h index 4dba082..ddc5625c 100644 --- a/ash/system/network/network_icon.h +++ b/ash/system/network/network_icon.h
@@ -30,6 +30,9 @@ // Strength of a wireless signal. enum class SignalStrength { NONE, WEAK, MEDIUM, STRONG }; +// Returns the color of an icon on the given |icon_type|. +SkColor GetDefaultColorForIconType(IconType icon_type); + // Returns an image to represent either a fully connected network or a // disconnected network. const gfx::ImageSkia GetBasicImage(
diff --git a/ash/system/network/network_list_view.cc b/ash/system/network/network_list_view.cc index 2240c84..b48e713 100644 --- a/ash/system/network/network_list_view.cc +++ b/ash/system/network/network_list_view.cc
@@ -339,9 +339,9 @@ // Mobile icons which are not connecting or connected should display a small // "X" icon superimposed so that it is clear that they are disconnected. network_image = gfx::ImageSkiaOperations::CreateSuperimposedImage( - info.image, gfx::CreateVectorIcon(kNetworkMobileNotConnectedXIcon, - info.image.height(), - kMobileNotConnectedXIconColor)); + info.image, + gfx::CreateVectorIcon(kNetworkMobileNotConnectedXIcon, + info.image.height(), kIconOnDarkBackgroundColor)); } else { network_image = info.image; } @@ -379,12 +379,14 @@ if (info.type != NetworkType::kTether) return nullptr; - views::ImageView* icon = TrayPopupUtils::CreateMoreImageView(); + views::ImageView* icon = new views::ImageView; + icon->SetPreferredSize(gfx::Size(kMenuIconSize, kMenuIconSize)); + icon->EnableCanvasFlippingForRTLUI(true); PowerStatus::BatteryImageInfo icon_info; icon_info.charge_percent = info.battery_percentage; - icon->SetImage( - PowerStatus::GetBatteryImage(icon_info, kMobileNetworkBatteryIconSize, - kMenuIconColorDisabled, kMenuIconColor)); + icon->SetImage(PowerStatus::GetBatteryImage( + icon_info, kMobileNetworkBatteryIconSize, + kIconOnDarkBackgroundColorDisabled, kIconOnDarkBackgroundColor)); // Show the numeric battery percentage on hover. icon->set_tooltip_text(base::FormatPercent(info.battery_percentage)); @@ -399,8 +401,8 @@ return nullptr; views::ImageView* controlled_icon = TrayPopupUtils::CreateMainImageView(); - controlled_icon->SetImage( - gfx::CreateVectorIcon(kSystemMenuBusinessIcon, kMenuIconColor)); + controlled_icon->SetImage(gfx::CreateVectorIcon(kSystemMenuBusinessIcon, + kIconOnDarkBackgroundColor)); return controlled_icon; } @@ -411,7 +413,7 @@ views::ImageView* controlled_icon = TrayPopupUtils::CreateMainImageView(); controlled_icon->SetImage( - gfx::CreateVectorIcon(kCaptivePortalIcon, kMenuIconColor)); + gfx::CreateVectorIcon(kCaptivePortalIcon, kIconOnDarkBackgroundColor)); controlled_icon->set_tooltip_text(l10n_util::GetStringFUTF16( IDS_ASH_STATUS_TRAY_EXTENSION_CONTROLLED_WIFI, base::UTF8ToUTF16(info.captive_portal_provider_name))); @@ -533,7 +535,7 @@ // Set 'info' icon on left side. views::ImageView* image_view = TrayPopupUtils::CreateMainImageView(); image_view->SetImage( - gfx::CreateVectorIcon(kSystemMenuInfoIcon, kMenuIconColor)); + gfx::CreateVectorIcon(kSystemMenuInfoIcon, kIconOnDarkBackgroundColor)); image_view->SetBackground(views::CreateSolidBackground(SK_ColorTRANSPARENT)); connection_warning->AddView(TriView::Container::START, image_view);
diff --git a/ash/system/palette/palette_tray.cc b/ash/system/palette/palette_tray.cc index 1deeb68..d160bd7a6 100644 --- a/ash/system/palette/palette_tray.cc +++ b/ash/system/palette/palette_tray.cc
@@ -67,9 +67,6 @@ constexpr int kPaddingBetweenTitleAndLeftEdge = 12; constexpr int kPaddingBetweenTitleAndSeparator = 3; -// Color of the separator. -const SkColor kPaletteSeparatorColor = SkColorSetARGB(0x1E, 0x00, 0x00, 0x00); - // Returns true if the |palette_tray| is on an internal display or on every // display if requested from the command line. bool ShouldShowOnDisplay(PaletteTray* palette_tray) { @@ -500,7 +497,7 @@ // Add horizontal separator between the title and tools. auto* separator = new views::Separator(); - separator->SetColor(kPaletteSeparatorColor); + separator->SetColor(kSeparatorOnLightBackgroundColor); separator->SetBorder(views::CreateEmptyBorder(gfx::Insets( kPaddingBetweenTitleAndSeparator, 0, kMenuSeparatorVerticalPadding, 0))); bubble_view->AddChildView(separator);
diff --git a/ash/system/session/logout_button_tray.cc b/ash/system/session/logout_button_tray.cc index b32d72e..34f03b5 100644 --- a/ash/system/session/logout_button_tray.cc +++ b/ash/system/session/logout_button_tray.cc
@@ -142,8 +142,9 @@ } else { button_->SetText(base::string16()); button_->SetAccessibleName(title); - button_->SetImage(views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(kShelfLogoutIcon, kTrayIconColor)); + button_->SetImage( + views::Button::STATE_NORMAL, + gfx::CreateVectorIcon(kShelfLogoutIcon, kIconOnDarkBackgroundColor)); button_->SetMinSize(gfx::Size(kTrayItemSize, kTrayItemSize)); } UpdateVisibility();
diff --git a/ash/system/tray/detailed_view_delegate.cc b/ash/system/tray/detailed_view_delegate.cc index fcb8ab6bb..03cedddee 100644 --- a/ash/system/tray/detailed_view_delegate.cc +++ b/ash/system/tray/detailed_view_delegate.cc
@@ -62,8 +62,8 @@ class BackButton : public CustomShapeButton { public: BackButton(views::ButtonListener* listener) : CustomShapeButton(listener) { - gfx::ImageSkia image = - gfx::CreateVectorIcon(kUnifiedMenuArrowBackIcon, kUnifiedMenuIconColor); + gfx::ImageSkia image = gfx::CreateVectorIcon(kUnifiedMenuArrowBackIcon, + kIconOnDarkBackgroundColor); SetImage(views::Button::STATE_NORMAL, image); SetImageHorizontalAlignment(ALIGN_RIGHT); SetImageVerticalAlignment(ALIGN_MIDDLE); @@ -145,7 +145,7 @@ views::View* DetailedViewDelegate::CreateTitleSeparator() { views::Separator* separator = new views::Separator(); - separator->SetColor(kUnifiedMenuSeparatorColor); + separator->SetColor(kSeparatorOnDarkBackgroundColor); separator->SetBorder(views::CreateEmptyBorder( kTitleRowProgressBarHeight - views::Separator::kThickness, 0, 0, 0)); return separator; @@ -156,7 +156,7 @@ if (show_separator) { view->SetBorder(views::CreatePaddedBorder( views::CreateSolidSidedBorder(0, 0, kTraySeparatorWidth, 0, - kUnifiedMenuSeparatorColor), + kSeparatorOnDarkBackgroundColor), gfx::Insets(kMenuSeparatorVerticalPadding, 0, kMenuSeparatorVerticalPadding - kTraySeparatorWidth, 0))); } else { @@ -168,7 +168,7 @@ views::Separator* DetailedViewDelegate::CreateListSubHeaderSeparator() { views::Separator* separator = new views::Separator(); - separator->SetColor(kUnifiedMenuSeparatorColor); + separator->SetColor(kSeparatorOnDarkBackgroundColor); separator->SetBorder(views::CreateEmptyBorder( kMenuSeparatorVerticalPadding - views::Separator::kThickness, 0, 0, 0)); return separator; @@ -183,8 +183,8 @@ if (icon.is_empty()) item->AddLabelRow(text); else - item->AddIconAndLabel(gfx::CreateVectorIcon(icon, kUnifiedMenuIconColor), - text); + item->AddIconAndLabel( + gfx::CreateVectorIcon(icon, kIconOnDarkBackgroundColor), text); return item; }
diff --git a/ash/system/tray/label_tray_view.cc b/ash/system/tray/label_tray_view.cc index bdadf25..91394cc 100644 --- a/ash/system/tray/label_tray_view.cc +++ b/ash/system/tray/label_tray_view.cc
@@ -46,7 +46,8 @@ views::View* LabelTrayView::CreateChildView( const base::string16& message) const { HoverHighlightView* child = new HoverHighlightView(click_listener_); - gfx::ImageSkia icon_image = gfx::CreateVectorIcon(icon_, kMenuIconColor); + gfx::ImageSkia icon_image = + gfx::CreateVectorIcon(icon_, kIconOnLightBackgroundColor); child->AddIconAndLabelForDefaultView(icon_image, message); child->text_label()->SetMultiLine(true); child->text_label()->SetAllowCharacterBreak(true);
diff --git a/ash/system/tray/system_menu_button.cc b/ash/system/tray/system_menu_button.cc index 0bc09dc..ecd0d7a 100644 --- a/ash/system/tray/system_menu_button.cc +++ b/ash/system/tray/system_menu_button.cc
@@ -53,9 +53,9 @@ void SystemMenuButton::SetVectorIcon(const gfx::VectorIcon& icon) { SetImage(views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(icon, kMenuIconColor)); + gfx::CreateVectorIcon(icon, kIconOnLightBackgroundColor)); SetImage(views::Button::STATE_DISABLED, - gfx::CreateVectorIcon(icon, kMenuIconColorDisabled)); + gfx::CreateVectorIcon(icon, kIconOnLightBackgroundColorDisabled)); } SystemMenuButton::~SystemMenuButton() = default;
diff --git a/ash/system/tray/tray_constants.cc b/ash/system/tray/tray_constants.cc index 6862765..8f35a1a5 100644 --- a/ash/system/tray/tray_constants.cc +++ b/ash/system/tray/tray_constants.cc
@@ -33,17 +33,11 @@ const int kTrayToggleButtonWidth = 68; -const SkColor kMobileNotConnectedXIconColor = SkColorSetRGB(0xb2, 0xb2, 0xb2); - -const SkColor kTrayIconColor = gfx::kGoogleGrey200; -const SkColor kOobeTrayIconColor = gfx::kGoogleGrey600; // Note that the alpha value should match kSignalStrengthImageBgAlpha in // ash/public/cpp/network_icon_image_source.cc const int kTrayIconBackgroundAlpha = 0x4D /* 30% */; const int kMenuIconSize = 20; -const SkColor kMenuIconColor = gfx::kChromeIconGrey; -const SkColor kMenuIconColorDisabled = SkColorSetA(gfx::kChromeIconGrey, 0x61); const int kMenuButtonSize = 48; const int kMenuSeparatorVerticalPadding = 4; const int kMenuExtraMarginFromLeftEdge = 4; @@ -53,8 +47,6 @@ const int kHitRegionPadding = 4; const int kHitRegionPaddingDense = 2; -const SkColor kMenuSeparatorColor = SkColorSetA(SK_ColorBLACK, 0x1F); - const SkColor kTrayPopupInkDropBaseColor = SK_ColorBLACK; const float kTrayPopupInkDropRippleOpacity = 0.06f; const float kTrayPopupInkDropHighlightOpacity = 0.08f;
diff --git a/ash/system/tray/tray_constants.h b/ash/system/tray/tray_constants.h index fba3711..6cff762 100644 --- a/ash/system/tray/tray_constants.h +++ b/ash/system/tray/tray_constants.h
@@ -60,8 +60,6 @@ // Constants for the title row. constexpr int kTitleRowProgressBarHeight = 2; -extern const SkColor kMobileNotConnectedXIconColor; - // Extra padding used to adjust hitting region around tray items. extern const int kHitRegionPadding; extern const int kHitRegionPaddingDense; @@ -73,14 +71,27 @@ // in tray detailed views. constexpr int kTraySeparatorWidth = 0; -// The color of the separators used in the system menu. -extern const SkColor kMenuSeparatorColor; +// Colors of separator on light/dark background. +constexpr SkColor kSeparatorOnLightBackgroundColor = + SkColorSetA(SK_ColorBLACK, 0x23); // 14% +constexpr SkColor kSeparatorOnDarkBackgroundColor = + SkColorSetA(SK_ColorWHITE, 0x23); // 14% + +// Primary colors of icon on light/dark background. Color of disabled icon is +// 38% of corresponding non-disabled icon. +constexpr SkColor kIconOnDarkBackgroundColor = gfx::kGoogleGrey200; +constexpr SkColor kIconOnDarkBackgroundColorDisabled = + SkColorSetA(kIconOnDarkBackgroundColor, 0x61); // 38% +constexpr SkColor kIconOnLightBackgroundColor = gfx::kGoogleGrey700; +constexpr SkColor kIconOnLightBackgroundColorDisabled = + SkColorSetA(kIconOnLightBackgroundColor, 0x61); // 38% + +// Second color of icon on dark background. +constexpr SkColor kIconOnDarkBackgroundSecondaryColor = gfx::kGoogleGrey500; // The size and foreground color of the icons appearing in the material design // system tray. constexpr int kTrayIconSize = 16; -extern const SkColor kTrayIconColor; -extern const SkColor kOobeTrayIconColor; extern const int kTrayIconBackgroundAlpha; // The padding around network tray icon in dip. @@ -90,8 +101,6 @@ // The size and foreground color of the icons appearing in the material design // system menu. extern const int kMenuIconSize; -extern const SkColor kMenuIconColor; -extern const SkColor kMenuIconColorDisabled; // The size of buttons in the system menu. ASH_EXPORT extern const int kMenuButtonSize; // The vertical padding for the system menu separator. @@ -118,35 +127,25 @@ // The radius used to draw the corners of the rounded rect style ink drops. extern const int kTrayPopupInkDropCornerRadius; -// The colors used when --enable-features=SystemTrayUnified flag is enabled. constexpr SkColor kUnifiedMenuBackgroundColor = SkColorSetARGB(0xf2, 0x20, 0x21, 0x24); constexpr SkColor kUnifiedMenuBackgroundColorWithBlur = SkColorSetA(kUnifiedMenuBackgroundColor, 0x99); constexpr float kUnifiedMenuBackgroundBlur = 30.f; constexpr SkColor kUnifiedMenuTextColor = SkColorSetRGB(0xf1, 0xf3, 0xf4); -constexpr SkColor kUnifiedMenuIconColor = SkColorSetRGB(0xe8, 0xea, 0xed); constexpr SkColor kUnifiedMenuSecondaryTextColor = - SkColorSetA(kUnifiedMenuIconColor, 0xa3); -constexpr SkColor kUnifiedMenuIconColorDisabled = - SkColorSetRGB(0x5f, 0x63, 0x68); + SkColorSetA(kIconOnDarkBackgroundColor, 0xa3); constexpr SkColor kUnifiedMenuTextColorDisabled = SkColorSetRGB(0x5f, 0x63, 0x68); constexpr SkColor kUnifiedMenuButtonColor = - SkColorSetA(kUnifiedMenuIconColor, 0x14); -constexpr SkColor kUnifiedMenuSeparatorColor = - SkColorSetA(kUnifiedMenuIconColor, 0x23); + SkColorSetA(kIconOnDarkBackgroundColor, 0x14); constexpr SkColor kUnifiedMenuButtonColorActive = SkColorSetRGB(0x25, 0x81, 0xdf); constexpr SkColor kUnifiedMenuButtonColorDisabled = SkColorSetA(kUnifiedMenuButtonColor, 0xa); -constexpr SkColor kUnifiedNotificationSeparatorColor = - SkColorSetRGB(0xdf, 0xe0, 0xe0); constexpr SkColor kUnifiedFeaturePodHoverColor = SkColorSetRGB(0xff, 0xff, 0xff); constexpr SkColor kUnifiedRecordingIconColor = gfx::kGoogleRedDark600; -constexpr SkColor kUnifiedManagedDeviceIconColor = - SkColorSetRGB(0x9a, 0xa0, 0xa6); constexpr gfx::Insets kUnifiedMenuItemPadding(0, 16, 16, 16); constexpr gfx::Insets kUnifiedSystemInfoViewPadding(4, 16, 16, 16); @@ -172,8 +171,6 @@ constexpr gfx::Insets kUnifiedCircularButtonFocusPadding(4); constexpr int kStackingNotificationCounterHeight = 32; constexpr gfx::Insets kStackingNotificationClearAllButtonPadding(8, 16); -constexpr SkColor kStackingNotificationCounterBorderColor = - SkColorSetRGB(0xe0, 0xe0, 0xe0); constexpr SkColor kStackingNotificationCounterLabelColor = SkColorSetRGB(0x5f, 0x64, 0x68); @@ -184,8 +181,6 @@ constexpr int kUnifiedManagedDeviceSpacing = 4; constexpr int kUnifiedSystemInfoHeight = 16; constexpr int kUnifiedSystemInfoSpacing = 8; -constexpr int kUnifiedSystemInfoSeparatorColor = - SkColorSetA(SK_ColorWHITE, 0x24); constexpr gfx::Insets kUnifiedSystemInfoDateViewPadding(3); // Constants used in FeaturePodsView of UnifiedSystemTray.
diff --git a/ash/system/tray/tray_detailed_view.cc b/ash/system/tray/tray_detailed_view.cc index c7844972..2268154 100644 --- a/ash/system/tray/tray_detailed_view.cc +++ b/ash/system/tray/tray_detailed_view.cc
@@ -242,7 +242,7 @@ cc::PaintFlags flags; gfx::ShadowValues shadow; shadow.emplace_back(gfx::Vector2d(0, kShadowOffsetY), kShadowBlur, - kMenuSeparatorColor); + kSeparatorOnDarkBackgroundColor); flags.setLooper(gfx::CreateShadowDrawLooper(shadow)); flags.setAntiAlias(true); canvas->ClipRect(shadowed_area, SkClipOp::kDifference);
diff --git a/ash/system/tray/tray_popup_item_style.cc b/ash/system/tray/tray_popup_item_style.cc index 971c42e..7eb7d03 100644 --- a/ash/system/tray/tray_popup_item_style.cc +++ b/ash/system/tray/tray_popup_item_style.cc
@@ -24,7 +24,7 @@ SkColor TrayPopupItemStyle::GetIconColor(ColorStyle color_style, bool use_unified_theme) { const SkColor kBaseIconColor = - use_unified_theme ? kUnifiedMenuIconColor : gfx::kChromeIconGrey; + use_unified_theme ? kIconOnDarkBackgroundColor : gfx::kChromeIconGrey; switch (color_style) { case ColorStyle::ACTIVE: return kBaseIconColor;
diff --git a/ash/system/tray/tray_popup_utils.cc b/ash/system/tray/tray_popup_utils.cc index 8377a911..19c0013 100644 --- a/ash/system/tray/tray_popup_utils.cc +++ b/ash/system/tray/tray_popup_utils.cc
@@ -167,15 +167,6 @@ return image; } -views::ImageView* TrayPopupUtils::CreateMoreImageView() { - auto* image = new views::ImageView; - image->SetPreferredSize(gfx::Size(gfx::Size(kMenuIconSize, kMenuIconSize))); - image->EnableCanvasFlippingForRTLUI(true); - image->SetImage( - gfx::CreateVectorIcon(kSystemMenuArrowRightIcon, kMenuIconColor)); - return image; -} - views::Slider* TrayPopupUtils::CreateSlider(views::SliderListener* listener) { views::Slider* slider = new views::Slider(listener); slider->SetBorder(views::CreateEmptyBorder( @@ -237,7 +228,7 @@ views::Separator* TrayPopupUtils::CreateVerticalSeparator() { views::Separator* separator = new views::Separator(); separator->SetPreferredHeight(24); - separator->SetColor(kMenuSeparatorColor); + separator->SetColor(kSeparatorOnLightBackgroundColor); return separator; } @@ -322,7 +313,7 @@ views::Separator* TrayPopupUtils::CreateListItemSeparator(bool left_inset) { views::Separator* separator = new views::Separator(); - separator->SetColor(kMenuSeparatorColor); + separator->SetColor(kSeparatorOnLightBackgroundColor); separator->SetBorder(views::CreateEmptyBorder( kMenuSeparatorVerticalPadding - views::Separator::kThickness, left_inset
diff --git a/ash/system/tray/tray_popup_utils.h b/ash/system/tray/tray_popup_utils.h index f422be6..06ee842 100644 --- a/ash/system/tray/tray_popup_utils.h +++ b/ash/system/tray/tray_popup_utils.h
@@ -100,13 +100,6 @@ // TODO(bruthig): Update all system menu rows to use this. static views::ImageView* CreateMainImageView(); - // Returns an image view to be used in the 'more' region of default rows. This - // is used for all 'more' images as well as other images that appear in this - // region, e.g. audio output icon. - // - // TODO(bruthig): Update all default rows to use this. - static views::ImageView* CreateMoreImageView(); - // Returns a slider configured for proper layout within a TriView container // with a FillLayout. static views::Slider* CreateSlider(views::SliderListener* listener);
diff --git a/ash/system/tray/tray_utils.cc b/ash/system/tray/tray_utils.cc index 8bd323173..65d7337d 100644 --- a/ash/system/tray/tray_utils.cc +++ b/ash/system/tray/tray_utils.cc
@@ -20,8 +20,8 @@ SkColor TrayIconColor(session_manager::SessionState session_state) { if (session_state == session_manager::SessionState::OOBE) - return kOobeTrayIconColor; - return kTrayIconColor; + return kIconOnLightBackgroundColor; + return kIconOnDarkBackgroundColor; } } // namespace ash
diff --git a/ash/system/tray/tray_utils.h b/ash/system/tray/tray_utils.h index fb89ed0..e99f6ee 100644 --- a/ash/system/tray/tray_utils.h +++ b/ash/system/tray/tray_utils.h
@@ -17,7 +17,7 @@ // Sets up a Label properly for the tray (sets color, font etc.). void SetupLabelForTray(views::Label* label); -// Get the current tray icon color for the given session state. +// Gets the current tray icon color for the given session state. SkColor TrayIconColor(session_manager::SessionState session_state); } // namespace ash
diff --git a/ash/system/unified/collapse_button.cc b/ash/system/unified/collapse_button.cc index 2a3aec1c..a704ca7 100644 --- a/ash/system/unified/collapse_button.cc +++ b/ash/system/unified/collapse_button.cc
@@ -62,10 +62,11 @@ } void CollapseButton::OnEnabledChanged() { - SetImage(views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(kUnifiedMenuExpandIcon, - GetEnabled() ? kUnifiedMenuIconColor - : kUnifiedMenuIconColorDisabled)); + SetImage( + views::Button::STATE_NORMAL, + gfx::CreateVectorIcon(kUnifiedMenuExpandIcon, + GetEnabled() ? kIconOnDarkBackgroundColor + : kIconOnDarkBackgroundColorDisabled)); } } // namespace ash
diff --git a/ash/system/unified/custom_shape_button.cc b/ash/system/unified/custom_shape_button.cc index 9ac205a..f0687af 100644 --- a/ash/system/unified/custom_shape_button.cc +++ b/ash/system/unified/custom_shape_button.cc
@@ -71,13 +71,13 @@ const { return TrayPopupUtils::CreateInkDropRipple( TrayPopupInkDropStyle::FILL_BOUNDS, this, - GetInkDropCenterBasedOnLastEvent(), kUnifiedMenuIconColor); + GetInkDropCenterBasedOnLastEvent(), kIconOnDarkBackgroundColor); } std::unique_ptr<views::InkDropHighlight> CustomShapeButton::CreateInkDropHighlight() const { return TrayPopupUtils::CreateInkDropHighlight( - TrayPopupInkDropStyle::FILL_BOUNDS, this, kUnifiedMenuIconColor); + TrayPopupInkDropStyle::FILL_BOUNDS, this, kIconOnDarkBackgroundColor); } std::unique_ptr<views::InkDropMask> CustomShapeButton::CreateInkDropMask()
diff --git a/ash/system/unified/feature_pod_button.cc b/ash/system/unified/feature_pod_button.cc index bb8839fc..c6b292c 100644 --- a/ash/system/unified/feature_pod_button.cc +++ b/ash/system/unified/feature_pod_button.cc
@@ -83,13 +83,13 @@ FeaturePodIconButton::CreateInkDropRipple() const { return TrayPopupUtils::CreateInkDropRipple( TrayPopupInkDropStyle::FILL_BOUNDS, this, - GetInkDropCenterBasedOnLastEvent(), kUnifiedMenuIconColor); + GetInkDropCenterBasedOnLastEvent(), kIconOnDarkBackgroundColor); } std::unique_ptr<views::InkDropHighlight> FeaturePodIconButton::CreateInkDropHighlight() const { return TrayPopupUtils::CreateInkDropHighlight( - TrayPopupInkDropStyle::FILL_BOUNDS, this, kUnifiedMenuIconColor); + TrayPopupInkDropStyle::FILL_BOUNDS, this, kIconOnDarkBackgroundColor); } std::unique_ptr<views::InkDropMask> FeaturePodIconButton::CreateInkDropMask() @@ -230,8 +230,8 @@ sub_label_->SetEnabledColor(GetEnabled() ? kUnifiedMenuSecondaryTextColor : kUnifiedMenuTextColorDisabled); detailed_view_arrow_->SetImage(gfx::CreateVectorIcon( - kUnifiedMenuMoreIcon, - GetEnabled() ? kUnifiedMenuIconColor : kUnifiedMenuIconColorDisabled)); + kUnifiedMenuMoreIcon, GetEnabled() ? kIconOnDarkBackgroundColor + : kIconOnDarkBackgroundColorDisabled)); } void FeaturePodLabelButton::LayoutInCenter(views::View* child, int y) { @@ -269,11 +269,12 @@ } void FeaturePodButton::SetVectorIcon(const gfx::VectorIcon& icon) { - icon_button_->SetImage(views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(icon, kUnifiedMenuIconColor)); + icon_button_->SetImage( + views::Button::STATE_NORMAL, + gfx::CreateVectorIcon(icon, kIconOnDarkBackgroundColor)); icon_button_->SetImage( views::Button::STATE_DISABLED, - gfx::CreateVectorIcon(icon, kUnifiedMenuIconColorDisabled)); + gfx::CreateVectorIcon(icon, kIconOnDarkBackgroundColorDisabled)); } void FeaturePodButton::SetLabel(const base::string16& label) {
diff --git a/ash/system/unified/rounded_label_button.cc b/ash/system/unified/rounded_label_button.cc index 02ed15ca..ea77543 100644 --- a/ash/system/unified/rounded_label_button.cc +++ b/ash/system/unified/rounded_label_button.cc
@@ -63,13 +63,13 @@ const { return TrayPopupUtils::CreateInkDropRipple( TrayPopupInkDropStyle::FILL_BOUNDS, this, - GetInkDropCenterBasedOnLastEvent(), kUnifiedMenuIconColor); + GetInkDropCenterBasedOnLastEvent(), kIconOnDarkBackgroundColor); } std::unique_ptr<views::InkDropHighlight> RoundedLabelButton::CreateInkDropHighlight() const { return TrayPopupUtils::CreateInkDropHighlight( - TrayPopupInkDropStyle::FILL_BOUNDS, this, kUnifiedMenuIconColor); + TrayPopupInkDropStyle::FILL_BOUNDS, this, kIconOnDarkBackgroundColor); } std::unique_ptr<views::InkDropMask> RoundedLabelButton::CreateInkDropMask()
diff --git a/ash/system/unified/top_shortcut_button.cc b/ash/system/unified/top_shortcut_button.cc index d4ec9278..6ef800b 100644 --- a/ash/system/unified/top_shortcut_button.cc +++ b/ash/system/unified/top_shortcut_button.cc
@@ -22,7 +22,7 @@ : TopShortcutButton(nullptr /* listener */, accessible_name_id) { SetImage(views::Button::STATE_DISABLED, gfx::CreateVectorIcon(icon, kTrayTopShortcutButtonIconSize, - kUnifiedMenuIconColor)); + kIconOnDarkBackgroundColor)); SetEnabled(false); } @@ -32,10 +32,10 @@ : TopShortcutButton(listener, accessible_name_id) { SetImage(views::Button::STATE_NORMAL, gfx::CreateVectorIcon(icon, kTrayTopShortcutButtonIconSize, - kUnifiedMenuIconColor)); + kIconOnDarkBackgroundColor)); SetImage(views::Button::STATE_DISABLED, gfx::CreateVectorIcon(icon, kTrayTopShortcutButtonIconSize, - kUnifiedMenuIconColorDisabled)); + kIconOnDarkBackgroundColorDisabled)); } TopShortcutButton::TopShortcutButton(views::ButtonListener* listener, @@ -47,7 +47,7 @@ SetTooltipText(l10n_util::GetStringUTF16(accessible_name_id)); TrayPopupUtils::ConfigureTrayPopupButton(this); - set_ink_drop_base_color(kUnifiedMenuIconColor); + set_ink_drop_base_color(kIconOnDarkBackgroundColor); auto path = std::make_unique<SkPath>(); path->addOval(gfx::RectToSkRect(gfx::Rect(CalculatePreferredSize())));
diff --git a/ash/system/unified/unified_managed_device_view.cc b/ash/system/unified/unified_managed_device_view.cc index 78b9143..9d9796c9 100644 --- a/ash/system/unified/unified_managed_device_view.cc +++ b/ash/system/unified/unified_managed_device_view.cc
@@ -73,7 +73,7 @@ !enterprise_domain_name.empty()) { // Show enterpised managed UI. icon_->SetImage(gfx::CreateVectorIcon(kSystemTrayManagedIcon, - kUnifiedManagedDeviceIconColor)); + kIconOnDarkBackgroundSecondaryColor)); if (!enterprise_domain_name.empty()) { label_->SetText(l10n_util::GetStringFUTF16( @@ -88,7 +88,7 @@ } else if (session->IsUserSupervised()) { // Show supervised user UI (locally supervised or Family Link). icon_->SetImage(gfx::CreateVectorIcon(GetSupervisedUserIcon(), - kUnifiedManagedDeviceIconColor)); + kIconOnDarkBackgroundSecondaryColor)); label_->SetText(GetSupervisedUserMessage()); SetVisible(true); } else {
diff --git a/ash/system/unified/unified_slider_view.cc b/ash/system/unified/unified_slider_view.cc index 6c3acb0e..8d84959 100644 --- a/ash/system/unified/unified_slider_view.cc +++ b/ash/system/unified/unified_slider_view.cc
@@ -76,9 +76,9 @@ void UnifiedSliderButton::SetVectorIcon(const gfx::VectorIcon& icon) { SetImage(views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(icon, kUnifiedMenuIconColor)); + gfx::CreateVectorIcon(icon, kIconOnDarkBackgroundColor)); SetImage(views::Button::STATE_DISABLED, - gfx::CreateVectorIcon(icon, kUnifiedMenuIconColor)); + gfx::CreateVectorIcon(icon, kIconOnDarkBackgroundColor)); } void UnifiedSliderButton::SetToggled(bool toggled) {
diff --git a/ash/system/unified/unified_system_info_view.cc b/ash/system/unified/unified_system_info_view.cc index 63008e2..8c230c2 100644 --- a/ash/system/unified/unified_system_info_view.cc +++ b/ash/system/unified/unified_system_info_view.cc
@@ -387,7 +387,7 @@ if (PowerStatus::Get()->IsBatteryPresent()) { auto* separator = new views::Separator(); - separator->SetColor(kUnifiedSystemInfoSeparatorColor); + separator->SetColor(kSeparatorOnDarkBackgroundColor); separator->SetPreferredHeight(kUnifiedSystemInfoHeight); AddChildView(separator);
diff --git a/ash/system/unified/user_chooser_view.cc b/ash/system/unified/user_chooser_view.cc index 3dc7e84a..afb34553 100644 --- a/ash/system/unified/user_chooser_view.cc +++ b/ash/system/unified/user_chooser_view.cc
@@ -82,8 +82,8 @@ gfx::Insets(kUnifiedTopShortcutSpacing), kUnifiedTopShortcutSpacing)); auto* icon = new views::ImageView; - icon->SetImage( - gfx::CreateVectorIcon(kSystemMenuNewUserIcon, kUnifiedMenuIconColor)); + icon->SetImage(gfx::CreateVectorIcon(kSystemMenuNewUserIcon, + kIconOnDarkBackgroundColor)); AddChildView(icon); auto* label = new views::Label( @@ -119,7 +119,7 @@ AddChildView(child); child->SetBorder(views::CreateSolidSidedBorder( 0, 0, kUnifiedNotificationSeparatorThickness, 0, - kUnifiedMenuSeparatorColor)); + kSeparatorOnDarkBackgroundColor)); } DISALLOW_COPY_AND_ASSIGN(Separator);
diff --git a/ash/test/ash_unittests.cc b/ash/test/ash_unittests.cc index 21240a8..fc071c82 100644 --- a/ash/test/ash_unittests.cc +++ b/ash/test/ash_unittests.cc
@@ -4,6 +4,7 @@ #include "ash/test/ash_test_suite.h" #include "base/bind.h" +#include "base/message_loop/message_pump_type.h" #include "base/test/launcher/unit_test_launcher.h" #include "base/threading/thread.h" #include "mojo/core/embedder/embedder.h" @@ -16,7 +17,7 @@ // The IPC thread is necessary for the window service. base::Thread ipc_thread("IPC thread"); ipc_thread.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); mojo::core::ScopedIPCSupport ipc_support( ipc_thread.task_runner(), mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);
diff --git a/ash/wm/desks/desks_controller.cc b/ash/wm/desks/desks_controller.cc index f9fcd412..12fa5ba8 100644 --- a/ash/wm/desks/desks_controller.cc +++ b/ash/wm/desks/desks_controller.cc
@@ -359,12 +359,17 @@ return true; } -void DesksController::MoveWindowFromActiveDeskTo( +bool DesksController::MoveWindowFromActiveDeskTo( aura::Window* window, Desk* target_desk, DesksMoveWindowFromActiveDeskSource source) { DCHECK_NE(active_desk_, target_desk); + // An active window might be an always-on-top or pip which doesn't belong to + // the active desk, and hence cannot be removed. + if (!base::Contains(active_desk_->windows(), window)) + return false; + base::AutoReset<bool> in_progress(&are_desks_being_modified_, true); auto* overview_controller = Shell::Get()->overview_controller(); @@ -380,6 +385,9 @@ base::NumberToString16(GetDeskIndex(active_desk_) + 1), base::NumberToString16(GetDeskIndex(target_desk) + 1))); + UMA_HISTOGRAM_ENUMERATION(kMoveWindowFromActiveDeskHistogramName, source); + ReportNumberOfWindowsPerDeskHistogram(); + if (in_overview) { DCHECK(overview_controller->InOverviewSession()); auto* overview_session = overview_controller->overview_session(); @@ -393,14 +401,12 @@ // When in overview, we should return immediately and not change the window // activation as we do below, since the dummy "OverviewModeFocusedWidget" // should remain active while overview mode is active.. - return; + return true; } - UMA_HISTOGRAM_ENUMERATION(kMoveWindowFromActiveDeskHistogramName, source); - ReportNumberOfWindowsPerDeskHistogram(); - // A window moving out of the active desk cannot be active. wm::DeactivateWindow(window); + return true; } void DesksController::OnRootWindowAdded(aura::Window* root_window) {
diff --git a/ash/wm/desks/desks_controller.h b/ash/wm/desks/desks_controller.h index f5300d386..9ad12f4 100644 --- a/ash/wm/desks/desks_controller.h +++ b/ash/wm/desks/desks_controller.h
@@ -108,7 +108,9 @@ // Moves |window| (which must belong to the currently active desk) to // |target_desk| (which must be a different desk). If |window| is minimized, // it will be unminimized after it's moved to |target_desk|. - void MoveWindowFromActiveDeskTo(aura::Window* window, + // Returns true on success, false otherwise (e.g. if |window| doesn't belong + // to the active desk). + bool MoveWindowFromActiveDeskTo(aura::Window* window, Desk* target_desk, DesksMoveWindowFromActiveDeskSource source);
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc index cb0fd158..f8620610 100644 --- a/ash/wm/desks/desks_unittests.cc +++ b/ash/wm/desks/desks_unittests.cc
@@ -38,6 +38,7 @@ #include "base/test/scoped_feature_list.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/window_parenting_client.h" +#include "ui/base/ui_base_types.h" #include "ui/chromeos/events/event_rewriter_chromeos.h" #include "ui/compositor_extra/shadow.h" #include "ui/events/gesture_detection/gesture_configuration.h" @@ -2162,6 +2163,34 @@ EXPECT_FALSE(overview_session->GetHighlightedWindow()); } +TEST_F(DesksAcceleratorsTest, CannotMoveAlwaysOnTopWindows) { + auto* controller = DesksController::Get(); + NewDesk(); + ASSERT_EQ(2u, controller->desks().size()); + Desk* desk_1 = controller->desks()[0].get(); + Desk* desk_2 = controller->desks()[1].get(); + EXPECT_TRUE(desk_1->is_active()); + + // An always-on-top window does not belong to any desk and hence cannot be + // removed. + auto win0 = CreateTestWindow(gfx::Rect(0, 0, 250, 100)); + win0->SetProperty(aura::client::kZOrderingKey, + ui::ZOrderLevel::kFloatingWindow); + wm::ActivateWindow(win0.get()); + EXPECT_EQ(win0.get(), window_util::GetActiveWindow()); + EXPECT_FALSE(DoesActiveDeskContainWindow(win0.get())); + EXPECT_FALSE(controller->MoveWindowFromActiveDeskTo( + win0.get(), desk_2, DesksMoveWindowFromActiveDeskSource::kDragAndDrop)); + const int flags = ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN; + SendAccelerator(ui::VKEY_OEM_4, flags); + EXPECT_EQ(win0.get(), window_util::GetActiveWindow()); + EXPECT_TRUE(win0->IsVisible()); + + // It remains visible even after switching desks. + ActivateDesk(desk_2); + EXPECT_TRUE(win0->IsVisible()); +} + // TODO(afakhry): Add more tests: // - Always on top windows are not tracked by any desk. // - Reusing containers when desks are removed and created.
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index 335f250..53cd765 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -1230,10 +1230,9 @@ if (target_desk == desks_controller->active_desk()) return false; - desks_controller->MoveWindowFromActiveDeskTo( + return desks_controller->MoveWindowFromActiveDeskTo( dragged_window, target_desk, DesksMoveWindowFromActiveDeskSource::kDragAndDrop); - return true; } return false;
diff --git a/base/BUILD.gn b/base/BUILD.gn index c04aa71..87b28b1 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -473,6 +473,7 @@ "message_loop/message_pump_io_ios.h", "message_loop/message_pump_mac.h", "message_loop/message_pump_mac.mm", + "message_loop/message_pump_type.h", "message_loop/message_pump_win.cc", "message_loop/message_pump_win.h", "message_loop/timer_slack.h", @@ -3415,6 +3416,7 @@ "test/android/javatests/src/org/chromium/base/test/util/SkipCheck.java", "test/android/javatests/src/org/chromium/base/test/util/TestFileUtil.java", "test/android/javatests/src/org/chromium/base/test/util/TimeoutScale.java", + "test/android/javatests/src/org/chromium/base/test/util/TimeoutTimer.java", "test/android/javatests/src/org/chromium/base/test/util/UserActionTester.java", "test/android/javatests/src/org/chromium/base/test/util/UrlUtils.java", "test/android/javatests/src/org/chromium/base/test/util/parameter/CommandLineParameter.java",
diff --git a/base/files/file_descriptor_watcher_posix_unittest.cc b/base/files/file_descriptor_watcher_posix_unittest.cc index 22f0514..b9f8a95 100644 --- a/base/files/file_descriptor_watcher_posix_unittest.cc +++ b/base/files/file_descriptor_watcher_posix_unittest.cc
@@ -12,6 +12,7 @@ #include "base/files/file_util.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/message_loop/message_pump_type.h" #include "base/posix/eintr_wrapper.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" @@ -63,7 +64,7 @@ if (GetParam() == FileDescriptorWatcherTestType::MESSAGE_PUMP_FOR_IO_ON_OTHER_THREAD) { Thread::Options options; - options.message_loop_type = MessageLoop::TYPE_IO; + options.message_pump_type = MessagePumpType::IO; ASSERT_TRUE(other_thread_.StartWithOptions(options)); file_descriptor_watcher_ = std::make_unique<FileDescriptorWatcher>(other_thread_.task_runner());
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc index 90cb3e3..9a47503 100644 --- a/base/message_loop/message_loop.cc +++ b/base/message_loop/message_loop.cc
@@ -25,26 +25,16 @@ namespace base { -// Unfortunately since we're not on C++17 we're required to provide an out of -// line definition. -constexpr MessageLoop::Type MessageLoop::TYPE_DEFAULT; -constexpr MessageLoop::Type MessageLoop::TYPE_UI; -constexpr MessageLoop::Type MessageLoop::TYPE_CUSTOM; -constexpr MessageLoop::Type MessageLoop::TYPE_IO; -#if defined(OS_ANDROID) -constexpr MessageLoop::Type MessageLoop::TYPE_JAVA; -#endif - -MessageLoop::MessageLoop(Type type) : MessageLoop(type, nullptr) { +MessageLoop::MessageLoop(MessagePumpType type) : MessageLoop(type, nullptr) { // For TYPE_CUSTOM you must either use // MessageLoop(std::unique_ptr<MessagePump> pump) or // MessageLoop::CreateUnbound() - DCHECK_NE(type_, TYPE_CUSTOM); + DCHECK_NE(type_, MessagePumpType::CUSTOM); BindToCurrentThread(); } MessageLoop::MessageLoop(std::unique_ptr<MessagePump> pump) - : MessageLoop(TYPE_CUSTOM, std::move(pump)) { + : MessageLoop(MessagePumpType::CUSTOM, std::move(pump)) { BindToCurrentThread(); } @@ -73,7 +63,7 @@ #endif // !defined(OS_IOS) } -bool MessageLoop::IsType(Type type) const { +bool MessageLoop::IsType(MessagePumpType type) const { return type_ == type; } @@ -101,17 +91,19 @@ //------------------------------------------------------------------------------ // static -std::unique_ptr<MessageLoop> MessageLoop::CreateUnbound(Type type) { +std::unique_ptr<MessageLoop> MessageLoop::CreateUnbound(MessagePumpType type) { return WrapUnique(new MessageLoop(type, nullptr)); } // static std::unique_ptr<MessageLoop> MessageLoop::CreateUnbound( std::unique_ptr<MessagePump> custom_pump) { - return WrapUnique(new MessageLoop(TYPE_CUSTOM, std::move(custom_pump))); + return WrapUnique( + new MessageLoop(MessagePumpType::CUSTOM, std::move(custom_pump))); } -MessageLoop::MessageLoop(Type type, std::unique_ptr<MessagePump> custom_pump) +MessageLoop::MessageLoop(MessagePumpType type, + std::unique_ptr<MessagePump> custom_pump) : sequence_manager_( sequence_manager::internal::SequenceManagerImpl::CreateUnbound( sequence_manager::SequenceManager::Settings::Builder() @@ -174,11 +166,11 @@ //------------------------------------------------------------------------------ // MessageLoopForUI -MessageLoopForUI::MessageLoopForUI(Type type) : MessageLoop(type) { +MessageLoopForUI::MessageLoopForUI(MessagePumpType type) : MessageLoop(type) { #if defined(OS_ANDROID) - DCHECK(type == TYPE_UI || type == TYPE_JAVA); + DCHECK(type == MessagePumpType::UI || type == MessagePump::Type::JAVA); #else - DCHECK_EQ(type, TYPE_UI); + DCHECK_EQ(type, MessagePumpType::UI); #endif }
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h index a1d6acc..ed43e7f 100644 --- a/base/message_loop/message_loop.h +++ b/base/message_loop/message_loop.h
@@ -14,7 +14,7 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/message_loop/message_loop_current.h" -#include "base/message_loop/message_pump.h" +#include "base/message_loop/message_pump_type.h" #include "base/message_loop/timer_slack.h" #include "base/pending_task.h" #include "base/run_loop.h" @@ -29,6 +29,7 @@ } // namespace internal class MessageLoopImpl; +class MessagePump; namespace sequence_manager { class TaskQueue; @@ -84,8 +85,10 @@ // for tests. TODO(https://crbug.com/891670/) remove this class. class BASE_EXPORT MessageLoop { public: - using Type = MessagePump::Type; + // DEPRECATED: Use MessagePumpType instead + using Type = MessagePumpType; + // DEPRECATED: Use MessagePumpType::* instead static constexpr Type TYPE_DEFAULT = Type::DEFAULT; static constexpr Type TYPE_UI = Type::UI; static constexpr Type TYPE_CUSTOM = Type::CUSTOM; @@ -96,9 +99,9 @@ // Normally, it is not necessary to instantiate a MessageLoop. Instead, it // is typical to make use of the current thread's MessageLoop instance. - explicit MessageLoop(Type type = Type::DEFAULT); - // Creates a TYPE_CUSTOM MessageLoop with the supplied MessagePump, which must - // be non-NULL. + explicit MessageLoop(MessagePumpType type = MessagePump::Type::DEFAULT); + // Creates a MessageLoop with the supplied MessagePump, which must be + // non-null. explicit MessageLoop(std::unique_ptr<MessagePump> custom_pump); virtual ~MessageLoop(); @@ -106,12 +109,12 @@ // Set the timer slack for this message loop. void SetTimerSlack(TimerSlack timer_slack); - // Returns true if this loop is |type|. This allows subclasses (especially - // those in tests) to specialize how they are identified. - virtual bool IsType(Type type) const; + // Returns true if this loop's pump is |type|. This allows subclasses + // (especially those in tests) to specialize how they are identified. + virtual bool IsType(MessagePumpType type) const; // Returns the type passed to the constructor. - Type type() const { return type_; } + MessagePumpType type() const { return type_; } // Sets a new TaskRunner for this message loop. If the message loop was // already bound, this must be called on the thread to which it is bound. @@ -151,7 +154,7 @@ // specific type with a custom loop. The implementation does not call // BindToCurrentThread. If this constructor is invoked directly by a subclass, // then the subclass must subsequently bind the message loop. - MessageLoop(Type type, std::unique_ptr<MessagePump> pump); + MessageLoop(MessagePumpType type, std::unique_ptr<MessagePump> pump); // Configure various members and bind this message loop to the current thread. void BindToCurrentThread(); @@ -184,7 +187,7 @@ // thread the message loop runs on, before calling Run(). // Before BindToCurrentThread() is called, only Post*Task() functions can // be called on the message loop. - static std::unique_ptr<MessageLoop> CreateUnbound(Type type); + static std::unique_ptr<MessageLoop> CreateUnbound(MessagePumpType type); static std::unique_ptr<MessageLoop> CreateUnbound( std::unique_ptr<MessagePump> pump); @@ -197,7 +200,7 @@ return sequence_manager_.get(); } - const Type type_; + const MessagePumpType type_; // If set this will be returned by the next call to CreateMessagePump(). // This is only set if |type_| is TYPE_CUSTOM and |pump_| is null. @@ -228,7 +231,7 @@ // class BASE_EXPORT MessageLoopForUI : public MessageLoop { public: - explicit MessageLoopForUI(Type type = TYPE_UI); + explicit MessageLoopForUI(MessagePumpType type = MessagePump::Type::UI); #if defined(OS_IOS) // On iOS, the main message loop cannot be Run(). Instead call Attach(), @@ -278,7 +281,7 @@ // class BASE_EXPORT MessageLoopForIO : public MessageLoop { public: - MessageLoopForIO() : MessageLoop(TYPE_IO) {} + MessageLoopForIO() : MessageLoop(MessagePumpType::IO) {} }; // Do not add any member variables to MessageLoopForIO! This is important b/c
diff --git a/base/message_loop/message_loop_current.cc b/base/message_loop/message_loop_current.cc index 54e2d2b..7688ba3 100644 --- a/base/message_loop/message_loop_current.cc +++ b/base/message_loop/message_loop_current.cc
@@ -5,9 +5,9 @@ #include "base/message_loop/message_loop_current.h" #include "base/bind.h" -#include "base/message_loop/message_loop.h" #include "base/message_loop/message_pump_for_io.h" #include "base/message_loop/message_pump_for_ui.h" +#include "base/message_loop/message_pump_type.h" #include "base/no_destructor.h" #include "base/task/sequence_manager/sequence_manager_impl.h" #include "base/threading/thread_local.h" @@ -114,10 +114,10 @@ auto* sequence_manager = GetCurrentSequenceManagerImpl(); DCHECK(sequence_manager); #if defined(OS_ANDROID) - DCHECK(sequence_manager->IsType(MessageLoop::TYPE_UI) || - sequence_manager->IsType(MessageLoop::TYPE_JAVA)); + DCHECK(sequence_manager->IsType(MessagePumpType::UI) || + sequence_manager->IsType(MessagePumpType::JAVA)); #else // defined(OS_ANDROID) - DCHECK(sequence_manager->IsType(MessageLoop::TYPE_UI)); + DCHECK(sequence_manager->IsType(MessagePumpType::UI)); #endif // defined(OS_ANDROID) return MessageLoopCurrentForUI(sequence_manager); } @@ -128,10 +128,10 @@ GetCurrentSequenceManagerImpl(); return sequence_manager && #if defined(OS_ANDROID) - (sequence_manager->IsType(MessageLoop::TYPE_UI) || - sequence_manager->IsType(MessageLoop::TYPE_JAVA)); + (sequence_manager->IsType(MessagePumpType::UI) || + sequence_manager->IsType(MessagePumpType::JAVA)); #else // defined(OS_ANDROID) - sequence_manager->IsType(MessageLoop::TYPE_UI); + sequence_manager->IsType(MessagePumpType::UI); #endif // defined(OS_ANDROID) } @@ -185,14 +185,14 @@ MessageLoopCurrentForIO MessageLoopCurrentForIO::Get() { auto* sequence_manager = GetCurrentSequenceManagerImpl(); DCHECK(sequence_manager); - DCHECK(sequence_manager->IsType(MessageLoop::TYPE_IO)); + DCHECK(sequence_manager->IsType(MessagePumpType::IO)); return MessageLoopCurrentForIO(sequence_manager); } // static bool MessageLoopCurrentForIO::IsSet() { auto* sequence_manager = GetCurrentSequenceManagerImpl(); - return sequence_manager && sequence_manager->IsType(MessageLoop::TYPE_IO); + return sequence_manager && sequence_manager->IsType(MessagePumpType::IO); } MessagePumpForIO* MessageLoopCurrentForIO::GetMessagePumpForIO() const {
diff --git a/base/message_loop/message_loop_unittest.cc b/base/message_loop/message_loop_unittest.cc index 3ada124..9f2e58d 100644 --- a/base/message_loop/message_loop_unittest.cc +++ b/base/message_loop/message_loop_unittest.cc
@@ -16,6 +16,7 @@ #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop_current.h" #include "base/message_loop/message_pump_for_io.h" +#include "base/message_loop/message_pump_type.h" #include "base/pending_task.h" #include "base/posix/eintr_wrapper.h" #include "base/run_loop.h" @@ -423,7 +424,7 @@ Thread thread("IOHandler test"); Thread::Options options; - options.message_loop_type = MessageLoop::TYPE_IO; + options.message_pump_type = MessagePumpType::IO; ASSERT_TRUE(thread.StartWithOptions(options)); TestIOHandler handler(kPipeName, callback_called.Get(), false); @@ -459,7 +460,7 @@ Thread thread("IOHandler test"); Thread::Options options; - options.message_loop_type = MessageLoop::TYPE_IO; + options.message_pump_type = MessagePumpType::IO; ASSERT_TRUE(thread.StartWithOptions(options)); TestIOHandler handler1(kPipeName1, callback1_called.Get(), false); @@ -503,33 +504,32 @@ // that message loops work properly in all configurations. Of course, in some // cases, a unit test may only be for a particular type of loop. -class MessageLoopTypedTest - : public ::testing::TestWithParam<MessageLoop::Type> { +class MessageLoopTypedTest : public ::testing::TestWithParam<MessagePumpType> { public: MessageLoopTypedTest() = default; ~MessageLoopTypedTest() = default; static std::string ParamInfoToString( - ::testing::TestParamInfo<MessageLoop::Type> param_info) { + ::testing::TestParamInfo<MessagePumpType> param_info) { switch (param_info.param) { - case MessageLoop::TYPE_DEFAULT: + case MessagePumpType::DEFAULT: return "default_pump"; - case MessageLoop::TYPE_IO: + case MessagePumpType::IO: return "IO_pump"; - case MessageLoop::TYPE_UI: + case MessagePumpType::UI: return "UI_pump"; - case MessageLoop::TYPE_CUSTOM: + case MessagePumpType::CUSTOM: break; #if defined(OS_ANDROID) - case MessageLoop::TYPE_JAVA: + case MessagePumpType::JAVA: break; #endif // defined(OS_ANDROID) #if defined(OS_MACOSX) - case MessagePump::Type::NS_RUNLOOP: + case MessagePumpType::NS_RUNLOOP: break; #endif // defined(OS_MACOSX) #if defined(OS_WIN) - case MessagePump::Type::UI_WITH_WM_QUIT_SUPPORT: + case MessagePumpType::UI_WITH_WM_QUIT_SUPPORT: break; #endif // defined(OS_WIN) } @@ -1471,9 +1471,9 @@ INSTANTIATE_TEST_SUITE_P(, MessageLoopTypedTest, - ::testing::Values(MessageLoop::TYPE_DEFAULT, - MessageLoop::TYPE_UI, - MessageLoop::TYPE_IO), + ::testing::Values(MessagePumpType::DEFAULT, + MessagePumpType::UI, + MessagePumpType::IO), MessageLoopTypedTest::ParamInfoToString); #if defined(OS_WIN) @@ -1482,7 +1482,7 @@ // Users of MessageLoop typically expect to control when their RunLoops stop // Run()ning explicitly, via QuitClosure() etc (see https://crbug.com/720078). TEST_F(MessageLoopTest, WmQuitIsIgnored) { - MessageLoop loop(MessageLoop::TYPE_UI); + MessageLoop loop(MessagePumpType::UI); // Post a WM_QUIT message to the current thread. ::PostQuitMessage(0); @@ -1507,7 +1507,7 @@ } TEST_F(MessageLoopTest, WmQuitIsNotIgnoredWithEnableWmQuit) { - MessageLoop loop(MessageLoop::TYPE_UI); + MessageLoop loop(MessagePumpType::UI); static_cast<MessageLoopForUI*>(&loop)->EnableWmQuit(); // Post a WM_QUIT message to the current thread. @@ -1530,7 +1530,7 @@ } TEST_F(MessageLoopTest, PostDelayedTask_SharedTimer_SubPump) { - MessageLoop message_loop(MessageLoop::TYPE_UI); + MessageLoop message_loop(MessagePumpType::UI); // Test that the interval of the timer, used to run the next delayed task, is // set to a value corresponding to when the next delayed task should run. @@ -1608,7 +1608,7 @@ // https://crrev.com/c/1455266/9/base/message_loop/message_pump_win.cc#125 // See below for the delayed task version. TEST_F(MessageLoopTest, PostImmediateTaskFromSystemPump) { - MessageLoop message_loop(MessageLoop::TYPE_UI); + MessageLoop message_loop(MessagePumpType::UI); RunLoop run_loop; @@ -1633,7 +1633,7 @@ // is the delayed task equivalent of the above PostImmediateTaskFromSystemPump // test. TEST_F(MessageLoopTest, PostDelayedTaskFromSystemPump) { - MessageLoop message_loop(MessageLoop::TYPE_UI); + MessageLoop message_loop(MessagePumpType::UI); RunLoop run_loop; @@ -1654,7 +1654,7 @@ } TEST_F(MessageLoopTest, WmQuitIsVisibleToSubPump) { - MessageLoop message_loop(MessageLoop::TYPE_UI); + MessageLoop message_loop(MessagePumpType::UI); // Regression test for https://crbug.com/888559. When processing a // kMsgHaveWork we peek and remove the next message and dispatch that ourself, @@ -1688,7 +1688,7 @@ } TEST_F(MessageLoopTest, RepostingWmQuitDoesntStarveUpcomingNativeLoop) { - MessageLoop message_loop(MessageLoop::TYPE_UI); + MessageLoop message_loop(MessagePumpType::UI); // This test ensures that application tasks are being processed by the native // subpump despite the kMsgHaveWork event having already been consumed by the @@ -1731,7 +1731,7 @@ // works. TEST_F(MessageLoopTest, DISABLED_UnwindingMultipleSubPumpsDoesntStarveApplicationTasks) { - MessageLoop message_loop(MessageLoop::TYPE_UI); + MessageLoop message_loop(MessagePumpType::UI); // Regression test for https://crbug.com/890016. // Tests that the subpump is still processing application tasks after @@ -1777,12 +1777,12 @@ namespace { // A side effect of this test is the generation a beep. Sorry. -void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) { - MessageLoop loop(message_loop_type); +void RunTest_RecursiveDenial2(MessagePumpType message_pump_type) { + MessageLoop loop(message_pump_type); Thread worker("RecursiveDenial2_worker"); Thread::Options options; - options.message_loop_type = message_loop_type; + options.message_pump_type = message_pump_type; ASSERT_EQ(true, worker.StartWithOptions(options)); TaskList order; win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL)); @@ -1819,19 +1819,19 @@ // This test occasionally hangs. See http://crbug.com/44567. TEST_F(MessageLoopTest, DISABLED_RecursiveDenial2) { - RunTest_RecursiveDenial2(MessageLoop::TYPE_DEFAULT); - RunTest_RecursiveDenial2(MessageLoop::TYPE_UI); - RunTest_RecursiveDenial2(MessageLoop::TYPE_IO); + RunTest_RecursiveDenial2(MessagePumpType::DEFAULT); + RunTest_RecursiveDenial2(MessagePumpType::UI); + RunTest_RecursiveDenial2(MessagePumpType::IO); } // A side effect of this test is the generation a beep. Sorry. This test also // needs to process windows messages on the current thread. TEST_F(MessageLoopTest, RecursiveSupport2) { - MessageLoop loop(MessageLoop::TYPE_UI); + MessageLoop loop(MessagePumpType::UI); Thread worker("RecursiveSupport2_worker"); Thread::Options options; - options.message_loop_type = MessageLoop::TYPE_UI; + options.message_pump_type = MessagePumpType::UI; ASSERT_EQ(true, worker.StartWithOptions(options)); TaskList order; win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL)); @@ -2032,10 +2032,10 @@ } TEST_F(MessageLoopTest, IsType) { - MessageLoop loop(MessageLoop::TYPE_UI); - EXPECT_TRUE(loop.IsType(MessageLoop::TYPE_UI)); - EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_IO)); - EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_DEFAULT)); + MessageLoop loop(MessagePumpType::UI); + EXPECT_TRUE(loop.IsType(MessagePumpType::UI)); + EXPECT_FALSE(loop.IsType(MessagePumpType::IO)); + EXPECT_FALSE(loop.IsType(MessagePumpType::DEFAULT)); } #if defined(OS_WIN) @@ -2110,7 +2110,7 @@ } TEST_F(MessageLoopTest, AlwaysHaveUserMessageWhenNesting) { - MessageLoop loop(MessageLoop::TYPE_UI); + MessageLoop loop(MessagePumpType::UI); HINSTANCE instance = CURRENT_MODULE(); WNDCLASSEX wc = {0}; wc.cbSize = sizeof(wc); @@ -2158,7 +2158,7 @@ // already has another active loop. This happens when thread creation fails. MessageLoop loop; std::unique_ptr<MessageLoop> unbound_loop( - MessageLoop::CreateUnbound(MessageLoop::TYPE_DEFAULT)); + MessageLoop::CreateUnbound(MessagePumpType::DEFAULT)); unbound_loop.reset(); EXPECT_TRUE(loop.task_runner()->RunsTasksInCurrentSequence()); EXPECT_EQ(loop.task_runner(), ThreadTaskRunnerHandle::Get());
diff --git a/base/message_loop/message_pump.cc b/base/message_loop/message_pump.cc index a3e119e..877ba35 100644 --- a/base/message_loop/message_pump.cc +++ b/base/message_loop/message_pump.cc
@@ -39,9 +39,9 @@ } // static -std::unique_ptr<MessagePump> MessagePump::Create(Type type) { +std::unique_ptr<MessagePump> MessagePump::Create(MessagePumpType type) { switch (type) { - case Type::UI: + case MessagePumpType::UI: if (message_pump_for_ui_factory_) return message_pump_for_ui_factory_(); #if defined(OS_IOS) || defined(OS_MACOSX) @@ -55,32 +55,32 @@ return std::make_unique<MessagePumpForUI>(); #endif - case Type::IO: + case MessagePumpType::IO: return std::make_unique<MessagePumpForIO>(); #if defined(OS_ANDROID) - case Type::JAVA: + case MessagePumpType::JAVA: return std::make_unique<MessagePumpForUI>(); #endif #if defined(OS_MACOSX) - case Type::NS_RUNLOOP: + case MessagePumpType::NS_RUNLOOP: return std::make_unique<MessagePumpNSRunLoop>(); #endif #if defined(OS_WIN) - case Type::UI_WITH_WM_QUIT_SUPPORT: { + case MessagePumpType::UI_WITH_WM_QUIT_SUPPORT: { auto pump = std::make_unique<MessagePumpForUI>(); pump->EnableWmQuit(); return pump; } #endif // defined(OS_WIN) - case Type::CUSTOM: + case MessagePumpType::CUSTOM: NOTREACHED(); return nullptr; - case Type::DEFAULT: + case MessagePumpType::DEFAULT: #if defined(OS_IOS) // On iOS, a native runloop is always required to pump system work. return std::make_unique<MessagePumpCFRunLoop>();
diff --git a/base/message_loop/message_pump.h b/base/message_loop/message_pump.h index 082c75d..db1c77e 100644 --- a/base/message_loop/message_pump.h +++ b/base/message_loop/message_pump.h
@@ -7,6 +7,7 @@ #include "base/base_export.h" #include "base/logging.h" +#include "base/message_loop/message_pump_type.h" #include "base/message_loop/timer_slack.h" #include "base/sequence_checker.h" #include "base/time/time.h" @@ -18,47 +19,8 @@ class BASE_EXPORT MessagePump { public: - // A MessagePump has a particular type, which indicates the set of - // asynchronous events it may process in addition to tasks and timers. - // - // TYPE_DEFAULT - // This type of pump only supports tasks and timers. - // - // TYPE_UI - // This type of pump also supports native UI events (e.g., Windows - // messages). - // - // TYPE_IO - // This type of pump also supports asynchronous IO. - // - // TYPE_JAVA - // This type of pump is backed by a Java message handler which is - // responsible for running the tasks added to the ML. This is only for use - // on Android. TYPE_JAVA behaves in essence like TYPE_UI, except during - // construction where it does not use the main thread specific pump factory. - // - // TYPE_NS_RUNLOOP - // This type of pump is backed by a NSRunLoop. This is only for use on - // OSX and IOS. - // - // UI_WITH_WM_QUIT_SUPPORT - // This type of pump supports WM_QUIT messages in addition to other native - // UI events. This is only for use on windows. - enum class Type { - DEFAULT, - UI, - CUSTOM, - IO, -#if defined(OS_ANDROID) - JAVA, -#endif // defined(OS_ANDROID) -#if defined(OS_MACOSX) - NS_RUNLOOP, -#endif // defined(OS_MACOSX) -#if defined(OS_WIN) - UI_WITH_WM_QUIT_SUPPORT, -#endif // defined(OS_WIN) - }; + // DEPRECATED: Use MessagePumpType instead. + using Type = MessagePumpType; using MessagePumpFactory = std::unique_ptr<MessagePump>(); // Uses the given base::MessagePumpFactory to override the default MessagePump @@ -69,7 +31,7 @@ static bool IsMessagePumpForUIFactoryOveridden(); // Creates the default MessagePump based on |type|. Caller owns return value. - static std::unique_ptr<MessagePump> Create(Type type); + static std::unique_ptr<MessagePump> Create(MessagePumpType type); // Please see the comments above the Run method for an illustration of how // these delegate methods are used.
diff --git a/base/message_loop/message_pump_glib_unittest.cc b/base/message_loop/message_pump_glib_unittest.cc index 512cea6..e3cbc83 100644 --- a/base/message_loop/message_pump_glib_unittest.cc +++ b/base/message_loop/message_pump_glib_unittest.cc
@@ -17,6 +17,7 @@ #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop_current.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread.h" @@ -161,7 +162,7 @@ // Overridden from testing::Test: void SetUp() override { - loop_ = new MessageLoop(MessageLoop::TYPE_UI); + loop_ = new MessageLoop(MessagePumpType::UI); injector_ = new EventInjector(); } void TearDown() override {
diff --git a/base/message_loop/message_pump_libevent_unittest.cc b/base/message_loop/message_pump_libevent_unittest.cc index 1547af29..4508347 100644 --- a/base/message_loop/message_pump_libevent_unittest.cc +++ b/base/message_loop/message_pump_libevent_unittest.cc
@@ -14,6 +14,7 @@ #include "base/files/file_util.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/posix/eintr_wrapper.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -32,12 +33,12 @@ class MessagePumpLibeventTest : public testing::Test { protected: MessagePumpLibeventTest() - : ui_loop_(new MessageLoop(MessageLoop::TYPE_UI)), + : ui_loop_(new MessageLoop(MessagePumpType::UI)), io_thread_("MessagePumpLibeventTestIOThread") {} ~MessagePumpLibeventTest() override = default; void SetUp() override { - Thread::Options options(MessageLoop::TYPE_IO, 0); + Thread::Options options(MessagePumpType::IO, 0); ASSERT_TRUE(io_thread_.StartWithOptions(options)); int ret = pipe(pipefds_); ASSERT_EQ(0, ret);
diff --git a/base/message_loop/message_pump_perftest.cc b/base/message_loop/message_pump_perftest.cc index 271e9035dd..d70b46c 100644 --- a/base/message_loop/message_pump_perftest.cc +++ b/base/message_loop/message_pump_perftest.cc
@@ -11,6 +11,7 @@ #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop_current.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" #include "base/synchronization/condition_variable.h" @@ -86,9 +87,9 @@ base::Unretained(this), schedule_calls)); } - void ScheduleWork(MessageLoop::Type target_type, int num_scheduling_threads) { + void ScheduleWork(MessagePumpType target_type, int num_scheduling_threads) { #if defined(OS_ANDROID) - if (target_type == MessageLoop::TYPE_JAVA) { + if (target_type == MessagePumpType::JAVA) { java_thread_.reset(new JavaHandlerThreadForTest("target")); java_thread_->Start(); } else @@ -134,7 +135,7 @@ scheduling_threads[i]->Stop(); } #if defined(OS_ANDROID) - if (target_type == MessageLoop::TYPE_JAVA) { + if (target_type == MessagePumpType::JAVA) { java_thread_->Stop(); java_thread_.reset(); } else @@ -154,11 +155,10 @@ max_batch_time = std::max(max_batch_time, max_batch_times_[i]); } std::string trace = StringPrintf( - "%d_threads_scheduling_to_%s_pump", - num_scheduling_threads, - target_type == MessageLoop::TYPE_IO + "%d_threads_scheduling_to_%s_pump", num_scheduling_threads, + target_type == MessagePumpType::IO ? "io" - : (target_type == MessageLoop::TYPE_UI ? "ui" : "default")); + : (target_type == MessagePumpType::UI ? "ui" : "default")); perf_test::PrintResult( "task", "", @@ -218,52 +218,52 @@ }; TEST_F(ScheduleWorkTest, ThreadTimeToIOFromOneThread) { - ScheduleWork(MessageLoop::TYPE_IO, 1); + ScheduleWork(MessagePumpType::IO, 1); } TEST_F(ScheduleWorkTest, ThreadTimeToIOFromTwoThreads) { - ScheduleWork(MessageLoop::TYPE_IO, 2); + ScheduleWork(MessagePumpType::IO, 2); } TEST_F(ScheduleWorkTest, ThreadTimeToIOFromFourThreads) { - ScheduleWork(MessageLoop::TYPE_IO, 4); + ScheduleWork(MessagePumpType::IO, 4); } TEST_F(ScheduleWorkTest, ThreadTimeToUIFromOneThread) { - ScheduleWork(MessageLoop::TYPE_UI, 1); + ScheduleWork(MessagePumpType::UI, 1); } TEST_F(ScheduleWorkTest, ThreadTimeToUIFromTwoThreads) { - ScheduleWork(MessageLoop::TYPE_UI, 2); + ScheduleWork(MessagePumpType::UI, 2); } TEST_F(ScheduleWorkTest, ThreadTimeToUIFromFourThreads) { - ScheduleWork(MessageLoop::TYPE_UI, 4); + ScheduleWork(MessagePumpType::UI, 4); } TEST_F(ScheduleWorkTest, ThreadTimeToDefaultFromOneThread) { - ScheduleWork(MessageLoop::TYPE_DEFAULT, 1); + ScheduleWork(MessagePumpType::DEFAULT, 1); } TEST_F(ScheduleWorkTest, ThreadTimeToDefaultFromTwoThreads) { - ScheduleWork(MessageLoop::TYPE_DEFAULT, 2); + ScheduleWork(MessagePumpType::DEFAULT, 2); } TEST_F(ScheduleWorkTest, ThreadTimeToDefaultFromFourThreads) { - ScheduleWork(MessageLoop::TYPE_DEFAULT, 4); + ScheduleWork(MessagePumpType::DEFAULT, 4); } #if defined(OS_ANDROID) TEST_F(ScheduleWorkTest, ThreadTimeToJavaFromOneThread) { - ScheduleWork(MessageLoop::TYPE_JAVA, 1); + ScheduleWork(MessagePumpType::JAVA, 1); } TEST_F(ScheduleWorkTest, ThreadTimeToJavaFromTwoThreads) { - ScheduleWork(MessageLoop::TYPE_JAVA, 2); + ScheduleWork(MessagePumpType::JAVA, 2); } TEST_F(ScheduleWorkTest, ThreadTimeToJavaFromFourThreads) { - ScheduleWork(MessageLoop::TYPE_JAVA, 4); + ScheduleWork(MessagePumpType::JAVA, 4); } #endif
diff --git a/base/message_loop/message_pump_type.h b/base/message_loop/message_pump_type.h new file mode 100644 index 0000000..41db010 --- /dev/null +++ b/base/message_loop/message_pump_type.h
@@ -0,0 +1,52 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_TYPE_H_ +#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_TYPE_H_ + +#include "build/build_config.h" + +namespace base { + +// A MessagePump has a particular type, which indicates the set of +// asynchronous events it may process in addition to tasks and timers. + +enum class MessagePumpType { + // This type of pump only supports tasks and timers. + DEFAULT, + + // This type of pump also supports native UI events (e.g., Windows + // messages). + UI, + + // User provided implementation of MessagePump interface + CUSTOM, + + // This type of pump also supports asynchronous IO. + IO, + +#if defined(OS_ANDROID) + // This type of pump is backed by a Java message handler which is + // responsible for running the tasks added to the ML. This is only for use + // on Android. TYPE_JAVA behaves in essence like TYPE_UI, except during + // construction where it does not use the main thread specific pump factory. + JAVA, +#endif // defined(OS_ANDROID) + +#if defined(OS_MACOSX) + // This type of pump is backed by a NSRunLoop. This is only for use on + // OSX and IOS. + NS_RUNLOOP, +#endif // defined(OS_MACOSX) + +#if defined(OS_WIN) + // This type of pump supports WM_QUIT messages in addition to other native + // UI events. This is only for use on windows. + UI_WITH_WM_QUIT_SUPPORT, +#endif // defined(OS_WIN) +}; + +} // namespace base + +#endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_TYPE_H_
diff --git a/base/message_loop/message_pump_unittest.cc b/base/message_loop/message_pump_unittest.cc index e7397cd6..2b6fc56 100644 --- a/base/message_loop/message_pump_unittest.cc +++ b/base/message_loop/message_pump_unittest.cc
@@ -10,6 +10,7 @@ #include "base/message_loop/message_loop.h" #include "base/message_loop/message_pump_for_io.h" #include "base/message_loop/message_pump_for_ui.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/task/single_thread_task_executor.h" #include "base/test/bind_test_util.h" @@ -32,9 +33,9 @@ namespace { -bool PumpTypeUsesDoSomeWork(MessageLoop::Type type) { +bool PumpTypeUsesDoSomeWork(MessagePumpType type) { switch (type) { - case MessagePump::Type::DEFAULT: + case MessagePumpType::DEFAULT: #if defined(OS_IOS) // iOS uses a MessagePumpCFRunLoop instead of MessagePumpDefault for // TYPE_DEFAULT. TODO(gab): migrate MessagePumpCFRunLoop too. @@ -43,7 +44,7 @@ return true; #endif - case MessagePump::Type::UI: + case MessagePumpType::UI: #if defined(OS_IOS) // iOS uses a MessagePumpDefault for UI in unit tests, ref. // test_support_ios.mm::CreateMessagePumpForUIForTests(). @@ -60,7 +61,7 @@ return false; #endif - case MessagePump::Type::IO: + case MessagePumpType::IO: #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS)) return true; #elif defined(OS_POSIX) && !defined(OS_NACL_SFI) @@ -73,15 +74,15 @@ return false; #endif - case MessagePump::Type::CUSTOM: + case MessagePumpType::CUSTOM: #if defined(OS_ANDROID) - case MessagePump::Type::JAVA: + case MessagePumpType::JAVA: #endif // defined(OS_ANDROID) #if defined(OS_MACOSX) - case MessagePump::Type::NS_RUNLOOP: + case MessagePumpType::NS_RUNLOOP: #endif // defined(OS_MACOSX) #if defined(OS_WIN) - case MessagePump::Type::UI_WITH_WM_QUIT_SUPPORT: + case MessagePumpType::UI_WITH_WM_QUIT_SUPPORT: #endif // defined(OS_WIN) // Not tested in this file. NOTREACHED(); @@ -106,7 +107,7 @@ DISALLOW_COPY_AND_ASSIGN(MockMessagePumpDelegate); }; -class MessagePumpTest : public ::testing::TestWithParam<MessageLoop::Type> { +class MessagePumpTest : public ::testing::TestWithParam<MessagePumpType> { public: MessagePumpTest() : message_pump_(MessagePump::Create(GetParam())) {} @@ -357,15 +358,15 @@ INSTANTIATE_TEST_SUITE_P(, MessagePumpTest, - ::testing::Values(MessageLoop::TYPE_DEFAULT, - MessageLoop::TYPE_UI, - MessageLoop::TYPE_IO)); + ::testing::Values(MessagePumpType::DEFAULT, + MessagePumpType::UI, + MessagePumpType::IO)); #if defined(OS_WIN) TEST(MessagePumpTestWin, WmQuitIsNotIgnoredWithEnableWmQuit) { SingleThreadTaskExecutor task_executor( - MessagePump::Type::UI_WITH_WM_QUIT_SUPPORT); + MessagePumpType::UI_WITH_WM_QUIT_SUPPORT); // Post a WM_QUIT message to the current thread. ::PostQuitMessage(0);
diff --git a/base/synchronization/waitable_event.h b/base/synchronization/waitable_event.h index c89f575c..a65c725 100644 --- a/base/synchronization/waitable_event.h +++ b/base/synchronization/waitable_event.h
@@ -34,7 +34,6 @@ namespace base { class TimeDelta; -class TimeTicks; // A WaitableEvent can be a useful thread synchronization tool when you want to // allow one thread to wait for another thread to finish some work. For @@ -98,17 +97,12 @@ void Wait(); // Wait up until wait_delta has passed for the event to be signaled. Returns - // true if the event was signaled. + // true if the event was signaled. Handles spurious wakeups and guarantees + // that |wait_delta| will have elapsed if this returns false. // // TimedWait can synchronise its own destruction like |Wait|. bool TimedWait(const TimeDelta& wait_delta); - // Wait up until end_time deadline has passed for the event to be signaled. - // Return true if the event was signaled. - // - // TimedWaitUntil can synchronise its own destruction like |Wait|. - bool TimedWaitUntil(const TimeTicks& end_time); - #if defined(OS_WIN) HANDLE handle() const { return handle_.Get(); } #endif
diff --git a/base/synchronization/waitable_event_mac.cc b/base/synchronization/waitable_event_mac.cc index db829954..ee601bb 100644 --- a/base/synchronization/waitable_event_mac.cc +++ b/base/synchronization/waitable_event_mac.cc
@@ -18,6 +18,7 @@ #include "base/posix/eintr_wrapper.h" #include "base/threading/scoped_blocking_call.h" #include "base/threading/thread_restrictions.h" +#include "base/time/time.h" #include "build/build_config.h" namespace base { @@ -103,15 +104,14 @@ } void WaitableEvent::Wait() { - bool result = TimedWaitUntil(TimeTicks::Max()); + bool result = TimedWait(TimeDelta::Max()); DCHECK(result) << "TimedWait() should never fail with infinite timeout"; } bool WaitableEvent::TimedWait(const TimeDelta& wait_delta) { - return TimedWaitUntil(TimeTicks::Now() + wait_delta); -} + if (wait_delta <= TimeDelta()) + return IsSignaled(); -bool WaitableEvent::TimedWaitUntil(const TimeTicks& end_time) { // Record the event that this thread is blocking upon (for hang diagnosis) and // consider blocked for scheduling purposes. Ignore this for non-blocking // WaitableEvents. @@ -128,7 +128,7 @@ mach_msg_option_t options = MACH_RCV_MSG; - if (!end_time.is_max()) + if (!wait_delta.is_max()) options |= MACH_RCV_TIMEOUT | MACH_RCV_INTERRUPT; mach_msg_size_t rcv_size = sizeof(msg); @@ -139,21 +139,32 @@ rcv_size = 0; } - kern_return_t kr; - mach_msg_timeout_t timeout = MACH_MSG_TIMEOUT_NONE; - do { - if (!end_time.is_max()) { - timeout = std::max<int64_t>( - 0, (end_time - TimeTicks::Now()).InMillisecondsRoundedUp()); - } + // TimeTicks takes care of overflow but we special case is_max() nonetheless + // to avoid invoking Now() unnecessarily (same for the increment step of the + // for loop if the condition variable returns early). + // Ref: https://crbug.com/910524#c7 + const TimeTicks end_time = + wait_delta.is_max() ? TimeTicks::Max() : TimeTicks::Now() + wait_delta; + // Fake |kr| value to boostrap the for loop. + kern_return_t kr = MACH_RCV_INTERRUPTED; + for (mach_msg_timeout_t timeout = wait_delta.is_max() + ? MACH_MSG_TIMEOUT_NONE + : wait_delta.InMillisecondsRoundedUp(); + // If the thread is interrupted during mach_msg(), the system call will + // be restarted. However, the libsyscall wrapper does not adjust the + // timeout by the amount of time already waited. Using MACH_RCV_INTERRUPT + // will instead return from mach_msg(), so that the call can be retried + // with an adjusted timeout. + kr == MACH_RCV_INTERRUPTED; + timeout = + end_time.is_max() + ? MACH_MSG_TIMEOUT_NONE + : std::max<int64_t>( + 0, + (end_time - TimeTicks::Now()).InMillisecondsRoundedUp())) { kr = mach_msg(&msg.header, options, 0, rcv_size, receive_right_->Name(), timeout, MACH_PORT_NULL); - // If the thread is interrupted during mach_msg(), the system call - // will be restarted. However, the libsyscall wrapper does not adjust - // the timeout by the amount of time already waited. - // Using MACH_RCV_INTERRUPT will instead return from mach_msg(), - // so that the call can be retried with an adjusted timeout. - } while (kr == MACH_RCV_INTERRUPTED); + } if (kr == KERN_SUCCESS) { return true;
diff --git a/base/synchronization/waitable_event_perftest.cc b/base/synchronization/waitable_event_perftest.cc index 85dc9557..894573a 100644 --- a/base/synchronization/waitable_event_perftest.cc +++ b/base/synchronization/waitable_event_perftest.cc
@@ -37,7 +37,7 @@ bool TimedWaitUntil(const TimeTicks& end_time) { ElapsedTimer timer; - const bool signaled = event_.TimedWaitUntil(end_time); + const bool signaled = event_.TimedWait(end_time - timer.Begin()); total_wait_time_ += timer.Elapsed(); ++wait_samples_; return signaled;
diff --git a/base/synchronization/waitable_event_posix.cc b/base/synchronization/waitable_event_posix.cc index fa9fcf2c..d89e3a27 100644 --- a/base/synchronization/waitable_event_posix.cc +++ b/base/synchronization/waitable_event_posix.cc
@@ -16,6 +16,7 @@ #include "base/synchronization/waitable_event.h" #include "base/threading/scoped_blocking_call.h" #include "base/threading/thread_restrictions.h" +#include "base/time/time.h" // ----------------------------------------------------------------------------- // A WaitableEvent on POSIX is implemented as a wait-list. Currently we don't @@ -152,17 +153,14 @@ }; void WaitableEvent::Wait() { - bool result = TimedWaitUntil(TimeTicks::Max()); + bool result = TimedWait(TimeDelta::Max()); DCHECK(result) << "TimedWait() should never fail with infinite timeout"; } bool WaitableEvent::TimedWait(const TimeDelta& wait_delta) { - // TimeTicks takes care of overflow including the cases when wait_delta - // is a maximum value. - return TimedWaitUntil(TimeTicks::Now() + wait_delta); -} + if (wait_delta <= TimeDelta()) + return IsSignaled(); -bool WaitableEvent::TimedWaitUntil(const TimeTicks& end_time) { // Record the event that this thread is blocking upon (for hang diagnosis) and // consider it blocked for scheduling purposes. Ignore this for non-blocking // WaitableEvents. @@ -174,8 +172,6 @@ scoped_blocking_call.emplace(BlockingType::MAY_BLOCK); } - const bool finite_time = !end_time.is_max(); - kernel_->lock_.Acquire(); if (kernel_->signaled_) { if (!kernel_->manual_reset_) { @@ -196,45 +192,45 @@ Enqueue(&sw); kernel_->lock_.Release(); // We are violating locking order here by holding the SyncWaiter lock but not - // the WaitableEvent lock. However, this is safe because we don't lock @lock_ + // the WaitableEvent lock. However, this is safe because we don't lock |lock_| // again before unlocking it. - for (;;) { - // Only sample Now() if waiting for a |finite_time|. - Optional<TimeTicks> current_time; - if (finite_time) - current_time = TimeTicks::Now(); - - if (sw.fired() || (finite_time && *current_time >= end_time)) { - const bool return_value = sw.fired(); - - // We can't acquire @lock_ before releasing the SyncWaiter lock (because - // of locking order), however, in between the two a signal could be fired - // and @sw would accept it, however we will still return false, so the - // signal would be lost on an auto-reset WaitableEvent. Thus we call - // Disable which makes sw::Fire return false. - sw.Disable(); - sw.lock()->Release(); - - // This is a bug that has been enshrined in the interface of - // WaitableEvent now: |Dequeue| is called even when |sw.fired()| is true, - // even though it'll always return false in that case. However, taking - // the lock ensures that |Signal| has completed before we return and - // means that a WaitableEvent can synchronise its own destruction. - kernel_->lock_.Acquire(); - kernel_->Dequeue(&sw, &sw); - kernel_->lock_.Release(); - - return return_value; - } - - if (finite_time) { - const TimeDelta max_wait(end_time - *current_time); - sw.cv()->TimedWait(max_wait); - } else { + // TimeTicks takes care of overflow but we special case is_max() nonetheless + // to avoid invoking Now() unnecessarily (same for the increment step of the + // for loop if the condition variable returns early). + // Ref: https://crbug.com/910524#c7 + const TimeTicks end_time = + wait_delta.is_max() ? TimeTicks::Max() : TimeTicks::Now() + wait_delta; + for (TimeDelta remaining = wait_delta; remaining > TimeDelta() && !sw.fired(); + remaining = end_time.is_max() ? TimeDelta::Max() + : end_time - TimeTicks::Now()) { + if (end_time.is_max()) sw.cv()->Wait(); - } + else + sw.cv()->TimedWait(remaining); } + + // Get the SyncWaiter signaled state before releasing the lock. + const bool return_value = sw.fired(); + + // We can't acquire |lock_| before releasing the SyncWaiter lock (because of + // locking order), however, in between the two a signal could be fired and + // |sw| would accept it, however we will still return false, so the signal + // would be lost on an auto-reset WaitableEvent. Thus we call Disable which + // makes sw::Fire return false. + sw.Disable(); + sw.lock()->Release(); + + // This is a bug that has been enshrined in the interface of WaitableEvent + // now: |Dequeue| is called even when |sw.fired()| is true, even though it'll + // always return false in that case. However, taking the lock ensures that + // |Signal| has completed before we return and means that a WaitableEvent can + // synchronise its own destruction. + kernel_->lock_.Acquire(); + kernel_->Dequeue(&sw, &sw); + kernel_->lock_.Release(); + + return return_value; } // -----------------------------------------------------------------------------
diff --git a/base/synchronization/waitable_event_unittest.cc b/base/synchronization/waitable_event_unittest.cc index 07323d5..0e982202 100644 --- a/base/synchronization/waitable_event_unittest.cc +++ b/base/synchronization/waitable_event_unittest.cc
@@ -235,40 +235,31 @@ EXPECT_GE(TimeTicks::Now() - start_time, delay); } -// Tests that TimedWaitUntil can be safely used with various end_time deadline -// values. -TEST(WaitableEventTest, TimedWaitUntil) { - WaitableEvent ev(WaitableEvent::ResetPolicy::AUTOMATIC, - WaitableEvent::InitialState::NOT_SIGNALED); +// Tests that timeouts of zero return immediately (true if already signaled, +// false otherwise). +TEST(WaitableEventTest, ZeroTimeout) { + WaitableEvent ev; + TimeTicks start_time = TimeTicks::Now(); + EXPECT_FALSE(ev.TimedWait(TimeDelta())); + EXPECT_LT(TimeTicks::Now() - start_time, TimeDelta::FromMilliseconds(1)); - TimeTicks start_time(TimeTicks::Now()); - TimeDelta delay = TimeDelta::FromMilliseconds(10); - - // Should be OK to wait for the current time or time in the past. - // That should end promptly and be equivalent to IsSignalled. - EXPECT_FALSE(ev.TimedWaitUntil(start_time)); - EXPECT_FALSE(ev.TimedWaitUntil(start_time - delay)); - - // Should be OK to wait for zero TimeTicks(). - EXPECT_FALSE(ev.TimedWaitUntil(TimeTicks())); - - // Waiting for a time in the future shouldn't end before the deadline - // if the event isn't signalled. - EXPECT_FALSE(ev.TimedWaitUntil(start_time + delay)); - EXPECT_GE(TimeTicks::Now() - start_time, delay); - - // Test that passing TimeTicks::Max to TimedWaitUntil is valid and isn't - // the same as passing TimeTicks(). Also verifies that signaling event - // ends the wait promptly. - WaitableEventSignaler signaler(delay, &ev); - PlatformThreadHandle thread; + ev.Signal(); start_time = TimeTicks::Now(); - PlatformThread::Create(0, &signaler, &thread); + EXPECT_TRUE(ev.TimedWait(TimeDelta())); + EXPECT_LT(TimeTicks::Now() - start_time, TimeDelta::FromMilliseconds(1)); +} - EXPECT_TRUE(ev.TimedWaitUntil(TimeTicks::Max())); - EXPECT_GE(TimeTicks::Now() - start_time, delay); +// Same as ZeroTimeout for negative timeouts. +TEST(WaitableEventTest, NegativeTimeout) { + WaitableEvent ev; + TimeTicks start_time = TimeTicks::Now(); + EXPECT_FALSE(ev.TimedWait(TimeDelta::FromMilliseconds(-10))); + EXPECT_LT(TimeTicks::Now() - start_time, TimeDelta::FromMilliseconds(1)); - PlatformThread::Join(thread); + ev.Signal(); + start_time = TimeTicks::Now(); + EXPECT_TRUE(ev.TimedWait(TimeDelta::FromMilliseconds(-10))); + EXPECT_LT(TimeTicks::Now() - start_time, TimeDelta::FromMilliseconds(1)); } } // namespace base
diff --git a/base/synchronization/waitable_event_win.cc b/base/synchronization/waitable_event_win.cc index 94e557ca..7c7fbf2 100644 --- a/base/synchronization/waitable_event_win.cc +++ b/base/synchronization/waitable_event_win.cc
@@ -72,22 +72,37 @@ DCHECK_EQ(WAIT_OBJECT_0, result); } -namespace { +bool WaitableEvent::TimedWait(const TimeDelta& wait_delta) { + if (wait_delta <= TimeDelta()) + return IsSignaled(); -// Helper function called from TimedWait and TimedWaitUntil. -bool WaitUntil(HANDLE handle, const TimeTicks& now, const TimeTicks& end_time) { - TimeDelta delta = end_time - now; - DCHECK_GT(delta, TimeDelta()); + // Record the event that this thread is blocking upon (for hang diagnosis) and + // consider it blocked for scheduling purposes. Ignore this for non-blocking + // WaitableEvents. + Optional<debug::ScopedEventWaitActivity> event_activity; + Optional<internal::ScopedBlockingCallWithBaseSyncPrimitives> + scoped_blocking_call; + if (waiting_is_blocking_) { + event_activity.emplace(this); + scoped_blocking_call.emplace(BlockingType::MAY_BLOCK); + } - do { - // On Windows, waiting for less than 1 ms results in WaitForSingleObject - // returning promptly which may result in the caller code spinning. - // We need to ensure that we specify at least the minimally possible 1 ms - // delay unless the initial timeout was exactly zero. - delta = std::max(delta, TimeDelta::FromMilliseconds(1)); - // Truncate the timeout to milliseconds. - DWORD timeout_ms = saturated_cast<DWORD>(delta.InMilliseconds()); - DWORD result = WaitForSingleObject(handle, timeout_ms); + // TimeTicks takes care of overflow but we special case is_max() nonetheless + // to avoid invoking Now() unnecessarily. + // WaitForSingleObject(handle_.Get(), INFINITE) doesn't spuriously wakeup so + // we don't need to worry about is_max() for the increment phase of the loop. + const TimeTicks end_time = + wait_delta.is_max() ? TimeTicks::Max() : TimeTicks::Now() + wait_delta; + for (TimeDelta remaining = wait_delta; remaining > TimeDelta(); + remaining = end_time - TimeTicks::Now()) { + // Truncate the timeout to milliseconds, rounded up to avoid spinning + // (either by returning too early or because a < 1ms timeout on Windows + // tends to return immediately). + const DWORD timeout_ms = + remaining.is_max() + ? INFINITE + : saturated_cast<DWORD>(remaining.InMillisecondsRoundedUp()); + const DWORD result = WaitForSingleObject(handle_.Get(), timeout_ms); DCHECK(result == WAIT_OBJECT_0 || result == WAIT_TIMEOUT) << "Unexpected WaitForSingleObject result " << result; switch (result) { @@ -98,59 +113,12 @@ // Windows. To make this consistent with the posix implementation we // should guarantee that TimedWait doesn't return earlier than the // specified |max_time| and wait again for the remaining time. - delta = end_time - TimeTicks::Now(); - break; + continue; } - } while (delta > TimeDelta()); + } return false; } -} // namespace - -bool WaitableEvent::TimedWait(const TimeDelta& wait_delta) { - DCHECK_GE(wait_delta, TimeDelta()); - if (wait_delta.is_zero()) - return IsSignaled(); - - // Record the event that this thread is blocking upon (for hang diagnosis) and - // consider it blocked for scheduling purposes. Ignore this for non-blocking - // WaitableEvents. - Optional<debug::ScopedEventWaitActivity> event_activity; - Optional<internal::ScopedBlockingCallWithBaseSyncPrimitives> - scoped_blocking_call; - if (waiting_is_blocking_) { - event_activity.emplace(this); - scoped_blocking_call.emplace(BlockingType::MAY_BLOCK); - } - - TimeTicks now(TimeTicks::Now()); - // TimeTicks takes care of overflow including the cases when wait_delta - // is a maximum value. - return WaitUntil(handle_.Get(), now, now + wait_delta); -} - -bool WaitableEvent::TimedWaitUntil(const TimeTicks& end_time) { - if (end_time.is_null()) - return IsSignaled(); - - // Record the event that this thread is blocking upon (for hang diagnosis) and - // consider it blocked for scheduling purposes. Ignore this for non-blocking - // WaitableEvents. - Optional<debug::ScopedEventWaitActivity> event_activity; - Optional<internal::ScopedBlockingCallWithBaseSyncPrimitives> - scoped_blocking_call; - if (waiting_is_blocking_) { - event_activity.emplace(this); - scoped_blocking_call.emplace(BlockingType::MAY_BLOCK); - } - - TimeTicks now(TimeTicks::Now()); - if (end_time <= now) - return IsSignaled(); - - return WaitUntil(handle_.Get(), now, end_time); -} - // static size_t WaitableEvent::WaitMany(WaitableEvent** events, size_t count) { DCHECK(count) << "Cannot wait on no events";
diff --git a/base/task/thread_pool/task_tracker_posix.h b/base/task/thread_pool/task_tracker_posix.h index 0d9c227..67a0f71b 100644 --- a/base/task/thread_pool/task_tracker_posix.h +++ b/base/task/thread_pool/task_tracker_posix.h
@@ -10,6 +10,7 @@ #include "base/base_export.h" #include "base/logging.h" #include "base/macros.h" +#include "base/message_loop/message_pump_type.h" #include "base/task/thread_pool/task_tracker.h" #include "base/threading/platform_thread.h" @@ -29,7 +30,7 @@ // Sets the task runner with which to setup FileDescriptorWatcher in // the scope in which tasks run. |io_thread_task_runner| must refer to - // a Thread with MessageLoop::TYPE_IO. + // a Thread with MessagePumpType::IO. // Must be called before starting to run tasks. // External synchronization is required between a call to this and a call to // RunTask().
diff --git a/base/task/thread_pool/task_tracker_posix_unittest.cc b/base/task/thread_pool/task_tracker_posix_unittest.cc index 2bf9e11..34812a1 100644 --- a/base/task/thread_pool/task_tracker_posix_unittest.cc +++ b/base/task/thread_pool/task_tracker_posix_unittest.cc
@@ -14,7 +14,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/posix/eintr_wrapper.h" #include "base/run_loop.h" #include "base/sequence_token.h" @@ -35,7 +35,7 @@ public: ThreadPoolTaskTrackerPosixTest() : service_thread_("ServiceThread") { Thread::Options service_thread_options; - service_thread_options.message_loop_type = MessageLoop::TYPE_IO; + service_thread_options.message_pump_type = MessagePumpType::IO; service_thread_.StartWithOptions(service_thread_options); tracker_.set_io_thread_task_runner(service_thread_.task_runner()); }
diff --git a/base/task/thread_pool/thread_pool_impl.cc b/base/task/thread_pool/thread_pool_impl.cc index e1f51c0..1c3bde91 100644 --- a/base/task/thread_pool/thread_pool_impl.cc +++ b/base/task/thread_pool/thread_pool_impl.cc
@@ -14,7 +14,7 @@ #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/feature_list.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/field_trial_params.h" #include "base/stl_util.h" #include "base/strings/string_util.h" @@ -142,11 +142,11 @@ // SFI), the service thread runs a MessageLoopForIO which is used to support // FileDescriptorWatcher in the scope in which tasks run. ServiceThread::Options service_thread_options; - service_thread_options.message_loop_type = + service_thread_options.message_pump_type = #if defined(OS_POSIX) && !defined(OS_NACL_SFI) - MessageLoop::TYPE_IO; + MessagePumpType::IO; #else - MessageLoop::TYPE_DEFAULT; + MessagePumpType::DEFAULT; #endif service_thread_options.timer_slack = TIMER_SLACK_MAXIMUM; CHECK(service_thread_->StartWithOptions(service_thread_options));
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/CallbackHelper.java b/base/test/android/javatests/src/org/chromium/base/test/util/CallbackHelper.java index ea8e0b0..86934b4a 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/util/CallbackHelper.java +++ b/base/test/android/javatests/src/org/chromium/base/test/util/CallbackHelper.java
@@ -175,11 +175,11 @@ long timeout, TimeUnit unit) throws InterruptedException, TimeoutException { assert mCallCount >= currentCallCount; assert numberOfCallsToWaitFor > 0; + TimeoutTimer timer = new TimeoutTimer(unit.toMillis(timeout)); synchronized (mLock) { int callCountWhenDoneWaiting = currentCallCount + numberOfCallsToWaitFor; - long deadline = System.currentTimeMillis() + unit.toMillis(timeout); - while (callCountWhenDoneWaiting > mCallCount && System.currentTimeMillis() < deadline) { - mLock.wait(deadline - System.currentTimeMillis()); + while (callCountWhenDoneWaiting > mCallCount && !timer.isTimedOut()) { + mLock.wait(timer.getRemainingMs()); if (mFailureString != null) { String s = mFailureString; mFailureString = null;
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/TimeoutTimer.java b/base/test/android/javatests/src/org/chromium/base/test/util/TimeoutTimer.java new file mode 100644 index 0000000..5b0cdfb6 --- /dev/null +++ b/base/test/android/javatests/src/org/chromium/base/test/util/TimeoutTimer.java
@@ -0,0 +1,41 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +package org.chromium.base.test.util; + +import android.os.Debug; +import android.os.SystemClock; + +/** + * Encapsulates timeout logic, and disables timeouts when debugger is attached. + */ +public class TimeoutTimer { + private final long mEndTimeMs; + private final long mTimeoutMs; + + /** + * @param timeoutMs Relative time for the timeout (unscaled). + */ + public TimeoutTimer(long timeoutMs) { + // TODO(agrieve): Apply ScalableTimeout.scaleTimeout() here rather than at callsites. + this.mTimeoutMs = timeoutMs; + this.mEndTimeMs = SystemClock.uptimeMillis() + timeoutMs; + } + + /** Whether this timer has expired. */ + public boolean isTimedOut() { + return getRemainingMs() == 0; + } + + /** Returns how much time is left in milliseconds. */ + public long getRemainingMs() { + if (Debug.isDebuggerConnected()) { + // Never decreases, but still short enough that it's safe to wait() on and have a + // timeout happen once the debugger detaches. + return mTimeoutMs; + } + long ret = mEndTimeMs - SystemClock.uptimeMillis(); + return ret < 0 ? 0 : ret; + } +}
diff --git a/base/test/scoped_task_environment.h b/base/test/scoped_task_environment.h index ce71719..7722b4ee 100644 --- a/base/test/scoped_task_environment.h +++ b/base/test/scoped_task_environment.h
@@ -103,7 +103,6 @@ // MOCK_TIME as expected, e.g.: // PlatformThread::Sleep // WaitableEvent::TimedWait - // WaitableEvent::TimedWaitUntil // ConditionVariable::TimedWait // // TODO(crbug.com/905412): Make MOCK_TIME always mock Time/TimeTicks::Now().
diff --git a/base/test/test_io_thread.cc b/base/test/test_io_thread.cc index 1b206589..5fb73e1 100644 --- a/base/test/test_io_thread.cc +++ b/base/test/test_io_thread.cc
@@ -5,7 +5,7 @@ #include "base/test/test_io_thread.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" namespace base { @@ -29,7 +29,7 @@ CHECK(!io_thread_started_); io_thread_started_ = true; CHECK(io_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); + base::Thread::Options(base::MessagePumpType::IO, 0))); } void TestIOThread::Stop() {
diff --git a/base/test/test_message_loop.cc b/base/test/test_message_loop.cc index bd3610f..d8bf055e 100644 --- a/base/test/test_message_loop.cc +++ b/base/test/test_message_loop.cc
@@ -9,7 +9,7 @@ TestMessageLoop::TestMessageLoop() = default; -TestMessageLoop::TestMessageLoop(MessageLoop::Type type) : loop_(type) {} +TestMessageLoop::TestMessageLoop(MessagePumpType type) : loop_(type) {} TestMessageLoop::~TestMessageLoop() { RunLoop().RunUntilIdle();
diff --git a/base/test/test_message_loop.h b/base/test/test_message_loop.h index ea2cca8d..be23936ac 100644 --- a/base/test/test_message_loop.h +++ b/base/test/test_message_loop.h
@@ -6,6 +6,7 @@ #define BASE_TEST_TEST_MESSAGE_LOOP_H_ #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" namespace base { @@ -18,7 +19,7 @@ class TestMessageLoop { public: TestMessageLoop(); - explicit TestMessageLoop(MessageLoop::Type type); + explicit TestMessageLoop(MessagePumpType type); ~TestMessageLoop(); scoped_refptr<SingleThreadTaskRunner> task_runner() {
diff --git a/base/threading/thread.cc b/base/threading/thread.cc index 96950c23..447bdaeb 100644 --- a/base/threading/thread.cc +++ b/base/threading/thread.cc
@@ -42,8 +42,8 @@ Thread::Options::Options() = default; -Thread::Options::Options(MessageLoop::Type type, size_t size) - : message_loop_type(type), stack_size(size) {} +Thread::Options::Options(MessagePumpType type, size_t size) + : message_pump_type(type), stack_size(size) {} Thread::Options::Options(Options&& other) = default; @@ -72,7 +72,7 @@ Options options; #if defined(OS_WIN) if (com_status_ == STA) - options.message_loop_type = MessageLoop::TYPE_UI; + options.message_pump_type = MessagePumpType::UI; #endif return StartWithOptions(options); } @@ -85,7 +85,7 @@ << "not allowed!"; #if defined(OS_WIN) DCHECK((com_status_ != STA) || - (options.message_loop_type == MessageLoop::TYPE_UI)); + (options.message_pump_type == MessagePumpType::UI)); #endif // Reset |id_| here to support restarting the thread. @@ -104,7 +104,7 @@ MessageLoop::CreateUnbound(options.message_pump_factory.Run())); } else { task_environment_ = std::make_unique<internal::MessageLoopTaskEnvironment>( - MessageLoop::CreateUnbound(options.message_loop_type)); + MessageLoop::CreateUnbound(options.message_pump_type)); } start_event_.Reset();
diff --git a/base/threading/thread.h b/base/threading/thread.h index 3b94305..4e18fbe9 100644 --- a/base/threading/thread.h +++ b/base/threading/thread.h
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop_current.h" +#include "base/message_loop/message_pump_type.h" #include "base/message_loop/timer_slack.h" #include "base/sequence_checker.h" #include "base/single_thread_task_runner.h" @@ -76,13 +77,13 @@ RepeatingCallback<std::unique_ptr<MessagePump>()>; Options(); - Options(MessageLoop::Type type, size_t size); + Options(MessagePumpType type, size_t size); Options(Options&& other); ~Options(); - // Specifies the type of message loop that will be allocated on the thread. + // Specifies the type of message pump that will be allocated on the thread. // This is ignored if message_pump_factory.is_null() is false. - MessageLoop::Type message_loop_type = MessageLoop::TYPE_DEFAULT; + MessagePumpType message_pump_type = MessagePump::Type::DEFAULT; // An unbound TaskEnvironment that will be bound to the thread. Ownership // of |task_environment| will be transferred to the thread. @@ -94,8 +95,8 @@ // Used to create the MessagePump for the MessageLoop. The callback is Run() // on the thread. If message_pump_factory.is_null(), then a MessagePump - // appropriate for |message_loop_type| is created. Setting this forces the - // MessageLoop::Type to TYPE_CUSTOM. This is not compatible with a non-null + // appropriate for |message_pump_type| is created. Setting this forces the + // MessagePumpType to TYPE_CUSTOM. This is not compatible with a non-null // |task_environment|. MessagePumpFactory message_pump_factory;
diff --git a/cc/input/scrollbar_controller.cc b/cc/input/scrollbar_controller.cc index 46f4b21..1550731 100644 --- a/cc/input/scrollbar_controller.cc +++ b/cc/input/scrollbar_controller.cc
@@ -25,7 +25,6 @@ LayerTreeHostImpl* layer_tree_host_impl) : layer_tree_host_impl_(layer_tree_host_impl), scrollbar_scroll_is_active_(false), - thumb_drag_in_progress_(false), autoscroll_state_(AutoScrollState::NO_AUTOSCROLL), currently_captured_scrollbar_(nullptr), previous_pointer_position_(gfx::PointF(0, 0)), @@ -41,6 +40,21 @@ layer_tree_host_impl_->mutator_host()->ScrollAnimationAbort(); } +gfx::Vector2dF ScrollbarController::GetThumbRelativePoint( + const gfx::PointF position_in_widget) { + bool clipped; + const gfx::PointF position_in_layer = + GetScrollbarRelativePosition(position_in_widget, &clipped); + + if (clipped) + return gfx::Vector2d(0, 0); + + const gfx::RectF thumb_rect( + currently_captured_scrollbar_->ComputeThumbQuadRect()); + DCHECK(thumb_rect.Contains(position_in_layer)); + return position_in_layer - gfx::PointF(thumb_rect.origin()); +} + // Performs hit test and prepares scroll deltas that will be used by GSB and // GSU. InputHandlerPointerResult ScrollbarController::HandleMouseDown( @@ -56,16 +70,16 @@ currently_captured_scrollbar_ = layer_impl->ToScrollbarLayer(); scroll_result.type = PointerResultType::kScrollbarScroll; layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries(); - ScrollbarPart scrollbar_part = + const ScrollbarPart scrollbar_part = GetScrollbarPartFromPointerDown(position_in_widget); scroll_result.scroll_offset = GetScrollOffsetForScrollbarPart( scrollbar_part, currently_captured_scrollbar_->orientation()); previous_pointer_position_ = position_in_widget; scrollbar_scroll_is_active_ = true; if (scrollbar_part == ScrollbarPart::THUMB) { - thumb_drag_in_progress_ = true; scroll_result.scroll_units = ui::input_types::ScrollGranularity::kScrollByPrecisePixel; + drag_anchor_relative_to_thumb_ = GetThumbRelativePoint(position_in_widget); } else { // TODO(arakeri): This needs to be updated to kLine once cc implements // handling it. crbug.com/959441 @@ -73,10 +87,12 @@ ui::input_types::ScrollGranularity::kScrollByPixel; } - // Thumb drag is the only scrollbar manipulation that cannot produce an - // autoscroll. All other interactions like clicking on arrows/trackparts have - // the potential of initiating an autoscroll (if held down long enough). - if (!scroll_result.scroll_offset.IsZero() && !thumb_drag_in_progress_) { + if (!scroll_result.scroll_offset.IsZero()) { + // Thumb drag is the only scrollbar manipulation that cannot produce an + // autoscroll. All other interactions like clicking on arrows/trackparts + // have the potential of initiating an autoscroll (if held down for long + // enough). + DCHECK(scrollbar_part != ScrollbarPart::THUMB); cancelable_autoscroll_task_ = std::make_unique<base::CancelableClosure>( base::Bind(&ScrollbarController::StartAutoScrollAnimation, base::Unretained(this), scroll_result.scroll_offset, @@ -89,29 +105,79 @@ return scroll_result; } +gfx::ScrollOffset ScrollbarController::GetScrollOffsetForDragPosition( + const gfx::PointF pointer_position_in_widget) { + layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries(); + + const gfx::Rect thumb_rect( + currently_captured_scrollbar_->ComputeThumbQuadRect()); + const gfx::PointF drag_position_relative_to_layer = + gfx::PointF(thumb_rect.origin()) + drag_anchor_relative_to_thumb_.value(); + + bool clipped = false; + const gfx::PointF pointer_position_in_layer = + GetScrollbarRelativePosition(pointer_position_in_widget, &clipped); + + if (clipped) + return gfx::ScrollOffset(0, 0); + + // Calculate the delta based on the previously known thumb drag point. + const gfx::Vector2dF pointer_delta = + pointer_position_in_layer - drag_position_relative_to_layer; + + gfx::ScrollOffset scaled_thumb_drag_delta; + const ScrollbarOrientation orientation = + currently_captured_scrollbar_->orientation(); + orientation == ScrollbarOrientation::VERTICAL + ? scaled_thumb_drag_delta.set_y(pointer_delta.y()) + : scaled_thumb_drag_delta.set_x(pointer_delta.x()); + + float scaled_scroller_to_scrollbar_ratio = GetScrollerToScrollbarRatio(); + scaled_thumb_drag_delta.Scale(scaled_scroller_to_scrollbar_ratio); + return scaled_thumb_drag_delta; +} + // Performs hit test and prepares scroll deltas that will be used by GSU. InputHandlerPointerResult ScrollbarController::HandleMouseMove( const gfx::PointF position_in_widget) { - const gfx::PointF previous_pointer_position = previous_pointer_position_; previous_pointer_position_ = position_in_widget; InputHandlerPointerResult scroll_result; - if (!thumb_drag_in_progress_) + + // If a thumb drag is not in progress, there's no point in continuing on. + if (!drag_anchor_relative_to_thumb_.has_value()) return scroll_result; + const ScrollNode* currently_scrolling_node = + layer_tree_host_impl_->CurrentlyScrollingNode(); + + // Thumb drag needs a scroll_node. Clear the thumb drag state and exit if it + // is unset. + if (currently_scrolling_node == nullptr) { + drag_anchor_relative_to_thumb_ = base::nullopt; + return scroll_result; + } + + // If scroll_offset can't be consumed, there's no point in continuing on. + const gfx::ScrollOffset scroll_offset( + GetScrollOffsetForDragPosition(position_in_widget)); + const gfx::Vector2dF clamped_scroll_offset( + layer_tree_host_impl_->ComputeScrollDelta( + *currently_scrolling_node, ScrollOffsetToVector2dF(scroll_offset))); + + if (clamped_scroll_offset.IsZero()) + return scroll_result; + + // Thumb drags have more granularity and are purely dependent on the pointer + // movement. Hence we use kPrecisePixel when dragging the thumb. + scroll_result.scroll_units = + ui::input_types::ScrollGranularity::kScrollByPrecisePixel; scroll_result.type = PointerResultType::kScrollbarScroll; - const ScrollbarOrientation orientation = - currently_captured_scrollbar_->orientation(); - if (orientation == ScrollbarOrientation::VERTICAL) - scroll_result.scroll_offset.set_y(position_in_widget.y() - - previous_pointer_position.y()); - else - scroll_result.scroll_offset.set_x(position_in_widget.x() - - previous_pointer_position.x()); + scroll_result.scroll_offset = gfx::ScrollOffset(clamped_scroll_offset); - LayerImpl* owner_scroll_layer = - layer_tree_host_impl_->active_tree()->ScrollableLayerByElementId( - currently_captured_scrollbar_->scroll_element_id()); + return scroll_result; +} +float ScrollbarController::GetScrollerToScrollbarRatio() { // Calculating the delta by which the scroller layer should move when // dragging the thumb depends on the following factors: // - scrollbar_track_length @@ -155,10 +221,15 @@ currently_captured_scrollbar_->scroll_layer_length(); float scrollbar_track_length = currently_captured_scrollbar_->TrackLength(); gfx::Rect thumb_rect(currently_captured_scrollbar_->ComputeThumbQuadRect()); + const ScrollbarOrientation orientation = + currently_captured_scrollbar_->orientation(); float scrollbar_thumb_length = orientation == ScrollbarOrientation::VERTICAL ? thumb_rect.height() : thumb_rect.width(); + const LayerImpl* owner_scroll_layer = + layer_tree_host_impl_->active_tree()->ScrollableLayerByElementId( + currently_captured_scrollbar_->scroll_element_id()); float viewport_length = orientation == ScrollbarOrientation::VERTICAL ? owner_scroll_layer->scroll_container_bounds().height() @@ -167,13 +238,17 @@ ((scroll_layer_length - viewport_length) / (scrollbar_track_length - scrollbar_thumb_length)) * layer_tree_host_impl_->active_tree()->device_scale_factor(); - scroll_result.scroll_offset.Scale(scaled_scroller_to_scrollbar_ratio); - // Thumb drags have more granularity and are purely dependent on the pointer - // movement. Hence we use kPrecisePixel when dragging the thumb. - scroll_result.scroll_units = - ui::input_types::ScrollGranularity::kScrollByPrecisePixel; - return scroll_result; + // Avoid precision loss later on by rounding up 3 decimal places here. + // TODO(arakeri): Revisit this while fixing crbug.com/986174. There is a + // precision loss that is happening somewhere which affects root scrollbars + // only. Even though it is not visible to the end user, without rounding up, + // the scrolling tests will fail due to this precision loss. + DCHECK_GT(scaled_scroller_to_scrollbar_ratio, 0); + scaled_scroller_to_scrollbar_ratio = + ceil(scaled_scroller_to_scrollbar_ratio * 1000.0) / 1000.0; + + return scaled_scroller_to_scrollbar_ratio; } bool ScrollbarController::ShouldCancelTrackAutoscroll() { @@ -285,7 +360,7 @@ cancelable_autoscroll_task_.reset(); } - thumb_drag_in_progress_ = false; + drag_anchor_relative_to_thumb_ = base::nullopt; autoscroll_state_ = AutoScrollState::NO_AUTOSCROLL; return scroll_result; }
diff --git a/cc/input/scrollbar_controller.h b/cc/input/scrollbar_controller.h index 550e63ef..f45a045 100644 --- a/cc/input/scrollbar_controller.h +++ b/cc/input/scrollbar_controller.h
@@ -58,6 +58,18 @@ // Decides whether a track autoscroll should be aborted. bool ShouldCancelTrackAutoscroll(); + // Calculates the scroll_offset based on position_in_widget and + // drag_anchor_relative_to_thumb_. + gfx::ScrollOffset GetScrollOffsetForDragPosition( + const gfx::PointF pointer_position_in_widget); + + // Returns a Vector2dF for position_in_widget relative to the scrollbar thumb. + gfx::Vector2dF GetThumbRelativePoint(const gfx::PointF position_in_widget); + + // Returns the ratio of the scroller length to the scrollbar length. This is + // needed to scale the scroll delta for thumb drag. + float GetScrollerToScrollbarRatio(); + LayerTreeHostImpl* layer_tree_host_impl_; // Used to safeguard against firing GSE without firing GSB and GSU. For @@ -65,9 +77,6 @@ // moving inside the scrollbar, a GSE will get queued up without this flag. bool scrollbar_scroll_is_active_; - // Used to tell if the scrollbar thumb is getting dragged. - bool thumb_drag_in_progress_; - // "Autoscroll" here means the continuous scrolling that occurs when the // pointer is held down on a hit-testable area of the scrollbar such as an // arrows of the track itself. @@ -77,6 +86,10 @@ // This is relative to the RenderWidget's origin. gfx::PointF previous_pointer_position_; + // This is used to track the pointer location relative to the thumb origin + // when a drag has started. + base::Optional<gfx::Vector2dF> drag_anchor_relative_to_thumb_; + std::unique_ptr<base::CancelableClosure> cancelable_autoscroll_task_; };
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index 5d2efc5..42228ee 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -473,6 +473,11 @@ result->Set("WheelRegion", std::move(region)); } + if (!non_fast_scrollable_region_.IsEmpty()) { + std::unique_ptr<base::Value> region = non_fast_scrollable_region_.AsValue(); + result->Set("NonFastScrollableRegion", std::move(region)); + } + return result; }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java index 3237350..408c2e02 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java
@@ -34,6 +34,7 @@ import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController; import org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver; +import org.chromium.content_public.browser.WebContents; import org.chromium.ui.modelutil.ListModel; /** @@ -49,6 +50,8 @@ private final BottomSheetController mBottomSheetController; private final AssistantBottomSheetContent mContent; private final ScrollView mScrollableContent; + @Nullable + private WebContents mWebContents; // Child coordinators. private final AssistantHeaderCoordinator mHeaderCoordinator; @@ -68,9 +71,12 @@ .addTransition(new ChangeBounds().setDuration(CHANGE_BOUNDS_TRANSITION_TIME_MS)) .addTransition(new Fade(Fade.IN).setDuration(FADE_IN_TRANSITION_TIME_MS)); - private final ObserverList<CompositorViewResizer.Observer> mSizeObservers = + private final ObserverList<CompositorViewResizer.Observer> mLayoutViewportSizeObservers = new ObserverList<>(); - private boolean mResizeViewport; + @AssistantViewportMode + private int mViewportMode = AssistantViewportMode.NO_RESIZE; + private int mLastLayoutViewportResizing; + private int mLastVisualViewportResizing; AssistantBottomBarCoordinator( ChromeActivity activity, AssistantModel model, BottomSheetController controller) { @@ -165,7 +171,13 @@ public void onSheetContentChanged(@Nullable BottomSheet.BottomSheetContent newContent) { // TODO(crbug.com/806868): Make sure this works and does not interfere with Duet // once we are in ChromeTabbedActivity. - notifyAutofillAssistantSizeChanged(); + updateLayoutViewportHeight(); + updateVisualViewportHeight(); + } + + @Override + public void onSheetOffsetChanged(float heightFraction, float offsetPx) { + updateVisualViewportHeight(); } }); @@ -184,6 +196,8 @@ } else { activity.addViewObscuringAllTabs(bottomSheet); } + } else if (AssistantModel.WEB_CONTENTS == propertyKey) { + mWebContents = model.get(AssistantModel.WEB_CONTENTS); } }); @@ -248,6 +262,8 @@ * Cleanup resources when this goes out of scope. */ public void destroy() { + resetVisualViewportHeight(); + mInfoBoxCoordinator.destroy(); mInfoBoxCoordinator = null; mPaymentRequestCoordinator.destroy(); @@ -266,11 +282,12 @@ mBottomSheetController.hideContent(mContent, /* animate= */ true); } - void setResizeViewport(boolean resizeViewport) { - if (resizeViewport == mResizeViewport) return; + void setViewportMode(@AssistantViewportMode int mode) { + if (mode == mViewportMode) return; - mResizeViewport = resizeViewport; - notifyAutofillAssistantSizeChanged(); + mViewportMode = mode; + updateVisualViewportHeight(); + updateLayoutViewportHeight(); } /** Set the peek mode. */ @@ -286,7 +303,7 @@ @Override public void onPeekHeightChanged() { - notifyAutofillAssistantSizeChanged(); + updateLayoutViewportHeight(); } private void setChildMarginTop(View child, int marginTop) { @@ -332,18 +349,59 @@ view.setLayoutParams(layoutParams); } - private void notifyAutofillAssistantSizeChanged() { - int height = getHeight(); - for (Observer observer : mSizeObservers) { - observer.onHeightChanged(height); + private void updateLayoutViewportHeight() { + setLayoutViewportResizing(getHeight()); + } + + /** + * Shrink the layout viewport by {@code resizing} pixels. This is an expensive operation that + * should be used with care. + */ + private void setLayoutViewportResizing(int resizing) { + if (resizing == mLastLayoutViewportResizing) return; + mLastLayoutViewportResizing = resizing; + + for (Observer observer : mLayoutViewportSizeObservers) { + observer.onHeightChanged(resizing); } } + private void updateVisualViewportHeight() { + BottomSheet bottomSheet = mBottomSheetController.getBottomSheet(); + if (mViewportMode != AssistantViewportMode.RESIZE_VISUAL_VIEWPORT + || bottomSheet.getCurrentSheetContent() != mContent) { + resetVisualViewportHeight(); + return; + } + + setVisualViewportResizing((int) Math.floor( + bottomSheet.getCurrentOffsetPx() - bottomSheet.getToolbarShadowHeight())); + } + + private void resetVisualViewportHeight() { + setVisualViewportResizing(0); + } + + /** + * Shrink the visual viewport by {@code resizing} pixels. This operation is cheaper than calling + * {@link #setLayoutViewportResizing} and can therefore be often called (e.g. during + * animations). + */ + private void setVisualViewportResizing(int resizing) { + if (resizing == mLastVisualViewportResizing || mWebContents == null + || mWebContents.getRenderWidgetHostView() == null) { + return; + } + + mLastVisualViewportResizing = resizing; + mWebContents.getRenderWidgetHostView().insetViewportBottom(resizing); + } + // Implementation of methods from AutofillAssistantSizeManager. @Override public int getHeight() { - if (mResizeViewport + if (mViewportMode == AssistantViewportMode.RESIZE_LAYOUT_VIEWPORT && mBottomSheetController.getBottomSheet().getCurrentSheetContent() == mContent) return mPeekHeightCoordinator.getPeekHeight(); @@ -352,11 +410,11 @@ @Override public void addObserver(Observer observer) { - mSizeObservers.addObserver(observer); + mLayoutViewportSizeObservers.addObserver(observer); } @Override public void removeObserver(Observer observer) { - mSizeObservers.removeObserver(observer); + mLayoutViewportSizeObservers.removeObserver(observer); } }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantModel.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantModel.java index 064ee59a..bc8dd30 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantModel.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantModel.java
@@ -13,6 +13,7 @@ import org.chromium.chrome.browser.autofill_assistant.infobox.AssistantInfoBoxModel; import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayModel; import org.chromium.chrome.browser.autofill_assistant.payment.AssistantPaymentRequestModel; +import org.chromium.content_public.browser.WebContents; import org.chromium.ui.modelutil.PropertyModel; /** @@ -25,6 +26,10 @@ new WritableBooleanPropertyKey(); static final WritableBooleanPropertyKey VISIBLE = new WritableBooleanPropertyKey(); + /** The web contents the Autofill Assistant is associated with. */ + static final WritableObjectPropertyKey<WebContents> WEB_CONTENTS = + new WritableObjectPropertyKey<>(); + private final AssistantOverlayModel mOverlayModel; private final AssistantHeaderModel mHeaderModel = new AssistantHeaderModel(); private final AssistantDetailsModel mDetailsModel = new AssistantDetailsModel(); @@ -40,7 +45,7 @@ } AssistantModel(AssistantOverlayModel overlayModel) { - super(ALLOW_SOFT_KEYBOARD, VISIBLE, ALLOW_TALKBACK_ON_WEBSITE); + super(ALLOW_SOFT_KEYBOARD, VISIBLE, WEB_CONTENTS, ALLOW_TALKBACK_ON_WEBSITE); mOverlayModel = overlayModel; } @@ -101,4 +106,9 @@ private boolean getVisible() { return get(VISIBLE); } + + @CalledByNative + private void setWebContents(WebContents contents) { + set(WEB_CONTENTS, contents); + } }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java index e34f805..79012311 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
@@ -303,8 +303,8 @@ } @CalledByNative - private void setResizeViewport(boolean resizeViewport) { - mCoordinator.getBottomBarCoordinator().setResizeViewport(resizeViewport); + private void setViewportMode(@AssistantViewportMode int mode) { + mCoordinator.getBottomBarCoordinator().setViewportMode(mode); } @CalledByNative
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/BottomBarView.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/BottomBarView.java index af4936d..3e77d6fb 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/BottomBarView.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/BottomBarView.java
@@ -121,4 +121,15 @@ public void setOnClickListener(StartSurfaceProperties.BottomBarClickListener listener) { mOnClickListener = listener; } + + /** + * Select the Tab at the specified position if needed. + * @param index The specified position. + */ + public void selectTabAt(int index) { + assert index >= 0 && index < mTabLayout.getTabCount(); + + if (index == mTabLayout.getSelectedTabPosition()) return; + mTabLayout.getTabAt(index).select(); + } } \ No newline at end of file
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/BottomBarViewBinder.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/BottomBarViewBinder.java index 85db334..7b68306 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/BottomBarViewBinder.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/BottomBarViewBinder.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.features.start_surface; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.BOTTOM_BAR_CLICKLISTENER; +import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.BOTTOM_BAR_SELECTED_TAB_POSITION; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_INCOGNITO; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_SHOWING_OVERVIEW; @@ -14,12 +15,14 @@ /** The view binder of the bottom bar. */ class BottomBarViewBinder { public static void bind(PropertyModel model, BottomBarView view, PropertyKey propertyKey) { - if (IS_INCOGNITO == propertyKey) { + if (BOTTOM_BAR_CLICKLISTENER == propertyKey) { + view.setOnClickListener(model.get(BOTTOM_BAR_CLICKLISTENER)); + } else if (BOTTOM_BAR_SELECTED_TAB_POSITION == propertyKey) { + view.selectTabAt(model.get(BOTTOM_BAR_SELECTED_TAB_POSITION)); + } else if (IS_INCOGNITO == propertyKey) { view.setIncognito(model.get(IS_INCOGNITO)); } else if (IS_SHOWING_OVERVIEW == propertyKey) { view.setVisibility(model.get(IS_SHOWING_OVERVIEW)); - } else if (BOTTOM_BAR_CLICKLISTENER == propertyKey) { - view.setOnClickListener(model.get(BOTTOM_BAR_CLICKLISTENER)); } } } \ No newline at end of file
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java index db2bcdd1..762439f 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.features.start_surface; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.BOTTOM_BAR_CLICKLISTENER; +import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.BOTTOM_BAR_SELECTED_TAB_POSITION; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.FEED_SURFACE_COORDINATOR; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_EXPLORE_SURFACE_VISIBLE; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_INCOGNITO; @@ -110,8 +111,10 @@ @Override public boolean onBackPressed() { - // TODO(crbug.com/982018): Check whether explore surface is shown, if yes, switch back to - // home surface. + if (mPropertyModel != null && mPropertyModel.get(IS_EXPLORE_SURFACE_VISIBLE)) { + setExploreSurfaceVisibility(false); + return true; + } return mGridController.onBackPressed(); } @@ -159,6 +162,10 @@ } mPropertyModel.set(IS_EXPLORE_SURFACE_VISIBLE, isVisible); + + // Update the 'BOTTOM_BAR_SELECTED_TAB_POSITION' property to reflect the change. This is + // needed when clicking back button on the explore surface. + mPropertyModel.set(BOTTOM_BAR_SELECTED_TAB_POSITION, isVisible ? 1 : 0); } void updateIncognitoMode(boolean isIncognito) {
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceProperties.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceProperties.java index 7b6e0553..3a675dd 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceProperties.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceProperties.java
@@ -26,6 +26,8 @@ new PropertyModel.WritableObjectPropertyKey<BottomBarClickListener>(); public static final PropertyModel.WritableIntPropertyKey BOTTOM_BAR_HEIGHT = new PropertyModel.WritableIntPropertyKey(); + public static final PropertyModel.WritableIntPropertyKey BOTTOM_BAR_SELECTED_TAB_POSITION = + new PropertyModel.WritableIntPropertyKey(); public static final PropertyModel.WritableBooleanPropertyKey IS_EXPLORE_SURFACE_VISIBLE = new PropertyModel.WritableBooleanPropertyKey(); public static final PropertyModel.WritableBooleanPropertyKey IS_INCOGNITO = @@ -38,6 +40,6 @@ public static final PropertyModel.WritableIntPropertyKey TOP_BAR_HEIGHT = new PropertyModel.WritableIntPropertyKey(); public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {BOTTOM_BAR_CLICKLISTENER, - BOTTOM_BAR_HEIGHT, IS_EXPLORE_SURFACE_VISIBLE, IS_INCOGNITO, IS_SHOWING_OVERVIEW, - FEED_SURFACE_COORDINATOR, TOP_BAR_HEIGHT}; + BOTTOM_BAR_HEIGHT, BOTTOM_BAR_SELECTED_TAB_POSITION, IS_EXPLORE_SURFACE_VISIBLE, + IS_INCOGNITO, IS_SHOWING_OVERVIEW, FEED_SURFACE_COORDINATOR, TOP_BAR_HEIGHT}; } \ No newline at end of file
diff --git a/chrome/android/java/res/layout/preference_category.xml b/chrome/android/java/res/layout/preference_category.xml deleted file mode 100644 index 6fa0c8a..0000000 --- a/chrome/android/java/res/layout/preference_category.xml +++ /dev/null
@@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2014 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> - -<!-- Emulates Android's preference_category_material.xml on pre-L devices. - Also used as the layout for IconPreferenceCategory. --> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center_vertical" - style="@style/PreferenceCategoryWithButtonStyle" > - - <TextView - android:id="@android:id/title" - android:layout_width="0dp" - android:layout_weight="1" - android:layout_height="wrap_content" - android:textAppearance="@style/TextAppearance.PreferenceCategoryText" /> - - <!-- Users of this layout are responsible to set contentDescription. --> - <ImageView - android:id="@android:id/icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:minHeight="@dimen/min_touch_target_size" - android:minWidth="@dimen/min_touch_target_size" - android:scaleType="center" - android:background="?android:attr/selectableItemBackground" - tools:ignore="ContentDescription" /> - -</LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index ccef52bd..3d824f90 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -152,7 +152,6 @@ <!-- Theme attributes pre-v21 --> <item name="android:textAppearanceMedium">@style/TextAppearance.PreferenceMediumText</item> <item name="android:textAppearanceSmall">@style/TextAppearance.BlackBody</item> - <item name="android:preferenceCategoryStyle">@style/PreferenceCategory</item> <item name="android:windowContentOverlay">@null</item> <item name="preferenceTheme">@style/Theme.Chromium.PreferenceTheme</item> </style> @@ -297,10 +296,10 @@ <item name="buttonBarButtonStyle">@style/TextAppearance.DialogButtonCompat</item> </style> - <!-- TODO(chouinard): Using all caps for support library preference dialog buttons to match - existing non-compat style, however we should later reexamine whether this is still the - right choice since it looks like most of our other AlertDialogs use the default title case. - --> + <!-- TODO(crbug.com/971791): Using all caps for support library preference dialog buttons to + match existing non-compat style, however we should later reexamine whether this is still + the right choice since it looks like most of our other AlertDialogs use the default title + case. --> <style name="TextAppearance.DialogButtonCompat" parent="AlertDialogButtonStyle"> <item name="android:textAllCaps">true</item> </style> @@ -317,21 +316,6 @@ <item name="android:textSize">18sp</item> <item name="android:textColor">?android:attr/textColorPrimary</item> </style> - <style name="PreferenceCategory"> - <item name="android:layout">@layout/preference_category</item> - <item name="android:shouldDisableView">false</item> - <item name="android:selectable">false</item> - </style> - <style name="PreferenceCategoryWithButtonStyle"> - <item name="android:paddingStart">8dp</item> - <item name="android:paddingEnd">4dp</item> - <item name="android:paddingTop">16dp</item> - <item name="android:layout_marginBottom">16dp</item> - </style> - <style name="TextAppearance.PreferenceCategoryText" parent="TextAppearance.RobotoMediumStyle"> - <item name="android:textColor">@color/pref_accent_color</item> - <item name="android:textSize">12sp</item> - </style> <style name="PreferenceTitle"> <item name="android:ellipsize">end</item> <item name="android:singleLine">true</item> @@ -701,7 +685,6 @@ <style name="ToolbarMenuButtonPhone" parent="ToolbarButton"> <item name="android:layout_gravity">top</item> <item name="android:paddingEnd">8dp</item> - <item name="android:background">@null</item> </style> <style name="ToolbarMenuButtonTablet" parent="ToolbarButton"> <item name="android:layout_width">43dp</item>
diff --git a/chrome/android/java/res/values-v21/styles.xml b/chrome/android/java/res/values-v21/styles.xml index 48b11ae..0eb5506 100644 --- a/chrome/android/java/res/values-v21/styles.xml +++ b/chrome/android/java/res/values-v21/styles.xml
@@ -18,12 +18,6 @@ <!-- Preferences --> <style name="Theme.Chromium.Preferences" parent="Base.Theme.Chromium.Preferences"> - <item name="android:divider">@null</item> - <!-- Overriding alertDialogTheme pre-v21 with our custom AlertDialog theme causes bad visual - states on ListPreference because we don't use the support library ListPreference. --> - <item name="android:alertDialogTheme">@style/Theme.Chromium.AlertDialog</item> - <!-- TODO(crbug.com/967022): Clean up the unnecessary preference alert dialog styles once - all dialog preferences are migrated to the support library. --> <item name="alertDialogTheme">@style/Theme.Chromium.Preferences.AlertDialog</item> <item name="preferenceTheme">@style/Theme.Chromium.PreferenceTheme</item> </style> @@ -52,14 +46,6 @@ <item name="android:paddingStart">16dp</item> </style> - <style name="PreferenceCategoryWithButtonStyle"> - <item name="android:paddingStart">?android:attr/listPreferredItemPaddingStart</item> - <item name="android:paddingEnd">4dp</item> - </style> - <style name="TextAppearance.PreferenceCategoryText" parent="TextAppearance.RobotoMediumStyle"> - <item name="android:textColor">@color/pref_accent_color</item> - <item name="android:textSize">12sp</item> - </style> <style name="PreferenceTitle"> <item name="android:ellipsize">end</item> <item name="android:singleLine">true</item>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java index 11bb422..f59171d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/PickerCategoryView.java
@@ -308,6 +308,28 @@ } /** + * @param isIncluded Whether the property was requested by the API. + * @param isEnabled Whether the property was allowed to be shared by the user. + * @param selected The property values that are currently selected. + * @return The list of property values to share. + */ + private List<String> getContactPropertyValues( + boolean isIncluded, boolean isEnabled, List<String> selected) { + if (!isIncluded) { + // The property wasn't requested in the API so return null. + return null; + } + + if (!isEnabled) { + // The user doesn't want to share this property, so return an empty array. + return new ArrayList<String>(); + } + + // Share whatever was selected. + return selected; + } + + /** * Notifies any listeners that one or more contacts have been selected. */ private void notifyContactsSelected() { @@ -319,12 +341,11 @@ for (ContactDetails contactDetails : selectedContacts) { contacts.add(new ContactsPickerListener.Contact( - includeNames ? contactDetails.getDisplayNames() : null, - includeEmails && PickerAdapter.includesEmails() ? contactDetails.getEmails() - : null, - includeTel && PickerAdapter.includesTelephones() - ? contactDetails.getPhoneNumbers() - : null)); + getContactPropertyValues(includeNames, true, contactDetails.getDisplayNames()), + getContactPropertyValues(includeEmails, PickerAdapter.includesEmails(), + contactDetails.getEmails()), + getContactPropertyValues(includeTel, PickerAdapter.includesTelephones(), + contactDetails.getPhoneNumbers()))); } executeAction(ContactsPickerListener.ContactsPickerAction.CONTACTS_SELECTED, contacts); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/Preferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/Preferences.java index a915dcfd3..313fad7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/Preferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/Preferences.java
@@ -24,8 +24,6 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.VisibleForTesting; @@ -40,12 +38,13 @@ /** * The Chrome settings activity. * - * This activity displays a single Fragment, typically a PreferenceFragment. As the user navigates - * through settings, a separate Preferences activity is created for each screen. Thus each fragment - * may freely modify its activity's action bar or title. This mimics the behavior of - * android.preference.PreferenceActivity. + * This activity displays a single {@link Fragment}, typically a {@link PreferenceFragmentCompat}. + * As the user navigates through settings, a separate Preferences activity is created for each + * screen. Thus each fragment may freely modify its activity's action bar or title. This mimics the + * behavior of {@link android.preference.PreferenceActivity}. * - * If the preference overrides the root layout (e.g. {@link HomepageEditor}), add the following: + * If the main fragment is not an instance of {@link PreferenceFragmentCompat} (e.g. {@link + * HomepageEditor}) or overrides {@link PreferenceFragmentCompat}'s layout, add the following: * 1) preferences_action_bar_shadow.xml to the custom XML hierarchy and * 2) an OnScrollChangedListener to the main content's view's view tree observer via * PreferenceUtils.getShowShadowOnScrollListener(...). @@ -162,18 +161,22 @@ @Override public void onAttachedToWindow() { super.onAttachedToWindow(); + Fragment fragment = getMainFragment(); - if (fragment == null || fragment.getView() == null - || fragment.getView().findViewById(R.id.list) == null) { + if (!(fragment instanceof PreferenceFragmentCompat)) { return; } - View contentView = fragment.getActivity().findViewById(android.R.id.content); - if (contentView == null || !(contentView instanceof FrameLayout)) { + + RecyclerView recyclerView = ((PreferenceFragmentCompat) fragment).getListView(); + if (recyclerView == null) { return; } - View inflatedView = View.inflate(getApplicationContext(), - R.layout.preferences_action_bar_shadow, (ViewGroup) contentView); - RecyclerView recyclerView = fragment.getView().findViewById(R.id.list); + + // Append action bar shadow to layout. + View inflatedView = getLayoutInflater().inflate( + R.layout.preferences_action_bar_shadow, findViewById(android.R.id.content)); + + // Display shadow on scroll. recyclerView.getViewTreeObserver().addOnScrollChangedListener( PreferenceUtils.getShowShadowOnScrollListener( recyclerView, inflatedView.findViewById(R.id.shadow)));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEnginePreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEnginePreference.java index 7edf850d..c5fa0f9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEnginePreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEnginePreference.java
@@ -13,8 +13,10 @@ import org.chromium.chrome.R; /** -* A preference fragment for selecting a default search engine. -*/ + * A preference fragment for selecting a default search engine. + * + * TODO(crbug.com/988877): Add on scroll shadow to action bar. + */ public class SearchEnginePreference extends ListFragment { private SearchEngineAdapter mSearchEngineAdapter;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButton.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButton.java index e0df141..6b9a288 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButton.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButton.java
@@ -8,21 +8,21 @@ import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.View; -import android.widget.ImageButton; import org.chromium.chrome.R; import org.chromium.chrome.browser.toolbar.TabCountProvider; import org.chromium.chrome.browser.toolbar.TabSwitcherDrawable; import org.chromium.chrome.browser.util.AccessibilityUtil; +import org.chromium.ui.widget.ChromeImageButton; /** * A button displaying the number of open tabs. Clicking the button toggles the tab switcher view. * TODO(twellington): Replace with TabSwitcherButtonCoordinator so code can be shared with bottom * toolbar. */ -public class ToggleTabStackButton extends ImageButton implements TabCountProvider.TabCountObserver, - View.OnClickListener, - View.OnLongClickListener { +public class ToggleTabStackButton + extends ChromeImageButton implements TabCountProvider.TabCountObserver, + View.OnClickListener, View.OnLongClickListener { private TabSwitcherDrawable mTabSwitcherButtonDrawable; private TabSwitcherDrawable mTabSwitcherButtonDrawableLight; private TabCountProvider mTabCountProvider;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java index df0d48f9..8a03bbb 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java
@@ -343,7 +343,7 @@ Assert.assertEquals(1, mLastSelectedContacts.size()); Assert.assertEquals( mTestContacts.get(0).getDisplayName(), mLastSelectedContacts.get(0).names.get(0)); - Assert.assertEquals(null, mLastSelectedContacts.get(0).emails); + Assert.assertEquals(new ArrayList<String>(), mLastSelectedContacts.get(0).emails); dismissDialog(); } @@ -366,7 +366,7 @@ Assert.assertEquals(1, mLastSelectedContacts.size()); Assert.assertEquals( mTestContacts.get(0).getDisplayName(), mLastSelectedContacts.get(0).names.get(0)); - Assert.assertEquals(null, mLastSelectedContacts.get(0).tel); + Assert.assertEquals(new ArrayList<String>(), mLastSelectedContacts.get(0).tel); dismissDialog(); }
diff --git a/chrome/app_shim/chrome_main_app_mode_mac.mm b/chrome/app_shim/chrome_main_app_mode_mac.mm index 53241ed..a04417b 100644 --- a/chrome/app_shim/chrome_main_app_mode_mac.mm +++ b/chrome/app_shim/chrome_main_app_mode_mac.mm
@@ -20,6 +20,7 @@ #include "base/mac/mac_logging.h" #include "base/mac/scoped_nsautorelease_pool.h" #include "base/macros.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -122,7 +123,7 @@ // Launch the IO thread. base::Thread::Options io_thread_options; - io_thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + io_thread_options.message_pump_type = base::MessagePumpType::IO; base::Thread *io_thread = new base::Thread("CrAppShimIO"); io_thread->StartWithOptions(io_thread_options); @@ -136,8 +137,7 @@ [AppShimApplication sharedApplication]; CHECK([NSApp isKindOfClass:[AppShimApplication class]]); - base::SingleThreadTaskExecutor main_task_executor( - base::MessagePump::Type::UI); + base::SingleThreadTaskExecutor main_task_executor(base::MessagePumpType::UI); ui::WindowResizeHelperMac::Get()->Init(main_task_executor.task_runner()); base::PlatformThread::SetName("CrAppShimMain");
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 04c4555..143b2f0 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -337,6 +337,8 @@ "component_updater/sw_reporter_installer_win.h", "consent_auditor/consent_auditor_factory.cc", "consent_auditor/consent_auditor_factory.h", + "content_index/content_index_metrics.cc", + "content_index/content_index_metrics.h", "content_index/content_index_provider_factory.cc", "content_index/content_index_provider_factory.h", "content_index/content_index_provider_impl.cc",
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index b123bc33..778a0ff 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -141,6 +141,7 @@ auto java_web_contents = web_contents->GetJavaWebContents(); Java_AutofillAssistantUiController_setWebContents(env, java_object_, java_web_contents); + Java_AssistantModel_setWebContents(env, GetModel(), java_web_contents); Java_AssistantPaymentRequestModel_setWebContents( env, GetPaymentRequestModel(), java_web_contents); if (ui_delegate->GetState() != AutofillAssistantState::INACTIVE) { @@ -163,7 +164,7 @@ RectF visual_viewport; ui_delegate->GetVisualViewport(&visual_viewport); OnTouchableAreaChanged(visual_viewport, area, restricted_area); - OnResizeViewportChanged(ui_delegate->GetResizeViewport()); + OnViewportModeChanged(ui_delegate->GetViewportMode()); OnPeekModeChanged(ui_delegate->GetPeekMode()); OnFormChanged(ui_delegate->GetForm()); @@ -310,9 +311,9 @@ GetHeaderModel(), visible); } -void UiControllerAndroid::OnResizeViewportChanged(bool resize_viewport) { - Java_AutofillAssistantUiController_setResizeViewport( - AttachCurrentThread(), java_object_, resize_viewport); +void UiControllerAndroid::OnViewportModeChanged(ViewportMode mode) { + Java_AutofillAssistantUiController_setViewportMode(AttachCurrentThread(), + java_object_, mode); } void UiControllerAndroid::OnPeekModeChanged( @@ -638,7 +639,7 @@ ShowSnackbar(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_MAYBE_GIVE_UP), base::BindOnce(&UiControllerAndroid::Shutdown, weak_ptr_factory_.GetWeakPtr(), - Metrics::DropOutReason::SHEET_CLOSED)); + Metrics::DropOutReason::OVERLAY_STOP)); } void UiControllerAndroid::UpdateTouchableArea() {
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.h b/chrome/browser/android/autofill_assistant/ui_controller_android.h index 0db14f6..5a69baa 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.h +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.h
@@ -97,7 +97,7 @@ const RectF& visual_viewport, const std::vector<RectF>& touchable_areas, const std::vector<RectF>& restricted_areas) override; - void OnResizeViewportChanged(bool resize_viewport) override; + void OnViewportModeChanged(ViewportMode mode) override; void OnPeekModeChanged( ConfigureBottomSheetProto::PeekMode peek_mode) override; void OnOverlayColorsChanged(const UiDelegate::OverlayColors& colors) override;
diff --git a/chrome/browser/android/profiles/profile_downloader_android.cc b/chrome/browser/android/profiles/profile_downloader_android.cc index 1f2a15a..4bd2bcd 100644 --- a/chrome/browser/android/profiles/profile_downloader_android.cc +++ b/chrome/browser/android/profiles/profile_downloader_android.cc
@@ -198,7 +198,8 @@ auto maybe_account_info = IdentityManagerFactory::GetForProfile(profile) - ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(email); + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( + email); if (!maybe_account_info.has_value()) { LOG(ERROR) << "Attempted to get AccountInfo for account not in the "
diff --git a/chrome/browser/android/signin/signin_investigator_android.cc b/chrome/browser/android/signin/signin_investigator_android.cc index 158ba293..487c292 100644 --- a/chrome/browser/android/signin/signin_investigator_android.cc +++ b/chrome/browser/android/signin/signin_investigator_android.cc
@@ -31,7 +31,8 @@ // that it falls back to email comparison. base::Optional<AccountInfo> maybe_account_info = IdentityManagerFactory::GetForProfile(profile) - ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(email); + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( + email); std::string account_id; if (maybe_account_info.has_value()) account_id = maybe_account_info.value().account_id;
diff --git a/chrome/browser/android/signin/signin_manager_android.cc b/chrome/browser/android/signin/signin_manager_android.cc index 3c1ecf9d..90f2d69 100644 --- a/chrome/browser/android/signin/signin_manager_android.cc +++ b/chrome/browser/android/signin/signin_manager_android.cc
@@ -268,7 +268,8 @@ gaia::ExtractDomainName(username); CoreAccountInfo account = identity_manager_ - ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(username) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( + username) .value(); auto callback = @@ -320,7 +321,8 @@ base::Optional<CoreAccountInfo> account = identity_manager_ - ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(username); + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( + username); RegisterPolicyWithAccount( account.value_or(CoreAccountInfo{}),
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc index 2376bdf0..6104112 100644 --- a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc +++ b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
@@ -173,7 +173,7 @@ const std::string gaia_id = identity_manager - ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress( + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( account_name) ->gaia; DCHECK(!gaia_id.empty()); @@ -630,7 +630,7 @@ base::Optional<AccountInfo> account_info = identity_manager_ - ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress( + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( account_name); DCHECK(account_info.has_value()); @@ -711,8 +711,9 @@ const std::string& account_id, bool initial_signin) { base::Optional<AccountInfo> account_info = - identity_manager_->FindAccountInfoForAccountWithRefreshTokenByAccountId( - account_id); + identity_manager_ + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id); DCHECK(account_info.has_value()); auto fetcher = std::make_unique<ArcBackgroundAuthCodeFetcher>( url_loader_factory_, profile_, account_id, initial_signin,
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc index f5dd7536..1e6c2ecb 100644 --- a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc +++ b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
@@ -603,8 +603,9 @@ signin::IdentityManager* identity_manager = IdentityManagerFactory::GetForProfile(profile()); base::Optional<AccountInfo> maybe_account_info = - identity_manager->FindAccountInfoForAccountWithRefreshTokenByEmailAddress( - kSecondaryAccountEmail); + identity_manager + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( + kSecondaryAccountEmail); ASSERT_TRUE(maybe_account_info.has_value()); // Necessary to ensure that the OnExtendedAccountInfoRemoved() observer will
diff --git a/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.cc b/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.cc index 27011ff..d35ce5a 100644 --- a/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.cc +++ b/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.cc
@@ -35,6 +35,12 @@ namespace { +// List of algorithms that the extension claims to support for the returned +// certificates. +constexpr extensions::api::certificate_provider::Hash kSupportedHashes[] = { + extensions::api::certificate_provider::Hash::HASH_SHA256, + extensions::api::certificate_provider::Hash::HASH_SHA1}; + base::Value ConvertBytesToValue(base::span<const uint8_t> bytes) { base::Value value(base::Value::Type::LIST); for (auto byte : bytes) @@ -49,17 +55,17 @@ return bytes; } -base::Value MakeCertInfoValue( - const net::X509Certificate& certificate, - const std::vector<extensions::api::certificate_provider::Hash>& - supported_hashes) { +base::span<const uint8_t> GetCertDer(const net::X509Certificate& certificate) { + return base::as_bytes(base::make_span( + net::x509_util::CryptoBufferAsStringPiece(certificate.cert_buffer()))); +} + +base::Value MakeCertInfoValue(const net::X509Certificate& certificate) { base::Value cert_info_value(base::Value::Type::DICTIONARY); cert_info_value.SetKey("certificate", - ConvertBytesToValue(base::as_bytes(base::make_span( - net::x509_util::CryptoBufferAsStringPiece( - certificate.cert_buffer()))))); + ConvertBytesToValue(GetCertDer(certificate))); base::Value supported_hashes_value(base::Value::Type::LIST); - for (auto supported_hash : supported_hashes) { + for (auto supported_hash : kSupportedHashes) { supported_hashes_value.GetList().emplace_back(base::Value( extensions::api::certificate_provider::ToString(supported_hash))); } @@ -157,23 +163,34 @@ base::Value TestCertificateProviderExtension::HandleCertificatesRequest() { base::Value cert_info_values(base::Value::Type::LIST); - cert_info_values.GetList().emplace_back(MakeCertInfoValue( - *certificate_, - {extensions::api::certificate_provider::Hash::HASH_SHA256})); + if (!should_fail_certificate_requests_) + cert_info_values.GetList().emplace_back(MakeCertInfoValue(*certificate_)); return cert_info_values; } base::Value TestCertificateProviderExtension::HandleSignDigestRequest( const base::Value& sign_request) { - // TODO(crbug.com/826417): Verify the "certificate" field value. + CHECK_EQ(*sign_request.FindKey("certificate"), + ConvertBytesToValue(GetCertDer(*certificate_))); const std::vector<uint8_t> digest = ExtractBytesFromValue(*sign_request.FindKey("digest")); - CHECK_EQ(extensions::api::certificate_provider::Hash::HASH_SHA256, - extensions::api::certificate_provider::ParseHash( - sign_request.FindKey("hash")->GetString())); + const extensions::api::certificate_provider::Hash hash = + extensions::api::certificate_provider::ParseHash( + sign_request.FindKey("hash")->GetString()); + int openssl_digest_type = 0; + if (hash == extensions::api::certificate_provider::Hash::HASH_SHA256) + openssl_digest_type = NID_sha256; + else if (hash == extensions::api::certificate_provider::Hash::HASH_SHA1) + openssl_digest_type = NID_sha1; + else + LOG(FATAL) << "Unexpected signature request hash: " << hash; + + if (should_fail_sign_digest_requests_) + return base::Value(); std::vector<uint8_t> signature; - RsaSignPrehashed(*private_key_, NID_sha256, digest, &signature); + CHECK( + RsaSignPrehashed(*private_key_, openssl_digest_type, digest, &signature)); return ConvertBytesToValue(signature); }
diff --git a/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.h b/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.h index 1dbbd9e..fa5ed3a 100644 --- a/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.h +++ b/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.h
@@ -34,7 +34,8 @@ // It subscribes itself for requests from the JavaScript side of the extension, // and implements the cryptographic operations using the "client_1" test // certificate and private key (see src/net/data/ssl/certificates). The -// signature algorithm is currently hardcoded to SHA-256. +// supported signature algorithms are currently hardcoded to PKCS #1 v1.5 with +// SHA-1 and SHA-256. class TestCertificateProviderExtension final : public content::NotificationObserver { public: @@ -46,6 +47,20 @@ return certificate_; } + // Sets whether the extension should respond with a failure to the + // onCertificatesRequested requests. + void set_should_fail_certificate_requests( + bool should_fail_certificate_requests) { + should_fail_certificate_requests_ = should_fail_certificate_requests; + } + + // Sets whether the extension should respond with a failure to the + // onSignDigestRequested requests. + void set_should_fail_sign_digest_requests( + bool should_fail_sign_digest_requests) { + should_fail_sign_digest_requests_ = should_fail_sign_digest_requests; + } + private: // content::NotificationObserver implementation: void Observe(int type, @@ -57,8 +72,10 @@ content::BrowserContext* const browser_context_; const std::string extension_id_; - scoped_refptr<net::X509Certificate> certificate_; - bssl::UniquePtr<EVP_PKEY> private_key_; + const scoped_refptr<net::X509Certificate> certificate_; + const bssl::UniquePtr<EVP_PKEY> private_key_; + bool should_fail_certificate_requests_ = false; + bool should_fail_sign_digest_requests_ = false; content::NotificationRegistrar notification_registrar_; DISALLOW_COPY_AND_ASSIGN(TestCertificateProviderExtension);
diff --git a/chrome/browser/chromeos/dbus/cryptohome_key_delegate_service_provider_browsertest.cc b/chrome/browser/chromeos/dbus/cryptohome_key_delegate_service_provider_browsertest.cc index ee362877..f8d4d32c 100644 --- a/chrome/browser/chromeos/dbus/cryptohome_key_delegate_service_provider_browsertest.cc +++ b/chrome/browser/chromeos/dbus/cryptohome_key_delegate_service_provider_browsertest.cc
@@ -143,6 +143,14 @@ &service_provider_); PrepareExtension(); + + // Populate the browser's state with the mapping between the test + // certificate provider extension and the certs that it provides, so that + // the tested implementation knows where it should send challenges to. In + // the real-world usage, this step is done by the Login/Lock Screens while + // preparing the parameters that are later used by the cryptohomed daemon + // for calling our D-Bus service. + RefreshCertsFromCertProviders(); } void TearDownOnMainThread() override { @@ -169,8 +177,11 @@ // Calls the tested ChallengeKey D-Bus method, requesting a signature // challenge. - // Fills |signature| with the data returned by the call. - void CallSignatureChallengeKey(std::vector<uint8_t>* signature) { + // Returns whether the D-Bus method succeeded, and on success fills + // |signature| with the data returned by the call. + bool CallSignatureChallengeKey( + cryptohome::ChallengeSignatureAlgorithm signature_algorithm, + std::vector<uint8_t>* signature) { const cryptohome::AccountIdentifier account_identifier = cryptohome::CreateAccountIdentifierFromAccountId(EmptyAccountId()); cryptohome::KeyChallengeRequest request; @@ -180,7 +191,7 @@ request.mutable_signature_request_data()->set_public_key_spki_der( GetCertSpki(*cert_provider_extension_->certificate())); request.mutable_signature_request_data()->set_signature_algorithm( - cryptohome::CHALLENGE_RSASSA_PKCS1_V1_5_SHA256); + signature_algorithm); dbus::MethodCall method_call( cryptohome::kCryptohomeKeyDelegateInterface, @@ -192,6 +203,8 @@ std::unique_ptr<dbus::Response> dbus_response = dbus_service_test_helper_->CallMethod(&method_call); + if (dbus_response->GetMessageType() == dbus::Message::MESSAGE_ERROR) + return false; dbus::MessageReader reader(dbus_response.get()); cryptohome::KeyChallengeResponse response; EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&response)); @@ -199,16 +212,17 @@ EXPECT_TRUE(response.signature_response_data().has_signature()); signature->assign(response.signature_response_data().signature().begin(), response.signature_response_data().signature().end()); + return true; } // Returns whether the given |signature| is a valid signature of the original // data. - bool IsSignatureValid(const std::vector<uint8_t>& signature) const { + bool IsSignatureValid(crypto::SignatureVerifier::SignatureAlgorithm algorithm, + const std::vector<uint8_t>& signature) const { const std::string spki = GetCertSpki(*cert_provider_extension_->certificate()); crypto::SignatureVerifier verifier; - if (!verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA256, - signature, + if (!verifier.VerifyInit(algorithm, signature, base::as_bytes(base::make_span(spki)))) { return false; } @@ -216,6 +230,10 @@ return verifier.VerifyFinal(); } + TestCertificateProviderExtension* cert_provider_extension() { + return cert_provider_extension_.get(); + } + private: // Test certificate provider extension: const std::string kExtensionId = "ecmhnokcdiianioonpgakiooenfnonid"; @@ -244,19 +262,56 @@ std::unique_ptr<TestCertificateProviderExtension> cert_provider_extension_; }; -// Verifies that the ChallengeKey method handles the signature challenge request -// by passing the request to the certificate provider extension. +// Verifies that the ChallengeKey request with the PKCS #1 v1.5 SHA-256 +// algorithm is handled successfully using the test provider. IN_PROC_BROWSER_TEST_F(CryptohomeKeyDelegateServiceProviderTest, - SignatureBasic) { - // Populate the browser's state with the mapping between the test certificate - // provider extension and the certs that it provides, so that the tested - // implementation knows where it should send challenges to. In the real-world - // usage, this step is done by the Login/Lock Screens while preparing the - // parameters that are later used by the cryptohomed daemon for calling our - // D-Bus service. + SignatureSuccessSha256) { + std::vector<uint8_t> signature; + EXPECT_TRUE(CallSignatureChallengeKey( + cryptohome::CHALLENGE_RSASSA_PKCS1_V1_5_SHA256, &signature)); + EXPECT_TRUE( + IsSignatureValid(crypto::SignatureVerifier::RSA_PKCS1_SHA256, signature)); +} + +// Verifies that the ChallengeKey request with the PKCS #1 v1.5 SHA-1 algorithm +// is handled successfully using the test provider. +IN_PROC_BROWSER_TEST_F(CryptohomeKeyDelegateServiceProviderTest, + SignatureSuccessSha1) { + std::vector<uint8_t> signature; + EXPECT_TRUE(CallSignatureChallengeKey( + cryptohome::CHALLENGE_RSASSA_PKCS1_V1_5_SHA1, &signature)); + EXPECT_TRUE( + IsSignatureValid(crypto::SignatureVerifier::RSA_PKCS1_SHA1, signature)); +} + +// Verifies that the ChallengeKey request fails when the requested algorithm +// isn't supported by the test provider. +IN_PROC_BROWSER_TEST_F(CryptohomeKeyDelegateServiceProviderTest, + SignatureErrorUnsupportedAlgorithm) { + std::vector<uint8_t> signature; + EXPECT_FALSE(CallSignatureChallengeKey( + cryptohome::CHALLENGE_RSASSA_PKCS1_V1_5_SHA384, &signature)); +} + +// Verifies that the ChallengeKey request fails when the used key isn't reported +// by the test provider anymore. +IN_PROC_BROWSER_TEST_F(CryptohomeKeyDelegateServiceProviderTest, + SignatureErrorKeyRemoved) { + cert_provider_extension()->set_should_fail_certificate_requests(true); RefreshCertsFromCertProviders(); std::vector<uint8_t> signature; - CallSignatureChallengeKey(&signature); - EXPECT_TRUE(IsSignatureValid(signature)); + EXPECT_FALSE(CallSignatureChallengeKey( + cryptohome::CHALLENGE_RSASSA_PKCS1_V1_5_SHA256, &signature)); +} + +// Verifies that the ChallengeKey request fails when the test provider returns +// an error to the signature request. +IN_PROC_BROWSER_TEST_F(CryptohomeKeyDelegateServiceProviderTest, + SignatureErrorWhileSigning) { + cert_provider_extension()->set_should_fail_sign_digest_requests(true); + + std::vector<uint8_t> signature; + EXPECT_FALSE(CallSignatureChallengeKey( + cryptohome::CHALLENGE_RSASSA_PKCS1_V1_5_SHA256, &signature)); }
diff --git a/chrome/browser/chromeos/login/session/chrome_session_manager.cc b/chrome/browser/chromeos/login/session/chrome_session_manager.cc index 8cb8282..eba67a8 100644 --- a/chrome/browser/chromeos/login/session/chrome_session_manager.cc +++ b/chrome/browser/chromeos/login/session/chrome_session_manager.cc
@@ -269,7 +269,8 @@ std::string login_user_id = login_account_id.GetUserEmail(); IdentityManagerFactory::GetForProfile(profile) ->GetPrimaryAccountMutator() - ->SetPrimaryAccountAndUpdateAccountInfo(login_user_id, login_user_id); + ->DeprecatedSetPrimaryAccountAndUpdateAccountInfo(login_user_id, + login_user_id); StartUserSession(profile, login_user_id); return; }
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index 1d13e88..cf66964e 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -23,6 +23,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/path_service.h" #include "base/single_thread_task_runner.h" @@ -114,6 +115,8 @@ #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "chromeos/assistant/buildflags.h" +#include "chromeos/components/account_manager/account_manager.h" +#include "chromeos/components/account_manager/account_manager_factory.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/cryptohome/cryptohome_parameters.h" @@ -1319,17 +1322,17 @@ profile->GetPrefs()->SetString(prefs::kSupervisedUserId, supervised_user_sync_id); } else if (user_manager->IsLoggedInAsUserWithGaiaAccount()) { - // Get the Gaia ID from the user context. If it's not available, this may - // not be available when unlocking a previously opened profile, or when - // creating a supervised users. However, in these cases the gaia_id should - // be already available in the account tracker. + // Get the Gaia ID from the user context. This may not be available when + // unlocking a previously opened profile, or when creating a supervised + // user. However, in these cases the gaia_id should be already available in + // |IdentityManager|. signin::IdentityManager* identity_manager = IdentityManagerFactory::GetForProfile(profile); std::string gaia_id = user_context.GetGaiaID(); if (gaia_id.empty()) { base::Optional<AccountInfo> maybe_account_info = identity_manager - ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress( + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( user_context.GetAccountId().GetUserEmail()); DCHECK(maybe_account_info.has_value() || IsRunningTest()); @@ -1343,12 +1346,97 @@ DCHECK(!gaia_id.empty()); } - // Make sure that the google service username is properly set (we do this - // on every sign in, not just the first login, to deal with existing - // profiles that might not have it set yet). - identity_manager->GetPrimaryAccountMutator() - ->SetPrimaryAccountAndUpdateAccountInfo( - gaia_id, user_context.GetAccountId().GetUserEmail()); + bool should_use_legacy_flow = false; + if (!switches::IsAccountManagerEnabled()) { + // Always use the legacy flow if Account Manager has not been enabled yet. + should_use_legacy_flow = true; + } else if (!identity_manager + ->FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId( + gaia_id) + .has_value() && + user_context.GetRefreshToken().empty()) { + // Edge case: |AccountManager| is enabled but neither |IdentityManager| + // nor |user_context| has the refresh token. This means that an existing + // user has switched on Account Manager for the first time and has not + // undergone the migration flow yet. This migration will be done shorty + // in-session. + // TODO(https://crbug.com/987955): Remove this. + should_use_legacy_flow = true; + } + base::UmaHistogramBoolean( + "AccountManager.LegacySetPrimaryAccountAndUpdateAccountInfo", + should_use_legacy_flow); + + if (!should_use_legacy_flow) { + // We need to set the Primary Account. This is handled by + // |IdentityManager|, which enforces the invariant that only an account + // previously known to |IdentityManager| can be set as the Primary + // Account. |IdentityManager| gets its knowledge of accounts from + // |AccountManager| and hence, before we set the Primary Account, we need + // to make sure that: + // 1. The account is present in |AccountManager|, and + // 2. |IdentityManager| has been notified about it. + + AccountManager* account_manager = + g_browser_process->platform_part() + ->GetAccountManagerFactory() + ->GetAccountManager(profile->GetPath().value()); + + // |AccountManager| MUST have been fully initialized at this point (via + // |UserSessionManager::InitializeAccountManager|), otherwise we cannot + // guarantee that |IdentityManager| will have this account in Step (2). + // Reason: |AccountManager::UpsertAccount| is an async API that can + // technically take an arbitrarily long amount of time to complete and + // notify |AccountManager|'s observers. However, if |AccountManager| has + // been fully initialized, |AccountManager::UpsertAccount| and the + // associated notifications happen synchronously. We are relying on that + // (undocumented) behaviour here. + // TODO(sinhak): This is a leaky abstraction. Explore if + // |UserSessionManager::InitProfilePreferences| can handle an asynchronous + // callback and continue. + DCHECK(account_manager->IsInitialized()); + + // 1. Make sure that the account is present in |AccountManager|. + if (!user_context.GetRefreshToken().empty()) { + // |AccountManager::UpsertAccount| is idempotent. We can safely call it + // without checking for re-auth cases. + // We MUST NOT revoke old Device Account tokens (|revoke_old_token| = + // |false|), otherwise Gaia will revoke all tokens associated to this + // user's device id, including |refresh_token_| and the user will be + // stuck performing an online auth with Gaia at every login. See + // https://crbug.com/952570 and https://crbug.com/865189 for context. + account_manager->UpsertAccount( + AccountManager::AccountKey{ + gaia_id, account_manager::AccountType::ACCOUNT_TYPE_GAIA}, + user->GetDisplayEmail() /* raw_email */, + user_context.GetRefreshToken(), false /* revoke_old_token */); + } + // else: If |user_context| does not contain a refresh token, then we are + // restoring an existing Profile, in which case the account will be + // already present in |AccountManager|. + + // 2. Make sure that IdentityManager has been notified about it. + base::Optional<AccountInfo> maybe_account_info = + identity_manager + ->FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId( + gaia_id); + DCHECK(maybe_account_info.has_value()); + // Make sure that the google service username is properly set (we do this + // on every sign in, not just the first login, to deal with existing + // profiles that might not have it set yet). + identity_manager->GetPrimaryAccountMutator()->SetPrimaryAccount( + maybe_account_info->account_id); + } else { + // Make sure that the google service username is properly set (we do this + // on every sign in, not just the first login, to deal with existing + // profiles that might not have it set yet). + // TODO(https://crbug.com/987955): Check the UMA stat and remove it when + // all users have been migrated to Account Manager. + identity_manager->GetPrimaryAccountMutator() + ->DeprecatedSetPrimaryAccountAndUpdateAccountInfo( + gaia_id, user_context.GetAccountId().GetUserEmail()); + } + std::string account_id = identity_manager->GetPrimaryAccountId(); VLOG(1) << "Seed IdentityManager with the authenticated account info, " << "success=" << !account_id.empty();
diff --git a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc index 661dfc0..e3519ef 100644 --- a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc +++ b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
@@ -701,7 +701,8 @@ IdentityManagerFactory::GetInstance()->GetForProfile(GetProfile()); EXPECT_TRUE( identity_manager - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(kTestEmail) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + kTestEmail) ->is_under_advanced_protection); } @@ -715,7 +716,8 @@ IdentityManagerFactory::GetInstance()->GetForProfile(GetProfile()); EXPECT_FALSE( identity_manager - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(kTestEmail) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + kTestEmail) ->is_under_advanced_protection); }
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc b/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc index 61c8f56..d95d0a9 100644 --- a/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc +++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc
@@ -9,14 +9,11 @@ #include "base/command_line.h" #include "base/metrics/histogram_macros.h" -#include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/account_id_from_account_info.h" #include "chrome/browser/signin/chrome_device_id_helper.h" #include "chrome/browser/signin/identity_manager_factory.h" -#include "chromeos/components/account_manager/account_manager.h" -#include "chromeos/components/account_manager/account_manager_factory.h" #include "chromeos/constants/chromeos_switches.h" #include "components/signin/public/base/signin_metrics.h" #include "components/signin/public/identity_manager/accounts_mutator.h" @@ -161,47 +158,29 @@ void OAuth2LoginManager::StoreOAuth2Token() { DCHECK(!refresh_token_.empty()); + signin::IdentityManager* identity_manager = GetIdentityManager(); + // The primary account must be already set at this point. + DCHECK(identity_manager->HasPrimaryAccount()); + const CoreAccountInfo primary_account_info = + identity_manager->GetPrimaryAccountInfo(); + if (switches::IsAccountManagerEnabled()) { - AccountManagerFactory* factory = - g_browser_process->platform_part()->GetAccountManagerFactory(); - AccountManager* account_manager = - factory->GetAccountManager(user_profile_->GetPath().value()); - - user_manager::User* const user = - ProfileHelper::Get()->GetUserByProfile(user_profile_); - - // We MUST NOT revoke old Device Account tokens, otherwise Gaia will revoke - // all tokens associated to this user's device id, including - // |refresh_token_| and the user will be stuck performing an online auth - // with Gaia at every login. See https://crbug.com/952570 and - // https://crbug.com/865189 for context. - account_manager->UpsertAccount( - AccountManager::AccountKey{ - user->GetAccountId().GetGaiaId(), - account_manager::AccountType::ACCOUNT_TYPE_GAIA}, - user->display_email() /* raw_email */, refresh_token_, - false /* revoke_old_token */); + // If Account Manager is enabled, we already have the refresh token at this + // point, and will not get any additional callbacks from Account Manager or + // Identity Manager about refresh tokens. Manually call + // |OnRefreshTokenUpdatedForAccount| to continue the flow. + // TODO(https://crbug.com/977137): Clean this up after cleaning + // OAuth2LoginVerifier. + OnRefreshTokenUpdatedForAccount(primary_account_info); } else { - // TODO(sinhak): Remove this when Account Manager is enabled by default. - - signin::IdentityManager* identity_manager = GetIdentityManager(); - DCHECK(identity_manager->HasPrimaryAccount()); - - // On ChromeOS, the primary account is set via - // PrimaryAccountMutator::SetPrimaryAccountAndUpdateAccountInfo(), which - // seeds the account info with AccountTrackerService. Hence, the primary - // account info will be available at this point. - const CoreAccountInfo primary_account_info = - identity_manager->GetPrimaryAccountInfo(); + // TODO(https://crbug.com/987955): Remove this when Account Manager is + // enabled by default. identity_manager->GetAccountsMutator()->AddOrUpdateAccount( primary_account_info.gaia, primary_account_info.email, refresh_token_, primary_account_info.is_under_advanced_protection, signin_metrics::SourceForRefreshTokenOperation::kUnknown); } - - for (auto& observer : observer_list_) - observer.OnNewRefreshTokenAvaiable(user_profile_); } void OAuth2LoginManager::VerifySessionCookies() {
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager.h b/chrome/browser/chromeos/login/signin/oauth2_login_manager.h index 27e483b..8782cc0 100644 --- a/chrome/browser/chromeos/login/signin/oauth2_login_manager.h +++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include <vector> #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -68,9 +69,6 @@ virtual void OnSessionRestoreStateChanged(Profile* user_profile, SessionRestoreState state) {} - // Raised when a new OAuth2 refresh token is available. - virtual void OnNewRefreshTokenAvaiable(Profile* user_profile) {} - // Raised when session's GAIA credentials (SID+LSID) are available to // other signed in services. virtual void OnSessionAuthenticated(Profile* user_profile) {}
diff --git a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.cc b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.cc index c882b84..4a31ad0 100644 --- a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.cc +++ b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.cc
@@ -130,8 +130,11 @@ } void DeviceOffHoursController::UpdateOffHoursMode() { - if (off_hours_intervals_.empty() || !network_synchronized_) { - if (!network_synchronized_) { + // Assume that time is network synchronized if response from dbus call is not + // arrived. + bool is_time_network_synchronized = network_synchronized_.value_or(true); + if (off_hours_intervals_.empty() || !is_time_network_synchronized) { + if (!is_time_network_synchronized) { VLOG(1) << "The system time isn't network synchronized. OffHours mode is " "unavailable."; }
diff --git a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.h b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.h index abc65d2..19204f8 100644 --- a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.h +++ b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.h
@@ -136,8 +136,10 @@ // base::DefaultClock. base::Clock* clock_; - // Value is false until the system time is synchronized with network time. - bool network_synchronized_ = false; + // Value is true if the system time is synchronized with network time, and + // false when synchronization failed. Value is not set until the response from + // the D-Bus call is not arrived. + base::Optional<bool> network_synchronized_; // Current "OffHours" time intervals. std::vector<WeeklyTimeInterval> off_hours_intervals_;
diff --git a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller_unittest.cc b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller_unittest.cc index 030a0077..c21383a4 100644 --- a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller_unittest.cc +++ b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller_unittest.cc
@@ -108,6 +108,7 @@ void SetUp() override { chromeos::DeviceSettingsTestBase::SetUp(); chromeos::SystemClockClient::InitializeFake(); + system_clock_client()->SetServiceIsAvailable(false); device_settings_service_->SetDeviceOffHoursControllerForTesting( std::make_unique<policy::off_hours::DeviceOffHoursController>()); @@ -156,6 +157,7 @@ }; TEST_F(DeviceOffHoursControllerSimpleTest, CheckOffHoursUnset) { + system_clock_client()->SetServiceIsAvailable(true); system_clock_client()->SetNetworkSynchronized(true); system_clock_client()->NotifyObserversSystemClockUpdated(); em::ChromeDeviceSettingsProto& proto(device_policy_->payload()); @@ -172,6 +174,7 @@ } TEST_F(DeviceOffHoursControllerSimpleTest, CheckOffHoursModeOff) { + system_clock_client()->SetServiceIsAvailable(true); system_clock_client()->SetNetworkSynchronized(true); system_clock_client()->NotifyObserversSystemClockUpdated(); em::ChromeDeviceSettingsProto& proto(device_policy_->payload()); @@ -197,6 +200,7 @@ } TEST_F(DeviceOffHoursControllerSimpleTest, CheckOffHoursModeOn) { + system_clock_client()->SetServiceIsAvailable(true); system_clock_client()->SetNetworkSynchronized(true); system_clock_client()->NotifyObserversSystemClockUpdated(); em::ChromeDeviceSettingsProto& proto(device_policy_->payload()); @@ -220,7 +224,37 @@ .guest_mode_enabled()); } +TEST_F(DeviceOffHoursControllerSimpleTest, + CheckOffHoursEnabledBeforeSystemClockUpdated) { + system_clock_client()->SetServiceIsAvailable(false); + em::ChromeDeviceSettingsProto& proto(device_policy_->payload()); + proto.mutable_guest_mode_enabled()->set_guest_mode_enabled(false); + UpdateDeviceSettings(); + int current_day_of_week = ExtractDayOfWeek(base::Time::Now()); + SetOffHoursPolicyToProto( + &proto, + OffHoursPolicy( + kUtcTimezone, + {WeeklyTimeInterval( + WeeklyTime(current_day_of_week, 0, 0), + WeeklyTime(NextDayOfWeek(current_day_of_week), + TimeDelta::FromHours(10).InMilliseconds(), 0))})); + UpdateDeviceSettings(); + // Trust the time until response from SystemClock is received. + EXPECT_TRUE(device_off_hours_controller()->is_off_hours_mode()); + + // SystemClock is updated. + system_clock_client()->SetServiceIsAvailable(true); + system_clock_client()->SetNetworkSynchronized(false); + system_clock_client()->NotifyObserversSystemClockUpdated(); + UpdateDeviceSettings(); + + // Response from SystemClock arrived, stop trusting the time. + EXPECT_FALSE(device_off_hours_controller()->is_off_hours_mode()); +} + TEST_F(DeviceOffHoursControllerSimpleTest, NoNetworkSynchronization) { + system_clock_client()->SetServiceIsAvailable(true); system_clock_client()->SetNetworkSynchronized(false); system_clock_client()->NotifyObserversSystemClockUpdated(); em::ChromeDeviceSettingsProto& proto(device_policy_->payload()); @@ -245,6 +279,7 @@ TEST_F(DeviceOffHoursControllerSimpleTest, IsCurrentSessionAllowedOnlyForOffHours) { + system_clock_client()->SetServiceIsAvailable(true); EXPECT_FALSE( device_off_hours_controller()->IsCurrentSessionAllowedOnlyForOffHours()); @@ -308,6 +343,7 @@ }; TEST_F(DeviceOffHoursControllerFakeClockTest, FakeClock) { + system_clock_client()->SetServiceIsAvailable(true); EXPECT_FALSE(device_off_hours_controller()->is_off_hours_mode()); int current_day_of_week = ExtractDayOfWeek(clock()->Now()); em::ChromeDeviceSettingsProto& proto(device_policy_->payload()); @@ -329,6 +365,7 @@ } TEST_F(DeviceOffHoursControllerFakeClockTest, CheckSendSuspendDone) { + system_clock_client()->SetServiceIsAvailable(true); int current_day_of_week = ExtractDayOfWeek(clock()->Now()); LOG(ERROR) << "day " << current_day_of_week; em::ChromeDeviceSettingsProto& proto(device_policy_->payload()); @@ -362,6 +399,7 @@ }; TEST_P(DeviceOffHoursControllerUpdateTest, CheckUpdateOffHoursPolicy) { + system_clock_client()->SetServiceIsAvailable(true); em::ChromeDeviceSettingsProto& proto(device_policy_->payload()); SetOffHoursPolicyToProto(&proto, off_hours_policy()); AdvanceTestClock(advance_clock());
diff --git a/chrome/browser/chromeos/policy/system_log_uploader.cc b/chrome/browser/chromeos/policy/system_log_uploader.cc index 8ace7c1..48a3009 100644 --- a/chrome/browser/chromeos/policy/system_log_uploader.cc +++ b/chrome/browser/chromeos/policy/system_log_uploader.cc
@@ -173,9 +173,12 @@ user_manager::UserManager::Get()->GetPrimaryUser()->IsAffiliated(); } } - return policy::GetAllPolicyValuesAsJSON( - ProfileManager::GetActiveUserProfile(), include_user_policies, - true /* with_device_data */, true /* is_pretty_print */); + return policy::DictionaryPolicyConversions() + .WithBrowserContext(ProfileManager::GetActiveUserProfile()) + .EnableUserPolicies(include_user_policies) + .EnableDevicePolicies(true) + .EnableDeviceInfo(true) + .ToJSON(); } void SystemLogDelegate::LoadSystemLogs(LogUploadCallback upload_callback) {
diff --git a/chrome/browser/content_index/content_index_browsertest.cc b/chrome/browser/content_index/content_index_browsertest.cc index f9f0284f..447f032 100644 --- a/chrome/browser/content_index/content_index_browsertest.cc +++ b/chrome/browser/content_index/content_index_browsertest.cc
@@ -11,6 +11,7 @@ #include "base/run_loop.h" #include "base/strings/string_util.h" #include "base/test/bind_test_util.h" +#include "base/test/metrics/histogram_tester.h" #include "chrome/browser/content_index/content_index_provider_impl.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -22,6 +23,7 @@ #include "content/public/common/content_switches.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "testing/gmock/include/gmock/gmock.h" +#include "third_party/blink/public/common/service_worker/service_worker_status_code.h" #include "third_party/re2/src/re2/re2.h" #include "url/gurl.h" @@ -265,4 +267,66 @@ EXPECT_TRUE(GetAllItems().empty()); } +IN_PROC_BROWSER_TEST_F(ContentIndexTest, UmaCollected) { + // Inititally there is no content. + { + base::HistogramTester histogram_tester; + EXPECT_TRUE(GetAllItems().empty()); + histogram_tester.ExpectUniqueSample("ContentIndex.NumEntriesAvailable", 0, + 1); + } + + // Record that two articles were added. + { + base::HistogramTester histogram_tester; + RunScript("AddContent('my-id-1')"); + RunScript("AddContent('my-id-2')"); + base::RunLoop() + .RunUntilIdle(); // Wait for the provider to get the content. + histogram_tester.ExpectBucketCount( + "ContentIndex.ContentAdded", blink::mojom::ContentCategory::ARTICLE, 2); + } + + // Querying the items should record that there are 2 entries available. + { + base::HistogramTester histogram_tester; + EXPECT_EQ(GetAllItems().size(), 2u); + histogram_tester.ExpectUniqueSample("ContentIndex.NumEntriesAvailable", 2, + 1); + } + + // User deletion will dispatch an event. + { + base::HistogramTester histogram_tester; + provider()->RemoveItem(offline_items().at("my-id-1").id); + EXPECT_EQ(RunScript("waitForMessageFromServiceWorker()"), "my-id-1"); + base::RunLoop().RunUntilIdle(); + + histogram_tester.ExpectBucketCount("ContentIndex.ContentDeleteEvent.Find", + blink::ServiceWorkerStatusCode::kOk, 1); + histogram_tester.ExpectBucketCount("ContentIndex.ContentDeleteEvent.Start", + blink::ServiceWorkerStatusCode::kOk, 1); + histogram_tester.ExpectBucketCount( + "ContentIndex.ContentDeleteEvent.Dispatch", + blink::ServiceWorkerStatusCode::kOk, 1); + } + + // Opening an article is recorded. + { + base::HistogramTester histogram_tester; + provider()->OpenItem( + offline_items_collection::LaunchLocation::DOWNLOAD_HOME, + offline_items().at("my-id-2").id); + + // Wait for the page to open. + base::RunLoop run_loop; + SetTabChangeQuitClosure(run_loop.QuitClosure()); + run_loop.Run(); + + histogram_tester.ExpectBucketCount("ContentIndex.ContentOpened", + blink::mojom::ContentCategory::ARTICLE, + 1); + } +} + } // namespace
diff --git a/chrome/browser/content_index/content_index_metrics.cc b/chrome/browser/content_index/content_index_metrics.cc new file mode 100644 index 0000000..2b004a2 --- /dev/null +++ b/chrome/browser/content_index/content_index_metrics.cc
@@ -0,0 +1,23 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/content_index/content_index_metrics.h" + +#include "base/metrics/histogram_functions.h" + +namespace content_index { + +void RecordContentAdded(blink::mojom::ContentCategory category) { + base::UmaHistogramEnumeration("ContentIndex.ContentAdded", category); +} + +void RecordContentOpened(blink::mojom::ContentCategory category) { + base::UmaHistogramEnumeration("ContentIndex.ContentOpened", category); +} + +void RecordContentIndexEntries(size_t num_entries) { + base::UmaHistogramCounts1000("ContentIndex.NumEntriesAvailable", num_entries); +} + +} // namespace content_index
diff --git a/chrome/browser/content_index/content_index_metrics.h b/chrome/browser/content_index/content_index_metrics.h new file mode 100644 index 0000000..c517ce4 --- /dev/null +++ b/chrome/browser/content_index/content_index_metrics.h
@@ -0,0 +1,23 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CONTENT_INDEX_CONTENT_INDEX_METRICS_H_ +#define CHROME_BROWSER_CONTENT_INDEX_CONTENT_INDEX_METRICS_H_ + +#include "third_party/blink/public/mojom/content_index/content_index.mojom.h" + +namespace content_index { + +// Records the category of the Content Index entry after registration. +void RecordContentAdded(blink::mojom::ContentCategory category); + +// Records the category of the Content Index entry when a user opens it. +void RecordContentOpened(blink::mojom::ContentCategory category); + +// Records the number of Content Index entries available when requested. +void RecordContentIndexEntries(size_t num_entries); + +} // namespace content_index + +#endif // CHROME_BROWSER_CONTENT_INDEX_CONTENT_INDEX_METRICS_H_
diff --git a/chrome/browser/content_index/content_index_provider_impl.cc b/chrome/browser/content_index/content_index_provider_impl.cc index 9291553..aad3de5 100644 --- a/chrome/browser/content_index/content_index_provider_impl.cc +++ b/chrome/browser/content_index/content_index_provider_impl.cc
@@ -11,6 +11,7 @@ #include "base/strings/string_split.h" #include "base/task/post_task.h" #include "build/build_config.h" +#include "chrome/browser/content_index/content_index_metrics.h" #include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h" #include "chrome/browser/profiles/profile.h" #include "components/offline_items_collection/core/offline_content_aggregator.h" @@ -128,6 +129,7 @@ void DidGetAllEntriesAcrossStorageParitions( std::unique_ptr<ContentIndexProviderImpl::OfflineItemList> item_list, ContentIndexProviderImpl::MultipleItemCallback callback) { + content_index::RecordContentIndexEntries(item_list->size()); std::move(callback).Run(*item_list); } @@ -163,6 +165,8 @@ for (auto& observer : observers_) observer.OnItemsAdded(items); + + content_index::RecordContentAdded(entry.description->category); } void ContentIndexProviderImpl::OnContentDeleted( @@ -211,6 +215,8 @@ ui::PAGE_TRANSITION_LINK); Navigate(&nav_params); #endif + + content_index::RecordContentOpened(entry->description->category); } void ContentIndexProviderImpl::RemoveItem(const ContentId& id) {
diff --git a/chrome/browser/data_saver/subresource_redirect_browsertest.cc b/chrome/browser/data_saver/subresource_redirect_browsertest.cc index 8755d7bd..47b5382 100644 --- a/chrome/browser/data_saver/subresource_redirect_browsertest.cc +++ b/chrome/browser/data_saver/subresource_redirect_browsertest.cc
@@ -97,9 +97,17 @@ return result; } + std::string RunScriptExtractString(const std::string& script) { + std::string result; + EXPECT_TRUE(ExecuteScriptAndExtractString( + browser()->tab_strip_model()->GetActiveWebContents(), script, &result)); + return result; + } + GURL http_url() const { return http_url_; } GURL https_url() const { return https_url_; } GURL compression_url() const { return compression_url_; } + GURL request_url() const { return request_url_; } GURL HttpURLWithPath(const std::string& path) { return http_server_->GetURL("insecure.com", path); @@ -108,6 +116,8 @@ return https_server_->GetURL("secure.com", path); } + void SetCompressionServerToFail() { compression_server_fail_ = true; } + base::HistogramTester* histogram_tester() { return &histogram_tester_; } private: @@ -122,6 +132,12 @@ HandleCompressionServerRequest(const net::test_server::HttpRequest& request) { std::unique_ptr<net::test_server::BasicHttpResponse> response = std::make_unique<net::test_server::BasicHttpResponse>(); + request_url_ = request.GetURL(); + + // If |compression_server_fail_| is set to true, return a hung response. + if (compression_server_fail_ == true) { + return std::make_unique<net::test_server::RawHttpResponse>("", ""); + } // For the purpose of this browsertest, a redirect to the compression server // that is looking to access image.png will be treated as though it is @@ -131,6 +147,11 @@ net::EscapeQueryParamValue("/image.png", true /* use_plus */), 0) != std::string::npos) { response->set_code(net::HTTP_OK); + } else if (request.GetURL().query().find( + net::EscapeQueryParamValue("/fail_image.png", + true /* use_plus */), + 0) != std::string::npos) { + response->set_code(net::HTTP_NOT_FOUND); } else { response->set_code(net::HTTP_TEMPORARY_REDIRECT); response->AddCustomHeader( @@ -143,6 +164,7 @@ GURL compression_url_; GURL http_url_; GURL https_url_; + GURL request_url_; std::unique_ptr<net::EmbeddedTestServer> http_server_; std::unique_ptr<net::EmbeddedTestServer> https_server_; @@ -150,6 +172,8 @@ base::HistogramTester histogram_tester_; + bool compression_server_fail_ = false; + DISALLOW_COPY_AND_ASSIGN(SubresourceRedirectBrowserTest); }; @@ -167,16 +191,19 @@ HttpsURLWithPath("/load_image/image.html")); RetryForHistogramUntilCountReached( - histogram_tester(), "SubresourceRedirect.CompressionAttempt.Status", 2); + histogram_tester(), "SubresourceRedirect.CompressionAttempt.ResponseCode", + 2); histogram_tester()->ExpectBucketCount( - "SubresourceRedirect.CompressionAttempt.Status", net::HTTP_OK, 1); + "SubresourceRedirect.CompressionAttempt.ResponseCode", net::HTTP_OK, 1); histogram_tester()->ExpectBucketCount( - "SubresourceRedirect.CompressionAttempt.Status", + "SubresourceRedirect.CompressionAttempt.ResponseCode", net::HTTP_TEMPORARY_REDIRECT, 1); EXPECT_TRUE(RunScriptExtractBool("checkImage()")); + + EXPECT_EQ(request_url().port(), compression_url().port()); } // This test loads private_url_image.html, which triggers a subresource @@ -189,13 +216,17 @@ browser(), HttpsURLWithPath("/load_image/private_url_image.html")); RetryForHistogramUntilCountReached( - histogram_tester(), "SubresourceRedirect.CompressionAttempt.Status", 2); + histogram_tester(), "SubresourceRedirect.CompressionAttempt.ResponseCode", + 2); histogram_tester()->ExpectBucketCount( - "SubresourceRedirect.CompressionAttempt.Status", + "SubresourceRedirect.CompressionAttempt.ResponseCode", net::HTTP_TEMPORARY_REDIRECT, 2); EXPECT_TRUE(RunScriptExtractBool("checkImage()")); + + EXPECT_EQ(GURL(RunScriptExtractString("imageSrc()")).port(), + https_url().port()); } // This test loads image_js.html, which triggers a javascript request @@ -207,16 +238,20 @@ HttpsURLWithPath("/load_image/image_js.html")); RetryForHistogramUntilCountReached( - histogram_tester(), "SubresourceRedirect.CompressionAttempt.Status", 2); + histogram_tester(), "SubresourceRedirect.CompressionAttempt.ResponseCode", + 2); histogram_tester()->ExpectBucketCount( - "SubresourceRedirect.CompressionAttempt.Status", net::HTTP_OK, 1); + "SubresourceRedirect.CompressionAttempt.ResponseCode", net::HTTP_OK, 1); histogram_tester()->ExpectBucketCount( - "SubresourceRedirect.CompressionAttempt.Status", + "SubresourceRedirect.CompressionAttempt.ResponseCode", net::HTTP_TEMPORARY_REDIRECT, 1); EXPECT_TRUE(RunScriptExtractBool("checkImage()")); + + EXPECT_EQ(GURL(RunScriptExtractString("imageSrc()")).port(), + https_url().port()); } // This test loads private_url_image.html, which triggers a javascript @@ -229,13 +264,17 @@ browser(), HttpsURLWithPath("/load_image/private_url_image_js.html")); RetryForHistogramUntilCountReached( - histogram_tester(), "SubresourceRedirect.CompressionAttempt.Status", 2); + histogram_tester(), "SubresourceRedirect.CompressionAttempt.ResponseCode", + 2); histogram_tester()->ExpectBucketCount( - "SubresourceRedirect.CompressionAttempt.Status", + "SubresourceRedirect.CompressionAttempt.ResponseCode", net::HTTP_TEMPORARY_REDIRECT, 2); EXPECT_TRUE(RunScriptExtractBool("checkImage()")); + + EXPECT_EQ(GURL(RunScriptExtractString("imageSrc()")).port(), + https_url().port()); } // This test loads image.html, from a non secure site. This triggers a @@ -250,7 +289,12 @@ SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); histogram_tester()->ExpectTotalCount( - "SubresourceRedirect.CompressionAttempt.Status", 0); + "SubresourceRedirect.CompressionAttempt.ResponseCode", 0); + + EXPECT_TRUE(RunScriptExtractBool("checkImage()")); + + EXPECT_EQ(GURL(RunScriptExtractString("imageSrc()")).port(), + http_url().port()); } // This test loads page_with_favicon.html, which creates a subresource @@ -264,7 +308,60 @@ SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); histogram_tester()->ExpectTotalCount( - "SubresourceRedirect.CompressionAttempt.Status", 0); + "SubresourceRedirect.CompressionAttempt.ResponseCode", 0); } } // namespace + +// This test loads a resource that will return a 404 from the server, this +// should trigger the fallback logic back to the original resource. In total +// This results in 2 redirects (to the compression server, and back to the +// original resource), 1 404 not-found from the compression server, and 1 +// 200 ok from the original resource. +IN_PROC_BROWSER_TEST_F(SubresourceRedirectBrowserTest, + FallbackOnServerNotFound) { + ui_test_utils::NavigateToURL(browser(), + HttpsURLWithPath("/load_image/fail_image.html")); + + content::FetchHistogramsFromChildProcesses(); + SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + + histogram_tester()->ExpectTotalCount( + "SubresourceRedirect.CompressionAttempt.ResponseCode", 3); + + histogram_tester()->ExpectBucketCount( + "SubresourceRedirect.CompressionAttempt.ResponseCode", + net::HTTP_TEMPORARY_REDIRECT, 2); + + histogram_tester()->ExpectBucketCount( + "SubresourceRedirect.CompressionAttempt.ResponseCode", + net::HTTP_NOT_FOUND, 1); + + EXPECT_TRUE(RunScriptExtractBool("checkImage()")); + + EXPECT_EQ(GURL(RunScriptExtractString("imageSrc()")).port(), + https_url().port()); +} + +// This test verifies that the client will utilize the fallback logic if the +// server/network fails and returns nothing. +IN_PROC_BROWSER_TEST_F(SubresourceRedirectBrowserTest, + FallbackOnServerFailure) { + SetCompressionServerToFail(); + + base::RunLoop().RunUntilIdle(); + ui_test_utils::NavigateToURL(browser(), + HttpsURLWithPath("/load_image/image.html")); + + RetryForHistogramUntilCountReached( + histogram_tester(), + "SubresourceRedirect.CompressionAttempt.ServerResponded", 1); + + histogram_tester()->ExpectBucketCount( + "SubresourceRedirect.CompressionAttempt.ServerResponded", false, 1); + + EXPECT_TRUE(RunScriptExtractBool("checkImage()")); + + EXPECT_EQ(GURL(RunScriptExtractString("imageSrc()")).port(), + https_url().port()); +}
diff --git a/chrome/browser/devtools/device/android_device_manager.cc b/chrome/browser/devtools/device/android_device_manager.cc index ce20fba..642ced71 100644 --- a/chrome/browser/devtools/device/android_device_manager.cc +++ b/chrome/browser/devtools/device/android_device_manager.cc
@@ -12,7 +12,7 @@ #include "base/bind.h" #include "base/location.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -516,7 +516,7 @@ instance_ = this; thread_ = new base::Thread(kDevToolsAdbBridgeThreadName); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; if (!thread_->StartWithOptions(options)) { delete thread_; thread_ = nullptr;
diff --git a/chrome/browser/devtools/inspector_protocol_config.json b/chrome/browser/devtools/inspector_protocol_config.json index ae2a2d8..5389729 100644 --- a/chrome/browser/devtools/inspector_protocol_config.json +++ b/chrome/browser/devtools/inspector_protocol_config.json
@@ -14,7 +14,7 @@ }, { "domain": "Browser", - "include": [ "getWindowForTarget", "getWindowBounds", "setWindowBounds", "close", "grantPermissions", "resetPermissions", "setDockTile" ], + "include": [ "getWindowForTarget", "getWindowBounds", "setWindowBounds", "close", "setDockTile" ], "include_events": [] }, {
diff --git a/chrome/browser/devtools/protocol/browser_handler.cc b/chrome/browser/devtools/protocol/browser_handler.cc index 2bc97ef..0dcf07c 100644 --- a/chrome/browser/devtools/protocol/browser_handler.cc +++ b/chrome/browser/devtools/protocol/browser_handler.cc
@@ -13,8 +13,6 @@ #include "chrome/browser/devtools/chrome_devtools_manager_delegate.h" #include "chrome/browser/devtools/devtools_dock_tile.h" #include "chrome/browser/lifetime/application_lifetime.h" -#include "chrome/browser/permissions/permission_manager.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_context.h" @@ -25,7 +23,6 @@ #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_png_rep.h" -using PermissionOverrides = std::set<content::PermissionType>; using protocol::Maybe; using protocol::Response; @@ -63,53 +60,6 @@ .Build(); } -Response FromProtocolPermissionType( - const protocol::Browser::PermissionType& type, - content::PermissionType* out_type) { - if (type == protocol::Browser::PermissionTypeEnum::Notifications) { - *out_type = content::PermissionType::NOTIFICATIONS; - } else if (type == protocol::Browser::PermissionTypeEnum::Geolocation) { - *out_type = content::PermissionType::GEOLOCATION; - } else if (type == - protocol::Browser::PermissionTypeEnum::ProtectedMediaIdentifier) { - *out_type = content::PermissionType::PROTECTED_MEDIA_IDENTIFIER; - } else if (type == protocol::Browser::PermissionTypeEnum::Midi) { - *out_type = content::PermissionType::MIDI; - } else if (type == protocol::Browser::PermissionTypeEnum::MidiSysex) { - *out_type = content::PermissionType::MIDI_SYSEX; - } else if (type == protocol::Browser::PermissionTypeEnum::DurableStorage) { - *out_type = content::PermissionType::DURABLE_STORAGE; - } else if (type == protocol::Browser::PermissionTypeEnum::AudioCapture) { - *out_type = content::PermissionType::AUDIO_CAPTURE; - } else if (type == protocol::Browser::PermissionTypeEnum::VideoCapture) { - *out_type = content::PermissionType::VIDEO_CAPTURE; - } else if (type == protocol::Browser::PermissionTypeEnum::BackgroundSync) { - *out_type = content::PermissionType::BACKGROUND_SYNC; - } else if (type == protocol::Browser::PermissionTypeEnum::Flash) { - *out_type = content::PermissionType::FLASH; - } else if (type == protocol::Browser::PermissionTypeEnum::Sensors) { - *out_type = content::PermissionType::SENSORS; - } else if (type == - protocol::Browser::PermissionTypeEnum::AccessibilityEvents) { - *out_type = content::PermissionType::ACCESSIBILITY_EVENTS; - } else if (type == protocol::Browser::PermissionTypeEnum::ClipboardRead) { - *out_type = content::PermissionType::CLIPBOARD_READ; - } else if (type == protocol::Browser::PermissionTypeEnum::ClipboardWrite) { - *out_type = content::PermissionType::CLIPBOARD_WRITE; - } else if (type == protocol::Browser::PermissionTypeEnum::PaymentHandler) { - *out_type = content::PermissionType::PAYMENT_HANDLER; - } else if (type == protocol::Browser::PermissionTypeEnum::BackgroundFetch) { - *out_type = content::PermissionType::BACKGROUND_FETCH; - } else if (type == protocol::Browser::PermissionTypeEnum::WakeLockScreen) { - *out_type = content::PermissionType::WAKE_LOCK_SCREEN; - } else if (type == protocol::Browser::PermissionTypeEnum::WakeLockSystem) { - *out_type = content::PermissionType::WAKE_LOCK_SYSTEM; - } else { - return Response::InvalidParams("Unknown permission type: " + type); - } - return Response::OK(); -} - } // namespace BrowserHandler::BrowserHandler(protocol::UberDispatcher* dispatcher, @@ -229,62 +179,6 @@ return Response::OK(); } -Response BrowserHandler::Disable() { - for (auto& browser_context_id : contexts_with_overridden_permissions_) { - Profile* profile = nullptr; - Maybe<std::string> context_id = - browser_context_id.empty() ? Maybe<std::string>() - : Maybe<std::string>(browser_context_id); - FindProfile(context_id, &profile); - if (profile) { - PermissionManager* permission_manager = PermissionManager::Get(profile); - permission_manager->ResetPermissionOverridesForDevTools(); - } - } - contexts_with_overridden_permissions_.clear(); - return Response::OK(); -} - -Response BrowserHandler::GrantPermissions( - const std::string& origin, - std::unique_ptr<protocol::Array<protocol::Browser::PermissionType>> - permissions, - Maybe<std::string> browser_context_id) { - Profile* profile = nullptr; - Response response = FindProfile(browser_context_id, &profile); - if (!response.isSuccess()) - return response; - - PermissionOverrides overrides; - for (const std::string& permission : *permissions) { - content::PermissionType type; - Response type_response = FromProtocolPermissionType(permission, &type); - if (!type_response.isSuccess()) - return type_response; - overrides.insert(type); - } - - PermissionManager* permission_manager = PermissionManager::Get(profile); - GURL url = GURL(origin).GetOrigin(); - permission_manager->SetPermissionOverridesForDevTools(url, - std::move(overrides)); - contexts_with_overridden_permissions_.insert( - browser_context_id.fromMaybe("")); - return Response::FallThrough(); -} - -Response BrowserHandler::ResetPermissions( - Maybe<std::string> browser_context_id) { - Profile* profile = nullptr; - Response response = FindProfile(browser_context_id, &profile); - if (!response.isSuccess()) - return response; - PermissionManager* permission_manager = PermissionManager::Get(profile); - permission_manager->ResetPermissionOverridesForDevTools(); - contexts_with_overridden_permissions_.erase(browser_context_id.fromMaybe("")); - return Response::FallThrough(); -} - protocol::Response BrowserHandler::SetDockTile( protocol::Maybe<std::string> label, protocol::Maybe<protocol::Binary> image) { @@ -295,26 +189,3 @@ !reps.empty() ? gfx::Image(reps) : gfx::Image()); return Response::OK(); } - -Response BrowserHandler::FindProfile( - const Maybe<std::string>& browser_context_id, - Profile** profile) { - auto* delegate = ChromeDevToolsManagerDelegate::GetInstance(); - if (!browser_context_id.isJust()) { - *profile = - Profile::FromBrowserContext(delegate->GetDefaultBrowserContext()); - if (*profile == nullptr) - return Response::Error("Browser context management is not supported."); - return Response::OK(); - } - - std::string context_id = browser_context_id.fromJust(); - for (auto* context : delegate->GetBrowserContexts()) { - if (context->UniqueId() == context_id) { - *profile = Profile::FromBrowserContext(context); - return Response::OK(); - } - } - return Response::InvalidParams("Failed to find browser context for id " + - context_id); -}
diff --git a/chrome/browser/devtools/protocol/browser_handler.h b/chrome/browser/devtools/protocol/browser_handler.h index 1786903..80a3055 100644 --- a/chrome/browser/devtools/protocol/browser_handler.h +++ b/chrome/browser/devtools/protocol/browser_handler.h
@@ -8,8 +8,6 @@ #include "base/containers/flat_set.h" #include "chrome/browser/devtools/protocol/browser.h" -class Profile; - class BrowserHandler : public protocol::Browser::Backend { public: BrowserHandler(protocol::UberDispatcher* dispatcher, @@ -28,23 +26,11 @@ protocol::Response SetWindowBounds( int window_id, std::unique_ptr<protocol::Browser::Bounds> out_bounds) override; - protocol::Response Disable() override; - protocol::Response GrantPermissions( - const std::string& origin, - std::unique_ptr<protocol::Array<protocol::Browser::PermissionType>> - permissions, - protocol::Maybe<std::string> browser_context_id) override; - protocol::Response ResetPermissions( - protocol::Maybe<std::string> browser_context_id) override; protocol::Response SetDockTile( protocol::Maybe<std::string> label, protocol::Maybe<protocol::Binary> image) override; private: - protocol::Response FindProfile( - const protocol::Maybe<std::string>& browser_context_id, - Profile** profile); - base::flat_set<std::string> contexts_with_overridden_permissions_; std::string target_id_;
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc index 2efd2f7..4e79acc 100644 --- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc +++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
@@ -199,7 +199,8 @@ const std::string& gaia_id) { OnReceivedExtensionAccountInfo(base::OptionalOrNullptr( IdentityManagerFactory::GetForProfile(GetProfile()) - ->FindAccountInfoForAccountWithRefreshTokenByGaiaId(gaia_id))); + ->FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId( + gaia_id))); } void IdentityGetAuthTokenFunction::OnReceivedExtensionAccountInfo( @@ -261,7 +262,7 @@ email_for_default_web_account_ = account.email; OnReceivedExtensionAccountInfo(base::OptionalOrNullptr( IdentityManagerFactory::GetForProfile(GetProfile()) - ->FindAccountInfoForAccountWithRefreshTokenByGaiaId( + ->FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId( account.gaia_id))); } else { OnReceivedExtensionAccountInfo(nullptr); @@ -800,7 +801,7 @@ void IdentityGetAuthTokenFunction::ShowExtensionLoginPrompt() { base::Optional<AccountInfo> account = IdentityManagerFactory::GetForProfile(GetProfile()) - ->FindAccountInfoForAccountWithRefreshTokenByAccountId( + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( token_key_.account_id); std::string email_hint = account ? account->email : email_for_default_web_account_;
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h index 0eb440b..1b3b4614 100644 --- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h +++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
@@ -129,8 +129,8 @@ // instance, or empty if this was not in the parameters. void GetAuthTokenForPrimaryAccount(const std::string& extension_gaia_id); - // Wrapper to FindAccountInfoForAccountWithRefreshTokenByGaiaId() to avoid a - // synchronous call to IdentityManager in RunAsync(). + // Wrapper to FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId() to + // avoid a synchronous call to IdentityManager in RunAsync(). void FetchExtensionAccountInfo(const std::string& gaia_id); // Called when the AccountInfo that this instance should use is available.
diff --git a/chrome/browser/extensions/extension_management.cc b/chrome/browser/extensions/extension_management.cc index 0c05134..676ac2e 100644 --- a/chrome/browser/extensions/extension_management.cc +++ b/chrome/browser/extensions/extension_management.cc
@@ -602,12 +602,14 @@ return settings.get(); } +// static ExtensionManagement* ExtensionManagementFactory::GetForBrowserContext( content::BrowserContext* context) { return static_cast<ExtensionManagement*>( GetInstance()->GetServiceForBrowserContext(context, true)); } +// static ExtensionManagementFactory* ExtensionManagementFactory::GetInstance() { return base::Singleton<ExtensionManagementFactory>::get(); }
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index f46f29a..8e931b2a 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -376,9 +376,8 @@ } void ExtensionService::Shutdown() { - ExtensionManagementFactory::GetInstance() - ->GetForBrowserContext(profile()) - ->RemoveObserver(this); + ExtensionManagementFactory::GetForBrowserContext(profile())->RemoveObserver( + this); } const Extension* ExtensionService::GetExtensionById(
diff --git a/chrome/browser/local_discovery/service_discovery_client_mac.mm b/chrome/browser/local_discovery/service_discovery_client_mac.mm index ba5214f..dfc1f080 100644 --- a/chrome/browser/local_discovery/service_discovery_client_mac.mm +++ b/chrome/browser/local_discovery/service_discovery_client_mac.mm
@@ -13,7 +13,7 @@ #include "base/bind.h" #include "base/debug/dump_without_crashing.h" #include "base/memory/singleton.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" #include "base/strings/sys_string_conversions.h" @@ -171,7 +171,7 @@ service_discovery_thread_.reset( new base::Thread(kServiceDiscoveryThreadName)); // Only TYPE_UI uses an NSRunLoop. - base::Thread::Options options(base::MessageLoop::TYPE_UI, 0); + base::Thread::Options options(base::MessagePumpType::UI, 0); service_discovery_thread_->StartWithOptions(options); } }
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list.cc b/chrome/browser/media/webrtc/native_desktop_media_list.cc index 872152ce..d284c0e6 100644 --- a/chrome/browser/media/webrtc/native_desktop_media_list.cc +++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/hash/hash.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" @@ -236,9 +237,9 @@ #if defined(OS_WIN) || defined(OS_MACOSX) // On Windows/OSX the thread must be a UI thread. - base::MessageLoop::Type thread_type = base::MessageLoop::TYPE_UI; + base::MessagePumpType thread_type = base::MessagePump::Type::UI; #else - base::MessageLoop::Type thread_type = base::MessageLoop::TYPE_DEFAULT; + base::MessagePumpType thread_type = base::MessagePump::Type::DEFAULT; #endif thread_.StartWithOptions(base::Thread::Options(thread_type, 0));
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc index 9c6092c..41f1a05 100644 --- a/chrome/browser/net/system_network_context_manager.cc +++ b/chrome/browser/net/system_network_context_manager.cc
@@ -84,11 +84,15 @@ void GetStubResolverConfig( PrefService* local_state, - bool* stub_resolver_enabled, + bool* insecure_stub_resolver_enabled, + net::DnsConfig::SecureDnsMode* secure_dns_mode, base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>>* dns_over_https_servers) { DCHECK(!dns_over_https_servers->has_value()); + *insecure_stub_resolver_enabled = + local_state->GetBoolean(prefs::kBuiltInDnsClientEnabled); + const auto& doh_server_list = local_state->GetList(prefs::kDnsOverHttpsServers)->GetList(); const auto& doh_server_method_list = @@ -128,20 +132,24 @@ } } - *stub_resolver_enabled = - dns_over_https_servers->has_value() || - local_state->GetBoolean(prefs::kBuiltInDnsClientEnabled); + // TODO(crbug.com/985589): Read secure dns mode from prefs. + if (dns_over_https_servers->has_value()) + *secure_dns_mode = net::DnsConfig::SecureDnsMode::AUTOMATIC; + else + *secure_dns_mode = net::DnsConfig::SecureDnsMode::OFF; } void OnStubResolverConfigChanged(PrefService* local_state, const std::string& pref_name) { - bool stub_resolver_enabled; + bool insecure_stub_resolver_enabled; + net::DnsConfig::SecureDnsMode secure_dns_mode; base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>> dns_over_https_servers; - GetStubResolverConfig(local_state, &stub_resolver_enabled, - &dns_over_https_servers); + GetStubResolverConfig(local_state, &insecure_stub_resolver_enabled, + &secure_dns_mode, &dns_over_https_servers); content::GetNetworkService()->ConfigureStubHostResolver( - stub_resolver_enabled, std::move(dns_over_https_servers)); + insecure_stub_resolver_enabled, secure_dns_mode, + std::move(dns_over_https_servers)); } // Constructs HttpAuthStaticParams based on |local_state|. @@ -554,13 +562,15 @@ // Configure the stub resolver. This must be done after the system // NetworkContext is created, but before anything has the chance to use it. - bool stub_resolver_enabled; + bool insecure_stub_resolver_enabled; + net::DnsConfig::SecureDnsMode secure_dns_mode; base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>> dns_over_https_servers; - GetStubResolverConfig(local_state_, &stub_resolver_enabled, - &dns_over_https_servers); + GetStubResolverConfig(local_state_, &insecure_stub_resolver_enabled, + &secure_dns_mode, &dns_over_https_servers); content::GetNetworkService()->ConfigureStubHostResolver( - stub_resolver_enabled, std::move(dns_over_https_servers)); + insecure_stub_resolver_enabled, secure_dns_mode, + std::move(dns_over_https_servers)); #if defined(OS_LINUX) && !defined(OS_CHROMEOS) const base::CommandLine& command_line = @@ -706,10 +716,12 @@ } void SystemNetworkContextManager::GetStubResolverConfigForTesting( - bool* stub_resolver_enabled, + bool* insecure_stub_resolver_enabled, + net::DnsConfig::SecureDnsMode* secure_dns_mode, base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>>* dns_over_https_servers) { - GetStubResolverConfig(g_browser_process->local_state(), stub_resolver_enabled, + GetStubResolverConfig(g_browser_process->local_state(), + insecure_stub_resolver_enabled, secure_dns_mode, dns_over_https_servers); }
diff --git a/chrome/browser/net/system_network_context_manager.h b/chrome/browser/net/system_network_context_manager.h index 59c34253..87c657e2 100644 --- a/chrome/browser/net/system_network_context_manager.h +++ b/chrome/browser/net/system_network_context_manager.h
@@ -130,7 +130,8 @@ // Returns configuration that would be sent to the stub DNS resolver. static void GetStubResolverConfigForTesting( - bool* stub_resolver_enabled, + bool* insecure_stub_resolver_enabled, + net::DnsConfig::SecureDnsMode* secure_dns_mode, base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>>* dns_over_https_servers);
diff --git a/chrome/browser/net/system_network_context_manager_browsertest.cc b/chrome/browser/net/system_network_context_manager_browsertest.cc index d36d128..2383a8ee 100644 --- a/chrome/browser/net/system_network_context_manager_browsertest.cc +++ b/chrome/browser/net/system_network_context_manager_browsertest.cc
@@ -30,25 +30,31 @@ namespace { void GetStubResolverConfig( - bool* stub_resolver_enabled, + bool* insecure_stub_resolver_enabled, + net::DnsConfig::SecureDnsMode* secure_dns_mode, base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>>* dns_over_https_servers) { dns_over_https_servers->reset(); SystemNetworkContextManager::GetStubResolverConfigForTesting( - stub_resolver_enabled, dns_over_https_servers); + insecure_stub_resolver_enabled, secure_dns_mode, dns_over_https_servers); } // Checks the values returned by GetStubResolverConfigForTesting() match // |async_dns_feature_enabled| (With empty DNS over HTTPS prefs). Then sets // various DNS over HTTPS servers, and makes sure the settings are respected. +// TODO(crbug.com/985589): Check that the SecureDnsMode is read correctly from +// the prefs once it is stored there. void RunStubResolverConfigTests(bool async_dns_feature_enabled) { // Check initial state. - bool stub_resolver_enabled = !async_dns_feature_enabled; + bool insecure_stub_resolver_enabled = !async_dns_feature_enabled; + net::DnsConfig::SecureDnsMode secure_dns_mode; base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>> dns_over_https_servers; - GetStubResolverConfig(&stub_resolver_enabled, &dns_over_https_servers); - EXPECT_EQ(async_dns_feature_enabled, stub_resolver_enabled); + GetStubResolverConfig(&insecure_stub_resolver_enabled, &secure_dns_mode, + &dns_over_https_servers); + EXPECT_EQ(async_dns_feature_enabled, insecure_stub_resolver_enabled); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF, secure_dns_mode); EXPECT_FALSE(dns_over_https_servers.has_value()); // Check state after setting various DNS over HTTPS preferences. @@ -74,8 +80,10 @@ servers.GetList().push_back(base::Value(kGoodGetTemplate)); local_state->Set(prefs::kDnsOverHttpsServers, servers); local_state->Set(prefs::kDnsOverHttpsServerMethods, methods); - GetStubResolverConfig(&stub_resolver_enabled, &dns_over_https_servers); - EXPECT_EQ(async_dns_feature_enabled, stub_resolver_enabled); + GetStubResolverConfig(&insecure_stub_resolver_enabled, &secure_dns_mode, + &dns_over_https_servers); + EXPECT_EQ(async_dns_feature_enabled, insecure_stub_resolver_enabled); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF, secure_dns_mode); EXPECT_FALSE(dns_over_https_servers.has_value()); servers.GetList().clear(); methods.GetList().clear(); @@ -83,8 +91,10 @@ methods.GetList().push_back(base::Value(kPost)); local_state->Set(prefs::kDnsOverHttpsServers, servers); local_state->Set(prefs::kDnsOverHttpsServerMethods, methods); - GetStubResolverConfig(&stub_resolver_enabled, &dns_over_https_servers); - EXPECT_EQ(async_dns_feature_enabled, stub_resolver_enabled); + GetStubResolverConfig(&insecure_stub_resolver_enabled, &secure_dns_mode, + &dns_over_https_servers); + EXPECT_EQ(async_dns_feature_enabled, insecure_stub_resolver_enabled); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF, secure_dns_mode); EXPECT_FALSE(dns_over_https_servers.has_value()); servers.GetList().clear(); methods.GetList().clear(); @@ -94,8 +104,10 @@ methods.GetList().push_back(base::Value(kPost)); local_state->Set(prefs::kDnsOverHttpsServers, servers); local_state->Set(prefs::kDnsOverHttpsServerMethods, methods); - GetStubResolverConfig(&stub_resolver_enabled, &dns_over_https_servers); - EXPECT_EQ(async_dns_feature_enabled, stub_resolver_enabled); + GetStubResolverConfig(&insecure_stub_resolver_enabled, &secure_dns_mode, + &dns_over_https_servers); + EXPECT_EQ(async_dns_feature_enabled, insecure_stub_resolver_enabled); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF, secure_dns_mode); EXPECT_FALSE(dns_over_https_servers.has_value()); servers.GetList().clear(); methods.GetList().clear(); @@ -105,8 +117,10 @@ methods.GetList().push_back(base::Value(3.14)); local_state->Set(prefs::kDnsOverHttpsServers, servers); local_state->Set(prefs::kDnsOverHttpsServerMethods, methods); - GetStubResolverConfig(&stub_resolver_enabled, &dns_over_https_servers); - EXPECT_EQ(async_dns_feature_enabled, stub_resolver_enabled); + GetStubResolverConfig(&insecure_stub_resolver_enabled, &secure_dns_mode, + &dns_over_https_servers); + EXPECT_EQ(async_dns_feature_enabled, insecure_stub_resolver_enabled); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF, secure_dns_mode); EXPECT_FALSE(dns_over_https_servers.has_value()); servers.GetList().clear(); methods.GetList().clear(); @@ -116,8 +130,10 @@ methods.GetList().push_back(base::Value(kPost)); local_state->Set(prefs::kDnsOverHttpsServers, servers); local_state->Set(prefs::kDnsOverHttpsServerMethods, methods); - GetStubResolverConfig(&stub_resolver_enabled, &dns_over_https_servers); - EXPECT_EQ(async_dns_feature_enabled, stub_resolver_enabled); + GetStubResolverConfig(&insecure_stub_resolver_enabled, &secure_dns_mode, + &dns_over_https_servers); + EXPECT_EQ(async_dns_feature_enabled, insecure_stub_resolver_enabled); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF, secure_dns_mode); EXPECT_FALSE(dns_over_https_servers.has_value()); servers.GetList().clear(); methods.GetList().clear(); @@ -127,8 +143,10 @@ methods.GetList().push_back(base::Value(kPost)); local_state->Set(prefs::kDnsOverHttpsServers, servers); local_state->Set(prefs::kDnsOverHttpsServerMethods, methods); - GetStubResolverConfig(&stub_resolver_enabled, &dns_over_https_servers); - EXPECT_EQ(true, stub_resolver_enabled); + GetStubResolverConfig(&insecure_stub_resolver_enabled, &secure_dns_mode, + &dns_over_https_servers); + EXPECT_EQ(async_dns_feature_enabled, insecure_stub_resolver_enabled); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::AUTOMATIC, secure_dns_mode); ASSERT_TRUE(dns_over_https_servers.has_value()); ASSERT_EQ(1u, dns_over_https_servers->size()); EXPECT_EQ(kGoodPostTemplate, dns_over_https_servers->at(0)->server_template); @@ -143,8 +161,10 @@ methods.GetList().push_back(base::Value(kPost)); local_state->Set(prefs::kDnsOverHttpsServers, servers); local_state->Set(prefs::kDnsOverHttpsServerMethods, methods); - GetStubResolverConfig(&stub_resolver_enabled, &dns_over_https_servers); - EXPECT_EQ(true, stub_resolver_enabled); + GetStubResolverConfig(&insecure_stub_resolver_enabled, &secure_dns_mode, + &dns_over_https_servers); + EXPECT_EQ(async_dns_feature_enabled, insecure_stub_resolver_enabled); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::AUTOMATIC, secure_dns_mode); ASSERT_TRUE(dns_over_https_servers.has_value()); ASSERT_EQ(1u, dns_over_https_servers->size()); EXPECT_EQ(kGoodGetTemplate, dns_over_https_servers->at(0)->server_template); @@ -159,8 +179,10 @@ methods.GetList().push_back(base::Value(kGet)); local_state->Set(prefs::kDnsOverHttpsServers, servers); local_state->Set(prefs::kDnsOverHttpsServerMethods, methods); - GetStubResolverConfig(&stub_resolver_enabled, &dns_over_https_servers); - EXPECT_EQ(true, stub_resolver_enabled); + GetStubResolverConfig(&insecure_stub_resolver_enabled, &secure_dns_mode, + &dns_over_https_servers); + EXPECT_EQ(async_dns_feature_enabled, insecure_stub_resolver_enabled); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::AUTOMATIC, secure_dns_mode); ASSERT_TRUE(dns_over_https_servers.has_value()); ASSERT_EQ(2u, dns_over_https_servers->size()); EXPECT_EQ(kGoodPostTemplate, dns_over_https_servers->at(0)->server_template); @@ -173,13 +195,17 @@ // Test case with policy BuiltInDnsClientEnabled enabled. local_state->Set(prefs::kDnsOverHttpsServers, servers); local_state->Set(prefs::kDnsOverHttpsServerMethods, methods); - GetStubResolverConfig(&stub_resolver_enabled, &dns_over_https_servers); - EXPECT_EQ(async_dns_feature_enabled, stub_resolver_enabled); + GetStubResolverConfig(&insecure_stub_resolver_enabled, &secure_dns_mode, + &dns_over_https_servers); + EXPECT_EQ(async_dns_feature_enabled, insecure_stub_resolver_enabled); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF, secure_dns_mode); EXPECT_FALSE(dns_over_https_servers.has_value()); local_state->Set(prefs::kBuiltInDnsClientEnabled, base::Value(!async_dns_feature_enabled)); - GetStubResolverConfig(&stub_resolver_enabled, &dns_over_https_servers); - EXPECT_EQ(!async_dns_feature_enabled, stub_resolver_enabled); + GetStubResolverConfig(&insecure_stub_resolver_enabled, &secure_dns_mode, + &dns_over_https_servers); + EXPECT_EQ(!async_dns_feature_enabled, insecure_stub_resolver_enabled); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF, secure_dns_mode); EXPECT_FALSE(dns_over_https_servers.has_value()); }
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc index fe56627..6935e4f8 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc
@@ -511,11 +511,6 @@ ancestor_data->AdjustAdBytes(unaccounted_ad_bytes, mime_type); } -void AdsPageLoadMetricsObserver::RecordAdFrameUkm(ukm::SourceId source_id) { - for (const FrameData& ad_frame_data : ad_frames_data_storage_) - ad_frame_data.RecordAdFrameLoadUkmEvent(source_id); -} - void AdsPageLoadMetricsObserver::RecordPageResourceTotalHistograms( ukm::SourceId source_id) { // Only records histograms on pages that have some ad bytes.
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h index 69d675bc..fc26f7569 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h
@@ -135,7 +135,6 @@ int process_id, const page_load_metrics::mojom::ResourceDataUpdatePtr& resource); - void RecordAdFrameUkm(ukm::SourceId source_id); void RecordPageResourceTotalHistograms(ukm::SourceId source_id); void RecordHistograms(ukm::SourceId source_id); void RecordAggregateHistogramsForAdTagging(
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc index 289cca1..42758c9f 100644 --- a/chrome/browser/permissions/permission_manager.cc +++ b/chrome/browser/permissions/permission_manager.cc
@@ -68,7 +68,7 @@ namespace { -// Helper method to convert ContentSetting to PermissionStatus. +// Helper methods to convert ContentSetting to PermissionStatus and vice versa. PermissionStatus ContentSettingToPermissionStatus(ContentSetting setting) { switch (setting) { case CONTENT_SETTING_ALLOW: @@ -88,6 +88,21 @@ return PermissionStatus::DENIED; } +ContentSetting PermissionStatusToContentSetting(PermissionStatus status) { + switch (status) { + case PermissionStatus::GRANTED: + return CONTENT_SETTING_ALLOW; + case PermissionStatus::ASK: + return CONTENT_SETTING_ASK; + case PermissionStatus::DENIED: + default: + return CONTENT_SETTING_BLOCK; + } + + NOTREACHED(); + return CONTENT_SETTING_DEFAULT; +} + // Helper method to convert PermissionType to ContentSettingType. ContentSettingsType PermissionTypeToContentSetting(PermissionType permission) { switch (permission) { @@ -732,9 +747,12 @@ const GURL& origin, const PermissionOverrides& overrides) { ContentSettingsTypeOverrides result; - for (const auto& item : overrides) - result.insert(PermissionTypeToContentSetting(item)); - devtools_permission_overrides_[origin] = std::move(result); + for (const auto& item : overrides) { + result[PermissionTypeToContentSetting(item.first)] = + PermissionStatusToContentSetting(item.second); + } + devtools_permission_overrides_[url::Origin::Create(origin)] = + std::move(result); } void PermissionManager::ResetPermissionOverridesForDevTools() { @@ -744,9 +762,13 @@ ContentSetting PermissionManager::GetPermissionOverrideForDevTools( const GURL& origin, ContentSettingsType permission) { - auto it = devtools_permission_overrides_.find(origin); + auto it = devtools_permission_overrides_.find(url::Origin::Create(origin)); if (it == devtools_permission_overrides_.end()) return CONTENT_SETTING_DEFAULT; - return it->second.count(permission) ? CONTENT_SETTING_ALLOW - : CONTENT_SETTING_BLOCK; + + auto setting_it = it->second.find(permission); + if (setting_it == it->second.end()) + return CONTENT_SETTING_DEFAULT; + + return setting_it->second; }
diff --git a/chrome/browser/permissions/permission_manager.h b/chrome/browser/permissions/permission_manager.h index 2e5b394..36d6dc94 100644 --- a/chrome/browser/permissions/permission_manager.h +++ b/chrome/browser/permissions/permission_manager.h
@@ -16,6 +16,7 @@ #include "components/keyed_service/core/keyed_service.h" #include "content/public/browser/permission_controller_delegate.h" #include "content/public/browser/permission_type.h" +#include "url/origin.h" class PermissionContextBase; struct PermissionResult; @@ -116,13 +117,12 @@ // denied due to the kill switch. bool IsPermissionKillSwitchOn(ContentSettingsType); - using PermissionOverrides = std::set<content::PermissionType>; - - // For the given |origin|, grant permissions that belong to |overrides| - // and reject all others. - void SetPermissionOverridesForDevTools(const GURL& origin, - const PermissionOverrides& overrides); - void ResetPermissionOverridesForDevTools(); + // For the given |origin|, overrides permissions that belong to |overrides|. + // These permissions are in-sync with the PermissionController. + void SetPermissionOverridesForDevTools( + const GURL& origin, + const PermissionOverrides& overrides) override; + void ResetPermissionOverridesForDevTools() override; private: friend class PermissionManagerTest; @@ -175,8 +175,10 @@ std::unique_ptr<PermissionContextBase>, ContentSettingsTypeHash> permission_contexts_; - using ContentSettingsTypeOverrides = std::set<ContentSettingsType>; - std::map<GURL, ContentSettingsTypeOverrides> devtools_permission_overrides_; + using ContentSettingsTypeOverrides = + base::flat_map<ContentSettingsType, ContentSetting>; + std::map<url::Origin, ContentSettingsTypeOverrides> + devtools_permission_overrides_; DISALLOW_COPY_AND_ASSIGN(PermissionManager); };
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index f21337a..c7404362 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -495,9 +495,6 @@ { key::kSSLVersionMin, prefs::kSSLVersionMin, base::Value::Type::STRING }, - { key::kSSLVersionMax, - prefs::kSSLVersionMax, - base::Value::Type::STRING }, { key::kNTPContentSuggestionsEnabled, ntp_snippets::prefs::kEnableSnippets, base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc b/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc index 2e86b5f..9a2c2d1d 100644 --- a/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc +++ b/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc
@@ -16,6 +16,7 @@ #include "base/command_line.h" #include "base/files/scoped_temp_dir.h" #include "base/message_loop/message_pump.h" +#include "base/message_loop/message_pump_type.h" #include "base/process/kill.h" #include "base/process/process.h" #include "base/rand_util.h" @@ -136,7 +137,7 @@ quit_closure_ = std::move(quit_closure); service_process_state_ = std::move(state); - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); io_thread_.reset(new base::Thread("TestServiceProcess_IO")); return io_thread_->StartWithOptions(options); }
diff --git a/chrome/browser/profiles/profile_downloader.cc b/chrome/browser/profiles/profile_downloader.cc index 6ec7efa..13b2d39af 100644 --- a/chrome/browser/profiles/profile_downloader.cc +++ b/chrome/browser/profiles/profile_downloader.cc
@@ -110,8 +110,9 @@ void ProfileDownloader::StartFetchingImage() { VLOG(1) << "Fetching user entry with token: " << auth_token_; auto maybe_account_info = - identity_manager_->FindAccountInfoForAccountWithRefreshTokenByAccountId( - account_id_); + identity_manager_ + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id_); if (maybe_account_info.has_value()) account_info_ = maybe_account_info.value();
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc index ae12e72..4f453ac 100644 --- a/chrome/browser/profiles/profile_window.cc +++ b/chrome/browser/profiles/profile_window.cc
@@ -372,7 +372,7 @@ IdentityManagerFactory::GetForProfile(profile); base::Optional<AccountInfo> primary_account_info = - identity_manager->FindExtendedAccountInfoForAccount( + identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken( identity_manager->GetPrimaryAccountInfo()); if (primary_account_info.has_value())
diff --git a/chrome/browser/resources/settings/internet_page/BUILD.gn b/chrome/browser/resources/settings/internet_page/BUILD.gn index 936eea4..73c2456 100644 --- a/chrome/browser/resources/settings/internet_page/BUILD.gn +++ b/chrome/browser/resources/settings/internet_page/BUILD.gn
@@ -84,7 +84,7 @@ "//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior", "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types", "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu", - "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior", + "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo", "//ui/webui/resources/js:assert", ] externs_list = [ "$externs_path/networking_private.js" ]
diff --git a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html index 42dcf86..ccac30a 100644 --- a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html
@@ -5,7 +5,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> -<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior_mojo.html"> <link rel="import" href="../settings_shared_css.html"> <dom-module id="settings-internet-known-networks-page"> @@ -38,8 +38,7 @@ on-click="fireShowDetails_"> <template is="dom-if" if="[[isPolicySourceMojo(item.source))]]"> <cr-policy-indicator on-click="doNothing_" - indicator-type="[[getIndicatorTypeForSourceMojo( - item.source)]]"> + indicator-type="[[getIndicatorTypeForSource(item.source)]]"> </cr-policy-indicator> </template> </cr-link-row> @@ -63,8 +62,7 @@ on-click="fireShowDetails_"> <template is="dom-if" if="[[isPolicySourceMojo(item.source))]]"> <cr-policy-indicator on-click="doNothing_" - indicator-type="[[getIndicatorTypeForSourceMojo( - item.source)]]"> + indicator-type="[[getIndicatorTypeForSource(item.source)]]"> </cr-policy-indicator> </template> </cr-link-row>
diff --git a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js index 6d613efe..c095580 100644 --- a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js
@@ -12,7 +12,7 @@ behaviors: [ CrNetworkListenerBehavior, - CrPolicyNetworkBehavior, + CrPolicyNetworkBehaviorMojo, ], properties: { @@ -162,14 +162,15 @@ // We need to make a round trip to Chrome in order to retrieve the managed // properties for the network. The delay is not noticeable (~5ms) and is // preferable to initiating a query for every known network at load time. - this.networkingPrivate.getManagedProperties( - this.selectedGuid_, properties => { - if (chrome.runtime.lastError || !properties) { - console.error( - 'Unexpected error: ' + chrome.runtime.lastError.message); + this.networkConfigProxy_.getManagedProperties(this.selectedGuid_) + .then(response => { + const properties = response.result; + if (!properties) { + console.error('Properties not found for: ' + this.selectedGuid_); return; } - if (this.isNetworkPolicyEnforced(properties.Priority)) { + if (properties.priority && + this.isNetworkPolicyEnforced(properties.priority)) { this.showAddPreferred_ = false; this.showRemovePreferred_ = false; } else { @@ -177,7 +178,7 @@ this.showAddPreferred_ = !preferred; this.showRemovePreferred_ = preferred; } - this.enableForget_ = !this.isPolicySource(properties.Source); + this.enableForget_ = !this.isPolicySource(networkState.source); /** @type {!CrActionMenuElement} */ (this.$.dotsMenu) .showAt(/** @type {!Element} */ (button)); });
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_process_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_process_win.cc index 44c33ca..976bc4e1 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_process_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_process_win.cc
@@ -15,6 +15,7 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/memory/scoped_refptr.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/sequenced_task_runner.h" #include "base/stl_util.h" @@ -598,7 +599,7 @@ if (options_.crash_point() == CrashPoint::kOnStartup) exit(kDeliberateCrashExitCode); - base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options thread_options(base::MessagePumpType::IO, 0); base::Thread io_thread("IPCThread"); EXPECT_TRUE(io_thread.StartWithOptions(thread_options)); if (::testing::Test::HasFailure())
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc index 7b37cdf..bdaab742 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -1010,7 +1010,7 @@ return AccountInfo(); base::Optional<AccountInfo> primary_account_info = - identity_manager->FindExtendedAccountInfoForAccount( + identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken( identity_manager->GetPrimaryAccountInfo()); return primary_account_info.value_or(AccountInfo());
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.cc b/chrome/browser/safe_browsing/client_side_detection_host.cc index bedbd4b..a633d641 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host.cc
@@ -577,9 +577,6 @@ browse_info_.get() && verdict->ParseFromString(verdict_str) && verdict->IsInitialized()) { - UMA_HISTOGRAM_BOOLEAN( - "SBClientPhishing.ClientDeterminesPhishing", - verdict->is_phishing()); // We only send phishing verdict to the server if the verdict is phishing or // if a SafeBrowsing interstitial was already shown for this site. E.g., a // malware or phishing interstitial was shown but the user clicked @@ -601,11 +598,6 @@ void ClientSideDetectionHost::MaybeShowPhishingWarning(GURL phishing_url, bool is_phishing) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DVLOG(2) << "Received server phishing verdict for URL:" << phishing_url - << " is_phishing:" << is_phishing; - UMA_HISTOGRAM_BOOLEAN( - "SBClientPhishing.ServerDeterminesPhishing", - is_phishing); if (is_phishing) { DCHECK(web_contents()); if (ui_manager_.get()) {
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_browsertest.cc b/chrome/browser/sharing/click_to_call/click_to_call_browsertest.cc new file mode 100644 index 0000000..6e105a8 --- /dev/null +++ b/chrome/browser/sharing/click_to_call/click_to_call_browsertest.cc
@@ -0,0 +1,158 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> +#include <string> + +#include "base/bind.h" +#include "base/macros.h" +#include "base/run_loop.h" +#include "base/strings/utf_string_conversions.h" +#include "base/test/bind_test_util.h" +#include "base/test/scoped_feature_list.h" +#include "build/build_config.h" +#include "chrome/app/chrome_command_ids.h" +#include "chrome/browser/gcm/gcm_profile_service_factory.h" +#include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h" +#include "chrome/browser/sharing/click_to_call/feature.h" +#include "chrome/browser/sharing/features.h" +#include "chrome/browser/sharing/sharing_device_info.h" +#include "chrome/browser/sharing/sharing_device_registration_result.h" +#include "chrome/browser/sharing/sharing_service.h" +#include "chrome/browser/sharing/sharing_service_factory.h" +#include "chrome/browser/sharing/sharing_sync_preference.h" +#include "chrome/browser/sync/test/integration/sync_test.h" +#include "chrome/browser/ui/browser.h" +#include "components/gcm_driver/fake_gcm_profile_service.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "url/gurl.h" + +namespace { +const char kTelUrl[] = "tel:+9876543210"; +} // namespace + +class ClickToCallBrowserTest : public SyncTest { + public: + ClickToCallBrowserTest() + : SyncTest(TWO_CLIENT), + scoped_testing_factory_installer_( + base::BindRepeating(&gcm::FakeGCMProfileService::Build)) {} + + ~ClickToCallBrowserTest() override {} + + void SetUpOnMainThread() override { + SyncTest::SetUpOnMainThread(); + + scoped_feature_list_.InitWithFeatures( + {kClickToCallUI, kSharingDeviceRegistration}, {}); + + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + std::unique_ptr<content::WebContents> web_contents_ptr = + content::WebContents::Create( + content::WebContents::CreateParams(GetProfile(0))); + web_contents = web_contents_ptr.get(); + Browser* browser = AddBrowser(0); + browser->tab_strip_model()->AppendWebContents(std::move(web_contents_ptr), + true); + } + + content::WebContents* GetWebContents() { return web_contents; } + + void SetUpDevices(int count) { + for (int i = 0; i < count; i++) { + SharingService* service = + SharingServiceFactory::GetForBrowserContext(GetProfile(i)); + + base::RunLoop run_loop; + service->RegisterDeviceInTesting( + std::string("TEST"), + static_cast<int>(SharingDeviceCapability::kTelephony), + base::BindLambdaForTesting([&](SharingDeviceRegistrationResult r) { + ASSERT_EQ(SharingDeviceRegistrationResult::kSuccess, r); + run_loop.Quit(); + })); + run_loop.Run(); + } + } + + std::unique_ptr<TestRenderViewContextMenu> InitRightClickMenu( + content::WebContents* web_contents, + const GURL& url, + const base::string16& link_text) { + content::ContextMenuParams params; + params.media_type = blink::WebContextMenuData::MediaType::kMediaTypeNone; + params.unfiltered_link_url = url; + params.link_url = url; + params.src_url = url; + params.link_text = link_text; + params.page_url = web_contents->GetVisibleURL(); + params.source_type = ui::MenuSourceType::MENU_SOURCE_MOUSE; +#if defined(OS_MACOSX) + params.writing_direction_default = 0; + params.writing_direction_left_to_right = 0; + params.writing_direction_right_to_left = 0; +#endif + auto menu = std::make_unique<TestRenderViewContextMenu>( + web_contents->GetMainFrame(), params); + menu->Init(); + return menu; + } + + void GetDeviceFCMToken(SharingService* sharing_service, + const std::string& guid, + std::string* fcm_token) const { + auto devices = sharing_service->GetSyncPreferences()->GetSyncedDevices(); + auto it = devices.find(guid); + ASSERT_NE(devices.end(), it); + *fcm_token = it->second.fcm_token; + } + + private: + gcm::GCMProfileServiceFactory::ScopedTestingFactoryInstaller + scoped_testing_factory_installer_; + base::test::ScopedFeatureList scoped_feature_list_; + content::WebContents* web_contents; + std::vector<std::string> device_fcm_tokens_; + DISALLOW_COPY_AND_ASSIGN(ClickToCallBrowserTest); +}; + +// TODO(himanshujaju): Add UI checks. Modularize common functions. +IN_PROC_BROWSER_TEST_F(ClickToCallBrowserTest, + ContextMenu_SingleDeviceAvailable) { + SetUpDevices(1); + AwaitQuiescence(); + + gcm::FakeGCMProfileService* gcm_service = + static_cast<gcm::FakeGCMProfileService*>( + gcm::GCMProfileServiceFactory::GetForProfile(GetProfile(0))); + gcm_service->set_collect(true); + + SharingService* sharing_service = + SharingServiceFactory::GetForBrowserContext(GetProfile(0)); + auto devices = sharing_service->GetDeviceCandidates( + static_cast<int>(SharingDeviceCapability::kTelephony)); + + std::unique_ptr<TestRenderViewContextMenu> menu = InitRightClickMenu( + GetWebContents(), GURL(kTelUrl), base::ASCIIToUTF16("Google")); + + // Check click to call items in context menu + ASSERT_TRUE(menu->IsItemPresent( + IDC_CONTENT_CONTEXT_SHARING_CLICK_TO_CALL_SINGLE_DEVICE)); + EXPECT_FALSE(menu->IsItemPresent( + IDC_CONTENT_CONTEXT_SHARING_CLICK_TO_CALL_MULTIPLE_DEVICES)); + + menu->ExecuteCommand(IDC_CONTENT_CONTEXT_SHARING_CLICK_TO_CALL_SINGLE_DEVICE, + 0); + + // Check SharingMessage and Receiver id + std::string fcm_token; + GetDeviceFCMToken(sharing_service, devices[0].guid(), &fcm_token); + EXPECT_EQ(fcm_token, gcm_service->last_receiver_id()); + chrome_browser_sharing::SharingMessage sharing_message; + sharing_message.ParseFromString(gcm_service->last_web_push_message().payload); + ASSERT_TRUE(sharing_message.has_click_to_call_message()); + EXPECT_EQ(GURL(kTelUrl).GetContent(), + sharing_message.click_to_call_message().phone_number()); +}
diff --git a/chrome/browser/sharing/sharing_device_registration.cc b/chrome/browser/sharing/sharing_device_registration.cc index 4e7d35080..742bd145 100644 --- a/chrome/browser/sharing/sharing_device_registration.cc +++ b/chrome/browser/sharing/sharing_device_registration.cc
@@ -188,6 +188,10 @@ } int SharingDeviceRegistration::GetDeviceCapabilities() const { + // Used in tests + if (device_capabilities_testing_value_) + return device_capabilities_testing_value_.value(); + int device_capabilities = static_cast<int>(SharingDeviceCapability::kNone); if (IsTelephonySupported()) { device_capabilities |= @@ -206,3 +210,8 @@ return false; } + +void SharingDeviceRegistration::SetDeviceCapabilityForTesting( + int device_capabilities) { + device_capabilities_testing_value_ = device_capabilities; +}
diff --git a/chrome/browser/sharing/sharing_device_registration.h b/chrome/browser/sharing/sharing_device_registration.h index 9e514bc..0b81920e 100644 --- a/chrome/browser/sharing/sharing_device_registration.h +++ b/chrome/browser/sharing/sharing_device_registration.h
@@ -47,6 +47,9 @@ // Un-registers device with sharing sync preferences. virtual void UnregisterDevice(RegistrationCallback callback); + // For testing + void SetDeviceCapabilityForTesting(int device_capabilities); + private: FRIEND_TEST_ALL_PREFIXES(SharingDeviceRegistrationTest, RegisterDeviceTest_Success); @@ -91,6 +94,7 @@ instance_id::InstanceIDDriver* instance_id_driver_; VapidKeyManager* vapid_key_manager_; syncer::LocalDeviceInfoProvider* local_device_info_provider_; + base::Optional<int> device_capabilities_testing_value_; base::WeakPtrFactory<SharingDeviceRegistration> weak_ptr_factory_{this};
diff --git a/chrome/browser/sharing/sharing_service.cc b/chrome/browser/sharing/sharing_service.cc index 4dfe5893..22abed13 100644 --- a/chrome/browser/sharing/sharing_service.cc +++ b/chrome/browser/sharing/sharing_service.cc
@@ -127,8 +127,6 @@ std::unordered_set<std::string> device_names; std::vector<SharingDeviceInfo> device_candidates; - const syncer::DeviceInfo* local_device_info = - local_device_info_provider_->GetLocalDeviceInfo(); for (const auto& device : all_devices) { // If the current device is considered expired for our purposes, stop here // since the next devices in the vector are at least as expired than this @@ -136,8 +134,7 @@ if (device->last_updated_timestamp() < min_updated_time) break; - if (local_device_info && - (local_device_info->client_name() == device->client_name())) { + if (GetDeviceName() == device->client_name()) { continue; } @@ -268,6 +265,15 @@ &SharingService::OnDeviceRegistered, weak_ptr_factory_.GetWeakPtr())); } +void SharingService::RegisterDeviceInTesting( + std::string device_name, + int capabilities, + SharingDeviceRegistration::RegistrationCallback callback) { + local_device_name_for_tests_ = std::move(device_name); + sharing_device_registration_->SetDeviceCapabilityForTesting(capabilities); + sharing_device_registration_->RegisterDevice(std::move(callback)); +} + void SharingService::UnregisterDevice() { sharing_device_registration_->UnregisterDevice(base::BindOnce( &SharingService::OnDeviceUnregistered, weak_ptr_factory_.GetWeakPtr())); @@ -358,6 +364,10 @@ sync_service_->GetActiveDataTypes().Has(syncer::PREFERENCES); } +SharingSyncPreference* SharingService::GetSyncPreferences() const { + return sync_prefs_.get(); +} + bool SharingService::IsSyncDisabled() const { return sync_service_ && (sync_service_->GetTransportState() == @@ -366,3 +376,15 @@ syncer::SyncService::TransportState::ACTIVE && !sync_service_->GetActiveDataTypes().Has(syncer::PREFERENCES))); } + +base::Optional<std::string> SharingService::GetDeviceName() const { + if (local_device_name_for_tests_) + return local_device_name_for_tests_; + + const syncer::DeviceInfo* local_device_info = + local_device_info_provider_->GetLocalDeviceInfo(); + if (local_device_info) + return local_device_info->client_name(); + else + return base::nullopt; +}
diff --git a/chrome/browser/sharing/sharing_service.h b/chrome/browser/sharing/sharing_service.h index fa0811b..145eb0e 100644 --- a/chrome/browser/sharing/sharing_service.h +++ b/chrome/browser/sharing/sharing_service.h
@@ -98,6 +98,14 @@ // Returns the current state of SharingService. virtual State GetState() const; + // For testing + void RegisterDeviceInTesting( + std::string device_name, + int capabilities, + SharingDeviceRegistration::RegistrationCallback callback); + + SharingSyncPreference* GetSyncPreferences() const; + private: // Overrides for syncer::SyncServiceObserver. void OnSyncShutdown(syncer::SyncService* sync) override; @@ -107,6 +115,7 @@ void OnAckReceived(const std::string& message_id) override; void RegisterDevice(); + void UnregisterDevice(); void OnDeviceRegistered(SharingDeviceRegistrationResult result); void OnDeviceUnregistered(SharingDeviceRegistrationResult result); @@ -122,6 +131,10 @@ // in transitioning state. bool IsSyncDisabled() const; + // Returns |local_device_name_for_tests_| if set, otherwise returns the actual + // device name from |local_device_info_provider_|. + base::Optional<std::string> GetDeviceName() const; + std::unique_ptr<SharingSyncPreference> sync_prefs_; std::unique_ptr<VapidKeyManager> vapid_key_manager_; std::unique_ptr<SharingDeviceRegistration> sharing_device_registration_; @@ -134,6 +147,7 @@ PingMessageHandler ping_message_handler_; net::BackoffEntry backoff_entry_; State state_; + base::Optional<std::string> local_device_name_for_tests_; // Map of random GUID to SendMessageCallback. std::map<std::string, SendMessageCallback> send_message_callbacks_;
diff --git a/chrome/browser/signin/dice_response_handler_unittest.cc b/chrome/browser/signin/dice_response_handler_unittest.cc index 8d93791..ccfe4b16 100644 --- a/chrome/browser/signin/dice_response_handler_unittest.cc +++ b/chrome/browser/signin/dice_response_handler_unittest.cc
@@ -245,7 +245,8 @@ // Check that the AccountInfo::is_under_advanced_protection is set. EXPECT_TRUE( identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) .value() .is_under_advanced_protection); } @@ -305,7 +306,8 @@ EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(account_id)); EXPECT_FALSE( identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) .value() .is_under_advanced_protection); } @@ -346,7 +348,8 @@ EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(account_id_1)); EXPECT_TRUE( identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id_1) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id_1) .value() .is_under_advanced_protection); // Simulate GaiaAuthFetcher success for the second request. @@ -357,7 +360,8 @@ EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(account_id_2)); EXPECT_FALSE( identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id_2) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id_2) .value() .is_under_advanced_protection); // Check that the reconcilor was blocked and unblocked exactly once.
diff --git a/chrome/browser/signin/signin_ui_util.cc b/chrome/browser/signin/signin_ui_util.cc index 0bcb7c5..d925f450 100644 --- a/chrome/browser/signin/signin_ui_util.cc +++ b/chrome/browser/signin/signin_ui_util.cc
@@ -174,7 +174,8 @@ IdentityManagerFactory::GetForProfile(profile); std::string email = identity_manager - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) ->email; if (email.empty()) { DCHECK_EQ(
diff --git a/chrome/browser/signin/signin_ui_util_unittest.cc b/chrome/browser/signin/signin_ui_util_unittest.cc index 7a642eb..1b6de2e 100644 --- a/chrome/browser/signin/signin_ui_util_unittest.cc +++ b/chrome/browser/signin/signin_ui_util_unittest.cc
@@ -278,7 +278,8 @@ EnableSync( GetIdentityManager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) .value(), is_default_promo_account); signin_metrics::PromoAction expected_promo_action = @@ -337,7 +338,8 @@ EnableSync( GetIdentityManager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) .value(), is_default_promo_account); ASSERT_FALSE(create_dice_turn_sync_on_helper_called_);
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service.cc b/chrome/browser/supervised_user/child_accounts/child_account_service.cc index 31da29f..2c4eb64 100644 --- a/chrome/browser/supervised_user/child_accounts/child_account_service.cc +++ b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
@@ -99,7 +99,7 @@ // If we're already signed in, check the account immediately just to be sure. // (We might have missed an update before registering as an observer.) base::Optional<AccountInfo> primary_account_info = - identity_manager_->FindExtendedAccountInfoForAccount( + identity_manager_->FindExtendedAccountInfoForAccountWithRefreshToken( identity_manager_->GetPrimaryAccountInfo()); if (primary_account_info.has_value())
diff --git a/chrome/browser/supervised_user/kids_chrome_management/kids_chrome_management_client.h b/chrome/browser/supervised_user/kids_chrome_management/kids_chrome_management_client.h index b0baa420..3a261e08 100644 --- a/chrome/browser/supervised_user/kids_chrome_management/kids_chrome_management_client.h +++ b/chrome/browser/supervised_user/kids_chrome_management/kids_chrome_management_client.h
@@ -57,7 +57,7 @@ // Interface to KidsManagementURLCheckerClient. Classifies a URL as safe // or restricted for a supervised user. - void ClassifyURL( + virtual void ClassifyURL( std::unique_ptr<kids_chrome_management::ClassifyUrlRequest> request_proto, KidsChromeManagementCallback callback);
diff --git a/chrome/browser/supervised_user/kids_management_url_checker_client.cc b/chrome/browser/supervised_user/kids_management_url_checker_client.cc index 9046b4e..4e22e2d4 100644 --- a/chrome/browser/supervised_user/kids_management_url_checker_client.cc +++ b/chrome/browser/supervised_user/kids_management_url_checker_client.cc
@@ -7,325 +7,71 @@ #include <utility> #include "base/callback.h" -#include "base/feature_list.h" -#include "base/json/json_reader.h" #include "base/logging.h" -#include "base/metrics/histogram_macros.h" -#include "base/optional.h" #include "base/stl_util.h" -#include "base/strings/string_piece.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/time/time.h" -#include "base/values.h" -#include "chrome/browser/supervised_user/supervised_user_constants.h" -#include "components/google/core/common/google_util.h" -#include "components/signin/public/identity_manager/access_token_info.h" -#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h" -#include "google_apis/google_api_keys.h" -#include "net/base/escape.h" -#include "net/base/load_flags.h" -#include "net/http/http_status_code.h" -#include "net/url_request/url_request_status.h" -#include "services/identity/public/cpp/scope_set.h" -#include "services/network/public/cpp/resource_request.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" -#include "services/network/public/cpp/simple_url_loader.h" -#include "url/url_constants.h" - -enum class KidsManagementClassification { kAllowed, kRestricted, kUnknown }; - -enum class KidsManagementResponseStatus { - kSuccess = 0, - kNetworkError = 1, - kUnexpectedClassificationValue = 2, - kParsingError = 3, - kTokenError = 4, - kHttpError = 5, - kMaxValue = kHttpError, -}; - -struct KidsManagementURLCheckerResponse { - public: - KidsManagementClassification classification; - KidsManagementResponseStatus status; - - static KidsManagementURLCheckerResponse ForSuccess( - KidsManagementClassification classification) { - return KidsManagementURLCheckerResponse( - KidsManagementResponseStatus::kSuccess, classification); - } - - static KidsManagementURLCheckerResponse ForFailure( - KidsManagementResponseStatus status) { - return KidsManagementURLCheckerResponse( - status, KidsManagementClassification::kUnknown); - } - - private: - KidsManagementURLCheckerResponse( - const KidsManagementResponseStatus& status, - const KidsManagementClassification& classification) - : classification(classification), status(status) {} -}; +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/supervised_user/kids_chrome_management/kids_chrome_management_client_factory.h" +#include "url/gurl.h" namespace { -const char kClassifyUrlApiPath[] = - "https://kidsmanagement-pa.googleapis.com/kidsmanagement/v1/people/" - "me:classifyUrl"; +using kids_chrome_management::ClassifyUrlResponse; -const char kKidPermissionScope[] = - "https://www.googleapis.com/auth/kid.permission"; -const char kDataContentType[] = "application/x-www-form-urlencoded"; -const char kDataFormat[] = "url=%s®ion_code=%s"; -// Possible responses from KidsManagement ClassifyUrl RPC allowed and restricted -const char kAllowed[] = "allowed"; -const char kRestricted[] = "restricted"; - -// Builds the POST data for KidsManagement ClassifyURL requests. -std::string BuildRequestData(const GURL& url, const std::string& region_code) { - std::string query = net::EscapeQueryParamValue(url.spec(), true); - return base::StringPrintf(kDataFormat, query.c_str(), region_code.c_str()); -} - -// Parses a KidsManagement API |response| and returns the classification. -// On failure returns classification kUnknown and status with the reason for -// failure. -KidsManagementURLCheckerResponse ParseResponse(const std::string& response) { - base::Optional<base::Value> optional_value = base::JSONReader::Read(response); - const base::DictionaryValue* dict = nullptr; - if (!optional_value || !optional_value.value().GetAsDictionary(&dict)) { - DLOG(WARNING) << "ParseResponse failed to parse global dictionary"; - return KidsManagementURLCheckerResponse::ForFailure( - KidsManagementResponseStatus::kParsingError); - } - - const base::Value* classification_value = - dict->FindKey("displayClassification"); - if (!classification_value) { - DLOG(WARNING) << "ParseResponse failed to parse displayClassification"; - return KidsManagementURLCheckerResponse::ForFailure( - KidsManagementResponseStatus::kParsingError); - } - - const std::string classification_string = classification_value->GetString(); - if (classification_string == kAllowed) { - return KidsManagementURLCheckerResponse::ForSuccess( - KidsManagementClassification::kAllowed); - } else if (classification_string == kRestricted) { - return KidsManagementURLCheckerResponse::ForSuccess( - KidsManagementClassification::kRestricted); - } - DLOG(WARNING) << "ParseResponse expected a valid displayClassification"; - return KidsManagementURLCheckerResponse::ForFailure( - KidsManagementResponseStatus::kUnexpectedClassificationValue); -} - -safe_search_api::ClientClassification ToClientClassification( - const KidsManagementClassification& classification) { - switch (classification) { - case KidsManagementClassification::kAllowed: - return safe_search_api::ClientClassification::kAllowed; - case KidsManagementClassification::kRestricted: - return safe_search_api::ClientClassification::kRestricted; - case KidsManagementClassification::kUnknown: +safe_search_api::ClientClassification ToSafeSearchClientClassification( + ClassifyUrlResponse* classify_url_response) { + switch (classify_url_response->display_classification()) { + case ClassifyUrlResponse::UNKNOWN_DISPLAY_CLASSIFICATION: return safe_search_api::ClientClassification::kUnknown; + case ClassifyUrlResponse::RESTRICTED: + return safe_search_api::ClientClassification::kRestricted; + case ClassifyUrlResponse::ALLOWED: + return safe_search_api::ClientClassification::kAllowed; } } } // namespace -struct KidsManagementURLCheckerClient::Check { - Check(const GURL& url, ClientCheckCallback callback); - ~Check(); - Check(Check&&) = default; - - GURL url; - std::unique_ptr<signin::PrimaryAccountAccessTokenFetcher> - access_token_fetcher; - bool access_token_expired; - std::unique_ptr<network::SimpleURLLoader> simple_url_loader; - ClientCheckCallback callback; - base::TimeTicks start_time; -}; - -KidsManagementURLCheckerClient::Check::Check(const GURL& url, - ClientCheckCallback callback) - : url(url), - access_token_expired(false), - callback(std::move(callback)), - start_time(base::TimeTicks::Now()) {} - -KidsManagementURLCheckerClient::Check::~Check() { - DCHECK(!callback); -} - KidsManagementURLCheckerClient::KidsManagementURLCheckerClient( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& country, - signin::IdentityManager* identity_manager) - : url_loader_factory_(std::move(url_loader_factory)), - traffic_annotation_( - net::DefineNetworkTrafficAnnotation("kids_management_url_checker", R"( - semantics { - sender: "Supervised Users" - description: - "Checks whether a given URL (or set of URLs) is considered safe by " - "Google KidsManagement." - trigger: - "If the parent enabled this feature for the child account, this is " - "sent for every navigation." - data: - "The request is authenticated with an OAuth2 access token " - "identifying the Google account. The URL to be checked." - destination: GOOGLE_OWNED_SERVICE - } - policy { - cookies_allowed: NO - setting: - "This feature is only used in child accounts and cannot be " - "disabled by settings. Parent accounts can disable it in the " - "family dashboard." - chrome_policy { - RestrictSigninToPattern { - policy_options {mode: MANDATORY} - RestrictSigninToPattern: "*@manageddomain.com" - } - } - })")), - country_(country), - identity_manager_(identity_manager) {} + const std::string& country) + : country_(country) {} KidsManagementURLCheckerClient::~KidsManagementURLCheckerClient() = default; void KidsManagementURLCheckerClient::CheckURL(const GURL& url, ClientCheckCallback callback) { - checks_in_progress_.push_front( - std::make_unique<Check>(url, std::move(callback))); + auto classify_url_request = + std::make_unique<kids_chrome_management::ClassifyUrlRequest>(); + classify_url_request->set_url(url.spec()); + classify_url_request->set_region_code(country_); - StartFetching(checks_in_progress_.begin()); + KidsChromeManagementClient* kids_chrome_management_client = + KidsChromeManagementClientFactory::GetInstance()->GetForBrowserContext( + ProfileManager::GetActiveUserProfile()); + + kids_chrome_management_client->ClassifyURL( + std::move(classify_url_request), + base::BindOnce(&KidsManagementURLCheckerClient::ConvertResponseCallback, + base::Unretained(this), url, std::move(callback))); } -void KidsManagementURLCheckerClient::StartFetching(CheckList::iterator it) { - identity::ScopeSet scopes{kKidPermissionScope}; - // It is safe to use Unretained(this) here given that the callback - // will not be invoked if this object is deleted. Likewise, |it| - // only comes from |checks_in_progress_|, which are owned by this object - // too. - it->get()->access_token_fetcher = - std::make_unique<signin::PrimaryAccountAccessTokenFetcher>( - "kids_url_classifier", identity_manager_, scopes, - base::BindOnce( - &KidsManagementURLCheckerClient::OnAccessTokenFetchComplete, - base::Unretained(this), it), - signin::PrimaryAccountAccessTokenFetcher::Mode::kImmediate); -} +void KidsManagementURLCheckerClient::ConvertResponseCallback( + const GURL& url, + ClientCheckCallback client_callback, + std::unique_ptr<google::protobuf::MessageLite> response_proto, + KidsChromeManagementClient::ErrorCode error_code) { + ClassifyUrlResponse* classify_url_response = + static_cast<ClassifyUrlResponse*>(response_proto.get()); -void KidsManagementURLCheckerClient::OnAccessTokenFetchComplete( - CheckList::iterator it, - GoogleServiceAuthError error, - signin::AccessTokenInfo token_info) { - if (error.state() != GoogleServiceAuthError::NONE) { - DLOG(WARNING) << "Token error: " << error.ToString(); + DVLOG(1) << "URL classification = " + << classify_url_response->display_classification(); - DispatchResult(it, KidsManagementURLCheckerResponse::ForFailure( - KidsManagementResponseStatus::kTokenError)); - return; - } - Check* check = it->get(); - - DVLOG(1) << "Checking URL " << check->url; - auto resource_request = std::make_unique<network::ResourceRequest>(); - resource_request->url = GURL(kClassifyUrlApiPath); - resource_request->method = "POST"; - resource_request->load_flags = - net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES; - resource_request->headers.SetHeader( - net::HttpRequestHeaders::kAuthorization, - base::StringPrintf(supervised_users::kAuthorizationHeaderFormat, - token_info.token.c_str())); - check->simple_url_loader = network::SimpleURLLoader::Create( - std::move(resource_request), traffic_annotation_); - check->simple_url_loader->AttachStringForUpload( - BuildRequestData(check->url, country_), kDataContentType); - - check->simple_url_loader->DownloadToString( - url_loader_factory_.get(), - base::BindOnce(&KidsManagementURLCheckerClient::OnSimpleLoaderComplete, - base::Unretained(this), it, token_info), - /*max_body_size*/ 128); -} - -void KidsManagementURLCheckerClient::OnSimpleLoaderComplete( - CheckList::iterator it, - signin::AccessTokenInfo token_info, - std::unique_ptr<std::string> response_body) { - Check* check = it->get(); - std::unique_ptr<network::SimpleURLLoader> simple_url_loader = - std::move(check->simple_url_loader); - int response_code = -1; - if (simple_url_loader->ResponseInfo() && - simple_url_loader->ResponseInfo()->headers) { - response_code = simple_url_loader->ResponseInfo()->headers->response_code(); - } - - // Handle first HTTP_UNAUTHORIZED response by removing access token and - // restarting the request from the beginning (fetching access token). - if (response_code == net::HTTP_UNAUTHORIZED && !check->access_token_expired) { - DLOG(WARNING) << "Access token expired:\n" << token_info.token; - check->access_token_expired = true; - identity::ScopeSet scopes{kKidPermissionScope}; - identity_manager_->RemoveAccessTokenFromCache( - identity_manager_->GetPrimaryAccountId(), scopes, token_info.token); - StartFetching(it); + if (error_code != KidsChromeManagementClient::ErrorCode::kSuccess) { + DVLOG(1) << "ClassifyUrl request failed."; + std::move(client_callback) + .Run(url, safe_search_api::ClientClassification::kUnknown); return; } - int net_error = simple_url_loader->NetError(); - if (net_error != net::OK) { - DLOG(WARNING) << "Network error " << net_error; - DispatchResult(it, KidsManagementURLCheckerResponse::ForFailure( - KidsManagementResponseStatus::kNetworkError)); - return; - } - - if (response_code != net::HTTP_OK) { - DLOG(WARNING) << "HTTP error " << response_code; - DLOG(WARNING) << "Response: " << response_body.get(); - DispatchResult(it, KidsManagementURLCheckerResponse::ForFailure( - KidsManagementResponseStatus::kHttpError)); - return; - } - - // |response_body| is nullptr only in case of failure - if (!response_body) { - DLOG(WARNING) << "URL request failed! Letting through..."; - DispatchResult(it, KidsManagementURLCheckerResponse::ForFailure( - KidsManagementResponseStatus::kNetworkError)); - return; - } - - DispatchResult(it, ParseResponse(*response_body)); -} - -void KidsManagementURLCheckerClient::DispatchResult( - CheckList::iterator it, - KidsManagementURLCheckerResponse response) { - if (response.status == KidsManagementResponseStatus::kSuccess) { - UMA_HISTOGRAM_TIMES("ManagedUsers.KidsManagementClassifyUrlSuccessDelay", - base::TimeTicks::Now() - it->get()->start_time); - } else { - UMA_HISTOGRAM_TIMES("ManagedUsers.KidsManagementClassifyUrlFailureDelay", - base::TimeTicks::Now() - it->get()->start_time); - } - - UMA_HISTOGRAM_ENUMERATION( - "ManagedUsers.KidsManagementUrlCheckerResponseStatus", response.status); - - safe_search_api::ClientClassification api_classification = - ToClientClassification(response.classification); - std::move(it->get()->callback).Run(it->get()->url, api_classification); - - checks_in_progress_.erase(it); + std::move(client_callback) + .Run(url, ToSafeSearchClientClassification(classify_url_response)); }
diff --git a/chrome/browser/supervised_user/kids_management_url_checker_client.h b/chrome/browser/supervised_user/kids_management_url_checker_client.h index bbcd129..6df522d 100644 --- a/chrome/browser/supervised_user/kids_management_url_checker_client.h +++ b/chrome/browser/supervised_user/kids_management_url_checker_client.h
@@ -5,27 +5,17 @@ #ifndef CHROME_BROWSER_SUPERVISED_USER_KIDS_MANAGEMENT_URL_CHECKER_CLIENT_H_ #define CHROME_BROWSER_SUPERVISED_USER_KIDS_MANAGEMENT_URL_CHECKER_CLIENT_H_ -#include <list> #include <memory> #include <string> #include "base/macros.h" -#include "base/memory/scoped_refptr.h" +#include "chrome/browser/supervised_user/kids_chrome_management/kids_chrome_management_client.h" #include "components/safe_search_api/url_checker_client.h" -#include "google_apis/gaia/google_service_auth_error.h" -#include "net/traffic_annotation/network_traffic_annotation.h" -#include "url/gurl.h" -namespace network { -class SharedURLLoaderFactory; -} // namespace network +class GURL; -namespace signin { -class IdentityManager; -struct AccessTokenInfo; -} // namespace signin - -struct KidsManagementURLCheckerResponse; +// TODO(crbug.com/988428): Change comments to use KidsChromeManagement instead +// of KidsManagement when migration is complete. // This class uses the KidsManagement ClassifyUrl to check the classification // of the content on a given URL and returns the result asynchronously @@ -35,10 +25,7 @@ public: // |country| should be a two-letter country code (ISO 3166-1 alpha-2), e.g., // "us". - KidsManagementURLCheckerClient( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& country, - signin::IdentityManager* identity_manager); + explicit KidsManagementURLCheckerClient(const std::string& country); ~KidsManagementURLCheckerClient() override; // Checks whether an |url| is restricted according to KidsManagement @@ -49,30 +36,13 @@ void CheckURL(const GURL& url, ClientCheckCallback callback) override; private: - struct Check; + void ConvertResponseCallback( + const GURL& url, + ClientCheckCallback client_callback, + std::unique_ptr<google::protobuf::MessageLite> response_proto, + KidsChromeManagementClient::ErrorCode error_code); - // Must be list so that iterators stay valid until they are erased. - using CheckList = std::list<std::unique_ptr<Check>>; - - void StartFetching(CheckList::iterator it); - - void OnAccessTokenFetchComplete(CheckList::iterator it, - GoogleServiceAuthError error, - signin::AccessTokenInfo token_info); - - void OnSimpleLoaderComplete(CheckList::iterator it, - signin::AccessTokenInfo token_info, - std::unique_ptr<std::string> response_body); - - void DispatchResult(CheckList::iterator it, - KidsManagementURLCheckerResponse response); - - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; - const net::NetworkTrafficAnnotationTag traffic_annotation_; const std::string country_; - signin::IdentityManager* identity_manager_; - - CheckList checks_in_progress_; DISALLOW_COPY_AND_ASSIGN(KidsManagementURLCheckerClient); };
diff --git a/chrome/browser/supervised_user/kids_management_url_checker_client_unittest.cc b/chrome/browser/supervised_user/kids_management_url_checker_client_unittest.cc index 5757cc4a..1957521f 100644 --- a/chrome/browser/supervised_user/kids_management_url_checker_client_unittest.cc +++ b/chrome/browser/supervised_user/kids_management_url_checker_client_unittest.cc
@@ -8,80 +8,125 @@ #include <utility> #include "base/bind.h" -#include "base/json/json_writer.h" -#include "base/test/scoped_feature_list.h" -#include "base/test/scoped_task_environment.h" +#include "base/macros.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" -#include "components/signin/public/identity_manager/identity_test_environment.h" -#include "net/http/http_status_code.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" -#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" -#include "services/network/test/test_url_loader_factory.h" +#include "chrome/browser/supervised_user/kids_chrome_management/kids_chrome_management_client.h" +#include "chrome/browser/supervised_user/kids_chrome_management/kids_chrome_management_client_factory.h" +#include "chrome/browser/supervised_user/kids_chrome_management/kidschromemanagement_messages.pb.h" +#include "chrome/common/chrome_constants.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/account_id/account_id.h" +#include "content/public/test/test_browser_thread_bundle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" +#endif + namespace { -const char kClassifyUrlApiPath[] = - "https://kidsmanagement-pa.googleapis.com/kidsmanagement/v1/people/" - "me:classifyUrl"; +using kids_chrome_management::ClassifyUrlResponse; -const char kEmail[] = "account@gmail.com"; - -std::string ClassificationToString( +ClassifyUrlResponse::DisplayClassification ConvertClassification( safe_search_api::ClientClassification classification) { switch (classification) { case safe_search_api::ClientClassification::kAllowed: - return "allowed"; + return ClassifyUrlResponse::ALLOWED; case safe_search_api::ClientClassification::kRestricted: - return "restricted"; + return ClassifyUrlResponse::RESTRICTED; case safe_search_api::ClientClassification::kUnknown: - return std::string(); + return ClassifyUrlResponse::UNKNOWN_DISPLAY_CLASSIFICATION; } } -// Build fake JSON string with a response according to |classification|. -std::string BuildResponse( +// Build fake response proto with a response according to |classification|. +std::unique_ptr<ClassifyUrlResponse> BuildResponseProto( safe_search_api::ClientClassification classification) { - base::DictionaryValue dict; - dict.SetKey("displayClassification", - base::Value(ClassificationToString(classification))); - std::string result; - base::JSONWriter::Write(dict, &result); - return result; + auto response_proto = std::make_unique<ClassifyUrlResponse>(); + + response_proto->set_display_classification( + ConvertClassification(classification)); + return response_proto; +} + +class KidsChromeManagementClientForTesting : public KidsChromeManagementClient { + public: + explicit KidsChromeManagementClientForTesting( + content::BrowserContext* context) + : KidsChromeManagementClient(static_cast<Profile*>(context)) {} + + ~KidsChromeManagementClientForTesting() override = default; + + void ClassifyURL( + std::unique_ptr<kids_chrome_management::ClassifyUrlRequest> request_proto, + KidsChromeManagementClient::KidsChromeManagementCallback callback) + override { + std::move(callback).Run(std::move(response_proto_), error_code_); + } + + void SetupResponse(std::unique_ptr<ClassifyUrlResponse> response_proto, + KidsChromeManagementClient::ErrorCode error_code) { + response_proto_ = std::move(response_proto); + error_code_ = error_code; + } + + private: + std::unique_ptr<ClassifyUrlResponse> response_proto_; + KidsChromeManagementClient::ErrorCode error_code_; + + DISALLOW_COPY_AND_ASSIGN(KidsChromeManagementClientForTesting); +}; + +std::unique_ptr<KeyedService> CreateKidsChromeManagementClient( + content::BrowserContext* context) { + return std::make_unique<KidsChromeManagementClientForTesting>(context); } } // namespace class KidsManagementURLCheckerClientTest : public testing::Test { public: - KidsManagementURLCheckerClientTest() - : test_shared_loader_factory_( - base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( - &test_url_loader_factory_)) { - AccountInfo account_info = - identity_test_env_.MakePrimaryAccountAvailable(kEmail); - account_id_ = account_info.account_id; - url_classifier_ = std::make_unique<KidsManagementURLCheckerClient>( - test_shared_loader_factory_, std::string(), - identity_test_env_.identity_manager()); + KidsManagementURLCheckerClientTest() = default; + void SetUp() override { + test_profile_manager_.reset( + new TestingProfileManager(TestingBrowserProcess::GetGlobal())); + ASSERT_TRUE(test_profile_manager_->SetUp()); + test_profile_manager_->SetLoggedIn(true); + +// ChromeOS requires a chromeos::FakeChromeUserManager for the tests to work. +#if defined(OS_CHROMEOS) + const char kEmail[] = "account@gmail.com"; + const AccountId test_account_id(AccountId::FromUserEmail(kEmail)); + user_manager_ = new chromeos::FakeChromeUserManager; + user_manager_->AddUser(test_account_id); + user_manager_->LoginUser(test_account_id); + user_manager_->SwitchActiveUser(test_account_id); + test_profile_ = test_profile_manager_->CreateTestingProfile( + test_account_id.GetUserEmail()); +#else + test_profile_ = + test_profile_manager_->CreateTestingProfile(chrome::kInitialProfile); +#endif + + DCHECK(test_profile_); + + KidsChromeManagementClientFactory::GetInstance()->SetTestingFactory( + test_profile_, base::BindRepeating(&CreateKidsChromeManagementClient)); + + url_classifier_ = std::make_unique<KidsManagementURLCheckerClient>("us"); } protected: - void IssueAccessTokens() { - identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( - account_id_, "access_token", - /*expiration_time*/ base::Time::Now() + base::TimeDelta::FromHours(1)); - } - - void IssueAccessTokenErrors() { - identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithError( - account_id_, GoogleServiceAuthError::FromServiceError("Error!")); - } - - void SetupResponse(net::HttpStatusCode status, const std::string& response) { - test_url_loader_factory_.AddResponse(kClassifyUrlApiPath, response, status); + void SetupClientResponse(std::unique_ptr<ClassifyUrlResponse> response_proto, + KidsChromeManagementClient::ErrorCode error_code) { + static_cast<KidsChromeManagementClientForTesting*>( + KidsChromeManagementClientFactory::GetInstance()->GetForBrowserContext( + test_profile_)) + ->SetupResponse(std::move(response_proto), error_code); } void CheckURL(const GURL& url) { @@ -90,30 +135,20 @@ base::Unretained(this))); } - void CheckURLWithResponse( - const GURL& url, - const safe_search_api::ClientClassification classification) { - CheckURL(url); - SetupResponse(net::HTTP_OK, BuildResponse(classification)); - - IssueAccessTokens(); - WaitForResponse(); - } - - // Only use this if setting response manually. CheckURLWithResponse already - // uses this. - void WaitForResponse() { base::RunLoop().RunUntilIdle(); } - MOCK_METHOD2(OnCheckDone, void(const GURL& url, safe_search_api::ClientClassification classification)); - base::test::ScopedTaskEnvironment scoped_task_environment_; - std::string account_id_; - signin::IdentityTestEnvironment identity_test_env_; - network::TestURLLoaderFactory test_url_loader_factory_; - scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; + content::TestBrowserThreadBundle thread_bundle_; + TestingProfile* test_profile_; + std::unique_ptr<TestingProfileManager> test_profile_manager_; std::unique_ptr<KidsManagementURLCheckerClient> url_classifier_; +#if defined(OS_CHROMEOS) + chromeos::FakeChromeUserManager* user_manager_; +#endif + + private: + DISALLOW_COPY_AND_ASSIGN(KidsManagementURLCheckerClientTest); }; TEST_F(KidsManagementURLCheckerClientTest, Simple) { @@ -125,7 +160,10 @@ EXPECT_CALL(*this, OnCheckDone(url, classification)); - CheckURLWithResponse(url, classification); + SetupClientResponse(BuildResponseProto(classification), + KidsChromeManagementClient::ErrorCode::kSuccess); + + CheckURL(url); } { GURL url("http://randomurl2.com"); @@ -135,30 +173,64 @@ EXPECT_CALL(*this, OnCheckDone(url, classification)); - CheckURLWithResponse(url, classification); + SetupClientResponse(BuildResponseProto(classification), + KidsChromeManagementClient::ErrorCode::kSuccess); + CheckURL(url); } } TEST_F(KidsManagementURLCheckerClientTest, AccessTokenError) { - GURL url("http://randomurl.com"); + GURL url("http://randomurl3.com"); - // Our callback should get called immediately on an error. - EXPECT_CALL( - *this, OnCheckDone(url, safe_search_api::ClientClassification::kUnknown)); + safe_search_api::ClientClassification classification = + safe_search_api::ClientClassification::kUnknown; + + SetupClientResponse(BuildResponseProto(classification), + KidsChromeManagementClient::ErrorCode::kTokenError); + + EXPECT_CALL(*this, OnCheckDone(url, classification)); CheckURL(url); - IssueAccessTokenErrors(); } -TEST_F(KidsManagementURLCheckerClientTest, NetworkError) { - GURL url("http://randomurl.com"); +TEST_F(KidsManagementURLCheckerClientTest, NetworkErrors) { + { + GURL url("http://randomurl4.com"); + + safe_search_api::ClientClassification classification = + safe_search_api::ClientClassification::kUnknown; + + SetupClientResponse(BuildResponseProto(classification), + KidsChromeManagementClient::ErrorCode::kNetworkError); + + EXPECT_CALL(*this, OnCheckDone(url, classification)); + + CheckURL(url); + } + + { + GURL url("http://randomurl5.com"); + + safe_search_api::ClientClassification classification = + safe_search_api::ClientClassification::kUnknown; + + SetupClientResponse(BuildResponseProto(classification), + KidsChromeManagementClient::ErrorCode::kHttpError); + + EXPECT_CALL(*this, OnCheckDone(url, classification)); + + CheckURL(url); + } +} + +TEST_F(KidsManagementURLCheckerClientTest, ServiceError) { + GURL url("http://randomurl6.com"); + + safe_search_api::ClientClassification classification = + safe_search_api::ClientClassification::kUnknown; + + SetupClientResponse(BuildResponseProto(classification), + KidsChromeManagementClient::ErrorCode::kServiceError); + + EXPECT_CALL(*this, OnCheckDone(url, classification)); CheckURL(url); - - IssueAccessTokens(); - - // Our callback should get called on an error. - EXPECT_CALL( - *this, OnCheckDone(url, safe_search_api::ClientClassification::kUnknown)); - - SetupResponse(net::HTTP_FORBIDDEN, std::string()); - WaitForResponse(); }
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc index f763fa1..5b54bc9 100644 --- a/chrome/browser/supervised_user/supervised_user_service.cc +++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -590,8 +590,7 @@ if (use_online_check) { url_filter_.InitAsyncURLChecker( content::BrowserContext::GetDefaultStoragePartition(profile_) - ->GetURLLoaderFactoryForBrowserProcess(), - IdentityManagerFactory::GetForProfile(profile_)); + ->GetURLLoaderFactoryForBrowserProcess()); } else { url_filter_.ClearAsyncURLChecker(); }
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter.cc b/chrome/browser/supervised_user/supervised_user_url_filter.cc index 8bc7bb3..7dba1385 100644 --- a/chrome/browser/supervised_user/supervised_user_url_filter.cc +++ b/chrome/browser/supervised_user/supervised_user_url_filter.cc
@@ -23,7 +23,6 @@ #include "base/task/post_task.h" #include "base/task_runner_util.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/supervised_user/experimental/supervised_user_blacklist.h" #include "chrome/browser/supervised_user/kids_management_url_checker_client.h" #include "chrome/common/chrome_features.h" @@ -534,8 +533,7 @@ } void SupervisedUserURLFilter::InitAsyncURLChecker( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - signin::IdentityManager* identity_manager) { + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { std::string country; variations::VariationsService* variations_service = g_browser_process->variations_service(); @@ -549,8 +547,8 @@ if ((base::FeatureList::IsEnabled( features::kKidsManagementUrlClassification))) { - url_checker_client = std::make_unique<KidsManagementURLCheckerClient>( - std::move(url_loader_factory), country, identity_manager); + url_checker_client = + std::make_unique<KidsManagementURLCheckerClient>(country); } else { // TODO(crbug.com/940454): remove safe_search_checker net::NetworkTrafficAnnotationTag traffic_annotation =
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter.h b/chrome/browser/supervised_user/supervised_user_url_filter.h index 1f7face9..37e9e01 100644 --- a/chrome/browser/supervised_user/supervised_user_url_filter.h +++ b/chrome/browser/supervised_user/supervised_user_url_filter.h
@@ -23,10 +23,6 @@ class GURL; class SupervisedUserBlacklist; -namespace signin { -class IdentityManager; -} - namespace base { class TaskRunner; } @@ -156,8 +152,7 @@ // Initializes the experimental asynchronous checker. void InitAsyncURLChecker( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - signin::IdentityManager* identity_manager); + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); // Clears any asynchronous checker. void ClearAsyncURLChecker();
diff --git a/chrome/browser/sync/test/integration/secondary_account_helper.cc b/chrome/browser/sync/test/integration/secondary_account_helper.cc index 048383f..dfd00178 100644 --- a/chrome/browser/sync/test/integration/secondary_account_helper.cc +++ b/chrome/browser/sync/test/integration/secondary_account_helper.cc
@@ -84,8 +84,9 @@ signin::IdentityManager* identity_manager = IdentityManagerFactory::GetForProfile(profile); base::Optional<AccountInfo> maybe_account = - identity_manager->FindAccountInfoForAccountWithRefreshTokenByEmailAddress( - email); + identity_manager + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( + email); DCHECK(maybe_account.has_value()); auto* primary_account_mutator = identity_manager->GetPrimaryAccountMutator(); primary_account_mutator->SetPrimaryAccount(maybe_account->account_id);
diff --git a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc index 345aaa8..e5030da 100644 --- a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
@@ -34,6 +34,7 @@ #include "components/sync_sessions/session_sync_service.h" #include "components/sync_sessions/session_sync_test_helper.h" #include "components/sync_sessions/synced_session_tracker.h" +#include "content/public/test/test_navigation_observer.h" #include "google_apis/gaia/gaia_auth_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -485,19 +486,29 @@ ASSERT_TRUE(CheckInitialState(0)); GURL first_url = GURL(kURL1); + content::TestNavigationObserver first_url_observer(first_url); + first_url_observer.StartWatchingNewWebContents(); ASSERT_TRUE(OpenTab(0, first_url)); + first_url_observer.WaitForNavigationFinished(); WaitForURLOnServer(first_url); GURL second_url = GURL(kURL2); + content::TestNavigationObserver second_url_observer(second_url); + second_url_observer.WatchExistingWebContents(); NavigateTab(0, second_url); + second_url_observer.WaitForNavigationFinished(); WaitForURLOnServer(second_url); + first_url_observer.WatchExistingWebContents(); NavigateTabBack(0); + first_url_observer.WaitForNavigationFinished(); WaitForURLOnServer(first_url); ExpectNavigationChain({first_url, second_url}); + second_url_observer.WatchExistingWebContents(); NavigateTabForward(0); + second_url_observer.WaitForNavigationFinished(); WaitForURLOnServer(second_url); ExpectNavigationChain({first_url, second_url}); @@ -509,25 +520,38 @@ ASSERT_TRUE(CheckInitialState(0)); GURL base_url = GURL(kURL1); + content::TestNavigationObserver base_url_observer(base_url); + base_url_observer.StartWatchingNewWebContents(); ASSERT_TRUE(OpenTab(0, base_url)); + base_url_observer.WaitForNavigationFinished(); WaitForURLOnServer(base_url); GURL first_url = GURL(kURL2); + content::TestNavigationObserver first_url_observer(first_url); + first_url_observer.WatchExistingWebContents(); NavigateTab(0, first_url); + first_url_observer.WaitForNavigationFinished(); WaitForURLOnServer(first_url); // Check that the navigation chain matches the above sequence of {base_url, // first_url}. ExpectNavigationChain({base_url, first_url}); + base_url_observer.WatchExistingWebContents(); NavigateTabBack(0); + base_url_observer.WaitForNavigationFinished(); WaitForURLOnServer(base_url); GURL second_url = GURL(kURL3); + content::TestNavigationObserver second_url_observer(second_url); + second_url_observer.WatchExistingWebContents(); NavigateTab(0, second_url); + first_url_observer.WaitForNavigationFinished(); WaitForURLOnServer(second_url); + base_url_observer.WatchExistingWebContents(); NavigateTabBack(0); + base_url_observer.WaitForNavigationFinished(); WaitForURLOnServer(base_url); // Check that the navigation chain contains second_url where first_url was
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index ee324d3..3e8a54f 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -602,7 +602,7 @@ if (!identity_manager) return base::string16(); base::Optional<AccountInfo> primary_account_info = - identity_manager->FindExtendedAccountInfoForAccount( + identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken( identity_manager->GetPrimaryAccountInfo()); return primary_account_info ? base::UTF8ToUTF16(primary_account_info->full_name)
diff --git a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc index aa4d2b7..20f1565 100644 --- a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc +++ b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc
@@ -703,7 +703,7 @@ if (!personal_data_manager) return; base::Optional<AccountInfo> account_info = - identity_manager->FindExtendedAccountInfoForAccount( + identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken( personal_data_manager->GetAccountInfoForPaymentsServer()); account_info_ = account_info.value_or(AccountInfo{}); }
diff --git a/chrome/browser/ui/webui/omnibox/omnibox.mojom b/chrome/browser/ui/webui/omnibox/omnibox.mojom index 0f5dbb70..42d400c 100644 --- a/chrome/browser/ui/webui/omnibox/omnibox.mojom +++ b/chrome/browser/ui/webui/omnibox/omnibox.mojom
@@ -65,7 +65,9 @@ }; interface OmniboxPageHandler { + // Registers the webui page. SetClientPage(OmniboxPage page); + // Prompts a autocopmlete controller to process an omnibox query. StartOmniboxQuery(string input_string, bool reset_autocomplete_controller, int32 cursor_position, @@ -77,8 +79,15 @@ }; interface OmniboxPage { - handleNewAutocompleteResponse(OmniboxResponse response, - bool isPageController); - HandleNewAutocompleteQuery(bool isPageController, string input_text); + // Notifies the page of an omnibox response from a autocomplete + // controller. |is_page_controller| indicates wether the response + // originates from a query initiated from the page via + // |StartOmniboxQuery| or from the browser omnibox. + HandleNewAutocompleteResponse(OmniboxResponse response, + bool is_page_controller); + // Notifies the page a new omnibox query has begun. + HandleNewAutocompleteQuery(bool is_page_controller, string input_text); + // Asyncronously notifies the page of the image data URLs for previous omnibox + // responses. HandleAnswerImageData(string image_url, string image_data); };
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc b/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc index 0c1f86f6..3775012 100644 --- a/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc +++ b/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc
@@ -296,7 +296,7 @@ image_urls.push_back(result_by_provider.results[j]->image); } - page_->handleNewAutocompleteResponse(std::move(response), + page_->HandleNewAutocompleteResponse(std::move(response), controller == controller_.get()); // Fill in image data
diff --git a/chrome/browser/ui/webui/policy_ui_handler.cc b/chrome/browser/ui/webui/policy_ui_handler.cc index 85b71b8..1c86b4e93 100644 --- a/chrome/browser/ui/webui/policy_ui_handler.cc +++ b/chrome/browser/ui/webui/policy_ui_handler.cc
@@ -923,11 +923,10 @@ } base::Value PolicyUIHandler::GetPolicyValues() const { - return policy::GetAllPolicyValuesAsArray( - web_ui()->GetWebContents()->GetBrowserContext(), - true /* with_user_policies */, true /* convert_values */, - false /* with_device_data */, true /* is_pretty_print */, - true /* convert_types */); + return policy::ArrayPolicyConversions() + .WithBrowserContext(web_ui()->GetWebContents()->GetBrowserContext()) + .EnableConvertValues(true) + .ToValue(); } void PolicyUIHandler::SendStatus() { @@ -1030,11 +1029,10 @@ void PolicyUIHandler::WritePoliciesToJSONFile( const base::FilePath& path) const { - constexpr bool is_pretty_print = true; - base::Value dict = policy::GetAllPolicyValuesAsDictionary( - web_ui()->GetWebContents()->GetBrowserContext(), - true /* with_user_policies */, false /* convert_values */, - false /* with_device_data */, is_pretty_print, true /* convert_types */); + base::Value dict = + policy::DictionaryPolicyConversions() + .WithBrowserContext(web_ui()->GetWebContents()->GetBrowserContext()) + .ToValue(); base::Value chrome_metadata(base::Value::Type::DICTIONARY); @@ -1085,8 +1083,7 @@ std::string json_policies; base::JSONWriter::WriteWithOptions( - dict, (is_pretty_print ? base::JSONWriter::OPTIONS_PRETTY_PRINT : 0), - &json_policies); + dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_policies); base::PostTaskWithTraits( FROM_HERE,
diff --git a/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc b/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc index e06d720..0da3190 100644 --- a/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
@@ -179,8 +179,9 @@ account.SetBoolean("isDeviceAccount", false); base::Optional<AccountInfo> maybe_account_info = - identity_manager_->FindAccountInfoForAccountWithRefreshTokenByGaiaId( - account_key.id); + identity_manager_ + ->FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId( + account_key.id); DCHECK(maybe_account_info.has_value()); account.SetBoolean(
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index 3ea106d0..6780ce8 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -554,7 +554,7 @@ // account. auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_); base::Optional<AccountInfo> primary_account_info = - identity_manager->FindExtendedAccountInfoForAccount( + identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken( identity_manager->GetPrimaryAccountInfo()); if (primary_account_info.has_value()) accounts_list.push_back(GetAccountValue(primary_account_info.value())); @@ -575,7 +575,7 @@ base::Optional<AccountInfo> maybe_account = IdentityManagerFactory::GetForProfile(profile_) - ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress( + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( email->GetString()); signin_ui_util::EnableSyncFromPromo(
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc index dd5f7fb49..0086f6c69 100644 --- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc +++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
@@ -74,8 +74,9 @@ AccountInfo GetAccountInfo(signin::IdentityManager* identity_manager, const std::string& account_id) { auto maybe_account_info = - identity_manager->FindAccountInfoForAccountWithRefreshTokenByAccountId( - account_id); + identity_manager + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id); return maybe_account_info.has_value() ? maybe_account_info.value() : AccountInfo(); }
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc index 5985972..2ae8e584 100644 --- a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc +++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
@@ -104,7 +104,7 @@ const base::ListValue* args) { DCHECK(profile_->IsSyncAllowed()); base::Optional<AccountInfo> primary_account_info = - identity_manager_->FindExtendedAccountInfoForAccount( + identity_manager_->FindExtendedAccountInfoForAccountWithRefreshToken( identity_manager_->GetPrimaryAccountInfo()); // Fire the "account-image-changed" listener from |SetUserImageURL()|. @@ -215,7 +215,7 @@ return; base::Optional<AccountInfo> primary_account_info = - identity_manager_->FindExtendedAccountInfoForAccount( + identity_manager_->FindExtendedAccountInfoForAccountWithRefreshToken( identity_manager_->GetPrimaryAccountInfo()); if (!primary_account_info) { // No account is signed in, so there is nothing to be displayed in the sync
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc b/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc index 3593351..f00370e 100644 --- a/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc +++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc
@@ -168,7 +168,7 @@ signin::IdentityManager* identity_manager = IdentityManagerFactory::GetForProfile(profile()); base::Optional<AccountInfo> primary_account = - identity_manager->FindExtendedAccountInfoForAccount( + identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken( identity_manager->GetPrimaryAccountInfo()); std::string original_picture_url =
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc index 5d58676..6fce99d 100644 --- a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc +++ b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
@@ -67,7 +67,7 @@ signin::IdentityManager* identity_manager = IdentityManagerFactory::GetForProfile(profile); base::Optional<AccountInfo> primary_account_info = - identity_manager->FindExtendedAccountInfoForAccount( + identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken( identity_manager->GetPrimaryAccountInfo()); GURL account_picture_url(primary_account_info ? primary_account_info->picture_url
diff --git a/chrome/browser/ui/webui/version_handler.cc b/chrome/browser/ui/webui/version_handler.cc index b62cff1..89080ba 100644 --- a/chrome/browser/ui/webui/version_handler.cc +++ b/chrome/browser/ui/webui/version_handler.cc
@@ -26,6 +26,7 @@ #include "content/public/browser/plugin_service.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" +#include "content/public/browser/web_ui_message_handler.h" #include "content/public/common/content_constants.h" #include "ppapi/buildflags/buildflags.h" #include "ui/base/l10n/l10n_util.h" @@ -66,17 +67,73 @@ version_ui::kRequestVersionInfo, base::BindRepeating(&VersionHandler::HandleRequestVersionInfo, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + version_ui::kRequestVariationInfo, + base::BindRepeating(&VersionHandler::HandleRequestVariationInfo, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + version_ui::kRequestPluginInfo, + base::BindRepeating(&VersionHandler::HandleRequestPluginInfo, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + version_ui::kRequestPathInfo, + base::BindRepeating(&VersionHandler::HandleRequestPathInfo, + base::Unretained(this))); } void VersionHandler::HandleRequestVersionInfo(const base::ListValue* args) { + // This method is overridden by platform-specific handlers which may still + // use |CallJavascriptFunction|. Main version info is returned by promise + // using handlers below. + // TODO(orinj): To fully eliminate chrome.send usage in JS, derived classes + // could be made to work more like this base class, using + // |ResolveJavascriptCallback| instead of |CallJavascriptFunction|. AllowJavascript(); +} + +void VersionHandler::HandleRequestVariationInfo(const base::ListValue* args) { + AllowJavascript(); + + std::string callback_id; + bool include_variations_cmd; + CHECK_EQ(2U, args->GetSize()); + CHECK(args->GetString(0, &callback_id)); + CHECK(args->GetBoolean(1, &include_variations_cmd)); + + base::Value response(base::Value::Type::DICTIONARY); + response.SetKey(version_ui::kKeyVariationsList, + std::move(*version_ui::GetVariationsList())); + if (include_variations_cmd) { + response.SetKey(version_ui::kKeyVariationsCmd, + version_ui::GetVariationsCommandLineAsValue()); + } + ResolveJavascriptCallback(base::Value(callback_id), response); +} + +void VersionHandler::HandleRequestPluginInfo(const base::ListValue* args) { + AllowJavascript(); + + std::string callback_id; + CHECK_EQ(1U, args->GetSize()); + CHECK(args->GetString(0, &callback_id)); + #if BUILDFLAG(ENABLE_PLUGINS) // The Flash version information is needed in the response, so make sure // the plugins are loaded. content::PluginService::GetInstance()->GetPlugins( - base::Bind(&VersionHandler::OnGotPlugins, - weak_ptr_factory_.GetWeakPtr())); + base::Bind(&VersionHandler::OnGotPlugins, weak_ptr_factory_.GetWeakPtr(), + callback_id)); +#else + RejectJavascriptCallback(base::Value(callback_id), base::Value()); #endif +} + +void VersionHandler::HandleRequestPathInfo(const base::ListValue* args) { + AllowJavascript(); + + std::string callback_id; + CHECK_EQ(1U, args->GetSize()); + CHECK(args->GetString(0, &callback_id)); // Grab the executable path on the FILE thread. It is returned in // OnGotFilePaths. @@ -87,32 +144,25 @@ base::BindOnce(&GetFilePaths, Profile::FromWebUI(web_ui())->GetPath(), base::Unretained(exec_path_buffer), base::Unretained(profile_path_buffer)), - base::BindOnce( - &VersionHandler::OnGotFilePaths, weak_ptr_factory_.GetWeakPtr(), - base::Owned(exec_path_buffer), base::Owned(profile_path_buffer))); - - // Respond with the variations info immediately. - CallJavascriptFunction(version_ui::kReturnVariationInfo, - *version_ui::GetVariationsList()); - GURL current_url = web_ui()->GetWebContents()->GetVisibleURL(); - if (current_url.query().find(version_ui::kVariationsShowCmdQuery) != - std::string::npos) { - CallJavascriptFunction(version_ui::kReturnVariationCmd, - version_ui::GetVariationsCommandLineAsValue()); - } + base::BindOnce(&VersionHandler::OnGotFilePaths, + weak_ptr_factory_.GetWeakPtr(), callback_id, + base::Owned(exec_path_buffer), + base::Owned(profile_path_buffer))); } -void VersionHandler::OnGotFilePaths(base::string16* executable_path_data, +void VersionHandler::OnGotFilePaths(std::string callback_id, + base::string16* executable_path_data, base::string16* profile_path_data) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - base::Value exec_path(*executable_path_data); - base::Value profile_path(*profile_path_data); - CallJavascriptFunction(version_ui::kReturnFilePaths, exec_path, profile_path); + base::Value response(base::Value::Type::DICTIONARY); + response.SetKey(version_ui::kKeyExecPath, base::Value(*executable_path_data)); + response.SetKey(version_ui::kKeyProfilePath, base::Value(*profile_path_data)); + ResolveJavascriptCallback(base::Value(callback_id), response); } #if BUILDFLAG(ENABLE_PLUGINS) void VersionHandler::OnGotPlugins( + std::string callback_id, const std::vector<content::WebPluginInfo>& plugins) { // Obtain the version of the first enabled Flash plugin. std::vector<content::WebPluginInfo> info_array; @@ -132,9 +182,7 @@ } } } - - base::Value arg(flash_version_and_path); - - CallJavascriptFunction(version_ui::kReturnFlashVersion, arg); + ResolveJavascriptCallback(base::Value(callback_id), + base::Value(flash_version_and_path)); } #endif // BUILDFLAG(ENABLE_PLUGINS)
diff --git a/chrome/browser/ui/webui/version_handler.h b/chrome/browser/ui/webui/version_handler.h index e4c27a53..47e66e7 100644 --- a/chrome/browser/ui/webui/version_handler.h +++ b/chrome/browser/ui/webui/version_handler.h
@@ -22,20 +22,36 @@ // content::WebUIMessageHandler implementation. void RegisterMessages() override; - // Callback for the "requestVersionInfo" message. This asynchronously requests - // the flash version and eventually returns it to the front end along with the - // list of variations using OnGotPlugins. + // Callback for the "requestVersionInfo" message sent by |chrome.send| in JS. + // This is still supported for platform-specific asynchronous calls (see + // derived classes) but the main version information is now retrieved with + // below messages using |cr.sendWithPromise|. virtual void HandleRequestVersionInfo(const base::ListValue* args); + // Callback for the "requestVariationInfo" message. This resolves immediately + // with variations list as well as command variations if requested. + virtual void HandleRequestVariationInfo(const base::ListValue* args); + + // Callback for the "requestPluginInfo" message. This asynchronously requests + // the flash version and eventually returns it to the front end along with the + // list of variations using |OnGotPlugins|. + virtual void HandleRequestPluginInfo(const base::ListValue* args); + + // Callback for the "requestPathInfo" message. This resolves asynchronously + // with |OnGotFilePaths|. + virtual void HandleRequestPathInfo(const base::ListValue* args); + private: // Callback which handles returning the executable and profile paths to the // front end. - void OnGotFilePaths(base::string16* executable_path_data, + void OnGotFilePaths(std::string callback_id, + base::string16* executable_path_data, base::string16* profile_path_data); // Callback for GetPlugins which responds to the page with the Flash version. // This also initiates the OS Version load on ChromeOS. - void OnGotPlugins(const std::vector<content::WebPluginInfo>& plugins); + void OnGotPlugins(std::string callback_id, + const std::vector<content::WebPluginInfo>& plugins); // Factory for the creating refs in callbacks. base::WeakPtrFactory<VersionHandler> weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/webui/version_handler_chromeos.cc b/chrome/browser/ui/webui/version_handler_chromeos.cc index 0791701..0868952f 100644 --- a/chrome/browser/ui/webui/version_handler_chromeos.cc +++ b/chrome/browser/ui/webui/version_handler_chromeos.cc
@@ -16,6 +16,8 @@ void VersionHandlerChromeOS::HandleRequestVersionInfo( const base::ListValue* args) { + VersionHandler::HandleRequestVersionInfo(args); + // Start the asynchronous load of the versions. base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, @@ -33,9 +35,6 @@ base::Bind(&chromeos::version_loader::GetARCVersion), base::Bind(&VersionHandlerChromeOS::OnARCVersion, weak_factory_.GetWeakPtr())); - - // Parent class takes care of the rest. - VersionHandler::HandleRequestVersionInfo(args); } void VersionHandlerChromeOS::OnVersion(const std::string& version) {
diff --git a/chrome/browser/ui/webui/version_handler_win.cc b/chrome/browser/ui/webui/version_handler_win.cc index c225e81..dd5ef639 100644 --- a/chrome/browser/ui/webui/version_handler_win.cc +++ b/chrome/browser/ui/webui/version_handler_win.cc
@@ -17,15 +17,14 @@ void VersionHandlerWindows::HandleRequestVersionInfo( const base::ListValue* args) { + VersionHandler::HandleRequestVersionInfo(args); + // Start the asynchronous load of the versions. base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::BindOnce(&version_utils::win::GetFullWindowsVersion), base::BindOnce(&VersionHandlerWindows::OnVersion, weak_factory_.GetWeakPtr())); - - // Parent class takes care of the rest. - VersionHandler::HandleRequestVersionInfo(args); } void VersionHandlerWindows::OnVersion(const std::string& version) {
diff --git a/chrome/chrome_cleaner/components/recovery_component.cc b/chrome/chrome_cleaner/components/recovery_component.cc index c0543735..e32761b 100644 --- a/chrome/chrome_cleaner/components/recovery_component.cc +++ b/chrome/chrome_cleaner/components/recovery_component.cc
@@ -17,6 +17,7 @@ #include "base/files/file.h" #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/message_loop/message_pump_type.h" #include "base/numerics/safe_conversions.h" #include "base/process/kill.h" #include "base/process/launch.h" @@ -154,7 +155,7 @@ void RecoveryComponent::PreScan() { bool success = recovery_io_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); DCHECK(success) << "Can't start File Thread!"; recovery_io_thread_.task_runner()->PostTask(
diff --git a/chrome/chrome_cleaner/components/system_report_component.cc b/chrome/chrome_cleaner/components/system_report_component.cc index 54a733e2..5cdb568 100644 --- a/chrome/chrome_cleaner/components/system_report_component.cc +++ b/chrome/chrome_cleaner/components/system_report_component.cc
@@ -707,13 +707,14 @@ GetNonWhitelistedDefaultExtensions(json_parser, &default_extension_policies, &default_extensions_done); - // Wait for all asynchronous parsing to be done + // Wait for all asynchronous parsing to be done with a single timeout for all + // phases combined. const base::TimeTicks end_time = base::TimeTicks::Now() + base::TimeDelta::FromMilliseconds(kParseAttemptTimeoutMilliseconds); - extension_settings_done.TimedWaitUntil(end_time); - master_preferences_done.TimedWaitUntil(end_time); - default_extensions_done.TimedWaitUntil(end_time); + extension_settings_done.TimedWait(end_time - base::TimeTicks::Now()); + master_preferences_done.TimedWait(end_time - base::TimeTicks::Now()); + default_extensions_done.TimedWait(end_time - base::TimeTicks::Now()); // Log extensions that were found for (const ExtensionPolicyRegistryEntry& policy :
diff --git a/chrome/chrome_cleaner/ipc/mojo_task_runner.cc b/chrome/chrome_cleaner/ipc/mojo_task_runner.cc index fd1c9f0..ab15974 100644 --- a/chrome/chrome_cleaner/ipc/mojo_task_runner.cc +++ b/chrome/chrome_cleaner/ipc/mojo_task_runner.cc
@@ -8,7 +8,7 @@ #include "base/command_line.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "mojo/core/embedder/embedder.h" namespace chrome_cleaner { @@ -58,7 +58,7 @@ bool MojoTaskRunner::Initialize() { io_thread_ = std::make_unique<base::Thread>("MojoThread"); if (!io_thread_->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0))) { + base::Thread::Options(base::MessagePumpType::IO, 0))) { io_thread_.reset(); return false; }
diff --git a/chrome/chrome_cleaner/scanner/force_installed_extension_scanner_impl.cc b/chrome/chrome_cleaner/scanner/force_installed_extension_scanner_impl.cc index 10b20c2a..82fdec8 100644 --- a/chrome/chrome_cleaner/scanner/force_installed_extension_scanner_impl.cc +++ b/chrome/chrome_cleaner/scanner/force_installed_extension_scanner_impl.cc
@@ -92,7 +92,8 @@ result.emplace(std::move(extension)); } - non_whitelist_default_extensions_done.TimedWaitUntil(end_time); + non_whitelist_default_extensions_done.TimedWait(end_time - + base::TimeTicks::Now()); while (policy_files_default_extensions.size() > 0) { ExtensionPolicyFile file = std::move(policy_files_default_extensions.back()); @@ -109,7 +110,7 @@ result.emplace(std::move(extension)); } - settings_force_installed_done.TimedWaitUntil(end_time); + settings_force_installed_done.TimedWait(end_time - base::TimeTicks::Now()); while (policy_registry_entries_force_installed.size() > 0) { ExtensionPolicyRegistryEntry entry = std::move(policy_registry_entries_force_installed.back()); @@ -126,7 +127,7 @@ result.emplace(std::move(extension)); } - master_preferences_done.TimedWaitUntil(end_time); + master_preferences_done.TimedWait(end_time - base::TimeTicks::Now()); while (policy_files_master_preferences.size() > 0) { ExtensionPolicyFile file = std::move(policy_files_master_preferences.back());
diff --git a/chrome/common/service_process_util_mac_unittest.mm b/chrome/common/service_process_util_mac_unittest.mm index f2849cc..47ccb026 100644 --- a/chrome/common/service_process_util_mac_unittest.mm +++ b/chrome/common/service_process_util_mac_unittest.mm
@@ -15,6 +15,7 @@ #include "base/mac/mac_util.h" #include "base/mac/scoped_nsobject.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/process/launch.h" #include "base/run_loop.h" #include "base/strings/sys_string_conversions.h" @@ -44,7 +45,7 @@ void SetUp() override { base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; ASSERT_TRUE(io_thread_.StartWithOptions(options)); ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); ASSERT_TRUE(MockLaunchd::MakeABundle(GetTempDirPath(), "Test",
diff --git a/chrome/common/service_process_util_unittest.cc b/chrome/common/service_process_util_unittest.cc index 01e26a5..4e0ca368 100644 --- a/chrome/common/service_process_util_unittest.cc +++ b/chrome/common/service_process_util_unittest.cc
@@ -22,6 +22,7 @@ #if !defined(OS_MACOSX) #include "base/at_exit.h" +#include "base/message_loop/message_pump_type.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/multiprocess_test.h" @@ -98,7 +99,7 @@ } void ServiceProcessStateTest::SetUp() { - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); ASSERT_TRUE(io_thread_.StartWithOptions(options)); } @@ -233,7 +234,7 @@ base::test::ScopedTaskEnvironment scoped_task_environment; base::RunLoop run_loop; base::Thread io_thread_("ServiceProcessStateTestShutdownIOThread"); - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); EXPECT_TRUE(io_thread_.StartWithOptions(options)); ServiceProcessState state; EXPECT_TRUE(state.Initialize());
diff --git a/chrome/renderer/safe_browsing/phishing_classifier.cc b/chrome/renderer/safe_browsing/phishing_classifier.cc index 3d75144..f0db660 100644 --- a/chrome/renderer/safe_browsing/phishing_classifier.cc +++ b/chrome/renderer/safe_browsing/phishing_classifier.cc
@@ -39,25 +39,6 @@ const float PhishingClassifier::kInvalidScore = -1.0; const float PhishingClassifier::kPhishyThreshold = 0.5; -namespace { -// Used for UMA, do not reorder. -enum SkipClassificationReason { - CLASSIFICATION_PROCEED = 0, - DEPRECATED_SKIP_HTTPS = 1, - SKIP_NONE_GET = 2, - SKIP_SCHEME_NOT_SUPPORTED = 3, - SKIP_REASON_MAX -}; - -void RecordReasonForSkippingClassificationToUMA( - SkipClassificationReason reason) { - UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.SkipClassificationReason", - reason, - SKIP_REASON_MAX); -} - -} // namespace - PhishingClassifier::PhishingClassifier(content::RenderFrame* render_frame, FeatureExtractorClock* clock) : render_frame_(render_frame), scorer_(nullptr), clock_(clock) { @@ -127,7 +108,6 @@ // Currently, we only classify http/https URLs that are GET requests. GURL url(frame->GetDocument().Url()); if (!url.SchemeIsHTTPOrHTTPS()) { - RecordReasonForSkippingClassificationToUMA(SKIP_SCHEME_NOT_SUPPORTED); RunFailureCallback(); return; } @@ -135,12 +115,10 @@ blink::WebDocumentLoader* document_loader = frame->GetDocumentLoader(); if (!document_loader || document_loader->HttpMethod().Ascii() != "GET") { if (document_loader) - RecordReasonForSkippingClassificationToUMA(SKIP_NONE_GET); RunFailureCallback(); return; } - RecordReasonForSkippingClassificationToUMA(CLASSIFICATION_PROCEED); features_.reset(new FeatureMap); if (!url_extractor_->ExtractFeatures(url, features_.get())) { RunFailureCallback(); @@ -190,7 +168,6 @@ verdict.set_model_version(scorer_->model_version()); verdict.set_url(main_frame->GetDocument().Url().GetString().Utf8()); for (const auto& it : features_->features()) { - DVLOG(2) << "Feature: " << it.first << " = " << it.second; bool result = hashed_features.AddRealFeature( crypto::SHA256HashString(it.first), it.second); DCHECK(result);
diff --git a/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.cc b/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.cc index 6cca973c..6681cf51 100644 --- a/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.cc +++ b/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.cc
@@ -8,6 +8,8 @@ #include "chrome/renderer/subresource_redirect/subresource_redirect_util.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h" #include "content/public/common/resource_type.h" +#include "net/base/escape.h" +#include "net/base/load_flags.h" #include "net/http/http_status_code.h" namespace subresource_redirect { @@ -36,19 +38,63 @@ std::vector<std::string>* to_be_removed_request_headers, net::HttpRequestHeaders* modified_request_headers) { UMA_HISTOGRAM_ENUMERATION( - "SubresourceRedirect.CompressionAttempt.Status", + "SubresourceRedirect.CompressionAttempt.ResponseCode", static_cast<net::HttpStatusCode>(response_head.headers->response_code()), net::HTTP_VERSION_NOT_SUPPORTED); } +void SubresourceRedirectURLLoaderThrottle::BeforeWillProcessResponse( + const GURL& response_url, + const network::ResourceResponseHead& response_head, + bool* defer) { + // If response was not from the compression server, don't restart it. + if (!response_url.is_valid()) + return; + GURL compression_server = GetLitePageSubresourceDomainURL(); + if (!response_url.DomainIs(compression_server.host())) + return; + if (response_url.EffectiveIntPort() != compression_server.EffectiveIntPort()) + return; + if (response_url.scheme() != compression_server.scheme()) + return; + + // Log all response codes, from the compression server. + UMA_HISTOGRAM_ENUMERATION( + "SubresourceRedirect.CompressionAttempt.ResponseCode", + static_cast<net::HttpStatusCode>(response_head.headers->response_code()), + net::HTTP_VERSION_NOT_SUPPORTED); + + // Do nothing with 2XX responses, as these requests were handled + // correctly by the compression server. + if ((response_head.headers->response_code() >= 200 && + response_head.headers->response_code() <= 299) || + response_head.headers->response_code() == 304) { + return; + } + + // Non 2XX responses from the compression server need to have unaltered + // requests sent to the original resource. + delegate_->RestartWithURLResetAndFlags(net::LOAD_NORMAL); +} + void SubresourceRedirectURLLoaderThrottle::WillProcessResponse( const GURL& response_url, network::ResourceResponseHead* response_head, bool* defer) { - UMA_HISTOGRAM_ENUMERATION( - "SubresourceRedirect.CompressionAttempt.Status", - static_cast<net::HttpStatusCode>(response_head->headers->response_code()), - net::HTTP_VERSION_NOT_SUPPORTED); + // If response was not from the compression server, don't record any metrics. + if (!response_url.is_valid()) + return; + GURL compression_server = GetLitePageSubresourceDomainURL(); + if (!response_url.DomainIs(compression_server.host())) + return; + if (response_url.EffectiveIntPort() != compression_server.EffectiveIntPort()) + return; + if (response_url.scheme() != compression_server.scheme()) + return; + + // Record that the server responded. + UMA_HISTOGRAM_BOOLEAN( + "SubresourceRedirect.CompressionAttempt.ServerResponded", true); // If compression was unsuccessful don't try and record compression percent. if (response_head->headers->response_code() != 200) @@ -74,6 +120,16 @@ static_cast<int>(ofcl - content_length)); } +void SubresourceRedirectURLLoaderThrottle::WillOnCompleteWithError( + const network::URLLoaderCompletionStatus& status, + bool* defer) { + // If the server fails, restart the request to the original resource, and + // record it. + delegate_->RestartWithURLResetAndFlags(net::LOAD_NORMAL); + UMA_HISTOGRAM_BOOLEAN( + "SubresourceRedirect.CompressionAttempt.ServerResponded", false); +} + void SubresourceRedirectURLLoaderThrottle::DetachFromCurrentSequence() {} } // namespace subresource_redirect
diff --git a/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h b/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h index 1f8dbca..50cf816c 100644 --- a/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h +++ b/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h
@@ -25,9 +25,15 @@ bool* defer, std::vector<std::string>* to_be_removed_request_headers, net::HttpRequestHeaders* modified_request_headers) override; + void BeforeWillProcessResponse( + const GURL& response_url, + const network::ResourceResponseHead& response_head, + bool* defer) override; void WillProcessResponse(const GURL& response_url, network::ResourceResponseHead* response_head, bool* defer) override; + void WillOnCompleteWithError(const network::URLLoaderCompletionStatus& status, + bool* defer) override; // Overridden to do nothing as the default implementation is NOT_REACHED() void DetachFromCurrentSequence() override; };
diff --git a/chrome/service/service_ipc_server_unittest.cc b/chrome/service/service_ipc_server_unittest.cc index 5f0031a6..4225a16 100644 --- a/chrome/service/service_ipc_server_unittest.cc +++ b/chrome/service/service_ipc_server_unittest.cc
@@ -95,7 +95,7 @@ void ServiceIPCServerTest::SetUp() { base::Thread::Options options; mojo::MessagePipe channel; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; ASSERT_TRUE(io_thread_.StartWithOptions(options)); server_.reset(new ServiceIPCServer(&service_process_client_,
diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc index dba3432..2cad9d8e 100644 --- a/chrome/service/service_process.cc +++ b/chrome/service/service_process.cc
@@ -17,7 +17,7 @@ #include "base/location.h" #include "base/macros.h" #include "base/memory/singleton.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/path_service.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -175,7 +175,7 @@ // Initialize the IO and FILE threads. base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; io_thread_.reset(new ServiceIOThread("ServiceProcess_IO")); if (!io_thread_->StartWithOptions(options)) { NOTREACHED();
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 3506e7f..d3df184 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1075,6 +1075,7 @@ "../browser/sessions/tab_restore_service_browsertest.cc", "../browser/sessions/tab_restore_service_load_waiter.cc", "../browser/sessions/tab_restore_service_load_waiter.h", + "../browser/sharing/click_to_call/click_to_call_browsertest.cc", "../browser/signin/consistency_cookie_browsertest.cc", "../browser/site_isolation/chrome_site_per_process_browsertest.cc", "../browser/site_isolation/site_details_browsertest.cc",
diff --git a/chrome/test/chromedriver/net/net_util_unittest.cc b/chrome/test/chromedriver/net/net_util_unittest.cc index 7ec19f1..f11511d 100644 --- a/chrome/test/chromedriver/net/net_util_unittest.cc +++ b/chrome/test/chromedriver/net/net_util_unittest.cc
@@ -11,7 +11,7 @@ #include "base/compiler_specific.h" #include "base/location.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" #include "base/synchronization/waitable_event.h" @@ -41,7 +41,7 @@ response_(kSendHello), scoped_task_environment_( base::test::ScopedTaskEnvironment::MainThreadType::IO) { - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); CHECK(io_thread_.StartWithOptions(options)); base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
diff --git a/chrome/test/chromedriver/net/sync_websocket_impl_unittest.cc b/chrome/test/chromedriver/net/sync_websocket_impl_unittest.cc index 75b4096..8ffaf3f 100644 --- a/chrome/test/chromedriver/net/sync_websocket_impl_unittest.cc +++ b/chrome/test/chromedriver/net/sync_websocket_impl_unittest.cc
@@ -7,7 +7,7 @@ #include "base/bind.h" #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/threading/platform_thread.h" #include "base/threading/thread.h" @@ -29,7 +29,7 @@ ~SyncWebSocketImplTest() override {} void SetUp() override { - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); ASSERT_TRUE(client_thread_.StartWithOptions(options)); context_getter_ = new URLRequestContextGetter(client_thread_.task_runner()); ASSERT_TRUE(server_.Start());
diff --git a/chrome/test/chromedriver/server/chromedriver_server.cc b/chrome/test/chromedriver/server/chromedriver_server.cc index f0a4c6f2..aa763b4 100644 --- a/chrome/test/chromedriver/server/chromedriver_server.cc +++ b/chrome/test/chromedriver/server/chromedriver_server.cc
@@ -20,6 +20,7 @@ #include "base/files/file_util.h" #include "base/lazy_instance.h" #include "base/logging.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" @@ -352,7 +353,7 @@ int adb_port) { base::Thread io_thread("ChromeDriver IO"); CHECK(io_thread.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); + base::Thread::Options(base::MessagePumpType::IO, 0))); base::SingleThreadTaskExecutor main_task_executor; base::RunLoop cmd_run_loop;
diff --git a/chrome/test/data/extensions/test_certificate_provider/extension.crx b/chrome/test/data/extensions/test_certificate_provider/extension.crx index 8331aba6c..a5a9cf2 100644 --- a/chrome/test/data/extensions/test_certificate_provider/extension.crx +++ b/chrome/test/data/extensions/test_certificate_provider/extension.crx Binary files differ
diff --git a/chrome/test/data/extensions/test_certificate_provider/extension/background.js b/chrome/test/data/extensions/test_certificate_provider/extension/background.js index 1ffdc605..e272ab03 100644 --- a/chrome/test/data/extensions/test_certificate_provider/extension/background.js +++ b/chrome/test/data/extensions/test_certificate_provider/extension/background.js
@@ -54,7 +54,10 @@ JSON.stringify( ['onSignDigestRequested', jsonifiableFromSignRequest(request)]), response => { - const signature = arrayBufferFromByteList(JSON.parse(response)); + const parsedResponse = JSON.parse(response); + const signature = (parsedResponse === null) ? + undefined : + arrayBufferFromByteList(parsedResponse); reportCallback(signature); }); });
diff --git a/chrome/test/data/load_image/fail_image.html b/chrome/test/data/load_image/fail_image.html new file mode 100644 index 0000000..25a4366 --- /dev/null +++ b/chrome/test/data/load_image/fail_image.html
@@ -0,0 +1,17 @@ +<html> +<head></head> +<img alt="long_placeholder_text" src="fail_image.png" /> +<script> +function checkImage() { + sendValueToTest(document.images[0].complete); +} + +function imageSrc() { + sendValueToTest(document.images[0].src); +} + +function sendValueToTest(value) { + window.domAutomationController.send(value); +} +</script> +</html>
diff --git a/chrome/test/data/load_image/fail_image.png b/chrome/test/data/load_image/fail_image.png new file mode 100644 index 0000000..12070dd5 --- /dev/null +++ b/chrome/test/data/load_image/fail_image.png Binary files differ
diff --git a/chrome/test/data/load_image/image.html b/chrome/test/data/load_image/image.html index 6b99865..accf515 100644 --- a/chrome/test/data/load_image/image.html +++ b/chrome/test/data/load_image/image.html
@@ -6,6 +6,10 @@ sendValueToTest(document.images[0].complete); } +function imageSrc() { + sendValueToTest(document.images[0].src); +} + function sendValueToTest(value) { window.domAutomationController.send(value); }
diff --git a/chrome/test/data/load_image/image_js.html b/chrome/test/data/load_image/image_js.html index b7f5855..1f092f6 100644 --- a/chrome/test/data/load_image/image_js.html +++ b/chrome/test/data/load_image/image_js.html
@@ -10,6 +10,10 @@ sendValueToTest(document.images[0].complete); } + function imageSrc() { + sendValueToTest(document.images[0].src); + } + function sendValueToTest(value) { window.domAutomationController.send(value); }
diff --git a/chrome/test/data/load_image/private_url_image.html b/chrome/test/data/load_image/private_url_image.html index 29bf1d6..a1b16ae0 100644 --- a/chrome/test/data/load_image/private_url_image.html +++ b/chrome/test/data/load_image/private_url_image.html
@@ -6,6 +6,10 @@ sendValueToTest((document.images[0].complete && (document.images[0].naturalWidth > 0))); } +function imageSrc() { + sendValueToTest(document.images[0].src); +} + function sendValueToTest(value) { window.domAutomationController.send(value); }
diff --git a/chrome/test/data/load_image/private_url_image_js.html b/chrome/test/data/load_image/private_url_image_js.html index 2483b400..a1232a7 100644 --- a/chrome/test/data/load_image/private_url_image_js.html +++ b/chrome/test/data/load_image/private_url_image_js.html
@@ -10,6 +10,10 @@ sendValueToTest((document.images[0].complete && (document.images[0].naturalWidth > 0))); } + function imageSrc() { + sendValueToTest(document.images[0].src); + } + function sendValueToTest(value) { window.domAutomationController.send(value); }
diff --git a/chrome/utility/image_writer/disk_unmounter_mac.cc b/chrome/utility/image_writer/disk_unmounter_mac.cc index abe577356..de0948a 100644 --- a/chrome/utility/image_writer/disk_unmounter_mac.cc +++ b/chrome/utility/image_writer/disk_unmounter_mac.cc
@@ -8,6 +8,7 @@ #include <sys/socket.h> #include "base/message_loop/message_pump_mac.h" +#include "base/message_loop/message_pump_type.h" #include "base/posix/eintr_wrapper.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" @@ -18,7 +19,7 @@ DiskUnmounterMac::DiskUnmounterMac() : cf_thread_("ImageWriterDiskArb") { base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_UI; + options.message_pump_type = base::MessagePumpType::UI; cf_thread_.StartWithOptions(options); }
diff --git a/chromecast/base/device_capabilities_impl_unittest.cc b/chromecast/base/device_capabilities_impl_unittest.cc index 692f5ed..2a427274 100644 --- a/chromecast/base/device_capabilities_impl_unittest.cc +++ b/chromecast/base/device_capabilities_impl_unittest.cc
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/values.h" #include "chromecast/base/serializers.h" @@ -238,7 +239,7 @@ class DeviceCapabilitiesImplTest : public ::testing::Test { protected: void SetUp() override { - message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO)); + message_loop_.reset(new base::MessageLoop(base::MessagePumpType::IO)); capabilities_ = DeviceCapabilities::Create(); mock_capabilities_observer_.reset(new MockCapabilitiesObserver()); capabilities_->AddCapabilitiesObserver(mock_capabilities_observer_.get());
diff --git a/chromecast/device/bluetooth/le/gatt_client_manager_impl_test.cc b/chromecast/device/bluetooth/le/gatt_client_manager_impl_test.cc index 6dd9a8d..cccf387 100644 --- a/chromecast/device/bluetooth/le/gatt_client_manager_impl_test.cc +++ b/chromecast/device/bluetooth/le/gatt_client_manager_impl_test.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/test/mock_callback.h" #include "base/test/test_mock_time_task_runner.h" #include "base/threading/thread_task_runner_handle.h" @@ -167,7 +168,7 @@ void SetUp() override { fake_task_runner_ = new base::TestMockTimeTaskRunner(); message_loop_ = - std::make_unique<base::MessageLoop>(base::MessageLoop::TYPE_DEFAULT); + std::make_unique<base::MessageLoop>(base::MessagePumpType::DEFAULT); message_loop_->SetTaskRunner(fake_task_runner_); gatt_client_ = std::make_unique<bluetooth_v2_shlib::MockGattClient>(); gatt_client_manager_ =
diff --git a/chromecast/external_mojo/broker_service/broker_service.cc b/chromecast/external_mojo/broker_service/broker_service.cc index 425c4747..4bb6493 100644 --- a/chromecast/external_mojo/broker_service/broker_service.cc +++ b/chromecast/external_mojo/broker_service/broker_service.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/location.h" #include "base/macros.h" +#include "base/message_loop/message_pump_type.h" #include "base/no_destructor.h" #include "base/sequenced_task_runner.h" #include "base/threading/thread.h" @@ -60,7 +61,7 @@ : service_binding_(this, std::move(request)) { io_thread_ = std::make_unique<base::Thread>("external_mojo"); io_thread_->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); std::vector<std::string> external_services_to_proxy; const service_manager::Manifest& manifest = GetManifest();
diff --git a/chromecast/media/audio/capture_service/capture_service_receiver.cc b/chromecast/media/audio/capture_service/capture_service_receiver.cc index ce0efae..e11ef0a 100644 --- a/chromecast/media/audio/capture_service/capture_service_receiver.cc +++ b/chromecast/media/audio/capture_service/capture_service_receiver.cc
@@ -12,6 +12,7 @@ #include "base/callback.h" #include "base/location.h" #include "base/logging.h" +#include "base/message_loop/message_pump_type.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "base/timer/timer.h" @@ -161,7 +162,7 @@ const ::media::AudioParameters& audio_params) : audio_params_(audio_params), io_thread_(__func__) { base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; // TODO(b/137106361): Tweak the thread priority once the thread priority for // speech processing gets fixed. options.priority = base::ThreadPriority::DISPLAY;
diff --git a/chromecast/media/audio/cast_audio_output_stream.cc b/chromecast/media/audio/cast_audio_output_stream.cc index cfad69a8..7f70077b 100644 --- a/chromecast/media/audio/cast_audio_output_stream.cc +++ b/chromecast/media/audio/cast_audio_output_stream.cc
@@ -14,6 +14,7 @@ #include "base/callback_helpers.h" #include "base/location.h" #include "base/logging.h" +#include "base/message_loop/message_pump_type.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread_task_runner_handle.h" #include "chromecast/base/bind_to_task_runner.h" @@ -483,7 +484,7 @@ DETACH_FROM_THREAD(io_thread_checker_); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; options.priority = base::ThreadPriority::REALTIME_AUDIO; CHECK(io_thread_.StartWithOptions(options)); io_task_runner_ = io_thread_.task_runner();
diff --git a/chromecast/media/cma/backend/android/volume_control_android.cc b/chromecast/media/cma/backend/android/volume_control_android.cc index fdaa65f..02c4dc1 100644 --- a/chromecast/media/cma/backend/android/volume_control_android.cc +++ b/chromecast/media/cma/backend/android/volume_control_android.cc
@@ -17,7 +17,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/no_destructor.h" #include "chromecast/base/init_command_line_shlib.h" #include "chromecast/base/serializers.h" @@ -45,7 +45,7 @@ base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this))); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; thread_.StartWithOptions(options); thread_.task_runner()->PostTask(
diff --git a/chromecast/media/cma/backend/cast_audio_json.cc b/chromecast/media/cma/backend/cast_audio_json.cc index 47d69d2..fcdc424 100644 --- a/chromecast/media/cma/backend/cast_audio_json.cc +++ b/chromecast/media/cma/backend/cast_audio_json.cc
@@ -13,7 +13,7 @@ #include "base/json/json_reader.h" #include "base/location.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/sequenced_task_runner.h" #include "build/build_config.h" @@ -59,7 +59,7 @@ : thread_("cast_audio_json_provider"), cast_audio_watcher_(std::make_unique<base::FilePathWatcher>()) { base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; thread_.StartWithOptions(options); task_runner_ = thread_.task_runner(); }
diff --git a/chromecast/media/cma/backend/desktop/volume_control_desktop.cc b/chromecast/media/cma/backend/desktop/volume_control_desktop.cc index a4c505c..069253f4 100644 --- a/chromecast/media/cma/backend/desktop/volume_control_desktop.cc +++ b/chromecast/media/cma/backend/desktop/volume_control_desktop.cc
@@ -14,7 +14,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/no_destructor.h" #include "base/numerics/ranges.h" #include "base/synchronization/lock.h" @@ -39,7 +39,7 @@ } base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; thread_.StartWithOptions(options); }
diff --git a/chromecast/media/cma/backend/stream_mixer.cc b/chromecast/media/cma/backend/stream_mixer.cc index 3c4ccd46c..26eccd2f7 100644 --- a/chromecast/media/cma/backend/stream_mixer.cc +++ b/chromecast/media/cma/backend/stream_mixer.cc
@@ -16,6 +16,7 @@ #include "base/bind_helpers.h" #include "base/compiler_specific.h" #include "base/logging.h" +#include "base/message_loop/message_pump_type.h" #include "base/no_destructor.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" @@ -185,7 +186,7 @@ options.priority = base::ThreadPriority::REALTIME_AUDIO; #if defined(OS_FUCHSIA) // MixerOutputStreamFuchsia uses FIDL, which works only on IO threads. - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; #endif mixer_thread_->StartWithOptions(options); mixer_task_runner_ = mixer_thread_->task_runner();
diff --git a/chromecast/media/cma/backend/volume_control.cc b/chromecast/media/cma/backend/volume_control.cc index c7b4d36..ae86e1d 100644 --- a/chromecast/media/cma/backend/volume_control.cc +++ b/chromecast/media/cma/backend/volume_control.cc
@@ -20,7 +20,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/no_destructor.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" @@ -124,7 +124,7 @@ } base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; thread_.StartWithOptions(options); thread_.task_runner()->PostTask(
diff --git a/chromeos/components/account_manager/account_manager.cc b/chromeos/components/account_manager/account_manager.cc index 81a05e0..0561dff 100644 --- a/chromeos/components/account_manager/account_manager.cc +++ b/chromeos/components/account_manager/account_manager.cc
@@ -202,6 +202,7 @@ // invocation of |Initialize| matches the one it is currently being called // with. DCHECK_EQ(home_dir, writer_->path().DirName()); + std::move(initialization_callback).Run(); return; } @@ -296,6 +297,11 @@ // AccountManager is supposed to be used as a leaky global. } +bool AccountManager::IsInitialized() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return init_state_ == InitializationState::kInitialized; +} + void AccountManager::RunOnInitialization(base::OnceClosure closure) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/chromeos/components/account_manager/account_manager.h b/chromeos/components/account_manager/account_manager.h index 05a9e6b..964375c 100644 --- a/chromeos/components/account_manager/account_manager.h +++ b/chromeos/components/account_manager/account_manager.h
@@ -139,6 +139,8 @@ // Same as above except that it accepts an |initialization_callback|, which // will be called after Account Manager has been fully initialized. + // If Account Manager has already been fully initialized, + // |initialization_callback| is called immediately. // Note: During initialization, there is no ordering guarantee between // |initialization_callback| and Account Manager's observers getting their // callbacks. @@ -148,6 +150,9 @@ DelayNetworkCallRunner delay_network_call_runner, base::OnceClosure initialization_callback); + // Returns |true| if |AccountManager| has been fully initialized. + bool IsInitialized() const; + // Gets (async) a list of account keys known to |AccountManager|. Note that // |callback| will be immediately called in the same thread if // |AccountManager| has been fully initialized and hence it may not be safe to @@ -258,7 +263,7 @@ class GaiaTokenRevocationRequest; friend class AccountManagerTest; - FRIEND_TEST_ALL_PREFIXES(AccountManagerTest, TestInitialization); + FRIEND_TEST_ALL_PREFIXES(AccountManagerTest, TestInitializationCompletes); FRIEND_TEST_ALL_PREFIXES(AccountManagerTest, TestTokenPersistence); FRIEND_TEST_ALL_PREFIXES(AccountManagerTest, UpdatingAccountEmailShouldNotOverwriteTokens);
diff --git a/chromeos/components/account_manager/account_manager_unittest.cc b/chromeos/components/account_manager/account_manager_unittest.cc index 9d03a1d..911f454f 100644 --- a/chromeos/components/account_manager/account_manager_unittest.cc +++ b/chromeos/components/account_manager/account_manager_unittest.cc
@@ -109,11 +109,21 @@ // parameters. void ResetAndInitializeAccountManager() { account_manager_ = std::make_unique<AccountManagerSpy>(); - account_manager_->Initialize( + InitializeAccountManager(account_manager_.get(), base::DoNothing()); + } + + // |account_manager| is a non-owning pointer. + void InitializeAccountManager(AccountManager* account_manager, + base::OnceClosure initialization_callback) { + account_manager->Initialize( tmp_dir_.GetPath(), test_url_loader_factory_.GetSafeWeakWrapper(), immediate_callback_runner_, base::SequencedTaskRunnerHandle::Get(), - base::DoNothing()); - account_manager_->SetPrefService(&pref_service_); + std::move(initialization_callback)); + account_manager->SetPrefService(&pref_service_); + scoped_task_environment_.RunUntilIdle(); + EXPECT_EQ(account_manager->init_state_, + AccountManager::InitializationState::kInitialized); + EXPECT_TRUE(account_manager->IsInitialized()); } // Check base/test/scoped_task_environment.h. This must be the first member / @@ -182,19 +192,39 @@ EXPECT_TRUE(key3.IsValid()); } -TEST_F(AccountManagerTest, TestInitialization) { +TEST_F(AccountManagerTest, TestInitializationCompletes) { AccountManager account_manager; EXPECT_EQ(account_manager.init_state_, AccountManager::InitializationState::kNotStarted); - account_manager.Initialize( - tmp_dir_.GetPath(), test_url_loader_factory_.GetSafeWeakWrapper(), - immediate_callback_runner_, base::SequencedTaskRunnerHandle::Get(), - base::DoNothing()); - account_manager.SetPrefService(&pref_service_); - scoped_task_environment_.RunUntilIdle(); - EXPECT_EQ(account_manager.init_state_, - AccountManager::InitializationState::kInitialized); + // Test assertions will be made inside the method. + InitializeAccountManager(&account_manager, base::DoNothing()); +} + +TEST_F(AccountManagerTest, TestInitializationCallbackIsCalled) { + bool init_callback_was_called = false; + base::OnceClosure closure = base::BindLambdaForTesting( + [&init_callback_was_called]() { init_callback_was_called = true; }); + AccountManager account_manager; + InitializeAccountManager(&account_manager, std::move(closure)); + ASSERT_TRUE(init_callback_was_called); +} + +// Tests that |AccountManager::Initialize|'s callback parameter is called, if +// |AccountManager::Initialize| is invoked after Account Manager has been fully +// initialized. +TEST_F(AccountManagerTest, + TestInitializationCallbackIsCalledIfAccountManagerIsAlreadyInitialized) { + // Make sure that Account Manager is fully initialized. + AccountManager account_manager; + InitializeAccountManager(&account_manager, base::DoNothing()); + + // Send a duplicate initialization call. + bool init_callback_was_called = false; + base::OnceClosure closure = base::BindLambdaForTesting( + [&init_callback_was_called]() { init_callback_was_called = true; }); + InitializeAccountManager(&account_manager, std::move(closure)); + ASSERT_TRUE(init_callback_was_called); } TEST_F(AccountManagerTest, TestUpsert) {
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc index 67a66a5..aefd933 100644 --- a/chromeos/dbus/dbus_thread_manager.cc +++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -8,7 +8,7 @@ #include "base/command_line.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/system/sys_info.h" #include "base/threading/thread.h" #include "chromeos/dbus/arc_keymaster_client.h" @@ -61,7 +61,7 @@ if (use_real_clients) { // Create the D-Bus thread. base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; dbus_thread_.reset(new base::Thread("D-Bus thread")); dbus_thread_->StartWithOptions(thread_options);
diff --git a/chromeos/dbus/system_clock/fake_system_clock_client.cc b/chromeos/dbus/system_clock/fake_system_clock_client.cc index 14c13ae7..ce4b2557 100644 --- a/chromeos/dbus/system_clock/fake_system_clock_client.cc +++ b/chromeos/dbus/system_clock/fake_system_clock_client.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <utility> + #include "chromeos/dbus/system_clock/fake_system_clock_client.h" #include "base/bind.h" #include "base/threading/sequenced_task_runner_handle.h" @@ -21,6 +23,18 @@ observer.SystemClockUpdated(); } +void FakeSystemClockClient::SetServiceIsAvailable(bool is_available) { + is_available_ = is_available; + + if (!is_available_) + return; + + std::vector<dbus::ObjectProxy::WaitForServiceToBeAvailableCallback> callbacks; + callbacks.swap(callbacks_); + for (auto& callback : callbacks) + std::move(callback).Run(true); +} + void FakeSystemClockClient::AddObserver(Observer* observer) { observers_.AddObserver(observer); } @@ -46,6 +60,12 @@ void FakeSystemClockClient::WaitForServiceToBeAvailable( dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback) { + // Parent controls when callbacks are fired. + if (!is_available_) { + callbacks_.push_back(std::move(callback)); + return; + } + base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), true)); }
diff --git a/chromeos/dbus/system_clock/fake_system_clock_client.h b/chromeos/dbus/system_clock/fake_system_clock_client.h index 21362b6..c14615d2 100644 --- a/chromeos/dbus/system_clock/fake_system_clock_client.h +++ b/chromeos/dbus/system_clock/fake_system_clock_client.h
@@ -6,6 +6,7 @@ #define CHROMEOS_DBUS_SYSTEM_CLOCK_FAKE_SYSTEM_CLOCK_CLIENT_H_ #include <stdint.h> +#include <vector> #include "base/macros.h" #include "base/observer_list.h" @@ -25,6 +26,7 @@ // TestInterface void SetNetworkSynchronized(bool network_synchronized) override; void NotifyObserversSystemClockUpdated() override; + void SetServiceIsAvailable(bool is_available) override; // SystemClockClient overrides void AddObserver(Observer* observer) override; @@ -38,8 +40,11 @@ SystemClockClient::TestInterface* GetTestInterface() override; private: + bool is_available_ = true; bool network_synchronized_ = false; + std::vector<dbus::ObjectProxy::WaitForServiceToBeAvailableCallback> + callbacks_; base::ObserverList<Observer>::Unchecked observers_; DISALLOW_COPY_AND_ASSIGN(FakeSystemClockClient);
diff --git a/chromeos/dbus/system_clock/system_clock_client.h b/chromeos/dbus/system_clock/system_clock_client.h index 019f9f5..691d695 100644 --- a/chromeos/dbus/system_clock/system_clock_client.h +++ b/chromeos/dbus/system_clock/system_clock_client.h
@@ -46,6 +46,11 @@ // Calls SystemClockUpdated for observers. virtual void NotifyObserversSystemClockUpdated() = 0; + + // If |is_available| is false callbacks passed to + // WaitForServiceToBeAvailable will pile up, until |is_available| is set + // back to true. + virtual void SetServiceIsAvailable(bool is_available) = 0; }; // Creates and initializes the global instance. |bus| must not be null.
diff --git a/chromeos/process_proxy/process_output_watcher_unittest.cc b/chromeos/process_proxy/process_output_watcher_unittest.cc index 969cc60..e58c36f 100644 --- a/chromeos/process_proxy/process_output_watcher_unittest.cc +++ b/chromeos/process_proxy/process_output_watcher_unittest.cc
@@ -16,6 +16,7 @@ #include "base/callback.h" #include "base/files/file_util.h" #include "base/location.h" +#include "base/message_loop/message_pump_type.h" #include "base/posix/eintr_wrapper.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -146,7 +147,7 @@ ASSERT_FALSE(output_watch_thread_started_); output_watch_thread_.reset(new base::Thread("ProcessOutpuWatchThread")); output_watch_thread_started_ = output_watch_thread_->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); ASSERT_TRUE(output_watch_thread_started_); int pt_pipe[2];
diff --git a/chromeos/process_proxy/process_proxy_registry.cc b/chromeos/process_proxy/process_proxy_registry.cc index ecfa92b..5d73249 100644 --- a/chromeos/process_proxy/process_proxy_registry.cc +++ b/chromeos/process_proxy/process_proxy_registry.cc
@@ -6,7 +6,7 @@ #include "base/bind.h" #include "base/command_line.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/sequenced_task_runner.h" #include "base/task/lazy_task_runner.h" @@ -185,7 +185,7 @@ // spinning a new thread. watcher_thread_.reset(new base::Thread(kWatcherThreadName)); return watcher_thread_->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); } base::ProcessHandle ProcessProxyRegistry::GetProcessHandleForTesting(
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index 18bc6c1..b7e698f 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -14,12 +14,9 @@ #include "base/i18n/rtl.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" -#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/system/sys_info.h" #include "base/task/post_task.h" #include "base/unguessable_token.h" -#include "build/util/webkit_version.h" #include "chromeos/assistant/internal/internal_constants.h" #include "chromeos/assistant/internal/internal_util.h" #include "chromeos/assistant/internal/proto/google3/assistant/api/client_input/warmer_welcome_input.pb.h" @@ -1159,24 +1156,10 @@ void AssistantManagerServiceImpl::UpdateInternalOptions( assistant_client::AssistantManagerInternal* assistant_manager_internal) { - // Build user agent string. - std::string user_agent; - base::StringAppendF(&user_agent, - "Mozilla/5.0 (X11; CrOS %s %s; %s) " - "AppleWebKit/%d.%d (KHTML, like Gecko)", - base::SysInfo::OperatingSystemArchitecture().c_str(), - base::SysInfo::OperatingSystemVersion().c_str(), - base::SysInfo::GetLsbReleaseBoard().c_str(), - WEBKIT_VERSION_MAJOR, WEBKIT_VERSION_MINOR); - - std::string arc_version = chromeos::version_loader::GetARCVersion(); - if (!arc_version.empty()) - base::StringAppendF(&user_agent, " ARC/%s", arc_version.c_str()); - // Build internal options auto* internal_options = assistant_manager_internal->CreateDefaultInternalOptions(); - SetAssistantOptions(internal_options, user_agent, + SetAssistantOptions(internal_options, service_->assistant_state()->locale().value(), spoken_feedback_enabled_);
diff --git a/chromeos/services/assistant/media_session/assistant_media_session.cc b/chromeos/services/assistant/media_session/assistant_media_session.cc index 90d3977e..8179967 100644 --- a/chromeos/services/assistant/media_session/assistant_media_session.cc +++ b/chromeos/services/assistant/media_session/assistant_media_session.cc
@@ -140,13 +140,12 @@ DCHECK(base::FeatureList::IsEnabled( media_session::features::kMediaSessionService)); - if (audio_focus_remote_.is_bound() && - !audio_focus_remote_.encountered_error()) + if (audio_focus_remote_.is_bound() && audio_focus_remote_.is_connected()) return; audio_focus_remote_.reset(); connector_->Connect(media_session::mojom::kServiceName, - audio_focus_remote_->BindNewPipeAndPassReceiver()); + audio_focus_remote_.BindNewPipeAndPassReceiver()); audio_focus_remote_->SetSourceName(kAudioFocusSourceName); }
diff --git a/chromeos/services/assistant/utils.cc b/chromeos/services/assistant/utils.cc index 9f015102..74123f64 100644 --- a/chromeos/services/assistant/utils.cc +++ b/chromeos/services/assistant/utils.cc
@@ -34,6 +34,10 @@ base::SysInfo::OperatingSystemVersion().c_str(), base::SysInfo::GetLsbReleaseBoard().c_str(), WEBKIT_VERSION_MAJOR, WEBKIT_VERSION_MINOR); + + std::string arc_version = chromeos::version_loader::GetARCVersion(); + if (!arc_version.empty()) + base::StringAppendF(user_agent, " ARC/%s", arc_version.c_str()); } } // namespace
diff --git a/chromeos/services/cros_healthd/OWNERS b/chromeos/services/cros_healthd/OWNERS index fea49f5..d60ebdb 100644 --- a/chromeos/services/cros_healthd/OWNERS +++ b/chromeos/services/cros_healthd/OWNERS
@@ -1,4 +1,3 @@ pmoy@chromium.org -wbbradley@chromium.org # COMPONENT: Enterprise
diff --git a/chromeos/services/cros_healthd/public/cpp/OWNERS b/chromeos/services/cros_healthd/public/cpp/OWNERS index fea49f5..d60ebdb 100644 --- a/chromeos/services/cros_healthd/public/cpp/OWNERS +++ b/chromeos/services/cros_healthd/public/cpp/OWNERS
@@ -1,4 +1,3 @@ pmoy@chromium.org -wbbradley@chromium.org # COMPONENT: Enterprise
diff --git a/chromeos/services/machine_learning/public/cpp/service_connection_unittest.cc b/chromeos/services/machine_learning/public/cpp/service_connection_unittest.cc index 73b059c7..0c383dc 100644 --- a/chromeos/services/machine_learning/public/cpp/service_connection_unittest.cc +++ b/chromeos/services/machine_learning/public/cpp/service_connection_unittest.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/macros.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" @@ -39,7 +40,7 @@ static void SetUpTestCase() { static base::Thread ipc_thread("ipc"); ipc_thread.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); static mojo::core::ScopedIPCSupport ipc_support( ipc_thread.task_runner(), mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);
diff --git a/chromeos/services/network_config/cros_network_config.cc b/chromeos/services/network_config/cros_network_config.cc index 7a880ad..f14c958 100644 --- a/chromeos/services/network_config/cros_network_config.cc +++ b/chromeos/services/network_config/cros_network_config.cc
@@ -108,16 +108,16 @@ : mojom::ConnectionStateType::kNotConnected; } -mojom::VPNType ShillVpnTypeToMojo(const std::string& shill_vpn_type) { - if (shill_vpn_type == shill::kProviderL2tpIpsec) +mojom::VPNType OncVpnTypeToMojo(const std::string& onc_vpn_type) { + if (onc_vpn_type == ::onc::vpn::kTypeL2TP_IPsec) return mojom::VPNType::kL2TPIPsec; - if (shill_vpn_type == shill::kProviderOpenVpn) + if (onc_vpn_type == ::onc::vpn::kOpenVPN) return mojom::VPNType::kOpenVPN; - if (shill_vpn_type == shill::kProviderThirdPartyVpn) + if (onc_vpn_type == ::onc::vpn::kThirdPartyVpn) return mojom::VPNType::kThirdPartyVPN; - if (shill_vpn_type == shill::kProviderArcVpn) + if (onc_vpn_type == ::onc::vpn::kArcVpn) return mojom::VPNType::kArcVPN; - NOTREACHED() << "Unsupported shill VPN type: " << shill_vpn_type; + NOTREACHED() << "Unsupported ONC VPN type: " << onc_vpn_type; return mojom::VPNType::kOpenVPN; } @@ -236,7 +236,8 @@ const NetworkState::VpnProviderInfo* vpn_provider = network->vpn_provider(); if (vpn_provider) { - vpn->type = ShillVpnTypeToMojo(vpn_provider->type); + vpn->type = OncVpnTypeToMojo( + ShillToOnc(vpn_provider->type, onc::kVPNTypeTable)); vpn->provider_id = vpn_provider->id; // TODO(stevenjb): Set the provider name in network state. // vpn->provider_name = vpn_provider->name; @@ -1081,6 +1082,8 @@ switch (type) { case mojom::NetworkType::kCellular: { auto cellular = mojom::ManagedCellularProperties::New(); + cellular->activation_state = network_state->GetMojoActivationState(); + const base::Value* cellular_dict = GetDictionary(properties, ::onc::network_config::kCellular); if (!cellular_dict) { @@ -1093,8 +1096,6 @@ GetManagedApnProperties(cellular_dict, ::onc::cellular::kAPN); cellular->apn_list = GetManagedApnList(cellular_dict->FindKey(::onc::cellular::kAPNList)); - cellular->activation_state = - GetString(cellular_dict, ::onc::cellular::kActivationState); cellular->allow_roaming = GetBoolean(properties, ::onc::cellular::kAllowRoaming); cellular->esn = GetString(cellular_dict, ::onc::cellular::kESN); @@ -1178,13 +1179,17 @@ GetManagedOpenVPNProperties(vpn_dict, ::onc::vpn::kOpenVPN); vpn->third_party_vpn = GetManagedThirdPartyVPNProperties( vpn_dict, ::onc::vpn::kThirdPartyVpn); - vpn->type = GetManagedString(vpn_dict, ::onc::vpn::kType); - CHECK(vpn->type); + mojom::ManagedStringPtr managed_type = + GetManagedString(vpn_dict, ::onc::vpn::kType); + CHECK(managed_type); + vpn->type = OncVpnTypeToMojo(managed_type->active_value); result->vpn = std::move(vpn); break; } case mojom::NetworkType::kWiFi: { auto wifi = mojom::ManagedWiFiProperties::New(); + wifi->security = network_state->GetMojoSecurity(); + const base::Value* wifi_dict = GetDictionary(properties, ::onc::network_config::kWiFi); if (!wifi_dict) { @@ -1208,8 +1213,6 @@ GetManagedInt32(wifi_dict, ::onc::wifi::kRoamThreshold); wifi->ssid = GetManagedString(wifi_dict, ::onc::wifi::kSSID); CHECK(wifi->ssid); - wifi->security = GetManagedString(wifi_dict, ::onc::wifi::kSecurity); - CHECK(wifi->security); wifi->signal_strength = GetInt32(wifi_dict, ::onc::wifi::kSignalStrength); wifi->tethering_state = GetString(wifi_dict, ::onc::wifi::kTetheringState);
diff --git a/chromeos/services/network_config/cros_network_config_unittest.cc b/chromeos/services/network_config/cros_network_config_unittest.cc index 83aa2b2..746bfea 100644 --- a/chromeos/services/network_config/cros_network_config_unittest.cc +++ b/chromeos/services/network_config/cros_network_config_unittest.cc
@@ -82,7 +82,7 @@ R"({"GUID": "wifi2_guid", "Type": "WiFi", "Name": "wifi2", "Priority": 0, "WiFi": { "Passphrase": "fake", "SSID": "%s", "HexSSID": "%s", - "Security": "WPA-PSK"}})", + "Security": "WPA-PSK", "AutoConnect": true}})", user_policy_ssid.c_str(), base::HexEncode(user_policy_ssid.c_str(), user_policy_ssid.size()) .c_str()))); @@ -111,11 +111,12 @@ kCellularDevicePath, shill::kSIMLockStatusProperty, sim_value, /*notify_changed=*/false); + // Note: These are Shill dictionaries, not ONC. helper().ConfigureService( R"({"GUID": "eth_guid", "Type": "ethernet", "State": "online"})"); wifi1_path_ = helper().ConfigureService( R"({"GUID": "wifi1_guid", "Type": "wifi", "State": "ready", - "Strength": 50})"); + "Strength": 50, "AutoConnect": true})"); helper().ConfigureService( R"({"GUID": "wifi2_guid", "Type": "wifi", "SSID": "wifi2", "State": "idle", "SecurityClass": "psk", "Strength": 100, @@ -431,7 +432,7 @@ EXPECT_EQ(mojom::ConnectionStateType::kNotConnected, properties->connection_state); ASSERT_TRUE(properties->wifi); - EXPECT_EQ(::onc::wifi::kWPA_PSK, properties->wifi->security->active_value); + EXPECT_EQ(mojom::SecurityType::kWpaPsk, properties->wifi->security); EXPECT_EQ(100, properties->wifi->signal_strength); properties = GetManagedProperties("cellular_guid"); @@ -443,7 +444,7 @@ ASSERT_TRUE(properties->cellular); EXPECT_EQ(0, properties->cellular->signal_strength); EXPECT_EQ("LTE", properties->cellular->network_technology); - EXPECT_EQ(::onc::cellular::kActivated, + EXPECT_EQ(mojom::ActivationStateType::kActivated, properties->cellular->activation_state); properties = GetManagedProperties("vpn_guid"); @@ -453,14 +454,28 @@ EXPECT_EQ(mojom::ConnectionStateType::kConnecting, properties->connection_state); ASSERT_TRUE(properties->vpn); - EXPECT_EQ(::onc::vpn::kTypeL2TP_IPsec, properties->vpn->type->active_value); + EXPECT_EQ(mojom::VPNType::kL2TPIPsec, properties->vpn->type); } // Test managed property policy values. TEST_F(CrosNetworkConfigTest, GetManagedPropertiesPolicy) { - mojom::ManagedPropertiesPtr properties = GetManagedProperties("wifi2_guid"); + mojom::ManagedPropertiesPtr properties = GetManagedProperties("wifi1_guid"); + ASSERT_TRUE(properties); + ASSERT_EQ("wifi1_guid", properties->guid); + ASSERT_TRUE(properties->wifi); + ASSERT_TRUE(properties->wifi->auto_connect); + EXPECT_TRUE(properties->wifi->auto_connect->active_value); + EXPECT_EQ(mojom::PolicySource::kNone, + properties->wifi->auto_connect->policy_source); + + properties = GetManagedProperties("wifi2_guid"); ASSERT_TRUE(properties); ASSERT_EQ("wifi2_guid", properties->guid); + ASSERT_TRUE(properties->wifi->auto_connect); + EXPECT_TRUE(properties->wifi->auto_connect->active_value); + EXPECT_EQ(mojom::PolicySource::kUserPolicyEnforced, + properties->wifi->auto_connect->policy_source); + EXPECT_TRUE(properties->wifi->auto_connect->policy_value); ASSERT_TRUE(properties->name); EXPECT_EQ("wifi2", properties->name->active_value); EXPECT_EQ(mojom::PolicySource::kUserPolicyEnforced, @@ -471,21 +486,6 @@ EXPECT_EQ(mojom::PolicySource::kUserPolicyEnforced, properties->priority->policy_source); EXPECT_EQ(0, properties->priority->policy_value); - - ASSERT_EQ(mojom::NetworkType::kWiFi, properties->type); - ASSERT_TRUE(properties->wifi); - EXPECT_EQ(::onc::wifi::kWPA_PSK, properties->wifi->security->active_value); - EXPECT_EQ(mojom::PolicySource::kUserPolicyEnforced, - properties->wifi->security->policy_source); - EXPECT_EQ(::onc::wifi::kWPA_PSK, *properties->wifi->security->policy_value); - - properties = GetManagedProperties("vpn_guid"); - ASSERT_TRUE(properties); - ASSERT_EQ("vpn_guid", properties->guid); - ASSERT_EQ(mojom::NetworkType::kVPN, properties->type); - ASSERT_TRUE(properties->vpn); - EXPECT_EQ(::onc::vpn::kTypeL2TP_IPsec, properties->vpn->type->active_value); - EXPECT_EQ(mojom::PolicySource::kNone, properties->vpn->type->policy_source); } TEST_F(CrosNetworkConfigTest, SetNetworkTypeEnabledState) {
diff --git a/chromeos/services/network_config/public/mojom/cros_network_config.mojom b/chromeos/services/network_config/public/mojom/cros_network_config.mojom index 5baf928..30254cc 100644 --- a/chromeos/services/network_config/public/mojom/cros_network_config.mojom +++ b/chromeos/services/network_config/public/mojom/cros_network_config.mojom
@@ -510,7 +510,7 @@ ManagedBoolean? auto_connect; ManagedApnProperties? apn; ManagedApnList? apn_list; - string? activation_state; + ActivationStateType activation_state; bool allow_roaming = false; string? esn; string? family; @@ -547,7 +547,7 @@ ManagedL2TPProperties? l2tp; ManagedOpenVPNProperties? open_vpn; ManagedThirdPartyVPNProperties? third_party_vpn; - ManagedString type; + VPNType type; }; struct ManagedWiFiProperties { @@ -562,7 +562,7 @@ ManagedBoolean? hidden_ssid; ManagedInt32? roam_threshold; ManagedString ssid; - ManagedString security; + SecurityType security; int32 signal_strength = 0; string? tethering_state; };
diff --git a/components/autofill/core/browser/autofill_and_password_manager_internals/autofill_and_password_manager_internals.js b/components/autofill/core/browser/autofill_and_password_manager_internals/autofill_and_password_manager_internals.js index 1ec9d0c..91fcdf8 100644 --- a/components/autofill/core/browser/autofill_and_password_manager_internals/autofill_and_password_manager_internals.js +++ b/components/autofill/core/browser/autofill_and_password_manager_internals/autofill_and_password_manager_internals.js
@@ -47,7 +47,15 @@ return; } logDiv.appendChild(document.createElement('hr')); - logDiv.appendChild(nodeToDomNode(node)); + if (node.type === 'fragment') { + if ('children' in node) { + node.children.forEach((child) => { + logDiv.appendChild(nodeToDomNode(child)); + }); + } + } else { + logDiv.appendChild(nodeToDomNode(node)); + } } function setUpAutofillInternals() {
diff --git a/components/autofill/core/browser/logging/log_buffer.cc b/components/autofill/core/browser/logging/log_buffer.cc index c8a8d1d..a9fe4db 100644 --- a/components/autofill/core/browser/logging/log_buffer.cc +++ b/components/autofill/core/browser/logging/log_buffer.cc
@@ -13,11 +13,6 @@ namespace { -// The LogBuffer creates a tree that will be rendered as HTML code. This tree -// supports two node types, "element" (representing a DOM Element) and "text" -// (representing a text node in the DOM). This function is used to check that -// attributes and children are only added to "element" nodes but not to "text" -// nodes. bool IsElement(const base::Value& value) { const std::string* type = value.FindStringKey("type"); return type && *type == "element"; @@ -28,6 +23,11 @@ return type && *type == "text"; } +bool IsFragment(const base::Value& value) { + const std::string* type = value.FindStringKey("type"); + return type && *type == "fragment"; +} + void AppendChildToLastNode(std::vector<base::Value>* buffer, base::Value&& new_child) { if (buffer->empty()) { @@ -36,7 +36,8 @@ } base::Value& parent = buffer->back(); - DCHECK(IsElement(parent)); + // Elements and Fragments can have children, but TextNodes cannot. + DCHECK(!IsTextNode(parent)); if (auto* children = parent.FindListKey("children")) { children->GetList().push_back(std::move(new_child)); @@ -76,21 +77,41 @@ return true; } +base::Value CreateEmptyFragment() { + base::Value::DictStorage storage; + storage.try_emplace("type", std::make_unique<base::Value>("fragment")); + return base::Value(storage); +} + } // namespace -LogBuffer::LogBuffer() = default; +LogBuffer::LogBuffer() { + buffer_.push_back(CreateEmptyFragment()); +} + LogBuffer::LogBuffer(LogBuffer&& other) noexcept = default; LogBuffer::~LogBuffer() = default; base::Value LogBuffer::RetrieveResult() { - if (buffer_.empty()) - return base::Value(); + // The buffer should always start with a fragment. + DCHECK(buffer_.size() >= 1); // Close not-yet-closed tags. while (buffer_.size() > 1) *this << CTag{}; - return std::exchange(buffer_.back(), base::Value()); + auto* children = buffer_[0].FindListKey("children"); + if (!children || children->GetList().empty()) + return base::Value(); + + // If the fragment has a single child, return that directly. + if (children->GetList().size() == 1) { + base::Value result = std::move(children->GetList().back()); + children->GetList().pop_back(); + return result; + } + + return std::exchange(buffer_.back(), CreateEmptyFragment()); } LogBuffer& operator<<(LogBuffer& buf, Tag&& tag) { @@ -108,8 +129,7 @@ LogBuffer& operator<<(LogBuffer& buf, CTag&& tag) { if (!buf.active()) return buf; - // Don't close the very first opened tag. It stays and gets returned in the - // end. + // Don't close the fragment. It stays and gets returned in the end. if (buf.buffer_.size() <= 1) return buf; @@ -174,6 +194,15 @@ base::Value node_to_add(buffer.RetrieveResult()); if (node_to_add.is_none()) return buf; + + if (IsFragment(node_to_add)) { + auto* children = node_to_add.FindListKey("children"); + if (!children) + return buf; + for (auto& child : children->GetList()) + AppendChildToLastNode(&buf.buffer_, std::exchange(child, base::Value())); + return buf; + } AppendChildToLastNode(&buf.buffer_, std::move(node_to_add)); return buf; }
diff --git a/components/autofill/core/browser/logging/log_buffer.h b/components/autofill/core/browser/logging/log_buffer.h index 016a638..ff6f448 100644 --- a/components/autofill/core/browser/logging/log_buffer.h +++ b/components/autofill/core/browser/logging/log_buffer.h
@@ -103,13 +103,14 @@ // The stack of values being constructed. Each item is a dictionary with the // following attributes: - // - type: 'element' | 'text' + // - type: 'element' | 'fragment' | 'text' // - value: name of tag | text content // - children (opt): list of child nodes // - attributes (opt): dictionary of name/value pairs // The |buffer_| serves as a stack where the last element is being // constructed. Once it is read (i.e. closed via a CTag), it is popped from // the stack and attached as a child of the previously second last element. + // Only the first element of buffer_ is a 'fragment' and it is never closed. std::vector<base::Value> buffer_; bool active_ = true;
diff --git a/components/autofill/core/browser/logging/log_buffer_unittest.cc b/components/autofill/core/browser/logging/log_buffer_unittest.cc index ba4946fc..1901445 100644 --- a/components/autofill/core/browser/logging/log_buffer_unittest.cc +++ b/components/autofill/core/browser/logging/log_buffer_unittest.cc
@@ -188,4 +188,38 @@ EXPECT_EQ(expected.RetrieveResult(), actual.RetrieveResult()); } +TEST(LogBuffer, CreateFragment) { + LogBuffer buffer; + buffer << "foo" << Br{} << "bar"; + std::string json; + EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json)); + EXPECT_EQ(R"({"children":[{"type":"text","value":"foo"},)" + R"({"type":"element","value":"br"},{"type":"text","value":"bar"}],)" + R"("type":"fragment"})", + json); +} + +TEST(LogBuffer, AppendFragmentByInlining) { + LogBuffer tmp_buffer; + tmp_buffer << "foo" << Br{} << "bar"; + LogBuffer buffer; + buffer << std::move(tmp_buffer); + std::string json; + EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json)); + EXPECT_EQ(R"({"children":[{"type":"text","value":"foo"},)" + R"({"type":"element","value":"br"},{"type":"text","value":"bar"}],)" + R"("type":"fragment"})", + json); +} + +TEST(LogBuffer, AppendSingleElementBuffer) { + LogBuffer tmp_buffer; + tmp_buffer << "foo"; + LogBuffer buffer; + buffer << std::move(tmp_buffer); + std::string json; + EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json)); + EXPECT_EQ(R"({"type":"text","value":"foo"})", json); +} + } // namespace autofill
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc index 2ccc969..35a9e06 100644 --- a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc +++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc
@@ -268,9 +268,10 @@ autofill_client_->GetIdentityManager()->GetPrimaryAccountInfo().email; base::Optional<AccountInfo> account_info = - autofill_client_->GetIdentityManager()->FindExtendedAccountInfoForAccount( - autofill_client_->GetPersonalDataManager() - ->GetAccountInfoForPaymentsServer()); + autofill_client_->GetIdentityManager() + ->FindExtendedAccountInfoForAccountWithRefreshToken( + autofill_client_->GetPersonalDataManager() + ->GetAccountInfoForPaymentsServer()); if (account_info.has_value()) { options->user.display_name = account_info.value().given_name; options->user.icon_url = GURL(account_info.value().picture_url);
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn index 2b8e35338..f14503f 100644 --- a/components/autofill_assistant/browser/BUILD.gn +++ b/components/autofill_assistant/browser/BUILD.gn
@@ -24,6 +24,7 @@ "metrics.h", "overlay_state.h", "payment_request.h", + "viewport_mode.h", ] } @@ -77,6 +78,8 @@ "actions/unsupported_action.h", "actions/upload_dom_action.cc", "actions/upload_dom_action.h", + "actions/wait_for_document_action.cc", + "actions/wait_for_document_action.h", "actions/wait_for_dom_action.cc", "actions/wait_for_dom_action.h", "actions/wait_for_navigation_action.cc", @@ -145,6 +148,7 @@ "ui_delegate.h", "user_action.cc", "user_action.h", + "viewport_mode.h", "web_controller.cc", "web_controller.h", ] @@ -175,6 +179,7 @@ "actions/mock_action_delegate.h", "actions/popup_message_action_unittest.cc", "actions/prompt_action_unittest.cc", + "actions/wait_for_document_action_unittest.cc", "actions/wait_for_dom_action_unittest.cc", "batch_element_checker_unittest.cc", "controller_unittest.cc",
diff --git a/components/autofill_assistant/browser/actions/action.cc b/components/autofill_assistant/browser/actions/action.cc index d1caf2bb..8f3c3a6 100644 --- a/components/autofill_assistant/browser/actions/action.cc +++ b/components/autofill_assistant/browser/actions/action.cc
@@ -125,6 +125,9 @@ case ActionProto::ActionInfoCase::kPopupMessage: out << "PopupMessage"; break; + case ActionProto::ActionInfoCase::kWaitForDocument: + out << "WaitForDocument"; + break; case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET: out << "ACTION_INFO_NOT_SET"; break;
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h index 0001d5b..e532ac11 100644 --- a/components/autofill_assistant/browser/actions/action_delegate.h +++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -16,6 +16,7 @@ #include "components/autofill_assistant/browser/info_box.h" #include "components/autofill_assistant/browser/selector.h" #include "components/autofill_assistant/browser/top_padding.h" +#include "components/autofill_assistant/browser/viewport_mode.h" #include "third_party/blink/public/mojom/payments/payment_request.mojom.h" #include "third_party/icu/source/common/unicode/umachine.h" @@ -217,6 +218,22 @@ virtual bool WaitForNavigation( base::OnceCallback<void(bool)> on_navigation_done) = 0; + // Waits for the value of Document.readyState to reach at least + // |min_ready_state| in |optional_frame| or, if it is empty, in the main + // document. + virtual void WaitForDocumentReadyState( + const Selector& optional_frame, + DocumentReadyState min_ready_state, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback) = 0; + + // Gets the value of Document.readyState in |optional_frame| or, if it is + // empty, in the main document. + virtual void GetDocumentReadyState( + const Selector& optional_frame, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback) = 0; + // Load |url| in the current tab. Returns immediately, before the new page has // been loaded. virtual void LoadURL(const GURL& url) = 0; @@ -256,11 +273,11 @@ // Shows the progress bar when |visible| is true. Hides it when false. virtual void SetProgressVisible(bool visible) = 0; - // Set whether the viewport should be resized. - virtual void SetResizeViewport(bool resize_viewport) = 0; + // Set the viewport mode. + virtual void SetViewportMode(ViewportMode mode) = 0; - // Checks whether the viewport should be resized. - virtual bool GetResizeViewport() = 0; + // Get the current viewport mode. + virtual ViewportMode GetViewportMode() = 0; // Set the peek mode. virtual void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) = 0;
diff --git a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action.cc b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action.cc index b72d2fb..cc573369 100644 --- a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action.cc +++ b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action.cc
@@ -8,6 +8,7 @@ #include "base/callback.h" #include "components/autofill_assistant/browser/actions/action_delegate.h" #include "components/autofill_assistant/browser/client_status.h" +#include "components/autofill_assistant/browser/viewport_mode.h" namespace autofill_assistant { @@ -26,12 +27,15 @@ // be visible to Javascript before moving on to another action. To do that, // this action registers a callback *before* making any change and waits for // a 'resize' event in the Javascript side. - bool resize = delegate_->GetResizeViewport(); + ViewportMode mode = delegate_->GetViewportMode(); bool expect_resize = - (!resize && - proto.viewport_resizing() == ConfigureBottomSheetProto::RESIZE) || - (resize && + (mode != ViewportMode::RESIZE_LAYOUT_VIEWPORT && + proto.viewport_resizing() == + ConfigureBottomSheetProto::RESIZE_LAYOUT_VIEWPORT) || + (mode == ViewportMode::RESIZE_LAYOUT_VIEWPORT && (proto.viewport_resizing() == ConfigureBottomSheetProto::NO_RESIZE || + proto.viewport_resizing() == + ConfigureBottomSheetProto::RESIZE_VISUAL_VIEWPORT || (proto.peek_mode() != ConfigureBottomSheetProto::UNDEFINED_PEEK_MODE && proto.peek_mode() != delegate_->GetPeekMode()))); @@ -49,11 +53,18 @@ } } - if (proto.viewport_resizing() == ConfigureBottomSheetProto::RESIZE) { - delegate_->SetResizeViewport(true); - } else if (proto.viewport_resizing() == - ConfigureBottomSheetProto::NO_RESIZE) { - delegate_->SetResizeViewport(false); + switch (proto.viewport_resizing()) { + case ConfigureBottomSheetProto::NO_CHANGE: + break; + case ConfigureBottomSheetProto::NO_RESIZE: + delegate_->SetViewportMode(ViewportMode::NO_RESIZE); + break; + case ConfigureBottomSheetProto::RESIZE_LAYOUT_VIEWPORT: + delegate_->SetViewportMode(ViewportMode::RESIZE_LAYOUT_VIEWPORT); + break; + case ConfigureBottomSheetProto::RESIZE_VISUAL_VIEWPORT: + delegate_->SetViewportMode(ViewportMode::RESIZE_VISUAL_VIEWPORT); + break; } if (proto.peek_mode() != ConfigureBottomSheetProto::UNDEFINED_PEEK_MODE) {
diff --git a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc index 5d7d22e..d33e409 100644 --- a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc
@@ -32,11 +32,11 @@ : task_env_(base::test::ScopedTaskEnvironment::TimeSource::MOCK_TIME) {} void SetUp() override { - ON_CALL(mock_action_delegate_, GetResizeViewport()) - .WillByDefault(Invoke([this]() { return resize_viewport_; })); - ON_CALL(mock_action_delegate_, SetResizeViewport(_)) + ON_CALL(mock_action_delegate_, GetViewportMode()) + .WillByDefault(Invoke([this]() { return viewport_mode_; })); + ON_CALL(mock_action_delegate_, SetViewportMode(_)) .WillByDefault( - Invoke([this](bool value) { resize_viewport_ = value; })); + Invoke([this](ViewportMode value) { viewport_mode_ = value; })); ON_CALL(mock_action_delegate_, GetPeekMode()) .WillByDefault(Invoke([this]() { return peek_mode_; })); ON_CALL(mock_action_delegate_, SetPeekMode(_)) @@ -89,7 +89,7 @@ MockActionDelegate mock_action_delegate_; MockWebController mock_web_controller_; ConfigureBottomSheetProto proto_; - bool resize_viewport_ = false; + ViewportMode viewport_mode_ = ViewportMode::NO_RESIZE; base::OnceCallback<void(const ClientStatus&)> on_resize_cb_; ConfigureBottomSheetProto::PeekMode peek_mode_ = ConfigureBottomSheetProto::HANDLE; @@ -101,7 +101,7 @@ Run(); EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); - EXPECT_FALSE(resize_viewport_); + EXPECT_EQ(ViewportMode::NO_RESIZE, viewport_mode_); EXPECT_EQ(ConfigureBottomSheetProto::HANDLE, peek_mode_); } @@ -110,35 +110,48 @@ Run(); EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); - EXPECT_FALSE(resize_viewport_); + EXPECT_EQ(ViewportMode::NO_RESIZE, viewport_mode_); EXPECT_EQ(ConfigureBottomSheetProto::HANDLE_HEADER, peek_mode_); } TEST_F(ConfigureBottomSheetActionTest, EnableResize) { - proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + proto_.set_viewport_resizing( + ConfigureBottomSheetProto::RESIZE_LAYOUT_VIEWPORT); Run(); EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); - EXPECT_TRUE(resize_viewport_); + EXPECT_EQ(ViewportMode::RESIZE_LAYOUT_VIEWPORT, viewport_mode_); + EXPECT_EQ(ConfigureBottomSheetProto::HANDLE, peek_mode_); +} + +TEST_F(ConfigureBottomSheetActionTest, EnableVisualViewportResize) { + proto_.set_viewport_resizing( + ConfigureBottomSheetProto::RESIZE_VISUAL_VIEWPORT); + Run(); + + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); + EXPECT_EQ(ViewportMode::RESIZE_VISUAL_VIEWPORT, viewport_mode_); EXPECT_EQ(ConfigureBottomSheetProto::HANDLE, peek_mode_); } TEST_F(ConfigureBottomSheetActionTest, EnableResizeWithPeekMode) { - proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + proto_.set_viewport_resizing( + ConfigureBottomSheetProto::RESIZE_LAYOUT_VIEWPORT); proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE_HEADER); Run(); EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); - EXPECT_TRUE(resize_viewport_); + EXPECT_EQ(ViewportMode::RESIZE_LAYOUT_VIEWPORT, viewport_mode_); EXPECT_EQ(ConfigureBottomSheetProto::HANDLE_HEADER, peek_mode_); } TEST_F(ConfigureBottomSheetActionTest, WaitAfterSettingResize) { - proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + proto_.set_viewport_resizing( + ConfigureBottomSheetProto::RESIZE_LAYOUT_VIEWPORT); RunWithTimeout(); - EXPECT_TRUE(resize_viewport_); + EXPECT_EQ(ViewportMode::RESIZE_LAYOUT_VIEWPORT, viewport_mode_); ASSERT_TRUE(on_resize_cb_); std::move(on_resize_cb_).Run(OkClientStatus()); @@ -146,7 +159,8 @@ } TEST_F(ConfigureBottomSheetActionTest, WaitFailsAfterSettingResize) { - proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + proto_.set_viewport_resizing( + ConfigureBottomSheetProto::RESIZE_LAYOUT_VIEWPORT); RunWithTimeout(); @@ -158,7 +172,8 @@ } TEST_F(ConfigureBottomSheetActionTest, WaitTimesOut) { - proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + proto_.set_viewport_resizing( + ConfigureBottomSheetProto::RESIZE_LAYOUT_VIEWPORT); RunWithTimeout(); @@ -171,7 +186,8 @@ } TEST_F(ConfigureBottomSheetActionTest, TimesOutAfterWindowResized) { - proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + proto_.set_viewport_resizing( + ConfigureBottomSheetProto::RESIZE_LAYOUT_VIEWPORT); RunWithTimeout(); @@ -181,11 +197,12 @@ ForceTimeout(); EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); - EXPECT_TRUE(resize_viewport_); + EXPECT_EQ(ViewportMode::RESIZE_LAYOUT_VIEWPORT, viewport_mode_); } TEST_F(ConfigureBottomSheetActionTest, WindowResizedAfterTimeout) { - proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + proto_.set_viewport_resizing( + ConfigureBottomSheetProto::RESIZE_LAYOUT_VIEWPORT); RunWithTimeout(); @@ -197,7 +214,7 @@ } TEST_F(ConfigureBottomSheetActionTest, WaitAfterUnsettingResize) { - resize_viewport_ = true; + viewport_mode_ = ViewportMode::RESIZE_LAYOUT_VIEWPORT; proto_.set_viewport_resizing(ConfigureBottomSheetProto::NO_RESIZE); RunWithTimeout(); @@ -206,7 +223,7 @@ } TEST_F(ConfigureBottomSheetActionTest, WaitAfterChangingPeekModeInResizeMode) { - resize_viewport_ = true; + viewport_mode_ = ViewportMode::RESIZE_LAYOUT_VIEWPORT; proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE_HEADER); RunWithTimeout(); @@ -224,7 +241,7 @@ } TEST_F(ConfigureBottomSheetActionTest, DontWaitIfPeekModeNotChanged) { - resize_viewport_ = true; + viewport_mode_ = ViewportMode::RESIZE_LAYOUT_VIEWPORT; proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE); RunWithTimeout(); @@ -233,13 +250,53 @@ } TEST_F(ConfigureBottomSheetActionTest, DontWaitIfResizeModeNotChanged) { - resize_viewport_ = true; - proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + viewport_mode_ = ViewportMode::RESIZE_LAYOUT_VIEWPORT; + proto_.set_viewport_resizing( + ConfigureBottomSheetProto::RESIZE_LAYOUT_VIEWPORT); RunWithTimeout(); ASSERT_FALSE(on_resize_cb_); } +TEST_F(ConfigureBottomSheetActionTest, DontWaitIfResizeVisualViewport) { + proto_.set_viewport_resizing( + ConfigureBottomSheetProto::RESIZE_VISUAL_VIEWPORT); + + RunWithTimeout(); + + ASSERT_FALSE(on_resize_cb_); +} + +TEST_F(ConfigureBottomSheetActionTest, + DontWaitIfDisablingResizeVisualViewport) { + viewport_mode_ = ViewportMode::RESIZE_VISUAL_VIEWPORT; + proto_.set_viewport_resizing(ConfigureBottomSheetProto::NO_RESIZE); + + RunWithTimeout(); + + ASSERT_FALSE(on_resize_cb_); +} + +TEST_F(ConfigureBottomSheetActionTest, WaitIfResizeVisualAfterLayoutViewport) { + viewport_mode_ = ViewportMode::RESIZE_LAYOUT_VIEWPORT; + proto_.set_viewport_resizing( + ConfigureBottomSheetProto::RESIZE_VISUAL_VIEWPORT); + + RunWithTimeout(); + + ASSERT_TRUE(on_resize_cb_); +} + +TEST_F(ConfigureBottomSheetActionTest, WaitIfResizeLayoutAfterVisualViewport) { + viewport_mode_ = ViewportMode::RESIZE_VISUAL_VIEWPORT; + proto_.set_viewport_resizing( + ConfigureBottomSheetProto::RESIZE_LAYOUT_VIEWPORT); + + RunWithTimeout(); + + ASSERT_TRUE(on_resize_cb_); +} + } // namespace } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h index 04225f2..bb4c9d94c 100644 --- a/components/autofill_assistant/browser/actions/mock_action_delegate.h +++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -168,8 +168,8 @@ MOCK_METHOD1(SetProgressVisible, void(bool visible)); MOCK_METHOD1(SetUserActions, void(std::unique_ptr<std::vector<UserAction>> user_action)); - MOCK_METHOD1(SetResizeViewport, void(bool resize_viewport)); - MOCK_METHOD0(GetResizeViewport, bool()); + MOCK_METHOD1(SetViewportMode, void(ViewportMode mode)); + MOCK_METHOD0(GetViewportMode, ViewportMode()); MOCK_METHOD1(SetPeekMode, void(ConfigureBottomSheetProto::PeekMode peek_mode)); MOCK_METHOD0(GetPeekMode, ConfigureBottomSheetProto::PeekMode()); @@ -179,13 +179,39 @@ base::RepeatingCallback<void(const FormProto::Result*)> callback)); void WaitForWindowHeightChange( - base::OnceCallback<void(const ClientStatus&)> callback) { + base::OnceCallback<void(const ClientStatus&)> callback) override { OnWaitForWindowHeightChange(callback); } MOCK_METHOD1(OnWaitForWindowHeightChange, void(base::OnceCallback<void(const ClientStatus&)>& callback)); + MOCK_METHOD2( + OnGetDocumentReadyState, + void(const Selector&, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)>&)); + + void GetDocumentReadyState( + const Selector& frame, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback) override { + OnGetDocumentReadyState(frame, callback); + } + + MOCK_METHOD3( + OnWaitForDocumentReadyState, + void(const Selector&, + DocumentReadyState min_ready_state, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)>&)); + + void WaitForDocumentReadyState( + const Selector& frame, + DocumentReadyState min_ready_state, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback) override { + OnWaitForDocumentReadyState(frame, min_ready_state, callback); + } + MOCK_METHOD0(RequireUI, void()); const ClientSettings& GetSettings() override { return client_settings_; }
diff --git a/components/autofill_assistant/browser/actions/navigate_action.cc b/components/autofill_assistant/browser/actions/navigate_action.cc index e713e36..684c694d 100644 --- a/components/autofill_assistant/browser/actions/navigate_action.cc +++ b/components/autofill_assistant/browser/actions/navigate_action.cc
@@ -9,6 +9,7 @@ #include "base/callback.h" #include "components/autofill_assistant/browser/actions/action_delegate.h" +#include "content/public/browser/web_contents.h" #include "url/gurl.h" namespace autofill_assistant { @@ -27,9 +28,31 @@ // without having to add an expect_navigation first. delegate_->ExpectNavigation(); - GURL url(proto_.navigate().url()); - delegate_->LoadURL(url); - UpdateProcessedAction(ACTION_APPLIED); + auto& proto = proto_.navigate(); + if (!proto.url().empty()) { + GURL url(proto_.navigate().url()); + delegate_->LoadURL(url); + UpdateProcessedAction(ACTION_APPLIED); + } else if (proto.go_backward()) { + auto& controller = delegate_->GetWebContents()->GetController(); + if (controller.CanGoBack()) { + controller.GoBack(); + UpdateProcessedAction(ACTION_APPLIED); + } else { + UpdateProcessedAction(PRECONDITION_FAILED); + } + } else if (proto.go_forward()) { + auto& controller = delegate_->GetWebContents()->GetController(); + if (controller.CanGoForward()) { + controller.GoForward(); + UpdateProcessedAction(ACTION_APPLIED); + } else { + UpdateProcessedAction(PRECONDITION_FAILED); + } + } else { + UpdateProcessedAction(UNSUPPORTED); + } + std::move(callback).Run(std::move(processed_action_proto_)); }
diff --git a/components/autofill_assistant/browser/actions/wait_for_document_action.cc b/components/autofill_assistant/browser/actions/wait_for_document_action.cc new file mode 100644 index 0000000..384aa92 --- /dev/null +++ b/components/autofill_assistant/browser/actions/wait_for_document_action.cc
@@ -0,0 +1,115 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill_assistant/browser/actions/wait_for_document_action.h" + +#include "components/autofill_assistant/browser/actions/action_delegate.h" +#include "components/autofill_assistant/browser/client_status.h" + +namespace autofill_assistant { + +WaitForDocumentAction::WaitForDocumentAction(ActionDelegate* delegate, + const ActionProto& proto) + : Action(delegate, proto) { + DCHECK(proto.has_wait_for_document()); +} + +WaitForDocumentAction::~WaitForDocumentAction() {} + +void WaitForDocumentAction::InternalProcessAction( + ProcessActionCallback callback) { + callback_ = std::move(callback); + + Selector selector(proto_.wait_for_document().frame()); + if (selector.empty()) { + // No element to wait for. + OnShortWaitForElement(/* element_found= */ true); + return; + } + delegate_->ShortWaitForElement( + selector, base::BindOnce(&WaitForDocumentAction::OnShortWaitForElement, + weak_ptr_factory_.GetWeakPtr())); +} + +void WaitForDocumentAction::OnShortWaitForElement(bool element_found) { + if (!element_found) { + SendResult(ClientStatus(ELEMENT_RESOLUTION_FAILED), + DOCUMENT_UNKNOWN_READY_STATE); + return; + } + delegate_->GetDocumentReadyState( + Selector(proto_.wait_for_document().frame()), + base::BindOnce(&WaitForDocumentAction::OnGetStartState, + weak_ptr_factory_.GetWeakPtr())); +} + +void WaitForDocumentAction::OnGetStartState(const ClientStatus& status, + DocumentReadyState start_state) { + if (!status.ok()) { + SendResult(status, DOCUMENT_UNKNOWN_READY_STATE); + return; + } + + processed_action_proto_->mutable_wait_for_document_result() + ->set_start_ready_state(start_state); + + if (start_state >= proto_.wait_for_document().min_ready_state()) { + SendResult(OkClientStatus(), start_state); + return; + } + + base::TimeDelta timeout = base::TimeDelta::FromMilliseconds( + proto_.wait_for_document().timeout_ms()); + if (timeout.is_zero()) { + SendResult(ClientStatus(TIMED_OUT), start_state); + return; + } + + timer_.Start(FROM_HERE, timeout, + base::BindOnce(&WaitForDocumentAction::OnTimeout, + weak_ptr_factory_.GetWeakPtr())); + delegate_->WaitForDocumentReadyState( + Selector(proto_.wait_for_document().frame()), + proto_.wait_for_document().min_ready_state(), + base::BindOnce(&WaitForDocumentAction::OnWaitForStartState, + weak_ptr_factory_.GetWeakPtr())); +} + +void WaitForDocumentAction::OnWaitForStartState( + const ClientStatus& status, + DocumentReadyState current_state) { + SendResult(status, current_state); +} + +void WaitForDocumentAction::OnTimeout() { + // We've already returned successfully. + if (!callback_) + return; + + delegate_->GetDocumentReadyState( + Selector(proto_.wait_for_document().frame()), + base::BindOnce(&WaitForDocumentAction::OnTimeoutInState, + weak_ptr_factory_.GetWeakPtr())); +} + +void WaitForDocumentAction::OnTimeoutInState(const ClientStatus& status, + DocumentReadyState end_state) { + DVLOG_IF(1, !status.ok()) + << __func__ << ": cannot report end_state because of " << status; + SendResult(ClientStatus(TIMED_OUT), end_state); +} + +void WaitForDocumentAction::SendResult(const ClientStatus& status, + DocumentReadyState end_state) { + // Only send a result for the first of OnTimeout or OnSuccess that finishes. + if (!callback_) + return; + + processed_action_proto_->mutable_wait_for_document_result() + ->set_end_ready_state(end_state); + UpdateProcessedAction(status); + std::move(callback_).Run(std::move(processed_action_proto_)); +} + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/wait_for_document_action.h b/components/autofill_assistant/browser/actions/wait_for_document_action.h new file mode 100644 index 0000000..1667cbe --- /dev/null +++ b/components/autofill_assistant/browser/actions/wait_for_document_action.h
@@ -0,0 +1,45 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_WAIT_FOR_DOCUMENT_ACTION_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_WAIT_FOR_DOCUMENT_ACTION_H_ + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" +#include "components/autofill_assistant/browser/actions/action.h" + +namespace autofill_assistant { + +class WaitForDocumentAction : public Action { + public: + explicit WaitForDocumentAction(ActionDelegate* delegate, + const ActionProto& proto); + ~WaitForDocumentAction() override; + + private: + // Overrides Action: + void InternalProcessAction(ProcessActionCallback callback) override; + + void OnShortWaitForElement(bool element_found); + + void OnGetStartState(const ClientStatus& status, + DocumentReadyState start_state); + void OnWaitForStartState(const ClientStatus& status, + DocumentReadyState end_state); + void OnTimeout(); + void OnTimeoutInState(const ClientStatus& status, + DocumentReadyState end_state); + void SendResult(const ClientStatus& status, DocumentReadyState end_state); + + ProcessActionCallback callback_; + base::OneShotTimer timer_; + base::WeakPtrFactory<WaitForDocumentAction> weak_ptr_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(WaitForDocumentAction); +}; + +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_WAIT_FOR_DOCUMENT_ACTION_H_
diff --git a/components/autofill_assistant/browser/actions/wait_for_document_action_unittest.cc b/components/autofill_assistant/browser/actions/wait_for_document_action_unittest.cc new file mode 100644 index 0000000..467e36c --- /dev/null +++ b/components/autofill_assistant/browser/actions/wait_for_document_action_unittest.cc
@@ -0,0 +1,211 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill_assistant/browser/actions/wait_for_document_action.h" + +#include <utility> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/test/bind_test_util.h" +#include "base/test/gmock_callback_support.h" +#include "base/test/mock_callback.h" +#include "base/test/scoped_task_environment.h" +#include "components/autofill_assistant/browser/actions/mock_action_delegate.h" +#include "components/autofill_assistant/browser/client_status.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace autofill_assistant { +namespace { + +using ::base::test::RunOnceCallback; +using ::testing::_; +using ::testing::ElementsAre; +using ::testing::Eq; +using ::testing::Invoke; +using ::testing::IsEmpty; +using ::testing::IsNull; +using ::testing::Pointee; +using ::testing::Property; +using ::testing::SizeIs; + +class WaitForDocumentActionTest : public testing::Test { + public: + WaitForDocumentActionTest() + : task_env_(base::test::ScopedTaskEnvironment::TimeSource::MOCK_TIME) {} + + void SetUp() override { + ON_CALL(mock_action_delegate_, OnWaitForDocumentReadyState(_, _, _)) + .WillByDefault(RunOnceCallback<2>(OkClientStatus(), DOCUMENT_COMPLETE)); + } + + // Runs the action defined in |proto_| and reports the result to + // |processed_action_|. + // + // Once it has run, the result of the action is available in + // |processed_action_|. Before the action has run, |processed_action_| status + // is UNKNOWN_ACTION_STATUS. + void Run() { + ActionProto action_proto; + *action_proto.mutable_wait_for_document() = proto_; + action_ = std::make_unique<WaitForDocumentAction>(&mock_action_delegate_, + action_proto); + action_->ProcessAction(base::BindOnce(base::BindLambdaForTesting( + [&](std::unique_ptr<ProcessedActionProto> result) { + LOG(ERROR) << "Got Processed action Result"; + processed_action_ = *result; + }))); + } + + protected: + // task_env_ must be first to guarantee other field + // creation run in that environment. + base::test::ScopedTaskEnvironment task_env_; + + MockActionDelegate mock_action_delegate_; + WaitForDocumentProto proto_; + ProcessedActionProto processed_action_; + std::unique_ptr<WaitForDocumentAction> action_; +}; + +TEST_F(WaitForDocumentActionTest, CheckOnceComplete) { + EXPECT_CALL(mock_action_delegate_, OnGetDocumentReadyState(_, _)) + .WillOnce(RunOnceCallback<1>(OkClientStatus(), DOCUMENT_COMPLETE)); + proto_.set_timeout_ms(0); + Run(); + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); + EXPECT_EQ(DOCUMENT_COMPLETE, + processed_action_.wait_for_document_result().start_ready_state()); + EXPECT_EQ(DOCUMENT_COMPLETE, + processed_action_.wait_for_document_result().end_ready_state()); +} + +TEST_F(WaitForDocumentActionTest, CheckOnceInteractive) { + EXPECT_CALL(mock_action_delegate_, OnGetDocumentReadyState(_, _)) + .WillOnce(RunOnceCallback<1>(OkClientStatus(), DOCUMENT_INTERACTIVE)); + proto_.set_timeout_ms(0); + Run(); + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); + EXPECT_EQ(DOCUMENT_INTERACTIVE, + processed_action_.wait_for_document_result().start_ready_state()); + EXPECT_EQ(DOCUMENT_INTERACTIVE, + processed_action_.wait_for_document_result().end_ready_state()); +} + +TEST_F(WaitForDocumentActionTest, CheckOnceLoading) { + EXPECT_CALL(mock_action_delegate_, OnGetDocumentReadyState(_, _)) + .WillOnce(RunOnceCallback<1>(OkClientStatus(), DOCUMENT_LOADING)); + proto_.set_timeout_ms(0); + Run(); + EXPECT_EQ(TIMED_OUT, processed_action_.status()); + EXPECT_EQ(DOCUMENT_LOADING, + processed_action_.wait_for_document_result().start_ready_state()); + EXPECT_EQ(DOCUMENT_LOADING, + processed_action_.wait_for_document_result().end_ready_state()); +} + +TEST_F(WaitForDocumentActionTest, CheckOnceRejectInteractive) { + EXPECT_CALL(mock_action_delegate_, OnGetDocumentReadyState(_, _)) + .WillOnce(RunOnceCallback<1>(OkClientStatus(), DOCUMENT_INTERACTIVE)); + proto_.set_timeout_ms(0); + proto_.set_min_ready_state(DOCUMENT_COMPLETE); + Run(); + EXPECT_EQ(TIMED_OUT, processed_action_.status()); + EXPECT_EQ(DOCUMENT_INTERACTIVE, + processed_action_.wait_for_document_result().start_ready_state()); + EXPECT_EQ(DOCUMENT_INTERACTIVE, + processed_action_.wait_for_document_result().end_ready_state()); +} + +TEST_F(WaitForDocumentActionTest, CheckOnceAcceptLoading) { + EXPECT_CALL(mock_action_delegate_, OnGetDocumentReadyState(_, _)) + .WillOnce(RunOnceCallback<1>(OkClientStatus(), DOCUMENT_LOADING)); + proto_.set_timeout_ms(0); + proto_.set_min_ready_state(DOCUMENT_LOADING); + Run(); + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); + EXPECT_EQ(DOCUMENT_LOADING, + processed_action_.wait_for_document_result().start_ready_state()); + EXPECT_EQ(DOCUMENT_LOADING, + processed_action_.wait_for_document_result().end_ready_state()); +} + +TEST_F(WaitForDocumentActionTest, WaitForDocumentInteractive) { + EXPECT_CALL(mock_action_delegate_, OnGetDocumentReadyState(_, _)) + .WillOnce(RunOnceCallback<1>(OkClientStatus(), DOCUMENT_LOADING)); + EXPECT_CALL(mock_action_delegate_, + OnWaitForDocumentReadyState(_, DOCUMENT_INTERACTIVE, _)) + .WillOnce(RunOnceCallback<2>(OkClientStatus(), DOCUMENT_INTERACTIVE)); + proto_.set_timeout_ms(1000); + Run(); + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); + EXPECT_EQ(DOCUMENT_LOADING, + processed_action_.wait_for_document_result().start_ready_state()); + EXPECT_EQ(DOCUMENT_INTERACTIVE, + processed_action_.wait_for_document_result().end_ready_state()); +} + +TEST_F(WaitForDocumentActionTest, WaitForDocumentInteractiveTimesOut) { + // The first time the document is reported as loading. + EXPECT_CALL(mock_action_delegate_, OnGetDocumentReadyState(_, _)) + .WillOnce(RunOnceCallback<1>(OkClientStatus(), DOCUMENT_LOADING)); + + // The document doesn't become complete right away. + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + captured_callback; + EXPECT_CALL(mock_action_delegate_, + OnWaitForDocumentReadyState(_, DOCUMENT_COMPLETE, _)) + .WillOnce(Invoke( + [&captured_callback]( + const Selector& frame, DocumentReadyState min_ready_state, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)>& + callback) { captured_callback = std::move(callback); })); + + proto_.set_timeout_ms(1000); + proto_.set_min_ready_state(DOCUMENT_COMPLETE); + Run(); + + // 1s afterwards, the document has become interactive, but not complete. The + // action times out and reports that. + EXPECT_CALL(mock_action_delegate_, OnGetDocumentReadyState(_, _)) + .WillOnce(RunOnceCallback<1>(OkClientStatus(), DOCUMENT_INTERACTIVE)); + task_env_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ(TIMED_OUT, processed_action_.status()); + EXPECT_EQ(DOCUMENT_LOADING, + processed_action_.wait_for_document_result().start_ready_state()); + EXPECT_EQ(DOCUMENT_INTERACTIVE, + processed_action_.wait_for_document_result().end_ready_state()); + + // This callback should be ignored. It's too late. This should not crash. + std::move(captured_callback).Run(OkClientStatus(), DOCUMENT_COMPLETE); +} + +TEST_F(WaitForDocumentActionTest, CheckDocumentInFrame) { + EXPECT_CALL(mock_action_delegate_, + OnShortWaitForElement(Selector({"#frame"}), _)) + .WillRepeatedly(RunOnceCallback<1>(true)); + + EXPECT_CALL(mock_action_delegate_, + OnGetDocumentReadyState(Selector({"#frame"}), _)) + .WillOnce(RunOnceCallback<1>(OkClientStatus(), DOCUMENT_COMPLETE)); + + proto_.set_timeout_ms(0); + proto_.mutable_frame()->add_selectors("#frame"); + Run(); + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); +} + +TEST_F(WaitForDocumentActionTest, CheckFrameElementNotFound) { + EXPECT_CALL(mock_action_delegate_, OnShortWaitForElement(_, _)) + .WillRepeatedly(RunOnceCallback<1>(false)); + + proto_.set_timeout_ms(0); + proto_.mutable_frame()->add_selectors("#frame"); + Run(); + EXPECT_EQ(ELEMENT_RESOLUTION_FAILED, processed_action_.status()); +} + +} // namespace +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc index 39ae7bb..764236a 100644 --- a/components/autofill_assistant/browser/controller.cc +++ b/components/autofill_assistant/browser/controller.cc
@@ -300,13 +300,13 @@ return true; } -void Controller::SetResizeViewport(bool resize_viewport) { - if (resize_viewport == resize_viewport_) +void Controller::SetViewportMode(ViewportMode mode) { + if (mode == viewport_mode_) return; - resize_viewport_ = resize_viewport; + viewport_mode_ = mode; for (ControllerObserver& observer : observers_) { - observer.OnResizeViewportChanged(resize_viewport); + observer.OnViewportModeChanged(mode); } } @@ -440,8 +440,8 @@ observers_.RemoveObserver(observer); } -bool Controller::GetResizeViewport() { - return resize_viewport_; +ViewportMode Controller::GetViewportMode() { + return viewport_mode_; } ConfigureBottomSheetProto::PeekMode Controller::GetPeekMode() {
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h index 38325f9..a6a32bc 100644 --- a/components/autofill_assistant/browser/controller.h +++ b/components/autofill_assistant/browser/controller.h
@@ -109,7 +109,7 @@ void SetProgressVisible(bool visible) override; void SetUserActions( std::unique_ptr<std::vector<UserAction>> user_actions) override; - void SetResizeViewport(bool resize_viewport) override; + void SetViewportMode(ViewportMode mode) override; void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) override; bool SetForm(std::unique_ptr<FormProto> form, base::RepeatingCallback<void(const FormProto::Result*)> callback) @@ -163,7 +163,7 @@ Metrics::DropOutReason reason) override; void PerformDelayedShutdownIfNecessary(); void MaybeReportFirstCheckDone(); - bool GetResizeViewport() override; + ViewportMode GetViewportMode() override; ConfigureBottomSheetProto::PeekMode GetPeekMode() override; void GetOverlayColors(OverlayColors* colors) const override; const FormProto* GetForm() const override; @@ -328,8 +328,8 @@ // Current set of user actions. May be null, but never empty. std::unique_ptr<std::vector<UserAction>> user_actions_; - // Whether the viewport should be resized. - bool resize_viewport_ = false; + // Current viewport mode. + ViewportMode viewport_mode_ = ViewportMode::NO_RESIZE; // Current peek mode. ConfigureBottomSheetProto::PeekMode peek_mode_ =
diff --git a/components/autofill_assistant/browser/controller_observer.cc b/components/autofill_assistant/browser/controller_observer.cc index 56c6a16..ba003cef 100644 --- a/components/autofill_assistant/browser/controller_observer.cc +++ b/components/autofill_assistant/browser/controller_observer.cc
@@ -30,7 +30,7 @@ const RectF& visual_viewport, const std::vector<RectF>& touchable_areas, const std::vector<RectF>& restricted_areas) {} -void ControllerObserver::OnResizeViewportChanged(bool resize_viewport) {} +void ControllerObserver::OnViewportModeChanged(ViewportMode mode) {} void ControllerObserver::OnPeekModeChanged( ConfigureBottomSheetProto::PeekMode peek_mode) {} void ControllerObserver::OnOverlayColorsChanged(
diff --git a/components/autofill_assistant/browser/controller_observer.h b/components/autofill_assistant/browser/controller_observer.h index 1b307643..2e6fcff 100644 --- a/components/autofill_assistant/browser/controller_observer.h +++ b/components/autofill_assistant/browser/controller_observer.h
@@ -19,6 +19,7 @@ #include "components/autofill_assistant/browser/state.h" #include "components/autofill_assistant/browser/ui_delegate.h" #include "components/autofill_assistant/browser/user_action.h" +#include "components/autofill_assistant/browser/viewport_mode.h" #include "third_party/blink/public/mojom/payments/payment_request.mojom.h" namespace autofill_assistant { @@ -90,8 +91,8 @@ const std::vector<RectF>& touchable_areas, const std::vector<RectF>& restricted_areas); - // Called when the viewport resize flag has changed. - virtual void OnResizeViewportChanged(bool resize_viewport); + // Called when the viewport mode has changed. + virtual void OnViewportModeChanged(ViewportMode mode); // Called when the peek mode has changed. virtual void OnPeekModeChanged(ConfigureBottomSheetProto::PeekMode peek_mode);
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.cc b/components/autofill_assistant/browser/fake_script_executor_delegate.cc index dd6874d..6d85266 100644 --- a/components/autofill_assistant/browser/fake_script_executor_delegate.cc +++ b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
@@ -99,12 +99,12 @@ payment_request_options_ = std::move(options); } -void FakeScriptExecutorDelegate::SetResizeViewport(bool resize_viewport) { - resize_viewport_ = resize_viewport; +void FakeScriptExecutorDelegate::SetViewportMode(ViewportMode mode) { + viewport_mode_ = mode; } -bool FakeScriptExecutorDelegate::GetResizeViewport() { - return resize_viewport_; +ViewportMode FakeScriptExecutorDelegate::GetViewportMode() { + return viewport_mode_; } void FakeScriptExecutorDelegate::SetPeekMode(
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.h b/components/autofill_assistant/browser/fake_script_executor_delegate.h index 2d1e66ef..9930b56 100644 --- a/components/autofill_assistant/browser/fake_script_executor_delegate.h +++ b/components/autofill_assistant/browser/fake_script_executor_delegate.h
@@ -49,8 +49,8 @@ std::unique_ptr<std::vector<UserAction>> user_actions) override; void SetPaymentRequestOptions( std::unique_ptr<PaymentRequestOptions> options) override; - void SetResizeViewport(bool resize_viewport) override; - bool GetResizeViewport() override; + void SetViewportMode(ViewportMode mode) override; + ViewportMode GetViewportMode() override; void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) override; ConfigureBottomSheetProto::PeekMode GetPeekMode() override; bool SetForm(std::unique_ptr<FormProto> form, @@ -115,7 +115,7 @@ bool navigating_to_new_document_ = false; bool navigation_error_ = false; std::set<ScriptExecutorDelegate::Listener*> listeners_; - bool resize_viewport_ = false; + ViewportMode viewport_mode_ = ViewportMode::NO_RESIZE; ConfigureBottomSheetProto::PeekMode peek_mode_ = ConfigureBottomSheetProto::HANDLE; bool require_ui_ = false;
diff --git a/components/autofill_assistant/browser/mock_controller_observer.h b/components/autofill_assistant/browser/mock_controller_observer.h index 37805953..6a5510b 100644 --- a/components/autofill_assistant/browser/mock_controller_observer.h +++ b/components/autofill_assistant/browser/mock_controller_observer.h
@@ -39,7 +39,7 @@ const std::vector<RectF>& restricted_areas)); MOCK_CONST_METHOD0(Terminate, bool()); MOCK_CONST_METHOD0(GetDropOutReason, Metrics::DropOutReason()); - MOCK_METHOD1(OnResizeViewportChanged, void(bool resize_viewport)); + MOCK_METHOD1(OnViewportModeChanged, void(ViewportMode mode)); MOCK_METHOD1(OnPeekModeChanged, void(ConfigureBottomSheetProto::PeekMode peek_mode)); MOCK_METHOD1(OnFormChanged, void(const FormProto* form));
diff --git a/components/autofill_assistant/browser/mock_web_controller.h b/components/autofill_assistant/browser/mock_web_controller.h index e1558f2..bd2b589e 100644 --- a/components/autofill_assistant/browser/mock_web_controller.h +++ b/components/autofill_assistant/browser/mock_web_controller.h
@@ -89,6 +89,32 @@ MOCK_METHOD1(OnWaitForWindowHeightChange, void(base::OnceCallback<void(const ClientStatus&)>& callback)); + + MOCK_METHOD2( + OnGetDocumentReadyState, + void(const Selector&, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)>&)); + + void GetDocumentReadyState( + const Selector& frame, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback) override { + OnGetDocumentReadyState(frame, callback); + } + + MOCK_METHOD3( + OnWaitForDocumentReadyState, + void(const Selector&, + DocumentReadyState min_ready_state, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)>&)); + + void WaitForDocumentReadyState( + const Selector& frame, + DocumentReadyState min_ready_state, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback) override { + OnWaitForDocumentReadyState(frame, min_ready_state, callback); + } }; } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/protocol_utils.cc b/components/autofill_assistant/browser/protocol_utils.cc index c2373c7..8f336e239 100644 --- a/components/autofill_assistant/browser/protocol_utils.cc +++ b/components/autofill_assistant/browser/protocol_utils.cc
@@ -30,6 +30,7 @@ #include "components/autofill_assistant/browser/actions/tell_action.h" #include "components/autofill_assistant/browser/actions/unsupported_action.h" #include "components/autofill_assistant/browser/actions/upload_dom_action.h" +#include "components/autofill_assistant/browser/actions/wait_for_document_action.h" #include "components/autofill_assistant/browser/actions/wait_for_dom_action.h" #include "components/autofill_assistant/browser/actions/wait_for_navigation_action.h" #include "components/autofill_assistant/browser/service.pb.h" @@ -295,6 +296,11 @@ client_action = std::make_unique<PopupMessageAction>(delegate, action); break; } + case ActionProto::ActionInfoCase::kWaitForDocument: { + client_action = + std::make_unique<WaitForDocumentAction>(delegate, action); + break; + } case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET: { DVLOG(1) << "Encountered action with ACTION_INFO_NOT_SET"; client_action = std::make_unique<UnsupportedAction>(delegate, action);
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc index a87860c..5c457225 100644 --- a/components/autofill_assistant/browser/script_executor.cc +++ b/components/autofill_assistant/browser/script_executor.cc
@@ -443,6 +443,23 @@ return true; } +void ScriptExecutor::GetDocumentReadyState( + const Selector& optional_frame, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback) { + delegate_->GetWebController()->GetDocumentReadyState(optional_frame, + std::move(callback)); +} + +void ScriptExecutor::WaitForDocumentReadyState( + const Selector& optional_frame, + DocumentReadyState min_ready_state, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback) { + delegate_->GetWebController()->WaitForDocumentReadyState( + optional_frame, min_ready_state, std::move(callback)); +} + void ScriptExecutor::LoadURL(const GURL& url) { delegate_->GetWebController()->LoadURL(url); } @@ -491,12 +508,12 @@ delegate_->SetInfoBox(info_box); } -void ScriptExecutor::SetResizeViewport(bool resize_viewport) { - delegate_->SetResizeViewport(resize_viewport); +void ScriptExecutor::SetViewportMode(ViewportMode mode) { + delegate_->SetViewportMode(mode); } -bool ScriptExecutor::GetResizeViewport() { - return delegate_->GetResizeViewport(); +ViewportMode ScriptExecutor::GetViewportMode() { + return delegate_->GetViewportMode(); } void ScriptExecutor::SetPeekMode(
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h index 58030034..749746f 100644 --- a/components/autofill_assistant/browser/script_executor.h +++ b/components/autofill_assistant/browser/script_executor.h
@@ -171,6 +171,16 @@ void ExpectNavigation() override; bool ExpectedNavigationHasStarted() override; bool WaitForNavigation(base::OnceCallback<void(bool)> callback) override; + void GetDocumentReadyState( + const Selector& optional_frame, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback) override; + void WaitForDocumentReadyState( + const Selector& optional_frame, + DocumentReadyState min_ready_state, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback) override; + void LoadURL(const GURL& url) override; void Shutdown() override; void Close() override; @@ -183,8 +193,8 @@ void SetInfoBox(const InfoBox& info_box) override; void SetProgress(int progress) override; void SetProgressVisible(bool visible) override; - void SetResizeViewport(bool resize_viewport) override; - bool GetResizeViewport() override; + void SetViewportMode(ViewportMode mode) override; + ViewportMode GetViewportMode() override; void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) override; ConfigureBottomSheetProto::PeekMode GetPeekMode() override; void WaitForWindowHeightChange(
diff --git a/components/autofill_assistant/browser/script_executor_delegate.h b/components/autofill_assistant/browser/script_executor_delegate.h index 333678c..dd254916 100644 --- a/components/autofill_assistant/browser/script_executor_delegate.h +++ b/components/autofill_assistant/browser/script_executor_delegate.h
@@ -15,6 +15,7 @@ #include "components/autofill_assistant/browser/payment_request.h" #include "components/autofill_assistant/browser/state.h" #include "components/autofill_assistant/browser/user_action.h" +#include "components/autofill_assistant/browser/viewport_mode.h" #include "url/gurl.h" namespace autofill { @@ -69,8 +70,8 @@ virtual void SetProgressVisible(bool visible) = 0; virtual void SetUserActions( std::unique_ptr<std::vector<UserAction>> user_action) = 0; - virtual bool GetResizeViewport() = 0; - virtual void SetResizeViewport(bool resize_viewport) = 0; + virtual ViewportMode GetViewportMode() = 0; + virtual void SetViewportMode(ViewportMode mode) = 0; virtual void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) = 0; virtual ConfigureBottomSheetProto::PeekMode GetPeekMode() = 0; virtual bool SetForm(
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index d52aed2..02a02666 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -410,6 +410,7 @@ ConfigureBottomSheetProto configure_bottom_sheet = 42; ShowFormProto show_form = 43; PopupMessageProto popup_message = 44; + WaitForDocumentProto wait_for_document = 45; } // Set to true to make the client remove any contextual information if the @@ -453,6 +454,8 @@ WaitForDomProto.Result wait_for_dom_result = 22; // Should be set as a result of FormAction. FormProto.Result form_result = 21; + + WaitForDocumentProto.Result wait_for_document_result = 25; } // Reports information about navigation that happened while @@ -944,9 +947,18 @@ optional ElementReferenceProto element = 1; } -// Load the given URL in the current tab. +// Controls the browser navigation. message NavigateProto { - optional string url = 1; + oneof value { + // Navigate to the given URL. + string url = 1; + // Navigate backward in the history. Action will return PRECONDITION_FAILED + // if it is not possible. + bool go_backward = 2; + // Navigate forward in the history. Action will return PRECONDITION_FAILED + // if it is not possible. + bool go_forward = 3; + } } // Specify from which point in the script navigation is expected for the next @@ -974,6 +986,55 @@ optional int32 timeout_ms = 1; } +// Chrome document.readyState values. +// +// Number is significant, as the document goes through these state in order, +// from initialized to complete. +enum DocumentReadyState { + option allow_alias = true; + + DOCUMENT_UNKNOWN_READY_STATE = 0; + DOCUMENT_UNINITIALIZED = 1; + DOCUMENT_LOADING = 2; + DOCUMENT_LOADED = 3; + DOCUMENT_INTERACTIVE = 4; + DOCUMENT_COMPLETE = 5; + + // Maximum value above. + DOCUMENT_MAX_READY_STATE = 5; +} + +// Wait for the document to be ready before proceeding. +// +// Client errors: +// TIMED_OUT if timed out waiting for an acceptable state. +// ELEMENT_RESOLUTION_FAILED if the specified frame selector could not be +// found. +message WaitForDocumentProto { + // Maximum amount of time to wait for the state to change. Set it to 0 to + // check once and report the result immediately, without waiting. + optional int32 timeout_ms = 1 [default = 5000]; + + // If specified, check the document in the given frame, instead + // of the main document. + optional ElementReferenceProto frame = 2; + + // The minimum ready state needed to satisfy the requirement. + optional DocumentReadyState min_ready_state = 3 + [default = DOCUMENT_INTERACTIVE]; + + message Result { + // The ready state found when the action started. + optional DocumentReadyState start_ready_state = 1; + + // The ready state found when the action ended. + // + // This is filled even when the action fails, so it is not guaranteed to + // match min_ready_state. + optional DocumentReadyState end_ready_state = 2; + } +} + // Allow choosing one or more possibility. If FocusElement was called just // before, allow interaction with the touchable element area, otherwise don't // allow any interactions. @@ -1278,13 +1339,17 @@ // Don't change resizing configuration. NO_CHANGE = 0; - // Resize the viewport such that it is completely visible when the sheet is - // in the peek state. - RESIZE = 1; + // Resize the layout viewport such that it is completely visible when the + // sheet is in the peek state. + RESIZE_LAYOUT_VIEWPORT = 1; // Don't resize the viewport such that it is overlaid by the sheet, even in // the peek state. NO_RESIZE = 2; + + // Dynamically resize the visual viewport by the height of the sheet. This + // allows to fully scroll the page above the sheet at any time. + RESIZE_VISUAL_VIEWPORT = 3; } // The peek mode allows to set what components are visible when the sheet is @@ -1309,8 +1374,9 @@ optional ViewportResizing viewport_resizing = 1; // Set the peek mode. This will change the peek height of the sheet. If - // resize_viewport is true or was set to true by a previous actions, the - // viewport will be resized to match the new peek height. + // viewport_resizing is set to RESIZE_LAYOUT_VIEWPORT or was set by a previous + // ConfigureBottomSheet action, the viewport will be resized to match the new + // peek height. optional PeekMode peek_mode = 2; // Maximum time to wait for the window to resize before continuing with the
diff --git a/components/autofill_assistant/browser/ui_delegate.h b/components/autofill_assistant/browser/ui_delegate.h index 3788ad1..680f94b9 100644 --- a/components/autofill_assistant/browser/ui_delegate.h +++ b/components/autofill_assistant/browser/ui_delegate.h
@@ -15,6 +15,7 @@ #include "components/autofill_assistant/browser/rectf.h" #include "components/autofill_assistant/browser/state.h" #include "components/autofill_assistant/browser/user_action.h" +#include "components/autofill_assistant/browser/viewport_mode.h" namespace autofill_assistant { class ControllerObserver; @@ -142,7 +143,7 @@ Metrics::DropOutReason reason) = 0; // Returns whether the viewport should be resized. - virtual bool GetResizeViewport() = 0; + virtual ViewportMode GetViewportMode() = 0; virtual ConfigureBottomSheetProto::PeekMode GetPeekMode() = 0;
diff --git a/components/autofill_assistant/browser/viewport_mode.h b/components/autofill_assistant/browser/viewport_mode.h new file mode 100644 index 0000000..f8fe8e2 --- /dev/null +++ b/components/autofill_assistant/browser/viewport_mode.h
@@ -0,0 +1,30 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_VIEWPORT_MODE_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_VIEWPORT_MODE_H_ + +#include <string> + +#include "base/callback.h" + +namespace autofill_assistant { + +// GENERATED_JAVA_ENUM_PACKAGE: ( +// org.chromium.chrome.browser.autofill_assistant) +// GENERATED_JAVA_CLASS_NAME_OVERRIDE: AssistantViewportMode +enum ViewportMode { + // Don't resize the layout nor visual viewport. + NO_RESIZE = 0, + + // Resize the layout viewport by the peek height of the sheet. + RESIZE_LAYOUT_VIEWPORT = 1, + + // Resize the visual viewport by the height of the sheet. + RESIZE_VISUAL_VIEWPORT = 2, +}; + +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_VIEWPORT_MODE_H_
diff --git a/components/autofill_assistant/browser/web_controller.cc b/components/autofill_assistant/browser/web_controller.cc index 274a40f2..a9494a1 100644 --- a/components/autofill_assistant/browser/web_controller.cc +++ b/components/autofill_assistant/browser/web_controller.cc
@@ -13,6 +13,7 @@ #include "base/bind_helpers.h" #include "base/callback.h" #include "base/logging.h" +#include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/task/post_task.h" @@ -357,6 +358,73 @@ *out = false; return false; } + +// Converts a int that correspond to the DocumentReadyState enum into an +// equivalent quoted Javascript string. +std::string DocumentReadyStateToQuotedJsString(int state) { + switch (static_cast<DocumentReadyState>(state)) { + case DOCUMENT_UNKNOWN_READY_STATE: + return "''"; + case DOCUMENT_UNINITIALIZED: + return "'uninitialized'"; + case DOCUMENT_LOADING: + return "'loading'"; + case DOCUMENT_LOADED: + return "'loaded'"; + case DOCUMENT_INTERACTIVE: + return "'interactive'"; + case DOCUMENT_COMPLETE: + return "'complete'"; + + // No default, to get a compilation error if a new enum value is left + // unsupported. + } + + // If the enum values aren't sequential, just add empty strings to fill in the + // blanks. + return "''"; +} + +// Appends to |out| the definition of a function that'll wait for a +// ready state, expressed as a DocumentReadyState enum value. +void AppendWaitForDocumentReadyStateFunction(std::string* out) { + // quoted_names covers all possible DocumentReadyState values. + std::vector<std::string> quoted_names(DOCUMENT_MAX_READY_STATE + 1); + for (int i = 0; i <= DOCUMENT_MAX_READY_STATE; i++) { + quoted_names[i] = DocumentReadyStateToQuotedJsString(i); + } + base::StrAppend(out, {R"(function (minReadyStateNum) { + return new Promise((fulfill, reject) => { + let handler = function(event) { + let readyState = document.readyState; + let readyStates = [)", + base::JoinString(quoted_names, ", "), R"(]; + let readyStateNum = readyStates.indexOf(readyState); + if (readyStateNum == -1) readyStateNum = 0; + if (readyStateNum >= minReadyStateNum) { + document.removeEventListener('readystatechange', handler); + fulfill(readyStateNum); + } + } + document.addEventListener('readystatechange', handler) + handler(); + }) +})"}); +} + +// Forward the result of WaitForDocumentReadyState to the callback. The same +// code work on both EvaluateResult and CallFunctionOnResult. +template <typename T> +void OnWaitForDocumentReadyState( + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> callback, + std::unique_ptr<T> result) { + ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); + DVLOG_IF(1, !status.ok()) + << __func__ << " Failed to get document ready state."; + int ready_state; + SafeGetIntValue(result->GetResult(), &ready_state); + std::move(callback).Run(status, static_cast<DocumentReadyState>(ready_state)); +} } // namespace class WebController::Worker { @@ -1191,6 +1259,74 @@ CheckJavaScriptResult(result.get(), __FILE__, __LINE__)); } +void WebController::GetDocumentReadyState( + const Selector& optional_frame, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback) { + WaitForDocumentReadyState(optional_frame, DOCUMENT_UNKNOWN_READY_STATE, + std::move(callback)); +} + +void WebController::WaitForDocumentReadyState( + const Selector& optional_frame, + DocumentReadyState min_ready_state, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback) { + if (optional_frame.empty()) { + std::string expression; + expression.append("("); + AppendWaitForDocumentReadyStateFunction(&expression); + base::StringAppendF(&expression, ")(%d)", + static_cast<int>(min_ready_state)); + devtools_client_->GetRuntime()->Evaluate( + runtime::EvaluateParams::Builder() + .SetExpression(expression) + .SetReturnByValue(true) + .SetAwaitPromise(true) + .Build(), + base::BindOnce(&OnWaitForDocumentReadyState<runtime::EvaluateResult>, + std::move(callback))); + return; + } + FindElement( + optional_frame, /* strict= */ false, + base::BindOnce(&WebController::OnFindElementForWaitForDocumentReadyState, + weak_ptr_factory_.GetWeakPtr(), min_ready_state, + std::move(callback))); +} + +void WebController::OnFindElementForWaitForDocumentReadyState( + DocumentReadyState min_ready_state, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> callback, + const ClientStatus& status, + std::unique_ptr<FindElementResult> element) { + if (!status.ok()) { + std::move(callback).Run(status, DOCUMENT_UNKNOWN_READY_STATE); + return; + } + + std::string function_declaration; + AppendWaitForDocumentReadyStateFunction(&function_declaration); + + std::vector<std::unique_ptr<runtime::CallArgument>> arguments; + arguments.emplace_back( + runtime::CallArgument::Builder() + .SetValue(base::Value::ToUniquePtrValue( + base::Value(static_cast<int>(min_ready_state)))) + .Build()); + devtools_client_->GetRuntime()->CallFunctionOn( + runtime::CallFunctionOnParams::Builder() + .SetObjectId(element ? element->object_id : "") + .SetFunctionDeclaration(function_declaration) + .SetArguments(std::move(arguments)) + .SetReturnByValue(true) + .SetAwaitPromise(true) + .Build(), + base::BindOnce( + &OnWaitForDocumentReadyState<runtime::CallFunctionOnResult>, + std::move(callback))); +} + void WebController::FindElement(const Selector& selector, bool strict_mode, FindElementCallback callback) {
diff --git a/components/autofill_assistant/browser/web_controller.h b/components/autofill_assistant/browser/web_controller.h index 51035732..44a27b0a 100644 --- a/components/autofill_assistant/browser/web_controller.h +++ b/components/autofill_assistant/browser/web_controller.h
@@ -186,6 +186,21 @@ virtual void WaitForWindowHeightChange( base::OnceCallback<void(const ClientStatus&)> callback); + // Gets the value of document.readyState for |optional_frame| or, if it is + // empty, in the main document. + virtual void GetDocumentReadyState( + const Selector& optional_frame, + base::OnceCallback<void(const ClientStatus&, + DocumentReadyState end_state)> callback); + + // Waits for the value of Document.readyState to satisfy |min_ready_state| in + // |optional_frame| or, if it is empty, in the main document. + virtual void WaitForDocumentReadyState( + const Selector& optional_frame, + DocumentReadyState min_ready_state, + base::OnceCallback<void(const ClientStatus&, + DocumentReadyState end_state)> callback); + private: friend class WebControllerBrowserTest; @@ -435,6 +450,17 @@ std::string object_id, base::OnceCallback<void(bool)> callback, std::unique_ptr<runtime::CallFunctionOnResult> result); + void OnFindElementForDocumentReadyState( + base::OnceCallback<void(const ClientStatus&, const std::string&)> + callback, + const ClientStatus& status, + std::unique_ptr<FindElementResult> element); + void OnFindElementForWaitForDocumentReadyState( + DocumentReadyState min_ready_state, + base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> + callback, + const ClientStatus& status, + std::unique_ptr<FindElementResult> element); // Weak pointer is fine here since it must outlive this web controller, which // is guaranteed by the owner of this object. @@ -448,6 +474,5 @@ base::WeakPtrFactory<WebController> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(WebController); }; - } // namespace autofill_assistant #endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_WEB_CONTROLLER_H_
diff --git a/components/autofill_assistant/browser/web_controller_browsertest.cc b/components/autofill_assistant/browser/web_controller_browsertest.cc index b951b13d..148a116e 100644 --- a/components/autofill_assistant/browser/web_controller_browsertest.cc +++ b/components/autofill_assistant/browser/web_controller_browsertest.cc
@@ -21,6 +21,7 @@ namespace autofill_assistant { +using ::testing::AnyOf; using ::testing::IsEmpty; const char* kTargetWebsitePath = "/autofill_assistant_target_website.html"; @@ -186,6 +187,16 @@ std::move(done_callback).Run(); } + void OnClientStatusAndReadyState(base::Closure done_callback, + ClientStatus* result_output, + DocumentReadyState* ready_state_out, + const ClientStatus& status, + DocumentReadyState ready_state) { + *result_output = status; + *ready_state_out = ready_state; + std::move(done_callback).Run(); + } + ClientStatus HighlightElement(const Selector& selector) { base::RunLoop run_loop; ClientStatus result; @@ -1176,4 +1187,53 @@ EXPECT_EQ(ACTION_APPLIED, result.proto_status()); } +IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, + WaitMainDocumentReadyStateInteractive) { + ClientStatus status; + DocumentReadyState end_state; + base::RunLoop run_loop; + web_controller_->WaitForDocumentReadyState( + Selector(), DOCUMENT_INTERACTIVE, + base::BindOnce(&WebControllerBrowserTest::OnClientStatusAndReadyState, + base::Unretained(this), run_loop.QuitClosure(), &status, + &end_state)); + run_loop.Run(); + + EXPECT_EQ(ACTION_APPLIED, status.proto_status()) << "Status: " << status; + EXPECT_THAT(end_state, AnyOf(DOCUMENT_INTERACTIVE, DOCUMENT_COMPLETE)); +} + +IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, + WaitMainDocumentReadyStateComplete) { + ClientStatus status; + DocumentReadyState end_state; + base::RunLoop run_loop; + web_controller_->WaitForDocumentReadyState( + Selector(), DOCUMENT_COMPLETE, + base::BindOnce(&WebControllerBrowserTest::OnClientStatusAndReadyState, + base::Unretained(this), run_loop.QuitClosure(), &status, + &end_state)); + run_loop.Run(); + + EXPECT_EQ(ACTION_APPLIED, status.proto_status()) << "Status: " << status; + EXPECT_EQ(DOCUMENT_COMPLETE, end_state); +} + +IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, + WaitFrameDocumentReadyStateLoaded) { + ClientStatus status; + DocumentReadyState end_state; + base::RunLoop run_loop; + web_controller_->WaitForDocumentReadyState( + Selector({"#iframe"}), DOCUMENT_LOADED, + base::BindOnce(&WebControllerBrowserTest::OnClientStatusAndReadyState, + base::Unretained(this), run_loop.QuitClosure(), &status, + &end_state)); + run_loop.Run(); + + EXPECT_EQ(ACTION_APPLIED, status.proto_status()) << "Status: " << status; + EXPECT_THAT(end_state, + AnyOf(DOCUMENT_LOADED, DOCUMENT_INTERACTIVE, DOCUMENT_COMPLETE)); +} + } // namespace
diff --git a/components/browser_watcher/window_hang_monitor_win_unittest.cc b/components/browser_watcher/window_hang_monitor_win_unittest.cc index 8881f97..b91fc183 100644 --- a/components/browser_watcher/window_hang_monitor_win_unittest.cc +++ b/components/browser_watcher/window_hang_monitor_win_unittest.cc
@@ -11,6 +11,7 @@ #include "base/base_switches.h" #include "base/bind.h" #include "base/command_line.h" +#include "base/message_loop/message_pump_type.h" #include "base/path_service.h" #include "base/process/launch.h" #include "base/process/process.h" @@ -143,7 +144,7 @@ // Creates a thread then creates the message window on it. void CreateMessageWindow() { ASSERT_TRUE(message_window_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_UI, 0))); + base::Thread::Options(base::MessagePumpType::UI, 0))); bool succeeded = false; base::WaitableEvent created( @@ -259,7 +260,7 @@ // window for |process|. Blocks until the monitor has been initialized. bool Start(base::Process process) { if (!thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_UI, 0))) { + base::Thread::Options(base::MessagePumpType::UI, 0))) { return false; }
diff --git a/components/cronet/android/cronet_library_loader.cc b/components/cronet/android/cronet_library_loader.cc index 4eba05c..10a009c 100644 --- a/components/cronet/android/cronet_library_loader.cc +++ b/components/cronet/android/cronet_library_loader.cc
@@ -19,6 +19,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/message_loop/message_loop_current.h" +#include "base/message_loop/message_pump_type.h" #include "base/synchronization/waitable_event.h" #include "base/task/single_thread_task_executor.h" #include "base/task/thread_pool/thread_pool.h" @@ -112,7 +113,7 @@ DCHECK(!base::MessageLoopCurrent::IsSet()); DCHECK(!g_init_task_executor); g_init_task_executor = - new base::SingleThreadTaskExecutor(base::MessageLoop::Type::JAVA); + new base::SingleThreadTaskExecutor(base::MessagePumpType::JAVA); // In integrated mode, NetworkChangeNotifier has been initialized by the host. #if BUILDFLAG(INTEGRATED_MODE)
diff --git a/components/cronet/android/test/quic_test_server.cc b/components/cronet/android/test/quic_test_server.cc index 09ad721..d756bcef 100644 --- a/components/cronet/android/test/quic_test_server.cc +++ b/components/cronet/android/test/quic_test_server.cc
@@ -8,7 +8,7 @@ #include "base/bind.h" #include "base/files/file_path.h" #include "base/files/file_util.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/test/test_support_android.h" #include "base/threading/thread.h" #include "components/cronet/android/cronet_tests_jni_headers/QuicTestServer_jni.h" @@ -88,7 +88,7 @@ g_quic_server_thread = new base::Thread("quic server thread"); base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; bool started = g_quic_server_thread->StartWithOptions(thread_options); DCHECK(started); base::FilePath test_files_root(
diff --git a/components/cronet/cronet_url_request_context.cc b/components/cronet/cronet_url_request_context.cc index d9dec9b9..04e66de 100644 --- a/components/cronet/cronet_url_request_context.cc +++ b/components/cronet/cronet_url_request_context.cc
@@ -23,7 +23,7 @@ #include "base/lazy_instance.h" #include "base/logging.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/statistics_recorder.h" #include "base/single_thread_task_runner.h" @@ -149,7 +149,7 @@ if (!network_task_runner_) { network_thread_ = std::make_unique<base::Thread>("network"); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; network_thread_->StartWithOptions(options); network_task_runner_ = network_thread_->task_runner(); }
diff --git a/components/cronet/ios/cronet_environment.mm b/components/cronet/ios/cronet_environment.mm index 8588672..9d7308ed 100644 --- a/components/cronet/ios/cronet_environment.mm +++ b/components/cronet/ios/cronet_environment.mm
@@ -15,7 +15,7 @@ #include "base/files/scoped_file.h" #include "base/mac/foundation_util.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/path_service.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" @@ -250,7 +250,7 @@ // Threads setup. file_thread_.reset(new base::Thread("Chrome File Thread")); file_thread_->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); // Fetching the task_runner will create the shared thread if necessary. scoped_refptr<base::SingleThreadTaskRunner> task_runner = ios_global_state::GetSharedNetworkIOThreadTaskRunner(); @@ -258,7 +258,7 @@ network_io_thread_.reset( new CronetNetworkThread("Chrome Network IO Thread", this)); network_io_thread_->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); } net::SetCookieStoreIOSClient(new CronetCookieStoreIOSClient(
diff --git a/components/download/internal/background_service/in_memory_download_unittest.cc b/components/download/internal/background_service/in_memory_download_unittest.cc index 19a7e6d3..535f4903 100644 --- a/components/download/internal/background_service/in_memory_download_unittest.cc +++ b/components/download/internal/background_service/in_memory_download_unittest.cc
@@ -6,7 +6,7 @@ #include "base/bind.h" #include "base/guid.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/test/bind_test_util.h" #include "base/test/scoped_task_environment.h" @@ -89,7 +89,7 @@ void SetUp() override { io_thread_.reset(new base::Thread("Network and Blob IO thread")); - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); io_thread_->StartWithOptions(options); base::RunLoop loop;
diff --git a/components/exo/wayland/fuzzer/server_environment.cc b/components/exo/wayland/fuzzer/server_environment.cc index b10056d..3604d4ff 100644 --- a/components/exo/wayland/fuzzer/server_environment.cc +++ b/components/exo/wayland/fuzzer/server_environment.cc
@@ -15,6 +15,7 @@ #include "base/command_line.h" #include "base/files/scoped_temp_dir.h" #include "base/i18n/rtl.h" +#include "base/message_loop/message_pump_type.h" #include "base/path_service.h" #include "base/test/icu_test_util.h" #include "components/exo/display.h" @@ -34,7 +35,7 @@ base::CommandLine::Init(0, nullptr); - base::Thread::Options ui_options(base::MessageLoop::TYPE_UI, 0); + base::Thread::Options ui_options(base::MessagePumpType::UI, 0); ui_thread_.StartWithOptions(ui_options); WaylandClientTestHelper::SetUIThreadTaskRunner(ui_thread_.task_runner()); }
diff --git a/components/gcm_driver/fake_gcm_profile_service.cc b/components/gcm_driver/fake_gcm_profile_service.cc index dd4da997..c875d5c 100644 --- a/components/gcm_driver/fake_gcm_profile_service.cc +++ b/components/gcm_driver/fake_gcm_profile_service.cc
@@ -38,6 +38,16 @@ void OnDispatchMessage(const std::string& app_id, const IncomingMessage& message); + // instance_id::FakeGCMDriverForInstanceID overrides: + void SendWebPushMessage(const std::string& app_id, + const std::string& authorized_entity, + const std::string& p256dh, + const std::string& auth_secret, + const std::string& fcm_token, + crypto::ECPrivateKey* vapid_key, + gcm::WebPushMessage message, + SendWebPushMessageCallback callback) override; + protected: // FakeGCMDriver overrides: void RegisterImpl(const std::string& app_id, @@ -152,6 +162,21 @@ app_id, receiver_id, message)); } +void FakeGCMProfileService::CustomFakeGCMDriver::SendWebPushMessage( + const std::string& app_id, + const std::string& authorized_entity, + const std::string& p256dh, + const std::string& auth_secret, + const std::string& fcm_token, + crypto::ECPrivateKey* vapid_key, + gcm::WebPushMessage message, + SendWebPushMessageCallback callback) { + if (service_->collect_) { + service_->last_receiver_id_ = fcm_token; + service_->last_web_push_message_ = std::move(message); + } +} + void FakeGCMProfileService::CustomFakeGCMDriver::DoSend( const std::string& app_id, const std::string& receiver_id,
diff --git a/components/gcm_driver/fake_gcm_profile_service.h b/components/gcm_driver/fake_gcm_profile_service.h index 8302eb63..fd6cd549 100644 --- a/components/gcm_driver/fake_gcm_profile_service.h +++ b/components/gcm_driver/fake_gcm_profile_service.h
@@ -39,6 +39,10 @@ return last_sent_message_; } + const WebPushMessage& last_web_push_message() const { + return last_web_push_message_; + } + const std::string& last_receiver_id() const { return last_receiver_id_; } const std::string& last_registered_app_id() const { @@ -69,6 +73,7 @@ std::list<GCMClient::Result> unregister_responses_; OutgoingMessage last_sent_message_; std::string last_receiver_id_; + WebPushMessage last_web_push_message_; DISALLOW_COPY_AND_ASSIGN(FakeGCMProfileService); };
diff --git a/components/grpc_support/test/get_stream_engine.cc b/components/grpc_support/test/get_stream_engine.cc index 2647abe..2f019e8 100644 --- a/components/grpc_support/test/get_stream_engine.cc +++ b/components/grpc_support/test/get_stream_engine.cc
@@ -10,7 +10,7 @@ #include "base/lazy_instance.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" @@ -116,7 +116,7 @@ static base::Thread* test_io_thread_ = new base::Thread("grpc_support_test_io_thread"); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; bool started = test_io_thread_->StartWithOptions(options); DCHECK(started);
diff --git a/components/invalidation/impl/non_blocking_invalidator_unittest.cc b/components/invalidation/impl/non_blocking_invalidator_unittest.cc index 6592f8f0..f5530d0 100644 --- a/components/invalidation/impl/non_blocking_invalidator_unittest.cc +++ b/components/invalidation/impl/non_blocking_invalidator_unittest.cc
@@ -9,6 +9,7 @@ #include "base/bind_helpers.h" #include "base/location.h" #include "base/memory/ref_counted.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" @@ -39,7 +40,7 @@ invalidation_state_tracker) { DCHECK(!invalidator_); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; io_thread_.StartWithOptions(options); net_config_helper_ = std::make_unique<jingle_glue::NetworkServiceConfigTestUtil>(
diff --git a/components/language/core/common/language_experiments.cc b/components/language/core/common/language_experiments.cc index e7cec35..df4c1f7 100644 --- a/components/language/core/common/language_experiments.cc +++ b/components/language/core/common/language_experiments.cc
@@ -24,7 +24,7 @@ const base::Feature kUseFluentLanguageModel{"UseFluentLanguageModel", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kNotifySyncOnLanguageDetermined{ - "NotifySyncOnLanguageDetermined", base::FEATURE_DISABLED_BY_DEFAULT}; + "NotifySyncOnLanguageDetermined", base::FEATURE_ENABLED_BY_DEFAULT}; // Base feature for Translate desktop UI experiment const base::Feature kUseButtonTranslateBubbleUi{
diff --git a/components/nacl/loader/nacl_listener.cc b/components/nacl/loader/nacl_listener.cc index 63ba6c7..f78eeffe 100644 --- a/components/nacl/loader/nacl_listener.cc +++ b/components/nacl/loader/nacl_listener.cc
@@ -20,7 +20,7 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/memory/read_only_shared_memory_region.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/rand_util.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -163,7 +163,7 @@ #endif is_started_(false) { io_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); DCHECK(g_listener == NULL); g_listener = this; }
diff --git a/components/nacl/loader/nonsfi/nonsfi_listener.cc b/components/nacl/loader/nonsfi/nonsfi_listener.cc index a44f99c..b6ca289 100644 --- a/components/nacl/loader/nonsfi/nonsfi_listener.cc +++ b/components/nacl/loader/nonsfi/nonsfi_listener.cc
@@ -10,7 +10,7 @@ #include "base/command_line.h" #include "base/file_descriptor_posix.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/rand_util.h" #include "base/run_loop.h" #include "build/build_config.h" @@ -41,7 +41,7 @@ base::WaitableEvent::InitialState::NOT_SIGNALED), key_fd_map_(new std::map<std::string, int>) { io_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); } NonSfiListener::~NonSfiListener() {
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc index 83c53df..b51333d 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -147,6 +147,7 @@ bool IsPasswordPrediction(const CredentialFieldType field_type) { switch (field_type) { case CredentialFieldType::kUsername: + case CredentialFieldType::kSingleUsername: case CredentialFieldType::kNone: return false; case CredentialFieldType::kCurrentPassword: @@ -213,6 +214,9 @@ // attributes. bool is_new_password_reliable = false; + // True if the current form has only username, but no passwords. + bool is_single_username = false; + // Returns true if some password field is present. This is the minimal // requirement for a successful creation of a PasswordForm is present. bool HasPasswords() const { @@ -220,6 +224,12 @@ << "There is no password to confirm if there is no new password field."; return password || new_password; } + + void ClearAllPasswordFields() { + password = nullptr; + new_password = nullptr; + confirmation_password = nullptr; + } }; // Returns true if |field| is in |significant_fields|. @@ -284,18 +294,25 @@ case CredentialFieldType::kUsername: if (!result->username) { processed_field = FindField(processed_fields, prediction); - if (processed_field) { + if (processed_field) result->username = processed_field->field; - } } else if (!second_username) { processed_field = FindField(processed_fields, prediction); - if (processed_field) { + if (processed_field) second_username = processed_field->field; - } } else { prevent_handling_two_usernames = true; } break; + case CredentialFieldType::kSingleUsername: + processed_field = FindField(processed_fields, prediction); + if (processed_field) { + result->username = processed_field->field; + result->is_single_username = true; + result->ClearAllPasswordFields(); + return; + } + break; case CredentialFieldType::kCurrentPassword: if (result->password) { prevent_handling_two_usernames = true; @@ -478,7 +495,8 @@ if (processed_field.is_password) passwords.push_back(&processed_field); } - DCHECK(!passwords.empty()); + if (passwords.empty()) + return std::vector<const FormFieldData*>(); // These two counters are used to determine the ReadonlyPasswordFields value // corresponding to this form. @@ -803,8 +821,6 @@ DCHECK(all_possible_passwords->empty()); std::vector<ProcessedField> result; - bool password_field_found = false; - result.reserve(fields.size()); // |all_possible_passwords| should only contain each value once. @@ -840,8 +856,6 @@ ProcessedField processed_field = { .field = &field, .autocomplete_flag = flag, .is_password = is_password}; - password_field_found |= is_password; - if (field.properties_mask & FieldPropertiesFlags::USER_TYPED) processed_field.interactability = Interactability::kCertain; else if (field.is_focusable) @@ -850,9 +864,6 @@ result.push_back(processed_field); } - if (!password_field_found) - result.clear(); - return result; } @@ -908,8 +919,10 @@ autofill::ValueElementVector all_possible_passwords, autofill::ValueElementVector all_possible_usernames, const base::Optional<FormPredictions>& form_predictions) { - if (!significant_fields.HasPasswords()) + if (!significant_fields.HasPasswords() && + !significant_fields.is_single_username) { return nullptr; + } // Create the PasswordForm and set data not related to specific fields. auto result = std::make_unique<PasswordForm>(); @@ -970,11 +983,14 @@ } // (2) If that failed, try to parse with autocomplete attributes. - ParseUsingAutocomplete(processed_fields, &significant_fields); - if (username_detection_method == - UsernameDetectionMethod::kNoUsernameDetected && - significant_fields.username) { - username_detection_method = UsernameDetectionMethod::kAutocompleteAttribute; + if (!significant_fields.is_single_username) { + ParseUsingAutocomplete(processed_fields, &significant_fields); + if (username_detection_method == + UsernameDetectionMethod::kNoUsernameDetected && + significant_fields.username) { + username_detection_method = + UsernameDetectionMethod::kAutocompleteAttribute; + } } // Pass the "reliability" information to mark the new-password fields as @@ -989,32 +1005,35 @@ const bool username_found_before_heuristic = significant_fields.username; // Try to parse with base heuristic. - Interactability username_max = Interactability::kUnlikely; - ParseUsingBaseHeuristics(processed_fields, mode, &significant_fields, - &username_max, &readonly_status_); - if (username_detection_method == - UsernameDetectionMethod::kNoUsernameDetected && - significant_fields.username) { - username_detection_method = UsernameDetectionMethod::kBaseHeuristic; - } + if (!significant_fields.is_single_username) { + Interactability username_max = Interactability::kUnlikely; + ParseUsingBaseHeuristics(processed_fields, mode, &significant_fields, + &username_max, &readonly_status_); + if (username_detection_method == + UsernameDetectionMethod::kNoUsernameDetected && + significant_fields.username) { + username_detection_method = UsernameDetectionMethod::kBaseHeuristic; + } - // Additionally, and based on the best interactability computed by base - // heuristics, try to improve the username based on the context of the - // fields, unless the username already came from more reliable types of - // analysis. - if (!username_found_before_heuristic) { - const FormFieldData* username_field_by_context = FindUsernameInPredictions( - form_data.username_predictions, processed_fields, username_max); - if (username_field_by_context && - !(mode == FormDataParser::Mode::kSaving && - username_field_by_context->value.empty())) { - significant_fields.username = username_field_by_context; - if (username_detection_method == - UsernameDetectionMethod::kNoUsernameDetected || - username_detection_method == - UsernameDetectionMethod::kBaseHeuristic) { - username_detection_method = - UsernameDetectionMethod::kHtmlBasedClassifier; + // Additionally, and based on the best interactability computed by base + // heuristics, try to improve the username based on the context of the + // fields, unless the username already came from more reliable types of + // analysis. + if (!username_found_before_heuristic) { + const FormFieldData* username_field_by_context = + FindUsernameInPredictions(form_data.username_predictions, + processed_fields, username_max); + if (username_field_by_context && + !(mode == FormDataParser::Mode::kSaving && + username_field_by_context->value.empty())) { + significant_fields.username = username_field_by_context; + if (username_detection_method == + UsernameDetectionMethod::kNoUsernameDetected || + username_detection_method == + UsernameDetectionMethod::kBaseHeuristic) { + username_detection_method = + UsernameDetectionMethod::kHtmlBasedClassifier; + } } } }
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc index 059fbb4..3cf4870c 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -2096,6 +2096,21 @@ .autocomplete_attribute = "new-password"}}}}); } +TEST(FormParserTest, SingleUsernamePrediction) { + CheckTestData({ + {"1 field", + {{.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::SINGLE_USERNAME}}}}, + {"Password field is ignored", + {{.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::SINGLE_USERNAME}}, + {.form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}}}, + }); +} + } // namespace } // namespace password_manager
diff --git a/components/password_manager/core/browser/form_parsing/password_field_prediction.cc b/components/password_manager/core/browser/form_parsing/password_field_prediction.cc index 7f46f57..ffe3ac5 100644 --- a/components/password_manager/core/browser/form_parsing/password_field_prediction.cc +++ b/components/password_manager/core/browser/form_parsing/password_field_prediction.cc
@@ -30,6 +30,8 @@ case autofill::USERNAME: case autofill::USERNAME_AND_EMAIL_ADDRESS: return CredentialFieldType::kUsername; + case autofill::SINGLE_USERNAME: + return CredentialFieldType::kSingleUsername; case autofill::PASSWORD: return CredentialFieldType::kCurrentPassword; case autofill::ACCOUNT_CREATION_PASSWORD:
diff --git a/components/password_manager/core/browser/form_parsing/password_field_prediction.h b/components/password_manager/core/browser/form_parsing/password_field_prediction.h index d92f876..0c91ee8 100644 --- a/components/password_manager/core/browser/form_parsing/password_field_prediction.h +++ b/components/password_manager/core/browser/form_parsing/password_field_prediction.h
@@ -20,6 +20,7 @@ enum class CredentialFieldType { kNone, kUsername, + kSingleUsername, kCurrentPassword, kNewPassword, kConfirmationPassword
diff --git a/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc b/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc index a0265ee..a9953935 100644 --- a/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc
@@ -13,8 +13,8 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -using autofill::AutofillField; using autofill::ACCOUNT_CREATION_PASSWORD; +using autofill::AutofillField; using autofill::CONFIRMATION_PASSWORD; using autofill::EMAIL_ADDRESS; using autofill::FormData; @@ -24,6 +24,7 @@ using autofill::NO_SERVER_DATA; using autofill::PASSWORD; using autofill::ServerFieldType; +using autofill::SINGLE_USERNAME; using autofill::UNKNOWN_TYPE; using autofill::USERNAME; using autofill::USERNAME_AND_EMAIL_ADDRESS; @@ -186,6 +187,8 @@ {"Username", USERNAME, CredentialFieldType::kUsername}, {"Username/Email", USERNAME_AND_EMAIL_ADDRESS, CredentialFieldType::kUsername}, + {"Single Username", SINGLE_USERNAME, + CredentialFieldType::kSingleUsername}, {"Password", PASSWORD, CredentialFieldType::kCurrentPassword}, {"New password", NEW_PASSWORD, CredentialFieldType::kNewPassword}, {"Account creation password", ACCOUNT_CREATION_PASSWORD,
diff --git a/components/password_manager/core/browser/import/csv_password.cc b/components/password_manager/core/browser/import/csv_password.cc index 0210dde..0a78a697 100644 --- a/components/password_manager/core/browser/import/csv_password.cc +++ b/components/password_manager/core/browser/import/csv_password.cc
@@ -17,6 +17,19 @@ using ::autofill::PasswordForm; +namespace { + +// Convert() unescapes a CSV field |str| and converts the result to a 16-bit +// string. |str| is assumed to exclude the outer pair of quotation marks, if +// originally present. +base::string16 Convert(base::StringPiece str) { + std::string str_copy(str); + base::ReplaceSubstringsAfterOffset(&str_copy, 0, "\"\"", "\""); + return base::UTF8ToUTF16(str_copy); +} + +} // namespace + CSVPassword::CSVPassword(const ColumnMap& map, base::StringPiece csv_row) : map_(map), row_(csv_row) {} @@ -74,8 +87,8 @@ ? origin.spec() : origin.GetOrigin().spec(); form->origin = std::move(origin); - form->username_value = base::UTF8ToUTF16(username); - form->password_value = base::UTF8ToUTF16(password); + form->username_value = Convert(username); + form->password_value = Convert(password); return true; }
diff --git a/components/password_manager/core/browser/import/csv_password_unittest.cc b/components/password_manager/core/browser/import/csv_password_unittest.cc index ff8c75c..03a19ed 100644 --- a/components/password_manager/core/browser/import/csv_password_unittest.cc +++ b/components/password_manager/core/browser/import/csv_password_unittest.cc
@@ -147,6 +147,16 @@ .Username("the-user") .Password("pwd") .Build(), + TestCaseBuilder("Escaped") + .Map({{0, CSVPassword::Label::kOrigin}, + {2, CSVPassword::Label::kUsername}, + {3, CSVPassword::Label::kPassword}}) + .CSV(R"(http://example.org,"a""b","u,+,c","p""")") + .Origin("http://example.org") + .SignonRealm("http://example.org/") + .Username("u,+,c") + .Password("p\"") + .Build(), TestCaseBuilder("path discarded") .Map({{2, CSVPassword::Label::kOrigin}, {1, CSVPassword::Label::kUsername},
diff --git a/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc b/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc index f05f509..8c085d2 100644 --- a/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc +++ b/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc
@@ -34,7 +34,7 @@ IdentityManagerHelper() = default; void FetchAccessToken(signin::IdentityManager* identity_manager, - const std::string& username, + const CoreAccountId& account_id, const StringCallback& callback); private: @@ -47,7 +47,7 @@ void CloudPolicyClientRegistrationHelper::IdentityManagerHelper:: FetchAccessToken(signin::IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const StringCallback& callback) { DCHECK(!access_token_fetcher_); // The caller must supply a username. @@ -96,7 +96,7 @@ void CloudPolicyClientRegistrationHelper::StartRegistration( signin::IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const base::Closure& callback) { DVLOG(1) << "Starting registration process with account_id"; DCHECK(!client_->is_registered());
diff --git a/components/policy/core/common/cloud/cloud_policy_client_registration_helper.h b/components/policy/core/common/cloud/cloud_policy_client_registration_helper.h index 828eddb..cd0c2ff5 100644 --- a/components/policy/core/common/cloud/cloud_policy_client_registration_helper.h +++ b/components/policy/core/common/cloud/cloud_policy_client_registration_helper.h
@@ -18,6 +18,7 @@ #include "components/policy/core/common/cloud/user_info_fetcher.h" #include "components/policy/policy_export.h" #include "components/policy/proto/device_management_backend.pb.h" +#include "google_apis/gaia/core_account_id.h" namespace signin { class IdentityManager; @@ -47,7 +48,7 @@ // and DM services, using the |account_id|. // |callback| is invoked when the registration is complete. void StartRegistration(signin::IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const base::Closure& callback); // Starts the device registration with an token enrollment process.
diff --git a/components/send_tab_to_self/send_tab_to_self_bridge.cc b/components/send_tab_to_self/send_tab_to_self_bridge.cc index e10dfefe..763bc21 100644 --- a/components/send_tab_to_self/send_tab_to_self_bridge.cc +++ b/components/send_tab_to_self/send_tab_to_self_bridge.cc
@@ -49,7 +49,7 @@ // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. enum class UMANotifyLocalDevice { - // The addedentry was sent to the local machine. + // The added entry was sent to the local machine. LOCAL = 0, // The added entry was targeted at a different machine. REMOTE = 1, @@ -712,11 +712,17 @@ } void SendTabToSelfBridge::SetTargetDeviceInfoList() { + // Verify that the current trackedCacheGuid is the local guid without + // enforcing that tracked cache guid is set. + DCHECK(device_info_tracker_->IsRecentLocalCacheGuid( + change_processor()->TrackedCacheGuid()) || + change_processor()->TrackedCacheGuid().empty()); + std::vector<std::unique_ptr<syncer::DeviceInfo>> all_devices = device_info_tracker_->GetAllDeviceInfo(); number_of_devices_ = all_devices.size(); - // Sort the DeviceInfo vector so the most recenly modified devices are first. + // Sort the DeviceInfo vector so the most recently modified devices are first. std::stable_sort(all_devices.begin(), all_devices.end(), [](const std::unique_ptr<syncer::DeviceInfo>& device1, const std::unique_ptr<syncer::DeviceInfo>& device2) { @@ -734,12 +740,8 @@ break; } - // TODO(crbug.com/966413): Implement a better way to dedupe local devices in - // case the user has other devices with the same name. - // Don't include this device. Also compare the name as the device can have - // different cache guids (e.g. after stopping and re-starting sync). - if (device->guid() == change_processor()->TrackedCacheGuid() || - device->client_name() == local_device_name_) { + // Don't include this device if it is the local device. + if (device_info_tracker_->IsRecentLocalCacheGuid(device->guid())) { continue; }
diff --git a/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc b/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc index 3f3ffee..f112705 100644 --- a/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc +++ b/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc
@@ -99,7 +99,7 @@ sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "scoped_is", clock()->Now() - base::TimeDelta::FromDays(1), /*send_tab_to_self_receiving_enabled=*/true); - AddTestDevice(local_device_.get()); + AddTestDevice(local_device_.get(), true); } // Initialized the bridge based on the current local device and store. Can @@ -179,8 +179,11 @@ .WillByDefault(Return(cache_guid)); } - void AddTestDevice(const syncer::DeviceInfo* device) { + void AddTestDevice(const syncer::DeviceInfo* device, bool local = false) { device_info_tracker_.Add(device); + if (local) { + device_info_tracker_.SetLocalCacheGuid(device->guid()); + } } syncer::MockModelTypeChangeProcessor* processor() { return &mock_processor_; }
diff --git a/components/signin/core/browser/about_signin_internals.cc b/components/signin/core/browser/about_signin_internals.cc index 3032fad8..7291d86 100644 --- a/components/signin/core/browser/about_signin_internals.cc +++ b/components/signin/core/browser/about_signin_internals.cc
@@ -418,7 +418,7 @@ void AboutSigninInternals::OnRefreshTokensLoaded() { RefreshTokenEvent event; - // event.account_id = CoreAccountId("All accounts"); + // This event concerns all accounts, so it does not have any account id. event.type = AboutSigninInternals::RefreshTokenEventType::kAllTokensLoaded; signin_status_.AddRefreshTokenEvent(event); NotifyObservers(); @@ -638,7 +638,7 @@ signin_error_controller->error_account_id(); const base::Optional<AccountInfo> error_account_info = identity_manager - ->FindAccountInfoForAccountWithRefreshTokenByAccountId( + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( error_account_id); AddSectionEntry(basic_info, "Auth Error", signin_error_controller->auth_error().ToString());
diff --git a/components/signin/core/browser/account_investigator_unittest.cc b/components/signin/core/browser/account_investigator_unittest.cc index c752ee4..ebcd10f 100644 --- a/components/signin/core/browser/account_investigator_unittest.cc +++ b/components/signin/core/browser/account_investigator_unittest.cc
@@ -145,9 +145,9 @@ namespace { -ListedAccount Account(const std::string& id) { +ListedAccount Account(const CoreAccountId& account_id) { ListedAccount account; - account.id = id; + account.id = account_id; return account; } @@ -166,9 +166,9 @@ const std::string kGaiaId2 = signin::GetTestGaiaIdForEmail("2@mail.com"); const std::string kGaiaId3 = signin::GetTestGaiaIdForEmail("3@mail.com"); -const ListedAccount one(Account(kGaiaId1)); -const ListedAccount two(Account(kGaiaId2)); -const ListedAccount three(Account(kGaiaId3)); +const ListedAccount one(Account(CoreAccountId(kGaiaId1))); +const ListedAccount two(Account(CoreAccountId(kGaiaId2))); +const ListedAccount three(Account(CoreAccountId(kGaiaId3))); const std::vector<ListedAccount> no_accounts{}; const std::vector<ListedAccount> just_one{one};
diff --git a/components/signin/core/browser/account_reconcilor_unittest.cc b/components/signin/core/browser/account_reconcilor_unittest.cc index c259b7e..155ca78 100644 --- a/components/signin/core/browser/account_reconcilor_unittest.cc +++ b/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -542,7 +542,7 @@ } } if (!authenticated_account_found) - EXPECT_EQ("", identity_manager->GetPrimaryAccountId()); + EXPECT_EQ(CoreAccountId(), identity_manager->GetPrimaryAccountId()); } void SetupTokens() { @@ -685,24 +685,23 @@ if (parameters.mode == gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER) { for (const CoreAccountId& account : parameters.accounts_to_send) { - cookies_after_reconcile.push_back({account, true}); + cookies_after_reconcile.push_back({account.id, true}); } } else { - std::set<CoreAccountId> accounts_set; - for (const CoreAccountId& account : parameters.accounts_to_send) { - accounts_set.insert(account); - } + std::set<CoreAccountId> accounts_set(parameters.accounts_to_send.begin(), + parameters.accounts_to_send.end()); cookies_after_reconcile = cookies_before_reconcile; for (Cookie& param : cookies_after_reconcile) { - if (accounts_set.find(param.gaia_id) != accounts_set.end()) { + if (accounts_set.find(CoreAccountId(param.gaia_id)) != + accounts_set.end()) { param.is_valid = true; - accounts_set.erase(param.gaia_id); + accounts_set.erase(CoreAccountId(param.gaia_id)); } else { param.is_valid = false; } } for (const CoreAccountId& account : accounts_set) { - cookies_after_reconcile.push_back({account, true}); + cookies_after_reconcile.push_back({account.id, true}); } } return cookies_after_reconcile; @@ -930,9 +929,9 @@ .Times(1); // MergeSession fixes an existing cookie or appends it at the end. auto it = std::find(cookies.begin(), cookies.end(), - Cookie{account_id_for_cookie, false /* is_valid */}); + Cookie{account_id_for_cookie.id, false /* is_valid */}); if (it == cookies.end()) - cookies.push_back({account_id_for_cookie, true}); + cookies.push_back({account_id_for_cookie.id, true}); else it->is_valid = true; } @@ -1074,8 +1073,8 @@ // response. std::vector<CoreAccountId> accounts_to_send; for (int i = 1; GetParam().gaia_api_calls_multilogin[i] != '\0'; ++i) { - accounts_to_send.push_back( - accounts_[GetParam().gaia_api_calls_multilogin[i]].gaia_id); + accounts_to_send.push_back(CoreAccountId( + accounts_[GetParam().gaia_api_calls_multilogin[i]].gaia_id)); } const signin::MultiloginParameters params(mode, accounts_to_send); cookies_after_reconcile = FakeSetAccountsInCookie(params, cookies);
diff --git a/components/signin/core/browser/signin_error_controller.cc b/components/signin/core/browser/signin_error_controller.cc index bbfd519f..5c13736 100644 --- a/components/signin/core/browser/signin_error_controller.cc +++ b/components/signin/core/browser/signin_error_controller.cc
@@ -27,10 +27,10 @@ void SigninErrorController::Update() { const GoogleServiceAuthError::State prev_error_state = auth_error_.state(); - const std::string prev_account_id = error_account_id_; + const CoreAccountId prev_account_id = error_account_id_; bool error_changed = false; - const std::string& primary_account_id = + const CoreAccountId& primary_account_id = identity_manager_->GetPrimaryAccountId(); if (identity_manager_->HasAccountWithRefreshTokenInPersistentErrorState( @@ -51,7 +51,7 @@ if (!error_changed && prev_error_state != GoogleServiceAuthError::NONE) { // No provider reported an error, so clear the error we have now. auth_error_ = GoogleServiceAuthError::AuthErrorNone(); - error_account_id_.clear(); + error_account_id_ = CoreAccountId(); error_changed = true; } @@ -70,8 +70,8 @@ } bool SigninErrorController::UpdateSecondaryAccountErrors( - const std::string& primary_account_id, - const std::string& prev_account_id, + const CoreAccountId& primary_account_id, + const CoreAccountId& prev_account_id, const GoogleServiceAuthError::State& prev_error_state) { // This method should not have been called if we are in // |AccountMode::PRIMARY_ACCOUNT|. @@ -84,7 +84,7 @@ bool error_changed = false; for (const CoreAccountInfo& account_info : identity_manager_->GetAccountsWithRefreshTokens()) { - std::string account_id = account_info.account_id; + CoreAccountId account_id = account_info.account_id; // Ignore the Primary Account. We are only interested in Secondary Accounts. if (account_id == primary_account_id) {
diff --git a/components/signin/core/browser/signin_error_controller.h b/components/signin/core/browser/signin_error_controller.h index b1f6486..61f6819 100644 --- a/components/signin/core/browser/signin_error_controller.h +++ b/components/signin/core/browser/signin_error_controller.h
@@ -57,7 +57,7 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); - const std::string& error_account_id() const { return error_account_id_; } + const CoreAccountId& error_account_id() const { return error_account_id_; } const GoogleServiceAuthError& auth_error() const { return auth_error_; } private: @@ -71,8 +71,8 @@ // Note: This function must not be called if |account_mode_| is // |AccountMode::PRIMARY_ACCOUNT|. bool UpdateSecondaryAccountErrors( - const std::string& primary_account_id, - const std::string& prev_account_id, + const CoreAccountId& primary_account_id, + const CoreAccountId& prev_account_id, const GoogleServiceAuthError::State& prev_error_state); // signin::IdentityManager::Observer: @@ -92,7 +92,7 @@ scoped_identity_manager_observer_; // The account that generated the last auth error. - std::string error_account_id_; + CoreAccountId error_account_id_; // The auth error detected the last time AuthStatusChanged() was invoked (or // NONE if AuthStatusChanged() has never been invoked).
diff --git a/components/signin/core/browser/signin_error_controller_unittest.cc b/components/signin/core/browser/signin_error_controller_unittest.cc index 92b478f..bcb736d 100644 --- a/components/signin/core/browser/signin_error_controller_unittest.cc +++ b/components/signin/core/browser/signin_error_controller_unittest.cc
@@ -51,7 +51,7 @@ // updated. EXPECT_CALL(observer, OnErrorChanged()).Times(0); - std::string test_account_id = + CoreAccountId test_account_id = identity_test_env.MakeAccountAvailable(kTestEmail).account_id; ::testing::Mock::VerifyAndClearExpectations(&observer); @@ -86,9 +86,9 @@ base::test::ScopedTaskEnvironment task_environment; signin::IdentityTestEnvironment identity_test_env; - std::string test_account_id = + CoreAccountId test_account_id = identity_test_env.MakeAccountAvailable(kTestEmail).account_id; - std::string other_test_account_id = + CoreAccountId other_test_account_id = identity_test_env.MakeAccountAvailable(kOtherTestEmail).account_id; SigninErrorController error_controller( SigninErrorController::AccountMode::ANY_ACCOUNT, @@ -119,9 +119,9 @@ signin::PrimaryAccountMutator* primary_account_mutator = identity_test_env.identity_manager()->GetPrimaryAccountMutator(); - std::string test_account_id = + CoreAccountId test_account_id = identity_test_env.MakeAccountAvailable(kTestEmail).account_id; - std::string other_test_account_id = + CoreAccountId other_test_account_id = identity_test_env.MakeAccountAvailable(kOtherTestEmail).account_id; SigninErrorController error_controller( SigninErrorController::AccountMode::PRIMARY_ACCOUNT, @@ -182,7 +182,7 @@ base::test::ScopedTaskEnvironment task_environment; signin::IdentityTestEnvironment identity_test_env; - std::string test_account_id = + CoreAccountId test_account_id = identity_test_env.MakeAccountAvailable(kTestEmail).account_id; SigninErrorController error_controller( SigninErrorController::AccountMode::ANY_ACCOUNT, @@ -219,7 +219,7 @@ } else { EXPECT_EQ(GoogleServiceAuthError::NONE, error_controller.auth_error().state()); - EXPECT_EQ("", error_controller.error_account_id()); + EXPECT_EQ(CoreAccountId(), error_controller.error_account_id()); } } } @@ -229,9 +229,9 @@ base::test::ScopedTaskEnvironment task_environment; signin::IdentityTestEnvironment identity_test_env; - std::string test_account_id = + CoreAccountId test_account_id = identity_test_env.MakeAccountAvailable(kTestEmail).account_id; - std::string other_test_account_id = + CoreAccountId other_test_account_id = identity_test_env.MakeAccountAvailable(kOtherTestEmail).account_id; SigninErrorController error_controller( SigninErrorController::AccountMode::ANY_ACCOUNT, @@ -287,7 +287,7 @@ AccountInfo primary_account_info = identity_test_env.MakePrimaryAccountAvailable(kPrimaryAccountEmail); - std::string secondary_account_id = + CoreAccountId secondary_account_id = identity_test_env.MakeAccountAvailable(kTestEmail).account_id; SigninErrorController error_controller( SigninErrorController::AccountMode::ANY_ACCOUNT, @@ -334,7 +334,7 @@ AccountInfo primary_account_info = identity_test_env.MakePrimaryAccountAvailable(kPrimaryAccountEmail); - std::string secondary_account_id = + CoreAccountId secondary_account_id = identity_test_env.MakeAccountAvailable(kTestEmail).account_id; SigninErrorController error_controller( SigninErrorController::AccountMode::ANY_ACCOUNT,
diff --git a/components/signin/internal/identity_manager/README.md b/components/signin/internal/identity_manager/README.md index f4fecc4..501040b 100644 --- a/components/signin/internal/identity_manager/README.md +++ b/components/signin/internal/identity_manager/README.md
@@ -1,3 +1,72 @@ The internal implementation of //components/signin/public/identity_manager; visible only to implementation files in -//components/signin/public/identity_manager. +//components/signin/public/identity_manager. This directory contains +implementations of pure interfaces in +//components/signin/public/identity_manager as well as internal classes. + +Here is how the various core internal classes support the public functionality +of IdentityManager (see +//components/signin/public/identity_manager/README.md for definitions of core +terms): + +- PrimaryAccountManager: Maintains the information of the primary account. When + it is set/cleared, calls out to IdentityManager via callbacks, resulting in the + firing of IdentityManager::Observer notifications. Setting/clearing occurs via + PrimaryAccountMutatorImpl. + Historically was exposed as SigninManager(Base). +- PrimaryAccountPolicyManager: Helper class for PrimaryAccountManager that + manages interactions between policy and the primary account, e.g. clearing the + primary account if signin becomes disallowed by policy. Historically was + contained within SigninManager. +- ProfileOAuth2TokenService: Manages the OAuth2 tokens for the user's Gaia + accounts. Delegates much of the functionality for refresh tokens to its + various platform-specific delegates, and delegates much of the functionality + for access tokens to the lower-level OAuth2AccessTokenManager class. Supports + the IdentityManager APIs for querying the state of the accounts with refresh + tokens and for fetching access tokens via (PrimaryAccount)AccessTokenFetcher. + Mutation of refresh tokens occurs via platform-specific flows: + - AcccountsMutatorImpl on desktop + - DeviceAccountsSynchronizerImpl on iOS + - Within the token service delegate by observing AccountManager on ChromeOS + - Via a legacy flow on Android (https://crbug.com/963391) + Has an observer API (ProfileOAuth2TokenServiceObserver); IdentityManager + observes token-related events via this API in order to fire + IdentityManager::Observer events. Other internal classes also observe + token-related events, which is why PO2TS still has observers rather than + directly calling out to IdentityManager via callbacks as other internal + classes do. +- ProfileOAuth2TokenServiceDelegate: Mostly-abstract class via which + ProfileOAuth2TokenService interacts with platform-specific functionality for + OAuth2 tokens. Has various platform-specific implementations. The + platform-specific implementations glue the cross-platform + ProfileOAuth2TokenService interface to the underlying platform support, and + dictate the firing of ProfileOAuth2TokenServiceObserver events. +- AccountTrackerService: Maintains the mapping from account ID to account + information for the user's Gaia accounts with refresh tokens. Supports the + various IdentityManager::FindAccountInfoXXX() methods. When account info is + updated/removed for a given account, calls out to IdentityManager via + callbacks, resulting in the firing of IdentityManager::Observer notifications. + Conceptually below ProfileOAuth2TokenService, as it is needed by various + platform-specific implementations of ProfileOAuth2TokenServiceDelegate, which + themselves are needed by ProfileOAuth2TokenService. +- AccountFetcherService: Fetches account information for the user's Gaia + accounts with refresh tokens in order to populate this information in + AccountTrackerService. Observes ProfileOAuth2TokenService in order to observe + addition and removal of accounts with refresh tokens to initiate + fetching/removal of account information. Split from AccountTrackerService in + order to support knowledge of ProfileOAuth2TokenService. +- GaiaCookieManagerService: Maintains information about the accounts in the Gaia + cookie. Supports IdentityManager::GetAccountsInCookieJar(). When the accounts + in the cookie are updated or the cookie itself is deleted, calls out to + IdentityManager via callbacks, resulting in the firing of + IdentityManager::Observer notifications. + +The layering of the core internal classes is as follows, with higher-level classes +listed first: + +- PrimaryAccountManager +- AccountFetcherService +- GaiaCookieManagerService (note: GCMS and AFS are independent peers) +- ProfileOAuth2TokenService +- various ProfileOAuth2TokenServiceDelegate implementations +- AccountTrackerService
diff --git a/components/signin/internal/identity_manager/account_tracker_service.h b/components/signin/internal/identity_manager/account_tracker_service.h index 5fc76f4..dc65e8c 100644 --- a/components/signin/internal/identity_manager/account_tracker_service.h +++ b/components/signin/internal/identity_manager/account_tracker_service.h
@@ -40,7 +40,7 @@ namespace signin { class IdentityManager; void SimulateSuccessfulFetchOfAccountInfo(IdentityManager*, - const std::string&, + const CoreAccountId&, const std::string&, const std::string&, const std::string&, @@ -150,7 +150,7 @@ friend class AccountFetcherService; friend void signin::SimulateSuccessfulFetchOfAccountInfo( signin::IdentityManager*, - const std::string&, + const CoreAccountId&, const std::string&, const std::string&, const std::string&,
diff --git a/components/signin/internal/identity_manager/account_tracker_service_unittest.cc b/components/signin/internal/identity_manager/account_tracker_service_unittest.cc index a11e96f3..e4f0d258 100644 --- a/components/signin/internal/identity_manager/account_tracker_service_unittest.cc +++ b/components/signin/internal/identity_manager/account_tracker_service_unittest.cc
@@ -118,7 +118,7 @@ class TrackingEvent { public: TrackingEvent(TrackingEventType type, - const std::string& account_id, + const CoreAccountId& account_id, const std::string& gaia_id, const std::string& email) : type_(type), @@ -143,11 +143,11 @@ } return base::StringPrintf( "{ type: %s, account_id: %s, gaia: %s, email: %s }", typestr, - account_id_.c_str(), gaia_id_.c_str(), email_.c_str()); + account_id_.id.c_str(), gaia_id_.c_str(), email_.c_str()); } TrackingEventType type_; - std::string account_id_; + CoreAccountId account_id_; std::string gaia_id_; std::string email_; }; @@ -186,7 +186,7 @@ void SetUp() override { testing::Test::SetUp(); CreateAccountTracker(base::FilePath(), /*network_enabled=*/true); - fake_oauth2_token_service_.LoadCredentials(""); + fake_oauth2_token_service_.LoadCredentials(CoreAccountId()); } void TearDown() override { @@ -220,9 +220,9 @@ } // Helpers to fake access token and user info fetching - std::string AccountKeyToAccountId(AccountKey account_key) { + CoreAccountId AccountKeyToAccountId(AccountKey account_key) { if (force_account_id_to_email_for_legacy_tests_) - return AccountKeyToEmail(account_key); + return CoreAccountId(AccountKeyToEmail(account_key)); return AccountTrackerService::PickAccountIdForAccount( &pref_service_, AccountKeyToGaiaId(account_key), @@ -576,7 +576,7 @@ TEST_F(AccountTrackerServiceTest, GetAccountInfo_Empty) { AccountInfo info = account_tracker()->GetAccountInfo( AccountKeyToAccountId(kAccountKeyAlpha)); - EXPECT_EQ(std::string(), info.account_id); + EXPECT_EQ(CoreAccountId(), info.account_id); } TEST_F(AccountTrackerServiceTest, GetAccountInfo_TokenAvailable) { @@ -650,7 +650,7 @@ const std::string email_beta = AccountKeyToEmail(kAccountKeyBeta); info = account_tracker()->FindAccountInfoByEmail(email_beta); - EXPECT_EQ(std::string(), info.account_id); + EXPECT_EQ(CoreAccountId(), info.account_id); } TEST_F(AccountTrackerServiceTest, Persistence) { @@ -735,7 +735,7 @@ const std::string gaia_id = AccountKeyToGaiaId(kAccountKeyFooBar); const std::string email = AccountKeyToEmail(kAccountKeyFooBar); const std::string email_dotted = AccountKeyToEmail(kAccountKeyFooDotBar); - const std::string account_id = + const CoreAccountId account_id = account_tracker()->PickAccountIdForAccount(gaia_id, email); account_tracker()->SeedAccountInfo(gaia_id, email); @@ -962,8 +962,10 @@ EXPECT_EQ(account_tracker()->GetMigrationState(), AccountTrackerService::MIGRATION_IN_PROGRESS); - AccountInfo account_info = account_tracker()->GetAccountInfo(gaia_alpha); - EXPECT_EQ(account_info.account_id, gaia_alpha); + CoreAccountId gaia_alpha_account_id(gaia_alpha); + AccountInfo account_info = + account_tracker()->GetAccountInfo(gaia_alpha_account_id); + EXPECT_EQ(account_info.account_id, gaia_alpha_account_id); EXPECT_EQ(account_info.gaia, gaia_alpha); EXPECT_EQ(account_info.email, email_alpha); @@ -1006,13 +1008,16 @@ EXPECT_EQ(account_tracker()->GetMigrationState(), AccountTrackerService::MIGRATION_NOT_STARTED); - AccountInfo account_info = account_tracker()->GetAccountInfo(email_alpha); - EXPECT_EQ(account_info.account_id, email_alpha); + CoreAccountId email_alpha_account_id(email_alpha); + AccountInfo account_info = + account_tracker()->GetAccountInfo(email_alpha_account_id); + EXPECT_EQ(account_info.account_id, email_alpha_account_id); EXPECT_EQ(account_info.gaia, gaia_alpha); EXPECT_EQ(account_info.email, email_alpha); - account_info = account_tracker()->GetAccountInfo(email_beta); - EXPECT_EQ(account_info.account_id, email_beta); + CoreAccountId email_beta_account_id(email_beta); + account_info = account_tracker()->GetAccountInfo(email_beta_account_id); + EXPECT_EQ(account_info.account_id, email_beta_account_id); EXPECT_EQ(account_info.email, email_beta); std::vector<AccountInfo> accounts = account_tracker()->GetAccounts(); @@ -1057,13 +1062,16 @@ EXPECT_EQ(account_tracker()->GetMigrationState(), AccountTrackerService::MIGRATION_IN_PROGRESS); - AccountInfo account_info = account_tracker()->GetAccountInfo(gaia_alpha); - EXPECT_EQ(account_info.account_id, gaia_alpha); + CoreAccountId gaia_alpha_account_id(gaia_alpha); + AccountInfo account_info = + account_tracker()->GetAccountInfo(gaia_alpha_account_id); + EXPECT_EQ(account_info.account_id, gaia_alpha_account_id); EXPECT_EQ(account_info.gaia, gaia_alpha); EXPECT_EQ(account_info.email, email_alpha); - account_info = account_tracker()->GetAccountInfo(gaia_beta); - EXPECT_EQ(account_info.account_id, gaia_beta); + CoreAccountId gaia_beta_account_id(gaia_beta); + account_info = account_tracker()->GetAccountInfo(gaia_beta_account_id); + EXPECT_EQ(account_info.account_id, gaia_beta_account_id); EXPECT_EQ(account_info.gaia, gaia_beta); EXPECT_EQ(account_info.email, email_beta); @@ -1077,13 +1085,13 @@ EXPECT_EQ(account_tracker()->GetMigrationState(), AccountTrackerService::MIGRATION_DONE); - account_info = account_tracker()->GetAccountInfo(gaia_alpha); - EXPECT_EQ(account_info.account_id, gaia_alpha); + account_info = account_tracker()->GetAccountInfo(gaia_alpha_account_id); + EXPECT_EQ(account_info.account_id, gaia_alpha_account_id); EXPECT_EQ(account_info.gaia, gaia_alpha); EXPECT_EQ(account_info.email, email_alpha); - account_info = account_tracker()->GetAccountInfo(gaia_beta); - EXPECT_EQ(account_info.account_id, gaia_beta); + account_info = account_tracker()->GetAccountInfo(gaia_beta_account_id); + EXPECT_EQ(account_info.account_id, gaia_beta_account_id); EXPECT_EQ(account_info.gaia, gaia_beta); EXPECT_EQ(account_info.email, email_beta); @@ -1291,7 +1299,7 @@ SimulateTokenAvailable(kAccountKeyAdvancedProtection); IssueAccessToken(kAccountKeyAdvancedProtection); - const std::string account_id = + const CoreAccountId account_id = AccountKeyToAccountId(kAccountKeyAdvancedProtection); account_tracker()->SetIsAdvancedProtectionAccount(account_id, true); AccountInfo info = account_tracker()->GetAccountInfo(account_id);
diff --git a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.cc b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.cc index 586ce74..2ae836a 100644 --- a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.cc +++ b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.cc
@@ -26,7 +26,7 @@ FakeProfileOAuth2TokenService::~FakeProfileOAuth2TokenService() {} void FakeProfileOAuth2TokenService::IssueAllTokensForAccount( - const std::string& account_id, + const CoreAccountId& account_id, const std::string& access_token, const base::Time& expiration) { GetFakeAccessTokenManager()->IssueAllTokensForAccount( @@ -34,14 +34,14 @@ } void FakeProfileOAuth2TokenService::IssueAllTokensForAccount( - const std::string& account_id, + const CoreAccountId& account_id, const OAuth2AccessTokenConsumer::TokenResponse& token_response) { GetFakeAccessTokenManager()->IssueAllTokensForAccount(account_id, token_response); } void FakeProfileOAuth2TokenService::IssueErrorForAllPendingRequestsForAccount( - const std::string& account_id, + const CoreAccountId& account_id, const GoogleServiceAuthError& error) { GetFakeAccessTokenManager()->IssueErrorForAllPendingRequestsForAccount( account_id, error);
diff --git a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.h b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.h index f06a83a..8245090 100644 --- a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.h +++ b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.h
@@ -47,17 +47,17 @@ GetPendingRequests(); // Helper routines to issue tokens for pending requests. - void IssueAllTokensForAccount(const std::string& account_id, + void IssueAllTokensForAccount(const CoreAccountId& account_id, const std::string& access_token, const base::Time& expiration); // Helper routines to issue token for pending requests based on TokenResponse. void IssueAllTokensForAccount( - const std::string& account_id, + const CoreAccountId& account_id, const OAuth2AccessTokenConsumer::TokenResponse& token_response); void IssueErrorForAllPendingRequestsForAccount( - const std::string& account_id, + const CoreAccountId& account_id, const GoogleServiceAuthError& error); void IssueTokenForScope(const OAuth2AccessTokenManager::ScopeSet& scopes,
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc index 0364fbc..7b6c3b8e 100644 --- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc +++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
@@ -837,10 +837,10 @@ } // Make a temporary copy of the account ids. - std::vector<std::string> accounts; + std::vector<CoreAccountId> accounts; for (const auto& token : refresh_tokens_) accounts.push_back(token.first); - for (const std::string& account : accounts) + for (const auto& account : accounts) RevokeCredentials(account); DCHECK_EQ(0u, refresh_tokens_.size());
diff --git a/components/signin/internal/identity_manager/primary_account_mutator_impl.cc b/components/signin/internal/identity_manager/primary_account_mutator_impl.cc index f9d1eba..85de348 100644 --- a/components/signin/internal/identity_manager/primary_account_mutator_impl.cc +++ b/components/signin/internal/identity_manager/primary_account_mutator_impl.cc
@@ -52,7 +52,7 @@ } #if defined(OS_CHROMEOS) -bool PrimaryAccountMutatorImpl::SetPrimaryAccountAndUpdateAccountInfo( +bool PrimaryAccountMutatorImpl::DeprecatedSetPrimaryAccountAndUpdateAccountInfo( const std::string& gaia_id, const std::string& email) { CoreAccountId account_id = account_tracker_->SeedAccountInfo(gaia_id, email);
diff --git a/components/signin/internal/identity_manager/primary_account_mutator_impl.h b/components/signin/internal/identity_manager/primary_account_mutator_impl.h index f15e6c1..91806ee4 100644 --- a/components/signin/internal/identity_manager/primary_account_mutator_impl.h +++ b/components/signin/internal/identity_manager/primary_account_mutator_impl.h
@@ -27,8 +27,9 @@ // PrimaryAccountMutator implementation. bool SetPrimaryAccount(const CoreAccountId& account_id) override; #if defined(OS_CHROMEOS) - bool SetPrimaryAccountAndUpdateAccountInfo(const std::string& gaia_id, - const std::string& email) override; + bool DeprecatedSetPrimaryAccountAndUpdateAccountInfo( + const std::string& gaia_id, + const std::string& email) override; #endif #if !defined(OS_CHROMEOS) bool ClearPrimaryAccount(
diff --git a/components/signin/public/identity_manager/README.md b/components/signin/public/identity_manager/README.md index b9bf55f..b1542f2 100644 --- a/components/signin/public/identity_manager/README.md +++ b/components/signin/public/identity_manager/README.md
@@ -8,12 +8,33 @@ Implementation files in this directory, however, are additionally allowed to depend on //components/signin/internal/identity_manager. -A quick guide through the core concepts: +Here we take a quick guide through the core concepts (note: Documentation on +specific IdentityManager and IdentityManager::Observer methods can be found as +method-level comments in identity_manager.h; this guide defines the core +concepts themselves and gives a high-level mapping between these core concepts +and the relevant IdentityManager(::Observer) API surfaces). +# Accounts - "Account" always refers to a Gaia account. -- "Primary account" in IdentityManager refers to what is called the - "authenticated account" in PrimaryAccountManager, i.e., the account that has - been blessed for sync by the user. +- An account has three core pieces of information, which are collected together + in the CoreAccountInfo struct and are available for the duration of the + account being visible to IdentityManager: + - The email address. + - The Gaia ID. + - The account ID. This is an opaque Chrome-specific identifier for the + account. +- The AccountInfo struct contains extra "extended" information about the account + that may become available only asynchronously after the account is first added + to Chrome. To interact with the extended account info, use the IdentityManager + methods with "ExtendedAccountInfo" in their names. To observe changes in the + state of the extended account info for one or more accounts, observe + IdentityManager and override one or more of the IdentityManager::Observer + methods with "ExtendedAccountInfo" in their names. + +# The Primary Account +- "Primary account" in IdentityManager refers to the account that has been + blessed for sync by the user (what in Chromium historically was often referred + to as the "authenticated account"). - "Unconsented primary account" is intuitively the browsing identity of the user that we display to the user; the user may or may not have blessed this account for sync. In particular, whenever a primary account exists, the unconsented @@ -25,6 +46,19 @@ "unconsented" in this context is that it means "did not consent"; really, this account is the "possibly unconsented, possibly primary, default account", which is a mouthful :). +- To interact with the primary account and/or unconsented primary account, use + the IdentityManager methods with "PrimaryAccount" in their names. To observe + changes in the presence of either of these accounts, observe IdentityManager + and override one or more of the methods with "PrimaryAccount" in their names + as desired. +- PrimaryAccountTokenFetcher is the primary client-side interface for obtaining + OAuth2 access tokens for the primary account (see the next section for the + discussion of OAuth2 tokens). In particular, it can handle the common use case + of "wait until the primary account is available and then fetch an access token + for it" transparently on behalf of the client. See + primary_account_access_token_fetcher.h for usage explanation and examples. + +# OAuth2 Access and Refresh Tokens - "OAuth2 tokens" are tokens related to the OAuth2 client-server authorization protocol. "OAuth2 refresh tokens" or just "refresh tokens" are long-lived tokens that the browser obtains via the user explicitly adding an account. @@ -37,12 +71,28 @@ signed in to the browser and embedder-level code then added the account to IdentityManager, or because the user has added an account at the system level that embedder-level code then made visible to IdentityManager). -- PrimaryAccountTokenFetcher is the primary client-side interface for obtaining - access tokens for the primary account. In particular, it can take care of - waiting until the primary account is available. + To interact with these accounts, use the IdentityManager methods with + "RefreshToken" in their name. To observe changes in the state of one or more + of these accounts, observe IdentityManager and override one or more of the + IdentityManager::Observer methods with "RefreshToken" in their name. - AccessTokenFetcher is the client-side interface for obtaining access tokens for arbitrary accounts; see access_token_fetcher.h for usage explanation and examples. + +# The Gaia Cookie +- "The Gaia cookie" refers to the cookie that contains the information of the + user's Gaia accounts that are available on the web. +- "The accounts in the Gaia cookie" and "the accounts in the cookie jar" refer to + the set of accounts in this cookie. To interact with these accounts, use the + IdentityManager methods with "Cookie" in their name. To observe changes in the + state of one or more of these accounts, observe IdentityManager and override + one or more of the IdentityManager::Observer methods with "Cookie" in their + name. Note that as the information that Chrome has about these accounts is + fundamentally different than that which Chrome has about the user's accounts + with OAuth2 refresh tokens, the struct encoding this information is also + distinct: see accounts_in_cookie_jar_info.h. + +# Interacting with IdentityManager and Friends in Tests - IdentityTestEnvironment is the preferred test infrastructure for unittests of production code that interacts with IdentityManager. It is suitable for use in cases where neither the production code nor the unittest is interacting @@ -56,11 +106,18 @@ tests and Profile-based unittests (in the latter case, consider migrating the test and production code away from using Profile directly and using IdentityTestEnvironment). + +# Mutation of Account State - Various mutators of account state are available through IdentityManager (e.g., PrimaryAccountMutator). These should in general be used only as part of larger embedder-specific flows for mutating the user's account state in ways that are - in line with product specifications. + in line with product specifications. If you are a consumer of + //components/identity/public/identity_manager and you believe that you have a + new use case for one of these API surfaces, you should first contact the + OWNERS of //components/signin to discuss this use case and how best to realize + it. +# Mental Mapping from Chromium's Historical API Surfaces for Signin Documentation on the mapping between usage of legacy signin classes (notably PrimaryAccountManager and ProfileOAuth2TokenService) and usage of IdentityManager is available here:
diff --git a/components/signin/public/identity_manager/access_token_fetcher.h b/components/signin/public/identity_manager/access_token_fetcher.h index 4318c9c..5f7f75d3 100644 --- a/components/signin/public/identity_manager/access_token_fetcher.h +++ b/components/signin/public/identity_manager/access_token_fetcher.h
@@ -92,6 +92,7 @@ // access_token_fetcher_ = // identity_manager_->CreateAccessTokenFetcherForAccount( // account_id, /*consumer_name=*/"MyClass", +// scopes, // base::BindOnce(&MyClass::OnAccessTokenRequestCompleted, // // It is safe to use base::Unretained as // // |this| owns |access_token_fetcher_|.
diff --git a/components/signin/public/identity_manager/accounts_mutator_unittest.cc b/components/signin/public/identity_manager/accounts_mutator_unittest.cc index 98669f6..8db42ec0 100644 --- a/components/signin/public/identity_manager/accounts_mutator_unittest.cc +++ b/components/signin/public/identity_manager/accounts_mutator_unittest.cc
@@ -148,7 +148,8 @@ AccountInfo account_info = identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) .value(); EXPECT_EQ(account_info.account_id, account_id); EXPECT_EQ(account_info.email, kTestEmail); @@ -180,7 +181,8 @@ account_id)); AccountInfo account_info = identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) .value(); EXPECT_EQ(account_info.account_id, account_id); EXPECT_EQ(account_info.email, kTestEmail); @@ -218,7 +220,8 @@ EXPECT_EQ(identity_manager()->GetAccountsWithRefreshTokens().size(), 1U); AccountInfo updated_account_info = identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) .value(); EXPECT_EQ(account_info.account_id, updated_account_info.account_id); EXPECT_EQ(account_info.gaia, updated_account_info.gaia); @@ -252,7 +255,8 @@ AccountInfo original_account_info = identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) .value(); EXPECT_EQ(original_account_info.account_id, account_id); EXPECT_EQ(original_account_info.email, kTestEmail); @@ -265,7 +269,8 @@ /*is_under_advanced_protection=*/base::nullopt); AccountInfo updated_account_info_1 = identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) .value(); // Only |is_child_account| changed so far, everything else remains the same. @@ -283,7 +288,8 @@ /*is_under_advanced_protection=*/true); AccountInfo updated_account_info_2 = identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) .value(); // |is_under_advanced_protection| has changed now, but |is_child_account| @@ -303,7 +309,8 @@ /*is_under_advanced_protection=*/false); AccountInfo reset_account_info = identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) .value(); // Everything is back to its original state now. @@ -377,7 +384,8 @@ AccountInfo secondary_account_info = identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id) .value(); EXPECT_EQ(identity_manager()->GetAccountsWithRefreshTokens().size(), 2U); @@ -617,9 +625,10 @@ // In the context of supervised users, the ProfileOAuth2TokenService is used // without the AccountTrackerService being used, so we can't use any of the - // IdentityManager::FindAccountInfoForAccountWithRefreshTokenBy*() methods - // since they won't find any account. Use GetAccountsWithRefreshTokens() and - // HasAccountWithRefreshToken*() instead, that only relies in the PO2TS. + // IdentityManager::FindExtendedAccountInfoForAccountWithRefreshTokenBy*() + // methods since they won't find any account. Use + // GetAccountsWithRefreshTokens() and HasAccountWithRefreshToken*() instead, + // that only relies in the PO2TS. std::vector<CoreAccountInfo> accounts = identity_manager()->GetAccountsWithRefreshTokens(); EXPECT_EQ(accounts.size(), 1U);
diff --git a/components/signin/public/identity_manager/identity_manager.cc b/components/signin/public/identity_manager/identity_manager.cc index de180ab..e7e6e90b 100644 --- a/components/signin/public/identity_manager/identity_manager.cc +++ b/components/signin/public/identity_manager/identity_manager.cc
@@ -281,7 +281,8 @@ return token_service_->GetAuthError(account_id); } -base::Optional<AccountInfo> IdentityManager::FindExtendedAccountInfoForAccount( +base::Optional<AccountInfo> +IdentityManager::FindExtendedAccountInfoForAccountWithRefreshToken( const CoreAccountInfo& account_info) const { AccountInfo extended_account_info = account_tracker_service_->GetAccountInfo(account_info.account_id); @@ -296,7 +297,7 @@ } base::Optional<AccountInfo> -IdentityManager::FindAccountInfoForAccountWithRefreshTokenByAccountId( +IdentityManager::FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( const CoreAccountId& account_id) const { AccountInfo account_info = account_tracker_service_->GetAccountInfo(account_id); @@ -310,9 +311,9 @@ return GetAccountInfoForAccountWithRefreshToken(account_info.account_id); } -base::Optional<AccountInfo> -IdentityManager::FindAccountInfoForAccountWithRefreshTokenByEmailAddress( - const std::string& email_address) const { +base::Optional<AccountInfo> IdentityManager:: + FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( + const std::string& email_address) const { AccountInfo account_info = account_tracker_service_->FindAccountInfoByEmail(email_address); @@ -326,7 +327,7 @@ } base::Optional<AccountInfo> -IdentityManager::FindAccountInfoForAccountWithRefreshTokenByGaiaId( +IdentityManager::FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId( const std::string& gaia_id) const { AccountInfo account_info = account_tracker_service_->FindAccountInfoByGaiaId(gaia_id);
diff --git a/components/signin/public/identity_manager/identity_manager.h b/components/signin/public/identity_manager/identity_manager.h index 91d91bf..52f4d3c 100644 --- a/components/signin/public/identity_manager/identity_manager.h +++ b/components/signin/public/identity_manager/identity_manager.h
@@ -265,7 +265,7 @@ // Returns extended information for account identified by |account_info|. // The information will be returned if the information is available and // refresh token is available for account. - base::Optional<AccountInfo> FindExtendedAccountInfoForAccount( + base::Optional<AccountInfo> FindExtendedAccountInfoForAccountWithRefreshToken( const CoreAccountInfo& account_info) const; // Looks up and returns information for account with given |account_id|. If @@ -273,7 +273,7 @@ // to searching on the vector returned by GetAccountsWithRefreshTokens() but // without allocating memory for the vector. base::Optional<AccountInfo> - FindAccountInfoForAccountWithRefreshTokenByAccountId( + FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( const CoreAccountId& account_id) const; // Looks up and returns information for account with given |email_address|. If @@ -281,14 +281,15 @@ // to searching on the vector returned by GetAccountsWithRefreshTokens() but // without allocating memory for the vector. base::Optional<AccountInfo> - FindAccountInfoForAccountWithRefreshTokenByEmailAddress( + FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( const std::string& email_address) const; // Looks up and returns information for account with given |gaia_id|. If the // account cannot be found, return an empty optional. This is equivalent to // searching on the vector returned by GetAccountsWithRefreshTokens() but // without allocating memory for the vector. - base::Optional<AccountInfo> FindAccountInfoForAccountWithRefreshTokenByGaiaId( + base::Optional<AccountInfo> + FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId( const std::string& gaia_id) const; // Creates an UbertokenFetcher given the passed-in information, allowing @@ -498,13 +499,13 @@ const std::string& email, const std::string& gaia_id); friend void SetRefreshTokenForAccount(IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const std::string& token_value); friend void SetInvalidRefreshTokenForAccount( IdentityManager* identity_manager, - const std::string& account_id); + const CoreAccountId& account_id); friend void RemoveRefreshTokenForAccount(IdentityManager* identity_manager, - const std::string& account_id); + const CoreAccountId& account_id); friend void UpdateAccountInfoForAccount(IdentityManager* identity_manager, AccountInfo account_info); friend void SetFreshnessOfAccountsInGaiaCookie( @@ -512,7 +513,7 @@ bool accounts_are_fresh); friend void UpdatePersistentErrorOfRefreshTokenForAccount( IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const GoogleServiceAuthError& auth_error); friend void DisableAccessTokenFetchRetries(IdentityManager* identity_manager); @@ -527,7 +528,7 @@ friend void SimulateSuccessfulFetchOfAccountInfo( IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const std::string& email, const std::string& gaia, const std::string& hosted_domain,
diff --git a/components/signin/public/identity_manager/identity_manager_unittest.cc b/components/signin/public/identity_manager/identity_manager_unittest.cc index 98a486f..9416681 100644 --- a/components/signin/public/identity_manager/identity_manager_unittest.cc +++ b/components/signin/public/identity_manager/identity_manager_unittest.cc
@@ -2047,11 +2047,11 @@ identity_manager_observer()->BatchChangeRecords().at(0).at(0)); } -// Checks that FindAccountInfoForAccountWithRefreshTokenByAccountId() returns -// information about the account if the account is found or nullopt if there -// are no accounts with requested |account_id|. +// Checks that FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId() +// returns information about the account if the account is found or nullopt if +// there are no accounts with requested |account_id|. TEST_F(IdentityManagerTest, - FindAccountInfoForAccountWithRefreshTokenByAccountId) { + FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId) { // Add an account (note: cannot use kTestEmail as it is already inserted // by the fixture common code, so use a different address). const AccountInfo foo_account_info = @@ -2059,24 +2059,26 @@ base::Optional<AccountInfo> maybe_account_info; maybe_account_info = - identity_manager()->FindAccountInfoForAccountWithRefreshTokenByAccountId( - "dummy_value"); + identity_manager() + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + "dummy_value"); EXPECT_FALSE(maybe_account_info.has_value()); maybe_account_info = - identity_manager()->FindAccountInfoForAccountWithRefreshTokenByAccountId( - foo_account_info.account_id); + identity_manager() + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + foo_account_info.account_id); EXPECT_TRUE(maybe_account_info.has_value()); EXPECT_EQ(foo_account_info.account_id, maybe_account_info.value().account_id); EXPECT_EQ(foo_account_info.email, maybe_account_info.value().email); EXPECT_EQ(foo_account_info.gaia, maybe_account_info.value().gaia); } -// Checks that FindAccountInfoForAccountWithRefreshTokenByEmailAddress() returns -// information about the account if the account is found or nullopt if there -// are no accounts with requested |email_address|. +// Checks that FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress() +// returns information about the account if the account is found or nullopt if +// there are no accounts with requested |email_address|. TEST_F(IdentityManagerTest, - FindAccountInfoForAccountWithRefreshTokenByEmailAddress) { + FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress) { // Add an account (note: cannot use kTestEmail as it is already inserted // by the fixture common code, so use a different address). const AccountInfo foo_account_info = @@ -2085,13 +2087,13 @@ base::Optional<AccountInfo> maybe_account_info; maybe_account_info = identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress( + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( "dummy_value"); EXPECT_FALSE(maybe_account_info.has_value()); maybe_account_info = identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress( + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( foo_account_info.email); EXPECT_TRUE(maybe_account_info.has_value()); EXPECT_EQ(foo_account_info.account_id, maybe_account_info.value().account_id); @@ -2099,10 +2101,11 @@ EXPECT_EQ(foo_account_info.gaia, maybe_account_info.value().gaia); } -// Checks that FindAccountInfoForAccountWithRefreshTokenByGaiaId() returns -// information about the account if the account is found or nullopt if there -// are no accounts with requested |gaia_id|. -TEST_F(IdentityManagerTest, FindAccountInfoForAccountWithRefreshTokenByGaiaId) { +// Checks that FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId() +// returns information about the account if the account is found or nullopt if +// there are no accounts with requested |gaia_id|. +TEST_F(IdentityManagerTest, + FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId) { // Add an account (note: cannot use kTestEmail as it is already inserted // by the fixture common code, so use a different address). const AccountInfo foo_account_info = @@ -2110,13 +2113,15 @@ base::Optional<AccountInfo> maybe_account_info; maybe_account_info = - identity_manager()->FindAccountInfoForAccountWithRefreshTokenByGaiaId( - "dummy_value"); + identity_manager() + ->FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId( + "dummy_value"); EXPECT_FALSE(maybe_account_info.has_value()); maybe_account_info = - identity_manager()->FindAccountInfoForAccountWithRefreshTokenByGaiaId( - foo_account_info.gaia); + identity_manager() + ->FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId( + foo_account_info.gaia); EXPECT_TRUE(maybe_account_info.has_value()); EXPECT_EQ(foo_account_info.account_id, maybe_account_info.value().account_id); EXPECT_EQ(foo_account_info.email, maybe_account_info.value().email); @@ -2207,47 +2212,51 @@ } } -// Check that FindExtendedAccountInfoForAccount returns a valid account info -// iff the account is known, has refresh token and all the extended information -// is available. -TEST_F(IdentityManagerTest, FindExtendedAccountInfoForAccount) { +// Check that FindExtendedAccountInfoForAccountWithRefreshToken returns a valid +// account info iff the account is known, has refresh token and all the extended +// information is available. +TEST_F(IdentityManagerTest, FindExtendedAccountInfoForAccountWithRefreshToken) { CoreAccountInfo account_info; account_info.email = kTestEmail; account_info.gaia = kTestGaiaId; account_info.account_id = identity_manager()->PickAccountIdForAccount(kTestGaiaId, kTestEmail); - // FindExtendedAccountInfoForAccount() returns empty optional if the - // account_info is invalid. - EXPECT_FALSE(identity_manager() - ->FindExtendedAccountInfoForAccount(CoreAccountInfo{}) - .has_value()); + // FindExtendedAccountInfoForAccountWithRefreshToken() returns empty optional + // if the account_info is invalid. + EXPECT_FALSE( + identity_manager() + ->FindExtendedAccountInfoForAccountWithRefreshToken(CoreAccountInfo{}) + .has_value()); - // FindExtendedAccountInfoForAccount() returns empty optional if the - // account_info is unknown. - EXPECT_FALSE(identity_manager() - ->FindExtendedAccountInfoForAccount(account_info) - .has_value()); + // FindExtendedAccountInfoForAccountWithRefreshToken() returns empty optional + // if the account_info is unknown. + EXPECT_FALSE( + identity_manager() + ->FindExtendedAccountInfoForAccountWithRefreshToken(account_info) + .has_value()); // Insert the core account information in the AccountTrackerService. const CoreAccountId account_id = account_tracker()->SeedAccountInfo(kTestGaiaId, kTestEmail); ASSERT_EQ(account_info.account_id, account_id); - // FindExtendedAccountInfoForAccount() returns empty optional if the account - // has no refresh token. - EXPECT_FALSE(identity_manager() - ->FindExtendedAccountInfoForAccount(account_info) - .has_value()); + // FindExtendedAccountInfoForAccountWithRefreshToken() returns empty optional + // if the account has no refresh token. + EXPECT_FALSE( + identity_manager() + ->FindExtendedAccountInfoForAccountWithRefreshToken(account_info) + .has_value()); // Insert refresh token for account. SetRefreshTokenForAccount(identity_manager(), account_info.account_id, "refresh-token"); - // FindExtendedAccountInfoForAccount() returns extended account information if - // the account is known and has valid refresh token. + // FindExtendedAccountInfoForAccountWithRefreshToken() returns extended + // account information if the account is known and has valid refresh token. const base::Optional<AccountInfo> extended_account_info = - identity_manager()->FindExtendedAccountInfoForAccount(account_info); + identity_manager()->FindExtendedAccountInfoForAccountWithRefreshToken( + account_info); ASSERT_TRUE(extended_account_info.has_value()); EXPECT_EQ(account_info.gaia, extended_account_info.value().gaia);
diff --git a/components/signin/public/identity_manager/identity_test_environment.cc b/components/signin/public/identity_manager/identity_test_environment.cc index 6c03341..08026c7a 100644 --- a/components/signin/public/identity_manager/identity_test_environment.cc +++ b/components/signin/public/identity_manager/identity_test_environment.cc
@@ -461,7 +461,7 @@ } void IdentityTestEnvironment::ReloadAccountsFromDisk() { - fake_token_service()->LoadCredentials(""); + fake_token_service()->LoadCredentials(CoreAccountId()); } bool IdentityTestEnvironment::IsAccessTokenRequestPending() {
diff --git a/components/signin/public/identity_manager/identity_test_environment.h b/components/signin/public/identity_manager/identity_test_environment.h index 3b5efc73..76aeeff 100644 --- a/components/signin/public/identity_manager/identity_test_environment.h +++ b/components/signin/public/identity_manager/identity_test_environment.h
@@ -287,7 +287,7 @@ kPending, kAvailable, } state; - base::Optional<std::string> account_id; + base::Optional<CoreAccountId> account_id; base::OnceClosure on_available; };
diff --git a/components/signin/public/identity_manager/identity_test_utils.cc b/components/signin/public/identity_manager/identity_test_utils.cc index 1cbd39b1..bf0617f 100644 --- a/components/signin/public/identity_manager/identity_test_utils.cc +++ b/components/signin/public/identity_manager/identity_test_utils.cc
@@ -51,7 +51,7 @@ ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const std::string& new_token) { DCHECK_EQ(account_tracker_service->GetAccountInfo(account_id).account_id, account_id) @@ -106,14 +106,14 @@ void SetRefreshTokenForPrimaryAccount(IdentityManager* identity_manager, const std::string& token_value) { DCHECK(identity_manager->HasPrimaryAccount()); - std::string account_id = identity_manager->GetPrimaryAccountId(); + CoreAccountId account_id = identity_manager->GetPrimaryAccountId(); SetRefreshTokenForAccount(identity_manager, account_id, token_value); } void SetInvalidRefreshTokenForPrimaryAccount( IdentityManager* identity_manager) { DCHECK(identity_manager->HasPrimaryAccount()); - std::string account_id = identity_manager->GetPrimaryAccountId(); + CoreAccountId account_id = identity_manager->GetPrimaryAccountId(); SetInvalidRefreshTokenForAccount(identity_manager, account_id); } @@ -122,7 +122,7 @@ if (!identity_manager->HasPrimaryAccount()) return; - std::string account_id = identity_manager->GetPrimaryAccountId(); + CoreAccountId account_id = identity_manager->GetPrimaryAccountId(); RemoveRefreshTokenForAccount(identity_manager, account_id); } @@ -132,8 +132,9 @@ CoreAccountInfo account_info = SetPrimaryAccount(identity_manager, email); SetRefreshTokenForPrimaryAccount(identity_manager); base::Optional<AccountInfo> primary_account_info = - identity_manager->FindAccountInfoForAccountWithRefreshTokenByAccountId( - account_info.account_id); + identity_manager + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_info.account_id); // Ensure that extended information for the account is available after setting // the refresh token. DCHECK(primary_account_info.has_value()); @@ -235,17 +236,17 @@ } void SetRefreshTokenForAccount(IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const std::string& token_value) { UpdateRefreshTokenForAccount( identity_manager->GetTokenService(), identity_manager->GetAccountTrackerService(), identity_manager, account_id, - token_value.empty() ? "refresh_token_for_" + account_id : token_value); + token_value.empty() ? "refresh_token_for_" + account_id.id : token_value); } void SetInvalidRefreshTokenForAccount(IdentityManager* identity_manager, - const std::string& account_id) { + const CoreAccountId& account_id) { UpdateRefreshTokenForAccount(identity_manager->GetTokenService(), identity_manager->GetAccountTrackerService(), @@ -254,7 +255,7 @@ } void RemoveRefreshTokenForAccount(IdentityManager* identity_manager, - const std::string& account_id) { + const CoreAccountId& account_id) { if (!identity_manager->HasAccountWithRefreshToken(account_id)) return; @@ -327,7 +328,7 @@ void UpdatePersistentErrorOfRefreshTokenForAccount( IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const GoogleServiceAuthError& auth_error) { DCHECK(identity_manager->HasAccountWithRefreshToken(account_id)); identity_manager->GetTokenService()->GetDelegate()->UpdateAuthError( @@ -351,7 +352,7 @@ } void SimulateSuccessfulFetchOfAccountInfo(IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const std::string& email, const std::string& gaia, const std::string& hosted_domain,
diff --git a/components/signin/public/identity_manager/identity_test_utils.h b/components/signin/public/identity_manager/identity_test_utils.h index c7842e60..9b01460 100644 --- a/components/signin/public/identity_manager/identity_test_utils.h +++ b/components/signin/public/identity_manager/identity_test_utils.h
@@ -115,21 +115,21 @@ // value will be used instead. // NOTE: See disclaimer at top of file re: direct usage. void SetRefreshTokenForAccount(IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const std::string& token_value = std::string()); // Sets a special invalid refresh token for the given account (which must // already be available). Blocks until the refresh token is set. // NOTE: See disclaimer at top of file re: direct usage. void SetInvalidRefreshTokenForAccount(IdentityManager* identity_manager, - const std::string& account_id); + const CoreAccountId& account_id); // Removes any refresh token that is present for the given account. Blocks until // the refresh token is removed. Is a no-op if no refresh token is present for // the given account. // NOTE: See disclaimer at top of file re: direct usage. void RemoveRefreshTokenForAccount(IdentityManager* identity_manager, - const std::string& account_id); + const CoreAccountId& account_id); // Puts the given accounts into the Gaia cookie, replacing any previous // accounts. Blocks until the accounts have been set. @@ -157,7 +157,7 @@ // account, i.e., an account with a refresh token. void UpdatePersistentErrorOfRefreshTokenForAccount( IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const GoogleServiceAuthError& auth_error); // Disables internal retries of failed access token fetches. @@ -174,7 +174,7 @@ // Simulate account fetching using AccountTrackerService without sending // network requests. void SimulateSuccessfulFetchOfAccountInfo(IdentityManager* identity_manager, - const std::string& account_id, + const CoreAccountId& account_id, const std::string& email, const std::string& gaia, const std::string& hosted_domain,
diff --git a/components/signin/public/identity_manager/primary_account_access_token_fetcher.h b/components/signin/public/identity_manager/primary_account_access_token_fetcher.h index 68436bc1..a11688f 100644 --- a/components/signin/public/identity_manager/primary_account_access_token_fetcher.h +++ b/components/signin/public/identity_manager/primary_account_access_token_fetcher.h
@@ -19,11 +19,116 @@ namespace signin { struct AccessTokenInfo; -// Helper class to ease the task of obtaining an OAuth2 access token for the -// authenticated account. This handles various special cases, e.g. when the -// refresh token isn't loaded yet (during startup), or when there is some -// transient error. -// May only be used on the UI thread. +// Class that supports obtaining OAuth2 access tokens for the user's primary +// account.See ./README.md for the definition of "accounts with OAuth2 refresh +// tokens" and "primary account". +// +// The usage model of this class is as follows: When a +// PrimaryAccountAccessTokenFetcher is created, it will make an access token +// request for the primary account (either immediately or if/once the primary +// account becomes available, based on the value of the specified |Mode| +// parameter). When the access token request is fulfilled the +// PrimaryAccountAccessTokenFetcher will call the specified callback, at which +// point it is safe for the caller to destroy the object. If the object is +// destroyed before the request is fulfilled the request is dropped and the +// callback will never be invoked. This class may only be used on the UI thread. +// +// To drive responses to access token fetches in unittests of clients of this +// class, use IdentityTestEnvironment. +// +// Concrete usage example (related concrete test example follows): +// class MyClass { +// public: +// MyClass(IdentityManager* identity_manager) : +// identity_manager_(identity_manager) { +// // An access token request could also be initiated at any arbitrary +// // point in the lifetime of |MyClass|. +// StartAccessTokenRequestForPrimaryAccount(); +// } +// +// +// ~MyClass() { +// // If the access token request is still live, the destruction of +// |access_token_fetcher_| will cause it to be dropped. +// } +// +// private: +// IdentityManager* identity_manager_; +// std::unique_ptr<PrimaryAccountAccessTokenFetcher> access_token_fetcher_; +// std::string access_token_; +// GoogleServiceAuthError access_token_request_error_; +// +// // Most commonly invoked as part of some larger flow to hit a Gaia +// // endpoint for a client-specific purpose (e.g., hitting sync +// // endpoints). +// // Could also be public, but in general, any clients that would need to +// // create access token requests could and should just create +// // PrimaryAccountAccessTokenFetchers directly themselves rather than +// // introducing wrapper API surfaces. +// MyClass::StartAccessTokenRequestForPrimaryAccount() { +// // Choose scopes to obtain for the access token. +// identity::ScopeSet scopes; +// scopes.insert(GaiaConstants::kMyFirstScope); +// scopes.insert(GaiaConstants::kMySecondScope); + +// // Choose the mode in which to fetch the access token: +// // see AccessTokenFetcher::Mode below for definitions. +// auto mode = +// signin::PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable; + +// // Create the fetcher. +// access_token_fetcher_ = +// std::make_unique<PrimaryAccountAccessTokenFetcher( +// /*consumer_name=*/"MyClass", +// identity_manager_, +// scopes, +// base::BindOnce(&MyClass::OnAccessTokenRequestCompleted, +// // It is safe to use base::Unretained as +// // |this| owns |access_token_fetcher_|. +// base::Unretained(this)), +// mode); +// +// } +// MyClass::OnAccessTokenRequestCompleted( +// GoogleServiceAuthError error, AccessTokenInfo access_token_info) { +// // It is safe to destroy |access_token_fetcher_| from this callback. +// access_token_fetcher_.reset(); +// +// if (error.state() == GoogleServiceAuthError::NONE) { +// // The fetcher successfully obtained an access token. +// access_token_ = access_token_info.token; +// // MyClass can now take whatever action required having an access +// // token (e.g.,hitting a given Gaia endpoint). +// ... +// } else { +// // The fetcher failed to obtain a token; |error| specifies why. +// access_token_request_error_ = error; +// // MyClass can now perform any desired error handling. +// ... +// } +// } +// } +// +// Concrete test example: +// TEST(MyClassTest, SuccessfulAccessTokenFetchForPrimaryAccount) { +// IdentityTestEnvironment identity_test_env; +// +// +// MyClass my_class(identity_test_env.identity_manager()); +// +// // Make the primary account available, which should result in an access +// // token fetch being made on behalf of |my_class|. +// identity_test_env.MakePrimaryAccountAvailable("test_email"); +// +// identity_test_env. +// WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( +// "access_token", base::Time::Max()); +// +// // MyClass::OnAccessTokenRequestCompleted() will have been invoked with +// // an AccessTokenInfo object containing the above-specified parameters; +// // the test can now perform any desired validation of expected actions +// // |MyClass| took in response. +// } class PrimaryAccountAccessTokenFetcher : public IdentityManager::Observer { public: // Specifies how this instance should behave:
diff --git a/components/signin/public/identity_manager/primary_account_mutator.h b/components/signin/public/identity_manager/primary_account_mutator.h index 94755ef..452335d11 100644 --- a/components/signin/public/identity_manager/primary_account_mutator.h +++ b/components/signin/public/identity_manager/primary_account_mutator.h
@@ -64,9 +64,8 @@ // account is known by IdentityManager. The reason is that there are // contexts on ChromeOS where the primary account is not guaranteed to be // known by IdentityManager when it is set. - // TODO(https://crbug.com/967605): Port callers to SetPrimaryAccount() once - // https://crbug.com/867602 is fixed. - virtual bool SetPrimaryAccountAndUpdateAccountInfo( + // TODO(https://crbug.com/987955): Remove this API. + virtual bool DeprecatedSetPrimaryAccountAndUpdateAccountInfo( const std::string& gaia_id, const std::string& email) = 0; #endif
diff --git a/components/sync/driver/configure_context.h b/components/sync/driver/configure_context.h index e0fd922..b144a526 100644 --- a/components/sync/driver/configure_context.h +++ b/components/sync/driver/configure_context.h
@@ -9,6 +9,7 @@ #include "components/sync/base/storage_option.h" #include "components/sync/engine/configure_reason.h" +#include "google_apis/gaia/core_account_id.h" namespace syncer { @@ -19,7 +20,7 @@ // controllers, which for USS datatypes propagate analogous information to the // processor/bridge via DataTypeActivationRequest. struct ConfigureContext { - std::string authenticated_account_id; + CoreAccountId authenticated_account_id; std::string cache_guid; StorageOption storage_option = STORAGE_ON_DISK; ConfigureReason reason = CONFIGURE_REASON_UNKNOWN;
diff --git a/components/sync/driver/glue/sync_engine_backend.h b/components/sync/driver/glue/sync_engine_backend.h index d65cef64..05ed14d6 100644 --- a/components/sync/driver/glue/sync_engine_backend.h +++ b/components/sync/driver/glue/sync_engine_backend.h
@@ -222,7 +222,7 @@ std::unique_ptr<SyncManager> sync_manager_; // Required for |nigori_controller_| LoadModels(). - std::string authenticated_account_id_; + CoreAccountId authenticated_account_id_; // Initialized in OnInitializationComplete() iff USS implementation of Nigori // is enabled.
diff --git a/components/sync/driver/profile_sync_service.cc b/components/sync/driver/profile_sync_service.cc index 2484f3f..29b68e56 100644 --- a/components/sync/driver/profile_sync_service.cc +++ b/components/sync/driver/profile_sync_service.cc
@@ -1492,7 +1492,7 @@ bool ProfileSyncService::HasCookieJarMismatch( const std::vector<gaia::ListedAccount>& cookie_jar_accounts) { - std::string account_id = GetAuthenticatedAccountInfo().account_id; + CoreAccountId account_id = GetAuthenticatedAccountInfo().account_id; // Iterate through list of accounts, looking for current sync account. for (const auto& account : cookie_jar_accounts) { if (account.id == account_id)
diff --git a/components/sync/engine/net/http_bridge_unittest.cc b/components/sync/engine/net/http_bridge_unittest.cc index 22d9652..cf840a3 100644 --- a/components/sync/engine/net/http_bridge_unittest.cc +++ b/components/sync/engine/net/http_bridge_unittest.cc
@@ -10,7 +10,7 @@ #include "base/bind.h" #include "base/bit_cast.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" @@ -53,7 +53,7 @@ void SetUp() override { base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; io_thread_.StartWithOptions(options); HttpBridge::SetIOCapableTaskRunnerForTest(io_thread_.task_runner());
diff --git a/components/sync/engine/sync_credentials.h b/components/sync/engine/sync_credentials.h index 2ab1830..bfa46e79 100644 --- a/components/sync/engine/sync_credentials.h +++ b/components/sync/engine/sync_credentials.h
@@ -7,6 +7,8 @@ #include <string> +#include "google_apis/gaia/core_account_id.h" + namespace syncer { // Contains everything needed to talk to and identify a user account. @@ -16,7 +18,7 @@ ~SyncCredentials(); // Account_id of signed in account. - std::string account_id; + CoreAccountId account_id; // The email associated with this account. std::string email;
diff --git a/components/sync/engine/sync_engine.h b/components/sync/engine/sync_engine.h index 8d53e56..5dd622e 100644 --- a/components/sync/engine/sync_engine.h +++ b/components/sync/engine/sync_engine.h
@@ -62,7 +62,7 @@ GURL service_url; std::string sync_user_agent; SyncEngine::HttpPostProviderFactoryGetter http_factory_getter; - std::string authenticated_account_id; + CoreAccountId authenticated_account_id; std::string invalidator_client_id; std::unique_ptr<SyncManagerFactory> sync_manager_factory; bool delete_sync_data_folder = false;
diff --git a/components/sync/engine/sync_manager.h b/components/sync/engine/sync_manager.h index 4fe4dbb..9a24a85 100644 --- a/components/sync/engine/sync_manager.h +++ b/components/sync/engine/sync_manager.h
@@ -219,7 +219,7 @@ // Must outlive SyncManager. ChangeDelegate* change_delegate; - std::string authenticated_account_id; + CoreAccountId authenticated_account_id; // Unqiuely identifies this client to the invalidation notification server. std::string invalidator_client_id;
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc index 43f420a..92108c4 100644 --- a/components/sync/engine_impl/sync_manager_impl.cc +++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -332,7 +332,7 @@ std::unique_ptr<syncable::DirectoryBackingStore> backing_store = args->engine_components_factory->BuildDirectoryBackingStore( EngineComponentsFactory::STORAGE_ON_DISK, - args->authenticated_account_id, cache_guid_generator, + args->authenticated_account_id.id, cache_guid_generator, absolute_db_path); DCHECK(backing_store); @@ -505,7 +505,7 @@ MakeWeakHandle(js_mutation_event_observer_.AsWeakPtr())); syncable::DirOpenResult open_result = syncable::NOT_INITIALIZED; - open_result = directory()->Open(args->authenticated_account_id, this, + open_result = directory()->Open(args->authenticated_account_id.id, this, transaction_observer); if (open_result != syncable::OPENED_NEW && open_result != syncable::OPENED_EXISTING) {
diff --git a/components/sync/model/data_type_activation_request.h b/components/sync/model/data_type_activation_request.h index f842ac47..75f0130 100644 --- a/components/sync/model/data_type_activation_request.h +++ b/components/sync/model/data_type_activation_request.h
@@ -10,6 +10,7 @@ #include "base/time/time.h" #include "components/sync/base/storage_option.h" #include "components/sync/model/model_error.h" +#include "google_apis/gaia/core_account_id.h" namespace syncer { @@ -26,7 +27,7 @@ DataTypeActivationRequest& operator=(DataTypeActivationRequest&& request); ModelErrorHandler error_handler; - std::string authenticated_account_id; + CoreAccountId authenticated_account_id; std::string cache_guid; StorageOption storage_option = STORAGE_ON_DISK;
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.cc b/components/sync/model_impl/client_tag_based_model_type_processor.cc index 984bff9..6c03e3b 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor.cc
@@ -201,8 +201,9 @@ } // Cache GUID verification earlier above guarantees the user is the same. + // TODO(https://crbug.com/959157): Use CoreAccountId instead of std::string. model_type_state_.set_authenticated_account_id( - activation_request_.authenticated_account_id); + activation_request_.authenticated_account_id.id); // For commit-only types, no updates are expected and hence we can consider // initial_sync_done(), reflecting that sync is enabled.
diff --git a/components/sync/nigori/nigori_model_type_processor.cc b/components/sync/nigori/nigori_model_type_processor.cc index 4b7ab4e..846c3be 100644 --- a/components/sync/nigori/nigori_model_type_processor.cc +++ b/components/sync/nigori/nigori_model_type_processor.cc
@@ -408,8 +408,9 @@ } // Cache GUID verification earlier above guarantees the user is the same. + // TODO(https://crbug.com/959157): Use CoreAccountId instead of std::string. model_type_state_.set_authenticated_account_id( - activation_request_.authenticated_account_id); + activation_request_.authenticated_account_id.id); auto activation_response = std::make_unique<DataTypeActivationResponse>(); activation_response->model_type_state = model_type_state_;
diff --git a/components/sync_device_info/fake_device_info_tracker.cc b/components/sync_device_info/fake_device_info_tracker.cc index c13f12d..6891365f 100644 --- a/components/sync_device_info/fake_device_info_tracker.cc +++ b/components/sync_device_info/fake_device_info_tracker.cc
@@ -34,7 +34,11 @@ std::unique_ptr<DeviceInfo> FakeDeviceInfoTracker::GetDeviceInfo( const std::string& client_id) const { - NOTREACHED(); + for (const DeviceInfo* device : devices_) { + if (device->guid() == client_id) { + return CloneDeviceInfo(*device); + } + } return nullptr; } @@ -66,12 +70,7 @@ bool FakeDeviceInfoTracker::IsRecentLocalCacheGuid( const std::string& cache_guid) const { - for (const DeviceInfo* device : devices_) { - if (device->guid() == cache_guid) { - return true; - } - } - return false; + return (local_device_cache_guid_ == cache_guid); } void FakeDeviceInfoTracker::Add(const DeviceInfo* device) { @@ -82,4 +81,10 @@ active_device_count_ = count; } +void FakeDeviceInfoTracker::SetLocalCacheGuid(const std::string& cache_guid) { + // ensure that this cache guid is present in the tracker. + DCHECK(GetDeviceInfo(cache_guid)); + local_device_cache_guid_ = cache_guid; +} + } // namespace syncer
diff --git a/components/sync_device_info/fake_device_info_tracker.h b/components/sync_device_info/fake_device_info_tracker.h index d9fa2d27..7c30f82 100644 --- a/components/sync_device_info/fake_device_info_tracker.h +++ b/components/sync_device_info/fake_device_info_tracker.h
@@ -41,9 +41,13 @@ // actual number of devices in |devices_|. void OverrideActiveDeviceCount(int count); + // Marks an existing DeviceInfo entry as being on the local device. + void SetLocalCacheGuid(const std::string& cache_guid); + private: // DeviceInfo stored here are not owned. std::vector<const DeviceInfo*> devices_; + std::string local_device_cache_guid_; base::Optional<int> active_device_count_; DISALLOW_COPY_AND_ASSIGN(FakeDeviceInfoTracker);
diff --git a/components/version_ui/resources/about_version.html b/components/version_ui/resources/about_version.html index 427bb0af..9441e42 100644 --- a/components/version_ui/resources/about_version.html +++ b/components/version_ui/resources/about_version.html
@@ -22,6 +22,7 @@ <script src="chrome://resources/js/ios/web_ui.js"></script> </if> + <script src="chrome://resources/js/promise_resolver.js"></script> <script src="chrome://resources/js/cr.js"></script> <script src="chrome://resources/js/load_time_data.js"></script> <script src="chrome://resources/js/parse_html_subset.js"></script>
diff --git a/components/version_ui/resources/about_version.js b/components/version_ui/resources/about_version.js index 2cbb6de..d2f61cf 100644 --- a/components/version_ui/resources/about_version.js +++ b/components/version_ui/resources/about_version.js
@@ -2,44 +2,40 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Note: The handle* functions below are called internally on promise +// resolution, unlike the other return* functions, which are called +// asynchronously by the host. + /** - * Callback from the backend with the list of variations to display. - * This call will build the variations section of the version page, or hide that - * section if there are none to display. - * @param {!Array<string>} variationsList The list of variations. + * Promise resolution handler for variations list and command line equivalent. + * @param {{variationsList: !Array<string>, variationsCmd: string=}} */ -function returnVariationInfo(variationsList) { +function handleVariationInfo({variationsList, variationsCmd}) { $('variations-section').hidden = !variationsList.length; $('variations-list').appendChild( parseHtmlSubset(variationsList.join('<br>'), ['BR'])); + + if (variationsCmd) { + $('variations-cmd-section').hidden = !variationsCmd; + $('variations-cmd').textContent = variationsCmd; + } } /** - * Callback from the backend with the variations formatted as command line - * input. This call will build the variations-cmd section of the version page - * if needed. - * @param {string} variationsCmd The variations info in command line format. - */ -function returnVariationCmd(variationsCmd) { - $('variations-cmd-section').hidden = !variationsCmd; - $('variations-cmd').textContent = variationsCmd; -} - -/** - * Callback from the backend with the executable and profile paths to display. + * Promise resolution handler for the executable and profile paths to display. * @param {string} execPath The executable path to display. * @param {string} profilePath The profile path to display. */ -function returnFilePaths(execPath, profilePath) { +function handlePathInfo({execPath, profilePath}) { $('executable_path').textContent = execPath; $('profile_path').textContent = profilePath; } /** - * Callback from the backend with the Flash version to display. + * Promise resolution handler for the Flash version to display. * @param {string} flashVersion The Flash version to display. */ -function returnFlashVersion(flashVersion) { +function handlePluginInfo(flashVersion) { $('flash_version').textContent = flashVersion; } @@ -83,6 +79,12 @@ /* All the work we do onload. */ function onLoadWork() { chrome.send('requestVersionInfo'); + const includeVariationsCmd = location.search.includes("show-variations-cmd"); + cr.sendWithPromise('requestVariationInfo', includeVariationsCmd) + .then(handleVariationInfo); + cr.sendWithPromise('requestPluginInfo').then(handlePluginInfo); + cr.sendWithPromise('requestPathInfo').then(handlePathInfo); + if (cr.isChromeOS) { $('arc_holder').hidden = true; chrome.chromeosInfoPrivate.get(['customizationId'], returnCustomizationId);
diff --git a/components/version_ui/version_ui_constants.cc b/components/version_ui/version_ui_constants.cc index 6ad2a1e..53e81e3 100644 --- a/components/version_ui/version_ui_constants.cc +++ b/components/version_ui/version_ui_constants.cc
@@ -12,10 +12,15 @@ // Message handlers. const char kRequestVersionInfo[] = "requestVersionInfo"; -const char kReturnFilePaths[] = "returnFilePaths"; -const char kReturnFlashVersion[] = "returnFlashVersion"; -const char kReturnVariationInfo[] = "returnVariationInfo"; -const char kReturnVariationCmd[] = "returnVariationCmd"; +const char kRequestVariationInfo[] = "requestVariationInfo"; +const char kRequestPluginInfo[] = "requestPluginInfo"; +const char kRequestPathInfo[] = "requestPathInfo"; + +// Named keys used in message handler responses. +const char kKeyVariationsList[] = "variationsList"; +const char kKeyVariationsCmd[] = "variationsCmd"; +const char kKeyExecPath[] = "execPath"; +const char kKeyProfilePath[] = "profilePath"; // Strings. const char kApplicationLabel[] = "application_label"; @@ -75,7 +80,6 @@ const char kUserAgentName[] = "user_agent_name"; const char kVariationsCmdName[] = "variations_cmd_name"; const char kVariationsName[] = "variations_name"; -const char kVariationsShowCmdQuery[] = "show-variations-cmd"; const char kVersion[] = "version"; const char kVersionBitSize[] = "version_bitsize"; const char kVersionModifier[] = "version_modifier";
diff --git a/components/version_ui/version_ui_constants.h b/components/version_ui/version_ui_constants.h index ebc50865..ffd3334a 100644 --- a/components/version_ui/version_ui_constants.h +++ b/components/version_ui/version_ui_constants.h
@@ -17,10 +17,14 @@ // Message handlers. // Must match the constants used in the resource files. extern const char kRequestVersionInfo[]; -extern const char kReturnFilePaths[]; -extern const char kReturnFlashVersion[]; -extern const char kReturnVariationInfo[]; -extern const char kReturnVariationCmd[]; +extern const char kRequestVariationInfo[]; +extern const char kRequestPluginInfo[]; +extern const char kRequestPathInfo[]; + +extern const char kKeyVariationsList[]; +extern const char kKeyVariationsCmd[]; +extern const char kKeyExecPath[]; +extern const char kKeyProfilePath[]; // Strings. // Must match the constants used in the resource files. @@ -81,7 +85,6 @@ extern const char kUserAgentName[]; extern const char kVariationsCmdName[]; extern const char kVariationsName[]; -extern const char kVariationsShowCmdQuery[]; extern const char kVersion[]; extern const char kVersionBitSize[]; extern const char kVersionModifier[];
diff --git a/components/viz/common/display/renderer_settings.h b/components/viz/common/display/renderer_settings.h index e3325536..116a777 100644 --- a/components/viz/common/display/renderer_settings.h +++ b/components/viz/common/display/renderer_settings.h
@@ -31,6 +31,7 @@ bool release_overlay_resources_after_gpu_query = false; bool tint_gl_composited_content = false; bool show_overdraw_feedback = false; + bool show_aggregated_damage = false; bool use_skia_renderer = false; bool allow_overlays = true; bool dont_round_texture_sizes_for_pixel_tests = false;
diff --git a/components/viz/common/switches.cc b/components/viz/common/switches.cc index 939af777..ad499b8f1 100644 --- a/components/viz/common/switches.cc +++ b/components/viz/common/switches.cc
@@ -37,6 +37,12 @@ const char kRunAllCompositorStagesBeforeDraw[] = "run-all-compositor-stages-before-draw"; +// Adds a DebugBorderDrawQuad to the top of the root RenderPass showing the +// damage rect after surface aggregation. Note that when enabled this feature +// sets the entire output rect as damaged after adding the quad to highlight the +// real damage rect, which could hide damage rect problems. +const char kShowAggregatedDamage[] = "show-aggregated-damage"; + // Enables the viz hit-test logic (HitTestAggregator and HitTestQuery), with // hit-test data coming from surface layer. const char kUseVizHitTestSurfaceLayer[] = "use-viz-hit-test-surface-layer";
diff --git a/components/viz/common/switches.h b/components/viz/common/switches.h index 8326b1d..ea7362d 100644 --- a/components/viz/common/switches.h +++ b/components/viz/common/switches.h
@@ -20,6 +20,7 @@ VIZ_COMMON_EXPORT extern const char kEnableVizDevTools[]; VIZ_COMMON_EXPORT extern const char kEnableVizHitTestDebug[]; VIZ_COMMON_EXPORT extern const char kRunAllCompositorStagesBeforeDraw[]; +VIZ_COMMON_EXPORT extern const char kShowAggregatedDamage[]; VIZ_COMMON_EXPORT extern const char kUseVizHitTestSurfaceLayer[]; VIZ_COMMON_EXPORT base::Optional<uint32_t> GetDeadlineToSynchronizeSurfaces();
diff --git a/components/viz/demo/service/demo_service.cc b/components/viz/demo/service/demo_service.cc index cdfe9c7..f4ff92b0 100644 --- a/components/viz/demo/service/demo_service.cc +++ b/components/viz/demo/service/demo_service.cc
@@ -7,7 +7,7 @@ #include <memory> #include <utility> -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/service/main/viz_compositor_thread_runner.h" @@ -22,7 +22,7 @@ params->frame_sink_manager = std::move(request); params->frame_sink_manager_client = client.PassInterface(); runner_ = std::make_unique<viz::VizCompositorThreadRunner>( - base::MessageLoop::TYPE_DEFAULT); + base::MessagePumpType::DEFAULT); runner_->CreateFrameSinkManager(std::move(params)); }
diff --git a/components/viz/host/renderer_settings_creation.cc b/components/viz/host/renderer_settings_creation.cc index cf3b10a..642eaa52 100644 --- a/components/viz/host/renderer_settings_creation.cc +++ b/components/viz/host/renderer_settings_creation.cc
@@ -11,6 +11,7 @@ #include "components/viz/common/display/overlay_strategy.h" #include "components/viz/common/display/renderer_settings.h" #include "components/viz/common/features.h" +#include "components/viz/common/switches.h" #include "ui/base/ui_base_switches.h" #if defined(OS_MACOSX) @@ -18,7 +19,6 @@ #endif #if defined(USE_OZONE) -#include "components/viz/common/switches.h" #include "ui/ozone/public/ozone_platform.h" #endif @@ -61,6 +61,8 @@ command_line->HasSwitch(switches::kTintGlCompositedContent); renderer_settings.show_overdraw_feedback = command_line->HasSwitch(switches::kShowOverdrawFeedback); + renderer_settings.show_aggregated_damage = + command_line->HasSwitch(switches::kShowAggregatedDamage); renderer_settings.allow_antialiasing = !command_line->HasSwitch(switches::kDisableCompositedAntialiasing); renderer_settings.use_skia_renderer = features::IsUsingSkiaRenderer();
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index 6b9f104..892e89b 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -21,6 +21,8 @@ "display/ca_layer_overlay.h", "display/color_lut_cache.cc", "display/color_lut_cache.h", + "display/damage_frame_annotator.cc", + "display/damage_frame_annotator.h", "display/dc_layer_overlay.cc", "display/dc_layer_overlay.h", "display/direct_renderer.cc",
diff --git a/components/viz/service/display/damage_frame_annotator.cc b/components/viz/service/display/damage_frame_annotator.cc new file mode 100644 index 0000000..d39992e6 --- /dev/null +++ b/components/viz/service/display/damage_frame_annotator.cc
@@ -0,0 +1,99 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/viz/service/display/damage_frame_annotator.h" + +#include <algorithm> +#include <utility> + +#include "cc/base/math_util.h" +#include "components/viz/common/quads/compositor_frame.h" +#include "components/viz/common/quads/debug_border_draw_quad.h" +#include "components/viz/common/quads/render_pass.h" +#include "components/viz/common/quads/shared_quad_state.h" + +namespace viz { + +DamageFrameAnnotator::DamageFrameAnnotator() = default; +DamageFrameAnnotator::~DamageFrameAnnotator() = default; + +void DamageFrameAnnotator::AnnotateAggregatedFrame(CompositorFrame* frame) { + DCHECK(frame); + auto* root_render_pass = frame->render_pass_list.back().get(); + + const gfx::Rect& damage_rect = root_render_pass->damage_rect; + gfx::Transform transform; + transform.Translate(damage_rect.x(), damage_rect.y()); + + annotations_.push_back( + AnnotationData{gfx::Rect(damage_rect.size()), transform, + Highlight{SkColorSetARGB(128, 255, 0, 0), 4}}); + + AnnotateRootRenderPass(root_render_pass); + annotations_.clear(); +} + +void DamageFrameAnnotator::AnnotateRootRenderPass(RenderPass* render_pass) { + const size_t num_quads_to_add = annotations_.size(); + + // Insert |num_quads_to_add| new SharedQuadState at the start of the list. + // This will invalidate all the existing SharedQuadState* in DrawQuads. + auto sqs_iter = + render_pass->shared_quad_state_list + .InsertBeforeAndInvalidateAllPointers<SharedQuadState>( + render_pass->shared_quad_state_list.begin(), num_quads_to_add); + + // Insert |num_quads_to_add| new DebugBorderDrawQuad at start of list. The + // quads will be drawn on top of the original quads. + auto quad_iter = + render_pass->quad_list + .InsertBeforeAndInvalidateAllPointers<DebugBorderDrawQuad>( + render_pass->quad_list.begin(), num_quads_to_add); + + // Initialize the SharedQuadStates and DebugBorderDrawQuads. + for (auto& annotation : annotations_) { + gfx::Rect output_rect = cc::MathUtil::MapEnclosingClippedRect( + annotation.transform, annotation.rect); + + SharedQuadState* new_sqs = *sqs_iter; + new_sqs->SetAll(annotation.transform, output_rect, output_rect, + gfx::RRectF(), output_rect, true, false, 1.f, + SkBlendMode::kSrcOver, 0); + + DebugBorderDrawQuad* new_quad = + static_cast<DebugBorderDrawQuad*>(*quad_iter); + new_quad->SetNew(new_sqs, annotation.rect, annotation.rect, + annotation.highlight.color, annotation.highlight.width); + + ++sqs_iter; + ++quad_iter; + } + + // At this point |quad_iter| points to the first DrawQuad that needs + // |shared_quad_state| fixed. |sqs_iter| points to the new address for the + // first original SharedQuadState. Iterate through all DrawQuads updating + // |shared_quad_state|. + const SharedQuadState* last_quad_from_sqs = (*quad_iter)->shared_quad_state; + while (quad_iter != render_pass->quad_list.end()) { + DrawQuad* quad = *quad_iter; + const SharedQuadState* from_sqs = quad->shared_quad_state; + + // If |shared_quad_state| of the current quad is different than the last + // quad we know to advance |sqs_iter| as well. + if (from_sqs != last_quad_from_sqs) { + DCHECK(sqs_iter != render_pass->shared_quad_state_list.end()); + ++sqs_iter; + last_quad_from_sqs = from_sqs; + } + + quad->shared_quad_state = *sqs_iter; + ++quad_iter; + } + DCHECK(++sqs_iter == render_pass->shared_quad_state_list.end()); + + // Set the entire frame as damaged. + render_pass->damage_rect = render_pass->output_rect; +} + +} // namespace viz
diff --git a/components/viz/service/display/damage_frame_annotator.h b/components/viz/service/display/damage_frame_annotator.h new file mode 100644 index 0000000..cab64d7c --- /dev/null +++ b/components/viz/service/display/damage_frame_annotator.h
@@ -0,0 +1,50 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_DAMAGE_FRAME_ANNOTATOR_H_ +#define COMPONENTS_VIZ_SERVICE_DISPLAY_DAMAGE_FRAME_ANNOTATOR_H_ + +#include <vector> + +#include "components/viz/service/display/surface_aggregator.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/transform.h" + +namespace viz { + +class CompositorFrame; +class RenderPass; + +// Draws a red outline around the root RenderPasses damage rect. +class DamageFrameAnnotator : public SurfaceAggregator::FrameAnnotator { + public: + DamageFrameAnnotator(); + ~DamageFrameAnnotator() override; + + // SurfaceAggregator::FrameAnnotator implementation. + void AnnotateAggregatedFrame(CompositorFrame* frame) override; + + private: + struct Highlight { + SkColor color; + int width; + }; + + struct AnnotationData { + gfx::Rect rect; + gfx::Transform transform; + Highlight highlight; + }; + + void AnnotateRootRenderPass(RenderPass* render_pass); + + std::vector<AnnotationData> annotations_; + + DISALLOW_COPY_AND_ASSIGN(DamageFrameAnnotator); +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_DAMAGE_FRAME_ANNOTATOR_H_
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc index c3b1ce9..cca345b 100644 --- a/components/viz/service/display/display.cc +++ b/components/viz/service/display/display.cc
@@ -22,6 +22,7 @@ #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/quads/draw_quad.h" #include "components/viz/common/quads/shared_quad_state.h" +#include "components/viz/service/display/damage_frame_annotator.h" #include "components/viz/service/display/direct_renderer.h" #include "components/viz/service/display/display_client.h" #include "components/viz/service/display/display_scheduler.h" @@ -378,9 +379,12 @@ renderer_->use_partial_swap() && !renderer_->has_overlay_validator(); bool needs_surface_occluding_damage_rect = renderer_->OverlayNeedsSurfaceOccludingDamageRect(); - aggregator_.reset(new SurfaceAggregator( + aggregator_ = std::make_unique<SurfaceAggregator>( surface_manager_, resource_provider_.get(), output_partial_list, - needs_surface_occluding_damage_rect)); + needs_surface_occluding_damage_rect); + if (settings_.show_aggregated_damage) + aggregator_->SetFrameAnnotator(std::make_unique<DamageFrameAnnotator>()); + aggregator_->set_output_is_secure(output_is_secure_); aggregator_->SetOutputColorSpace(device_color_space_); // Consider adding a softare limit as well.
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc index fe10c91..a1c0c664 100644 --- a/components/viz/service/display/surface_aggregator.cc +++ b/components/viz/service/display/surface_aggregator.cc
@@ -19,6 +19,7 @@ #include "base/trace_event/trace_event.h" #include "cc/base/math_util.h" #include "components/viz/common/quads/compositor_frame.h" +#include "components/viz/common/quads/debug_border_draw_quad.h" #include "components/viz/common/quads/draw_quad.h" #include "components/viz/common/quads/render_pass_draw_quad.h" #include "components/viz/common/quads/shared_quad_state.h" @@ -1557,6 +1558,10 @@ break; } } + + if (frame_annotator_) + frame_annotator_->AnnotateAggregatedFrame(&frame); + return frame; } @@ -1612,6 +1617,12 @@ return false; } +void SurfaceAggregator::SetFrameAnnotator( + std::unique_ptr<FrameAnnotator> frame_annotator) { + DCHECK(!frame_annotator_); + frame_annotator_ = std::move(frame_annotator); +} + bool SurfaceAggregator::IsRootSurface(const Surface* surface) const { return surface->surface_id() == root_surface_id_; }
diff --git a/components/viz/service/display/surface_aggregator.h b/components/viz/service/display/surface_aggregator.h index d16f763..9012e6d 100644 --- a/components/viz/service/display/surface_aggregator.h +++ b/components/viz/service/display/surface_aggregator.h
@@ -35,6 +35,15 @@ using SurfaceIndexMap = base::flat_map<SurfaceId, uint64_t>; using FrameSinkIdMap = base::flat_map<FrameSinkId, LocalSurfaceId>; + // Interface that can modify the aggregated CompositorFrame to annotate it. + // For example it could add extra quads. + class FrameAnnotator { + public: + virtual ~FrameAnnotator() = default; + + virtual void AnnotateAggregatedFrame(CompositorFrame* frame) = 0; + }; + SurfaceAggregator(SurfaceManager* manager, DisplayResourceProvider* provider, bool aggregate_only_damaged, @@ -63,6 +72,8 @@ bool NotifySurfaceDamageAndCheckForDisplayDamage(const SurfaceId& surface_id); + void SetFrameAnnotator(std::unique_ptr<FrameAnnotator> frame_annotator); + private: struct ClipData { ClipData() : is_clipped(false) {} @@ -326,6 +337,9 @@ // the display if they're damaged. base::flat_map<FrameSinkId, std::vector<SurfaceRange>> damage_ranges_; + // Used to annotate the aggregated frame for debugging. + std::unique_ptr<FrameAnnotator> frame_annotator_; + int64_t display_trace_id_ = -1; base::flat_set<SurfaceId> undrawn_surfaces_;
diff --git a/components/viz/service/main/viz_compositor_thread_runner.cc b/components/viz/service/main/viz_compositor_thread_runner.cc index acf32199..790848c27 100644 --- a/components/viz/service/main/viz_compositor_thread_runner.cc +++ b/components/viz/service/main/viz_compositor_thread_runner.cc
@@ -41,7 +41,7 @@ const char kThreadName[] = "VizCompositorThread"; std::unique_ptr<VizCompositorThreadType> CreateAndStartCompositorThread( - base::MessageLoop::Type message_loop_type) { + base::MessagePumpType message_pump_type) { const base::ThreadPriority thread_priority = base::FeatureList::IsEnabled(features::kGpuUseDisplayThreadPriority) ? base::ThreadPriority::DISPLAY @@ -55,7 +55,7 @@ auto thread = std::make_unique<base::Thread>(kThreadName); base::Thread::Options thread_options; - thread_options.message_loop_type = message_loop_type; + thread_options.message_pump_type = message_pump_type; #if defined(OS_MACOSX) // Increase the thread priority to get more reliable values in performance @@ -77,8 +77,8 @@ } // namespace VizCompositorThreadRunner::VizCompositorThreadRunner( - base::MessageLoop::Type message_loop_type) - : thread_(CreateAndStartCompositorThread(message_loop_type)), + base::MessagePumpType message_pump_type) + : thread_(CreateAndStartCompositorThread(message_pump_type)), task_runner_(thread_->task_runner()) {} VizCompositorThreadRunner::~VizCompositorThreadRunner() {
diff --git a/components/viz/service/main/viz_compositor_thread_runner.h b/components/viz/service/main/viz_compositor_thread_runner.h index 06f4e6a..c0d18e1 100644 --- a/components/viz/service/main/viz_compositor_thread_runner.h +++ b/components/viz/service/main/viz_compositor_thread_runner.h
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "build/build_config.h" #include "services/network/public/mojom/tcp_socket.mojom.h" #include "services/viz/privileged/mojom/viz_main.mojom.h" @@ -49,7 +49,7 @@ // and then stop the thread. class VizCompositorThreadRunner { public: - explicit VizCompositorThreadRunner(base::MessageLoop::Type message_loop_type); + explicit VizCompositorThreadRunner(base::MessagePumpType message_pump_type); // Performs teardown on thread and then stops thread. ~VizCompositorThreadRunner();
diff --git a/components/viz/service/main/viz_main_impl.cc b/components/viz/service/main/viz_main_impl.cc index bfa4920..af3b4fc 100644 --- a/components/viz/service/main/viz_main_impl.cc +++ b/components/viz/service/main/viz_main_impl.cc
@@ -9,7 +9,7 @@ #include "base/bind.h" #include "base/feature_list.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/power_monitor/power_monitor.h" #include "base/power_monitor/power_monitor_device_source.h" #include "base/single_thread_task_runner.h" @@ -37,7 +37,7 @@ std::unique_ptr<base::Thread> CreateAndStartIOThread() { // TODO(sad): We do not need the IO thread once gpu has a separate process. // It should be possible to use |main_task_runner_| for doing IO tasks. - base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options thread_options(base::MessagePumpType::IO, 0); // TODO(reveman): Remove this in favor of setting it explicitly for each // type of process. if (base::FeatureList::IsEnabled(features::kGpuUseDisplayThreadPriority))
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index 94e0d6d..709ccfae 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc
@@ -924,25 +924,23 @@ delegate_->PostTaskSchedulerStart(); - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { - bool force_in_process = false; - if (should_start_service_manager_only) { - force_in_process = true; - } else { + bool force_in_process = false; + if (should_start_service_manager_only) { + force_in_process = true; + } else { #if defined(OS_ANDROID) - auto finch_value = kDevicesForceInProcessParam.Get(); - auto devices = base::SplitString( - finch_value, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - auto current_device = - std::string(base::android::BuildInfo::GetInstance()->model()); - for (auto device : devices) { - if (device == current_device) { - force_in_process = true; - break; - } + auto finch_value = kDevicesForceInProcessParam.Get(); + auto devices = base::SplitString(finch_value, ";", base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); + auto current_device = + std::string(base::android::BuildInfo::GetInstance()->model()); + for (auto device : devices) { + if (device == current_device) { + force_in_process = true; + break; } -#endif } +#endif if (force_in_process) { // This must be called before creating the ServiceManagerContext.
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index f7589c0d..b850292 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -671,6 +671,8 @@ "content_index/content_index_context_impl.h", "content_index/content_index_database.cc", "content_index/content_index_database.h", + "content_index/content_index_metrics.cc", + "content_index/content_index_metrics.h", "content_index/content_index_service_impl.cc", "content_index/content_index_service_impl.h", "content_service_delegate_impl.cc",
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index 6e97b675..39663b5 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -268,11 +268,11 @@ int end_offset, ax::mojom::TextAffinity end_affinity) { BrowserAccessibilityPositionInstance anchor = - start_object.IsTextOnlyObject() + start_object.PlatformIsLeaf() ? CreateTextPosition(start_object, start_offset, start_affinity) : CreateTreePosition(start_object, start_offset); BrowserAccessibilityPositionInstance focus = - end_object.IsTextOnlyObject() + end_object.PlatformIsLeaf() ? CreateTextPosition(end_object, end_offset, end_affinity) : CreateTreePosition(end_object, end_offset); // |AXPlatformRange| takes ownership of its anchor and focus.
diff --git a/content/browser/appcache/appcache_response_unittest.cc b/content/browser/appcache/appcache_response_unittest.cc index 345279dde..b274837 100644 --- a/content/browser/appcache/appcache_response_unittest.cc +++ b/content/browser/appcache/appcache_response_unittest.cc
@@ -14,7 +14,7 @@ #include "base/compiler_specific.h" #include "base/containers/stack.h" #include "base/location.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/pickle.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" @@ -73,7 +73,7 @@ scoped_task_environment_ = std::make_unique<base::test::ScopedTaskEnvironment>(); io_thread_ = std::make_unique<base::Thread>("AppCacheResponseTest Thread"); - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); io_thread_->StartWithOptions(options); }
diff --git a/content/browser/appcache/appcache_storage_impl_unittest.cc b/content/browser/appcache/appcache_storage_impl_unittest.cc index d25aa23f3..5e660347 100644 --- a/content/browser/appcache/appcache_storage_impl_unittest.cc +++ b/content/browser/appcache/appcache_storage_impl_unittest.cc
@@ -17,7 +17,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/location.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" @@ -263,7 +263,7 @@ // We start the background thread as TYPE_IO because we also use the // db_thread for the disk_cache which needs to be of TYPE_IO. - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); background_thread = std::make_unique<base::Thread>("AppCacheTest::BackgroundThread"); ASSERT_TRUE(background_thread->StartWithOptions(options));
diff --git a/content/browser/appcache/appcache_url_request_job_unittest.cc b/content/browser/appcache/appcache_url_request_job_unittest.cc index da5a91a..07bd247 100644 --- a/content/browser/appcache/appcache_url_request_job_unittest.cc +++ b/content/browser/appcache/appcache_url_request_job_unittest.cc
@@ -18,7 +18,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/pickle.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" @@ -235,7 +235,7 @@ std::make_unique<base::test::ScopedTaskEnvironment>(); io_thread_ = std::make_unique<base::Thread>("AppCacheURLRequestJobTest Thread"); - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); io_thread_->StartWithOptions(options); }
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc index baf22af..19d091a 100644 --- a/content/browser/background_sync/background_sync_manager.cc +++ b/content/browser/background_sync/background_sync_manager.cc
@@ -895,7 +895,7 @@ // registration, so set delay_until to override its default value. if (registration.sync_type() == BackgroundSyncType::PERIODIC) { registration.set_delay_until(GetDelayUntilAfterApplyingMinGapForOrigin( - registration.origin(), delay)); + BackgroundSyncType::PERIODIC, registration.origin(), delay)); } ServiceWorkerRegistration* sw_registration = @@ -1489,11 +1489,15 @@ } base::Time BackgroundSyncManager::GetDelayUntilAfterApplyingMinGapForOrigin( + BackgroundSyncType sync_type, const url::Origin& origin, base::TimeDelta delay) const { DCHECK_CURRENTLY_ON(BrowserThread::IO); base::Time now_plus_delay = clock_->Now() + delay; + if (sync_type != BackgroundSyncType::PERIODIC) + return now_plus_delay; + base::Time soonest_wakeup_time_for_origin = GetSoonestPeriodicSyncEventTimeForOrigin(origin); if (soonest_wakeup_time_for_origin.is_null()) @@ -1981,7 +1985,7 @@ registration->set_sync_state(blink::mojom::BackgroundSyncState::PENDING); registration_completed = false; registration->set_delay_until(GetDelayUntilAfterApplyingMinGapForOrigin( - registration->origin(), delay)); + registration->sync_type(), registration->origin(), delay)); std::string event_name = GetSyncEventName(registration->sync_type()) + (succeeded ? " event completed" : " event failed");
diff --git a/content/browser/background_sync/background_sync_manager.h b/content/browser/background_sync/background_sync_manager.h index e3e2a85b..13272fd 100644 --- a/content/browser/background_sync/background_sync_manager.h +++ b/content/browser/background_sync/background_sync_manager.h
@@ -170,7 +170,9 @@ // correct starting point to add to |delay| to so that the resulting // |delay_until| for the |registration| ensures the minimum gap between // periodicsync events fired for the origin. + // |delay| is only updated if |sync_type| is periodic. base::Time GetDelayUntilAfterApplyingMinGapForOrigin( + blink::mojom::BackgroundSyncType sync_type, const url::Origin& origin, base::TimeDelta delay) const;
diff --git a/content/browser/background_sync/background_sync_manager_unittest.cc b/content/browser/background_sync/background_sync_manager_unittest.cc index 26c1f05..4419b8b 100644 --- a/content/browser/background_sync/background_sync_manager_unittest.cc +++ b/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -1274,6 +1274,38 @@ Unregister(sync_options_2_); } +TEST_F(BackgroundSyncManagerTest, CrossRegistrationLimitsForOrigin) { + InitPeriodicSyncEventTest(); + base::TimeDelta thirteen_hours = base::TimeDelta::FromHours(13); + sync_options_1_.min_interval = thirteen_hours.InMilliseconds(); + EXPECT_TRUE(Register(sync_options_1_)); + + EXPECT_EQ(0, periodic_sync_events_called_); + EXPECT_TRUE(GetRegistration(sync_options_1_)); + + // Register another periodic sync with the same origin, but a smaller + // minInterval. Expect the delay to be set to the larger minInterval from the + // already registered periodic sync. + base::TimeDelta twelve_hours = base::TimeDelta::FromHours(12); + sync_options_2_.min_interval = twelve_hours.InMilliseconds(); + EXPECT_TRUE(Register(sync_options_2_)); + + EXPECT_EQ(0, periodic_sync_events_called_); + EXPECT_TRUE(GetRegistration(sync_options_2_)); + + // Advance clock. + test_clock_.Advance(twelve_hours); + FireReadyEvents(); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(0, periodic_sync_events_called_); + + test_clock_.Advance(base::TimeDelta::FromHours(1)); + FireReadyEvents(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(2, periodic_sync_events_called_); +} + TEST_F(BackgroundSyncManagerTest, ReregisterMidSyncFirstAttemptFails) { InitDelayedSyncEventTest(); RegisterAndVerifySyncEventDelayed(sync_options_1_);
diff --git a/content/browser/browser_associated_interface_unittest.cc b/content/browser/browser_associated_interface_unittest.cc index 7acb5b7..33804af 100644 --- a/content/browser/browser_associated_interface_unittest.cc +++ b/content/browser/browser_associated_interface_unittest.cc
@@ -8,7 +8,7 @@ #include "base/bind.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/pickle.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -137,7 +137,7 @@ static void RunTestClient(mojo::ScopedMessagePipeHandle pipe) { base::Thread io_thread("Client IO thread"); io_thread.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); ProxyRunner proxy(std::move(pipe), false, io_thread.task_runner()); mojom::BrowserAssociatedInterfaceTestDriverAssociatedPtr driver;
diff --git a/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc b/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc index d2d7504a..2f94b56f 100644 --- a/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc +++ b/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "content/browser/browsing_data/browsing_data_remover_impl.h" + #include <stddef.h> #include <stdint.h> @@ -27,7 +29,6 @@ #include "base/task/post_task.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" -#include "content/browser/browsing_data/browsing_data_remover_impl.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browsing_data_filter_builder.h" @@ -63,26 +64,28 @@ #if BUILDFLAG(ENABLE_REPORTING) #include "net/network_error_logging/mock_persistent_nel_store.h" #include "net/network_error_logging/network_error_logging_service.h" +#include "net/reporting/mock_persistent_reporting_store.h" #include "net/reporting/reporting_cache.h" +#include "net/reporting/reporting_endpoint.h" #include "net/reporting/reporting_report.h" #include "net/reporting/reporting_service.h" #include "net/reporting/reporting_test_util.h" #endif // BUILDFLAG(ENABLE_REPORTING) +using testing::_; using testing::ByRef; using testing::Eq; using testing::Invoke; using testing::IsEmpty; using testing::MakeMatcher; -using testing::MatchResultListener; using testing::Matcher; using testing::MatcherInterface; +using testing::MatchResultListener; using testing::Not; using testing::Return; using testing::SizeIs; using testing::UnorderedElementsAre; using testing::WithArgs; -using testing::_; using CookieDeletionFilterPtr = network::mojom::CookieDeletionFilterPtr; namespace content { @@ -1285,7 +1288,64 @@ } #if BUILDFLAG(ENABLE_REPORTING) -TEST_F(BrowsingDataRemoverImplTest, RemoveReportingCache) { +TEST_F(BrowsingDataRemoverImplTest, RemoveReportingCache_WithStore) { + // TODO: rewrite this test to work with Network Service objects. + // https://crbug.com/967698 + if (base::FeatureList::IsEnabled(network::features::kNetworkService)) + return; + + net::MockPersistentReportingStore store; + auto reporting_context = std::make_unique<net::TestReportingContext>( + base::DefaultClock::GetInstance(), base::DefaultTickClock::GetInstance(), + net::ReportingPolicy(), &store); + net::ReportingCache* reporting_cache = reporting_context->cache(); + std::unique_ptr<net::ReportingService> reporting_service = + net::ReportingService::CreateForTesting(std::move(reporting_context)); + + reporting_service->ProcessHeader(GURL("https://origin/path"), + R"json( + {"endpoints":[{"url":"https://endpoint/"}], + "group":"group", "max_age":86400} + )json"); + store.FinishLoading(true /* load_success */); + store.Flush(); + + BrowserContext::GetDefaultStoragePartition(GetBrowserContext()) + ->GetURLRequestContext() + ->GetURLRequestContext() + ->set_reporting_service(reporting_service.get()); + + ASSERT_EQ(1u, reporting_cache->GetEndpointCount()); + EXPECT_THAT( + store.GetAllCommands(), + testing::IsSupersetOf( + {net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + ADD_REPORTING_ENDPOINT, + GURL("https://origin/"), "group", GURL("https://endpoint/")), + net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + ADD_REPORTING_ENDPOINT_GROUP, + GURL("https://origin/"), "group")})); + + BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), + BrowsingDataRemover::DATA_TYPE_COOKIES, false); + + EXPECT_EQ(0u, reporting_cache->GetEndpointCount()); + EXPECT_THAT( + store.GetAllCommands(), + testing::IsSupersetOf( + {net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + DELETE_REPORTING_ENDPOINT, + GURL("https://origin/"), "group", GURL("https://endpoint/")), + net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + DELETE_REPORTING_ENDPOINT_GROUP, + GURL("https://origin/"), "group")})); +} + +TEST_F(BrowsingDataRemoverImplTest, RemoveReportingCache_NoPersistentStore) { // TODO: rewrite this test to work with Network Service objects. // https://crbug.com/967698 if (base::FeatureList::IsEnabled(network::features::kNetworkService)) @@ -1372,6 +1432,118 @@ url::Origin::Create(domain4))); } +TEST_F(BrowsingDataRemoverImplTest, + RemoveReportingCache_SpecificOriginsFromStore) { + // TODO: rewrite this test to work with Network Service objects. + // https://crbug.com/967698 + if (base::FeatureList::IsEnabled(network::features::kNetworkService)) + return; + + net::MockPersistentReportingStore store; + auto reporting_context = std::make_unique<net::TestReportingContext>( + base::DefaultClock::GetInstance(), base::DefaultTickClock::GetInstance(), + net::ReportingPolicy(), &store); + net::ReportingCache* reporting_cache = reporting_context->cache(); + std::unique_ptr<net::ReportingService> reporting_service = + net::ReportingService::CreateForTesting(std::move(reporting_context)); + + reporting_service->ProcessHeader(GURL("https://google.com"), + R"json( + {"endpoints":[{"url":"https://google.com"}], + "group":"group", "max_age":86400} + )json"); + reporting_service->ProcessHeader(GURL("https://host2.com"), + R"json( + {"endpoints":[{"url":"https://host2.com"}], + "group":"group", "max_age":86400} + )json"); + reporting_service->ProcessHeader(GURL("https://host3.com"), + R"json( + {"endpoints":[{"url":"https://host3.com"}], + "group":"group", "max_age":86400} + )json"); + reporting_service->ProcessHeader(GURL("https://host4.com"), + R"json( + {"endpoints":[{"url":"https://host4.com"}], + "group":"group", "max_age":86400} + )json"); + store.FinishLoading(true /* load_success */); + store.Flush(); + + BrowserContext::GetDefaultStoragePartition(GetBrowserContext()) + ->GetURLRequestContext() + ->GetURLRequestContext() + ->set_reporting_service(reporting_service.get()); + + ASSERT_EQ(4u, reporting_cache->GetEndpointCount()); + EXPECT_THAT( + store.GetAllCommands(), + testing::IsSupersetOf( + {net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + ADD_REPORTING_ENDPOINT, + GURL("https://google.com/"), "group", + GURL("https://google.com/")), + net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + ADD_REPORTING_ENDPOINT_GROUP, + GURL("https://google.com/"), "group"), + net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + ADD_REPORTING_ENDPOINT, + GURL("https://host2.com/"), "group", GURL("https://host2.com/")), + net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + ADD_REPORTING_ENDPOINT_GROUP, + GURL("https://host2.com/"), "group"), + net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + ADD_REPORTING_ENDPOINT, + GURL("https://host3.com/"), "group", GURL("https://host3.com/")), + net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + ADD_REPORTING_ENDPOINT_GROUP, + GURL("https://host3.com/"), "group"), + net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + ADD_REPORTING_ENDPOINT, + GURL("https://host4.com/"), "group", GURL("https://host4.com/")), + net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + ADD_REPORTING_ENDPOINT_GROUP, + GURL("https://host4.com/"), "group")})); + + std::unique_ptr<BrowsingDataFilterBuilder> filter_builder( + BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST)); + filter_builder->AddRegisterableDomain("google.com"); + filter_builder->AddRegisterableDomain("host3.com"); + BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), + BrowsingDataRemover::DATA_TYPE_COOKIES, + std::move(filter_builder)); + + EXPECT_EQ(2u, reporting_cache->GetEndpointCount()); + EXPECT_THAT( + store.GetAllCommands(), + testing::IsSupersetOf( + {net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + DELETE_REPORTING_ENDPOINT, + GURL("https://google.com/"), "group", + GURL("https://google.com/")), + net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + DELETE_REPORTING_ENDPOINT_GROUP, + GURL("https://google.com/"), "group"), + net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + DELETE_REPORTING_ENDPOINT, + GURL("https://host3.com/"), "group", GURL("https://host3.com/")), + net::MockPersistentReportingStore::Command( + net::MockPersistentReportingStore::Command::Type:: + DELETE_REPORTING_ENDPOINT_GROUP, + GURL("https://host3.com/"), "group")})); +} + TEST_F(BrowsingDataRemoverImplTest, RemoveReportingCache_NoService) { // TODO: rewrite this test to work with Network Service objects. // https://crbug.com/967698
diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc index 5bb9bc2..a99c344 100644 --- a/content/browser/compositor/viz_process_transport_factory.cc +++ b/content/browser/compositor/viz_process_transport_factory.cc
@@ -10,7 +10,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/debug/dump_without_crashing.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/task/post_task.h" #include "cc/mojo_embedder/async_layer_tree_frame_sink.h" @@ -191,7 +191,7 @@ // GPU process access is disabled. Start a new thread to run the display // compositor in-process and connect HostFrameSinkManager to it. viz_compositor_thread_ = std::make_unique<viz::VizCompositorThreadRunner>( - base::MessageLoop::TYPE_DEFAULT); + base::MessagePumpType::DEFAULT); viz::mojom::FrameSinkManagerParamsPtr params = viz::mojom::FrameSinkManagerParams::New();
diff --git a/content/browser/content_index/content_index_context_impl.cc b/content/browser/content_index/content_index_context_impl.cc index 65353e61..62a6b799 100644 --- a/content/browser/content_index/content_index_context_impl.cc +++ b/content/browser/content_index/content_index_context_impl.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/task/post_task.h" +#include "content/browser/content_index/content_index_metrics.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -113,6 +114,8 @@ scoped_refptr<ServiceWorkerRegistration> registration) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + content_index::RecordDisptachStatus("Find", service_worker_status); + if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) return; @@ -130,9 +133,14 @@ scoped_refptr<ServiceWorkerVersion> service_worker, scoped_refptr<ServiceWorkerRegistration> registration, const std::string& description_id, - blink::ServiceWorkerStatusCode start_worker_status) { + blink::ServiceWorkerStatusCode service_worker_status) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + content_index::RecordDisptachStatus("Start", service_worker_status); + + if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) + return; + // Don't allow DB operations while the `contentdelete` event is firing. // This is to prevent re-registering the deleted content within the event. content_index_database_.BlockOrigin(service_worker->script_origin()); @@ -151,6 +159,7 @@ blink::ServiceWorkerStatusCode service_worker_status) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + content_index::RecordDisptachStatus("Dispatch", service_worker_status); content_index_database_.UnblockOrigin(origin); }
diff --git a/content/browser/content_index/content_index_context_impl.h b/content/browser/content_index/content_index_context_impl.h index 6cc780b3..33fb5f9 100644 --- a/content/browser/content_index/content_index_context_impl.h +++ b/content/browser/content_index/content_index_context_impl.h
@@ -67,7 +67,7 @@ scoped_refptr<ServiceWorkerVersion> service_worker, scoped_refptr<ServiceWorkerRegistration> registration, const std::string& description_id, - blink::ServiceWorkerStatusCode start_worker_status); + blink::ServiceWorkerStatusCode service_worker_status); void DidDispatchEvent(const url::Origin& origin, blink::ServiceWorkerStatusCode service_worker_status);
diff --git a/content/browser/content_index/content_index_database.cc b/content/browser/content_index/content_index_database.cc index cdbcb57..084ed7d 100644 --- a/content/browser/content_index/content_index_database.cc +++ b/content/browser/content_index/content_index_database.cc
@@ -11,6 +11,7 @@ #include "base/time/time.h" #include "content/browser/background_fetch/storage/image_helpers.h" #include "content/browser/content_index/content_index.pb.h" +#include "content/browser/content_index/content_index_metrics.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -122,6 +123,7 @@ if (blocked_origins_.count(origin)) { // TODO(crbug.com/973844): Does this need a more specific error? std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR); + content_index::RecordRegistrationBlocked(description->category); return; } @@ -162,6 +164,8 @@ blink::mojom::ContentIndexService::AddCallback callback, ContentIndexEntry entry, blink::ServiceWorkerStatusCode status) { + content_index::RecordDatabaseOperationStatus("Add", status); + if (status != blink::ServiceWorkerStatusCode::kOk) { std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR); return; @@ -196,6 +200,8 @@ const std::string& entry_id, blink::mojom::ContentIndexService::DeleteCallback callback, blink::ServiceWorkerStatusCode status) { + content_index::RecordDatabaseOperationStatus("Delete", status); + if (status != blink::ServiceWorkerStatusCode::kOk) { std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR); return; @@ -223,6 +229,8 @@ blink::mojom::ContentIndexService::GetDescriptionsCallback callback, const std::vector<std::string>& data, blink::ServiceWorkerStatusCode status) { + content_index::RecordDatabaseOperationStatus("GetDescriptions", status); + if (status == blink::ServiceWorkerStatusCode::kErrorNotFound) { std::move(callback).Run(blink::mojom::ContentIndexError::NONE, /* descriptions= */ {}); @@ -276,6 +284,8 @@ base::OnceCallback<void(SkBitmap)> icon_callback, const std::vector<std::string>& data, blink::ServiceWorkerStatusCode status) { + content_index::RecordDatabaseOperationStatus("GetIcon", status); + if (status != blink::ServiceWorkerStatusCode::kOk || data.empty()) { std::move(icon_callback).Run(SkBitmap()); return; @@ -303,8 +313,9 @@ ContentIndexContext::GetAllEntriesCallback callback, const std::vector<std::pair<int64_t, std::string>>& user_data, blink::ServiceWorkerStatusCode status) { + content_index::RecordDatabaseOperationStatus("GetAllEntries", status); + if (status != blink::ServiceWorkerStatusCode::kOk) { - // TODO(crbug.com/973844): Handle or report this error. std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR, /* entries= */ {}); return; @@ -321,8 +332,8 @@ for (const auto& ud : user_data) { auto entry = EntryFromSerializedProto(ud.first, ud.second); + // TODO(crbug.com/973844): Clear the storage if there is data corruption. if (!entry) { - // TODO(crbug.com/973844): Handle or report this error. std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR, /* entries= */ {}); return; @@ -351,8 +362,9 @@ ContentIndexContext::GetEntryCallback callback, const std::vector<std::string>& data, blink::ServiceWorkerStatusCode status) { + content_index::RecordDatabaseOperationStatus("GetEntry", status); + if (status != blink::ServiceWorkerStatusCode::kOk) { - // TODO(crbug.com/973844): Handle or report this error. std::move(callback).Run(base::nullopt); return; }
diff --git a/content/browser/content_index/content_index_database_unittest.cc b/content/browser/content_index/content_index_database_unittest.cc index 4a7734b..43bdad4d 100644 --- a/content/browser/content_index/content_index_database_unittest.cc +++ b/content/browser/content_index/content_index_database_unittest.cc
@@ -8,6 +8,7 @@ #include "base/run_loop.h" #include "base/test/bind_test_util.h" +#include "base/test/metrics/histogram_tester.h" #include "content/browser/service_worker/embedded_worker_test_helper.h" #include "content/public/browser/content_index_provider.h" #include "content/public/test/test_browser_context.h" @@ -437,4 +438,39 @@ blink::mojom::ContentIndexError::NONE); } +TEST_F(ContentIndexDatabaseTest, UmaRecorded) { + base::HistogramTester histogram_tester; + + EXPECT_EQ(AddEntry(CreateDescription("id")), + blink::mojom::ContentIndexError::NONE); + histogram_tester.ExpectBucketCount("ContentIndex.Database.Add", + blink::ServiceWorkerStatusCode::kOk, 1); + + EXPECT_FALSE(GetIcon("id").isNull()); + histogram_tester.ExpectBucketCount("ContentIndex.Database.GetIcon", + blink::ServiceWorkerStatusCode::kOk, 1); + + EXPECT_EQ(GetAllEntries().size(), 1u); + histogram_tester.ExpectBucketCount("ContentIndex.Database.GetAllEntries", + blink::ServiceWorkerStatusCode::kOk, 1); + + EXPECT_EQ(GetDescriptions().size(), 1u); + histogram_tester.ExpectBucketCount("ContentIndex.Database.GetDescriptions", + blink::ServiceWorkerStatusCode::kOk, 1); + + EXPECT_TRUE(GetEntry("id")); + histogram_tester.ExpectBucketCount("ContentIndex.Database.GetEntry", + blink::ServiceWorkerStatusCode::kOk, 1); + + EXPECT_EQ(DeleteEntry("id"), blink::mojom::ContentIndexError::NONE); + histogram_tester.ExpectBucketCount("ContentIndex.Database.Delete", + blink::ServiceWorkerStatusCode::kOk, 1); + + database()->BlockOrigin(origin()); + AddEntry(CreateDescription("id")); + histogram_tester.ExpectBucketCount("ContentIndex.RegistrationBlocked", + blink::mojom::ContentCategory::HOME_PAGE, + 1); +} + } // namespace content
diff --git a/content/browser/content_index/content_index_metrics.cc b/content/browser/content_index/content_index_metrics.cc new file mode 100644 index 0000000..9614622ae --- /dev/null +++ b/content/browser/content_index/content_index_metrics.cc
@@ -0,0 +1,28 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/content_index/content_index_metrics.h" + +#include "base/metrics/histogram_functions.h" + +namespace content { +namespace content_index { + +void RecordDatabaseOperationStatus(const std::string& name, + blink::ServiceWorkerStatusCode status) { + base::UmaHistogramEnumeration("ContentIndex.Database." + name, status); +} + +void RecordDisptachStatus(const std::string& phase, + blink::ServiceWorkerStatusCode status_code) { + base::UmaHistogramEnumeration("ContentIndex.ContentDeleteEvent." + phase, + status_code); +} + +void RecordRegistrationBlocked(blink::mojom::ContentCategory category) { + base::UmaHistogramEnumeration("ContentIndex.RegistrationBlocked", category); +} + +} // namespace content_index +} // namespace content
diff --git a/content/browser/content_index/content_index_metrics.h b/content/browser/content_index/content_index_metrics.h new file mode 100644 index 0000000..176b7e14 --- /dev/null +++ b/content/browser/content_index/content_index_metrics.h
@@ -0,0 +1,33 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_CONTENT_INDEX_CONTENT_INDEX_METRICS_H_ +#define CONTENT_BROWSER_CONTENT_INDEX_CONTENT_INDEX_METRICS_H_ + +#include <string> + +#include "third_party/blink/public/common/service_worker/service_worker_status_code.h" +#include "third_party/blink/public/mojom/content_index/content_index.mojom.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h" + +namespace content { +namespace content_index { + +// Records the result of DB operation identified by |name|. +// |name| must be one of ContentIndexDatabaseTask. +void RecordDatabaseOperationStatus(const std::string& name, + blink::ServiceWorkerStatusCode status); + +// Records the status of dispatching the `contentdelete` event. +// |phase| must be one of ContentIndexDispatchPhase. +void RecordDisptachStatus(const std::string& phase, + blink::ServiceWorkerStatusCode status); + +// Records the category of a blocked entry. +void RecordRegistrationBlocked(blink::mojom::ContentCategory category); + +} // namespace content_index +} // namespace content + +#endif // CONTENT_BROWSER_CONTENT_INDEX_CONTENT_INDEX_METRICS_H_
diff --git a/content/browser/devtools/devtools_http_handler.cc b/content/browser/devtools/devtools_http_handler.cc index 83772ae8..90fbb4fd 100644 --- a/content/browser/devtools/devtools_http_handler.cc +++ b/content/browser/devtools/devtools_http_handler.cc
@@ -17,6 +17,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/memory/ref_counted_memory.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -792,7 +793,7 @@ std::unique_ptr<base::Thread> thread( new base::Thread(kDevToolsHandlerThreadName)); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; if (thread->StartWithOptions(options)) { auto task_runner = thread->task_runner(); task_runner->PostTask(
diff --git a/content/browser/devtools/devtools_pipe_handler.cc b/content/browser/devtools/devtools_pipe_handler.cc index d03bacc..73412287 100644 --- a/content/browser/devtools/devtools_pipe_handler.cc +++ b/content/browser/devtools/devtools_pipe_handler.cc
@@ -20,7 +20,7 @@ #include "base/command_line.h" #include "base/files/file_util.h" #include "base/memory/ref_counted_memory.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_util.h" @@ -248,7 +248,7 @@ : read_fd_(kReadFD), write_fd_(kWriteFD) { read_thread_.reset(new base::Thread(kDevToolsPipeHandlerReadThreadName)); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; if (!read_thread_->StartWithOptions(options)) { read_thread_.reset(); Shutdown();
diff --git a/content/browser/devtools/protocol/browser_handler.cc b/content/browser/devtools/protocol/browser_handler.cc index a1093fc..f1424d4 100644 --- a/content/browser/devtools/protocol/browser_handler.cc +++ b/content/browser/devtools/protocol/browser_handler.cc
@@ -44,7 +44,7 @@ if (browser_context) { PermissionControllerImpl* permission_controller = PermissionControllerImpl::FromBrowserContext(browser_context); - permission_controller->ResetPermissionOverridesForDevTools(); + permission_controller->ResetOverridesForDevTools(); } } contexts_with_overridden_permissions_.clear(); @@ -211,19 +211,21 @@ Response response = FindBrowserContext(browser_context_id, &browser_context); if (!response.isSuccess()) return response; - PermissionControllerImpl::PermissionOverrides overrides; + + std::vector<PermissionType> internal_permissions; + internal_permissions.reserve(permissions->size()); for (const protocol::Browser::PermissionType& t : *permissions) { PermissionType type; Response type_response = FromProtocolPermissionType(t, &type); if (!type_response.isSuccess()) return type_response; - overrides.insert(type); + internal_permissions.push_back(type); } PermissionControllerImpl* permission_controller = PermissionControllerImpl::FromBrowserContext(browser_context); GURL url = GURL(origin).GetOrigin(); - permission_controller->SetPermissionOverridesForDevTools(url, overrides); + permission_controller->GrantOverridesForDevTools(url, internal_permissions); contexts_with_overridden_permissions_.insert( browser_context_id.fromMaybe("")); return Response::OK(); @@ -237,7 +239,7 @@ return response; PermissionControllerImpl* permission_controller = PermissionControllerImpl::FromBrowserContext(browser_context); - permission_controller->ResetPermissionOverridesForDevTools(); + permission_controller->ResetOverridesForDevTools(); contexts_with_overridden_permissions_.erase(browser_context_id.fromMaybe("")); return Response::OK(); }
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index a22390af..4e949d2 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -18,7 +18,7 @@ #include "base/feature_list.h" #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" @@ -842,7 +842,7 @@ base::Thread::Options options; #if defined(OS_WIN) || defined(OS_MACOSX) // WGL needs to create its own window and pump messages on it. - options.message_loop_type = base::MessageLoop::TYPE_UI; + options.message_pump_type = base::MessagePumpType::UI; #endif if (base::FeatureList::IsEnabled(features::kGpuUseDisplayThreadPriority)) options.priority = base::ThreadPriority::DISPLAY;
diff --git a/content/browser/media/capture/desktop_capture_device.cc b/content/browser/media/capture/desktop_capture_device.cc index bc04d73..0ad210b 100644 --- a/content/browser/media/capture/desktop_capture_device.cc +++ b/content/browser/media/capture/desktop_capture_device.cc
@@ -14,7 +14,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" @@ -587,9 +587,9 @@ : thread_("desktopCaptureThread") { #if defined(OS_WIN) || defined(OS_MACOSX) // On Windows/OSX the thread must be a UI thread. - base::MessageLoop::Type thread_type = base::MessageLoop::TYPE_UI; + base::MessagePumpType thread_type = base::MessagePump::Type::UI; #else - base::MessageLoop::Type thread_type = base::MessageLoop::TYPE_DEFAULT; + base::MessagePumpType thread_type = base::MessagePump::Type::DEFAULT; #endif thread_.StartWithOptions(base::Thread::Options(thread_type, 0));
diff --git a/content/browser/native_file_system/native_file_system_file_handle_impl.cc b/content/browser/native_file_system/native_file_system_file_handle_impl.cc index 695447b..822d0532 100644 --- a/content/browser/native_file_system/native_file_system_file_handle_impl.cc +++ b/content/browser/native_file_system/native_file_system_file_handle_impl.cc
@@ -67,19 +67,6 @@ weak_factory_.GetWeakPtr(), std::move(callback))); } -void NativeFileSystemFileHandleImpl::Remove(RemoveCallback callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - - RunWithWritePermission( - base::BindOnce(&NativeFileSystemFileHandleImpl::RemoveImpl, - weak_factory_.GetWeakPtr()), - base::BindOnce([](RemoveCallback callback) { - std::move(callback).Run( - NativeFileSystemError::New(base::File::FILE_ERROR_ACCESS_DENIED)); - }), - std::move(callback)); -} - void NativeFileSystemFileHandleImpl::CreateFileWriter( CreateFileWriterCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -150,19 +137,6 @@ blob_ptr.PassInterface())); } -void NativeFileSystemFileHandleImpl::RemoveImpl(RemoveCallback callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - DCHECK_EQ(GetWritePermissionStatus(), - blink::mojom::PermissionStatus::GRANTED); - - operation_runner()->RemoveFile( - url(), base::BindOnce( - [](RemoveCallback callback, base::File::Error result) { - std::move(callback).Run(NativeFileSystemError::New(result)); - }, - std::move(callback))); -} - void NativeFileSystemFileHandleImpl::CreateFileWriterImpl( CreateFileWriterCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/content/browser/native_file_system/native_file_system_file_handle_impl.h b/content/browser/native_file_system/native_file_system_file_handle_impl.h index 607c2933..72d0cc3 100644 --- a/content/browser/native_file_system/native_file_system_file_handle_impl.h +++ b/content/browser/native_file_system/native_file_system_file_handle_impl.h
@@ -43,7 +43,6 @@ void RequestPermission(bool writable, RequestPermissionCallback callback) override; void AsBlob(AsBlobCallback callback) override; - void Remove(RemoveCallback callback) override; void CreateFileWriter(CreateFileWriterCallback callback) override; void Transfer( blink::mojom::NativeFileSystemTransferTokenRequest token) override; @@ -53,7 +52,6 @@ base::File::Error result, const base::File::Info& info); - void RemoveImpl(RemoveCallback callback); void CreateFileWriterImpl(CreateFileWriterCallback callback); base::WeakPtr<NativeFileSystemHandleBase> AsWeakPtr() override;
diff --git a/content/browser/permissions/permission_controller_impl.cc b/content/browser/permissions/permission_controller_impl.cc index e077653..1269594 100644 --- a/content/browser/permissions/permission_controller_impl.cc +++ b/content/browser/permissions/permission_controller_impl.cc
@@ -15,6 +15,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "third_party/blink/public/mojom/permissions/permission_status.mojom.h" +#include "url/origin.h" class GURL; @@ -22,14 +23,6 @@ namespace { -blink::mojom::PermissionStatus GetPermissionOverrideStatus( - const PermissionControllerImpl::PermissionOverrides& permission_overrides, - const PermissionType& permission) { - if (permission_overrides.find(permission) == permission_overrides.end()) - return blink::mojom::PermissionStatus::DENIED; - return blink::mojom::PermissionStatus::GRANTED; -} - base::Optional<blink::scheduler::WebSchedulerTrackedFeature> PermissionToSchedulingFeature(PermissionType permission_name) { switch (permission_name) { @@ -130,46 +123,77 @@ subscription.embedding_origin); } -void PermissionControllerImpl::SetPermissionOverridesForDevTools( - const GURL& origin, - const PermissionOverrides& overrides) { - std::vector<base::Closure> callbacks; +PermissionControllerImpl::SubscriptionsStatusMap +PermissionControllerImpl::GetSubscriptionsStatuses( + const base::Optional<GURL>& origin) { + SubscriptionsStatusMap statuses; for (SubscriptionsMap::iterator iter(&subscriptions_); !iter.IsAtEnd(); iter.Advance()) { Subscription* subscription = iter.GetCurrentValue(); - if (subscription->requesting_origin != origin) + if (origin.has_value() && subscription->requesting_origin != *origin) continue; - blink::mojom::PermissionStatus current_value = - GetSubscriptionCurrentValue(*subscription); - blink::mojom::PermissionStatus new_value = - GetPermissionOverrideStatus(overrides, subscription->permission); - if (current_value != new_value) - callbacks.push_back(base::Bind(subscription->callback, new_value)); + statuses[iter.GetCurrentKey()] = GetSubscriptionCurrentValue(*subscription); } - devtools_permission_overrides_[origin] = overrides; + return statuses; +} + +void PermissionControllerImpl::NotifyChangedSubscriptions( + const SubscriptionsStatusMap& old_statuses) { + std::vector<base::Closure> callbacks; + for (const auto& it : old_statuses) { + auto key = it.first; + Subscription* subscription = subscriptions_.Lookup(key); + if (!subscription) + continue; + blink::mojom::PermissionStatus old_status = it.second; + blink::mojom::PermissionStatus new_status = + GetSubscriptionCurrentValue(*subscription); + if (new_status != old_status) + callbacks.push_back(base::Bind(subscription->callback, new_status)); + } for (const auto& callback : callbacks) callback.Run(); } -void PermissionControllerImpl::ResetPermissionOverridesForDevTools() { - std::map<GURL, PermissionOverrides> old_overrides; - old_overrides.swap(devtools_permission_overrides_); - std::vector<base::Closure> callbacks; - for (SubscriptionsMap::iterator iter(&subscriptions_); !iter.IsAtEnd(); - iter.Advance()) { - Subscription* subscription = iter.GetCurrentValue(); - auto overrides_it = old_overrides.find(subscription->requesting_origin); - if (overrides_it == old_overrides.end()) - continue; - blink::mojom::PermissionStatus current_value = GetPermissionOverrideStatus( - overrides_it->second, subscription->permission); - blink::mojom::PermissionStatus new_value = - GetSubscriptionCurrentValue(*subscription); - if (current_value != new_value) - callbacks.push_back(base::Bind(subscription->callback, new_value)); - } - for (const auto& callback : callbacks) - callback.Run(); +void PermissionControllerImpl::GrantOverridesForDevTools( + const GURL& origin, + const std::vector<PermissionType>& permissions) { + const auto old_statuses = GetSubscriptionsStatuses(origin); + devtools_permission_overrides_.GrantPermissions(url::Origin::Create(origin), + permissions); + // If any statuses changed because they lose overrides or the new overrides + // modify their previous state (overridden or not), subscribers must be + // notified manually. + NotifyChangedSubscriptions(old_statuses); + + UpdateDelegateOverridesForDevTools(origin); +} + +void PermissionControllerImpl::ResetOverridesForDevTools() { + const auto old_statuses = GetSubscriptionsStatuses(); + devtools_permission_overrides_ = DevToolsPermissionOverrides(); + + // If any statuses changed because they lost their overrides, the subscribers + // must be notified manually. + NotifyChangedSubscriptions(old_statuses); + + PermissionControllerDelegate* delegate = + browser_context_->GetPermissionControllerDelegate(); + if (delegate) + delegate->ResetPermissionOverridesForDevTools(); +} + +void PermissionControllerImpl::UpdateDelegateOverridesForDevTools( + const GURL& origin) { + PermissionControllerDelegate* delegate = + browser_context_->GetPermissionControllerDelegate(); + if (!delegate) + return; + + // If no overrides exist, still want to update with "blank" overrides. + PermissionOverrides current_overrides = + devtools_permission_overrides_.GetAll(url::Origin::Create(origin)); + delegate->SetPermissionOverridesForDevTools(origin, current_overrides); } int PermissionControllerImpl::RequestPermission( @@ -180,9 +204,11 @@ const base::Callback<void(blink::mojom::PermissionStatus)>& callback) { NotifySchedulerAboutPermissionRequest(render_frame_host, permission); - auto it = devtools_permission_overrides_.find(requesting_origin.GetOrigin()); - if (it != devtools_permission_overrides_.end()) { - callback.Run(GetPermissionOverrideStatus(it->second, permission)); + base::Optional<blink::mojom::PermissionStatus> status_override = + devtools_permission_overrides_.Get(url::Origin::Create(requesting_origin), + permission); + if (status_override.has_value()) { + callback.Run(*status_override); return kNoPendingOperation; } @@ -206,12 +232,22 @@ for (PermissionType permission : permissions) NotifySchedulerAboutPermissionRequest(render_frame_host, permission); - auto it = devtools_permission_overrides_.find(requesting_origin.GetOrigin()); - if (it != devtools_permission_overrides_.end()) { - std::vector<blink::mojom::PermissionStatus> result; - for (auto& permission : permissions) - result.push_back(GetPermissionOverrideStatus(it->second, permission)); - callback.Run(result); + const PermissionOverrides& overrides = devtools_permission_overrides_.GetAll( + url::Origin::Create(requesting_origin)); + if (!overrides.empty()) { + std::vector<blink::mojom::PermissionStatus> results; + for (const auto& permission : permissions) { + auto it = overrides.find(permission); + // TODO(rohpavone): This approach will not work when using SetPermissions, + // because can no longer assume that all overrides are specified is + // removed. + if (it == overrides.end()) + results.push_back(blink::mojom::PermissionStatus::DENIED); + else + results.push_back(it->second); + } + + callback.Run(results); return kNoPendingOperation; } @@ -232,9 +268,11 @@ PermissionType permission, const GURL& requesting_origin, const GURL& embedding_origin) { - auto it = devtools_permission_overrides_.find(requesting_origin.GetOrigin()); - if (it != devtools_permission_overrides_.end()) - return GetPermissionOverrideStatus(it->second, permission); + base::Optional<blink::mojom::PermissionStatus> status = + devtools_permission_overrides_.Get(url::Origin::Create(requesting_origin), + permission); + if (status.has_value()) + return *status; PermissionControllerDelegate* delegate = browser_context_->GetPermissionControllerDelegate(); @@ -249,9 +287,11 @@ PermissionType permission, RenderFrameHost* render_frame_host, const GURL& requesting_origin) { - auto it = devtools_permission_overrides_.find(requesting_origin.GetOrigin()); - if (it != devtools_permission_overrides_.end()) - return GetPermissionOverrideStatus(it->second, permission); + base::Optional<blink::mojom::PermissionStatus> status = + devtools_permission_overrides_.Get(url::Origin::Create(requesting_origin), + permission); + if (status.has_value()) + return *status; PermissionControllerDelegate* delegate = browser_context_->GetPermissionControllerDelegate(); @@ -274,9 +314,11 @@ void PermissionControllerImpl::OnDelegatePermissionStatusChange( Subscription* subscription, blink::mojom::PermissionStatus status) { - auto overrides_it = - devtools_permission_overrides_.find(subscription->requesting_origin); - if (overrides_it == devtools_permission_overrides_.end()) + base::Optional<blink::mojom::PermissionStatus> status_override = + devtools_permission_overrides_.Get( + url::Origin::Create(subscription->requesting_origin), + subscription->permission); + if (!status_override.has_value()) subscription->callback.Run(status); }
diff --git a/content/browser/permissions/permission_controller_impl.h b/content/browser/permissions/permission_controller_impl.h index f6f0c2c..96e0dc6f 100644 --- a/content/browser/permissions/permission_controller_impl.h +++ b/content/browser/permissions/permission_controller_impl.h
@@ -7,6 +7,7 @@ #include "base/containers/id_map.h" #include "content/common/content_export.h" +#include "content/public/browser/devtools_permission_overrides.h" #include "content/public/browser/permission_controller.h" #include "url/gurl.h" @@ -25,12 +26,14 @@ static PermissionControllerImpl* FromBrowserContext( BrowserContext* browser_context); - using PermissionOverrides = std::set<PermissionType>; - // For the given |origin|, grant permissions that belong to |overrides| - // and reject all others. - void SetPermissionOverridesForDevTools(const GURL& origin, - const PermissionOverrides& overrides); - void ResetPermissionOverridesForDevTools(); + using PermissionOverrides = DevToolsPermissionOverrides::PermissionOverrides; + + // For the given |origin|, grant permissions in |overrides| and reject all + // others. + void GrantOverridesForDevTools( + const GURL& origin, + const std::vector<PermissionType>& permissions); + void ResetOverridesForDevTools(); // PermissionController implementation. blink::mojom::PermissionStatus GetPermissionStatus( @@ -73,13 +76,19 @@ private: struct Subscription; using SubscriptionsMap = base::IDMap<std::unique_ptr<Subscription>>; + using SubscriptionsStatusMap = + base::flat_map<SubscriptionsMap::KeyType, blink::mojom::PermissionStatus>; blink::mojom::PermissionStatus GetSubscriptionCurrentValue( const Subscription& subscription); + SubscriptionsStatusMap GetSubscriptionsStatuses( + const base::Optional<GURL>& origin = base::nullopt); + void NotifyChangedSubscriptions(const SubscriptionsStatusMap& old_statuses); void OnDelegatePermissionStatusChange(Subscription* subscription, blink::mojom::PermissionStatus status); + void UpdateDelegateOverridesForDevTools(const GURL& origin); - std::map<GURL, PermissionOverrides> devtools_permission_overrides_; + DevToolsPermissionOverrides devtools_permission_overrides_; SubscriptionsMap subscriptions_; BrowserContext* browser_context_;
diff --git a/content/browser/renderer_host/input/scroll_latency_browsertest.cc b/content/browser/renderer_host/input/scroll_latency_browsertest.cc index 1f98c08..876685f 100644 --- a/content/browser/renderer_host/input/scroll_latency_browsertest.cc +++ b/content/browser/renderer_host/input/scroll_latency_browsertest.cc
@@ -223,6 +223,15 @@ mouse_down.SetTimeStamp(base::TimeTicks::Now()); GetWidgetHost()->ForwardMouseEvent(mouse_down); + // This is to avoid a race condition where a mousemove is processed before + // the renderer has had a chance to set up the scroll state (like the + // scroll_node etc). This happens due to the fact that when the renderer + // gets a mousedown, it is first "queued" as a GSB. At this point, the + // scroll node is not yet set up. Now, if a mousemove is sent from the + // browser proc before a frame is generated, it gets dispatched immediately + // and this can lead to nullptr derefernces. + RunUntilInputProcessed(GetWidgetHost()); + blink::WebMouseEvent mouse_move = SyntheticWebMouseEventBuilder::Build( blink::WebInputEvent::kMouseMove, scrollbar_thumb.x, scrollbar_thumb.y + 10, 0);
diff --git a/content/browser/renderer_host/input/touch_emulator.cc b/content/browser/renderer_host/input/touch_emulator.cc index 26498b6..3d1b90fe 100644 --- a/content/browser/renderer_host/input/touch_emulator.cc +++ b/content/browser/renderer_host/input/touch_emulator.cc
@@ -187,7 +187,7 @@ client_->ShowContextMenuAtPoint( gfx::Point(mouse_event.PositionInWidget().x, mouse_event.PositionInWidget().y), - ui::MENU_SOURCE_MOUSE); + ui::MENU_SOURCE_MOUSE, target_view); } if (mouse_event.button != WebMouseEvent::Button::kLeft)
diff --git a/content/browser/renderer_host/input/touch_emulator_client.h b/content/browser/renderer_host/input/touch_emulator_client.h index 4f398b0..fb7fede 100644 --- a/content/browser/renderer_host/input/touch_emulator_client.h +++ b/content/browser/renderer_host/input/touch_emulator_client.h
@@ -25,8 +25,10 @@ virtual void ForwardEmulatedTouchEvent(const blink::WebTouchEvent& event, RenderWidgetHostViewBase* target) = 0; virtual void SetCursor(const WebCursor& cursor) = 0; + // |target| is the view associated with the corresponding input event. virtual void ShowContextMenuAtPoint(const gfx::Point& point, - const ui::MenuSourceType source_type) = 0; + const ui::MenuSourceType source_type, + RenderWidgetHostViewBase* target) = 0; }; } // namespace content
diff --git a/content/browser/renderer_host/input/touch_emulator_unittest.cc b/content/browser/renderer_host/input/touch_emulator_unittest.cc index 4cffb84..b95f1aa1 100644 --- a/content/browser/renderer_host/input/touch_emulator_unittest.cc +++ b/content/browser/renderer_host/input/touch_emulator_unittest.cc
@@ -89,7 +89,8 @@ } void ShowContextMenuAtPoint(const gfx::Point& point, - const ui::MenuSourceType source_type) override {} + const ui::MenuSourceType source_type, + RenderWidgetHostViewBase* target) override {} protected: TouchEmulator* emulator() const {
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 2d28692..cad7a97 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -34,7 +34,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/shared_memory_mapping.h" #include "base/memory/writable_shared_memory_region.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram_base.h" #include "base/metrics/histogram_macros.h" @@ -1691,11 +1691,11 @@ base::Thread::Options options; #if defined(OS_WIN) && !defined(OS_MACOSX) // In-process plugins require this to be a UI message loop. - options.message_loop_type = base::MessageLoop::TYPE_UI; + options.message_pump_type = base::MessagePumpType::UI; #else // We can't have multiple UI loops on Linux and Android, so we don't support // in-process plugins. - options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; + options.message_pump_type = base::MessagePumpType::DEFAULT; #endif // As for execution sequence, this callback should have no any dependency // on starting in-process-render-thread.
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 8278ff4f..0ccc622 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1272,11 +1272,6 @@ input_router_->WaitForInputProcessed(std::move(callback)); } -void RenderWidgetHostImpl::ForwardEmulatedGestureEvent( - const blink::WebGestureEvent& gesture_event) { - ForwardGestureEvent(gesture_event); -} - void RenderWidgetHostImpl::ForwardGestureEvent( const blink::WebGestureEvent& gesture_event) { ForwardGestureEventWithLatencyInfo( @@ -1390,14 +1385,6 @@ } } -void RenderWidgetHostImpl::ForwardEmulatedTouchEvent( - const blink::WebTouchEvent& touch_event, - RenderWidgetHostViewBase* target) { - TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardEmulatedTouchEvent"); - ForwardTouchEventWithLatencyInfo(touch_event, - ui::LatencyInfo(ui::SourceEventType::TOUCH)); -} - void RenderWidgetHostImpl::ForwardTouchEventWithLatencyInfo( const blink::WebTouchEvent& touch_event, const ui::LatencyInfo& latency) {
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 9583543..cf54a5f 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -127,7 +127,6 @@ public InputDispositionHandler, public RenderProcessHostImpl::PriorityClient, public RenderProcessHostObserver, - public TouchEmulatorClient, public SyntheticGestureController::Delegate, public viz::mojom::CompositorFrameSink, public IPC::Listener, @@ -439,14 +438,9 @@ // Returns an emulator for this widget. See TouchEmulator for more details. TouchEmulator* GetTouchEmulator(); - // TouchEmulatorClient implementation. - void ForwardEmulatedGestureEvent( - const blink::WebGestureEvent& gesture_event) override; - void ForwardEmulatedTouchEvent(const blink::WebTouchEvent& touch_event, - RenderWidgetHostViewBase* target) override; - void SetCursor(const WebCursor& cursor) override; + void SetCursor(const WebCursor& cursor); void ShowContextMenuAtPoint(const gfx::Point& point, - const ui::MenuSourceType source_type) override; + const ui::MenuSourceType source_type); // Queues a synthetic gesture for testing purposes. Invokes the on_complete // callback when the gesture is finished running.
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc index d3d024f4..8389fbd 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router.cc +++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -1933,15 +1933,11 @@ void RenderWidgetHostInputEventRouter::ShowContextMenuAtPoint( const gfx::Point& point, - const ui::MenuSourceType source_type) { - // It's possible that since |last_mouse_move_target_| was set by the - // outbound mouse event that the view may have gone away. Before dispatching - // the context menu, confirm the view is still available. - if (!IsViewInMap(last_mouse_move_target_)) - return; - - auto* rwhi = static_cast<RenderWidgetHostImpl*>( - last_mouse_move_target_->GetRenderWidgetHost()); + const ui::MenuSourceType source_type, + RenderWidgetHostViewBase* target) { + DCHECK(IsViewInMap(target)); + auto* rwhi = + static_cast<RenderWidgetHostImpl*>(target->GetRenderWidgetHost()); DCHECK(rwhi); rwhi->ShowContextMenuAtPoint(point, source_type); }
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.h b/content/browser/renderer_host/render_widget_host_input_event_router.h index 8e91fe7..3eee383 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router.h +++ b/content/browser/renderer_host/render_widget_host_input_event_router.h
@@ -172,7 +172,8 @@ RenderWidgetHostViewBase* target) override; void SetCursor(const WebCursor& cursor) override; void ShowContextMenuAtPoint(const gfx::Point& point, - const ui::MenuSourceType source_type) override; + const ui::MenuSourceType source_type, + RenderWidgetHostViewBase* target) override; // HitTestRegionObserver void OnAggregatedHitTestRegionListUpdated(
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc b/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc index 21920184..29d6e84 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
@@ -900,4 +900,12 @@ EXPECT_NE(view_root_.get(), bubbling_gesture_scroll_target()); } +// Calling ShowContextMenuAtPoint without other events will happen when desktop +// devtools connect to a browser instance running on a mobile. It should not +// crash. +TEST_F(RenderWidgetHostInputEventRouterTest, CanCallShowContextMenuAtPoint) { + rwhier()->ShowContextMenuAtPoint(gfx::Point(0, 0), ui::MENU_SOURCE_MOUSE, + view_root_.get()); +} + } // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index a0a61eff..c97e3c3a 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -297,7 +297,6 @@ bool HasValidFrame() const; void MoveCaret(const gfx::Point& point); - void ShowContextMenuAtPoint(const gfx::Point& point, ui::MenuSourceType); void DismissTextHandles(); void SetTextHandlesTemporarilyHidden(bool hide_handles); void SelectWordAroundCaretAck(bool did_select,
diff --git a/content/browser/scheduler/browser_task_executor.cc b/content/browser/scheduler/browser_task_executor.cc index 3025bd30..197ab5d 100644 --- a/content/browser/scheduler/browser_task_executor.cc +++ b/content/browser/scheduler/browser_task_executor.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/deferred_sequenced_task_runner.h" +#include "base/message_loop/message_pump_type.h" #include "base/no_destructor.h" #include "base/task/post_task.h" #include "base/threading/thread_task_runner_handle.h" @@ -277,7 +278,7 @@ } base::Thread::Options options; - options.message_loop_type = base::MessagePump::Type::IO; + options.message_pump_type = base::MessagePumpType::IO; options.task_environment = g_browser_task_executor->browser_io_task_environment_.release(); // Up the priority of the |io_thread_| as some of its IPCs relate to
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc index 2ac4547a..29d0295 100644 --- a/content/browser/service_manager/service_manager_context.cc +++ b/content/browser/service_manager/service_manager_context.cc
@@ -17,7 +17,7 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/no_destructor.h" #include "base/optional.h" #include "base/process/process_handle.h" @@ -667,7 +667,7 @@ scoped_refptr<base::SequencedTaskRunner> task_runner = service_manager_thread_task_runner_; if (base::FeatureList::IsEnabled(kNetworkServiceDedicatedThread)) { - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); network_service_thread_.StartWithOptions(options); task_runner = network_service_thread_.task_runner(); }
diff --git a/content/child/child_process.cc b/content/child/child_process.cc index 7765881..6b0532c 100644 --- a/content/child/child_process.cc +++ b/content/child/child_process.cc
@@ -8,7 +8,7 @@ #include "base/bind.h" #include "base/lazy_instance.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/process/process_handle.h" #include "base/single_thread_task_runner.h" #include "base/task/thread_pool/thread_pool.h" @@ -53,7 +53,7 @@ } // We can't recover from failing to start the IO thread. - base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options thread_options(base::MessagePumpType::IO, 0); thread_options.priority = io_thread_priority; #if defined(OS_ANDROID) // TODO(reveman): Remove this in favor of setting it explicitly for each type
diff --git a/content/common/throttling_url_loader.cc b/content/common/throttling_url_loader.cc index 280d850f0..209a1ee 100644 --- a/content/common/throttling_url_loader.cc +++ b/content/common/throttling_url_loader.cc
@@ -117,6 +117,14 @@ loader_->RestartWithFlags(additional_load_flags); } + void RestartWithURLResetAndFlags(int additional_load_flags) override { + if (!loader_) + return; + + ScopedDelegateCall scoped_delegate_call(this); + loader_->RestartWithURLResetAndFlags(additional_load_flags); + } + void Detach() { loader_ = nullptr; } private: @@ -322,16 +330,16 @@ bool deferred = false; DCHECK(deferring_throttles_.empty()); if (!throttles_.empty()) { + original_url_ = url_request->url; for (auto& entry : throttles_) { auto* throttle = entry.throttle.get(); bool throttle_deferred = false; - GURL original_url = url_request->url; throttle->WillStartRequest(url_request, &throttle_deferred); - if (original_url != url_request->url) { + if (original_url_ != url_request->url) { DCHECK(throttle_will_start_redirect_url_.is_empty()) << "ThrottlingURLLoader doesn't support multiple throttles " "changing the URL."; - if (original_url.SchemeIsHTTPOrHTTPS() && + if (original_url_.SchemeIsHTTPOrHTTPS() && !url_request->url.SchemeIsHTTPOrHTTPS() && !throttle->makes_unsafe_redirect()) { NOTREACHED() << "A URLLoaderThrottle can't redirect from http(s) to " @@ -341,7 +349,7 @@ } // Restore the original URL so that all throttles see the same original // URL. - url_request->url = original_url; + url_request->url = original_url_; } if (!HandleThrottleResult(throttle, throttle_deferred, &deferred)) return; @@ -359,6 +367,10 @@ void ThrottlingURLLoader::StartNow() { DCHECK(start_info_); + if (throttle_will_start_original_url_) { + throttle_will_start_redirect_url_ = original_url_; + throttle_will_start_original_url_ = false; + } if (!throttle_will_start_redirect_url_.is_empty()) { auto first_party_url_policy = start_info_->url_request.update_first_party_url_on_redirect @@ -488,6 +500,13 @@ has_pending_restart_ = true; } +void ThrottlingURLLoader::RestartWithURLResetAndFlags( + int additional_load_flags) { + pending_restart_flags_ |= additional_load_flags; + throttle_will_start_original_url_ = true; + has_pending_restart_ = true; +} + void ThrottlingURLLoader::OnReceiveResponse( const network::ResourceResponseHead& response_head) { DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
diff --git a/content/common/throttling_url_loader.h b/content/common/throttling_url_loader.h index 2ab4d7bb..efac175f 100644 --- a/content/common/throttling_url_loader.h +++ b/content/common/throttling_url_loader.h
@@ -114,6 +114,9 @@ void RestartWithFlags(int additional_load_flags); + // Restart the request using |original_url_|. + void RestartWithURLResetAndFlags(int additional_load_flags); + // network::mojom::URLLoaderClient implementation: void OnReceiveResponse( const network::ResourceResponseHead& response_head) override; @@ -248,6 +251,11 @@ // Only supported with the network service. GURL throttle_will_redirect_redirect_url_; + // Set if the request should be made using the |original_url_|. + bool throttle_will_start_original_url_ = false; + // The first URL seen by the throttle. + GURL original_url_; + const net::NetworkTrafficAnnotationTag traffic_annotation_; uint32_t inside_delegate_calls_ = 0;
diff --git a/content/common/throttling_url_loader_unittest.cc b/content/common/throttling_url_loader_unittest.cc index 8cdc30f74..4b0a9c8 100644 --- a/content/common/throttling_url_loader_unittest.cc +++ b/content/common/throttling_url_loader_unittest.cc
@@ -1756,5 +1756,973 @@ } } +// Call RestartWithURLResetAndFlags() from a single throttle while processing +// BeforeWillProcessResponse(), and verify that it restarts with the original +// URL. +TEST_F(ThrottlingURLLoaderTest, RestartWithURLResetAndFlags) { + base::RunLoop run_loop1; + base::RunLoop run_loop2; + base::RunLoop run_loop3; + + // URL for internal redirect. + GURL modified_url = GURL("www.example.uk.com"); + throttle_->set_modify_url_in_will_start(modified_url); + + // Check that the initial loader uses the default load flags (0). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(0, url_request.load_flags); + quit_closure.Run(); + }, + run_loop1.QuitClosure())); + + // Set the client to actually follow redirects to allow URL resetting to + // occur. + client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() { + net::HttpRequestHeaders modified_headers; + loader_->FollowRedirect({} /* removed_headers */, + std::move(modified_headers)); + })); + + // Restart the request when processing BeforeWillProcessResponse(), using + // different load flags (1), and an URL reset. + throttle_->set_before_will_process_response_callback(base::BindRepeating( + [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { + delegate->RestartWithURLResetAndFlags(1); + })); + + CreateLoaderAndStart(); + + run_loop1.Run(); + + EXPECT_EQ(1u, factory_.create_loader_and_start_called()); + EXPECT_EQ(1u, throttle_->will_start_request_called()); + EXPECT_EQ(0u, throttle_->will_redirect_request_called()); + EXPECT_EQ(0u, throttle_->before_will_process_response_called()); + EXPECT_EQ(0u, throttle_->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), modified_url); + + // The next time we intercept CreateLoaderAndStart() should be for the + // restarted request (load flags of 1). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(1, url_request.load_flags); + quit_closure.Run(); + }, + run_loop2.QuitClosure())); + + factory_.NotifyClientOnReceiveResponse(); + + run_loop2.Run(); + + // Now that the restarted request has been made, clear + // BeforeWillProcessResponse() so it doesn't restart the request yet again. + throttle_->set_before_will_process_response_callback( + TestURLLoaderThrottle::ThrottleCallback()); + + client_.set_on_complete_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int error) { + EXPECT_EQ(net::OK, error); + quit_closure.Run(); + }, + run_loop3.QuitClosure())); + + // Complete the response. + factory_.NotifyClientOnReceiveResponse(); + factory_.NotifyClientOnComplete(net::OK); + + run_loop3.Run(); + + EXPECT_EQ(2u, factory_.create_loader_and_start_called()); + EXPECT_EQ(1u, throttle_->will_start_request_called()); + EXPECT_EQ(1u, throttle_->will_redirect_request_called()); + EXPECT_EQ(2u, throttle_->before_will_process_response_called()); + EXPECT_EQ(1u, throttle_->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), request_url); +} + +// Call RestartWithURLResetAndFlags() from a single throttle after having +// deferred BeforeWillProcessResponse(), and verify it uses the original URL. +TEST_F(ThrottlingURLLoaderTest, DeferThenRestartWithURLResetAndFlags) { + base::RunLoop run_loop1; + base::RunLoop run_loop2; + base::RunLoop run_loop3; + base::RunLoop run_loop4; + + // URL for internal redirect. + GURL modified_url = GURL("www.example.uk.com"); + throttle_->set_modify_url_in_will_start(modified_url); + + // Check that the initial loader uses the default load flags (0). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(0, url_request.load_flags); + quit_closure.Run(); + }, + run_loop1.QuitClosure())); + + // Set the client to actually follow redirects to allow URL resetting to + // occur. + client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() { + net::HttpRequestHeaders modified_headers; + loader_->FollowRedirect({} /* removed_headers */, + std::move(modified_headers)); + })); + + // Defer BeforeWillProcessResponse(). + throttle_->set_before_will_process_response_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { + *defer = true; + quit_closure.Run(); + }, + run_loop2.QuitClosure())); + + CreateLoaderAndStart(); + + run_loop1.Run(); + + EXPECT_EQ(1u, factory_.create_loader_and_start_called()); + EXPECT_EQ(1u, throttle_->will_start_request_called()); + EXPECT_EQ(0u, throttle_->will_redirect_request_called()); + EXPECT_EQ(0u, throttle_->before_will_process_response_called()); + EXPECT_EQ(0u, throttle_->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), modified_url); + + factory_.NotifyClientOnReceiveResponse(); + + run_loop2.Run(); + + EXPECT_EQ(1u, factory_.create_loader_and_start_called()); + EXPECT_EQ(1u, throttle_->will_start_request_called()); + EXPECT_EQ(0u, throttle_->will_redirect_request_called()); + EXPECT_EQ(1u, throttle_->before_will_process_response_called()); + EXPECT_EQ(0u, throttle_->will_process_response_called()); + + // The next time we intercept CreateLoaderAndStart() should be for the + // restarted request (load flags of 1). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(1, url_request.load_flags); + quit_closure.Run(); + }, + run_loop3.QuitClosure())); + + throttle_->delegate()->RestartWithURLResetAndFlags(1); + throttle_->delegate()->Resume(); + + run_loop3.Run(); + + // Now that the restarted request has been made, clear + // BeforeWillProcessResponse(). + throttle_->set_before_will_process_response_callback( + TestURLLoaderThrottle::ThrottleCallback()); + + client_.set_on_complete_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int error) { + EXPECT_EQ(net::OK, error); + quit_closure.Run(); + }, + run_loop4.QuitClosure())); + + // Complete the response. + factory_.NotifyClientOnReceiveResponse(); + factory_.NotifyClientOnComplete(net::OK); + + run_loop4.Run(); + + EXPECT_EQ(2u, factory_.create_loader_and_start_called()); + EXPECT_EQ(1u, throttle_->will_start_request_called()); + EXPECT_EQ(1u, throttle_->will_redirect_request_called()); + EXPECT_EQ(2u, throttle_->before_will_process_response_called()); + EXPECT_EQ(1u, throttle_->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), request_url); +} + +// Call RestartWithURLResetFlags() from a multiple throttles while processing +// BeforeWillProcessResponse(). Ensures that the request is restarted exactly +// once, using the combination of all additional load flags, and with the +// original URL. +TEST_F(ThrottlingURLLoaderTest, MultipleRestartWithURLResetAndFlags) { + // Create two additional TestURLLoaderThrottles for a total of 3, and keep + // local unowned pointers to them in |throttles|. + std::vector<TestURLLoaderThrottle*> throttles; + ASSERT_EQ(1u, throttles_.size()); + throttles.push_back(throttle_); + for (size_t i = 0; i < 2u; ++i) { + auto throttle = std::make_unique<TestURLLoaderThrottle>(); + throttles.push_back(throttle.get()); + throttles_.push_back(std::move(throttle)); + } + ASSERT_EQ(3u, throttles_.size()); + ASSERT_EQ(3u, throttles.size()); + + base::RunLoop run_loop1; + base::RunLoop run_loop2; + base::RunLoop run_loop3; + + // URL for internal redirect. + GURL modified_url = GURL("www.example.uk.com"); + throttle_->set_modify_url_in_will_start(modified_url); + + // Check that the initial loader uses the default load flags (0). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(0, url_request.load_flags); + quit_closure.Run(); + }, + run_loop1.QuitClosure())); + + // Set the client to actually follow redirects to allow URL resetting to + // occur. + client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() { + net::HttpRequestHeaders modified_headers; + loader_->FollowRedirect({} /* removed_headers */, + std::move(modified_headers)); + })); + + // Have two of the three throttles restart whe processing + // BeforeWillProcessResponse(), using + // different load flags (2 and 8), but both with URL resets. + throttles[0]->set_before_will_process_response_callback(base::BindRepeating( + [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { + delegate->RestartWithURLResetAndFlags(2); + })); + throttles[2]->set_before_will_process_response_callback(base::BindRepeating( + [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { + delegate->RestartWithURLResetAndFlags(8); + })); + + CreateLoaderAndStart(); + + run_loop1.Run(); + + EXPECT_EQ(1u, factory_.create_loader_and_start_called()); + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(0u, throttle->will_redirect_request_called()); + EXPECT_EQ(0u, throttle->before_will_process_response_called()); + EXPECT_EQ(0u, throttle->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), modified_url); + } + + // The next time we intercept CreateLoaderAndStart() should be for the + // restarted request (load flags of 10 = (2 | 8)). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(10, url_request.load_flags); + quit_closure.Run(); + }, + run_loop2.QuitClosure())); + + factory_.NotifyClientOnReceiveResponse(); + + run_loop2.Run(); + + // Now that the restarted request has been made, clear + // BeforeWillProcessResponse() so it doesn't restart the request yet again. + for (auto* throttle : throttles) { + throttle->set_before_will_process_response_callback( + TestURLLoaderThrottle::ThrottleCallback()); + } + + client_.set_on_complete_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int error) { + EXPECT_EQ(net::OK, error); + quit_closure.Run(); + }, + run_loop3.QuitClosure())); + + // Complete the response. + factory_.NotifyClientOnReceiveResponse(); + factory_.NotifyClientOnComplete(net::OK); + + run_loop3.Run(); + + EXPECT_EQ(2u, factory_.create_loader_and_start_called()); + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(1u, throttle->will_redirect_request_called()); + EXPECT_EQ(2u, throttle->before_will_process_response_called()); + EXPECT_EQ(1u, throttle->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), request_url); + } +} + +// Call RestartWithURLResetAndFlags() from multiple throttles after having +// deferred BeforeWillProcessResponse() in each. Ensures that the request is +// started exactly once, using the combination of all additional load flags, +// and with the original URL. +TEST_F(ThrottlingURLLoaderTest, MultipleDeferThenRestartWithURLResetAndFlags) { + // Create two additional TestURLLoaderThrottles for a total of 3, and keep + // local unowned pointers to them in |throttles|. + std::vector<TestURLLoaderThrottle*> throttles; + ASSERT_EQ(1u, throttles_.size()); + throttles.push_back(throttle_); + for (size_t i = 0; i < 2u; ++i) { + auto throttle = std::make_unique<TestURLLoaderThrottle>(); + throttles.push_back(throttle.get()); + throttles_.push_back(std::move(throttle)); + } + + ASSERT_EQ(3u, throttles_.size()); + ASSERT_EQ(3u, throttles.size()); + + base::RunLoop run_loop1; + base::RunLoop run_loop2; + base::RunLoop run_loop3; + base::RunLoop run_loop4; + + // URL for internal redirect. + GURL modified_url = GURL("www.example.uk.com"); + throttle_->set_modify_url_in_will_start(modified_url); + + // Check that the initial loader uses the default load flags (0). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(0, url_request.load_flags); + quit_closure.Run(); + }, + run_loop1.QuitClosure())); + + // Set the client to actually follow redirects to allow URL resetting to + // occur. + client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() { + net::HttpRequestHeaders modified_headers; + loader_->FollowRedirect({} /* removed_headers */, + std::move(modified_headers)); + })); + + // Have all of the throttles defer. Once they have all been deferred, quit + // run_loop2. + int throttle_counter = 0; + for (auto* throttle : throttles) { + throttle->set_before_will_process_response_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int* count, + blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { + *defer = true; + if (++(*count) == 3) { + quit_closure.Run(); + } + }, + run_loop2.QuitClosure(), &throttle_counter)); + } + + CreateLoaderAndStart(); + + run_loop1.Run(); + + EXPECT_EQ(1u, factory_.create_loader_and_start_called()); + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(0u, throttle->will_redirect_request_called()); + EXPECT_EQ(0u, throttle->before_will_process_response_called()); + EXPECT_EQ(0u, throttle->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), modified_url); + } + + factory_.NotifyClientOnReceiveResponse(); + + run_loop2.Run(); + + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(0u, throttle->will_redirect_request_called()); + EXPECT_EQ(1u, throttle->before_will_process_response_called()); + EXPECT_EQ(0u, throttle->will_process_response_called()); + } + + // The next time we intercept CreateLoaderAndStart() should be for the + // restarted request (load flags of 1 | 2 | 4). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(7, url_request.load_flags); + quit_closure.Run(); + }, + run_loop3.QuitClosure())); + + int next_load_flag = 1; + for (auto* throttle : throttles) { + throttle->delegate()->RestartWithURLResetAndFlags(next_load_flag); + throttle->delegate()->Resume(); + next_load_flag <<= 1; + } + + run_loop3.Run(); + + // Now that the restarted request has been made, clear + // BeforeWillProcessResponse(). + for (auto* throttle : throttles) { + throttle->set_before_will_process_response_callback( + TestURLLoaderThrottle::ThrottleCallback()); + } + + client_.set_on_complete_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int error) { + EXPECT_EQ(net::OK, error); + quit_closure.Run(); + }, + run_loop4.QuitClosure())); + + // Complete the response. + factory_.NotifyClientOnReceiveResponse(); + factory_.NotifyClientOnComplete(net::OK); + + run_loop4.Run(); + + EXPECT_EQ(2u, factory_.create_loader_and_start_called()); + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(1u, throttle->will_redirect_request_called()); + EXPECT_EQ(2u, throttle->before_will_process_response_called()); + EXPECT_EQ(1u, throttle->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), request_url); + } +} + +// Call RestartWithURLResetAndFlags() from multiple throttles -- two while +// deferred, and one while processing BeforeWillProcessResponse(). Ensures that +// the request is restarted exactly once, using the combination of all +// additional load flags, and that the restarted requests use the original URL. +TEST_F(ThrottlingURLLoaderTest, + MultipleRestartWithURLResetAndFlagsDeferAndSync) { + // Create two additional TestURLLoaderThrottles for a total of 3, and keep + // local unowned pointers to them in |throttles|. + std::vector<TestURLLoaderThrottle*> throttles; + ASSERT_EQ(1u, throttles_.size()); + throttles.push_back(throttle_); + for (size_t i = 0; i < 2u; ++i) { + auto throttle = std::make_unique<TestURLLoaderThrottle>(); + throttles.push_back(throttle.get()); + throttles_.push_back(std::move(throttle)); + } + + ASSERT_EQ(3u, throttles_.size()); + ASSERT_EQ(3u, throttles.size()); + + base::RunLoop run_loop1; + base::RunLoop run_loop2; + base::RunLoop run_loop3; + base::RunLoop run_loop4; + + // URL for internal redirect. + GURL modified_url = GURL("www.example.uk.com"); + throttle_->set_modify_url_in_will_start(modified_url); + + // Check that the initial loader uses the default load flags (0). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(0, url_request.load_flags); + quit_closure.Run(); + }, + run_loop1.QuitClosure())); + + // Set the client to actually follow redirects to allow URL resetting to + // occur. + client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() { + net::HttpRequestHeaders modified_headers; + loader_->FollowRedirect({} /* removed_headers */, + std::move(modified_headers)); + })); + + // Have two of the throttles defer, and one call restart + // synchronously. Once all are run, quit run_loop2. + int throttle_counter = 0; + for (size_t i = 0; i < 2u; ++i) { + throttles[i]->set_before_will_process_response_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int* count, + blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { + *defer = true; + if (++(*count) == 3) { + quit_closure.Run(); + } + }, + run_loop2.QuitClosure(), &throttle_counter)); + } + throttles[2]->set_before_will_process_response_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int* count, + blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { + delegate->RestartWithURLResetAndFlags(4); + if (++(*count) == 3) { + quit_closure.Run(); + } + }, + run_loop2.QuitClosure(), &throttle_counter)); + + CreateLoaderAndStart(); + + run_loop1.Run(); + + EXPECT_EQ(1u, factory_.create_loader_and_start_called()); + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(0u, throttle->will_redirect_request_called()); + EXPECT_EQ(0u, throttle->before_will_process_response_called()); + EXPECT_EQ(0u, throttle->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), modified_url); + } + + factory_.NotifyClientOnReceiveResponse(); + + run_loop2.Run(); + + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(0u, throttle->will_redirect_request_called()); + EXPECT_EQ(1u, throttle->before_will_process_response_called()); + EXPECT_EQ(0u, throttle->will_process_response_called()); + } + + // The next time we intercept CreateLoaderAndStart() should be for the + // restarted request (load flags of 1 | 2 | 4). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(7, url_request.load_flags); + quit_closure.Run(); + }, + run_loop3.QuitClosure())); + + int next_load_flag = 1; + for (auto* throttle : throttles) { + throttle->delegate()->RestartWithURLResetAndFlags(next_load_flag); + throttle->delegate()->Resume(); + next_load_flag <<= 1; + } + + run_loop3.Run(); + + // Now that the restarted request has been made, clear + // BeforeWillProcessResponse(). + for (auto* throttle : throttles) { + throttle->set_before_will_process_response_callback( + TestURLLoaderThrottle::ThrottleCallback()); + } + + client_.set_on_complete_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int error) { + EXPECT_EQ(net::OK, error); + quit_closure.Run(); + }, + run_loop4.QuitClosure())); + + // Complete the response. + factory_.NotifyClientOnReceiveResponse(); + factory_.NotifyClientOnComplete(net::OK); + + run_loop4.Run(); + + EXPECT_EQ(2u, factory_.create_loader_and_start_called()); + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(1u, throttle->will_redirect_request_called()); + EXPECT_EQ(2u, throttle->before_will_process_response_called()); + EXPECT_EQ(1u, throttle->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), request_url); + } +} + +// Call RestartWithFlags() and RestartWithURLResetFlags() from separate +// throttles while processing BeforeWillProcessResponse(). Ensures that the +// request is restarted exactly once, using the combination of all additional +// load flags, and with the original URL. +TEST_F(ThrottlingURLLoaderTest, MultipleRestartsOfMultipleTypes) { + // Create two additional TestURLLoaderThrottles for a total of 3, and keep + // local unowned pointers to them in |throttles|. + std::vector<TestURLLoaderThrottle*> throttles; + ASSERT_EQ(1u, throttles_.size()); + throttles.push_back(throttle_); + for (size_t i = 0; i < 2u; ++i) { + auto throttle = std::make_unique<TestURLLoaderThrottle>(); + throttles.push_back(throttle.get()); + throttles_.push_back(std::move(throttle)); + } + ASSERT_EQ(3u, throttles_.size()); + ASSERT_EQ(3u, throttles.size()); + + base::RunLoop run_loop1; + base::RunLoop run_loop2; + base::RunLoop run_loop3; + + // URL for internal redirect. + GURL modified_url = GURL("www.example.uk.com"); + throttle_->set_modify_url_in_will_start(modified_url); + + // Check that the initial loader uses the default load flags (0). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(0, url_request.load_flags); + quit_closure.Run(); + }, + run_loop1.QuitClosure())); + + // Set the client to actually follow redirects to allow URL resetting to + // occur. + client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() { + net::HttpRequestHeaders modified_headers; + loader_->FollowRedirect({} /* removed_headers */, + std::move(modified_headers)); + })); + + // Have two of the three throttles restart whe processing + // BeforeWillProcessResponse(), using + // different load flags (2 and 8), but both with URL resets. + throttles[0]->set_before_will_process_response_callback(base::BindRepeating( + [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { + delegate->RestartWithURLResetAndFlags(2); + })); + throttles[2]->set_before_will_process_response_callback(base::BindRepeating( + [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { + delegate->RestartWithURLResetAndFlags(8); + })); + + CreateLoaderAndStart(); + + run_loop1.Run(); + + EXPECT_EQ(1u, factory_.create_loader_and_start_called()); + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(0u, throttle->will_redirect_request_called()); + EXPECT_EQ(0u, throttle->before_will_process_response_called()); + EXPECT_EQ(0u, throttle->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), modified_url); + } + + // The next time we intercept CreateLoaderAndStart() should be for the + // restarted request (load flags of 10 = (2 | 8)). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(10, url_request.load_flags); + quit_closure.Run(); + }, + run_loop2.QuitClosure())); + + factory_.NotifyClientOnReceiveResponse(); + + run_loop2.Run(); + + // Now that the restarted request has been made, clear + // BeforeWillProcessResponse() so it doesn't restart the request yet again. + for (auto* throttle : throttles) { + throttle->set_before_will_process_response_callback( + TestURLLoaderThrottle::ThrottleCallback()); + } + + client_.set_on_complete_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int error) { + EXPECT_EQ(net::OK, error); + quit_closure.Run(); + }, + run_loop3.QuitClosure())); + + // Complete the response. + factory_.NotifyClientOnReceiveResponse(); + factory_.NotifyClientOnComplete(net::OK); + + run_loop3.Run(); + + EXPECT_EQ(2u, factory_.create_loader_and_start_called()); + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(1u, throttle->will_redirect_request_called()); + EXPECT_EQ(2u, throttle->before_will_process_response_called()); + EXPECT_EQ(1u, throttle->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), request_url); + } +} + +// Call RestartWithURLResetAndFlags() and RestartWithFlags from separate +// throttles after having deferred BeforeWillProcessResponse() in each. Ensures +// that the request is started exactly once, using the combination of all +// additional load flags, and with the original URL. +TEST_F(ThrottlingURLLoaderTest, MultipleDeferThenRestartsOfMultipleTypes) { + // Create two additional TestURLLoaderThrottles for a total of 3, and keep + // local unowned pointers to them in |throttles|. + std::vector<TestURLLoaderThrottle*> throttles; + ASSERT_EQ(1u, throttles_.size()); + throttles.push_back(throttle_); + for (size_t i = 0; i < 2u; ++i) { + auto throttle = std::make_unique<TestURLLoaderThrottle>(); + throttles.push_back(throttle.get()); + throttles_.push_back(std::move(throttle)); + } + + ASSERT_EQ(3u, throttles_.size()); + ASSERT_EQ(3u, throttles.size()); + + base::RunLoop run_loop1; + base::RunLoop run_loop2; + base::RunLoop run_loop3; + base::RunLoop run_loop4; + + // URL for internal redirect. + GURL modified_url = GURL("www.example.uk.com"); + throttle_->set_modify_url_in_will_start(modified_url); + + // Check that the initial loader uses the default load flags (0). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(0, url_request.load_flags); + quit_closure.Run(); + }, + run_loop1.QuitClosure())); + + // Set the client to actually follow redirects to allow URL resetting to + // occur. + client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() { + net::HttpRequestHeaders modified_headers; + loader_->FollowRedirect({} /* removed_headers */, + std::move(modified_headers)); + })); + + // Have all of the throttles defer. Once they have all been deferred, quit + // run_loop2. + int throttle_counter = 0; + for (auto* throttle : throttles) { + throttle->set_before_will_process_response_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int* count, + blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { + *defer = true; + if (++(*count) == 3) { + quit_closure.Run(); + } + }, + run_loop2.QuitClosure(), &throttle_counter)); + } + + CreateLoaderAndStart(); + + run_loop1.Run(); + + EXPECT_EQ(1u, factory_.create_loader_and_start_called()); + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(0u, throttle->will_redirect_request_called()); + EXPECT_EQ(0u, throttle->before_will_process_response_called()); + EXPECT_EQ(0u, throttle->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), modified_url); + } + + factory_.NotifyClientOnReceiveResponse(); + + run_loop2.Run(); + + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(0u, throttle->will_redirect_request_called()); + EXPECT_EQ(1u, throttle->before_will_process_response_called()); + EXPECT_EQ(0u, throttle->will_process_response_called()); + } + + // The next time we intercept CreateLoaderAndStart() should be for the + // restarted request (load flags of 1 | 2 | 4). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(7, url_request.load_flags); + quit_closure.Run(); + }, + run_loop3.QuitClosure())); + + int next_load_flag = 1; + bool with_url_reset = true; + for (auto* throttle : throttles) { + if (with_url_reset) { + throttle->delegate()->RestartWithURLResetAndFlags(next_load_flag); + with_url_reset = false; + } + throttle->delegate()->RestartWithFlags(next_load_flag); + throttle->delegate()->Resume(); + next_load_flag <<= 1; + } + + run_loop3.Run(); + + // Now that the restarted request has been made, clear + // BeforeWillProcessResponse(). + for (auto* throttle : throttles) { + throttle->set_before_will_process_response_callback( + TestURLLoaderThrottle::ThrottleCallback()); + } + + client_.set_on_complete_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int error) { + EXPECT_EQ(net::OK, error); + quit_closure.Run(); + }, + run_loop4.QuitClosure())); + + // Complete the response. + factory_.NotifyClientOnReceiveResponse(); + factory_.NotifyClientOnComplete(net::OK); + + run_loop4.Run(); + + EXPECT_EQ(2u, factory_.create_loader_and_start_called()); + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(1u, throttle->will_redirect_request_called()); + EXPECT_EQ(2u, throttle->before_will_process_response_called()); + EXPECT_EQ(1u, throttle->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), request_url); + } +} + +// Call RestartWithURLResetAndFlags() from two throttles while +// deferred, and one RestartWithFlags() while processing +// BeforeWillProcessResponse(). Ensures that the request is restarted exactly +// once, using the combination of all additional load flags, and that the +// restarted requests use the original URL. +TEST_F(ThrottlingURLLoaderTest, MultipleRestartOfMultipleTypesDeferAndSync) { + // Create two additional TestURLLoaderThrottles for a total of 3, and keep + // local unowned pointers to them in |throttles|. + std::vector<TestURLLoaderThrottle*> throttles; + ASSERT_EQ(1u, throttles_.size()); + throttles.push_back(throttle_); + for (size_t i = 0; i < 2u; ++i) { + auto throttle = std::make_unique<TestURLLoaderThrottle>(); + throttles.push_back(throttle.get()); + throttles_.push_back(std::move(throttle)); + } + + ASSERT_EQ(3u, throttles_.size()); + ASSERT_EQ(3u, throttles.size()); + + base::RunLoop run_loop1; + base::RunLoop run_loop2; + base::RunLoop run_loop3; + base::RunLoop run_loop4; + + // URL for internal redirect. + GURL modified_url = GURL("www.example.uk.com"); + throttle_->set_modify_url_in_will_start(modified_url); + + // Check that the initial loader uses the default load flags (0). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(0, url_request.load_flags); + quit_closure.Run(); + }, + run_loop1.QuitClosure())); + + // Set the client to actually follow redirects to allow URL resetting to + // occur. + client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() { + net::HttpRequestHeaders modified_headers; + loader_->FollowRedirect({} /* removed_headers */, + std::move(modified_headers)); + })); + + // Have two of the throttles defer, and one call restart + // synchronously. Once all are run, quit run_loop2. + int throttle_counter = 0; + for (size_t i = 0; i < 2u; ++i) { + throttles[i]->set_before_will_process_response_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int* count, + blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { + *defer = true; + if (++(*count) == 3) { + quit_closure.Run(); + } + }, + run_loop2.QuitClosure(), &throttle_counter)); + } + throttles[2]->set_before_will_process_response_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int* count, + blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { + delegate->RestartWithFlags(4); + if (++(*count) == 3) { + quit_closure.Run(); + } + }, + run_loop2.QuitClosure(), &throttle_counter)); + + CreateLoaderAndStart(); + + run_loop1.Run(); + + EXPECT_EQ(1u, factory_.create_loader_and_start_called()); + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(0u, throttle->will_redirect_request_called()); + EXPECT_EQ(0u, throttle->before_will_process_response_called()); + EXPECT_EQ(0u, throttle->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), modified_url); + } + + factory_.NotifyClientOnReceiveResponse(); + + run_loop2.Run(); + + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(0u, throttle->will_redirect_request_called()); + EXPECT_EQ(1u, throttle->before_will_process_response_called()); + EXPECT_EQ(0u, throttle->will_process_response_called()); + } + + // The next time we intercept CreateLoaderAndStart() should be for the + // restarted request (load flags of 1 | 2 | 4). + factory_.set_on_create_loader_and_start(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, + const network::ResourceRequest& url_request) { + EXPECT_EQ(7, url_request.load_flags); + quit_closure.Run(); + }, + run_loop3.QuitClosure())); + + int next_load_flag = 1; + for (auto* throttle : throttles) { + throttle->delegate()->RestartWithURLResetAndFlags(next_load_flag); + throttle->delegate()->Resume(); + next_load_flag <<= 1; + } + + run_loop3.Run(); + + // Now that the restarted request has been made, clear + // BeforeWillProcessResponse(). + for (auto* throttle : throttles) { + throttle->set_before_will_process_response_callback( + TestURLLoaderThrottle::ThrottleCallback()); + } + + client_.set_on_complete_callback(base::BindRepeating( + [](const base::RepeatingClosure& quit_closure, int error) { + EXPECT_EQ(net::OK, error); + quit_closure.Run(); + }, + run_loop4.QuitClosure())); + + // Complete the response. + factory_.NotifyClientOnReceiveResponse(); + factory_.NotifyClientOnComplete(net::OK); + + run_loop4.Run(); + + EXPECT_EQ(2u, factory_.create_loader_and_start_called()); + for (auto* throttle : throttles) { + EXPECT_EQ(1u, throttle->will_start_request_called()); + EXPECT_EQ(1u, throttle->will_redirect_request_called()); + EXPECT_EQ(2u, throttle->before_will_process_response_called()); + EXPECT_EQ(1u, throttle->will_process_response_called()); + EXPECT_EQ(throttle_->observed_response_url(), request_url); + } +} + } // namespace } // namespace content
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index de80e10..27d0fb2 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/feature_list.h" #include "base/lazy_instance.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/histogram_macros.h" #include "base/rand_util.h" #include "base/run_loop.h" @@ -246,14 +247,14 @@ if (command_line.HasSwitch(switches::kHeadless)) { main_thread_task_executor = std::make_unique<base::SingleThreadTaskExecutor>( - base::MessagePump::Type::DEFAULT); + base::MessagePumpType::DEFAULT); } else { #if defined(OS_WIN) // The GpuMain thread should not be pumping Windows messages because no UI // is expected to run on this thread. main_thread_task_executor = std::make_unique<base::SingleThreadTaskExecutor>( - base::MessagePump::Type::DEFAULT); + base::MessagePumpType::DEFAULT); #elif defined(USE_X11) // Depending on how Chrome is running there are multiple threads that can // make Xlib function calls. Call XInitThreads() here to be safe, even if @@ -267,7 +268,7 @@ return RESULT_CODE_GPU_DEAD_ON_ARRIVAL; main_thread_task_executor = std::make_unique<base::SingleThreadTaskExecutor>( - base::MessagePump::Type::UI); + base::MessagePumpType::UI); event_source = ui::PlatformEventSource::CreateDefault(); #elif defined(USE_OZONE) // The MessagePump type required depends on the Ozone platform selected at @@ -283,14 +284,14 @@ // https://crbug.com/312462#c51 and https://crbug.com/783298 main_thread_task_executor = std::make_unique<base::SingleThreadTaskExecutor>( - base::MessagePump::Type::NS_RUNLOOP); + base::MessagePumpType::NS_RUNLOOP); // Tell LaunchServices to continue without a connection to the daemon. _LSSetApplicationLaunchServicesServerConnectionStatus(0, nullptr); #else main_thread_task_executor = std::make_unique<base::SingleThreadTaskExecutor>( - base::MessagePump::Type::DEFAULT); + base::MessagePumpType::DEFAULT); #endif }
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 4588449..d1a38911 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -30,7 +30,6 @@ #include "net/ssl/client_cert_store.h" #include "net/url_request/url_request_context_getter.h" #include "services/device/public/cpp/geolocation/location_provider.h" -#include "services/network/public/cpp/features.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/service_manager/sandbox/sandbox_type.h" @@ -791,9 +790,6 @@ bool in_memory, const base::FilePath& relative_partition_path) { DCHECK(context); - if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) - return nullptr; - network::mojom::NetworkContextPtr network_context; network::mojom::NetworkContextParamsPtr context_params = network::mojom::NetworkContextParams::New();
diff --git a/content/public/browser/permission_controller_delegate.h b/content/public/browser/permission_controller_delegate.h index 269d5e7..57f4d58a 100644 --- a/content/public/browser/permission_controller_delegate.h +++ b/content/public/browser/permission_controller_delegate.h
@@ -6,6 +6,7 @@ #define CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_DELEGATE_H_ #include "content/common/content_export.h" +#include "content/public/browser/devtools_permission_overrides.h" #include "third_party/blink/public/mojom/permissions/permission_status.mojom.h" class GURL; @@ -16,6 +17,7 @@ class CONTENT_EXPORT PermissionControllerDelegate { public: + using PermissionOverrides = DevToolsPermissionOverrides::PermissionOverrides; virtual ~PermissionControllerDelegate() = default; // Requests a permission on behalf of a frame identified by @@ -93,6 +95,17 @@ // an already unsubscribed |subscription_id| or providing the // |subscription_id| kNoPendingOperation is a no-op. virtual void UnsubscribePermissionStatusChange(int subscription_id) = 0; + + // Manually overrides default permission settings of delegate, if overrides + // are tracked by the delegate. This method should only be called by the + // PermissionController owning the delegate. + virtual void SetPermissionOverridesForDevTools( + const GURL& origin, + const PermissionOverrides& overrides) {} + + // Removes overrides that have been set, if any, for all origins. If delegate + // does not maintain own permission set, then nothing happens. + virtual void ResetPermissionOverridesForDevTools() {} }; } // namespace content
diff --git a/content/public/common/network_service_util.cc b/content/public/common/network_service_util.cc index 1f239d5..f31da6a 100644 --- a/content/public/common/network_service_util.cc +++ b/content/public/common/network_service_util.cc
@@ -34,14 +34,10 @@ } // namespace bool IsOutOfProcessNetworkService() { - return base::FeatureList::IsEnabled(network::features::kNetworkService) && - !IsInProcessNetworkService(); + return !IsInProcessNetworkService(); } bool IsInProcessNetworkService() { - if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) - return false; - if (g_force_in_process_network_service || base::FeatureList::IsEnabled(features::kNetworkServiceInProcess) || base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/CriteriaHelper.java b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/CriteriaHelper.java index 68cfc87..83f584a 100644 --- a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/CriteriaHelper.java +++ b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/CriteriaHelper.java
@@ -6,11 +6,10 @@ import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; -import android.os.SystemClock; - import org.junit.Assert; import org.chromium.base.ThreadUtils; +import org.chromium.base.test.util.TimeoutTimer; import java.util.concurrent.Callable; @@ -79,8 +78,8 @@ public static void pollInstrumentationThread( Criteria criteria, long maxTimeoutMs, long checkIntervalMs) { boolean isSatisfied = criteria.isSatisfied(); - long startTime = SystemClock.uptimeMillis(); - while (!isSatisfied && SystemClock.uptimeMillis() - startTime < maxTimeoutMs) { + TimeoutTimer timer = new TimeoutTimer(maxTimeoutMs); + while (!isSatisfied && !timer.isTimedOut()) { try { Thread.sleep(checkIntervalMs); } catch (InterruptedException e) {
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc index 74a6b17..ae299b4a 100644 --- a/content/public/test/browser_test_base.cc +++ b/content/public/test/browser_test_base.cc
@@ -490,7 +490,6 @@ } void BrowserTestBase::SimulateNetworkServiceCrash() { - CHECK(base::FeatureList::IsEnabled(network::features::kNetworkService)); CHECK(!IsInProcessNetworkService()) << "Can't crash the network service if it's running in-process!"; network::mojom::NetworkServiceTestPtr network_service_test; @@ -602,8 +601,7 @@ PreRunTestOnMainThread(); std::unique_ptr<InitialNavigationObserver> initial_navigation_observer; - if (initial_web_contents_ && - base::FeatureList::IsEnabled(network::features::kNetworkService)) { + if (initial_web_contents_) { // Some tests may add host_resolver() rules in their SetUpOnMainThread // method and navigate inside of it. This is a best effort to catch that // and sync the host_resolver() rules to the network process in that case,
diff --git a/content/public/test/content_mock_cert_verifier.cc b/content/public/test/content_mock_cert_verifier.cc index 59242e2..8e2e379 100644 --- a/content/public/test/content_mock_cert_verifier.cc +++ b/content/public/test/content_mock_cert_verifier.cc
@@ -35,10 +35,8 @@ switches::kMockCertVerifierDefaultResultForTesting, base::NumberToString(default_result)); - if (!base::FeatureList::IsEnabled(network::features::kNetworkService) || - IsInProcessNetworkService()) { + if (IsInProcessNetworkService()) return; - } EnsureNetworkServiceTestInitialized(); mojo::ScopedAllowSyncCallForTesting allow_sync_call; @@ -59,10 +57,8 @@ int rv) { verifier_->AddResultForCertAndHost(cert, host_pattern, verify_result, rv); - if (!base::FeatureList::IsEnabled(network::features::kNetworkService) || - IsInProcessNetworkService()) { + if (IsInProcessNetworkService()) return; - } EnsureNetworkServiceTestInitialized(); mojo::ScopedAllowSyncCallForTesting allow_sync_call;
diff --git a/content/public/test/network_service_test_helper.cc b/content/public/test/network_service_test_helper.cc index 552ba2a4..eabd467f 100644 --- a/content/public/test/network_service_test_helper.cc +++ b/content/public/test/network_service_test_helper.cc
@@ -266,9 +266,6 @@ void NetworkServiceTestHelper::RegisterNetworkBinders( service_manager::BinderRegistry* registry) { - if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) - return; - registry->AddInterface( base::Bind(&NetworkServiceTestHelper::BindNetworkServiceTestRequest, base::Unretained(this)));
diff --git a/content/public/test/signed_exchange_browser_test_helper.cc b/content/public/test/signed_exchange_browser_test_helper.cc index 23b8f68..33e9f1175 100644 --- a/content/public/test/signed_exchange_browser_test_helper.cc +++ b/content/public/test/signed_exchange_browser_test_helper.cc
@@ -21,9 +21,6 @@ #include "net/cert/mock_cert_verifier.h" #include "net/dns/mock_host_resolver.h" #include "net/test/cert_test_util.h" -#include "net/test/url_request/url_request_mock_http_job.h" -#include "net/url_request/url_request_filter.h" -#include "services/network/public/cpp/features.h" namespace content { @@ -64,18 +61,12 @@ void SignedExchangeBrowserTestHelper::InstallUrlInterceptor( const GURL& url, const std::string& data_path) { - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { - if (!interceptor_) { - interceptor_ = std::make_unique<URLLoaderInterceptor>(base::BindRepeating( - &SignedExchangeBrowserTestHelper::OnInterceptCallback, - base::Unretained(this))); - } - interceptor_data_path_map_[url] = data_path; - } else { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&InstallMockInterceptors, url, data_path)); + if (!interceptor_) { + interceptor_ = std::make_unique<URLLoaderInterceptor>(base::BindRepeating( + &SignedExchangeBrowserTestHelper::OnInterceptCallback, + base::Unretained(this))); } + interceptor_data_path_map_[url] = data_path; } void SignedExchangeBrowserTestHelper::InstallMockCert( @@ -98,16 +89,6 @@ "content/test/data/sxg/test.example.org.public.pem.cbor"); } -void SignedExchangeBrowserTestHelper::InstallMockInterceptors( - const GURL& url, - const std::string& data_path) { - base::FilePath root_path; - CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &root_path)); - net::URLRequestFilter::GetInstance()->AddUrlInterceptor( - url, net::URLRequestMockHTTPJob::CreateInterceptorForSingleFile( - root_path.AppendASCII(data_path))); -} - bool SignedExchangeBrowserTestHelper::OnInterceptCallback( URLLoaderInterceptor::RequestParams* params) { const auto it = interceptor_data_path_map_.find(params->url_request.url);
diff --git a/content/public/test/signed_exchange_browser_test_helper.h b/content/public/test/signed_exchange_browser_test_helper.h index 37cc0e5f..b14f1729 100644 --- a/content/public/test/signed_exchange_browser_test_helper.h +++ b/content/public/test/signed_exchange_browser_test_helper.h
@@ -72,9 +72,6 @@ static const uint64_t kSignatureHeaderExpires; private: - static void InstallMockInterceptors(const GURL& url, - const std::string& data_path); - bool OnInterceptCallback(URLLoaderInterceptor::RequestParams* params); std::unique_ptr<URLLoaderInterceptor> interceptor_;
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index 6f66951b..7da5c66d 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -588,7 +588,8 @@ DCHECK(blink::WebInputEvent::kGestureTapDown == event.GetType() || blink::WebInputEvent::kGestureScrollBegin == event.GetType() || blink::WebInputEvent::kGestureScrollEnd == event.GetType() || - gesture_event.resending_plugin_id == browser_plugin_instance_id_); + gesture_event.resending_plugin_id == browser_plugin_instance_id_) + << "Unexpected event seen: " << event.GetName(event.GetType()); // We shouldn't be forwarding GestureEvents to the Guest anymore. Indicate // we handled this only if it's a non-resent event.
diff --git a/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc b/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc index 33ab6bb..e260eef 100644 --- a/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc +++ b/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc
@@ -9,6 +9,7 @@ #include <vector> #include "base/bind.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" @@ -30,7 +31,7 @@ std::unique_ptr<base::Thread> MakeIOThread() { auto io_thread = std::make_unique<base::Thread>("test IO thread"); - base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options thread_options(base::MessagePumpType::IO, 0); CHECK(io_thread->StartWithOptions(thread_options)); return io_thread; }
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index e39eed3..c47eb19 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -20,6 +20,7 @@ #include "base/macros.h" #include "base/memory/discardable_memory_allocator.h" #include "base/memory/shared_memory.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" @@ -2203,7 +2204,7 @@ media_thread_.reset(new base::Thread("Media")); #if defined(OS_FUCHSIA) // Start IO thread on Fuchsia to make that thread usable for FIDL. - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); #else base::Thread::Options options; #endif
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index ac9173c..de6c8746 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -51,7 +51,6 @@ #include "net/ssl/client_cert_identity.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context_getter.h" -#include "services/network/public/cpp/features.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/service_manager/public/cpp/manifest.h" #include "services/service_manager/public/cpp/manifest_builder.h" @@ -495,10 +494,6 @@ BrowserContext* context, bool in_memory, const base::FilePath& relative_partition_path) { - DCHECK(context); - if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) - return nullptr; - network::mojom::NetworkContextPtr network_context; network::mojom::NetworkContextParamsPtr context_params = network::mojom::NetworkContextParams::New();
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 131e462f..e0d45eb 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -254,6 +254,9 @@ # Failing on AMD RX 550 crbug.com/angleproject/3354 [ win amd-0x699f ] deqp/functional/gles3/fborender/shared_colorbuffer_02.html [ Skip ] +# Flaky on AMD Win7 +crbug.com/989050 [ d3d11 win7 amd ] conformance2/textures/misc/tex-unpack-params-imagedata.html [ RetryOnFailure ] + # Passthrough command decoder crbug.com/844349 [ passthrough ] conformance/misc/webgl-specific-stencil-settings.html [ Failure ] crbug.com/951628 [ passthrough ] conformance/rendering/blending.html [ Failure ]
diff --git a/content/utility/utility_service_factory.cc b/content/utility/utility_service_factory.cc index e4c8405f..a16d93d 100644 --- a/content/utility/utility_service_factory.cc +++ b/content/utility/utility_service_factory.cc
@@ -27,7 +27,6 @@ #include "services/data_decoder/data_decoder_service.h" #include "services/data_decoder/public/mojom/constants.mojom.h" #include "services/network/network_service.h" -#include "services/network/public/cpp/features.h" #include "services/service_manager/public/mojom/service.mojom.h" #include "services/tracing/public/cpp/tracing_features.h" #include "services/tracing/public/mojom/constants.mojom.h" @@ -154,8 +153,7 @@ !base::FeatureList::IsEnabled( features::kTracingServiceInProcess)) { service = std::make_unique<tracing::TracingService>(std::move(request)); - } else if (service_name == mojom::kNetworkServiceName && - base::FeatureList::IsEnabled(network::features::kNetworkService)) { + } else if (service_name == mojom::kNetworkServiceName) { // Unlike other services supported by the utility process, the network // service runs on the IO thread and never self-terminates. GetContentClient()->utility()->RegisterNetworkBinders(
diff --git a/dbus/bus_unittest.cc b/dbus/bus_unittest.cc index 559bfd7..1981a71e 100644 --- a/dbus/bus_unittest.cc +++ b/dbus/bus_unittest.cc
@@ -9,6 +9,7 @@ #include "base/files/file_descriptor_watcher_posix.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" @@ -133,7 +134,7 @@ // Start the D-Bus thread. base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; base::Thread dbus_thread("D-Bus thread"); dbus_thread.StartWithOptions(thread_options); @@ -211,7 +212,7 @@ TEST(BusTest, UnregisterExportedObject) { // Start the D-Bus thread. base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; base::Thread dbus_thread("D-Bus thread"); dbus_thread.StartWithOptions(thread_options); @@ -261,7 +262,7 @@ TEST(BusTest, ShutdownAndBlockWithDBusThread) { // Start the D-Bus thread. base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; base::Thread dbus_thread("D-Bus thread"); dbus_thread.StartWithOptions(thread_options);
diff --git a/dbus/end_to_end_async_unittest.cc b/dbus/end_to_end_async_unittest.cc index f90c443..2cf07b47 100644 --- a/dbus/end_to_end_async_unittest.cc +++ b/dbus/end_to_end_async_unittest.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" @@ -46,7 +47,7 @@ // Start the D-Bus thread. dbus_thread_.reset(new base::Thread("D-Bus Thread")); base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options)); // Start the test service, using the D-Bus thread.
diff --git a/dbus/object_manager_unittest.cc b/dbus/object_manager_unittest.cc index 5654fa0..37080e57 100644 --- a/dbus/object_manager_unittest.cc +++ b/dbus/object_manager_unittest.cc
@@ -11,6 +11,7 @@ #include <vector> #include "base/bind.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/test/scoped_task_environment.h" @@ -68,7 +69,7 @@ // Start the D-Bus thread. dbus_thread_.reset(new base::Thread("D-Bus Thread")); base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options)); // Start the test service, using the D-Bus thread.
diff --git a/dbus/property_unittest.cc b/dbus/property_unittest.cc index f3d4e8f..5e9f496 100644 --- a/dbus/property_unittest.cc +++ b/dbus/property_unittest.cc
@@ -13,6 +13,7 @@ #include "base/bind.h" #include "base/logging.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" @@ -60,7 +61,7 @@ // Start the D-Bus thread. dbus_thread_.reset(new base::Thread("D-Bus Thread")); base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options)); // Start the test service, using the D-Bus thread.
diff --git a/dbus/signal_sender_verification_unittest.cc b/dbus/signal_sender_verification_unittest.cc index 92fe63a..c2998d8 100644 --- a/dbus/signal_sender_verification_unittest.cc +++ b/dbus/signal_sender_verification_unittest.cc
@@ -5,6 +5,7 @@ #include <memory> #include "base/bind.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_samples.h" #include "base/run_loop.h" @@ -36,7 +37,7 @@ // Start the D-Bus thread. dbus_thread_.reset(new base::Thread("D-Bus Thread")); base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options)); // Create the test service, using the D-Bus thread.
diff --git a/dbus/test_server.cc b/dbus/test_server.cc index a20cf56..448b177 100644 --- a/dbus/test_server.cc +++ b/dbus/test_server.cc
@@ -4,7 +4,7 @@ #include "base/at_exit.h" #include "base/command_line.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/test/test_timeouts.h" #include "dbus/bus.h" #include "dbus/test_service.h" @@ -16,7 +16,7 @@ base::Thread dbus_thread("D-Bus Thread"); base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; CHECK(dbus_thread.StartWithOptions(thread_options)); dbus::TestService::Options options;
diff --git a/dbus/test_service.cc b/dbus/test_service.cc index 4cfbcc9..7486e9c2 100644 --- a/dbus/test_service.cc +++ b/dbus/test_service.cc
@@ -12,7 +12,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/guid.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/test/test_timeouts.h" @@ -59,7 +59,7 @@ bool TestService::StartService() { base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; return StartWithOptions(thread_options); }
diff --git a/device/bluetooth/bluetooth_socket_thread.cc b/device/bluetooth/bluetooth_socket_thread.cc index c9fbb8a..c2a3de3 100644 --- a/device/bluetooth/bluetooth_socket_thread.cc +++ b/device/bluetooth/bluetooth_socket_thread.cc
@@ -5,7 +5,7 @@ #include "device/bluetooth/bluetooth_socket_thread.h" #include "base/lazy_instance.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/sequenced_task_runner.h" #include "base/threading/thread.h" @@ -56,7 +56,7 @@ return; base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; thread_.reset(new base::Thread("BluetoothSocketThread")); thread_->StartWithOptions(thread_options); task_runner_ = thread_->task_runner();
diff --git a/device/bluetooth/dbus/bluez_dbus_thread_manager.cc b/device/bluetooth/dbus/bluez_dbus_thread_manager.cc index 6ba28d2..b7f9e22c3 100644 --- a/device/bluetooth/dbus/bluez_dbus_thread_manager.cc +++ b/device/bluetooth/dbus/bluez_dbus_thread_manager.cc
@@ -4,7 +4,7 @@ #include "device/bluetooth/dbus/bluez_dbus_thread_manager.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/threading/thread.h" #include "dbus/bus.h" @@ -14,7 +14,7 @@ BluezDBusThreadManager::BluezDBusThreadManager() { base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; dbus_thread_.reset(new base::Thread("Bluez D-Bus thread")); dbus_thread_->StartWithOptions(thread_options);
diff --git a/device/gamepad/gamepad_provider.cc b/device/gamepad/gamepad_provider.cc index 5c730fe..0389dda 100644 --- a/device/gamepad/gamepad_provider.cc +++ b/device/gamepad/gamepad_provider.cc
@@ -13,7 +13,7 @@ #include "base/bind.h" #include "base/location.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/third_party/dynamic_annotations/dynamic_annotations.h" @@ -170,16 +170,15 @@ #if defined(OS_LINUX) // On Linux, the data fetcher needs to watch file descriptors, so the message // loop needs to be a libevent loop. - const base::MessageLoop::Type kMessageLoopType = base::MessageLoop::TYPE_IO; + const base::MessagePumpType kMessageLoopType = base::MessagePump::Type::IO; #elif defined(OS_ANDROID) // On Android, keeping a message loop of default type. - const base::MessageLoop::Type kMessageLoopType = - base::MessageLoop::TYPE_DEFAULT; + const base::MessagePumpType kMessageLoopType = base::MessagePumpType::DEFAULT; #else // On Mac, the data fetcher uses IOKit which depends on CFRunLoop, so the // message loop needs to be a UI-type loop. On Windows it must be a UI loop // to properly pump the MessageWindow that captures device state. - const base::MessageLoop::Type kMessageLoopType = base::MessageLoop::TYPE_UI; + const base::MessagePumpType kMessageLoopType = base::MessagePump::Type::UI; #endif polling_thread_->StartWithOptions(base::Thread::Options(kMessageLoopType, 0));
diff --git a/device/vr/windows_mixed_reality/mixed_reality_device.cc b/device/vr/windows_mixed_reality/mixed_reality_device.cc index 96e1ec3..d49c71a 100644 --- a/device/vr/windows_mixed_reality/mixed_reality_device.cc +++ b/device/vr/windows_mixed_reality/mixed_reality_device.cc
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/numerics/math_constants.h" #include "base/threading/thread.h" #include "build/build_config.h" @@ -98,7 +98,7 @@ // We need to start a UI message loop or we will not receive input events // on 1809 or newer. base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_UI; + options.message_pump_type = base::MessagePumpType::UI; render_loop_->StartWithOptions(options); // IsRunning() should be true here unless the thread failed to start (likely
diff --git a/docs/ios/objects.md b/docs/ios/objects.md index 11738698..a6dd32d 100644 --- a/docs/ios/objects.md +++ b/docs/ios/objects.md
@@ -119,9 +119,7 @@ instead should support the tab helper being unavailable. A WebState and all the attached tab helpers are sometimes called a -tab (because they implement what the user sees and interacts with in -a browser tab). There currently is a Tab interface but it is a legacy -object that is deprecated and is slowly being removed. If possible, -prefer to use WebState directly instead of Tab. +tab because they implement what the user sees and interacts with in +a browser tab. The corresponding object on desktop is WebContents.
diff --git a/extensions/browser/api/networking_private/networking_private_linux.cc b/extensions/browser/api/networking_private/networking_private_linux.cc index b13bdc7..67ba24c7 100644 --- a/extensions/browser/api/networking_private/networking_private_linux.cc +++ b/extensions/browser/api/networking_private/networking_private_linux.cc
@@ -9,7 +9,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/strings/string16.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" @@ -138,7 +138,7 @@ NetworkingPrivateLinux::NetworkingPrivateLinux() : dbus_thread_("Networking Private DBus"), network_manager_proxy_(NULL) { - base::Thread::Options thread_options(base::MessageLoop::Type::IO, 0); + base::Thread::Options thread_options(base::MessagePumpType::IO, 0); dbus_thread_.StartWithOptions(thread_options); dbus_thread_.task_runner()->PostTask(
diff --git a/extensions/renderer/resources/automation/automation_node.js b/extensions/renderer/resources/automation/automation_node.js index 5fce69a..61c4551 100644 --- a/extensions/renderer/resources/automation/automation_node.js +++ b/extensions/renderer/resources/automation/automation_node.js
@@ -953,6 +953,8 @@ result += ' childTreeID=' + childTreeID; if (name) result += ' name=' + name; + if (this.className) + result += ' className=' + this.className; return result; },
diff --git a/google_apis/gaia/fake_oauth2_access_token_manager.cc b/google_apis/gaia/fake_oauth2_access_token_manager.cc index 4e48c808..5aabb8c4 100644 --- a/google_apis/gaia/fake_oauth2_access_token_manager.cc +++ b/google_apis/gaia/fake_oauth2_access_token_manager.cc
@@ -28,7 +28,7 @@ FakeOAuth2AccessTokenManager::~FakeOAuth2AccessTokenManager() {} void FakeOAuth2AccessTokenManager::IssueAllTokensForAccount( - const std::string& account_id, + const CoreAccountId& account_id, const std::string& access_token, const base::Time& expiration) { DCHECK(!auto_post_fetch_response_on_message_loop_); @@ -39,7 +39,7 @@ } void FakeOAuth2AccessTokenManager::IssueAllTokensForAccount( - const std::string& account_id, + const CoreAccountId& account_id, const OAuth2AccessTokenConsumer::TokenResponse& token_response) { DCHECK(!auto_post_fetch_response_on_message_loop_); CompleteRequests(account_id, true, FakeOAuth2AccessTokenManager::ScopeSet(), @@ -47,7 +47,7 @@ } void FakeOAuth2AccessTokenManager::IssueErrorForAllPendingRequestsForAccount( - const std::string& account_id, + const CoreAccountId& account_id, const GoogleServiceAuthError& error) { DCHECK(!auto_post_fetch_response_on_message_loop_); CompleteRequests(account_id, true, FakeOAuth2AccessTokenManager::ScopeSet(), @@ -59,7 +59,8 @@ const std::string& access_token, const base::Time& expiration) { DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests("", false, scope, GoogleServiceAuthError::AuthErrorNone(), + CompleteRequests(CoreAccountId(), false, scope, + GoogleServiceAuthError::AuthErrorNone(), OAuth2AccessTokenConsumer::TokenResponse( access_token, expiration, std::string() /* id_token */)); } @@ -68,22 +69,23 @@ const FakeOAuth2AccessTokenManager::ScopeSet& scope, const OAuth2AccessTokenConsumer::TokenResponse& token_response) { DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests("", false, scope, GoogleServiceAuthError::AuthErrorNone(), - token_response); + CompleteRequests(CoreAccountId(), false, scope, + GoogleServiceAuthError::AuthErrorNone(), token_response); } void FakeOAuth2AccessTokenManager::IssueErrorForScope( const FakeOAuth2AccessTokenManager::ScopeSet& scope, const GoogleServiceAuthError& error) { DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests("", false, scope, error, + CompleteRequests(CoreAccountId(), false, scope, error, OAuth2AccessTokenConsumer::TokenResponse()); } void FakeOAuth2AccessTokenManager::IssueErrorForAllPendingRequests( const GoogleServiceAuthError& error) { DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests("", true, FakeOAuth2AccessTokenManager::ScopeSet(), error, + CompleteRequests(CoreAccountId(), true, + FakeOAuth2AccessTokenManager::ScopeSet(), error, OAuth2AccessTokenConsumer::TokenResponse()); } @@ -91,7 +93,8 @@ const std::string& access_token, const base::Time& expiration) { DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests("", true, FakeOAuth2AccessTokenManager::ScopeSet(), + CompleteRequests(CoreAccountId(), true, + FakeOAuth2AccessTokenManager::ScopeSet(), GoogleServiceAuthError::AuthErrorNone(), OAuth2AccessTokenConsumer::TokenResponse( access_token, expiration, std::string() /* id_token */)); @@ -100,12 +103,13 @@ void FakeOAuth2AccessTokenManager::IssueTokenForAllPendingRequests( const OAuth2AccessTokenConsumer::TokenResponse& token_response) { DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests("", true, FakeOAuth2AccessTokenManager::ScopeSet(), + CompleteRequests(CoreAccountId(), true, + FakeOAuth2AccessTokenManager::ScopeSet(), GoogleServiceAuthError::AuthErrorNone(), token_response); } void FakeOAuth2AccessTokenManager::CompleteRequests( - const std::string& account_id, + const CoreAccountId& account_id, bool all_scopes, const FakeOAuth2AccessTokenManager::ScopeSet& scope, const GoogleServiceAuthError& error, @@ -151,7 +155,7 @@ void FakeOAuth2AccessTokenManager::CancelAllRequests() { CompleteRequests( - "", true, FakeOAuth2AccessTokenManager::ScopeSet(), + CoreAccountId(), true, FakeOAuth2AccessTokenManager::ScopeSet(), GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED), OAuth2AccessTokenConsumer::TokenResponse()); }
diff --git a/google_apis/gaia/fake_oauth2_access_token_manager.h b/google_apis/gaia/fake_oauth2_access_token_manager.h index d9efa6be..6ce90527 100644 --- a/google_apis/gaia/fake_oauth2_access_token_manager.h +++ b/google_apis/gaia/fake_oauth2_access_token_manager.h
@@ -23,7 +23,7 @@ PendingRequest(const PendingRequest& other); ~PendingRequest(); - std::string account_id; + CoreAccountId account_id; std::string client_id; std::string client_secret; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory; @@ -40,17 +40,17 @@ std::vector<PendingRequest> GetPendingRequests(); // Helper routines to issue tokens for pending requests. - void IssueAllTokensForAccount(const std::string& account_id, + void IssueAllTokensForAccount(const CoreAccountId& account_id, const std::string& access_token, const base::Time& expiration); // Helper routines to issue token for pending requests based on TokenResponse. void IssueAllTokensForAccount( - const std::string& account_id, + const CoreAccountId& account_id, const OAuth2AccessTokenConsumer::TokenResponse& token_response); void IssueErrorForAllPendingRequestsForAccount( - const std::string& account_id, + const CoreAccountId& account_id, const GoogleServiceAuthError& error); void IssueTokenForScope(const OAuth2AccessTokenManager::ScopeSet& scopes, @@ -102,7 +102,7 @@ // requests for all accounts are completed, otherwise only requests for the // given account. void CompleteRequests( - const std::string& account_id, + const CoreAccountId& account_id, bool all_scopes, const OAuth2AccessTokenManager::ScopeSet& scopes, const GoogleServiceAuthError& error,
diff --git a/google_apis/gaia/oauth2_access_token_manager_unittest.cc b/google_apis/gaia/oauth2_access_token_manager_unittest.cc index 0c35169..44dbc870 100644 --- a/google_apis/gaia/oauth2_access_token_manager_unittest.cc +++ b/google_apis/gaia/oauth2_access_token_manager_unittest.cc
@@ -66,6 +66,21 @@ return false; } + void OnAccessTokenInvalidated( + const CoreAccountId& account_id, + const std::string& client_id, + const OAuth2AccessTokenManager::ScopeSet& scopes, + const std::string& access_token) override { + if (!on_access_token_invalidated_callback_) + return; + + EXPECT_EQ(access_token_invalidated_account_id_, account_id); + EXPECT_EQ(access_token_invalidated_client_id_, client_id); + EXPECT_EQ(access_token_invalidated_scopes_, scopes); + EXPECT_EQ(access_token_invalidated_access_token_, access_token); + std::move(on_access_token_invalidated_callback_).Run(); + } + void AddAccount(CoreAccountId id, std::string refresh_token) { account_ids_to_refresh_tokens_[id] = refresh_token; } @@ -74,10 +89,28 @@ access_token_fetch_closure_ = std::move(closure); } + void SetOnAccessTokenInvalidated( + const CoreAccountId& account_id, + const std::string& client_id, + const OAuth2AccessTokenManager::ScopeSet& scopes, + const std::string& access_token, + base::OnceClosure callback) { + access_token_invalidated_account_id_ = account_id; + access_token_invalidated_client_id_ = client_id; + access_token_invalidated_scopes_ = scopes; + access_token_invalidated_access_token_ = access_token; + on_access_token_invalidated_callback_ = std::move(callback); + } + private: scoped_refptr<network::SharedURLLoaderFactory> shared_factory_; std::map<CoreAccountId, std::string> account_ids_to_refresh_tokens_; base::OnceClosure access_token_fetch_closure_; + CoreAccountId access_token_invalidated_account_id_; + std::string access_token_invalidated_client_id_; + OAuth2AccessTokenManager::ScopeSet access_token_invalidated_scopes_; + std::string access_token_invalidated_access_token_; + base::OnceClosure on_access_token_invalidated_callback_; }; class FakeOAuth2AccessTokenManagerConsumer @@ -322,3 +355,16 @@ GaiaUrls::GetInstance()->oauth2_chrome_client_id(), account_id_, OAuth2AccessTokenManager::ScopeSet())); } + +// Test that InvalidateAccessToken triggers OnAccessTokenInvalidated. +TEST_F(OAuth2AccessTokenManagerTest, OnAccessTokenInvalidated) { + base::RunLoop run_loop; + OAuth2AccessTokenManager::ScopeSet scope_set; + scope_set.insert("scope"); + std::string access_token("access_token"); + delegate_.SetOnAccessTokenInvalidated( + account_id_, GaiaUrls::GetInstance()->oauth2_chrome_client_id(), + scope_set, access_token, run_loop.QuitClosure()); + token_manager_.InvalidateAccessToken(account_id_, scope_set, access_token); + run_loop.Run(); +}
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg index 58958dd..e3d5ebbab 100644 --- a/infra/config/cr-buildbucket.cfg +++ b/infra/config/cr-buildbucket.cfg
@@ -2489,6 +2489,7 @@ mixins: "fuzz-ci" mixins: "linux-xenial" mixins: "builderless" + mixins: "goma-rbe-prod" } builders { name: "Linux CFI" @@ -2531,6 +2532,7 @@ mixins: "fuzz-ci" mixins: "linux-xenial" mixins: "builderless" + mixins: "goma-rbe-prod" } builders { name: "UBSan vptr Release" @@ -4463,7 +4465,7 @@ builders { mixins: "win-try" mixins: "goma-j300" - # TODO(crbug/881609): Add 'dimensions: "ssd:1"'. + dimensions: "ssd:1" name: "win7-rel" execution_timeout_secs: 16200 # 4.5h }
diff --git a/infra/config/luci-milo.cfg b/infra/config/luci-milo.cfg index b07c79a6..7cc9a808 100644 --- a/infra/config/luci-milo.cfg +++ b/infra/config/luci-milo.cfg
@@ -3074,6 +3074,16 @@ category: "week7|msan" short_name: "none" } + builders { + name: "buildbucket/luci.chromium.ci/TSAN Release" + category: "week8|tsan" + short_name: "rel" + } + builders { + name: "buildbucket/luci.chromium.ci/TSAN Debug" + category: "week8|tsan" + short_name: "dbg" + } } consoles {
diff --git a/ios/chrome/browser/metrics/first_user_action_recorder_unittest.cc b/ios/chrome/browser/metrics/first_user_action_recorder_unittest.cc index 0d91169a..12e64fb 100644 --- a/ios/chrome/browser/metrics/first_user_action_recorder_unittest.cc +++ b/ios/chrome/browser/metrics/first_user_action_recorder_unittest.cc
@@ -5,6 +5,7 @@ #include <memory> #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/run_loop.h" @@ -22,7 +23,7 @@ class FirstUserActionRecorderTest : public PlatformTest { protected: void SetUp() override { - loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_DEFAULT)); + loop_.reset(new base::MessageLoop(base::MessagePumpType::DEFAULT)); ui_thread_.reset(new web::TestWebThread(web::WebThread::UI, loop_.get())); base::TimeDelta delta = base::TimeDelta::FromSeconds(60);
diff --git a/ios/chrome/browser/overscroll_actions/BUILD.gn b/ios/chrome/browser/overscroll_actions/BUILD.gn index 3184f6e9..75405c5 100644 --- a/ios/chrome/browser/overscroll_actions/BUILD.gn +++ b/ios/chrome/browser/overscroll_actions/BUILD.gn
@@ -30,6 +30,7 @@ "//base/test:test_support", "//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/ui/overscroll_actions", + "//ios/chrome/common/colors", "//ios/chrome/test/fakes", "//ios/web/public", "//ios/web/public/test",
diff --git a/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper_unittest.mm b/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper_unittest.mm index c4b5178..9348fff 100644 --- a/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper_unittest.mm +++ b/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper_unittest.mm
@@ -10,6 +10,8 @@ #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h" #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h" +#import "ios/chrome/common/colors/incognito_color_util.h" +#import "ios/chrome/common/colors/semantic_color_names.h" #import "ios/chrome/test/fakes/fake_overscroll_actions_controller_delegate.h" #import "ios/web/public/test/fakes/test_web_state.h" #include "ios/web/public/test/test_web_thread_bundle.h" @@ -112,9 +114,7 @@ web_state_.SetBrowserState(browser_state_.get()); overscroll_tab_helper()->SetDelegate(overscroll_delegate_); SimulatePullForRefreshAction(); - UIColor* expected_color = - [UIColor colorWithWhite:kActionViewBackgroundColorBrightnessNonIncognito - alpha:1.0]; + UIColor* expected_color = [UIColor colorNamed:kBackgroundColor]; EXPECT_TRUE(action_view()); EXPECT_NSEQ(expected_color, action_view().backgroundColor); } @@ -135,9 +135,11 @@ browser_state_->GetOffTheRecordChromeBrowserState()); overscroll_tab_helper()->SetDelegate(overscroll_delegate_); SimulatePullForRefreshAction(); + // For iOS 13 and dark mode, the incognito overscroll actions view uses a + // dynamic color. UIColor* expected_color = - [UIColor colorWithWhite:kActionViewBackgroundColorBrightnessIncognito - alpha:1.0]; + color::IncognitoDynamicColor(true, [UIColor colorNamed:kBackgroundColor], + [UIColor colorNamed:kBackgroundDarkColor]); EXPECT_TRUE(action_view()); EXPECT_NSEQ(expected_color, action_view().backgroundColor); }
diff --git a/ios/chrome/browser/signin/authentication_service.mm b/ios/chrome/browser/signin/authentication_service.mm index b6a4d02..c95a50a 100644 --- a/ios/chrome/browser/signin/authentication_service.mm +++ b/ios/chrome/browser/signin/authentication_service.mm
@@ -59,8 +59,8 @@ ChromeIdentity* identity) { std::string gaia_id = base::SysNSStringToUTF8([identity gaiaID]); auto maybe_account = - identity_manager->FindAccountInfoForAccountWithRefreshTokenByGaiaId( - gaia_id); + identity_manager + ->FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId(gaia_id); AccountInfo account_info = maybe_account.has_value() ? maybe_account.value() : AccountInfo(); return account_info.account_id; @@ -311,8 +311,9 @@ // from the SSO library and that hosted_domain is set (should be the proper // hosted domain or kNoHostedDomainFound that are both non-empty strings). const base::Optional<AccountInfo> account_info = - identity_manager_->FindAccountInfoForAccountWithRefreshTokenByAccountId( - account_id); + identity_manager_ + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id); CHECK(account_info.has_value()); CHECK(!account_info->hosted_domain.empty()); @@ -547,7 +548,7 @@ bool AuthenticationService::IsAuthenticatedIdentityManaged() const { base::Optional<AccountInfo> primary_account_info = - identity_manager_->FindExtendedAccountInfoForAccount( + identity_manager_->FindExtendedAccountInfoForAccountWithRefreshToken( identity_manager_->GetPrimaryAccountInfo()); if (!primary_account_info) return false;
diff --git a/ios/chrome/browser/signin/authentication_service_unittest.mm b/ios/chrome/browser/signin/authentication_service_unittest.mm index 563f8b5..b25e45c 100644 --- a/ios/chrome/browser/signin/authentication_service_unittest.mm +++ b/ios/chrome/browser/signin/authentication_service_unittest.mm
@@ -193,7 +193,8 @@ std::string user_email = base::SysNSStringToUTF8([identity(0) userEmail]); AccountInfo account_info = identity_manager() - ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(user_email) + ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( + user_email) .value(); EXPECT_EQ(user_email, account_info.email); EXPECT_EQ(base::SysNSStringToUTF8([identity(0) gaiaID]), account_info.gaia);
diff --git a/ios/chrome/browser/tabs/tab_lifecycle.md b/ios/chrome/browser/tabs/tab_lifecycle.md index fa4e850..847fdfcd 100644 --- a/ios/chrome/browser/tabs/tab_lifecycle.md +++ b/ios/chrome/browser/tabs/tab_lifecycle.md
@@ -1,20 +1,13 @@ # `Tab` lifecycle -`LegacyTabHelper` creates `Tab` and keep it retained. `AttachTabHelpers` -creates `LegacyTabHelper` first and then all the other tab helpers. The -`AttachTabHelpers` method can be invoked on a newly created `WebState`. - -From that point, `LegacyTabHelper::GetTabFromWebState()` will return the -`Tab` associated with `WebState`. That method will return `nil` before -the call to `AttachTabHelpers`. +`Tab` is a virtual concept that refers to the` WebState` UI. A `WebState` is created then it's +passed to `AttachTabHelpers` which creates all the other tab helpers. and attaches them to +the `WebState`. ````cpp web::WebState::CreateParams params{...}; std::unique_ptr<web::WebState> web_state = web::WebState::Create(params); AttachTabHelper(web_state.get()); - -Tab* tab = LegacyTabHelper::GetFromWebState(web_state.get()); -DCHECK(tab != nil); ```` When a `WebState` is added to a `TabModel`'s `WebStateList`, @@ -24,18 +17,7 @@ TabModel* tab_model = ...; std::unique_ptr<web::WebState> web_state = ...; [tab_model webStateList]->InsertWebState(0, std::move(web_state)); -Tab* tab = LegacyTabHelper::GetFromWebState( - [tab_model webStateList]->GetWebStateAt(0)); -DCHECK(tab != nil); ``` -`Tab` register itself as a `WebStateObserver`. When `-webStateDestroyed:` -is invoked as part of `WebState` destruction, `Tab` destroys its state and -should no longer be used (as `-webState` will return `nullptr`). - -`LegacyTabHelper` is a `WebStateUserData` thus it is destroyed after the -`WebState` destructor completes. `LegacyTabHelper` release its reference -to `Tab` when destroyed. - -It is better to only use `WebState` and to access the `Tab` via -`LegacyTabHelper` as `Tab` will be removed in the new architecture. +All Tab helpers are `WebStateUserData` thus they are destroyed after the +`WebState` destructor completes.
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm index 4817761f..d323702 100644 --- a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm +++ b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
@@ -259,7 +259,7 @@ signin::IdentityManager* identity_manager = IdentityManagerFactory::GetForBrowserState(browserState); base::Optional<AccountInfo> primary_account_info = - identity_manager->FindExtendedAccountInfoForAccount( + identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken( identity_manager->GetPrimaryAccountInfo()); DCHECK(primary_account_info); NSString* hostedDomain =
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm index 1ae438f..1a53d2ca 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm
@@ -290,9 +290,13 @@ [ContentSuggestionsLearnMoreItem accessibilityIdentifier])) assertWithMatcher:grey_notNil()]; - // Open the last item. + // Open the last item. After the extra space of the last suggestion is + // removed, this test case fails on iPhoneX. Double-Tap on the last suggestion + // is a workaround. + // TODO(crbug.com/979143): Find out the reason and fix it. Also consider + // converting the test case to EG2 or deprecating MDCCollectionView. [CellWithMatcher(grey_accessibilityID(@"AdditionalSuggestion9")) - performAction:grey_tap()]; + performAction:grey_doubleTap()]; // Check that the page has been opened. [ChromeEarlGrey waitForWebStateContainingText:kPageLoadedString];
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_perftest.mm b/ios/chrome/browser/ui/omnibox/omnibox_perftest.mm index 5c63fbe2..417acbb8 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_perftest.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_perftest.mm
@@ -271,8 +271,7 @@ // Measures the amount of time it takes to type in the word "google" one // letter at a time. -// TODO(crbug.com/799488): Re-enable this test. -TEST_F(OmniboxPerfTest, DISABLED_TestTypingInTextField) { +TEST_F(OmniboxPerfTest, TestTypingInTextField) { OmniboxTextFieldIOS* textField = (OmniboxTextFieldIOS*)FindViewByClass( coordinator_.viewController.view, [OmniboxTextFieldIOS class]); // The characters to type into the omnibox text field.
diff --git a/ios/chrome/browser/ui/overscroll_actions/BUILD.gn b/ios/chrome/browser/ui/overscroll_actions/BUILD.gn index f2fa8c1..8b1ea85 100644 --- a/ios/chrome/browser/ui/overscroll_actions/BUILD.gn +++ b/ios/chrome/browser/ui/overscroll_actions/BUILD.gn
@@ -34,6 +34,7 @@ "//ios/chrome/browser/ui/toolbar/public", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/voice", + "//ios/chrome/common/colors", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser/ui", "//ios/web/common",
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm index 79a70ba..5829e04 100644 --- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm +++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm
@@ -367,7 +367,7 @@ } - (void)setStyle:(OverscrollStyle)style { - [self.overscrollActionView setStyle:style]; + self.overscrollActionView.style = style; } #pragma mark - webViewScrollView and UIScrollView delegates implementations
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h index 32db654..c14a2edb 100644 --- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h +++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h
@@ -58,6 +58,8 @@ @property(nonatomic, strong, readonly) UIView* backgroundView; // Whether cropping is set on the selection circle (true by default). @property(nonatomic, assign) BOOL selectionCroppingEnabled; +// The current style of the overscroll actions UI. +@property(nonatomic, assign) OverscrollStyle style; @property(nonatomic, assign) id<OverscrollActionsViewDelegate> delegate; @@ -82,9 +84,6 @@ // action has been selected. - (void)displayActionAnimation; -// Sets the style of the overscroll action UI. -- (void)setStyle:(OverscrollStyle)style; - @end #endif // IOS_CHROME_BROWSER_UI_OVERSCROLL_ACTIONS_OVERSCROLL_ACTIONS_VIEW_H_
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm index 714fec1..a1defd6 100644 --- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm +++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm
@@ -12,6 +12,8 @@ #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" #include "ios/chrome/browser/ui/util/rtl_geometry.h" #include "ios/chrome/browser/ui/util/uikit_ui_util.h" +#import "ios/chrome/common/colors/incognito_color_util.h" +#import "ios/chrome/common/colors/semantic_color_names.h" #include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/chrome/grit/ios_strings.h" #include "ios/chrome/grit/ios_theme_resources.h" @@ -88,9 +90,6 @@ const CGFloat kActionLabelVerticalPadding = 25.0; // The minimum distance between the action labels and the side of the screen. const CGFloat kActionLabelSidePadding = 15.0; -// The value to use as the R, B, and B components for the action label text and -// selection layer animation. -const CGFloat kSelectionColor = 0.4; // This function maps a value from a range to another. CGFloat MapValueToRange(FloatRange from, FloatRange to, CGFloat value) { @@ -196,6 +195,8 @@ @property(nonatomic, strong, readwrite) UIView* snapshotView; // The parent layer on the selection circle used for cropping purpose. @property(nonatomic, strong, readwrite) CALayer* selectionCircleCroppingLayer; +// Computed property for whether the current state is incognito or not. +@property(nonatomic, assign, readonly) BOOL incognito; // An absolute horizontal offset that also takes into account snapping. - (CGFloat)absoluteHorizontalOffset; @@ -249,30 +250,6 @@ @implementation OverscrollActionsView -@synthesize selectedAction = _selectedAction; -@synthesize addTabActionImageView = _addTabActionImageView; -@synthesize reloadActionImageView = _reloadActionImageView; -@synthesize closeTabActionImageView = _closeTabActionImageView; -@synthesize addTabActionImageViewHighlighted = - _addTabActionImageViewHighlighted; -@synthesize reloadActionImageViewHighlighted = - _reloadActionImageViewHighlighted; -@synthesize closeTabActionImageViewHighlighted = - _closeTabActionImageViewHighlighted; -@synthesize addTabLabel = _addTabLabel; -@synthesize reloadLabel = _reloadLabel; -@synthesize closeTabLabel = _closeTabLabel; -@synthesize highlightMaskLayer = _highlightMaskLayer; -@synthesize selectionCircleLayer = _selectionCircleLayer; -@synthesize selectionCircleMaskLayer = _selectionCircleMaskLayer; -@synthesize verticalOffset = _verticalOffset; -@synthesize horizontalOffset = _horizontalOffset; -@synthesize overscrollState = _overscrollState; -@synthesize backgroundView = _backgroundView; -@synthesize snapshotView = _snapshotView; -@synthesize selectionCircleCroppingLayer = _selectionCircleCroppingLayer; -@synthesize delegate = _delegate; - - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { @@ -291,18 +268,36 @@ [_selectionCircleCroppingLayer addSublayer:_selectionCircleLayer]; _addTabActionImageView = [[UIImageView alloc] init]; + _addTabActionImageView.image = [[UIImage imageNamed:kNewTabActionImage] + imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + _addTabActionImageView.tintColor = + [UIColor colorNamed:@"tab_toolbar_button_color"]; + [_addTabActionImageView sizeToFit]; [self addSubview:_addTabActionImageView]; _reloadActionImageView = [[UIImageView alloc] init]; + _reloadActionImageView.image = [[UIImage imageNamed:kReloadActionImage] + imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + _reloadActionImageView.tintColor = + [UIColor colorNamed:@"tab_toolbar_button_color"]; + [_reloadActionImageView sizeToFit]; if (UseRTLLayout()) [_reloadActionImageView setTransform:CGAffineTransformMakeScale(-1, 1)]; [self addSubview:_reloadActionImageView]; _closeTabActionImageView = [[UIImageView alloc] init]; + _closeTabActionImageView.image = [[UIImage imageNamed:kCloseActionImage] + imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + _closeTabActionImageView.tintColor = + [UIColor colorNamed:@"tab_toolbar_button_color"]; + [_closeTabActionImageView sizeToFit]; [self addSubview:_closeTabActionImageView]; _highlightMaskLayer = [[CALayer alloc] init]; _highlightMaskLayer.frame = self.bounds; _highlightMaskLayer.contentsGravity = kCAGravityCenter; - _highlightMaskLayer.backgroundColor = [[UIColor clearColor] CGColor]; + // Disable the entire highlight mask. + // TODO(crbug.com/986804): Remove the highlight mask after dark mode + // launches and this design is permanent. + _selectionCircleMaskLayer.fillColor = UIColor.clearColor.CGColor; [_highlightMaskLayer setMask:_selectionCircleMaskLayer]; [self.layer addSublayer:_highlightMaskLayer]; @@ -325,7 +320,7 @@ _addTabLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]; _addTabLabel.adjustsFontForContentSizeCategory = NO; - _addTabLabel.textColor = [UIColor colorWithWhite:kSelectionColor alpha:1.0]; + _addTabLabel.textColor = [UIColor colorNamed:@"tab_toolbar_button_color"]; _addTabLabel.text = l10n_util::GetNSString(IDS_IOS_OVERSCROLL_NEW_TAB_LABEL); [self addSubview:_addTabLabel]; @@ -337,7 +332,7 @@ _reloadLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]; _reloadLabel.adjustsFontForContentSizeCategory = NO; - _reloadLabel.textColor = [UIColor colorWithWhite:kSelectionColor alpha:1.0]; + _reloadLabel.textColor = [UIColor colorNamed:@"tab_toolbar_button_color"]; _reloadLabel.text = l10n_util::GetNSString(IDS_IOS_OVERSCROLL_RELOAD_LABEL); [self addSubview:_reloadLabel]; _closeTabLabel = [[UILabel alloc] init]; @@ -348,8 +343,7 @@ _closeTabLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]; _closeTabLabel.adjustsFontForContentSizeCategory = NO; - _closeTabLabel.textColor = - [UIColor colorWithWhite:kSelectionColor alpha:1.0]; + _closeTabLabel.textColor = [UIColor colorNamed:@"tab_toolbar_button_color"]; _closeTabLabel.text = l10n_util::GetNSString(IDS_IOS_OVERSCROLL_CLOSE_TAB_LABEL); [self addSubview:_closeTabLabel]; @@ -507,6 +501,11 @@ [CATransaction commit]; } +- (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { + [super traitCollectionDidChange:previousTraitCollection]; + [self updateLayerColors]; +} + #pragma mark - Private - (CGFloat)absoluteHorizontalOffset { @@ -895,7 +894,7 @@ const CGRect bounds = CGRectMake(0, 0, kSelectionEdge, kSelectionEdge); CAShapeLayer* selectionCircleLayer = [[CAShapeLayer alloc] init]; selectionCircleLayer.bounds = bounds; - selectionCircleLayer.backgroundColor = [[UIColor clearColor] CGColor]; + selectionCircleLayer.backgroundColor = UIColor.clearColor.CGColor; selectionCircleLayer.opacity = 0; selectionCircleLayer.transform = CATransform3DMakeScale( kSelectionInitialDownScale, kSelectionInitialDownScale, 1); @@ -942,7 +941,8 @@ } - (void)setStyle:(OverscrollStyle)style { - switch (style) { + _style = style; + switch (self.style) { case OverscrollStyle::NTP_NON_INCOGNITO: self.backgroundColor = ntp_home::kNTPBackgroundColor(); break; @@ -950,54 +950,47 @@ self.backgroundColor = [UIColor colorWithWhite:0 alpha:0]; break; case OverscrollStyle::REGULAR_PAGE_NON_INCOGNITO: - self.backgroundColor = [UIColor - colorWithWhite:kActionViewBackgroundColorBrightnessNonIncognito - alpha:1.0]; + self.backgroundColor = [UIColor colorNamed:kBackgroundColor]; break; case OverscrollStyle::REGULAR_PAGE_INCOGNITO: - self.backgroundColor = - [UIColor colorWithWhite:kActionViewBackgroundColorBrightnessIncognito - alpha:1.0]; + self.backgroundColor = color::IncognitoDynamicColor( + true, [UIColor colorNamed:kBackgroundColor], + [UIColor colorNamed:kBackgroundDarkColor]); break; } - BOOL incognito = style == OverscrollStyle::NTP_INCOGNITO || - style == OverscrollStyle::REGULAR_PAGE_INCOGNITO; - if (incognito) { - [_addTabActionImageView - setImage:[UIImage imageNamed:kNewTabActionActiveImage]]; - [_reloadActionImageView - setImage:[UIImage imageNamed:kReloadActionActiveImage]]; - [_closeTabActionImageView - setImage:[UIImage imageNamed:kCloseActionActiveImage]]; - _selectionCircleLayer.fillColor = - [UIColor colorWithRed:1 green:1 blue:1 alpha:0.2].CGColor; - _selectionCircleMaskLayer.fillColor = [[UIColor clearColor] CGColor]; - [_addTabLabel setTextColor:[UIColor whiteColor]]; - [_reloadLabel setTextColor:[UIColor whiteColor]]; - [_closeTabLabel setTextColor:[UIColor whiteColor]]; - } else { - [_addTabActionImageView setImage:[UIImage imageNamed:kNewTabActionImage]]; - [_reloadActionImageView setImage:[UIImage imageNamed:kReloadActionImage]]; - [_closeTabActionImageView setImage:[UIImage imageNamed:kCloseActionImage]]; + [self updateLayerColors]; +} - [_addTabActionImageViewHighlighted - setImage:[UIImage imageNamed:kNewTabActionActiveImage]]; - [_reloadActionImageViewHighlighted - setImage:[UIImage imageNamed:kReloadActionActiveImage]]; - [_closeTabActionImageViewHighlighted - setImage:[UIImage imageNamed:kCloseActionActiveImage]]; - - _selectionCircleLayer.fillColor = - [UIColor colorWithWhite:kSelectionColor alpha:1.0].CGColor; - _selectionCircleMaskLayer.fillColor = [[UIColor blackColor] CGColor]; +// CGColor doesn't support iOS 13 dynamic colors, so those must be resolved +// more often. +- (void)updateLayerColors { +#if defined(__IPHONE_13_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0) + if (@available(iOS 13, *)) { + [self.traitCollection performAsCurrentTraitCollection:^{ + _selectionCircleLayer.fillColor = + [UIColor colorNamed:kTextfieldBackgroundColor].CGColor; + }]; + return; } - [_addTabActionImageView sizeToFit]; - [_reloadActionImageView sizeToFit]; - [_closeTabActionImageView sizeToFit]; - [_addTabActionImageViewHighlighted sizeToFit]; - [_reloadActionImageViewHighlighted sizeToFit]; - [_closeTabActionImageViewHighlighted sizeToFit]; +#endif + + // Fallback for iOS 12. + if (self.incognito) { + UIColor* buttonColor = + [UIColor colorNamed:@"tab_toolbar_button_color_incognito"]; + _addTabActionImageView.tintColor = buttonColor; + _reloadActionImageView.tintColor = buttonColor; + _closeTabActionImageView.tintColor = buttonColor; + _addTabLabel.textColor = buttonColor; + _reloadLabel.textColor = buttonColor; + _closeTabLabel.textColor = buttonColor; + _selectionCircleLayer.fillColor = + [UIColor colorNamed:kTextfieldBackgroundDarkColor].CGColor; + } else { + _selectionCircleLayer.fillColor = + [UIColor colorNamed:kTextfieldBackgroundColor].CGColor; + } } - (OverscrollAction)actionAtLocation:(CGPoint)location {
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm index 31cd45e..0f625ec 100644 --- a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
@@ -529,7 +529,7 @@ signin::IdentityManager* identityManager = IdentityManagerFactory::GetForBrowserState(_browserState); base::Optional<AccountInfo> accountInfo = - identityManager->FindExtendedAccountInfoForAccount( + identityManager->FindExtendedAccountInfoForAccountWithRefreshToken( identityManager->GetPrimaryAccountInfo()); std::string hosted_domain = accountInfo.has_value() ? accountInfo.value().hosted_domain
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc index 2d5eb4a..b8ba3ece 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.cc +++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -35,5 +35,5 @@ const base::Feature kLanguageSettings{"LanguageSettings", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kOptionalArticleThumbnail{ - "OptionalArticleThumbnail", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kOptionalArticleThumbnail{"OptionalArticleThumbnail", + base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/webui/version_handler.cc b/ios/chrome/browser/ui/webui/version_handler.cc index f4fa09b..9a208e9 100644 --- a/ios/chrome/browser/ui/webui/version_handler.cc +++ b/ios/chrome/browser/ui/webui/version_handler.cc
@@ -18,14 +18,19 @@ void VersionHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( - version_ui::kRequestVersionInfo, - base::BindRepeating(&VersionHandler::HandleRequestVersionInfo, + version_ui::kRequestVariationInfo, + base::BindRepeating(&VersionHandler::HandleRequestVariationInfo, base::Unretained(this))); } -void VersionHandler::HandleRequestVersionInfo(const base::ListValue* args) { +void VersionHandler::HandleRequestVariationInfo(const base::ListValue* args) { // Respond with the variations info immediately. - base::Value variations_list = version_ui::GetVariationsList()->Clone(); - std::vector<const base::Value*> params{&variations_list}; - web_ui()->CallJavascriptFunction(version_ui::kReturnVariationInfo, params); + std::string callback_id; + CHECK_EQ(2U, args->GetSize()); + CHECK(args->GetString(0, &callback_id)); + + base::Value response(base::Value::Type::DICTIONARY); + response.SetKey(version_ui::kKeyVariationsList, + std::move(*version_ui::GetVariationsList())); + web_ui()->ResolveJavascriptCallback(base::Value(callback_id), response); }
diff --git a/ios/chrome/browser/ui/webui/version_handler.h b/ios/chrome/browser/ui/webui/version_handler.h index 20cf7f9..0fa7f849 100644 --- a/ios/chrome/browser/ui/webui/version_handler.h +++ b/ios/chrome/browser/ui/webui/version_handler.h
@@ -21,9 +21,9 @@ // content::WebUIMessageHandler implementation. void RegisterMessages() override; - // Callback for the "requestVersionInfo" message. This asynchronously requests - // the list of variations. - void HandleRequestVersionInfo(const base::ListValue* args); + // Callback for the "requestVariationInfo" message. This responds immediately + // with the list of variations. + void HandleRequestVariationInfo(const base::ListValue* args); private: DISALLOW_COPY_AND_ASSIGN(VersionHandler);
diff --git a/ios/chrome/browser/web/font_size_js_unittest.mm b/ios/chrome/browser/web/font_size_js_unittest.mm index fa8d8e57..b9426d71 100644 --- a/ios/chrome/browser/web/font_size_js_unittest.mm +++ b/ios/chrome/browser/web/font_size_js_unittest.mm
@@ -11,6 +11,7 @@ #import "ios/web/public/test/web_test_with_web_state.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" +#include "ui/base/device_form_factor.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -66,6 +67,12 @@ return; } #endif + // TODO(crbug.com/983776): This test also appears to be generally broken on + // iPads with beta 5. It appears to be a simulator bug. Re-enable on beta 6. + if (base::ios::IsRunningOnIOS13OrLater() && + ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { + return; + } float original_size = 0; float current_size = 0; @@ -189,6 +196,12 @@ return; } #endif + // TODO(crbug.com/983776): This test also appears to be generally broken on + // iPads with beta 5. It appears to be a simulator bug. Re-enable on beta 6. + if (base::ios::IsRunningOnIOS13OrLater() && + ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { + return; + } float original_size = 0; float current_size = 0; @@ -264,6 +277,12 @@ return; } #endif + // TODO(crbug.com/983776): This test also appears to be generally broken on + // iPads with beta 5. It appears to be a simulator bug. Re-enable on beta 6. + if (base::ios::IsRunningOnIOS13OrLater() && + ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { + return; + } float original_size_1 = 0; float original_size_2 = 0;
diff --git a/ios/chrome/test/run_all_unittests.cc b/ios/chrome/test/run_all_unittests.cc index 0d414b9d..e9d37063 100644 --- a/ios/chrome/test/run_all_unittests.cc +++ b/ios/chrome/test/run_all_unittests.cc
@@ -3,7 +3,7 @@ // found in the LICENSE file. #include "base/bind.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/test/launcher/unit_test_launcher.h" #include "base/threading/thread.h" #include "ios/chrome/app/startup/ios_chrome_main.h" @@ -19,7 +19,7 @@ base::Thread ipc_thread("IPC thread"); ipc_thread.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); mojo::core::ScopedIPCSupport ipc_support( ipc_thread.task_runner(), mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);
diff --git a/ios/web/init/web_main_loop.mm b/ios/web/init/web_main_loop.mm index bb7f858..984b229 100644 --- a/ios/web/init/web_main_loop.mm +++ b/ios/web/init/web_main_loop.mm
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/logging.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/histogram_macros.h" #include "base/path_service.h" #include "base/power_monitor/power_monitor.h" @@ -121,7 +122,7 @@ ios_global_state::StartThreadPool(); base::Thread::Options io_message_loop_options; - io_message_loop_options.message_loop_type = base::MessagePump::Type::IO; + io_message_loop_options.message_pump_type = base::MessagePumpType::IO; io_thread_ = std::make_unique<WebSubThread>(WebThread::IO); if (!io_thread_->StartWithOptions(io_message_loop_options)) LOG(FATAL) << "Failed to start WebThread::IO";
diff --git a/ios/web/test/test_web_thread.cc b/ios/web/test/test_web_thread.cc index 4cb38dc..a33d2fc 100644 --- a/ios/web/test/test_web_thread.cc +++ b/ios/web/test/test_web_thread.cc
@@ -6,6 +6,7 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "ios/web/web_sub_thread.h" #include "ios/web/web_thread_impl.h" @@ -61,7 +62,7 @@ void TestWebThread::StartIOThreadUnregistered() { base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; CHECK(real_thread_->StartWithOptions(options)); }
diff --git a/ipc/ipc_channel_mojo_unittest.cc b/ipc/ipc_channel_mojo_unittest.cc index 387efad4..abfe788 100644 --- a/ipc/ipc_channel_mojo_unittest.cc +++ b/ipc/ipc_channel_mojo_unittest.cc
@@ -21,6 +21,7 @@ #include "base/memory/platform_shared_memory_region.h" #include "base/memory/shared_memory.h" #include "base/memory/shared_memory_mapping.h" +#include "base/message_loop/message_pump_type.h" #include "base/optional.h" #include "base/path_service.h" #include "base/pickle.h" @@ -787,7 +788,7 @@ void CreateProxy(IPC::Listener* listener) { io_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); proxy_ = IPC::SyncChannel::Create(listener, io_thread_.task_runner(), base::ThreadTaskRunnerHandle::Get(), &never_signaled_);
diff --git a/ipc/ipc_channel_proxy_unittest.cc b/ipc/ipc_channel_proxy_unittest.cc index 6f6a435..65e40ef 100644 --- a/ipc/ipc_channel_proxy_unittest.cc +++ b/ipc/ipc_channel_proxy_unittest.cc
@@ -8,7 +8,7 @@ #include <stdint.h> #include <memory> -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/pickle.h" #include "base/run_loop.h" #include "base/threading/thread.h" @@ -245,7 +245,7 @@ thread_.reset(new base::Thread("ChannelProxyTestServerThread")); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; thread_->StartWithOptions(options); listener_.reset(new QuitListener());
diff --git a/ipc/ipc_sync_channel_unittest.cc b/ipc/ipc_sync_channel_unittest.cc index f9804dd0..6a11e14 100644 --- a/ipc/ipc_sync_channel_unittest.cc +++ b/ipc/ipc_sync_channel_unittest.cc
@@ -15,6 +15,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/macros.h" +#include "base/message_loop/message_pump_type.h" #include "base/process/process_handle.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -88,7 +89,7 @@ channel_->Close(); } void Start() { - StartThread(&listener_thread_, base::MessageLoop::TYPE_DEFAULT); + StartThread(&listener_thread_, base::MessagePumpType::DEFAULT); ListenerThread()->task_runner()->PostTask( FROM_HERE, base::BindOnce(&Worker::OnStart, base::Unretained(this))); } @@ -192,7 +193,7 @@ // Called on the listener thread to create the sync channel. void OnStart() { // Link ipc_thread_, listener_thread_ and channel_ altogether. - StartThread(&ipc_thread_, base::MessageLoop::TYPE_IO); + StartThread(&ipc_thread_, base::MessagePumpType::IO); channel_.reset(CreateChannel()); channel_created_->Signal(); Run(); @@ -237,9 +238,9 @@ return true; } - void StartThread(base::Thread* thread, base::MessageLoop::Type type) { + void StartThread(base::Thread* thread, base::MessagePumpType type) { base::Thread::Options options; - options.message_loop_type = type; + options.message_pump_type = type; thread->StartWithOptions(options); } @@ -1040,7 +1041,7 @@ std::move(channel_handle)), thread_("helper_thread") { base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; + options.message_pump_type = base::MessagePumpType::DEFAULT; thread_.StartWithOptions(options); filter_ = new TestSyncMessageFilter(shutdown_event(), this, thread_.task_runner());
diff --git a/media/audio/audio_input_unittest.cc b/media/audio/audio_input_unittest.cc index 2e908188..3763e79 100644 --- a/media/audio/audio_input_unittest.cc +++ b/media/audio/audio_input_unittest.cc
@@ -8,7 +8,7 @@ #include "base/callback.h" #include "base/environment.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/test/test_message_loop.h" #include "base/threading/platform_thread.h" @@ -69,7 +69,7 @@ class AudioInputTest : public testing::Test { public: AudioInputTest() - : message_loop_(base::MessageLoop::TYPE_UI), + : message_loop_(base::MessagePumpType::UI), audio_manager_(AudioManager::CreateForTesting( std::make_unique<TestAudioThread>())), audio_input_stream_(NULL) {
diff --git a/media/audio/audio_thread_impl.cc b/media/audio/audio_thread_impl.cc index c3dfddf..4f7b07c 100644 --- a/media/audio/audio_thread_impl.cc +++ b/media/audio/audio_thread_impl.cc
@@ -4,6 +4,7 @@ #include "media/audio/audio_thread_impl.h" +#include "base/message_loop/message_pump_type.h" #include "base/optional.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/default_tick_clock.h" @@ -20,7 +21,7 @@ thread_.init_com_with_mta(true); #elif defined(OS_FUCHSIA) // FIDL-based APIs require async_t, which is initialized on IO thread. - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; #endif CHECK(thread_.StartWithOptions(thread_options));
diff --git a/media/audio/mac/audio_auhal_mac_unittest.cc b/media/audio/mac/audio_auhal_mac_unittest.cc index 03eb7544..281b941 100644 --- a/media/audio/mac/audio_auhal_mac_unittest.cc +++ b/media/audio/mac/audio_auhal_mac_unittest.cc
@@ -4,7 +4,7 @@ #include "base/bind.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/synchronization/waitable_event.h" #include "base/test/test_message_loop.h" @@ -39,7 +39,7 @@ class AUHALStreamTest : public testing::Test { public: AUHALStreamTest() - : message_loop_(base::MessageLoop::TYPE_UI), + : message_loop_(base::MessagePumpType::UI), manager_(AudioManager::CreateForTesting( std::make_unique<TestAudioThread>())), manager_device_info_(manager_.get()) {
diff --git a/media/capture/run_all_unittests.cc b/media/capture/run_all_unittests.cc index 9c4b277..b3173506 100644 --- a/media/capture/run_all_unittests.cc +++ b/media/capture/run_all_unittests.cc
@@ -5,7 +5,7 @@ #include <stdio.h> #include "base/bind.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/test/launcher/unit_test_launcher.h" #include "base/test/test_suite.h" #include "base/threading/thread.h" @@ -22,7 +22,7 @@ void SetUp() final { mojo::core::Init(); mojo_ipc_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); mojo_ipc_support_.reset(new mojo::core::ScopedIPCSupport( mojo_ipc_thread_.task_runner(), mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST));
diff --git a/media/cast/test/utility/standalone_cast_environment.cc b/media/cast/test/utility/standalone_cast_environment.cc index 88d166f0..f12ef34 100644 --- a/media/cast/test/utility/standalone_cast_environment.cc +++ b/media/cast/test/utility/standalone_cast_environment.cc
@@ -5,7 +5,7 @@ #include "media/cast/test/utility/standalone_cast_environment.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/threading/thread_restrictions.h" #include "base/time/default_tick_clock.h" @@ -21,8 +21,7 @@ name##_thread_.StartWithOptions(options); \ CastEnvironment::name##_thread_proxy_ = name##_thread_.task_runner() - CREATE_TASK_RUNNER(main, - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + CREATE_TASK_RUNNER(main, base::Thread::Options(base::MessagePumpType::IO, 0)); CREATE_TASK_RUNNER(audio, base::Thread::Options()); CREATE_TASK_RUNNER(video, base::Thread::Options()); #undef CREATE_TASK_RUNNER
diff --git a/media/cast/test/utility/udp_proxy.cc b/media/cast/test/utility/udp_proxy.cc index 1337bcd..207dfc9 100644 --- a/media/cast/test/utility/udp_proxy.cc +++ b/media/cast/test/utility/udp_proxy.cc
@@ -13,7 +13,7 @@ #include "base/containers/circular_deque.h" #include "base/logging.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/rand_util.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" @@ -686,7 +686,7 @@ blocked_(false) { base::ScopedAllowBlockingForTesting allow_blocking; proxy_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); base::WaitableEvent start_event( base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED);
diff --git a/media/gpu/test/video_decode_accelerator_unittest_helpers.cc b/media/gpu/test/video_decode_accelerator_unittest_helpers.cc index 5e05151d..95bc1a7 100644 --- a/media/gpu/test/video_decode_accelerator_unittest_helpers.cc +++ b/media/gpu/test/video_decode_accelerator_unittest_helpers.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/files/file_util.h" +#include "base/message_loop/message_pump_type.h" #include "base/strings/string_split.h" #include "base/threading/thread_task_runner_handle.h" #include "media/base/video_decoder_config.h" @@ -37,7 +38,7 @@ void VideoDecodeAcceleratorTestEnvironment::SetUp() { base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_UI; + options.message_pump_type = base::MessagePumpType::UI; rendering_thread_.StartWithOptions(options); base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
diff --git a/media/gpu/video_encode_accelerator_unittest.cc b/media/gpu/video_encode_accelerator_unittest.cc index df4e3b7..e110931 100644 --- a/media/gpu/video_encode_accelerator_unittest.cc +++ b/media/gpu/video_encode_accelerator_unittest.cc
@@ -24,6 +24,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/unsafe_shared_memory_region.h" #include "base/memory/weak_ptr.h" +#include "base/message_loop/message_pump_type.h" #include "base/numerics/safe_conversions.h" #include "base/process/process_handle.h" #include "base/single_thread_task_runner.h" @@ -738,7 +739,7 @@ ui::OzonePlatform::InitializeForUI(params); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_UI; + options.message_pump_type = base::MessagePumpType::UI; ASSERT_TRUE(rendering_thread_.StartWithOptions(options)); base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED);
diff --git a/media/midi/task_service.cc b/media/midi/task_service.cc index 4ba79ddb..8fc087b 100644 --- a/media/midi/task_service.cc +++ b/media/midi/task_service.cc
@@ -7,7 +7,7 @@ #include <limits> #include "base/bind.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" @@ -149,7 +149,7 @@ #if defined(OS_WIN) threads_[thread]->init_com_with_mta(true); #elif defined(OS_MACOSX) - options.message_loop_type = base::MessageLoop::TYPE_UI; + options.message_pump_type = base::MessagePumpType::UI; #endif threads_[thread]->StartWithOptions(options); }
diff --git a/mojo/core/channel_unittest.cc b/mojo/core/channel_unittest.cc index 623ec6c..d098f56 100644 --- a/mojo/core/channel_unittest.cc +++ b/mojo/core/channel_unittest.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/optional.h" #include "base/process/process_handle.h" #include "base/process/process_metrics.h" @@ -250,14 +251,14 @@ }; TEST(ChannelTest, PeerShutdownDuringRead) { - base::MessageLoop message_loop(base::MessageLoop::TYPE_IO); + base::MessageLoop message_loop(base::MessagePumpType::IO); PlatformChannel channel; // Create a "client" Channel with one end of the pipe, and Start() it. std::unique_ptr<base::Thread> client_thread = std::make_unique<base::Thread>("clientio_thread"); client_thread->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); scoped_refptr<Channel> client_channel = Channel::Create( nullptr, ConnectionParams(channel.TakeRemoteEndpoint()), @@ -314,7 +315,7 @@ }; TEST(ChannelTest, RejectHandles) { - base::MessageLoop message_loop(base::MessageLoop::TYPE_IO); + base::MessageLoop message_loop(base::MessagePumpType::IO); PlatformChannel platform_channel; RejectHandlesDelegate receiver_delegate; @@ -422,7 +423,7 @@ TEST(ChannelTest, PeerStressTest) { constexpr size_t kLotsOfMessages = 1024; - base::MessageLoop message_loop(base::MessageLoop::TYPE_IO); + base::MessageLoop message_loop(base::MessagePumpType::IO); base::RunLoop run_loop; // Both channels should receive all the messages that each is sent. When @@ -441,7 +442,7 @@ // Create a second IO thread for the peer channel. base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; base::Thread peer_thread("peer_b_io"); peer_thread.StartWithOptions(thread_options); @@ -543,7 +544,7 @@ }; TEST(ChannelTest, MessageSizeTest) { - base::MessageLoop message_loop(base::MessageLoop::TYPE_IO); + base::MessageLoop message_loop(base::MessagePumpType::IO); PlatformChannel platform_channel; SingleMessageWaiterDelegate receiver_delegate;
diff --git a/mojo/public/cpp/bindings/lib/validation_util.h b/mojo/public/cpp/bindings/lib/validation_util.h index 3b88956f..a8edae3a 100644 --- a/mojo/public/cpp/bindings/lib/validation_util.h +++ b/mojo/public/cpp/bindings/lib/validation_util.h
@@ -147,16 +147,24 @@ ValidationContext* validation_context); template <typename T> -bool ValidateContainer(const Pointer<T>& input, - ValidationContext* validation_context, - const ContainerValidateParams* validate_params) { - ValidationContext::ScopedDepthTracker depth_tracker(validation_context); +bool ValidateParams(const Pointer<T>& input, + ValidationContext* validation_context) { if (validation_context->ExceedsMaxDepth()) { ReportValidationError(validation_context, VALIDATION_ERROR_MAX_RECURSION_DEPTH); return false; } - return ValidatePointer(input, validation_context) && + + return ValidatePointer(input, validation_context); +} + +template <typename T> +bool ValidateContainer(const Pointer<T>& input, + ValidationContext* validation_context, + const ContainerValidateParams* validate_params) { + ValidationContext::ScopedDepthTracker depth_tracker(validation_context); + + return ValidateParams(input, validation_context) && T::Validate(input.Get(), validation_context, validate_params); } @@ -164,12 +172,8 @@ bool ValidateStruct(const Pointer<T>& input, ValidationContext* validation_context) { ValidationContext::ScopedDepthTracker depth_tracker(validation_context); - if (validation_context->ExceedsMaxDepth()) { - ReportValidationError(validation_context, - VALIDATION_ERROR_MAX_RECURSION_DEPTH); - return false; - } - return ValidatePointer(input, validation_context) && + + return ValidateParams(input, validation_context) && T::Validate(input.Get(), validation_context); } @@ -189,12 +193,8 @@ bool ValidateNonInlinedUnion(const Pointer<T>& input, ValidationContext* validation_context) { ValidationContext::ScopedDepthTracker depth_tracker(validation_context); - if (validation_context->ExceedsMaxDepth()) { - ReportValidationError(validation_context, - VALIDATION_ERROR_MAX_RECURSION_DEPTH); - return false; - } - return ValidatePointer(input, validation_context) && + + return ValidateParams(input, validation_context) && T::Validate(input.Get(), validation_context, false); }
diff --git a/net/BUILD.gn b/net/BUILD.gn index be5b930f..76fef2d3 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -3248,6 +3248,18 @@ "//third_party/boringssl", ] } + + executable("quic_client_for_interop_test") { + sources = [ + "third_party/quiche/src/quic/tools/fake_proof_verifier.h", + "third_party/quiche/src/quic/tools/quic_client_interop_test_bin.cc", + ] + deps = [ + ":epoll_quic_tools", + ":net", + ":simple_quic_tools", + ] + } } if (is_android) {
diff --git a/net/base/network_change_notifier_fuchsia_unittest.cc b/net/base/network_change_notifier_fuchsia_unittest.cc index cd339bf8..0e30c892b 100644 --- a/net/base/network_change_notifier_fuchsia_unittest.cc +++ b/net/base/network_change_notifier_fuchsia_unittest.cc
@@ -12,6 +12,7 @@ #include "base/bind.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/threading/sequence_bound.h" #include "base/threading/thread.h" @@ -165,7 +166,7 @@ explicit FakeNetstackAsync( fidl::InterfaceRequest<fuchsia::netstack::Netstack> netstack_request) : thread_("Netstack Thread") { - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); CHECK(thread_.StartWithOptions(options)); netstack_ = base::SequenceBound<FakeNetstack>(thread_.task_runner(), std::move(netstack_request));
diff --git a/net/base/network_config_watcher_mac.cc b/net/base/network_config_watcher_mac.cc index 5aef19f..fb6362c8 100644 --- a/net/base/network_config_watcher_mac.cc +++ b/net/base/network_config_watcher_mac.cc
@@ -10,7 +10,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread.h" @@ -265,7 +265,7 @@ // We create this notifier thread because the notification implementation // needs a thread with a CFRunLoop, and there's no guarantee that // MessageLoopCurrent::Get() meets that criterion. - base::Thread::Options thread_options(base::MessageLoop::TYPE_UI, 0); + base::Thread::Options thread_options(base::MessagePumpType::UI, 0); notifier_thread_->StartWithOptions(thread_options); }
diff --git a/net/base/network_notification_thread_mac.cc b/net/base/network_notification_thread_mac.cc index 436b99b6..684bfc9 100644 --- a/net/base/network_notification_thread_mac.cc +++ b/net/base/network_notification_thread_mac.cc
@@ -4,6 +4,7 @@ #include "net/base/network_notification_thread_mac.h" +#include "base/message_loop/message_pump_type.h" #include "base/no_destructor.h" #include "base/threading/thread.h" @@ -22,7 +23,7 @@ NotificationThreadMac() : thread_("NetworkNotificationThreadMac") { base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_UI; + options.message_pump_type = base::MessagePumpType::UI; options.joinable = false; thread_.StartWithOptions(options); task_runner_ = thread_.task_runner();
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc index 0d0d2c7..b7b90c31 100644 --- a/net/cert/cert_verify_proc_unittest.cc +++ b/net/cert/cert_verify_proc_unittest.cc
@@ -12,6 +12,7 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/macros.h" +#include "base/message_loop/message_pump_type.h" #include "base/rand_util.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" @@ -874,14 +875,7 @@ } bool WeakKeysAreInvalid() const { -#if defined(OS_IOS) - // Starting with iOS 13, certs with weak keys are treated as (recoverable) - // invalid certificate errors. - if (verify_proc_type() == CERT_VERIFY_PROC_IOS && - base::ios::IsRunningOnIOS13OrLater()) { - return true; - } -#elif defined(OS_MACOSX) +#if defined(OS_MACOSX) and !defined(OS_IOS) // Starting with Mac OS 10.12, certs with weak keys are treated as // (recoverable) invalid certificate errors. if (verify_proc_type() == CERT_VERIFY_PROC_MAC && @@ -3030,7 +3024,7 @@ void SetUp() override { // Create a network thread to be used for network fetches, and wait for // initialization to complete on that thread. - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); network_thread_ = std::make_unique<base::Thread>("network_thread"); CHECK(network_thread_->StartWithOptions(options));
diff --git a/net/cert_net/cert_net_fetcher_impl_unittest.cc b/net/cert_net/cert_net_fetcher_impl_unittest.cc index 2456bb28..bf05678e 100644 --- a/net/cert_net/cert_net_fetcher_impl_unittest.cc +++ b/net/cert_net/cert_net_fetcher_impl_unittest.cc
@@ -10,7 +10,7 @@ #include "base/bind.h" #include "base/compiler_specific.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/synchronization/lock.h" #include "net/cert/cert_net_fetcher.h" @@ -178,7 +178,7 @@ void StartNetworkThread() { // Start the network thread. network_thread_.reset(new base::Thread("network thread")); - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); EXPECT_TRUE(network_thread_->StartWithOptions(options)); // Initialize the URLRequestContext (and wait till it has completed).
diff --git a/net/disk_cache/blockfile/backend_impl.cc b/net/disk_cache/blockfile/backend_impl.cc index b231b7c..eb87014 100644 --- a/net/disk_cache/blockfile/backend_impl.cc +++ b/net/disk_cache/blockfile/backend_impl.cc
@@ -15,7 +15,7 @@ #include "base/hash/hash.h" #include "base/lazy_instance.h" #include "base/location.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" #include "base/rand_util.h" @@ -118,7 +118,7 @@ public: CacheThread() : base::Thread("CacheThread_BlockFile") { CHECK( - StartWithOptions(base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); + StartWithOptions(base::Thread::Options(base::MessagePumpType::IO, 0))); } ~CacheThread() override {
diff --git a/net/http/http_proxy_connect_job.cc b/net/http/http_proxy_connect_job.cc index a9fbbdc..30ccddd 100644 --- a/net/http/http_proxy_connect_job.cc +++ b/net/http/http_proxy_connect_job.cc
@@ -698,7 +698,8 @@ spdy::SpdyPriority spdy_priority = ConvertRequestPriorityToQuicPriority(kH2QuicTunnelPriority); - quic_stream->SetPriority(spdy_priority); + spdy::SpdyStreamPrecedence precedence(spdy_priority); + quic_stream->SetPriority(precedence); transport_socket_ = std::make_unique<QuicProxyClientSocket>( std::move(quic_stream), std::move(quic_session_), GetUserAgent(),
diff --git a/net/nqe/network_congestion_analyzer.cc b/net/nqe/network_congestion_analyzer.cc index ada2a65..60300ed 100644 --- a/net/nqe/network_congestion_analyzer.cc +++ b/net/nqe/network_congestion_analyzer.cc
@@ -62,6 +62,20 @@ base::TimeDelta::FromMilliseconds(40), base::TimeDelta::FromMilliseconds(15)}; +// The min and max values for the count of in-flight requests in +// |count_inflight_requests_to_queueing_delay_| cache. This range covers more +// than 95% of cases under all types of connection types. +static constexpr size_t kMinCountOfRequests = 1u; +static constexpr size_t kMaxCountOfRequests = 30u; + +// The max number of samples that can be hold in a bucket in the +// |count_inflight_requests_to_queueing_delay_| cache. +static constexpr size_t kMaxCountOfSamplesPerBucket = 10u; + +// The min value for a count-delay mapping sample to be reasonable enough to be +// inserted into the cache. +static constexpr size_t kMinScoreForValidSamples = 50; + } // namespace namespace nqe { @@ -75,7 +89,8 @@ tick_clock_(tick_clock), recent_active_hosts_count_(0u), count_inflight_requests_for_peak_queueing_delay_(0u), - peak_count_inflight_requests_measurement_period_(0u) { + peak_count_inflight_requests_measurement_period_(0u), + count_peak_queueing_delay_mapping_sample_(0u) { DCHECK(tick_clock_); DCHECK(network_quality_estimator_); DCHECK_EQ(kQueueingDelayLevelMaxVal, @@ -143,6 +158,19 @@ return peak_delay; } +// net::EffectiveConnectionTypeObserver: +void NetworkCongestionAnalyzer::OnEffectiveConnectionTypeChanged( + net::EffectiveConnectionType effective_connection_type) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (effective_connection_type_ == effective_connection_type) + return; + + effective_connection_type_ = effective_connection_type; + count_inflight_requests_to_queueing_delay_.clear(); + count_peak_queueing_delay_mapping_sample_ = 0; +} + void NetworkCongestionAnalyzer::ComputeRecentQueueingDelay( const std::map<nqe::internal::IPHash, nqe::internal::CanonicalStats>& recent_rtt_stats, @@ -335,6 +363,122 @@ base::NumberToString(peak_queueing_delay_level), count_inflight_requests_for_peak_queueing_delay_); } + + UpdateRequestsCountAndPeakQueueingDelayMapping(); +} + +void NetworkCongestionAnalyzer:: + UpdateRequestsCountAndPeakQueueingDelayMapping() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + size_t truncated_count = + std::min(std::max(count_inflight_requests_for_peak_queueing_delay_, + kMinCountOfRequests), + kMaxCountOfRequests); + + DCHECK_LE(kMinCountOfRequests, truncated_count); + DCHECK_GE(kMaxCountOfRequests, truncated_count); + + base::Optional<size_t> mapping_score = + ComputePeakDelayMappingSampleScore(truncated_count, peak_queueing_delay_); + // Records the score that evaluates the mapping between the count of requests + // to the peak observed queueing delay. + if (mapping_score.has_value()) { + UMA_HISTOGRAM_COUNTS_100( + "NQE.CongestionAnalyzer.PeakQueueingDelayMappingScore", + mapping_score.value()); + } + + // Discards the mapping sample if there are at least 10 samples in the cache + // and its score is less than the threshold. The purpose is to make the + // majority of cached samples reasonable so that they can be used to evaluate + // whether a new sample is valid or not. + if (count_peak_queueing_delay_mapping_sample_ >= 10 && + mapping_score.value_or(0) < kMinScoreForValidSamples) { + return; + } + + AddRequestsCountAndPeakQueueingDelaySample(truncated_count, + peak_queueing_delay_); +} + +base::Optional<size_t> +NetworkCongestionAnalyzer::ComputePeakDelayMappingSampleScore( + const size_t count_inflight_requests, + const base::TimeDelta& peak_queueing_delay) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (count_inflight_requests < kMinCountOfRequests || + count_inflight_requests > kMaxCountOfRequests) { + return base::nullopt; + } + + if (count_peak_queueing_delay_mapping_sample_ < 5) + return base::nullopt; + + size_t count_positive_samples = 0; + size_t delay_level = ComputePeakQueueingDelayLevel(peak_queueing_delay); + DCHECK_LE(1u, delay_level); + + for (const auto& cached_entry : count_inflight_requests_to_queueing_delay_) { + if (cached_entry.first < count_inflight_requests) { + for (const auto& it : cached_entry.second) { + if (it < peak_queueing_delay) + ++count_positive_samples; + } + } else if (cached_entry.first == count_inflight_requests) { + for (const auto& it : cached_entry.second) { + size_t it_delay_level = ComputePeakQueueingDelayLevel(it); + // Two samples are considered near if the difference in queueing delay + // levels is small. The absolute time difference is small for samples + // whose queueing delay level is from 1 to 5 (max val=500 msec). The two + // samples are also considered near if the absolute time difference is + // less than the 500 msec threshold. + if (it_delay_level <= delay_level + 1 || + it_delay_level >= delay_level - 1 || + std::abs(it.InMilliseconds() - + peak_queueing_delay.InMilliseconds()) <= 500) { + ++count_positive_samples; + } + } + } else { + for (const auto& it : cached_entry.second) { + if (it > peak_queueing_delay) + ++count_positive_samples; + } + } + } + + return count_positive_samples * 100 / + count_peak_queueing_delay_mapping_sample_; +} + +void NetworkCongestionAnalyzer::AddRequestsCountAndPeakQueueingDelaySample( + const size_t count_inflight_requests, + const base::TimeDelta& peak_queueing_delay) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (count_inflight_requests < kMinCountOfRequests || + count_inflight_requests > kMaxCountOfRequests) { + return; + } + + auto count_map_it = + count_inflight_requests_to_queueing_delay_.find(count_inflight_requests); + // Creates a new entry if no matching record is found. + if (count_map_it == count_inflight_requests_to_queueing_delay_.end()) { + count_inflight_requests_to_queueing_delay_[count_inflight_requests] + .push_front(peak_queueing_delay); + ++count_peak_queueing_delay_mapping_sample_; + } else { + count_map_it->second.push_front(peak_queueing_delay); + ++count_peak_queueing_delay_mapping_sample_; + + if (count_map_it->second.size() > kMaxCountOfSamplesPerBucket) { + count_map_it->second.pop_back(); + --count_peak_queueing_delay_mapping_sample_; + } + } } void NetworkCongestionAnalyzer::set_recent_downlink_throughput_kbps(
diff --git a/net/nqe/network_congestion_analyzer.h b/net/nqe/network_congestion_analyzer.h index 3a6eecd4..7fd6f85c 100644 --- a/net/nqe/network_congestion_analyzer.h +++ b/net/nqe/network_congestion_analyzer.h
@@ -6,6 +6,7 @@ #define NET_NQE_NETWORK_CONGESTION_ANALYZER_H_ #include <cmath> +#include <deque> #include <map> #include <unordered_map> @@ -16,6 +17,7 @@ #include "base/time/time.h" #include "net/base/net_export.h" #include "net/nqe/effective_connection_type.h" +#include "net/nqe/effective_connection_type_observer.h" #include "net/nqe/network_quality.h" #include "net/nqe/network_quality_estimator_util.h" #include "net/nqe/observation_buffer.h" @@ -32,11 +34,12 @@ // NetworkCongestionAnalyzer holds the network congestion information, such // as the recent packet queue length in the mobile edge, recent queueing delay, // recent downlink throughput. -class NET_EXPORT_PRIVATE NetworkCongestionAnalyzer { +class NET_EXPORT_PRIVATE NetworkCongestionAnalyzer + : public net::EffectiveConnectionTypeObserver { public: NetworkCongestionAnalyzer(NetworkQualityEstimator* network_quality_estimator, const base::TickClock* tick_clock); - ~NetworkCongestionAnalyzer(); + ~NetworkCongestionAnalyzer() override; // Returns the number of hosts that are involved in the last attempt of // computing the recent queueing delay. These hosts are recent active hosts. @@ -88,6 +91,12 @@ TestDetectLowQueueingDelay); FRIEND_TEST_ALL_PREFIXES(NetworkCongestionAnalyzerTest, TestComputeQueueingDelayLevel); + FRIEND_TEST_ALL_PREFIXES(NetworkCongestionAnalyzerTest, + TestComputePeakDelayMappingSampleScore); + + // net::EffectiveConnectionTypeObserver: + void OnEffectiveConnectionTypeChanged( + net::EffectiveConnectionType effective_connection_type) override; // Returns the bucketized value of the peak queueing delay (a.k.a. peak // queueing delay level). |peak_queueing_delay| is peak queueing delay @@ -116,6 +125,29 @@ // concurrent requests within the current measurement period. void FinalizeCurrentMeasurementPeriod(); + // Updates the cache that stores the mapping between the count of in-flight + // requests to the peak observed queueing delay. + void UpdateRequestsCountAndPeakQueueingDelayMapping(); + + // Computes the score that evaluates the mapping between the count of inflight + // requests to peak queueing delay. The score equals to the percent value of + // existing samples that conform to the rule: the more in-flight requests, the + // higher peak queueing delay. Samples with more in-flight requests should + // result in higher queueing delay. Samples with fewer in-flight requests + // should result in lower queueing delay. Samples with the same count of + // requests should result in similar queueing delay. Returns nullopt if the + // count of in-flight requests is out of range or there are less than 5 + // samples in the cache. + base::Optional<size_t> ComputePeakDelayMappingSampleScore( + const size_t count_inflight_requests, + const base::TimeDelta& peak_queueing_delay) const; + + // Inserts the mapping sample into the cache. The mapping is between the count + // of in-flight requests to the observed peak queueing delay. + void AddRequestsCountAndPeakQueueingDelaySample( + const size_t count_inflight_requests, + const base::TimeDelta& peak_queueing_delay); + // Starts tracking the peak queueing delay for |request|. void TrackPeakQueueingDelayBegin(const URLRequest* request); @@ -144,6 +176,10 @@ // Guaranteed to be non-null during the lifetime of |this|. const base::TickClock* tick_clock_; + // Current value of the effective connection type. + net::EffectiveConnectionType effective_connection_type_ = + net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN; + // Recent downstream throughput estimate. It is the median of most recent // downstream throughput observations (in kilobits per second). base::Optional<int32_t> recent_downlink_throughput_kbps_; @@ -194,6 +230,19 @@ // delay. base::Optional<size_t> count_inflight_requests_causing_high_delay_; + // The cache that holds the mapping between the number of in-flight requests + // to the peak observed queueing delay. Samples are stored in buckets keyed by + // the count of in-flight requests. This helps searching for the in-flight + // requests threshold to keep the peak queueing delay bounded. The count of + // in-flight requests ranges from 1 to 30. A sample with a lower or a higher + // value would be casted to the closest boundary. Each bucket can hold at most + // |kMaxCountOfSamplesPerBucket| most-recent samples. + std::map<size_t, std::deque<base::TimeDelta>> + count_inflight_requests_to_queueing_delay_; + + // The number of samples in |count_inflight_requests_to_queueing_delay_|. + size_t count_peak_queueing_delay_mapping_sample_; + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(NetworkCongestionAnalyzer);
diff --git a/net/nqe/network_congestion_analyzer_unittest.cc b/net/nqe/network_congestion_analyzer_unittest.cc index 8123acf7..659c71b 100644 --- a/net/nqe/network_congestion_analyzer_unittest.cc +++ b/net/nqe/network_congestion_analyzer_unittest.cc
@@ -40,6 +40,7 @@ base::TimeDelta::FromMilliseconds(400), base::TimeDelta::FromMilliseconds(40), base::TimeDelta::FromMilliseconds(15)}; +static constexpr size_t kMinScoreForValidSamples = 50; // Verifies that the network queueing delay is computed correctly based on RTT // and downlink throughput observations. @@ -247,6 +248,93 @@ } } +// Verifies that the mapping sample is correctly evaluated with the computation +// of the count-delay mapping score. Also, verifies that samples are inserted +// into the cache when their mapping scores exceed the threshold. +TEST_F(NetworkCongestionAnalyzerTest, TestComputePeakDelayMappingSampleScore) { + TestNetworkQualityEstimator network_quality_estimator; + base::SimpleTestTickClock tick_clock; + NetworkCongestionAnalyzer analyzer(&network_quality_estimator, &tick_clock); + + // Insert these samples into the cache. They are used to evaluate whether a + // new sample is valid or not. + std::map<size_t, base::TimeDelta> cached_requests_count_peak_delay_sample = { + {1, base::TimeDelta::FromMilliseconds(100)}, + {2, base::TimeDelta::FromMilliseconds(200)}, + {3, base::TimeDelta::FromMilliseconds(300)}, + {4, base::TimeDelta::FromMilliseconds(400)}, + {5, base::TimeDelta::FromMilliseconds(500)}, + {6, base::TimeDelta::FromMilliseconds(600)}, + {7, base::TimeDelta::FromMilliseconds(700)}, + {8, base::TimeDelta::FromMilliseconds(800)}, + {9, base::TimeDelta::FromMilliseconds(900)}, + {10, base::TimeDelta::FromMilliseconds(1000)}}; + + for (const auto& sample : cached_requests_count_peak_delay_sample) { + analyzer.count_inflight_requests_for_peak_queueing_delay_ = sample.first; + analyzer.peak_queueing_delay_ = sample.second; + analyzer.UpdateRequestsCountAndPeakQueueingDelayMapping(); + } + + // Checks that the scores are correctly computed. + std::vector<std::pair<size_t, base::TimeDelta>> mapping_sample = { + std::make_pair(1, base::TimeDelta::FromMilliseconds(100)), + std::make_pair(2, base::TimeDelta::FromMilliseconds(200)), + std::make_pair(3, base::TimeDelta::FromMilliseconds(400)), + std::make_pair(4, base::TimeDelta::FromMilliseconds(800)), + std::make_pair(5, base::TimeDelta::FromMilliseconds(400)), + std::make_pair(6, base::TimeDelta::FromMilliseconds(200)), + std::make_pair(7, base::TimeDelta::FromMilliseconds(200)), + std::make_pair(8, base::TimeDelta::FromMilliseconds(200)), + std::make_pair(9, base::TimeDelta::FromMilliseconds(200)), + std::make_pair(10, base::TimeDelta::FromMilliseconds(900)), + std::make_pair(11, base::TimeDelta::FromMilliseconds(500))}; + std::vector<size_t> ground_truth_mapping_score = {100, 100, 90, 60, 90, 60, + 50, 40, 30, 90, 40}; + + EXPECT_EQ(mapping_sample.size(), ground_truth_mapping_score.size()); + EXPECT_EQ(10u, analyzer.count_peak_queueing_delay_mapping_sample_); + + for (size_t i = 0; i < mapping_sample.size(); ++i) { + EXPECT_EQ(analyzer.ComputePeakDelayMappingSampleScore( + mapping_sample[i].first, mapping_sample[i].second), + ground_truth_mapping_score[i]); + } + + // Checks that only samples with a score higher than a threshold would be + // inserted into the cache. + size_t inserted_samples_count = 0; + size_t samples_count_before = 0; + bool is_inserted = false; + for (const auto& sample : mapping_sample) { + samples_count_before = + analyzer.count_inflight_requests_to_queueing_delay_[sample.first] + .size(); + is_inserted = + analyzer.ComputePeakDelayMappingSampleScore(sample.first, sample.second) + .value_or(0) >= kMinScoreForValidSamples; + // Inserts the new sample. + analyzer.count_inflight_requests_for_peak_queueing_delay_ = sample.first; + analyzer.peak_queueing_delay_ = sample.second; + analyzer.UpdateRequestsCountAndPeakQueueingDelayMapping(); + if (is_inserted) { + ++inserted_samples_count; + EXPECT_EQ( + samples_count_before + 1, + analyzer.count_inflight_requests_to_queueing_delay_[sample.first] + .size()); + } else { + EXPECT_EQ( + samples_count_before, + analyzer.count_inflight_requests_to_queueing_delay_[sample.first] + .size()); + } + } + + EXPECT_EQ(10u + inserted_samples_count, + analyzer.count_peak_queueing_delay_mapping_sample_); +} + } // namespace internal } // namespace nqe
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc index cde4971..7e6788e 100644 --- a/net/nqe/network_quality_estimator.cc +++ b/net/nqe/network_quality_estimator.cc
@@ -179,6 +179,7 @@ DCHECK_EQ(nqe::internal::OBSERVATION_CATEGORY_COUNT, base::size(rtt_ms_observations_)); + AddEffectiveConnectionTypeObserver(&network_congestion_analyzer_); network_quality_store_.reset(new nqe::internal::NetworkQualityStore()); NetworkChangeNotifier::AddConnectionTypeObserver(this); throughput_analyzer_.reset(new nqe::internal::ThroughputAnalyzer( @@ -253,9 +254,9 @@ NetworkQualityEstimator::~NetworkQualityEstimator() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); NetworkChangeNotifier::RemoveConnectionTypeObserver(this); + RemoveEffectiveConnectionTypeObserver(&network_congestion_analyzer_); } - void NetworkQualityEstimator::NotifyStartTransaction( const URLRequest& request) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/net/proxy_resolution/proxy_config_service_linux_unittest.cc b/net/proxy_resolution/proxy_config_service_linux_unittest.cc index 8fdbcfcc7..bd63225 100644 --- a/net/proxy_resolution/proxy_config_service_linux_unittest.cc +++ b/net/proxy_resolution/proxy_config_service_linux_unittest.cc
@@ -15,7 +15,7 @@ #include "base/format_macros.h" #include "base/location.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" @@ -287,7 +287,7 @@ base::WaitableEvent::InitialState::NOT_SIGNALED) { // Start the main IO thread. base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; main_thread_.StartWithOptions(options); // Make sure the thread started.
diff --git a/net/quic/quic_chromium_client_session.cc b/net/quic/quic_chromium_client_session.cc index b85a00a..f300786a 100644 --- a/net/quic/quic_chromium_client_session.cc +++ b/net/quic/quic_chromium_client_session.cc
@@ -939,7 +939,7 @@ quic::QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin, - spdy::SpdyPriority priority, + const spdy::SpdyStreamPrecedence& precedence, quic::QuicReferenceCountedPointer<quic::QuicAckListenerInterface> ack_listener) { spdy::SpdyStreamId parent_stream_id = 0; @@ -947,10 +947,11 @@ bool exclusive = false; if (headers_include_h2_stream_dependency_) { - priority_dependency_state_.OnStreamCreation(id, priority, &parent_stream_id, - &weight, &exclusive); + priority_dependency_state_.OnStreamCreation(id, precedence.spdy3_priority(), + &parent_stream_id, &weight, + &exclusive); } else { - weight = spdy::Spdy3PriorityToHttp2Weight(priority); + weight = spdy::Spdy3PriorityToHttp2Weight(precedence.spdy3_priority()); } return WriteHeadersOnHeadersStreamImpl(id, std::move(headers), fin, @@ -968,10 +969,11 @@ void QuicChromiumClientSession::UpdateStreamPriority( quic::QuicStreamId id, - spdy::SpdyPriority new_priority) { + const spdy::SpdyStreamPrecedence& new_precedence) { if (headers_include_h2_stream_dependency_ || VersionHasStreamType(connection()->transport_version())) { - auto updates = priority_dependency_state_.OnStreamUpdate(id, new_priority); + auto updates = priority_dependency_state_.OnStreamUpdate( + id, new_precedence.spdy3_priority()); for (auto update : updates) { if (!VersionHasStreamType(connection()->transport_version())) { WritePriority(update.id, update.parent_stream_id, update.weight, @@ -988,7 +990,7 @@ } } } - quic::QuicSpdySession::UpdateStreamPriority(id, new_priority); + quic::QuicSpdySession::UpdateStreamPriority(id, new_precedence); } void QuicChromiumClientSession::OnStreamFrame(
diff --git a/net/quic/quic_chromium_client_session.h b/net/quic/quic_chromium_client_session.h index c8ca8a1..6eee78fc 100644 --- a/net/quic/quic_chromium_client_session.h +++ b/net/quic/quic_chromium_client_session.h
@@ -465,12 +465,13 @@ quic::QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin, - spdy::SpdyPriority priority, + const spdy::SpdyStreamPrecedence& precedence, quic::QuicReferenceCountedPointer<quic::QuicAckListenerInterface> ack_listener) override; void UnregisterStreamPriority(quic::QuicStreamId id, bool is_static) override; - void UpdateStreamPriority(quic::QuicStreamId id, - spdy::SpdyPriority new_priority) override; + void UpdateStreamPriority( + quic::QuicStreamId id, + const spdy::SpdyStreamPrecedence& new_precedence) override; // quic::QuicSession methods: void OnStreamFrame(const quic::QuicStreamFrame& frame) override; @@ -841,7 +842,7 @@ bool ignore_read_error_; // If true, client headers will include HTTP/2 stream dependency info derived - // from spdy::SpdyPriority. + // from spdy::SpdyStreamPrecedence. bool headers_include_h2_stream_dependency_; Http2PriorityDependencies priority_dependency_state_;
diff --git a/net/quic/quic_chromium_client_stream.cc b/net/quic/quic_chromium_client_stream.cc index 1a29107b..97b6b66 100644 --- a/net/quic/quic_chromium_client_stream.cc +++ b/net/quic/quic_chromium_client_stream.cc
@@ -257,9 +257,9 @@ } void QuicChromiumClientStream::Handle::SetPriority( - spdy::SpdyPriority priority) { + const spdy::SpdyStreamPrecedence& precedence) { if (stream_) - stream_->SetPriority(priority); + stream_->SetPriority(precedence); } void QuicChromiumClientStream::Handle::Reset( @@ -542,8 +542,8 @@ net_log_.AddEvent( NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS, [&](NetLogCaptureMode capture_mode) { - return QuicRequestNetLogParams(id(), &header_block, priority(), - capture_mode); + return QuicRequestNetLogParams( + id(), &header_block, precedence().spdy3_priority(), capture_mode); }); size_t len = quic::QuicSpdyStream::WriteHeaders(std::move(header_block), fin, std::move(ack_listener));
diff --git a/net/quic/quic_chromium_client_stream.h b/net/quic/quic_chromium_client_stream.h index 30baf2a5..5e9c8841 100644 --- a/net/quic/quic_chromium_client_stream.h +++ b/net/quic/quic_chromium_client_stream.h
@@ -107,8 +107,8 @@ // stream is open. void DisableConnectionMigrationToCellularNetwork(); - // Sets the priority of the stream to |priority|. - void SetPriority(spdy::SpdyPriority priority); + // Sets the precedence of the stream to |precedence|. + void SetPriority(const spdy::SpdyStreamPrecedence& precedence); // Sends a RST_STREAM frame to the peer and closes the streams. void Reset(quic::QuicRstStreamErrorCode error_code);
diff --git a/net/quic/quic_chromium_client_stream_test.cc b/net/quic/quic_chromium_client_stream_test.cc index f696e42..f654267d 100644 --- a/net/quic/quic_chromium_client_stream_test.cc +++ b/net/quic/quic_chromium_client_stream_test.cc
@@ -79,7 +79,8 @@ void(quic::QuicStreamId stream_id, quic::QuicStringPiece headers_data)); MOCK_METHOD2(OnStreamHeadersPriority, - void(quic::QuicStreamId stream_id, spdy::SpdyPriority priority)); + void(quic::QuicStreamId stream_id, + const spdy::SpdyStreamPrecedence& precedence)); MOCK_METHOD3(OnStreamHeadersComplete, void(quic::QuicStreamId stream_id, bool fin, size_t frame_len)); MOCK_METHOD2(OnPromiseHeaders, @@ -96,17 +97,17 @@ quic::QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin, - spdy::SpdyPriority priority, + const spdy::SpdyStreamPrecedence& precedence, quic::QuicReferenceCountedPointer<quic::QuicAckListenerInterface> ack_listener) override { - return WriteHeadersOnHeadersStreamMock(id, headers, fin, priority, + return WriteHeadersOnHeadersStreamMock(id, headers, fin, precedence, std::move(ack_listener)); } MOCK_METHOD5(WriteHeadersOnHeadersStreamMock, size_t(quic::QuicStreamId id, const spdy::SpdyHeaderBlock& headers, bool fin, - spdy::SpdyPriority priority, + const spdy::SpdyStreamPrecedence& precedence, const quic::QuicReferenceCountedPointer< quic::QuicAckListenerInterface>& ack_listener)); MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(quic::QuicTime::Delta delta));
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h index 16590ee..161337d 100644 --- a/net/quic/quic_flags_list.h +++ b/net/quic/quic_flags_list.h
@@ -339,4 +339,4 @@ QUIC_FLAG( bool, FLAGS_quic_restart_flag_quic_dispatcher_hands_chlo_extractor_one_version, - true) + false)
diff --git a/net/quic/quic_http_stream.cc b/net/quic/quic_http_stream.cc index fe7c0a8..f524f69c 100644 --- a/net/quic/quic_http_stream.cc +++ b/net/quic/quic_http_stream.cc
@@ -182,7 +182,8 @@ spdy::SpdyPriority spdy_priority = ConvertRequestPriorityToQuicPriority(priority_); - stream_->SetPriority(spdy_priority); + const spdy::SpdyStreamPrecedence precedence(spdy_priority); + stream_->SetPriority(precedence); next_state_ = STATE_OPEN; NetLogQuicPushStream(stream_net_log_, quic_session()->net_log(), @@ -572,7 +573,8 @@ DCHECK(response_info_); spdy::SpdyPriority priority = ConvertRequestPriorityToQuicPriority(priority_); - stream_->SetPriority(priority); + spdy::SpdyStreamPrecedence precedence(priority); + stream_->SetPriority(precedence); next_state_ = STATE_SEND_HEADERS; return OK; }
diff --git a/net/quic/quic_http_utils.h b/net/quic/quic_http_utils.h index f495bdb..9645a866 100644 --- a/net/quic/quic_http_utils.h +++ b/net/quic/quic_http_utils.h
@@ -15,6 +15,8 @@ namespace net { +// TODO(crbug/988608): Convert to SpdyStreamPrecedence directly instead of to +// SpdyPriority which will go away eventually. NET_EXPORT_PRIVATE spdy::SpdyPriority ConvertRequestPriorityToQuicPriority( RequestPriority priority);
diff --git a/net/reporting/mock_persistent_reporting_store.cc b/net/reporting/mock_persistent_reporting_store.cc index b56c80f..85cb40d0 100644 --- a/net/reporting/mock_persistent_reporting_store.cc +++ b/net/reporting/mock_persistent_reporting_store.cc
@@ -5,29 +5,80 @@ #include "net/reporting/mock_persistent_reporting_store.h" #include <algorithm> +#include <memory> namespace net { MockPersistentReportingStore::Command::Command( Type type, ReportingClientsLoadedCallback loaded_callback) - : type(type), loaded_callback(std::move(loaded_callback)) {} + : type(type), loaded_callback(std::move(loaded_callback)) { + DCHECK(type == Type::LOAD_REPORTING_CLIENTS); +} MockPersistentReportingStore::Command::Command( Type type, const ReportingEndpoint& endpoint) - : type(type), group_key(endpoint.group_key), url(endpoint.info.url) {} + : type(type), group_key(endpoint.group_key), url(endpoint.info.url) { + DCHECK(type == Type::ADD_REPORTING_ENDPOINT || + type == Type::UPDATE_REPORTING_ENDPOINT_DETAILS || + type == Type::DELETE_REPORTING_ENDPOINT); +} + +MockPersistentReportingStore::Command::Command(Type type, + const GURL& origin, + const std::string& group, + const GURL& endpoint) + : MockPersistentReportingStore::Command(type, + url::Origin::Create(origin), + group, + endpoint) {} + +MockPersistentReportingStore::Command::Command(Type type, + const url::Origin& origin, + const std::string& group, + const GURL& endpoint) + : MockPersistentReportingStore::Command( + type, + ReportingEndpoint(origin, + group, + ReportingEndpoint::EndpointInfo{endpoint})) {} MockPersistentReportingStore::Command::Command( Type type, const CachedReportingEndpointGroup& group) - : type(type), group_key(group.group_key) {} + : type(type), group_key(group.group_key) { + DCHECK(type == Type::ADD_REPORTING_ENDPOINT_GROUP || + type == Type::UPDATE_REPORTING_ENDPOINT_GROUP_DETAILS || + type == Type::UPDATE_REPORTING_ENDPOINT_GROUP_ACCESS_TIME || + type == Type::DELETE_REPORTING_ENDPOINT_GROUP); +} -MockPersistentReportingStore::Command::Command(Type type) : type(type) {} +MockPersistentReportingStore::Command::Command(Type type) : type(type) { + DCHECK(type == Type::FLUSH || type == Type::LOAD_REPORTING_CLIENTS); +} MockPersistentReportingStore::Command::Command(const Command& other) : type(other.type), group_key(other.group_key), url(other.url) {} +MockPersistentReportingStore::Command::Command(Type type, + const GURL& origin, + const std::string& group) + : MockPersistentReportingStore::Command(type, + url::Origin::Create(origin), + group) {} + +MockPersistentReportingStore::Command::Command(Type type, + const url::Origin& origin, + const std::string& group) + : MockPersistentReportingStore::Command( + type, + CachedReportingEndpointGroup(origin, + group, + OriginSubdomains::DEFAULT /* unused */, + base::Time() /* unused */, + base::Time() /* unused */)) {} + MockPersistentReportingStore::Command::Command(Command&& other) = default; MockPersistentReportingStore::Command::~Command() = default; @@ -68,6 +119,52 @@ return !(lhs == rhs); } +std::ostream& operator<<(std::ostream& out, + const MockPersistentReportingStore::Command& cmd) { + switch (cmd.type) { + case MockPersistentReportingStore::Command::Type::LOAD_REPORTING_CLIENTS: + return out << "LOAD_REPORTING_CLIENTS()"; + case MockPersistentReportingStore::Command::Type::FLUSH: + return out << "FLUSH()"; + case MockPersistentReportingStore::Command::Type::ADD_REPORTING_ENDPOINT: + return out << "ADD_REPORTING_ENDPOINT(" + << "origin=" << cmd.group_key.origin << ", " + << "group=" << cmd.group_key.group_name << ", " + << "endpoint=" << cmd.url << ")"; + case MockPersistentReportingStore::Command::Type:: + UPDATE_REPORTING_ENDPOINT_DETAILS: + return out << "UPDATE_REPORTING_ENDPOINT_DETAILS(" + << "origin=" << cmd.group_key.origin << ", " + << "group=" << cmd.group_key.group_name << ", " + << "endpoint=" << cmd.url << ")"; + case MockPersistentReportingStore::Command::Type::DELETE_REPORTING_ENDPOINT: + return out << "DELETE_REPORTING_ENDPOINT(" + << "origin=" << cmd.group_key.origin << ", " + << "group=" << cmd.group_key.group_name << ", " + << "endpoint=" << cmd.url << ")"; + case MockPersistentReportingStore::Command::Type:: + ADD_REPORTING_ENDPOINT_GROUP: + return out << "ADD_REPORTING_ENDPOINT_GROUP(" + << "origin=" << cmd.group_key.origin << ", " + << "group=" << cmd.group_key.group_name << ")"; + case MockPersistentReportingStore::Command::Type:: + UPDATE_REPORTING_ENDPOINT_GROUP_ACCESS_TIME: + return out << "UPDATE_REPORTING_ENDPOINT_GROUP_ACCESS_TIME(" + << "origin=" << cmd.group_key.origin << ", " + << "group=" << cmd.group_key.group_name << ")"; + case MockPersistentReportingStore::Command::Type:: + UPDATE_REPORTING_ENDPOINT_GROUP_DETAILS: + return out << "UPDATE_REPORTING_ENDPOINT_GROUP_DETAILS(" + << "origin=" << cmd.group_key.origin << ", " + << "group=" << cmd.group_key.group_name << ")"; + case MockPersistentReportingStore::Command::Type:: + DELETE_REPORTING_ENDPOINT_GROUP: + return out << "DELETE_REPORTING_ENDPOINT_GROUP(" + << "origin=" << cmd.group_key.origin << ", " + << "group=" << cmd.group_key.group_name << ")"; + } +} + MockPersistentReportingStore::MockPersistentReportingStore() : load_started_(false), endpoint_count_(0),
diff --git a/net/reporting/mock_persistent_reporting_store.h b/net/reporting/mock_persistent_reporting_store.h index cbfe4376..92bbc90e 100644 --- a/net/reporting/mock_persistent_reporting_store.h +++ b/net/reporting/mock_persistent_reporting_store.h
@@ -40,11 +40,27 @@ // Constructor for LOAD_REPORTING_CLIENTS commands. Command(Type type, ReportingClientsLoadedCallback loaded_callback); - // Constructor for endpoint commands. + // Constructors for endpoint commands. |type| must be one of + // ADD_REPORTING_ENDPOINT, UPDATE_REPORTING_ENDPOINT_DETAILS, or + // DELETE_REPORTING_ENDPOINT Command(Type type, const ReportingEndpoint& endpoint); - // Constructor for endpoint group commands. + Command(Type type, + const GURL& origin, + const std::string& group, + const GURL& endpoint); + Command(Type type, + const url::Origin& origin, + const std::string& group, + const GURL& endpoint); + // Constructors for endpoint group commands. |type| must be one of + // ADD_REPORTING_ENDPOINT_GROUP, + // UPDATE_REPORTING_ENDPOINT_GROUP_ACCESS_TIME, + // UPDATE_REPORTING_ENDPOINT_GROUP_DETAILS, or + // DELETE_REPORTING_ENDPOINT_GROUP Command(Type type, const CachedReportingEndpointGroup& group); - // Constructor for FLUSH commands. + Command(Type type, const GURL& origin, const std::string& group); + Command(Type type, const url::Origin& origin, const std::string& group); + // |type| must be LOAD_REPORTING_CLIENTS or FLUSH. Command(Type type); Command(const Command& other); @@ -147,6 +163,8 @@ const MockPersistentReportingStore::Command& rhs); bool operator!=(const MockPersistentReportingStore::Command& lhs, const MockPersistentReportingStore::Command& rhs); +std::ostream& operator<<(std::ostream& out, + const MockPersistentReportingStore::Command& cmd); } // namespace net
diff --git a/net/reporting/reporting_browsing_data_remover.cc b/net/reporting/reporting_browsing_data_remover.cc index 0194732..004e527f 100644 --- a/net/reporting/reporting_browsing_data_remover.cc +++ b/net/reporting/reporting_browsing_data_remover.cc
@@ -38,6 +38,7 @@ cache->RemoveClient(origin); } } + cache->Flush(); } // static @@ -50,6 +51,7 @@ if ((data_type_mask & DATA_TYPE_CLIENTS) != 0) { cache->RemoveAllClients(); } + cache->Flush(); } } // namespace net
diff --git a/net/reporting/reporting_cache.h b/net/reporting/reporting_cache.h index a9f6ad7..1eb28b9 100644 --- a/net/reporting/reporting_cache.h +++ b/net/reporting/reporting_cache.h
@@ -199,6 +199,9 @@ // Gets the total number of endpoints in the cache across all origins. virtual size_t GetEndpointCount() const = 0; + // Flush the contents of the cache to disk, if applicable. + virtual void Flush() = 0; + // Finds an endpoint for the given |origin|, |group_name|, and |url|, // otherwise returns an invalid ReportingEndpoint. virtual ReportingEndpoint GetEndpointForTesting(const url::Origin& origin,
diff --git a/net/reporting/reporting_cache_impl.cc b/net/reporting/reporting_cache_impl.cc index 52cf80e..8c6df6f 100644 --- a/net/reporting/reporting_cache_impl.cc +++ b/net/reporting/reporting_cache_impl.cc
@@ -554,6 +554,11 @@ return endpoints_.size(); } +void ReportingCacheImpl::Flush() { + if (context_->IsClientDataPersisted()) + store()->Flush(); +} + ReportingEndpoint ReportingCacheImpl::GetEndpointForTesting( const url::Origin& origin, const std::string& group_name,
diff --git a/net/reporting/reporting_cache_impl.h b/net/reporting/reporting_cache_impl.h index bccd0b1..ac8ca7b 100644 --- a/net/reporting/reporting_cache_impl.h +++ b/net/reporting/reporting_cache_impl.h
@@ -84,6 +84,7 @@ const std::string& group_name) override; base::Value GetClientsAsValue() const override; size_t GetEndpointCount() const override; + void Flush() override; ReportingEndpoint GetEndpointForTesting(const url::Origin& origin, const std::string& group_name, const GURL& url) const override;
diff --git a/net/reporting/reporting_context.cc b/net/reporting/reporting_context.cc index 1c38d6f..b74f32d 100644 --- a/net/reporting/reporting_context.cc +++ b/net/reporting/reporting_context.cc
@@ -87,8 +87,6 @@ void ReportingContext::OnShutdown() { uploader_->OnShutdown(); - if (store_) - store_->Flush(); } ReportingContext::ReportingContext(
diff --git a/net/reporting/reporting_service.cc b/net/reporting/reporting_service.cc index 313a825..197642cab 100644 --- a/net/reporting/reporting_service.cc +++ b/net/reporting/reporting_service.cc
@@ -28,14 +28,28 @@ constexpr int kMaxJsonSize = 16 * 1024; constexpr int kMaxJsonDepth = 5; +// If constructed with a PersistentReportingStore, the first call to any of +// QueueReport(), ProcessHeader(), RemoveBrowsingData(), or +// RemoveAllBrowsingData() on a valid input will trigger a load from the store. +// Tasks are queued pending completion of loading from the store. class ReportingServiceImpl : public ReportingService { public: ReportingServiceImpl(std::unique_ptr<ReportingContext> context) - : context_(std::move(context)), shut_down_(false) {} + : context_(std::move(context)), + shut_down_(false), + started_loading_from_store_(false), + initialized_(false), + weak_factory_(this) { + if (!context_->IsClientDataPersisted()) + initialized_ = true; + } // ReportingService implementation: - ~ReportingServiceImpl() override = default; + ~ReportingServiceImpl() override { + if (initialized_) + context_->cache()->Flush(); + } void QueueReport(const GURL& url, const std::string& user_agent, @@ -43,9 +57,6 @@ const std::string& type, std::unique_ptr<const base::Value> body, int depth) override { - if (shut_down_) - return; - DCHECK(context_); DCHECK(context_->delegate()); @@ -57,16 +68,18 @@ if (!sanitized_url.is_valid()) return; - context_->cache()->AddReport(sanitized_url, user_agent, group, type, - std::move(body), depth, - context_->tick_clock().NowTicks(), 0); + base::TimeTicks queued_ticks = context_->tick_clock().NowTicks(); + + // base::Unretained is safe because the callback is stored in + // |task_backlog_| which will not outlive |this|. + DoOrBacklogTask(base::BindOnce(&ReportingServiceImpl::DoQueueReport, + base::Unretained(this), + std::move(sanitized_url), user_agent, group, + type, std::move(body), depth, queued_ticks)); } void ProcessHeader(const GURL& url, const std::string& header_string) override { - if (shut_down_) - return; - if (header_string.size() > kMaxJsonSize) { ReportingHeaderParser::RecordHeaderDiscardedForJsonTooBig(); return; @@ -81,20 +94,23 @@ } DVLOG(1) << "Received Reporting policy for " << url.GetOrigin(); - ReportingHeaderParser::ParseHeader(context_.get(), url, - std::move(header_value)); + DoOrBacklogTask(base::BindOnce(&ReportingServiceImpl::DoProcessHeader, + base::Unretained(this), url, + std::move(header_value))); } void RemoveBrowsingData(int data_type_mask, const base::RepeatingCallback<bool(const GURL&)>& origin_filter) override { - ReportingBrowsingDataRemover::RemoveBrowsingData( - context_->cache(), data_type_mask, origin_filter); + DoOrBacklogTask(base::BindOnce(&ReportingServiceImpl::DoRemoveBrowsingData, + base::Unretained(this), data_type_mask, + origin_filter)); } void RemoveAllBrowsingData(int data_type_mask) override { - ReportingBrowsingDataRemover::RemoveAllBrowsingData(context_->cache(), - data_type_mask); + DoOrBacklogTask( + base::BindOnce(&ReportingServiceImpl::DoRemoveAllBrowsingData, + base::Unretained(this), data_type_mask)); } void OnShutdown() override { @@ -119,8 +135,98 @@ } private: + void DoOrBacklogTask(base::OnceClosure task) { + if (shut_down_) + return; + + FetchAllClientsFromStoreIfNecessary(); + + if (!initialized_) { + task_backlog_.push_back(std::move(task)); + return; + } + + std::move(task).Run(); + } + + void DoQueueReport(GURL sanitized_url, + const std::string& user_agent, + const std::string& group, + const std::string& type, + std::unique_ptr<const base::Value> body, + int depth, + base::TimeTicks queued_ticks) { + DCHECK(initialized_); + context_->cache()->AddReport(sanitized_url, user_agent, group, type, + std::move(body), depth, queued_ticks, + 0 /* attempts */); + } + + void DoProcessHeader(const GURL& url, + std::unique_ptr<base::Value> header_value) { + DCHECK(initialized_); + ReportingHeaderParser::ParseHeader(context_.get(), url, + std::move(header_value)); + } + + void DoRemoveBrowsingData( + int data_type_mask, + const base::RepeatingCallback<bool(const GURL&)>& origin_filter) { + DCHECK(initialized_); + ReportingBrowsingDataRemover::RemoveBrowsingData( + context_->cache(), data_type_mask, origin_filter); + } + + void DoRemoveAllBrowsingData(int data_type_mask) { + DCHECK(initialized_); + ReportingBrowsingDataRemover::RemoveAllBrowsingData(context_->cache(), + data_type_mask); + } + + void ExecuteBacklog() { + DCHECK(initialized_); + DCHECK(context_); + + if (shut_down_) + return; + + for (base::OnceClosure& task : task_backlog_) { + std::move(task).Run(); + } + task_backlog_.clear(); + } + + void FetchAllClientsFromStoreIfNecessary() { + if (!context_->IsClientDataPersisted() || started_loading_from_store_) + return; + + started_loading_from_store_ = true; + FetchAllClientsFromStore(); + } + + void FetchAllClientsFromStore() { + DCHECK(context_->IsClientDataPersisted()); + DCHECK(!initialized_); + + context_->store()->LoadReportingClients(base::BindOnce( + &ReportingServiceImpl::OnClientsLoaded, weak_factory_.GetWeakPtr())); + } + + void OnClientsLoaded( + std::vector<ReportingEndpoint> loaded_endpoints, + std::vector<CachedReportingEndpointGroup> loaded_endpoint_groups) { + initialized_ = true; + context_->cache()->AddClientsLoadedFromStore( + std::move(loaded_endpoints), std::move(loaded_endpoint_groups)); + ExecuteBacklog(); + } + std::unique_ptr<ReportingContext> context_; bool shut_down_; + bool started_loading_from_store_; + bool initialized_; + std::vector<base::OnceClosure> task_backlog_; + base::WeakPtrFactory<ReportingServiceImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ReportingServiceImpl); };
diff --git a/net/reporting/reporting_service_unittest.cc b/net/reporting/reporting_service_unittest.cc index 96feab9..6277f9a 100644 --- a/net/reporting/reporting_service_unittest.cc +++ b/net/reporting/reporting_service_unittest.cc
@@ -7,9 +7,12 @@ #include <memory> #include <string> +#include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/time/tick_clock.h" #include "base/values.h" +#include "net/reporting/mock_persistent_reporting_store.h" +#include "net/reporting/reporting_browsing_data_remover.h" #include "net/reporting/reporting_cache.h" #include "net/reporting/reporting_context.h" #include "net/reporting/reporting_policy.h" @@ -17,26 +20,49 @@ #include "net/reporting/reporting_service.h" #include "net/reporting/reporting_test_util.h" #include "net/test/test_with_scoped_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { namespace { -class ReportingServiceTest : public TestWithScopedTaskEnvironment { +using CommandType = MockPersistentReportingStore::Command::Type; + +// The tests are parametrized on a boolean value which represents whether to use +// a MockPersistentReportingStore (if false, no store is used). +class ReportingServiceTest : public ::testing::TestWithParam<bool>, + public WithScopedTaskEnvironment { protected: const GURL kUrl_ = GURL("https://origin/path"); + const GURL kUrl2_ = GURL("https://origin2/path"); const url::Origin kOrigin_ = url::Origin::Create(kUrl_); + const url::Origin kOrigin2_ = url::Origin::Create(kUrl2_); const GURL kEndpoint_ = GURL("https://endpoint/"); const std::string kUserAgent_ = "Mozilla/1.0"; const std::string kGroup_ = "group"; const std::string kType_ = "type"; - ReportingServiceTest() - : context_( - new TestReportingContext(&clock_, &tick_clock_, ReportingPolicy())), - service_( - ReportingService::CreateForTesting(base::WrapUnique(context_))) {} + ReportingServiceTest() { + if (GetParam()) + store_ = std::make_unique<MockPersistentReportingStore>(); + else + store_ = nullptr; + auto test_context = std::make_unique<TestReportingContext>( + &clock_, &tick_clock_, ReportingPolicy(), store_.get()); + context_ = test_context.get(); + + service_ = ReportingService::CreateForTesting(std::move(test_context)); + } + + // If the store exists, simulate finishing loading the store, which should + // make the rest of the test run synchronously. + void FinishLoading(bool load_success) { + if (store_) + store_->FinishLoading(load_success); + } + + MockPersistentReportingStore* store() { return store_.get(); } TestReportingContext* context() { return context_; } ReportingService* service() { return service_.get(); } @@ -44,13 +70,15 @@ base::SimpleTestClock clock_; base::SimpleTestTickClock tick_clock_; + std::unique_ptr<MockPersistentReportingStore> store_; TestReportingContext* context_; std::unique_ptr<ReportingService> service_; }; -TEST_F(ReportingServiceTest, QueueReport) { +TEST_P(ReportingServiceTest, QueueReport) { service()->QueueReport(kUrl_, kUserAgent_, kGroup_, kType_, std::make_unique<base::DictionaryValue>(), 0); + FinishLoading(true /* load_success */); std::vector<const ReportingReport*> reports; context()->cache()->GetReports(&reports); @@ -61,11 +89,12 @@ EXPECT_EQ(kType_, reports[0]->type); } -TEST_F(ReportingServiceTest, QueueReportSanitizeUrl) { +TEST_P(ReportingServiceTest, QueueReportSanitizeUrl) { // Same as kUrl_ but with username, password, and fragment. GURL url = GURL("https://username:password@origin/path#fragment"); service()->QueueReport(url, kUserAgent_, kGroup_, kType_, std::make_unique<base::DictionaryValue>(), 0); + FinishLoading(true /* load_success */); std::vector<const ReportingReport*> reports; context()->cache()->GetReports(&reports); @@ -76,8 +105,10 @@ EXPECT_EQ(kType_, reports[0]->type); } -TEST_F(ReportingServiceTest, DontQueueReportInvalidUrl) { +TEST_P(ReportingServiceTest, DontQueueReportInvalidUrl) { GURL url = GURL("https://"); + // This does not trigger an attempt to load from the store because the url + // is immediately rejected as invalid. service()->QueueReport(url, kUserAgent_, kGroup_, kType_, std::make_unique<base::DictionaryValue>(), 0); @@ -86,7 +117,7 @@ ASSERT_EQ(0u, reports.size()); } -TEST_F(ReportingServiceTest, ProcessHeader) { +TEST_P(ReportingServiceTest, ProcessHeader) { service()->ProcessHeader(kUrl_, "{\"endpoints\":[{\"url\":\"" + kEndpoint_.spec() + "\"}]," @@ -94,11 +125,12 @@ kGroup_ + "\"," "\"max_age\":86400}"); + FinishLoading(true /* load_success */); EXPECT_EQ(1u, context()->cache()->GetEndpointCount()); } -TEST_F(ReportingServiceTest, ProcessHeader_TooLong) { +TEST_P(ReportingServiceTest, ProcessHeader_TooLong) { const std::string header_too_long = "{\"endpoints\":[{\"url\":\"" + kEndpoint_.spec() + "\"}]," @@ -107,12 +139,14 @@ "\"," "\"max_age\":86400," + "\"junk\":\"" + std::string(32 * 1024, 'a') + "\"}"; + // This does not trigger an attempt to load from the store because the header + // is immediately rejected as invalid. service()->ProcessHeader(kUrl_, header_too_long); EXPECT_EQ(0u, context()->cache()->GetEndpointCount()); } -TEST_F(ReportingServiceTest, ProcessHeader_TooDeep) { +TEST_P(ReportingServiceTest, ProcessHeader_TooDeep) { const std::string header_too_deep = "{\"endpoints\":[{\"url\":\"" + kEndpoint_.spec() + "\"}]," @@ -121,10 +155,207 @@ "\"," "\"max_age\":86400," + "\"junk\":[[[[[[[[[[]]]]]]]]]]}"; + // This does not trigger an attempt to load from the store because the header + // is immediately rejected as invalid. service()->ProcessHeader(kUrl_, header_too_deep); EXPECT_EQ(0u, context()->cache()->GetEndpointCount()); } +TEST_P(ReportingServiceTest, WriteToStore) { + if (!store()) + return; + + MockPersistentReportingStore::CommandList expected_commands; + + // This first call to any public method triggers a load. The load will block + // until we call FinishLoading. + service()->ProcessHeader(kUrl_, "{\"endpoints\":[{\"url\":\"" + + kEndpoint_.spec() + + "\"}]," + "\"group\":\"" + + kGroup_ + + "\"," + "\"max_age\":86400}"); + expected_commands.emplace_back(CommandType::LOAD_REPORTING_CLIENTS); + EXPECT_THAT(store()->GetAllCommands(), + testing::UnorderedElementsAreArray(expected_commands)); + + // Unblock the load. The will let the remaining calls to the service complete + // without blocking. + FinishLoading(true /* load_success */); + expected_commands.emplace_back( + CommandType::ADD_REPORTING_ENDPOINT, + ReportingEndpoint(kOrigin_, kGroup_, + ReportingEndpoint::EndpointInfo{kEndpoint_})); + expected_commands.emplace_back( + CommandType::ADD_REPORTING_ENDPOINT_GROUP, + CachedReportingEndpointGroup( + kOrigin_, kGroup_, OriginSubdomains::DEFAULT /* irrelevant */, + base::Time() /* irrelevant */, base::Time() /* irrelevant */)); + EXPECT_THAT(store()->GetAllCommands(), + testing::UnorderedElementsAreArray(expected_commands)); + + service()->ProcessHeader(kUrl2_, "{\"endpoints\":[{\"url\":\"" + + kEndpoint_.spec() + + "\"}]," + "\"group\":\"" + + kGroup_ + + "\"," + "\"max_age\":86400}"); + expected_commands.emplace_back( + CommandType::ADD_REPORTING_ENDPOINT, + ReportingEndpoint(kOrigin2_, kGroup_, + ReportingEndpoint::EndpointInfo{kEndpoint_})); + expected_commands.emplace_back( + CommandType::ADD_REPORTING_ENDPOINT_GROUP, + CachedReportingEndpointGroup( + kOrigin2_, kGroup_, OriginSubdomains::DEFAULT /* irrelevant */, + base::Time() /* irrelevant */, base::Time() /* irrelevant */)); + EXPECT_THAT(store()->GetAllCommands(), + testing::UnorderedElementsAreArray(expected_commands)); + + service()->QueueReport(kUrl_, kUserAgent_, kGroup_, kType_, + std::make_unique<base::DictionaryValue>(), 0); + expected_commands.emplace_back( + CommandType::UPDATE_REPORTING_ENDPOINT_GROUP_ACCESS_TIME, + CachedReportingEndpointGroup( + kOrigin_, kGroup_, OriginSubdomains::DEFAULT /* irrelevant */, + base::Time() /* irrelevant */, base::Time() /* irrelevant */)); + EXPECT_THAT(store()->GetAllCommands(), + testing::UnorderedElementsAreArray(expected_commands)); + + service()->RemoveBrowsingData(ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS, + base::BindRepeating([](const GURL& url) { + return url.host() == "origin"; + })); + expected_commands.emplace_back( + CommandType::DELETE_REPORTING_ENDPOINT, + ReportingEndpoint(kOrigin_, kGroup_, + ReportingEndpoint::EndpointInfo{kEndpoint_})); + expected_commands.emplace_back( + CommandType::DELETE_REPORTING_ENDPOINT_GROUP, + CachedReportingEndpointGroup( + kOrigin_, kGroup_, OriginSubdomains::DEFAULT /* irrelevant */, + base::Time() /* irrelevant */, base::Time() /* irrelevant */)); + expected_commands.emplace_back(CommandType::FLUSH); + EXPECT_THAT(store()->GetAllCommands(), + testing::UnorderedElementsAreArray(expected_commands)); + + service()->RemoveAllBrowsingData( + ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS); + expected_commands.emplace_back( + CommandType::DELETE_REPORTING_ENDPOINT, + ReportingEndpoint(kOrigin2_, kGroup_, + ReportingEndpoint::EndpointInfo{kEndpoint_})); + expected_commands.emplace_back( + CommandType::DELETE_REPORTING_ENDPOINT_GROUP, + CachedReportingEndpointGroup( + kOrigin2_, kGroup_, OriginSubdomains::DEFAULT /* irrelevant */, + base::Time() /* irrelevant */, base::Time() /* irrelevant */)); + expected_commands.emplace_back(CommandType::FLUSH); + EXPECT_THAT(store()->GetAllCommands(), + testing::UnorderedElementsAreArray(expected_commands)); +} + +TEST_P(ReportingServiceTest, WaitUntilLoadFinishesBeforeWritingToStore) { + if (!store()) + return; + + MockPersistentReportingStore::CommandList expected_commands; + + // This first call to any public method triggers a load. The load will block + // until we call FinishLoading. + service()->ProcessHeader(kUrl_, "{\"endpoints\":[{\"url\":\"" + + kEndpoint_.spec() + + "\"}]," + "\"group\":\"" + + kGroup_ + + "\"," + "\"max_age\":86400}"); + expected_commands.emplace_back(CommandType::LOAD_REPORTING_CLIENTS); + EXPECT_THAT(store()->GetAllCommands(), + testing::UnorderedElementsAreArray(expected_commands)); + + service()->ProcessHeader(kUrl2_, "{\"endpoints\":[{\"url\":\"" + + kEndpoint_.spec() + + "\"}]," + "\"group\":\"" + + kGroup_ + + "\"," + "\"max_age\":86400}"); + EXPECT_THAT(store()->GetAllCommands(), + testing::UnorderedElementsAreArray(expected_commands)); + + service()->QueueReport(kUrl_, kUserAgent_, kGroup_, kType_, + std::make_unique<base::DictionaryValue>(), 0); + EXPECT_THAT(store()->GetAllCommands(), + testing::UnorderedElementsAreArray(expected_commands)); + + service()->RemoveBrowsingData(ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS, + base::BindRepeating([](const GURL& url) { + return url.host() == "origin"; + })); + EXPECT_THAT(store()->GetAllCommands(), + testing::UnorderedElementsAreArray(expected_commands)); + + service()->RemoveAllBrowsingData( + ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS); + EXPECT_THAT(store()->GetAllCommands(), + testing::UnorderedElementsAreArray(expected_commands)); + + // Unblock the load. The will let the remaining calls to the service complete + // without blocking. + FinishLoading(true /* load_success */); + expected_commands.emplace_back( + CommandType::ADD_REPORTING_ENDPOINT, + ReportingEndpoint(kOrigin_, kGroup_, + ReportingEndpoint::EndpointInfo{kEndpoint_})); + expected_commands.emplace_back( + CommandType::ADD_REPORTING_ENDPOINT, + ReportingEndpoint(kOrigin2_, kGroup_, + ReportingEndpoint::EndpointInfo{kEndpoint_})); + expected_commands.emplace_back( + CommandType::ADD_REPORTING_ENDPOINT_GROUP, + CachedReportingEndpointGroup( + kOrigin_, kGroup_, OriginSubdomains::DEFAULT /* irrelevant */, + base::Time() /* irrelevant */, base::Time() /* irrelevant */)); + expected_commands.emplace_back( + CommandType::ADD_REPORTING_ENDPOINT_GROUP, + CachedReportingEndpointGroup( + kOrigin2_, kGroup_, OriginSubdomains::DEFAULT /* irrelevant */, + base::Time() /* irrelevant */, base::Time() /* irrelevant */)); + expected_commands.emplace_back( + CommandType::UPDATE_REPORTING_ENDPOINT_GROUP_ACCESS_TIME, + CachedReportingEndpointGroup( + kOrigin_, kGroup_, OriginSubdomains::DEFAULT /* irrelevant */, + base::Time() /* irrelevant */, base::Time() /* irrelevant */)); + expected_commands.emplace_back( + CommandType::DELETE_REPORTING_ENDPOINT, + ReportingEndpoint(kOrigin_, kGroup_, + ReportingEndpoint::EndpointInfo{kEndpoint_})); + expected_commands.emplace_back( + CommandType::DELETE_REPORTING_ENDPOINT_GROUP, + CachedReportingEndpointGroup( + kOrigin_, kGroup_, OriginSubdomains::DEFAULT /* irrelevant */, + base::Time() /* irrelevant */, base::Time() /* irrelevant */)); + expected_commands.emplace_back(CommandType::FLUSH); + expected_commands.emplace_back( + CommandType::DELETE_REPORTING_ENDPOINT, + ReportingEndpoint(kOrigin2_, kGroup_, + ReportingEndpoint::EndpointInfo{kEndpoint_})); + expected_commands.emplace_back( + CommandType::DELETE_REPORTING_ENDPOINT_GROUP, + CachedReportingEndpointGroup( + kOrigin2_, kGroup_, OriginSubdomains::DEFAULT /* irrelevant */, + base::Time() /* irrelevant */, base::Time() /* irrelevant */)); + expected_commands.emplace_back(CommandType::FLUSH); + EXPECT_THAT(store()->GetAllCommands(), + testing::UnorderedElementsAreArray(expected_commands)); +} + +INSTANTIATE_TEST_SUITE_P(ReportingServiceStoreTest, + ReportingServiceTest, + ::testing::Bool()); } // namespace } // namespace net
diff --git a/net/test/embedded_test_server/embedded_test_server.cc b/net/test/embedded_test_server/embedded_test_server.cc index 6ebe322c..81bfaa2 100644 --- a/net/test/embedded_test_server/embedded_test_server.cc +++ b/net/test/embedded_test_server/embedded_test_server.cc
@@ -12,6 +12,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/message_loop/message_loop_current.h" +#include "base/message_loop/message_pump_type.h" #include "base/path_service.h" #include "base/process/process_metrics.h" #include "base/run_loop.h" @@ -174,7 +175,7 @@ DCHECK(!io_thread_.get()) << "Server must not be started while server is running"; base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessagePump::Type::IO; + thread_options.message_pump_type = base::MessagePumpType::IO; io_thread_ = std::make_unique<base::Thread>("EmbeddedTestServer IO Thread"); CHECK(io_thread_->StartWithOptions(thread_options)); CHECK(io_thread_->WaitUntilThreadStarted());
diff --git a/net/test/embedded_test_server/embedded_test_server_unittest.cc b/net/test/embedded_test_server/embedded_test_server_unittest.cc index 52bae82..a61700f1 100644 --- a/net/test/embedded_test_server/embedded_test_server_unittest.cc +++ b/net/test/embedded_test_server/embedded_test_server_unittest.cc
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/path_service.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -130,7 +131,7 @@ void SetUp() override { base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; ASSERT_TRUE(io_thread_.StartWithOptions(thread_options)); request_context_getter_ = base::MakeRefCounted<TestURLRequestContextGetter>( @@ -527,7 +528,7 @@ scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner; base::Thread io_thread("io_thread"); base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; ASSERT_TRUE(io_thread.StartWithOptions(thread_options)); io_thread_runner = io_thread.task_runner();
diff --git a/net/test/quic_simple_test_server.cc b/net/test/quic_simple_test_server.cc index b8cd94c..92866c7 100644 --- a/net/test/quic_simple_test_server.cc +++ b/net/test/quic_simple_test_server.cc
@@ -10,7 +10,7 @@ #include "base/bind.h" #include "base/files/file_path.h" #include "base/files/file_util.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" @@ -197,7 +197,7 @@ DCHECK(!g_quic_server_thread); g_quic_server_thread = new base::Thread("quic server thread"); base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; bool started = g_quic_server_thread->StartWithOptions(thread_options); DCHECK(started); base::FilePath test_files_root = GetTestCertsDirectory();
diff --git a/net/test/spawned_test_server/remote_test_server.cc b/net/test/spawned_test_server/remote_test_server.cc index f0c8a0b..d29e762 100644 --- a/net/test/spawned_test_server/remote_test_server.cc +++ b/net/test/spawned_test_server/remote_test_server.cc
@@ -14,7 +14,7 @@ #include "base/files/file_util.h" #include "base/json/json_writer.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" @@ -201,7 +201,7 @@ config_ = RemoteTestServerConfig::Load(); bool thread_started = io_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); CHECK(thread_started); // Unlike LocalTestServer, RemoteTestServer passes relative paths to the test
diff --git a/net/test/tcp_socket_proxy_unittest.cc b/net/test/tcp_socket_proxy_unittest.cc index 8a33129..54bde532 100644 --- a/net/test/tcp_socket_proxy_unittest.cc +++ b/net/test/tcp_socket_proxy_unittest.cc
@@ -4,7 +4,7 @@ #include "net/test/tcp_socket_proxy.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/threading/thread.h" #include "build/build_config.h" #include "net/base/io_buffer.h" @@ -25,7 +25,7 @@ public: TcpSocketProxyTest() : io_thread_("TcpSocketProxyTest IO Thread") { EXPECT_TRUE(io_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); + base::Thread::Options(base::MessagePumpType::IO, 0))); listen_socket_ = std::make_unique<TCPServerSocket>(nullptr, net::NetLogSource());
diff --git a/net/tools/cert_verify_tool/cert_verify_tool.cc b/net/tools/cert_verify_tool/cert_verify_tool.cc index ef089bd..3f07908 100644 --- a/net/tools/cert_verify_tool/cert_verify_tool.cc +++ b/net/tools/cert_verify_tool/cert_verify_tool.cc
@@ -9,7 +9,7 @@ #include "base/callback_helpers.h" #include "base/command_line.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/strings/string_split.h" #include "base/synchronization/waitable_event.h" #include "base/task/thread_pool/thread_pool.h" @@ -354,7 +354,7 @@ // Create a network thread to be used for AIA fetches, and wait for a // CertNetFetcher to be constructed on that thread. - base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options options(base::MessagePumpType::IO, 0); base::Thread thread("network_thread"); CHECK(thread.StartWithOptions(options)); // Owned by this thread, but initialized, used, and shutdown on the network
diff --git a/net/tools/quic/quic_http_proxy_backend.cc b/net/tools/quic/quic_http_proxy_backend.cc index 7785eaa..fc4bf25 100644 --- a/net/tools/quic/quic_http_proxy_backend.cc +++ b/net/tools/quic/quic_http_proxy_backend.cc
@@ -14,6 +14,7 @@ #include <vector> #include "base/bind.h" +#include "base/message_loop/message_pump_type.h" #include "build/build_config.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" @@ -51,7 +52,7 @@ if (proxy_thread_ == nullptr) { proxy_thread_ = std::make_unique<base::Thread>("quic proxy thread"); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; bool result = proxy_thread_->StartWithOptions(options); proxy_task_runner_ = proxy_thread_->task_runner(); CHECK(result);
diff --git a/net/url_request/url_fetcher_impl_unittest.cc b/net/url_request/url_fetcher_impl_unittest.cc index a7346f4..b110b7c1 100644 --- a/net/url_request/url_fetcher_impl_unittest.cc +++ b/net/url_request/url_fetcher_impl_unittest.cc
@@ -18,7 +18,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/location.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/path_service.h" #include "base/run_loop.h" #include "base/sequenced_task_runner.h" @@ -363,7 +363,7 @@ if (!network_thread_) { network_thread_.reset(new base::Thread("network thread")); base::Thread::Options network_thread_options; - network_thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + network_thread_options.message_pump_type = base::MessagePumpType::IO; bool result = network_thread_->StartWithOptions(network_thread_options); CHECK(result); }
diff --git a/ppapi/nacl_irt/plugin_startup.cc b/ppapi/nacl_irt/plugin_startup.cc index ef88f290..599cca52 100644 --- a/ppapi/nacl_irt/plugin_startup.cc +++ b/ppapi/nacl_irt/plugin_startup.cc
@@ -8,7 +8,7 @@ #include "base/file_descriptor_posix.h" #include "base/location.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" @@ -82,7 +82,7 @@ base::WaitableEvent::InitialState::NOT_SIGNALED); g_io_thread = new base::Thread("Chrome_NaClIOThread"); g_io_thread->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); if (IsValidChannelHandle(g_manifest_service_handle)) { // Manifest service must be created on IOThread so that the main message
diff --git a/ppapi/proxy/plugin_globals.cc b/ppapi/proxy/plugin_globals.cc index 740cefe9..a8e543b5 100644 --- a/ppapi/proxy/plugin_globals.cc +++ b/ppapi/proxy/plugin_globals.cc
@@ -5,7 +5,7 @@ #include "ppapi/proxy/plugin_globals.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/task_runner.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" @@ -174,7 +174,7 @@ if (!file_thread_.get()) { file_thread_.reset(new base::Thread("Plugin::File")); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; file_thread_->StartWithOptions(options); } return file_thread_->task_runner().get();
diff --git a/ppapi/proxy/ppapi_proxy_test.cc b/ppapi/proxy/ppapi_proxy_test.cc index 573c020eb..71bf780 100644 --- a/ppapi/proxy/ppapi_proxy_test.cc +++ b/ppapi/proxy/ppapi_proxy_test.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/location.h" +#include "base/message_loop/message_pump_type.h" #include "base/observer_list.h" #include "base/process/process_handle.h" #include "base/run_loop.h" @@ -571,7 +572,7 @@ void TwoWayTest::SetUp() { base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; io_thread_.StartWithOptions(options); plugin_thread_.Start();
diff --git a/remoting/base/auto_thread.cc b/remoting/base/auto_thread.cc index f289e18..cb379a2d 100644 --- a/remoting/base/auto_thread.cc +++ b/remoting/base/auto_thread.cc
@@ -51,7 +51,7 @@ // from within StartWithType. struct AutoThread::StartupData { // Fields describing the desired thread behaviour. - base::MessagePump::Type loop_type; + base::MessagePumpType pump_type; // Used to receive the AutoThreadTaskRunner for the thread. scoped_refptr<AutoThreadTaskRunner> task_runner; @@ -59,8 +59,8 @@ // Used to synchronize thread startup. base::WaitableEvent event; - explicit StartupData(base::MessagePump::Type type) - : loop_type(type), + explicit StartupData(base::MessagePumpType type) + : pump_type(type), event(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED) {} }; @@ -69,7 +69,7 @@ scoped_refptr<AutoThreadTaskRunner> AutoThread::CreateWithType( const char* name, scoped_refptr<AutoThreadTaskRunner> joiner, - base::MessagePump::Type type) { + base::MessagePumpType type) { AutoThread* thread = new AutoThread(name, joiner.get()); scoped_refptr<AutoThreadTaskRunner> task_runner = thread->StartWithType(type); if (!task_runner.get()) @@ -80,7 +80,7 @@ // static scoped_refptr<AutoThreadTaskRunner> AutoThread::Create( const char* name, scoped_refptr<AutoThreadTaskRunner> joiner) { - return CreateWithType(name, joiner, base::MessagePump::Type::DEFAULT); + return CreateWithType(name, joiner, base::MessagePumpType::DEFAULT); } #if defined(OS_WIN) @@ -88,12 +88,12 @@ scoped_refptr<AutoThreadTaskRunner> AutoThread::CreateWithLoopAndComInitTypes( const char* name, scoped_refptr<AutoThreadTaskRunner> joiner, - base::MessagePump::Type loop_type, + base::MessagePumpType pump_type, ComInitType com_init_type) { AutoThread* thread = new AutoThread(name, joiner.get()); thread->SetComInitType(com_init_type); scoped_refptr<AutoThreadTaskRunner> task_runner = - thread->StartWithType(loop_type); + thread->StartWithType(pump_type); if (!task_runner.get()) delete thread; return task_runner; @@ -135,10 +135,10 @@ } scoped_refptr<AutoThreadTaskRunner> AutoThread::StartWithType( - base::MessagePump::Type type) { + base::MessagePumpType type) { DCHECK(thread_.is_null()); #if defined(OS_WIN) - DCHECK(com_init_type_ != COM_INIT_STA || type == base::MessagePump::Type::UI); + DCHECK(com_init_type_ != COM_INIT_STA || type == base::MessagePumpType::UI); #endif StartupData startup_data(type); @@ -195,7 +195,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); base::SingleThreadTaskExecutor single_thread_task_executor( - startup_data_->loop_type); + startup_data_->pump_type); base::RunLoop run_loop; // Complete the initialization of our AutoThread object. @@ -216,7 +216,7 @@ #if defined(OS_POSIX) && !defined(OS_NACL) // Allow threads running a MessageLoopForIO to use FileDescriptorWatcher. std::unique_ptr<base::FileDescriptorWatcher> file_descriptor_watcher; - if (single_thread_task_executor.type() == base::MessagePump::Type::IO) { + if (single_thread_task_executor.type() == base::MessagePumpType::IO) { file_descriptor_watcher.reset(new base::FileDescriptorWatcher( single_thread_task_executor.task_runner())); }
diff --git a/remoting/base/auto_thread.h b/remoting/base/auto_thread.h index 38d6f1e..745802e 100644 --- a/remoting/base/auto_thread.h +++ b/remoting/base/auto_thread.h
@@ -9,7 +9,7 @@ #include "base/callback_forward.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/threading/platform_thread.h" #include "base/threading/thread_checker.h" #include "build/build_config.h" @@ -39,7 +39,7 @@ static scoped_refptr<AutoThreadTaskRunner> CreateWithType( const char* name, scoped_refptr<AutoThreadTaskRunner> joiner, - base::MessageLoop::Type type); + base::MessagePumpType type); static scoped_refptr<AutoThreadTaskRunner> Create( const char* name, scoped_refptr<AutoThreadTaskRunner> joiner); @@ -51,7 +51,7 @@ static scoped_refptr<AutoThreadTaskRunner> CreateWithLoopAndComInitTypes( const char* name, scoped_refptr<AutoThreadTaskRunner> joiner, - base::MessageLoop::Type loop_type, + base::MessagePumpType pump_type, ComInitType com_init_type); #endif @@ -71,8 +71,7 @@ // // NOTE: You must not call this MessageLoop's Quit method directly. The // thread will exit when no references to the TaskRunner remain. - scoped_refptr<AutoThreadTaskRunner> StartWithType( - base::MessageLoop::Type type); + scoped_refptr<AutoThreadTaskRunner> StartWithType(base::MessagePumpType type); #if defined(OS_WIN) // Configures the thread to initialize the specified COM apartment type.
diff --git a/remoting/base/auto_thread_unittest.cc b/remoting/base/auto_thread_unittest.cc index 2038ca67..39504c1 100644 --- a/remoting/base/auto_thread_unittest.cc +++ b/remoting/base/auto_thread_unittest.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/files/file_path.h" #include "base/memory/ref_counted.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/scoped_native_library.h" #include "base/single_thread_task_runner.h" @@ -137,9 +138,8 @@ #if defined(OS_WIN) TEST_F(AutoThreadTest, ThreadWithComMta) { scoped_refptr<base::TaskRunner> task_runner = - AutoThread::CreateWithLoopAndComInitTypes(kThreadName, - main_task_runner_, - base::MessageLoop::TYPE_DEFAULT, + AutoThread::CreateWithLoopAndComInitTypes(kThreadName, main_task_runner_, + base::MessagePumpType::DEFAULT, AutoThread::COM_INIT_MTA); EXPECT_TRUE(task_runner); @@ -158,9 +158,8 @@ TEST_F(AutoThreadTest, ThreadWithComSta) { scoped_refptr<base::TaskRunner> task_runner = - AutoThread::CreateWithLoopAndComInitTypes(kThreadName, - main_task_runner_, - base::MessageLoop::TYPE_UI, + AutoThread::CreateWithLoopAndComInitTypes(kThreadName, main_task_runner_, + base::MessagePumpType::UI, AutoThread::COM_INIT_STA); EXPECT_TRUE(task_runner);
diff --git a/remoting/base/run_all_unittests.cc b/remoting/base/run_all_unittests.cc index 213d61c..5d93e12 100644 --- a/remoting/base/run_all_unittests.cc +++ b/remoting/base/run_all_unittests.cc
@@ -3,7 +3,7 @@ // found in the LICENSE file. #include "base/bind.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/test/launcher/unit_test_launcher.h" #include "base/test/test_suite.h" #include "base/threading/thread.h" @@ -15,7 +15,7 @@ base::Thread ipc_thread("IPC thread"); ipc_thread.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); mojo::core::Init(); mojo::core::ScopedIPCSupport ipc_support(
diff --git a/remoting/client/chromoting_client_runtime.cc b/remoting/client/chromoting_client_runtime.cc index c5c0a05..3bdf27c 100644 --- a/remoting/client/chromoting_client_runtime.cc +++ b/remoting/client/chromoting_client_runtime.cc
@@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/memory/singleton.h" #include "base/message_loop/message_loop_current.h" +#include "base/message_loop/message_pump_type.h" #include "base/task/single_thread_task_executor.h" #include "base/task/thread_pool/thread_pool.h" #include "build/build_config.h" @@ -34,7 +35,7 @@ VLOG(1) << "Starting main message loop"; ui_task_executor_.reset( - new base::SingleThreadTaskExecutor(base::MessagePump::Type::UI)); + new base::SingleThreadTaskExecutor(base::MessagePumpType::UI)); #if defined(DEBUG) net::URLFetcher::SetIgnoreCertificateRequests(true); @@ -49,7 +50,7 @@ audio_task_runner_ = AutoThread::Create("native_audio", ui_task_runner_); display_task_runner_ = AutoThread::Create("native_disp", ui_task_runner_); network_task_runner_ = AutoThread::CreateWithType( - "native_net", ui_task_runner_, base::MessageLoop::TYPE_IO); + "native_net", ui_task_runner_, base::MessagePumpType::IO); mojo::core::Init(); }
diff --git a/remoting/host/chromoting_host_context.cc b/remoting/host/chromoting_host_context.cc index 853c069..b924d13 100644 --- a/remoting/host/chromoting_host_context.cc +++ b/remoting/host/chromoting_host_context.cc
@@ -7,7 +7,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" @@ -117,32 +117,32 @@ // apartment, which requires a UI thread. scoped_refptr<AutoThreadTaskRunner> audio_task_runner = AutoThread::CreateWithLoopAndComInitTypes( - "ChromotingAudioThread", ui_task_runner, base::MessageLoop::TYPE_UI, + "ChromotingAudioThread", ui_task_runner, base::MessagePumpType::UI, AutoThread::COM_INIT_STA); #else // !defined(OS_WIN) scoped_refptr<AutoThreadTaskRunner> audio_task_runner = AutoThread::CreateWithType("ChromotingAudioThread", ui_task_runner, - base::MessageLoop::TYPE_IO); + base::MessagePumpType::IO); #endif // !defined(OS_WIN) scoped_refptr<AutoThreadTaskRunner> file_task_runner = AutoThread::CreateWithType("ChromotingFileThread", ui_task_runner, - base::MessageLoop::TYPE_IO); + base::MessagePumpType::IO); scoped_refptr<AutoThreadTaskRunner> network_task_runner = AutoThread::CreateWithType("ChromotingNetworkThread", ui_task_runner, - base::MessageLoop::TYPE_IO); + base::MessagePumpType::IO); network_task_runner->PostTask(FROM_HERE, base::BindOnce(&DisallowBlockingOperations)); return base::WrapUnique(new ChromotingHostContext( ui_task_runner, audio_task_runner, file_task_runner, AutoThread::CreateWithType("ChromotingInputThread", ui_task_runner, - base::MessageLoop::TYPE_IO), + base::MessagePumpType::IO), network_task_runner, #if defined(OS_MACOSX) // Mac requires a UI thread for the capturer. AutoThread::CreateWithType("ChromotingCaptureThread", ui_task_runner, - base::MessageLoop::TYPE_UI), + base::MessagePumpType::UI), #else AutoThread::Create("ChromotingCaptureThread", ui_task_runner), #endif
diff --git a/remoting/host/config_file_watcher_unittest.cc b/remoting/host/config_file_watcher_unittest.cc index 9077d01..b5d0a1d 100644 --- a/remoting/host/config_file_watcher_unittest.cc +++ b/remoting/host/config_file_watcher_unittest.cc
@@ -8,6 +8,7 @@ #include "base/files/file_util.h" #include "base/macros.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "remoting/base/auto_thread.h" #include "remoting/base/auto_thread_task_runner.h" @@ -78,8 +79,8 @@ message_loop_.task_runner(), run_loop_.QuitClosure()); scoped_refptr<AutoThreadTaskRunner> io_task_runner = - AutoThread::CreateWithType( - "IPC thread", task_runner, base::MessageLoop::TYPE_IO); + AutoThread::CreateWithType("IPC thread", task_runner, + base::MessagePumpType::IO); // Create an instance of the config watcher. watcher_.reset(
diff --git a/remoting/host/desktop_process.cc b/remoting/host/desktop_process.cc index 73ac698..9b576db 100644 --- a/remoting/host/desktop_process.cc +++ b/remoting/host/desktop_process.cc
@@ -15,6 +15,7 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/strings/string_util.h" #include "build/build_config.h" #include "ipc/ipc_channel_proxy.h" @@ -129,14 +130,12 @@ #if defined(OS_WIN) // On Windows the AudioCapturer requires COM, so we run a single-threaded // apartment, which requires a UI thread. - audio_task_runner = - AutoThread::CreateWithLoopAndComInitTypes("ChromotingAudioThread", - caller_task_runner_, - base::MessageLoop::TYPE_UI, - AutoThread::COM_INIT_STA); + audio_task_runner = AutoThread::CreateWithLoopAndComInitTypes( + "ChromotingAudioThread", caller_task_runner_, base::MessagePumpType::UI, + AutoThread::COM_INIT_STA); #else // !defined(OS_WIN) audio_task_runner = AutoThread::CreateWithType( - "ChromotingAudioThread", caller_task_runner_, base::MessageLoop::TYPE_IO); + "ChromotingAudioThread", caller_task_runner_, base::MessagePumpType::IO); #endif // !defined(OS_WIN) // Create a desktop agent.
diff --git a/remoting/host/desktop_process_unittest.cc b/remoting/host/desktop_process_unittest.cc index 2db48ab..be5f9b4d 100644 --- a/remoting/host/desktop_process_unittest.cc +++ b/remoting/host/desktop_process_unittest.cc
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "build/build_config.h" @@ -240,8 +241,8 @@ scoped_refptr<AutoThreadTaskRunner> ui_task_runner = new AutoThreadTaskRunner( message_loop_.task_runner(), quit_ui_task_runner); - io_task_runner_ = AutoThread::CreateWithType( - "IPC thread", ui_task_runner, base::MessageLoop::TYPE_IO); + io_task_runner_ = AutoThread::CreateWithType("IPC thread", ui_task_runner, + base::MessagePumpType::IO); mojo::MessagePipe pipe; daemon_channel_ = IPC::ChannelProxy::Create(
diff --git a/remoting/host/host_power_save_blocker_unittest.cc b/remoting/host/host_power_save_blocker_unittest.cc index 6b501861..22ea605 100644 --- a/remoting/host/host_power_save_blocker_unittest.cc +++ b/remoting/host/host_power_save_blocker_unittest.cc
@@ -7,7 +7,7 @@ #include <memory> #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/threading/thread.h" #include "remoting/host/host_status_monitor.h" #include "testing/gtest/include/gtest/gtest.h" @@ -34,7 +34,7 @@ void HostPowerSaveBlockerTest::SetUp() { ASSERT_TRUE(blocking_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)) && + base::Thread::Options(base::MessagePumpType::IO, 0)) && blocking_thread_.WaitUntilThreadStarted()); blocker_.reset(new HostPowerSaveBlocker(monitor_, ui_message_loop_.task_runner(),
diff --git a/remoting/host/ipc_desktop_environment_unittest.cc b/remoting/host/ipc_desktop_environment_unittest.cc index 941bcfe..f1ce73a0 100644 --- a/remoting/host/ipc_desktop_environment_unittest.cc +++ b/remoting/host/ipc_desktop_environment_unittest.cc
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/process/process.h" #include "base/process/process_handle.h" #include "base/run_loop.h" @@ -265,8 +266,8 @@ task_runner_ = new AutoThreadTaskRunner( message_loop_.task_runner(), main_run_loop_.QuitClosure()); - io_task_runner_ = AutoThread::CreateWithType( - "IPC thread", task_runner_, base::MessageLoop::TYPE_IO); + io_task_runner_ = AutoThread::CreateWithType("IPC thread", task_runner_, + base::MessagePumpType::IO); setup_run_loop_.reset(new base::RunLoop());
diff --git a/remoting/host/linux/audio_pipe_reader_unittest.cc b/remoting/host/linux/audio_pipe_reader_unittest.cc index 6559a833..70d35a4 100644 --- a/remoting/host/linux/audio_pipe_reader_unittest.cc +++ b/remoting/host/linux/audio_pipe_reader_unittest.cc
@@ -13,6 +13,7 @@ #include "base/files/file.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" @@ -33,7 +34,7 @@ pipe_path_ = test_dir_.GetPath().AppendASCII("test_pipe"); audio_thread_.reset(new base::Thread("TestAudioThread")); audio_thread_->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); reader_ = AudioPipeReader::Create(audio_thread_->task_runner(), pipe_path_); reader_->AddObserver(this);
diff --git a/remoting/host/native_messaging/native_messaging_reader.cc b/remoting/host/native_messaging/native_messaging_reader.cc index de38084c..6ee6fa5 100644 --- a/remoting/host/native_messaging/native_messaging_reader.cc +++ b/remoting/host/native_messaging/native_messaging_reader.cc
@@ -13,7 +13,7 @@ #include "base/json/json_reader.h" #include "base/location.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" @@ -147,7 +147,7 @@ : reader_thread_("Reader"), weak_factory_(this) { reader_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, /*size=*/0)); + base::Thread::Options(base::MessagePumpType::IO, /*size=*/0)); read_task_runner_ = reader_thread_.task_runner(); core_.reset(new Core(std::move(file), base::ThreadTaskRunnerHandle::Get(),
diff --git a/remoting/host/security_key/security_key_auth_handler_posix_unittest.cc b/remoting/host/security_key/security_key_auth_handler_posix_unittest.cc index d0a8cefc..df11308 100644 --- a/remoting/host/security_key/security_key_auth_handler_posix_unittest.cc +++ b/remoting/host/security_key/security_key_auth_handler_posix_unittest.cc
@@ -14,6 +14,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/macros.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/threading/thread.h" #include "net/base/io_buffer.h" @@ -75,7 +76,7 @@ remoting::SecurityKeyAuthHandler::SetSecurityKeySocketName(socket_path_); EXPECT_TRUE(file_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); + base::Thread::Options(base::MessagePumpType::IO, 0))); send_message_callback_ = base::Bind(&SecurityKeyAuthHandlerPosixTest::SendMessageToClient,
diff --git a/remoting/host/security_key/security_key_message_reader.cc b/remoting/host/security_key/security_key_message_reader.cc index 77b1e40c..810c752 100644 --- a/remoting/host/security_key/security_key_message_reader.cc +++ b/remoting/host/security_key/security_key_message_reader.cc
@@ -11,7 +11,7 @@ #include "base/bind.h" #include "base/files/file.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" #include "base/threading/thread_task_runner_handle.h" @@ -24,7 +24,7 @@ reader_thread_("SecurityKeyMessageReader"), weak_factory_(this) { base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; reader_thread_.StartWithOptions(options); read_task_runner_ = reader_thread_.task_runner();
diff --git a/remoting/host/security_key/security_key_message_reader_impl.cc b/remoting/host/security_key/security_key_message_reader_impl.cc index 5c3cd1d..53067c7 100644 --- a/remoting/host/security_key/security_key_message_reader_impl.cc +++ b/remoting/host/security_key/security_key_message_reader_impl.cc
@@ -11,7 +11,7 @@ #include "base/bind.h" #include "base/files/file.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" #include "base/threading/thread_task_runner_handle.h" @@ -25,7 +25,7 @@ reader_thread_("SecurityKeyMessageReaderImpl"), weak_factory_(this) { base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; reader_thread_.StartWithOptions(options); read_task_runner_ = reader_thread_.task_runner();
diff --git a/remoting/host/security_key/security_key_message_writer_impl_unittest.cc b/remoting/host/security_key/security_key_message_writer_impl_unittest.cc index 1eea21c9a..b19defd 100644 --- a/remoting/host/security_key/security_key_message_writer_impl_unittest.cc +++ b/remoting/host/security_key/security_key_message_writer_impl_unittest.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/stl_util.h" #include "base/task_runner_util.h" @@ -99,7 +100,7 @@ base::Thread reader_thread("ReaderThread"); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; reader_thread.StartWithOptions(options); // Used to block until the read complete callback is triggered.
diff --git a/remoting/host/setup/daemon_controller.cc b/remoting/host/setup/daemon_controller.cc index e654fd2..0591a21 100644 --- a/remoting/host/setup/daemon_controller.cc +++ b/remoting/host/setup/daemon_controller.cc
@@ -8,7 +8,7 @@ #include "base/bind.h" #include "base/location.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" @@ -29,10 +29,10 @@ #if defined(OS_WIN) delegate_thread_->SetComInitType(AutoThread::COM_INIT_STA); delegate_task_runner_ = - delegate_thread_->StartWithType(base::MessageLoop::TYPE_UI); + delegate_thread_->StartWithType(base::MessagePumpType::UI); #else delegate_task_runner_ = - delegate_thread_->StartWithType(base::MessageLoop::TYPE_DEFAULT); + delegate_thread_->StartWithType(base::MessagePumpType::DEFAULT); #endif }
diff --git a/remoting/ios/app/remoting_view_controller.mm b/remoting/ios/app/remoting_view_controller.mm index cb41901..10a0fdee 100644 --- a/remoting/ios/app/remoting_view_controller.mm +++ b/remoting/ios/app/remoting_view_controller.mm
@@ -32,6 +32,7 @@ #import "remoting/ios/domain/client_session_details.h" #import "remoting/ios/facade/remoting_service.h" +#include "base/mac/scoped_cftyperef.h" #include "base/strings/sys_string_conversions.h" #include "remoting/base/oauth_token_getter.h" #include "remoting/base/string_resources.h"
diff --git a/remoting/test/protocol_perftest.cc b/remoting/test/protocol_perftest.cc index 390db09..cf499595 100644 --- a/remoting/test/protocol_perftest.cc +++ b/remoting/test/protocol_perftest.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/files/file_util.h" #include "base/macros.h" +#include "base/message_loop/message_pump_type.h" #include "base/rand_util.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -114,7 +115,7 @@ encode_thread_("encode"), decode_thread_("decode") { host_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); capture_thread_.Start(); encode_thread_.Start(); decode_thread_.Start();
diff --git a/rlz/lib/rlz_lib_test.cc b/rlz/lib/rlz_lib_test.cc index 59c89b4..06a489e 100644 --- a/rlz/lib/rlz_lib_test.cc +++ b/rlz/lib/rlz_lib_test.cc
@@ -19,7 +19,7 @@ #include "base/bind.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/posix/eintr_wrapper.h" #include "base/strings/stringprintf.h" #include "base/test/scoped_task_environment.h" @@ -630,7 +630,7 @@ #endif base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; base::Thread io_thread("rlz_unittest_io_thread"); ASSERT_TRUE(io_thread.StartWithOptions(options));
diff --git a/services/device/battery/battery_status_manager_linux.cc b/services/device/battery/battery_status_manager_linux.cc index b0797c7..3811cc68 100644 --- a/services/device/battery/battery_status_manager_linux.cc +++ b/services/device/battery/battery_status_manager_linux.cc
@@ -16,7 +16,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread.h" @@ -603,7 +603,7 @@ if (notifier_thread_) return true; - base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options thread_options(base::MessagePumpType::IO, 0); auto notifier_thread = std::make_unique<BatteryStatusNotificationThread>(callback_); if (!notifier_thread->StartWithOptions(thread_options)) {
diff --git a/services/identity/identity_accessor_impl.cc b/services/identity/identity_accessor_impl.cc index e7ca0d1..a148f98 100644 --- a/services/identity/identity_accessor_impl.cc +++ b/services/identity/identity_accessor_impl.cc
@@ -102,8 +102,9 @@ void IdentityAccessorImpl::OnAccountStateChange(const std::string& account_id) { base::Optional<AccountInfo> account_info = - identity_manager_->FindAccountInfoForAccountWithRefreshTokenByAccountId( - account_id); + identity_manager_ + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id); if (account_info.has_value()) { AccountState account_state = GetStateOfAccount(account_info.value());
diff --git a/services/network/network_service.cc b/services/network/network_service.cc index c7a9519..ef87812 100644 --- a/services/network/network_service.cc +++ b/services/network/network_service.cc
@@ -31,7 +31,6 @@ #include "net/cert/cert_database.h" #include "net/cert/ct_log_response_parser.h" #include "net/cert/signed_tree_head.h" -#include "net/dns/dns_config.h" #include "net/dns/dns_config_overrides.h" #include "net/dns/host_resolver.h" #include "net/dns/host_resolver_manager.h" @@ -433,17 +432,16 @@ } void NetworkService::ConfigureStubHostResolver( - bool stub_resolver_enabled, + bool insecure_dns_client_enabled, + net::DnsConfig::SecureDnsMode secure_dns_mode, base::Optional<std::vector<mojom::DnsOverHttpsServerPtr>> dns_over_https_servers) { - // If the stub resolver is not enabled, |dns_over_https_servers| has no - // effect. - DCHECK(stub_resolver_enabled || !dns_over_https_servers); DCHECK(!dns_over_https_servers || !dns_over_https_servers->empty()); // Enable or disable the insecure part of DnsClient. "DnsClient" is the class // that implements the stub resolver. - host_resolver_manager_->SetInsecureDnsClientEnabled(stub_resolver_enabled); + host_resolver_manager_->SetInsecureDnsClientEnabled( + insecure_dns_client_enabled); // Configure DNS over HTTPS. if (!dns_over_https_servers || dns_over_https_servers.value().empty()) { @@ -457,9 +455,7 @@ overrides.dns_over_https_servers.value().emplace_back( doh_server->server_template, doh_server->use_post); } - // TODO(crbug.com/985589): Allow the secure dns mode to be set independently - // of the insecure part of the stub resolver. - overrides.secure_dns_mode = net::DnsConfig::SecureDnsMode::AUTOMATIC; + overrides.secure_dns_mode = secure_dns_mode; host_resolver_manager_->SetDnsConfigOverrides(overrides); }
diff --git a/services/network/network_service.h b/services/network/network_service.h index 5ce34457..633cebdd 100644 --- a/services/network/network_service.h +++ b/services/network/network_service.h
@@ -23,6 +23,7 @@ #include "base/timer/timer.h" #include "build/build_config.h" #include "mojo/public/cpp/bindings/binding.h" +#include "net/dns/dns_config.h" #include "net/http/http_auth_preferences.h" #include "net/log/net_log.h" #include "net/log/trace_net_log_observer.h" @@ -142,7 +143,8 @@ void CreateNetworkContext(mojom::NetworkContextRequest request, mojom::NetworkContextParamsPtr params) override; void ConfigureStubHostResolver( - bool stub_resolver_enabled, + bool insecure_dns_client_enabled, + net::DnsConfig::SecureDnsMode secure_dns_mode, base::Optional<std::vector<mojom::DnsOverHttpsServerPtr>> dns_over_https_servers) override; void DisableQuic() override;
diff --git a/services/network/network_service_unittest.cc b/services/network/network_service_unittest.cc index b8993a45..4e279b4 100644 --- a/services/network/network_service_unittest.cc +++ b/services/network/network_service_unittest.cc
@@ -22,6 +22,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "net/base/escape.h" +#include "net/base/ip_endpoint.h" #include "net/base/mock_network_change_notifier.h" #include "net/base/url_util.h" #include "net/dns/dns_config_service.h" @@ -443,23 +444,55 @@ #if !defined(OS_IOS) TEST_F(NetworkServiceTest, DnsClientEnableDisable) { - // HostResolver::GetDnsConfigAsValue() returns nullptr if the stub resolver is - // disabled. - EXPECT_FALSE(service() - ->host_resolver_manager() - ->GetInsecureDnsClientEnabledForTesting()); + // Set valid DnsConfig. + net::DnsConfig config; + config.nameservers.push_back(net::IPEndPoint()); + service()->host_resolver_manager()->SetBaseDnsConfigForTesting(config); + service()->ConfigureStubHostResolver( - true /* stub_resolver_enabled */, + true /* insecure_dns_client_enabled */, + net::DnsConfig::SecureDnsMode::OFF, base::nullopt /* dns_over_https_servers */); EXPECT_TRUE(service() ->host_resolver_manager() ->GetInsecureDnsClientEnabledForTesting()); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF, + service()->host_resolver_manager()->GetSecureDnsModeForTesting()); + service()->ConfigureStubHostResolver( - false /* stub_resolver_enabled */, + false /* insecure_dns_client_enabled */, + net::DnsConfig::SecureDnsMode::OFF, base::nullopt /* dns_over_https_servers */); EXPECT_FALSE(service() ->host_resolver_manager() ->GetInsecureDnsClientEnabledForTesting()); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF, + service()->host_resolver_manager()->GetSecureDnsModeForTesting()); + + service()->ConfigureStubHostResolver( + false /* insecure_dns_client_enabled */, + net::DnsConfig::SecureDnsMode::AUTOMATIC, + base::nullopt /* dns_over_https_servers */); + EXPECT_FALSE(service() + ->host_resolver_manager() + ->GetInsecureDnsClientEnabledForTesting()); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF, + service()->host_resolver_manager()->GetSecureDnsModeForTesting()); + + std::vector<mojom::DnsOverHttpsServerPtr> dns_over_https_servers_ptr; + mojom::DnsOverHttpsServerPtr dns_over_https_server = + mojom::DnsOverHttpsServer::New(); + dns_over_https_server->server_template = "https://foo/"; + dns_over_https_server->use_post = true; + dns_over_https_servers_ptr.emplace_back(std::move(dns_over_https_server)); + service()->ConfigureStubHostResolver(false /* insecure_dns_client_enabled */, + net::DnsConfig::SecureDnsMode::AUTOMATIC, + std::move(dns_over_https_servers_ptr)); + EXPECT_FALSE(service() + ->host_resolver_manager() + ->GetInsecureDnsClientEnabledForTesting()); + EXPECT_EQ(net::DnsConfig::SecureDnsMode::AUTOMATIC, + service()->host_resolver_manager()->GetSecureDnsModeForTesting()); } TEST_F(NetworkServiceTest, DnsOverHttpsEnableDisable) { @@ -487,7 +520,8 @@ dns_over_https_server->use_post = kServer1UsePost; dns_over_https_servers_ptr.emplace_back(std::move(dns_over_https_server)); - service()->ConfigureStubHostResolver(true /* stub_resolver_enabled */, + service()->ConfigureStubHostResolver(false /* insecure_dns_client_enabled */, + net::DnsConfig::SecureDnsMode::AUTOMATIC, std::move(dns_over_https_servers_ptr)); EXPECT_TRUE(service()->host_resolver_manager()->GetDnsConfigAsValue()); const auto* dns_over_https_servers = @@ -510,7 +544,8 @@ dns_over_https_server->use_post = kServer3UsePost; dns_over_https_servers_ptr.emplace_back(std::move(dns_over_https_server)); - service()->ConfigureStubHostResolver(true /* stub_resolver_enabled */, + service()->ConfigureStubHostResolver(true /* insecure_dns_client_enabled */, + net::DnsConfig::SecureDnsMode::SECURE, std::move(dns_over_https_servers_ptr)); EXPECT_TRUE(service()->host_resolver_manager()->GetDnsConfigAsValue()); dns_over_https_servers =
diff --git a/services/network/public/cpp/host_resolver.typemap b/services/network/public/cpp/host_resolver.typemap index 20cb2428..77691a20 100644 --- a/services/network/public/cpp/host_resolver.typemap +++ b/services/network/public/cpp/host_resolver.typemap
@@ -1,9 +1,10 @@ # Copyright 2018 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# found in the LICENSE file. mojom = "//services/network/public/mojom/host_resolver.mojom" public_headers = [ + "//net/dns/dns_config.h", "//net/dns/dns_config_overrides.h", "//net/dns/host_resolver.h", "//net/dns/host_resolver_source.h", @@ -22,4 +23,5 @@ "network.mojom.DnsQueryType=net::DnsQueryType", "network.mojom.ResolveHostParameters.Source=net::HostResolverSource", "network.mojom.MdnsListenClient.UpdateType=net::HostResolver::MdnsListener::Delegate::UpdateType", + "network.mojom.SecureDnsMode=net::DnsConfig::SecureDnsMode", ]
diff --git a/services/network/public/cpp/host_resolver_mojom_traits.cc b/services/network/public/cpp/host_resolver_mojom_traits.cc index 0192278..3796681 100644 --- a/services/network/public/cpp/host_resolver_mojom_traits.cc +++ b/services/network/public/cpp/host_resolver_mojom_traits.cc
@@ -373,4 +373,38 @@ } } +// static +network::mojom::SecureDnsMode +EnumTraits<network::mojom::SecureDnsMode, net::DnsConfig::SecureDnsMode>:: + ToMojom(net::DnsConfig::SecureDnsMode secure_dns_mode) { + switch (secure_dns_mode) { + case net::DnsConfig::SecureDnsMode::OFF: + return network::mojom::SecureDnsMode::OFF; + case net::DnsConfig::SecureDnsMode::AUTOMATIC: + return network::mojom::SecureDnsMode::AUTOMATIC; + case net::DnsConfig::SecureDnsMode::SECURE: + return network::mojom::SecureDnsMode::SECURE; + } + NOTREACHED(); + return network::mojom::SecureDnsMode::OFF; +} + +// static +bool EnumTraits<network::mojom::SecureDnsMode, net::DnsConfig::SecureDnsMode>:: + FromMojom(network::mojom::SecureDnsMode in, + net::DnsConfig::SecureDnsMode* out) { + switch (in) { + case network::mojom::SecureDnsMode::OFF: + *out = net::DnsConfig::SecureDnsMode::OFF; + return true; + case network::mojom::SecureDnsMode::AUTOMATIC: + *out = net::DnsConfig::SecureDnsMode::AUTOMATIC; + return true; + case network::mojom::SecureDnsMode::SECURE: + *out = net::DnsConfig::SecureDnsMode::SECURE; + return true; + } + return false; +} + } // namespace mojo
diff --git a/services/network/public/cpp/host_resolver_mojom_traits.h b/services/network/public/cpp/host_resolver_mojom_traits.h index b6c7ac44..b7e175b 100644 --- a/services/network/public/cpp/host_resolver_mojom_traits.h +++ b/services/network/public/cpp/host_resolver_mojom_traits.h
@@ -17,6 +17,7 @@ #include "net/base/address_family.h" #include "net/base/ip_address.h" #include "net/base/ip_endpoint.h" +#include "net/dns/dns_config.h" #include "net/dns/dns_config_overrides.h" #include "net/dns/dns_hosts.h" #include "net/dns/host_resolver.h" @@ -105,6 +106,15 @@ net::HostResolver::MdnsListener::Delegate::UpdateType* output); }; +template <> +struct EnumTraits<network::mojom::SecureDnsMode, + net::DnsConfig::SecureDnsMode> { + static network::mojom::SecureDnsMode ToMojom( + net::DnsConfig::SecureDnsMode secure_dns_mode); + static bool FromMojom(network::mojom::SecureDnsMode in, + net::DnsConfig::SecureDnsMode* out); +}; + } // namespace mojo #endif // SERVICES_NETWORK_PUBLIC_CPP_HOST_RESOLVER_MOJOM_TRAITS_H_
diff --git a/services/network/public/mojom/host_resolver.mojom b/services/network/public/mojom/host_resolver.mojom index cd137d8e..fce8cc7 100644 --- a/services/network/public/mojom/host_resolver.mojom +++ b/services/network/public/mojom/host_resolver.mojom
@@ -40,6 +40,13 @@ SECURE, }; +// This enum corresponds to DnsConfig::SecureDnsMode. +enum SecureDnsMode { + OFF, + AUTOMATIC, + SECURE, +}; + // Overridable DNS configuration values for host resolution. All fields default // to a non-overriding state where the relevant value will be used from system // DNS configuration.
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom index cd3d86c..3c87dc1d 100644 --- a/services/network/public/mojom/network_service.mojom +++ b/services/network/public/mojom/network_service.mojom
@@ -324,19 +324,21 @@ // resolver. // // |dns_over_https_servers| is an optional list of DNS over HTTPS servers. - // When populated, all DNS lookups will try to use DNS over HTTPS in the order - // the servers are provided in and will only fall back to using system - // settings if DNS over HTTPS fails. It is illegal to have a populated - // |dns_over_https_servers| when |stub_resolver_enabled| is false. + // DnsTransactions will by default follow the behavior of |secure_dns_mode|. + // In SECURE mode, only DoH lookups will be performed. In AUTOMATIC mode, + // DoH lookups to available servers will be performed first, and insecure + // lookups will be used as a fallback. In OFF mode, only insecure lookups will + // be performed. When insecure lookups are performed, they will be sent by + // the async resolver first if |insecure_dns_client_enabled| is true and + // then by the system resolver as a fallback. // // DNS over HTTPS will use the primary NetworkContext, so can only be enabled // after the primary network context has been created. Other than that // limitation, this method can be called at any time to change DNS // configuration, though calling it will fail any DNS lookups that have // already been started. - // - // Both the stub resolver and DNS over HTTPS are disabled by default. - ConfigureStubHostResolver(bool stub_resolver_enabled, + ConfigureStubHostResolver(bool insecure_dns_client_enabled, + SecureDnsMode secure_dns_mode, array<DnsOverHttpsServer>? dns_over_https_servers); // Disables QUIC for the NetworkService. Affects all existing NetworkContexts,
diff --git a/services/network/transitional_url_loader_factory_owner_unittest.cc b/services/network/transitional_url_loader_factory_owner_unittest.cc index 332e76a1..1930491 100644 --- a/services/network/transitional_url_loader_factory_owner_unittest.cc +++ b/services/network/transitional_url_loader_factory_owner_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/test/bind_test_util.h" #include "base/test/scoped_task_environment.h" @@ -74,7 +75,7 @@ TEST_F(TransitionalURLLoaderFactoryOwnerTest, CrossThread) { base::Thread io_thread("IO"); base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; + options.message_pump_type = base::MessagePumpType::IO; ASSERT_TRUE(io_thread.StartWithOptions(options)); TestOnTaskRunner(io_thread.task_runner(), base::BindLambdaForTesting([&]() {
diff --git a/services/service_manager/public/cpp/service_executable/service_executable_environment.cc b/services/service_manager/public/cpp/service_executable/service_executable_environment.cc index 6cf9e501..3a9be1d 100644 --- a/services/service_manager/public/cpp/service_executable/service_executable_environment.cc +++ b/services/service_manager/public/cpp/service_executable/service_executable_environment.cc
@@ -6,8 +6,8 @@ #include "base/command_line.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop_current.h" +#include "base/message_loop/message_pump_type.h" #include "base/synchronization/waitable_event.h" #include "base/task/thread_pool/thread_pool.h" #include "build/build_config.h" @@ -56,7 +56,7 @@ base::ThreadPoolInstance::CreateAndStartWithDefaultParams( "StandaloneService"); ipc_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); ipc_support_.emplace(ipc_thread_.task_runner(), mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);
diff --git a/services/test/run_all_unittests.cc b/services/test/run_all_unittests.cc index 0979d18a..b3613986 100644 --- a/services/test/run_all_unittests.cc +++ b/services/test/run_all_unittests.cc
@@ -6,7 +6,7 @@ #include "base/files/file.h" #include "base/i18n/icu_util.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/path_service.h" #include "base/test/launcher/unit_test_launcher.h" #include "base/test/test_suite.h" @@ -80,7 +80,7 @@ base::Thread ipc_thread("IPC thread"); ipc_thread.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); mojo::core::ScopedIPCSupport ipc_support( ipc_thread.task_runner(), mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);
diff --git a/services/viz/privileged/mojom/compositing/renderer_settings.mojom b/services/viz/privileged/mojom/compositing/renderer_settings.mojom index 8191e56..d9caf73e 100644 --- a/services/viz/privileged/mojom/compositing/renderer_settings.mojom +++ b/services/viz/privileged/mojom/compositing/renderer_settings.mojom
@@ -18,6 +18,7 @@ bool release_overlay_resources_after_gpu_query; bool should_clear_root_render_pass; bool show_overdraw_feedback; + bool show_aggregated_damage; int32 slow_down_compositing_scale_factor; bool use_skia_renderer; bool record_sk_picture;
diff --git a/services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.cc b/services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.cc index fa50c1c1..436aee9 100644 --- a/services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.cc +++ b/services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.cc
@@ -25,6 +25,7 @@ data.release_overlay_resources_after_gpu_query(); out->tint_gl_composited_content = data.tint_gl_composited_content(); out->show_overdraw_feedback = data.show_overdraw_feedback(); + out->show_aggregated_damage = data.show_aggregated_damage(); out->highp_threshold_min = data.highp_threshold_min(); out->slow_down_compositing_scale_factor = data.slow_down_compositing_scale_factor();
diff --git a/services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.h b/services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.h index 240a847..0210173 100644 --- a/services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.h +++ b/services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.h
@@ -54,6 +54,10 @@ return input.show_overdraw_feedback; } + static bool show_aggregated_damage(const viz::RendererSettings& input) { + return input.show_aggregated_damage; + } + static int highp_threshold_min(const viz::RendererSettings& input) { return input.highp_threshold_min; }
diff --git a/services/viz/public/cpp/gpu/gpu_unittest.cc b/services/viz/public/cpp/gpu/gpu_unittest.cc index 87f302b..c3d32fd 100644 --- a/services/viz/public/cpp/gpu/gpu_unittest.cc +++ b/services/viz/public/cpp/gpu/gpu_unittest.cc
@@ -6,7 +6,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/synchronization/waitable_event.h" #include "base/test/scoped_task_environment.h" @@ -83,7 +83,7 @@ class GpuTest : public testing::Test { public: GpuTest() : io_thread_("GPUIOThread") { - base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); + base::Thread::Options thread_options(base::MessagePumpType::IO, 0); thread_options.priority = base::ThreadPriority::NORMAL; CHECK(io_thread_.StartWithOptions(thread_options)); }
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index cf6da2df3..a237b48 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -7841,7 +7841,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -7860,7 +7860,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -7879,7 +7879,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -7898,7 +7898,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -7917,7 +7917,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -7936,7 +7936,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -7955,7 +7955,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -7974,7 +7974,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -7993,7 +7993,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8012,7 +8012,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8031,7 +8031,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8050,7 +8050,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8070,7 +8070,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8089,7 +8089,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8108,7 +8108,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8127,7 +8127,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 25 @@ -8149,7 +8149,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 30 @@ -8172,7 +8172,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8191,7 +8191,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8211,7 +8211,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8230,7 +8230,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8249,7 +8249,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8268,7 +8268,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8287,7 +8287,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8306,7 +8306,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8325,7 +8325,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8344,7 +8344,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8363,7 +8363,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8382,7 +8382,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8401,7 +8401,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 6 @@ -8423,7 +8423,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 2 @@ -8446,7 +8446,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8465,7 +8465,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 2 @@ -8487,7 +8487,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8506,7 +8506,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8525,7 +8525,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8544,7 +8544,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8563,7 +8563,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8582,7 +8582,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8601,7 +8601,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8620,7 +8620,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8639,7 +8639,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8658,7 +8658,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8677,7 +8677,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8696,7 +8696,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8715,7 +8715,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8734,7 +8734,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8753,7 +8753,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8772,7 +8772,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 5 @@ -8795,7 +8795,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8814,7 +8814,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8833,7 +8833,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8852,7 +8852,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8871,7 +8871,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8890,7 +8890,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8909,7 +8909,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8928,7 +8928,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8947,7 +8947,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8966,7 +8966,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -8985,7 +8985,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9004,7 +9004,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9023,7 +9023,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9042,7 +9042,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9061,7 +9061,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9080,7 +9080,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9099,7 +9099,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9118,7 +9118,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 2 @@ -9139,7 +9139,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9158,7 +9158,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9177,7 +9177,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9196,7 +9196,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9215,7 +9215,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9234,7 +9234,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9253,7 +9253,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9272,7 +9272,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9291,7 +9291,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9310,7 +9310,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9329,7 +9329,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9348,7 +9348,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9367,7 +9367,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9386,7 +9386,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9405,7 +9405,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9424,7 +9424,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9443,7 +9443,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9462,7 +9462,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9481,7 +9481,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9500,7 +9500,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9519,7 +9519,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 2 @@ -9539,7 +9539,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9559,7 +9559,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9578,7 +9578,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9597,7 +9597,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9616,7 +9616,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9635,7 +9635,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -9654,7 +9654,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 9e89d9c..d5f424d9 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -3699,7 +3699,7 @@ }, 'Linux ChromiumOS MSan Tests': { 'mixins': [ - 'linux-trusty', + 'linux-xenial', 'x86-64', ], 'test_suites': {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index f14047aea..9ec2b983 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -3533,7 +3533,6 @@ "enable_features": [ "OmniboxDisplayTitleForCurrentUrl", "OmniboxDocumentProvider", - "OmniboxGroupSuggestionsBySearchVsUrl", "OmniboxLocalEntitySuggestions", "OmniboxRichEntitySuggestions", "OmniboxTailSuggestions", @@ -5274,6 +5273,21 @@ ] } ], + "TabGroupsUiImprovementsAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TabGroupsUiImprovementsAndroid" + ] + } + ] + } + ], "TabGroupsYourTabsTogether": [ { "platforms": [
diff --git a/third_party/blink/common/loader/url_loader_throttle.cc b/third_party/blink/common/loader/url_loader_throttle.cc index 08e45c4..c777b961 100644 --- a/third_party/blink/common/loader/url_loader_throttle.cc +++ b/third_party/blink/common/loader/url_loader_throttle.cc
@@ -28,6 +28,11 @@ NOTIMPLEMENTED(); } +void URLLoaderThrottle::Delegate::RestartWithURLResetAndFlags( + int additional_load_flags) { + NOTIMPLEMENTED(); +} + URLLoaderThrottle::Delegate::~Delegate() {} URLLoaderThrottle::~URLLoaderThrottle() {}
diff --git a/third_party/blink/public/common/feature_policy/feature_policy.h b/third_party/blink/public/common/feature_policy/feature_policy.h index 6e1e6fe..c0f89e7 100644 --- a/third_party/blink/public/common/feature_policy/feature_policy.h +++ b/third_party/blink/public/common/feature_policy/feature_policy.h
@@ -74,7 +74,7 @@ // // If the default policy is in effect for a frame, then it controls how the // feature is inherited by any cross-origin iframes embedded by the frame. (See -// the comments below in FeaturePolicy::DefaultPolicy for specifics) +// the comments below in FeaturePolicy::FeatureDefault for specifics) // // Policy Inheritance // ------------------ @@ -83,7 +83,7 @@ // receive the same set of enables features as the parent frame. Whether or not // features are inherited by cross-origin iframes without an explicit policy is // determined by the feature's default policy. (Again, see the comments in -// FeaturePolicy::DefaultPolicy for details) +// FeaturePolicy::FeatureDefault for details) // ListValue (PolicyValue) // ---------------------- @@ -180,6 +180,8 @@ // a feature when neither it nor any parent frame have declared an explicit // policy. The three possibilities map directly to Feature Policy Allowlist // semantics. + // + // The default values for each feature are set in GetDefaultFeatureList. enum class FeatureDefault { // Equivalent to []. If this default policy is in effect for a frame, then // the feature will not be enabled for that frame or any of its children.
diff --git a/third_party/blink/public/common/loader/url_loader_throttle.h b/third_party/blink/public/common/loader/url_loader_throttle.h index 1085dcd..abf57f15 100644 --- a/third_party/blink/public/common/loader/url_loader_throttle.h +++ b/third_party/blink/public/common/loader/url_loader_throttle.h
@@ -96,6 +96,26 @@ // restarted using a combined value of all of the |additional_load_flags|. virtual void RestartWithFlags(int additional_load_flags); + // Restarts the URL loader using |additional_load_flags| and the unmodified + // URL if it was changed in WillStartRequest(). + // + // If called on an URL loader that did not modify the URL in + // WillStartRequest(), this method has the same outcome as + // RestartWithFlags(). + // + // Restarting is only valid while executing within + // BeforeWillProcessResponse(), or during its deferred handling (before + // having called Resume()). + // + // When a URL loader is restarted, throttles will NOT have their + // WillStartRequest() method called again - that is only called for the + // initial request start. + // + // If multiple throttles call RestartWithFlags() and + // RestartWithURLResetAndFlags() then the URL loader will be restarted + // using a combined value of all of the |additional_load_flags|. + virtual void RestartWithURLResetAndFlags(int additional_load_flags); + protected: virtual ~Delegate(); };
diff --git a/third_party/blink/public/mojom/content_index/content_index.mojom b/third_party/blink/public/mojom/content_index/content_index.mojom index e5e10e7..ab23bb04 100644 --- a/third_party/blink/public/mojom/content_index/content_index.mojom +++ b/third_party/blink/public/mojom/content_index/content_index.mojom
@@ -19,7 +19,7 @@ STORAGE_ERROR, }; -// These values are persisted, do not change or create gaps. +// These values are persisted and recorded, do not change or create gaps. enum ContentCategory { // "homepage" HOME_PAGE = 1,
diff --git a/third_party/blink/public/mojom/native_file_system/native_file_system_file_handle.mojom b/third_party/blink/public/mojom/native_file_system/native_file_system_file_handle.mojom index a32eabe..de71c67 100644 --- a/third_party/blink/public/mojom/native_file_system/native_file_system_file_handle.mojom +++ b/third_party/blink/public/mojom/native_file_system/native_file_system_file_handle.mojom
@@ -24,10 +24,6 @@ // Returns a blob representing the current state of this file. AsBlob() => (NativeFileSystemError result, SerializedBlob? blob); - // Deletes this file. - // TODO(oyiptong): Remove this method. It isn't part of the spec anymore. - Remove() => (NativeFileSystemError result); - // Returns a FileWriter object. The FileWriter provides write operations on a file. CreateFileWriter() => (NativeFileSystemError result, NativeFileSystemFileWriter? writer);
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 36365960..7bcf3e9 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2362,6 +2362,9 @@ kV8RegExpMatchAllWithNonGlobalRegExp = 2980, kCSSValueOverflowXOverlay = 2981, kCSSValueOverflowYOverlay = 2982, + kContentIndexAdd = 2983, + kContentIndexDelete = 2984, + kContentIndexGet = 2985, // 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/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index 05d1654..c4ae387ef 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -880,12 +880,6 @@ virtual WebLocalFrameClient::AppCacheType GetAppCacheType() { return WebLocalFrameClient::AppCacheType::kAppCacheForNone; } - // TODO(https://crbug.com/982996): This is a stopgap implementation for - // removing DocumentLoader dependencies from shared workers. Remove this once - // it's done. - virtual base::UnguessableToken GetAppCacheHostIDForSharedWorker() { - return base::UnguessableToken(); - } }; } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/animation.h b/third_party/blink/renderer/core/animation/animation.h index 977874e..81d8973d4 100644 --- a/third_party/blink/renderer/core/animation/animation.h +++ b/third_party/blink/renderer/core/animation/animation.h
@@ -121,13 +121,8 @@ void setCurrentTime(double new_current_time, bool is_null, ExceptionState& = ASSERT_NO_EXCEPTION); - - double CurrentTimeInternal() const; double UnlimitedCurrentTimeInternal() const; - void SetCurrentTimeInternal(double new_current_time, - TimingUpdateReason = kTimingUpdateOnDemand); - bool Paused() const { return paused_ && !is_paused_for_testing_; } static const char* PlayStateString(AnimationPlayState); String playState() const { return PlayStateString(animation_play_state_); } @@ -143,15 +138,13 @@ ScriptPromise finished(ScriptState*); ScriptPromise ready(ScriptState*); - bool Playing() const override { - return !(PlayStateInternal() == kIdle || Limited() || paused_ || - is_paused_for_testing_); + bool Paused() const { + return GetPlayState() == kPaused && !is_paused_for_testing_; } - // TODO(crbug/960944): Deprecate. This version of the play state is not to - // spec due to the inclusion of a 'pending' state. Whether or not an animation - // is pending is separate from the actual play state. - AnimationPlayState PlayStateInternal() const; + bool Playing() const override { + return GetPlayState() == kRunning && !Limited() && !is_paused_for_testing_; + } // Indicates if the animation is out of sync with the compositor. A change to // the play state (running/paused) requires synchronization with the @@ -252,6 +245,15 @@ RegisteredEventListener&) override; private: + // TODO(crbug/960944): Deprecate. This version of the play state is not to + // spec due to the inclusion of a 'pending' state. Whether or not an animation + // is pending is separate from the actual play state. + AnimationPlayState PlayStateInternal() const; + + double CurrentTimeInternal() const; + void SetCurrentTimeInternal(double new_current_time, + TimingUpdateReason = kTimingUpdateOnDemand); + void ClearOutdated(); void ForceServiceOnNextFrame();
diff --git a/third_party/blink/renderer/core/animation/animation_test.cc b/third_party/blink/renderer/core/animation/animation_test.cc index a3a15ffe1..3d1e7bf3 100644 --- a/third_party/blink/renderer/core/animation/animation_test.cc +++ b/third_party/blink/renderer/core/animation/animation_test.cc
@@ -224,7 +224,7 @@ StartTimeline(); EXPECT_EQ("finished", animation->playState()); - EXPECT_EQ(0, timeline->CurrentTimeInternal()->InSecondsF()); + EXPECT_EQ(0, timeline->currentTime()); EXPECT_EQ(0, animation->currentTime()); EXPECT_FALSE(animation->Paused()); EXPECT_FALSE(animation->pending());
diff --git a/third_party/blink/renderer/core/animation/document_timeline_test.cc b/third_party/blink/renderer/core/animation/document_timeline_test.cc index 904b8d7..ca3fc53 100644 --- a/third_party/blink/renderer/core/animation/document_timeline_test.cc +++ b/third_party/blink/renderer/core/animation/document_timeline_test.cc
@@ -44,9 +44,12 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" +// NaN has the special property that NaN != NaN. +#define EXPECT_NAN(x) EXPECT_NE(x, x) + namespace { -base::TimeTicks TimeTicksFromSecondsD(double seconds) { - return base::TimeTicks() + base::TimeDelta::FromSecondsD(seconds); +base::TimeTicks TimeTicksFromMillisecondsD(double seconds) { + return base::TimeTicks() + base::TimeDelta::FromMillisecondsD(seconds); } } // namespace @@ -74,7 +77,7 @@ timeline->SetTimingForTesting(platform_timing); timeline->ResetForTesting(); - ASSERT_EQ(base::TimeDelta(), timeline->CurrentTimeInternal().value()); + ASSERT_EQ(0, timeline->currentTime()); } void TearDown() override { @@ -84,8 +87,8 @@ ThreadState::Current()->CollectAllGarbageForTesting(); } - void UpdateClockAndService(double time) { - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(time)); + void UpdateClockAndService(double time_ms) { + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(time_ms)); GetPendingAnimations().Update(nullptr, false); timeline->ServiceAnimations(kTimingUpdateForAnimationFrame); timeline->ScheduleNextService(); @@ -134,12 +137,11 @@ timeline->Play(keyframe_effect); UpdateClockAndService(0); - EXPECT_EQ(base::TimeDelta(), timeline->CurrentTimeInternal().value()); + EXPECT_FLOAT_EQ(0, timeline->currentTime()); EXPECT_FALSE(keyframe_effect->IsInEffect()); - UpdateClockAndService(100); - EXPECT_EQ(base::TimeDelta::FromSeconds(100), - timeline->CurrentTimeInternal().value()); + UpdateClockAndService(1000); + EXPECT_FLOAT_EQ(1000, timeline->currentTime()); } TEST_F(AnimationDocumentTimelineTest, EmptyForwardsKeyframeAnimation) { @@ -152,38 +154,37 @@ timeline->Play(keyframe_effect); UpdateClockAndService(0); - EXPECT_EQ(base::TimeDelta(), timeline->CurrentTimeInternal()); + EXPECT_EQ(0, timeline->currentTime()); EXPECT_TRUE(keyframe_effect->IsInEffect()); - UpdateClockAndService(100); - EXPECT_EQ(base::TimeDelta::FromSeconds(100), - timeline->CurrentTimeInternal().value()); + UpdateClockAndService(1000); + EXPECT_FLOAT_EQ(1000, timeline->currentTime()); } TEST_F(AnimationDocumentTimelineTest, ZeroTime) { - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(100)); - EXPECT_EQ(base::Optional<base::TimeDelta>(base::TimeDelta::FromSeconds(100)), - timeline->CurrentTimeInternal()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(1000)); + EXPECT_EQ(1000, timeline->currentTime()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(200)); - EXPECT_EQ(base::TimeDelta::FromSeconds(200), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(2000)); + EXPECT_EQ(2000, timeline->currentTime()); } -// EffectiveTime is identical to CurrentTimeInternal except that it returns 0 +// EffectiveTime is identical to currentTime/1000 except that it returns 0 // when the timeline is inactive. TEST_F(AnimationDocumentTimelineTest, EffectiveTime) { - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(200)); - EXPECT_EQ(200, timeline->EffectiveTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(200), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(2000)); + EXPECT_EQ(2, timeline->EffectiveTime()); + EXPECT_EQ(2000, timeline->currentTime()); auto* document_without_frame = MakeGarbageCollected<Document>(); DocumentTimeline* inactive_timeline = DocumentTimeline::Create( document_without_frame, base::TimeDelta(), platform_timing); EXPECT_EQ(0, inactive_timeline->EffectiveTime()); - EXPECT_EQ(base::nullopt, inactive_timeline->CurrentTimeInternal()); + EXPECT_NAN(inactive_timeline->currentTime()); + bool is_null = false; + inactive_timeline->currentTime(is_null); + EXPECT_TRUE(is_null); } TEST_F(AnimationDocumentTimelineTest, PlaybackRateNormal) { @@ -191,134 +192,114 @@ timeline->SetPlaybackRate(1.0); EXPECT_EQ(1.0, timeline->PlaybackRate()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(100)); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(1000)); EXPECT_EQ(zero_time, timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(100), - timeline->CurrentTimeInternal().value()); + EXPECT_EQ(1000, timeline->currentTime()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(200)); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(2000)); EXPECT_EQ(zero_time, timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(200), - timeline->CurrentTimeInternal().value()); + EXPECT_EQ(2000, timeline->currentTime()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRateNormalWithOriginTime) { - base::TimeDelta origin_time = base::TimeDelta::FromSeconds(-1000); + base::TimeDelta origin_time = base::TimeDelta::FromMilliseconds(-1000); timeline = DocumentTimeline::Create(document.Get(), origin_time, platform_timing); timeline->ResetForTesting(); EXPECT_EQ(1.0, timeline->PlaybackRate()); EXPECT_EQ(base::TimeTicks() + origin_time, timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1000), - timeline->CurrentTimeInternal().value()); + EXPECT_EQ(1000, timeline->currentTime()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(100)); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(100)); EXPECT_EQ(base::TimeTicks() + origin_time, timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1100), - timeline->CurrentTimeInternal().value()); + EXPECT_EQ(1100, timeline->currentTime()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(200)); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(200)); EXPECT_EQ(base::TimeTicks() + origin_time, timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1200), - timeline->CurrentTimeInternal().value()); + EXPECT_EQ(1200, timeline->currentTime()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRatePause) { - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(100)); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(1000)); EXPECT_EQ(base::TimeTicks(), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(100), - timeline->CurrentTimeInternal().value()); + EXPECT_EQ(1000, timeline->currentTime()); timeline->SetPlaybackRate(0.0); EXPECT_EQ(0.0, timeline->PlaybackRate()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(200)); - EXPECT_EQ(TimeTicksFromSecondsD(100), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(100), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(2000)); + EXPECT_EQ(TimeTicksFromMillisecondsD(1000), timeline->ZeroTime()); + EXPECT_EQ(1000, timeline->currentTime()); timeline->SetPlaybackRate(1.0); EXPECT_EQ(1.0, timeline->PlaybackRate()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(400)); - EXPECT_EQ(TimeTicksFromSecondsD(100), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(300), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(4000)); + EXPECT_EQ(TimeTicksFromMillisecondsD(1000), timeline->ZeroTime()); + EXPECT_EQ(3000, timeline->currentTime()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRatePauseWithOriginTime) { - base::TimeDelta origin_time = base::TimeDelta::FromSeconds(-1000); + base::TimeDelta origin_time = base::TimeDelta::FromMilliseconds(-1000); timeline = DocumentTimeline::Create(document.Get(), origin_time, platform_timing); timeline->ResetForTesting(); EXPECT_EQ(base::TimeTicks() + origin_time, timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1000), - timeline->CurrentTimeInternal().value()); - - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(100)); + EXPECT_EQ(1000, timeline->currentTime()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(100)); EXPECT_EQ(base::TimeTicks() + origin_time, timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1100), - timeline->CurrentTimeInternal().value()); + EXPECT_EQ(1100, timeline->currentTime()); timeline->SetPlaybackRate(0.0); EXPECT_EQ(0.0, timeline->PlaybackRate()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(200)); - EXPECT_EQ(TimeTicksFromSecondsD(1100), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1100), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(200)); + EXPECT_EQ(TimeTicksFromMillisecondsD(1100), timeline->ZeroTime()); + EXPECT_EQ(1100, timeline->currentTime()); timeline->SetPlaybackRate(1.0); EXPECT_EQ(1.0, timeline->PlaybackRate()); - EXPECT_EQ(TimeTicksFromSecondsD(-900), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1100), - timeline->CurrentTimeInternal().value()); + EXPECT_EQ(TimeTicksFromMillisecondsD(-900), timeline->ZeroTime()); + EXPECT_EQ(1100, timeline->currentTime()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(400)); - EXPECT_EQ(TimeTicksFromSecondsD(-900), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1300), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(400)); + EXPECT_EQ(TimeTicksFromMillisecondsD(-900), timeline->ZeroTime()); + EXPECT_EQ(1300, timeline->currentTime()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRateSlow) { - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(100)); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(1000)); EXPECT_EQ(base::TimeTicks(), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(100), - timeline->CurrentTimeInternal().value()); + EXPECT_EQ(1000, timeline->currentTime()); timeline->SetPlaybackRate(0.5); EXPECT_EQ(0.5, timeline->PlaybackRate()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(300)); - EXPECT_EQ(TimeTicksFromSecondsD(-100), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(200), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(3000)); + EXPECT_EQ(TimeTicksFromMillisecondsD(-1000), timeline->ZeroTime()); + EXPECT_EQ(2000, timeline->currentTime()); timeline->SetPlaybackRate(1.0); EXPECT_EQ(1.0, timeline->PlaybackRate()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(400)); - EXPECT_EQ(TimeTicksFromSecondsD(100), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(300), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(4000)); + EXPECT_EQ(TimeTicksFromMillisecondsD(1000), timeline->ZeroTime()); + EXPECT_EQ(3000, timeline->currentTime()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRateFast) { - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(100)); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(1000)); EXPECT_EQ(base::TimeTicks(), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(100), - timeline->CurrentTimeInternal().value()); + EXPECT_EQ(1000, timeline->currentTime()); timeline->SetPlaybackRate(2.0); EXPECT_EQ(2.0, timeline->PlaybackRate()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(300)); - EXPECT_EQ(TimeTicksFromSecondsD(50), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(500), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(3000)); + EXPECT_EQ(TimeTicksFromMillisecondsD(500), timeline->ZeroTime()); + EXPECT_EQ(5000, timeline->currentTime()); timeline->SetPlaybackRate(1.0); EXPECT_EQ(1.0, timeline->PlaybackRate()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(400)); - EXPECT_EQ(TimeTicksFromSecondsD(-200), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(600), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(4000)); + EXPECT_EQ(TimeTicksFromMillisecondsD(-2000), timeline->ZeroTime()); + EXPECT_EQ(6000, timeline->currentTime()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRateFastWithOriginTime) { @@ -326,32 +307,27 @@ document.Get(), base::TimeDelta::FromSeconds(-1000), platform_timing); timeline->ResetForTesting(); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(100)); - EXPECT_EQ(TimeTicksFromSecondsD(-1000), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1100), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(100000)); + EXPECT_EQ(TimeTicksFromMillisecondsD(-1000000), timeline->ZeroTime()); + EXPECT_EQ(1100000, timeline->currentTime()); timeline->SetPlaybackRate(2.0); EXPECT_EQ(2.0, timeline->PlaybackRate()); - EXPECT_EQ(TimeTicksFromSecondsD(-450), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1100), - timeline->CurrentTimeInternal().value()); + EXPECT_EQ(TimeTicksFromMillisecondsD(-450000), timeline->ZeroTime()); + EXPECT_EQ(1100000, timeline->currentTime()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(300)); - EXPECT_EQ(TimeTicksFromSecondsD(-450), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1500), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(300000)); + EXPECT_EQ(TimeTicksFromMillisecondsD(-450000), timeline->ZeroTime()); + EXPECT_EQ(1500000, timeline->currentTime()); timeline->SetPlaybackRate(1.0); EXPECT_EQ(1.0, timeline->PlaybackRate()); - EXPECT_EQ(TimeTicksFromSecondsD(-1200), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1500), - timeline->CurrentTimeInternal().value()); + EXPECT_EQ(TimeTicksFromMillisecondsD(-1200000), timeline->ZeroTime()); + EXPECT_EQ(1500000, timeline->currentTime()); - GetAnimationClock().UpdateTime(TimeTicksFromSecondsD(400)); - EXPECT_EQ(TimeTicksFromSecondsD(-1200), timeline->ZeroTime()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1600), - timeline->CurrentTimeInternal().value()); + GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(400000)); + EXPECT_EQ(TimeTicksFromMillisecondsD(-1200000), timeline->ZeroTime()); + EXPECT_EQ(1600000, timeline->currentTime()); } TEST_F(AnimationDocumentTimelineTest, PauseForTesting) { @@ -365,8 +341,8 @@ Animation* animation2 = timeline->Play(anim2); timeline->PauseAnimationsForTesting(seek_time); - EXPECT_FLOAT_EQ(seek_time, animation1->CurrentTimeInternal()); - EXPECT_FLOAT_EQ(seek_time, animation2->CurrentTimeInternal()); + EXPECT_FLOAT_EQ(seek_time * 1000, animation1->currentTime()); + EXPECT_FLOAT_EQ(seek_time * 1000, animation2->currentTime()); } TEST_F(AnimationDocumentTimelineTest, DelayBeforeAnimationStart) { @@ -385,13 +361,13 @@ EXPECT_CALL(*platform_timing, WakeAfter(timing.start_delay - MinimumDelay() - 1.5)); - UpdateClockAndService(1.5); + UpdateClockAndService(1500); EXPECT_CALL(*platform_timing, ServiceOnNextFrame()); Wake(); EXPECT_CALL(*platform_timing, ServiceOnNextFrame()); - UpdateClockAndService(4.98); + UpdateClockAndService(4980); } TEST_F(AnimationDocumentTimelineTest, UseAnimationAfterTimelineDeref) {
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect_test.cc b/third_party/blink/renderer/core/animation/keyframe_effect_test.cc index 7545f7e9..fbefcf7 100644 --- a/third_party/blink/renderer/core/animation/keyframe_effect_test.cc +++ b/third_party/blink/renderer/core/animation/keyframe_effect_test.cc
@@ -376,22 +376,22 @@ EXPECT_EQ(inf, keyframe_effect->TimeToReverseEffectChange()); // End of the before phase. - animation->SetCurrentTimeInternal(100); + animation->setCurrentTime(100000, false); EXPECT_EQ(100, keyframe_effect->TimeToForwardsEffectChange()); EXPECT_EQ(0, keyframe_effect->TimeToReverseEffectChange()); // Nearing the end of the active phase. - animation->SetCurrentTimeInternal(199); + animation->setCurrentTime(199000, false); EXPECT_EQ(1, keyframe_effect->TimeToForwardsEffectChange()); EXPECT_EQ(0, keyframe_effect->TimeToReverseEffectChange()); // End of the active phase. - animation->SetCurrentTimeInternal(200); + animation->setCurrentTime(200000, false); EXPECT_EQ(100, keyframe_effect->TimeToForwardsEffectChange()); EXPECT_EQ(0, keyframe_effect->TimeToReverseEffectChange()); // End of the animation. - animation->SetCurrentTimeInternal(300); + animation->setCurrentTime(300000, false); EXPECT_EQ(inf, keyframe_effect->TimeToForwardsEffectChange()); EXPECT_EQ(100, keyframe_effect->TimeToReverseEffectChange()); }
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index e689a6b..d3aa1838 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -1270,12 +1270,6 @@ return web_frame_->Client()->GetAppCacheType(); } -base::UnguessableToken -LocalFrameClientImpl::GetAppCacheHostIDForSharedWorker() { - DCHECK(web_frame_->Client()); - return web_frame_->Client()->GetAppCacheHostIDForSharedWorker(); -} - STATIC_ASSERT_ENUM(DownloadCrossOriginRedirects::kFollow, WebLocalFrameClient::CrossOriginRedirects::kFollow); STATIC_ASSERT_ENUM(DownloadCrossOriginRedirects::kNavigate,
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h index 4b9d8bc..cab736e 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -329,7 +329,6 @@ void UpdateSubresourceFactory( std::unique_ptr<blink::URLLoaderFactoryBundleInfo> info) override; WebLocalFrameClient::AppCacheType GetAppCacheType() override; - base::UnguessableToken GetAppCacheHostIDForSharedWorker() override; private: struct DocumentInterfaceBrokerForwarderTraits {
diff --git a/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc b/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc index 2902b156..ccb3bd5 100644 --- a/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc +++ b/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
@@ -225,8 +225,6 @@ shadow_page_ = std::make_unique<WorkerShadowPage>( this, std::move(loader_factory), std::move(privacy_preferences), appcache_host_id_); - // TODO(https://crbug.com/982996): Create ApplicationCacheHostForSharedWorker - // here without depending on WorkerShadowPage and DocumentLoader. // If we were asked to pause worker context on start and wait for debugger // then now is a good time to do that.
diff --git a/third_party/blink/renderer/core/exported/worker_shadow_page.cc b/third_party/blink/renderer/core/exported/worker_shadow_page.cc index d7368d4..6b8a4b07 100644 --- a/third_party/blink/renderer/core/exported/worker_shadow_page.cc +++ b/third_party/blink/renderer/core/exported/worker_shadow_page.cc
@@ -70,6 +70,7 @@ std::unique_ptr<WebNavigationParams> params = WebNavigationParams::CreateWithHTMLBuffer( SharedBuffer::Create(content.c_str(), content.length()), script_url); + params->appcache_host_id = appcache_host_id_; main_frame_->GetFrame()->Loader().CommitNavigation(std::move(params), nullptr /* extra_data */); }
diff --git a/third_party/blink/renderer/core/exported/worker_shadow_page.h b/third_party/blink/renderer/core/exported/worker_shadow_page.h index c5bc16a..79c26c4 100644 --- a/third_party/blink/renderer/core/exported/worker_shadow_page.h +++ b/third_party/blink/renderer/core/exported/worker_shadow_page.h
@@ -75,9 +75,6 @@ WebLocalFrameClient::AppCacheType GetAppCacheType() override { return client_->GetAppCacheType(); } - base::UnguessableToken GetAppCacheHostIDForSharedWorker() override { - return appcache_host_id_; - } Document* GetDocument() { return main_frame_->GetFrame()->GetDocument(); } WebSettings* GetSettings() { return web_view_->GetSettings(); }
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h index b91f8681..f58f6a9 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -534,12 +534,6 @@ virtual WebLocalFrameClient::AppCacheType GetAppCacheType() { return WebLocalFrameClient::AppCacheType::kAppCacheForNone; } - // TODO(https://crbug.com/982996): This is a stopgap implementation for - // removing DocumentLoader dependencies from shared workers. Remove this once - // it's done. - virtual base::UnguessableToken GetAppCacheHostIDForSharedWorker() { - return base::UnguessableToken(); - } }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index aef6dd9..73fc77c 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -369,7 +369,7 @@ if (diff.TransformChanged()) { if (auto* coordinator = GetFrame()->GetPage()->GetScrollingCoordinator()) - coordinator->NotifyTransformChanged(GetFrame()); + coordinator->NotifyGeometryChanged(GetFrameView()); } // Update the script style map, from the new computed style.
diff --git a/third_party/blink/renderer/core/layout/layout_theme_win.cc b/third_party/blink/renderer/core/layout/layout_theme_win.cc index dd0f52d..c5dff3c9 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_win.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_win.cc
@@ -4,6 +4,10 @@ #include "third_party/blink/renderer/core/layout/layout_theme_win.h" +#include <windows.h> + +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" + namespace blink { scoped_refptr<LayoutTheme> LayoutThemeWin::Create() { @@ -15,4 +19,46 @@ return *layout_theme; } +Color LayoutThemeWin::SystemColor(CSSValueID css_value_id) const { + if (!RuntimeEnabledFeatures::UseWindowsSystemColorsEnabled()) { + return LayoutThemeDefault::SystemColor(css_value_id); + } + + int system_index; + + switch (css_value_id) { + case CSSValueID::kButtonface: + system_index = COLOR_BTNFACE; + break; + case CSSValueID::kButtontext: + system_index = COLOR_BTNTEXT; + break; + case CSSValueID::kGraytext: + system_index = COLOR_GRAYTEXT; + break; + case CSSValueID::kHighlight: + system_index = COLOR_HIGHLIGHT; + break; + case CSSValueID::kHighlighttext: + system_index = COLOR_HIGHLIGHTTEXT; + break; + case CSSValueID::kWindow: + system_index = COLOR_WINDOW; + break; + case CSSValueID::kWindowtext: + system_index = COLOR_WINDOWTEXT; + break; + default: + return LayoutThemeDefault::SystemColor(css_value_id); + } + + return SystemColorBySystemIndex(system_index); +} + +Color LayoutThemeWin::SystemColorBySystemIndex(int system_index) { + DWORD system_color = ::GetSysColor(system_index); + return Color(GetRValue(system_color), GetGValue(system_color), + GetBValue(system_color)); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_theme_win.h b/third_party/blink/renderer/core/layout/layout_theme_win.h index b26f21c..4b772ba 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_win.h +++ b/third_party/blink/renderer/core/layout/layout_theme_win.h
@@ -12,6 +12,11 @@ class LayoutThemeWin final : public LayoutThemeDefault { public: static scoped_refptr<LayoutTheme> Create(); + + Color SystemColor(CSSValueID css_value_id) const override; + + private: + static Color SystemColorBySystemIndex(int system_index); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc index 76ed37b9..25f9134 100644 --- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc +++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc
@@ -120,18 +120,19 @@ // always intersects. bool Intersects(const NGExclusionSpaceInternal::NGShelf& shelf, const NGBfcOffset& offset, - const LayoutUnit inline_size) { + const LayoutUnit inline_size, + bool is_inline_level) { if (shelf.line_right >= offset.line_offset && shelf.line_left <= offset.line_offset + inline_size) return true; + // Negative available space creates a zero-width opportunity at the inline-end // of the shelf. Consider such shelf intersects. - // TODO(kojii): This is correct to find layout opportunities for zero-width - // in-flow inline or block objects (e.g., <br>,) but not correct for - // zero-width floats. - if (UNLIKELY(shelf.line_left > offset.line_offset || - shelf.line_right < offset.line_offset + inline_size)) + if (UNLIKELY(is_inline_level && + (shelf.line_left > offset.line_offset || + shelf.line_right < offset.line_offset + inline_size))) return true; + return false; } @@ -162,8 +163,9 @@ NGLayoutOpportunity CreateLayoutOpportunity( const NGExclusionSpaceInternal::NGShelf& shelf, const NGBfcOffset& offset, - const LayoutUnit inline_size) { - DCHECK(Intersects(shelf, offset, inline_size)); + const LayoutUnit inline_size, + bool is_inline_level) { + DCHECK(Intersects(shelf, offset, inline_size, is_inline_level)); NGBfcOffset start_offset(std::max(shelf.line_left, offset.line_offset), std::max(shelf.block_offset, offset.block_offset)); @@ -550,7 +552,7 @@ NGLayoutOpportunity return_opportunity; IterateAllLayoutOpportunities( - offset, available_inline_size, + offset, available_inline_size, false /* is_inline_level */, [&return_opportunity, &minimum_size, &available_inline_size](const NGLayoutOpportunity opportunity) -> bool { // Determine if this opportunity will fit the given size. @@ -577,8 +579,9 @@ const LayoutUnit available_inline_size) const { LayoutOpportunityVector opportunities; + // This method is only used for determining the position of line-boxes. IterateAllLayoutOpportunities( - offset, available_inline_size, + offset, available_inline_size, true /* is_inline_level */, [&opportunities](const NGLayoutOpportunity opportunity) -> bool { opportunities.push_back(std::move(opportunity)); return false; @@ -591,6 +594,7 @@ void NGExclusionSpaceInternal::DerivedGeometry::IterateAllLayoutOpportunities( const NGBfcOffset& offset, const LayoutUnit available_inline_size, + bool is_inline_level, const LambdaFunc& lambda) const { auto* shelves_it = shelves_.begin(); auto* areas_it = areas_.begin(); @@ -604,7 +608,7 @@ DCHECK_NE(shelves_it, shelves_end); const NGShelf& shelf = *shelves_it; - if (!Intersects(shelf, offset, available_inline_size)) { + if (!Intersects(shelf, offset, available_inline_size, is_inline_level)) { ++shelves_it; continue; } @@ -649,7 +653,8 @@ HasSolidEdges(shelf.line_right_edges, offset.block_offset, LayoutUnit::Max()); if (has_solid_edges) { - if (lambda(CreateLayoutOpportunity(shelf, offset, available_inline_size))) + if (lambda(CreateLayoutOpportunity(shelf, offset, available_inline_size, + is_inline_level))) return; } ++shelves_it;
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h index 142c04c..5adea8b 100644 --- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h +++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
@@ -360,6 +360,7 @@ template <typename LambdaFunc> void IterateAllLayoutOpportunities(const NGBfcOffset& offset, const LayoutUnit available_inline_size, + bool is_inline_level, const LambdaFunc&) const; // See |NGShelf| for a broad description of what shelves are. We always
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc index 94c4a325..5ecc148 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
@@ -126,6 +126,38 @@ EXPECT_EQ(line1.Children()[0]->GetLayoutObject(), ellipsis.GetLayoutObject()); } +TEST_F(NGInlineLayoutAlgorithmTest, EllipsisInlineBoxOnly) { + LoadAhem(); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <style> + html, body { margin: 0; } + #container { + font: 10px/1 Ahem; + width: 5ch; + overflow: hidden; + text-overflow: ellipsis; + } + span { + border: solid 10ch blue; + } + </style> + <div id=container><span></span></div> + )HTML"); + scoped_refptr<const NGPhysicalBoxFragment> block = + GetBoxFragmentByElementId("container"); + EXPECT_EQ(1u, block->Children().size()); + const auto& line1 = + To<NGPhysicalLineBoxFragment>(*block->Children()[0].get()); + + // There should not be ellipsis in this line. + for (const auto& child : line1.Children()) { + if (const auto* text = DynamicTo<NGPhysicalTextFragment>(child.get())) { + EXPECT_FALSE(text->IsEllipsis()); + } + } +} + // This test ensures box fragments are generated when necessary, even when the // line is empty. One such case is when the line contains a containing box of an // out-of-flow object.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc index 836de6a..ddadc09 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
@@ -97,7 +97,9 @@ // Create the ellipsis, associating it with the ellipsized child. LayoutObject* ellipsized_layout_object = ellpisized_child->PhysicalFragment()->GetMutableLayoutObject(); - DCHECK(ellipsized_layout_object && ellipsized_layout_object->IsInline()); + DCHECK(ellipsized_layout_object && ellipsized_layout_object->IsInline() && + (ellipsized_layout_object->IsText() || + ellipsized_layout_object->IsAtomicInlineLevel())); NGTextFragmentBuilder builder(line_style_->GetWritingMode()); builder.SetText(ellipsized_layout_object, ellipsis_text, ellipsis_style, true /* is_ellipsis_style */, @@ -171,6 +173,12 @@ if (!child->HasInFlowFragment()) return false; + // Inline boxes should not be ellipsized. Usually they will be created in the + // later phase, but empty inline box are already created. + if (child->layout_result && + child->layout_result->PhysicalFragment().IsInlineBox()) + return false; + // Can't place ellipsis if this child is completely outside of the box. LayoutUnit child_inline_offset = IsLtr(line_direction_)
diff --git a/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc b/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc index 2800106..e3fb56a3 100644 --- a/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc +++ b/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc
@@ -41,6 +41,7 @@ #include "third_party/blink/renderer/core/frame/hosts_using_features.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" +#include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/inspector/inspector_application_cache_agent.h" #include "third_party/blink/renderer/core/loader/appcache/application_cache.h" #include "third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.h" @@ -69,9 +70,6 @@ } // namespace -// TODO(https://crbug.com/982996): Remove this creation function, and instead -// directly create an appcache host for frame in DocumentLoader, and for shared -// workers in WebSharedWorkerImpl. ApplicationCacheHost* ApplicationCacheHost::Create( DocumentLoader* document_loader) { DCHECK(document_loader); @@ -88,26 +86,53 @@ local_frame->GetTaskRunner(TaskType::kNetworking)); case WebLocalFrameClient::AppCacheType::kAppCacheForSharedWorker: return MakeGarbageCollected<ApplicationCacheHostForSharedWorker>( - local_frame->Client()->GetAppCacheHostIDForSharedWorker(), - Thread::Current()->GetTaskRunner()); + document_loader, Thread::Current()->GetTaskRunner()); default: - return MakeGarbageCollected<ApplicationCacheHost>( - /*interface_broker=*/nullptr, /*task_runner=*/nullptr); + return MakeGarbageCollected<ApplicationCacheHost>(document_loader, + nullptr, nullptr); } return nullptr; } +// We provide a custom implementation of this class that calls out to the +// embedding application instead of using WebCore's built in appcache system. +// This file replaces webcore/appcache/ApplicationCacheHost.cpp in our build. + ApplicationCacheHost::ApplicationCacheHost( + DocumentLoader* document_loader, mojom::blink::DocumentInterfaceBroker* interface_broker, scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : task_runner_(std::move(task_runner)), + : document_loader_(document_loader), + task_runner_(std::move(task_runner)), interface_broker_(interface_broker) {} ApplicationCacheHost::~ApplicationCacheHost() = default; -void ApplicationCacheHost::Detach() { +void ApplicationCacheHost::WillStartLoading(ResourceRequest& request) { + if (!IsApplicationCacheEnabled() || !backend_host_.is_bound()) + return; + const base::UnguessableToken& host_id = GetHostID(); + if (!host_id.is_empty()) + request.SetAppCacheHostID(host_id); +} + +void ApplicationCacheHost::WillStartLoadingMainResource(DocumentLoader* loader, + const KURL& url, + const String& method) { + if (!IsApplicationCacheEnabled()) + return; + + // We defer binding to backend to avoid unnecessary binding around creating + // empty documents. At this point, we're initiating a main resource load for + // the document, so its for real. + BindBackend(); +} + +void ApplicationCacheHost::DetachFromDocumentLoader() { + // Detach from the owning DocumentLoader and close mojo pipes. receiver_.reset(); backend_host_.reset(); + document_loader_ = nullptr; } ApplicationCacheHost::CacheInfo ApplicationCacheHost::ApplicationCacheInfo() { @@ -125,11 +150,6 @@ return host_id_; } -void ApplicationCacheHost::SetHostID(const base::UnguessableToken& host_id) { - DCHECK(!host_id.is_empty()); - host_id_ = host_id; -} - void ApplicationCacheHost::SelectCacheForSharedWorker( int64_t app_cache_id, base::OnceClosure completion_callback) { @@ -165,6 +185,14 @@ // This is not implemented intentionally. See https://crbug.com/175063 } +bool ApplicationCacheHost::IsApplicationCacheEnabled() { + DCHECK(document_loader_->GetFrame()); + return document_loader_->GetFrame()->GetSettings() && + document_loader_->GetFrame() + ->GetSettings() + ->GetOfflineWebApplicationCacheEnabled(); +} + void ApplicationCacheHost::CacheSelected(mojom::blink::AppCacheInfoPtr info) { if (!backend_host_.is_bound()) return; @@ -287,7 +315,11 @@ if (!task_runner_) return false; - DCHECK(!host_id_.is_empty()); + // PlzNavigate: The browser passes the ID to be used. + if (!document_loader_->AppcacheHostId().is_empty()) + host_id_ = document_loader_->AppcacheHostId(); + else + host_id_ = base::UnguessableToken::Create(); mojo::PendingRemote<mojom::blink::AppCacheFrontend> frontend_remote; receiver_.Bind(frontend_remote.InitWithNewPipeAndPassReceiver(), @@ -317,4 +349,8 @@ return true; } +void ApplicationCacheHost::Trace(blink::Visitor* visitor) { + visitor->Trace(document_loader_); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/loader/appcache/application_cache_host.h b/third_party/blink/renderer/core/loader/appcache/application_cache_host.h index 70cc19a..388dd740 100644 --- a/third_party/blink/renderer/core/loader/appcache/application_cache_host.h +++ b/third_party/blink/renderer/core/loader/appcache/application_cache_host.h
@@ -64,10 +64,11 @@ // |interface_broker| can be null for workers and |task_runner| is null for // kAppCacheForNone. explicit ApplicationCacheHost( + DocumentLoader* document_loader, mojom::blink::DocumentInterfaceBroker* interface_broker, scoped_refptr<base::SingleThreadTaskRunner> task_runner); ~ApplicationCacheHost() override; - virtual void Detach(); + virtual void DetachFromDocumentLoader(); struct CacheInfo { STACK_ALLOCATED(); @@ -91,6 +92,9 @@ int64_t padding_sizes_ = 0; }; + // Annotate request for ApplicationCache. + void WillStartLoading(ResourceRequest&); + mojom::blink::AppCacheStatus GetStatus() const; virtual bool Update() { return false; } virtual bool SwapCache() { return false; } @@ -102,10 +106,7 @@ void FillResourceList(Vector<mojom::blink::AppCacheResourceInfo>*); CacheInfo ApplicationCacheInfo(); - const base::UnguessableToken& GetHostID() const; - void SetHostID(const base::UnguessableToken& host_id); - void SelectCacheForSharedWorker(int64_t app_cache_id, base::OnceClosure completion_callback); @@ -121,23 +122,21 @@ void SetSubresourceFactory( network::mojom::blink::URLLoaderFactoryPtr url_loader_factory) override {} - virtual void WillStartLoading(ResourceRequest&) {} virtual void WillStartLoadingMainResource(DocumentLoader* loader, const KURL& url, - const String& method) {} + const String& method); virtual void SelectCacheWithoutManifest() {} virtual void SelectCacheWithManifest(const KURL& manifest_url) {} virtual void DidReceiveResponseForMainResource(const ResourceResponse&) {} - virtual void Trace(blink::Visitor*) {} + virtual void Trace(blink::Visitor*); protected: + DocumentLoader* GetDocumentLoader() const { return document_loader_; } + mojo::Remote<mojom::blink::AppCacheHost> backend_host_; mojom::blink::AppCacheStatus status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_UNCACHED; - // Non-empty |host_id_| must be set before calling this function. - bool BindBackend(); - private: virtual void NotifyApplicationCache(mojom::AppCacheEventID, int progress_total, @@ -148,6 +147,11 @@ const String& error_message) {} void GetAssociatedCacheInfo(CacheInfo* info); + bool IsApplicationCacheEnabled(); + bool BindBackend(); + + // TODO(https://crbug.com/982996): Move this to ApplicationCacheHostForFrame. + Member<DocumentLoader> document_loader_; mojo::Receiver<mojom::blink::AppCacheFrontend> receiver_{this}; base::UnguessableToken host_id_;
diff --git a/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.cc b/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.cc index a33b224..1d704ad 100644 --- a/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.cc +++ b/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.cc
@@ -10,10 +10,8 @@ #include "third_party/blink/renderer/core/events/application_cache_error_event.h" #include "third_party/blink/renderer/core/events/progress_event.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" -#include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/loader/appcache/application_cache.h" -#include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/platform/web_test_support.h" @@ -45,13 +43,13 @@ DocumentLoader* document_loader, mojom::blink::DocumentInterfaceBroker* interface_broker, scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : ApplicationCacheHost(interface_broker, std::move(task_runner)), - local_frame_(document_loader->GetFrame()), - document_loader_(document_loader) {} + : ApplicationCacheHost(document_loader, + interface_broker, + std::move(task_runner)), + local_frame_(document_loader->GetFrame()) {} -void ApplicationCacheHostForFrame::Detach() { - ApplicationCacheHost::Detach(); - document_loader_ = nullptr; +void ApplicationCacheHostForFrame::DetachFromDocumentLoader() { + ApplicationCacheHost::DetachFromDocumentLoader(); SetApplicationCache(nullptr); } @@ -82,7 +80,7 @@ if (!success) return false; backend_host_->GetStatus(&status_); - probe::UpdateApplicationCacheStatus(document_loader_->GetFrame()); + probe::UpdateApplicationCacheStatus(GetDocumentLoader()->GetFrame()); return true; } @@ -134,33 +132,14 @@ std::move(pending_factories)); } -void ApplicationCacheHostForFrame::WillStartLoading(ResourceRequest& request) { - if (!IsApplicationCacheEnabled() || !backend_host_.is_bound()) - return; - const base::UnguessableToken& host_id = GetHostID(); - if (!host_id.is_empty()) - request.SetAppCacheHostID(host_id); -} - void ApplicationCacheHostForFrame::WillStartLoadingMainResource( DocumentLoader* loader, const KURL& url, const String& method) { - if (!IsApplicationCacheEnabled()) + ApplicationCacheHost::WillStartLoadingMainResource(loader, url, method); + if (!backend_host_.is_bound()) return; - // PlzNavigate: The browser passes the ID to be used. - DCHECK(GetHostID().is_empty()); - if (!document_loader_->AppcacheHostId().is_empty()) - SetHostID(document_loader_->AppcacheHostId()); - else - SetHostID(base::UnguessableToken::Create()); - - // We defer binding to backend to avoid unnecessary binding around creating - // empty documents. At this point, we're initiating a main resource load for - // the document, so its for real. - BindBackend(); - original_main_resource_url_ = ClearUrlRef(url); is_get_method_ = (method == kHttpGETMethod); DCHECK(method == method.UpperASCII()); @@ -205,7 +184,7 @@ void ApplicationCacheHostForFrame::SelectCacheWithManifest( const KURL& manifest_url) { - LocalFrame* frame = document_loader_->GetFrame(); + LocalFrame* frame = GetDocumentLoader()->GetFrame(); Document* document = frame->GetDocument(); if (document->IsSandboxed(WebSandboxFlags::kOrigin)) { // Prevent sandboxes from establishing application caches. @@ -296,7 +275,6 @@ void ApplicationCacheHostForFrame::Trace(blink::Visitor* visitor) { visitor->Trace(dom_application_cache_); visitor->Trace(local_frame_); - visitor->Trace(document_loader_); ApplicationCacheHost::Trace(visitor); } @@ -309,7 +287,7 @@ int error_status, const String& error_message) { if (id != mojom::AppCacheEventID::APPCACHE_PROGRESS_EVENT) { - probe::UpdateApplicationCacheStatus(document_loader_->GetFrame()); + probe::UpdateApplicationCacheStatus(GetDocumentLoader()->GetFrame()); } if (defers_events_) { @@ -351,12 +329,4 @@ dom_application_cache_->DispatchEvent(*event); } -bool ApplicationCacheHostForFrame::IsApplicationCacheEnabled() { - DCHECK(document_loader_->GetFrame()); - return document_loader_->GetFrame()->GetSettings() && - document_loader_->GetFrame() - ->GetSettings() - ->GetOfflineWebApplicationCacheEnabled(); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.h b/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.h index 8d0b7aa..4c91f580 100644 --- a/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.h +++ b/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.h
@@ -20,7 +20,7 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner); // ApplicationCacheHost: - void Detach() override; + void DetachFromDocumentLoader() override; bool Update() override; bool SwapCache() override; void SetApplicationCache(ApplicationCache*) override; @@ -32,7 +32,6 @@ void SetSubresourceFactory( network::mojom::blink::URLLoaderFactoryPtr url_loader_factory) override; - void WillStartLoading(ResourceRequest&) override; void WillStartLoadingMainResource(DocumentLoader* loader, const KURL& url, const String& method) override; @@ -85,13 +84,9 @@ int error_status, const String& error_message); - bool IsApplicationCacheEnabled(); - WeakMember<ApplicationCache> dom_application_cache_ = nullptr; Member<LocalFrame> local_frame_; - Member<DocumentLoader> document_loader_; - bool is_get_method_ = false; bool was_select_cache_called_ = false; IsNewMasterEntry is_new_master_entry_ = MAYBE_NEW_ENTRY;
diff --git a/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_shared_worker.cc b/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_shared_worker.cc index 5d489323..e06e2f3 100644 --- a/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_shared_worker.cc +++ b/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_shared_worker.cc
@@ -7,14 +7,11 @@ namespace blink { ApplicationCacheHostForSharedWorker::ApplicationCacheHostForSharedWorker( - const base::UnguessableToken& appcache_host_id, + DocumentLoader* document_loader, scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : ApplicationCacheHost(nullptr, /* interface_broker */ - std::move(task_runner)) { - SetHostID(appcache_host_id ? appcache_host_id - : base::UnguessableToken::Create()); - BindBackend(); -} + : ApplicationCacheHost(document_loader, + nullptr, /* interface_broker */ + std::move(task_runner)) {} ApplicationCacheHostForSharedWorker::~ApplicationCacheHostForSharedWorker() = default;
diff --git a/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_shared_worker.h b/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_shared_worker.h index 968babb..67d34f8 100644 --- a/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_shared_worker.h +++ b/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_shared_worker.h
@@ -12,7 +12,7 @@ class ApplicationCacheHostForSharedWorker final : public ApplicationCacheHost { public: ApplicationCacheHostForSharedWorker( - const base::UnguessableToken& appcache_host_id, + DocumentLoader* document_loader, scoped_refptr<base::SingleThreadTaskRunner> task_runner); ~ApplicationCacheHostForSharedWorker() override;
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 0ff4a07..7133dc0 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1083,7 +1083,7 @@ return; if (application_cache_host_) { - application_cache_host_->Detach(); + application_cache_host_->DetachFromDocumentLoader(); application_cache_host_.Clear(); } service_worker_network_provider_ = nullptr;
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc index 69a5e32..fc700e6 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -94,6 +94,7 @@ void ScrollingCoordinator::SetShouldHandleScrollGestureOnMainThreadRegion( const Region& region, GraphicsLayer* layer) { + DCHECK(!RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()); if (cc::Layer* cc_layer = GraphicsLayerToCcLayer(layer)) cc_layer->SetNonFastScrollableRegion(RegionToCCRegion(region)); } @@ -104,14 +105,6 @@ frame_view->GetScrollingContext()->SetShouldScrollOnMainThreadIsDirty(true); } -void ScrollingCoordinator::NotifyTransformChanged(LocalFrame* frame) { - DCHECK(frame); - if (!frame->View()) - return; - - frame->View()->GetScrollingContext()->SetTouchEventTargetRectsAreDirty(true); -} - ScrollableArea* ScrollingCoordinator::ScrollableAreaWithElementIdInAllLocalFrames( const CompositorElementId& id) { @@ -167,33 +160,8 @@ LocalFrameUkmAggregator::kScrollingCoordinator); TRACE_EVENT0("input", "ScrollingCoordinator::UpdateAfterPaint"); - // TODO(pdr): Move the scroll gesture region logic to use touch action rects. - // These features are similar and do not need independent implementations. if (scroll_gesture_region_dirty) { - // Compute the regions of the page where we can't handle scroll gestures on - // the impl thread. This currently includes: - // 1. All scrollable areas, such as subframes, overflow divs and list boxes, - // whose composited scrolling are not enabled. We need to do this even if - // the frame view whose layout was updated is not the main frame. - // 2. Resize control areas, e.g. the small rect at the right bottom of - // div/textarea/iframe when CSS property "resize" is enabled. - // 3. Plugin areas. - Region main_thread_scrolling_region; - Region main_thread_fixed_region; - ComputeShouldHandleScrollGestureOnMainThreadRegion( - frame, &main_thread_scrolling_region, &main_thread_fixed_region); - - SetShouldHandleScrollGestureOnMainThreadRegion( - main_thread_scrolling_region, - frame_view->GetScrollableArea()->LayerForScrolling()); - - // Fixed regions will be stored on the visual viewport's scroll layer. This - // is because a region for an area that's fixed to the layout viewport - // won't move when the layout viewport scrolls. - SetShouldHandleScrollGestureOnMainThreadRegion( - main_thread_fixed_region, - page_->GetVisualViewport().LayerForScrolling()); - + UpdateNonFastScrollableRegions(frame); frame_view->GetScrollingContext()->SetScrollGestureRegionIsDirty(false); } @@ -252,6 +220,60 @@ ForAllPaintingGraphicsLayers(*child, function); } +// Set the non-fast scrollable regions on |layer|'s cc layer. +static void UpdateLayerNonFastScrollableRegions(GraphicsLayer& layer) { + DCHECK(RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()); + // CompositeAfterPaint does this update in PaintArtifactCompositor. + DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); + + DCHECK(layer.PaintsContentOrHitTest()); + + if (layer.Client().ShouldThrottleRendering()) { + layer.CcLayer()->SetNonFastScrollableRegion(cc::Region()); + return; + } + + auto offset = layer.GetOffsetFromTransformNode(); + gfx::Vector2dF layer_offset = gfx::Vector2dF(offset.X(), offset.Y()); + PaintChunkSubset paint_chunks = + PaintChunkSubset(layer.GetPaintController().PaintChunks()); + PaintArtifactCompositor::UpdateNonFastScrollableRegions( + layer.CcLayer(), layer_offset, layer.GetPropertyTreeState(), + paint_chunks); +} + +// Compute the regions of the page where we can't handle scroll gestures on +// the impl thread. This currently includes: +// 1. All scrollable areas, such as subframes, overflow divs and list boxes, +// whose composited scrolling are not enabled. We need to do this even if +// the frame view whose layout was updated is not the main frame. +// 2. Resize control areas, e.g. the small rect at the right bottom of +// div/textarea/iframe when CSS property "resize" is enabled. +// 3. Plugin areas. +void ScrollingCoordinator::UpdateNonFastScrollableRegions(LocalFrame* frame) { + if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) { + auto* view_layer = frame->View()->GetLayoutView()->Layer(); + if (auto* root = view_layer->Compositor()->PaintRootGraphicsLayer()) + ForAllPaintingGraphicsLayers(*root, UpdateLayerNonFastScrollableRegions); + } else { + Region main_thread_scrolling_region; + Region main_thread_fixed_region; + ComputeShouldHandleScrollGestureOnMainThreadRegion( + frame, &main_thread_scrolling_region, &main_thread_fixed_region); + + SetShouldHandleScrollGestureOnMainThreadRegion( + main_thread_scrolling_region, + frame->View()->GetScrollableArea()->LayerForScrolling()); + + // Fixed regions will be stored on the visual viewport's scroll layer. + // This is because a region for an area that's fixed to the layout + // viewport won't move when the layout viewport scrolls. + SetShouldHandleScrollGestureOnMainThreadRegion( + main_thread_fixed_region, + page_->GetVisualViewport().LayerForScrolling()); + } +} + // Set the touch action rects on the cc layer from the touch action data stored // on the GraphicsLayer's paint chunks. static void UpdateLayerTouchActionRects(GraphicsLayer& layer) { @@ -627,9 +649,7 @@ TRACE_EVENT0("input", "ScrollingCoordinator::updateTouchEventTargetRectsIfNeeded"); - // TODO(chrishtr): implement touch event target rects for CAP. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; + DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); auto* view_layer = frame->View()->GetLayoutView()->Layer(); if (auto* root = view_layer->Compositor()->PaintRootGraphicsLayer()) @@ -827,6 +847,8 @@ namespace { bool ScrollsWithRootFrame(LayoutObject* object) { + DCHECK(!RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()); + DCHECK(object); DCHECK(object->GetFrame()); @@ -866,6 +888,8 @@ const LocalFrame* frame, Region* scrolling_region, Region* fixed_region) const { + DCHECK(!RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()); + LocalFrameView* frame_view = frame->View(); DCHECK(scrolling_region); DCHECK(fixed_region);
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h index 4efb8fc..9b4c6427 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
@@ -98,8 +98,6 @@ // Called when any frame has done its layout or compositing has changed. void NotifyGeometryChanged(LocalFrameView*); - // Called when any transform has changed. - void NotifyTransformChanged(LocalFrame*); // Update non-fast scrollable regions, touch event target rects, main thread // scrolling reasons, and whether the visual viewport is user scrollable. @@ -164,6 +162,7 @@ Region* scrolling_region, Region* fixed_region) const; + void UpdateNonFastScrollableRegions(LocalFrame*); void UpdateTouchEventTargetRectsIfNeeded(LocalFrame*); void UpdateUserInputScrollable(ScrollableArea*);
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc index 26038093..f467e4b7 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
@@ -68,12 +68,28 @@ namespace blink { -class ScrollingCoordinatorTest : public testing::Test, - public testing::WithParamInterface<bool>, - private ScopedBlinkGenPropertyTreesForTest { +// kScrollingCoordinatorTestNoFlags runs with BlinkGenPropertyTrees and +// PaintNonFastScrollableRegions disabled. Using +// (kScrollingCoordinatorTestBlinkGenPropertyTrees | +// kScrollingCoordinatorTestPaintNonFastScrollableRegions) enables both. +enum { + kScrollingCoordinatorTestNoFlags = 1 << 0, + kScrollingCoordinatorTestBlinkGenPropertyTrees = 1 << 1, + kScrollingCoordinatorTestPaintNonFastScrollableRegions = 1 << 2, +}; + +class ScrollingCoordinatorTest + : public testing::Test, + public testing::WithParamInterface<unsigned>, + private ScopedBlinkGenPropertyTreesForTest, + private ScopedPaintNonFastScrollableRegionsForTest { public: ScrollingCoordinatorTest() - : ScopedBlinkGenPropertyTreesForTest(GetParam()), + : ScopedBlinkGenPropertyTreesForTest( + GetParam() & kScrollingCoordinatorTestBlinkGenPropertyTrees), + ScopedPaintNonFastScrollableRegionsForTest( + GetParam() & + kScrollingCoordinatorTestPaintNonFastScrollableRegions), base_url_("http://www.test.com/") { helper_.Initialize(nullptr, nullptr, nullptr, &ConfigureSettings); GetWebView()->MainFrameWidget()->Resize(IntSize(320, 240)); @@ -144,7 +160,15 @@ frame_test_helpers::WebViewHelper helper_; }; -INSTANTIATE_TEST_SUITE_P(All, ScrollingCoordinatorTest, testing::Bool()); +INSTANTIATE_TEST_SUITE_P( + All, + ScrollingCoordinatorTest, + ::testing::Values( + kScrollingCoordinatorTestNoFlags, + kScrollingCoordinatorTestBlinkGenPropertyTrees, + kScrollingCoordinatorTestPaintNonFastScrollableRegions, + (kScrollingCoordinatorTestBlinkGenPropertyTrees | + kScrollingCoordinatorTestPaintNonFastScrollableRegions))); TEST_P(ScrollingCoordinatorTest, fastScrollingByDefault) { GetWebView()->MainFrameWidget()->Resize(WebSize(800, 600)); @@ -1024,7 +1048,6 @@ // Ensure we don't crash when a plugin becomes a LayoutInline TEST_P(ScrollingCoordinatorTest, PluginBecomesLayoutInline) { - HistogramTester histogram_tester; LoadHTML(R"HTML( <style> body { @@ -1051,7 +1074,10 @@ // Ensure NonFastScrollableRegions are correctly generated for both fixed and // in-flow plugins that need them. TEST_P(ScrollingCoordinatorTest, NonFastScrollableRegionsForPlugins) { - HistogramTester histogram_tester; + // TODO(pdr): Paint non-fast scrollable regions for plugins. + if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) + return; + LoadHTML(R"HTML( <style> body { @@ -1101,6 +1127,42 @@ EXPECT_EQ(fixed.Rects().at(0), IntRect(0, 500, 200, 200)); } +TEST_P(ScrollingCoordinatorTest, NonFastScrollableRegionWithBorder) { + GetWebView()->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled( + false); + LoadHTML(R"HTML( + <!DOCTYPE html> + <style> + body { margin: 0; } + #scroller { + height: 100px; + width: 100px; + overflow-y: scroll; + border: 10px solid black; + } + </style> + <div id="scroller"> + <div id="forcescroll" style="height: 1000px;"></div> + </div> + )HTML"); + ForceFullCompositingUpdate(); + + // The non-fast scrollable regions are stored on different layers with and + // without PaintNonFastScrollableRegions. This test is only interested in + // the dimensions of the non-fast region generated. + cc::Layer* non_fast_layer = nullptr; + if (!RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) { + Page* page = GetFrame()->GetPage(); + non_fast_layer = page->GetVisualViewport().ScrollLayer()->CcLayer(); + } else { + non_fast_layer = + GetFrame()->View()->LayoutViewport()->LayerForScrolling()->CcLayer(); + } + + EXPECT_EQ(non_fast_layer->non_fast_scrollable_region().bounds(), + gfx::Rect(0, 0, 120, 120)); +} + TEST_P(ScrollingCoordinatorTest, overflowScrolling) { RegisterMockedHttpURLLoad("overflow-scrolling.html"); NavigateTo(base_url_ + "overflow-scrolling.html"); @@ -1415,20 +1477,30 @@ GetFrame()->GetDocument()->View()->GetScrollableArea()->SetScrollOffset( ScrollOffset(0, 1000), kProgrammaticScroll); - Region scrolling; - Region fixed; - Page* page = GetFrame()->GetPage(); - page->GetScrollingCoordinator() - ->ComputeShouldHandleScrollGestureOnMainThreadRegion( - To<LocalFrame>(page->MainFrame()), &scrolling, &fixed); + ForceFullCompositingUpdate(); - EXPECT_TRUE(fixed.IsEmpty()) << "Since the DIV will move when the main frame " - "is scrolled, it should not " - "be placed in the fixed region."; + if (!RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) { + Region scrolling; + Region fixed; + Page* page = GetFrame()->GetPage(); + page->GetScrollingCoordinator() + ->ComputeShouldHandleScrollGestureOnMainThreadRegion( + To<LocalFrame>(page->MainFrame()), &scrolling, &fixed); - EXPECT_EQ(scrolling.Bounds(), IntRect(0, 1200, 65, 65)) - << "Since the DIV will move when the main frame is scrolled, it should " - "be placed in the scrolling region."; + EXPECT_TRUE(fixed.IsEmpty()) + << "Since the DIV will move when the main frame is scrolled, it should" + " not be placed in the fixed region."; + + EXPECT_EQ(scrolling.Bounds(), IntRect(0, 1200, 65, 65)) + << "Since the DIV will move when the main frame is scrolled, it should " + "be placed in the scrolling region."; + } + + auto* layout_viewport = GetFrame()->View()->LayoutViewport(); + auto* mapping = layout_viewport->Layer()->GetCompositedLayerMapping(); + auto* non_fast_layer = mapping->ScrollingContentsLayer()->CcLayer(); + EXPECT_EQ(non_fast_layer->non_fast_scrollable_region().bounds(), + gfx::Rect(0, 1200, 65, 65)); } // Same as above but test that the rect is correctly calculated into the fixed @@ -1444,7 +1516,7 @@ #spacer { height: 10000px; } - iframe { + #iframe { position: fixed; top: 20px; left: 0px; @@ -1455,7 +1527,7 @@ </style> <div id="spacer"></div> - <iframe srcdoc=" + <iframe id="iframe" srcdoc=" <!DOCTYPE html> <style> body { margin: 0; } @@ -1487,20 +1559,47 @@ GetFrame()->GetDocument()->View()->GetScrollableArea()->SetScrollOffset( ScrollOffset(0, 1000), kProgrammaticScroll); - Region scrolling; - Region fixed; - Page* page = GetFrame()->GetPage(); - page->GetScrollingCoordinator() - ->ComputeShouldHandleScrollGestureOnMainThreadRegion( - To<LocalFrame>(page->MainFrame()), &scrolling, &fixed); + ForceFullCompositingUpdate(); - EXPECT_TRUE(scrolling.IsEmpty()) << "Since the DIV will not move when the " - "main frame is scrolled, it should " - "not be placed in the scrolling region."; + if (!RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) { + Region scrolling; + Region fixed; + Page* page = GetFrame()->GetPage(); + page->GetScrollingCoordinator() + ->ComputeShouldHandleScrollGestureOnMainThreadRegion( + To<LocalFrame>(page->MainFrame()), &scrolling, &fixed); - EXPECT_EQ(fixed.Bounds(), IntRect(0, 20, 75, 75)) - << "Since the DIV not move when the main frame is scrolled, it should be " - "placed in the scrolling region."; + EXPECT_TRUE(scrolling.IsEmpty()) + << "Since the DIV will not move when the " + "main frame is scrolled, it should " + "not be placed in the scrolling region."; + + EXPECT_EQ(fixed.Bounds(), IntRect(0, 20, 75, 75)) + << "Since the DIV not move when the main frame is scrolled, it should " + "be placed in the scrolling region."; + } + + if (!RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) { + // Since the main frame isn't scrollable, the NonFastScrollableRegions + // should be stored on the visual viewport's scrolling layer, rather than + // the main frame's scrolling contents layer. This is a restriction of the + // pre-PaintNonFastScrollableRegions code which only stored non-fast regions + // on one scrolling layer, and required using the visual viewport's + // scrolling layer to correctly handle some fixed-position cases. + auto* non_fast_layer = + GetFrame()->GetPage()->GetVisualViewport().ScrollLayer()->CcLayer(); + EXPECT_EQ(non_fast_layer->non_fast_scrollable_region().bounds(), + gfx::Rect(0, 20, 75, 75)); + } else { + // PaintNonFastScrollableRegions can put the non-fast scrollable region on + // the fixed-position layer. + auto* outer_iframe = GetFrame()->GetDocument()->getElementById("iframe"); + auto* outer_iframe_box = ToLayoutBox(outer_iframe->GetLayoutObject()); + auto* mapping = outer_iframe_box->Layer()->GetCompositedLayerMapping(); + auto* non_fast_layer = mapping->MainGraphicsLayer()->CcLayer(); + EXPECT_EQ(non_fast_layer->non_fast_scrollable_region().bounds(), + gfx::Rect(0, 0, 75, 75)); + } } TEST_P(ScrollingCoordinatorTest, IframeCompositedScrollingHideAndShow) { @@ -1526,40 +1625,36 @@ ForceFullCompositingUpdate(); - // Since the main frame isn't scrollable, the NonFastScrollableRegions should - // be stored on the visual viewport's scrolling layer, rather than the main - // frame's scrolling contents layer. - Page* page = GetFrame()->GetPage(); - cc::Layer* inner_viewport_scroll_layer = - page->GetVisualViewport().ScrollLayer()->CcLayer(); - Element* iframe = GetFrame()->GetDocument()->getElementById("iframe"); + cc::Layer* non_fast_layer = nullptr; + if (!RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) { + // Since the main frame isn't scrollable, the NonFastScrollableRegions + // should be stored on the visual viewport's scrolling layer, rather than + // the main frame's scrolling contents layer. This is a restriction of the + // pre-PaintNonFastScrollableRegions code which only stored non-fast regions + // on one scrolling layer, and required using the visual viewport's + // scrolling layer to correctly handle some fixed-position cases. + Page* page = GetFrame()->GetPage(); + non_fast_layer = page->GetVisualViewport().ScrollLayer()->CcLayer(); + } else { + non_fast_layer = + GetFrame()->View()->LayoutViewport()->LayerForScrolling()->CcLayer(); + } // Should have a NFSR initially. - ForceFullCompositingUpdate(); - EXPECT_FALSE(inner_viewport_scroll_layer->non_fast_scrollable_region() - .bounds() - .IsEmpty()); - - // Ensure the frame's scrolling layer didn't get an NFSR. - cc::Layer* outer_viewport_scroll_layer = - GetFrame()->View()->LayoutViewport()->LayerForScrolling()->CcLayer(); - EXPECT_TRUE(outer_viewport_scroll_layer->non_fast_scrollable_region() - .bounds() - .IsEmpty()); + EXPECT_EQ(non_fast_layer->non_fast_scrollable_region().bounds(), + gfx::Rect(2, 2, 100, 100)); // Hiding the iframe should clear the NFSR. + Element* iframe = GetFrame()->GetDocument()->getElementById("iframe"); iframe->setAttribute(html_names::kStyleAttr, "display: none"); ForceFullCompositingUpdate(); - EXPECT_TRUE(inner_viewport_scroll_layer->non_fast_scrollable_region() - .bounds() - .IsEmpty()); + EXPECT_TRUE(non_fast_layer->non_fast_scrollable_region().bounds().IsEmpty()); // Showing it again should compute the NFSR. iframe->setAttribute(html_names::kStyleAttr, ""); ForceFullCompositingUpdate(); - EXPECT_FALSE(inner_viewport_scroll_layer->non_fast_scrollable_region() - .bounds() - .IsEmpty()); + EXPECT_EQ(non_fast_layer->non_fast_scrollable_region().bounds(), + gfx::Rect(2, 2, 100, 100)); } // Same as above but the main frame is scrollable. This should cause the non @@ -1737,6 +1832,124 @@ histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 2); } +// TODO(pdr): Replace this with ScrollingCoordinatorTest when +// PaintNonFastScrollableRegions is launched. +using PaintNonFastScrollableRegionsScrollingCoordinatorTest = + ScrollingCoordinatorTest; +INSTANTIATE_TEST_SUITE_P( + All, + PaintNonFastScrollableRegionsScrollingCoordinatorTest, + ::testing::Values(kScrollingCoordinatorTestPaintNonFastScrollableRegions)); + +TEST_P(PaintNonFastScrollableRegionsScrollingCoordinatorTest, + NonCompositedNonFastScrollableRegion) { + GetWebView()->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled( + false); + LoadHTML(R"HTML( + <!DOCTYPE html> + <style> + body { margin: 0; } + #composited_container { + width: 220px; + height: 220px; + will-change: transform; + } + #scroller { + height: 200px; + width: 200px; + overflow-y: scroll; + } + </style> + <div id="composited_container"> + <div id="scroller"> + <div id="forcescroll" style="height: 1000px;"></div> + </div> + </div> + )HTML"); + ForceFullCompositingUpdate(); + + auto* container = + GetFrame()->GetDocument()->getElementById("composited_container"); + auto* layer = ToLayoutBox(container->GetLayoutObject())->Layer(); + auto* mapping = layer->GetCompositedLayerMapping(); + // The non-scrolling graphics layer should have a non-scrolling region for the + // non-composited scroller. + cc::Layer* cc_layer = mapping->MainGraphicsLayer()->CcLayer(); + auto region = cc_layer->non_fast_scrollable_region(); + EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 200, 200)); +} + +TEST_P(PaintNonFastScrollableRegionsScrollingCoordinatorTest, + NonCompositedResizerNonFastScrollableRegion) { + // TODO(pdr): Paint non-fast scrollable regions for resizers + // (crbug.com/864567). + if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) + return; + + GetWebView()->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled( + false); + LoadHTML(R"HTML( + <style> + #container { will-change: transform; } + #scroller { + width: 80px; + height: 80px; + resize: both; + overflow-y: scroll; + } + </style> + <div id="container"> + <div id="scroller"></div> + </div> + )HTML"); + ForceFullCompositingUpdate(); + + auto* container_element = + GetFrame()->GetDocument()->getElementById("container"); + auto* container = ToLayoutBox(container_element->GetLayoutObject()); + auto* container_graphics_layer = + container->EnclosingLayer()->GraphicsLayerBacking(container); + // The non-fast scrollable region should be on the container's graphics layer + // and not one of the viewport scroll layers because the region should move + // when the container moves and not when the viewport scrolls. + auto region = + container_graphics_layer->CcLayer()->non_fast_scrollable_region(); + EXPECT_EQ(region.bounds(), gfx::Rect(66, 66, 14, 14)); +} + +TEST_P(PaintNonFastScrollableRegionsScrollingCoordinatorTest, + CompositedResizerNonFastScrollableRegion) { + // TODO(pdr): Paint non-fast scrollable regions for resizers + // (crbug.com/864567). + if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) + return; + LoadHTML(R"HTML( + <style> + #container { will-change: transform; } + #scroller { + will-change: transform; + width: 80px; + height: 80px; + resize: both; + overflow-y: scroll; + } + </style> + <div id="container"> + <div id="scroller"></div> + </div> + )HTML"); + ForceFullCompositingUpdate(); + + auto* scroller_element = + GetFrame()->GetDocument()->getElementById("scroller"); + auto* scroller = ToLayoutBox(scroller_element->GetLayoutObject()); + auto* scroll_corner_graphics_layer = + scroller->GetScrollableArea()->LayerForScrollCorner(); + auto region = + scroll_corner_graphics_layer->CcLayer()->non_fast_scrollable_region(); + EXPECT_EQ(region.bounds(), gfx::Rect(-7, -7, 14, 14)); +} + class ScrollingCoordinatorTestWithAcceleratedContext : public ScrollingCoordinatorTest { public: @@ -1765,9 +1978,15 @@ FakeGLES2Interface gl_; }; -INSTANTIATE_TEST_SUITE_P(All, - ScrollingCoordinatorTestWithAcceleratedContext, - testing::Bool()); +INSTANTIATE_TEST_SUITE_P( + All, + ScrollingCoordinatorTestWithAcceleratedContext, + ::testing::Values( + kScrollingCoordinatorTestNoFlags, + kScrollingCoordinatorTestBlinkGenPropertyTrees, + kScrollingCoordinatorTestPaintNonFastScrollableRegions, + (kScrollingCoordinatorTestBlinkGenPropertyTrees | + kScrollingCoordinatorTestPaintNonFastScrollableRegions))); TEST_P(ScrollingCoordinatorTestWithAcceleratedContext, CanvasTouchActionRects) { LoadHTML(R"HTML(
diff --git a/third_party/blink/renderer/core/paint/README.md b/third_party/blink/renderer/core/paint/README.md index fdcc1c66..dd43d94 100644 --- a/third_party/blink/renderer/core/paint/README.md +++ b/third_party/blink/renderer/core/paint/README.md
@@ -669,9 +669,30 @@ ### Hit test painting -Hit testing is done in paint-order. Hit test display items are emitted in the -background phase of painting. Hit test display items are produced even if there -is no painted content. +Hit testing is done in paint-order, and to preserve this information the paint +system is re-used to paint hit test display items in the background phase of +painting. This information is then used in the compositor to implement cc-side +hit testing. Hit test display items are produced even if there is no painted +content. + +There are two types of hit test painting: + +1. [HitTestDisplayItem](../../platform/graphics/paint/hit_test_display_item.h) + + Used for [touch action rects](http://docs.google.com/document/u/1/d/1ksiqEPkDeDuI_l5HvWlq1MfzFyDxSnsNB8YXIaXa3sE/view) + which are areas of the page that allow certain gesture effects, as well as + areas of the page that disallow touch events due to blocking touch event + handlers. + +2. [ScrollHitTestDisplayItem](../../platform/graphics/paint/scroll_hit_test_display_item.h) + + Used to create + [non-fast scrollable regions](https://docs.google.com/document/d/1IyYJ6bVF7KZq96b_s5NrAzGtVoBXn_LQnya9y4yT3iw/view) + to prevent compositor scrolling of non-composited scrollers, plugins with + blocking scroll event handlers, and resize handles. + + This is also used for CompositeAfterPaint to force a special cc::Layer that + is marked as being scrollable. ### PaintNG
diff --git a/third_party/blink/renderer/core/paint/box_painter.cc b/third_party/blink/renderer/core/paint/box_painter.cc index 2882422..7c625b0 100644 --- a/third_party/blink/renderer/core/paint/box_painter.cc +++ b/third_party/blink/renderer/core/paint/box_painter.cc
@@ -98,11 +98,28 @@ RecordHitTestData(paint_info, paint_rect, *background_client); - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) { + bool needs_scroll_hit_test = true; + if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + // Pre-CompositeAfterPaint, there is no need to emit scroll hit test + // display items for composited scrollers because these display items are + // only used to create non-fast scrollable regions for non-composited + // scrollers. With CompositeAfterPaint, we always paint the scroll hit + // test display items but ignore the non-fast region if the scroll was + // composited in PaintArtifactCompositor::UpdateNonFastScrollableRegions. + if (layout_box_.HasLayer() && + layout_box_.Layer()->GetCompositedLayerMapping() && + layout_box_.Layer() + ->GetCompositedLayerMapping() + ->HasScrollingLayer()) { + needs_scroll_hit_test = false; + } + } + // Record the scroll hit test after the non-scrolling background so // background squashing is not affected. Hit test order would be equivalent // if this were immediately before the non-scrolling background. - if (!painting_scrolling_background) + if (!painting_scrolling_background && needs_scroll_hit_test) RecordScrollHitTestData(paint_info, *background_client); } } @@ -300,7 +317,7 @@ void BoxPainter::RecordScrollHitTestData( const PaintInfo& paint_info, const DisplayItemClient& background_client) { - DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); + DCHECK(RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()); // Hit test display items are only needed for compositing. This flag is used // for for printing and drag images which do not need hit testing. @@ -329,8 +346,9 @@ paint_info.context.GetPaintController(), fragment->LocalBorderBoxProperties(), background_client, DisplayItem::kScrollHitTest); - ScrollHitTestDisplayItem::Record(paint_info.context, background_client, - *properties->ScrollTranslation()); + ScrollHitTestDisplayItem::Record( + paint_info.context, background_client, DisplayItem::kScrollHitTest, + properties->ScrollTranslation(), fragment->VisualRect()); } }
diff --git a/third_party/blink/renderer/core/paint/box_painter_test.cc b/third_party/blink/renderer/core/paint/box_painter_test.cc index f384f5a..a936d90 100644 --- a/third_party/blink/renderer/core/paint/box_painter_test.cc +++ b/third_party/blink/renderer/core/paint/box_painter_test.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/paint/box_painter.h" #include "testing/gmock/include/gmock/gmock.h" +#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h" #include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h" @@ -34,10 +35,12 @@ PaintPhase::kSelfOutlineOnly)))); } -TEST_P(BoxPainterTest, ScrollHitTestOrderWithScrollBackgroundAttachment) { - // Only CompositeAfterPaint supports scroll hit test display items. - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; +using BoxPainterScrollHitTestTest = PaintControllerPaintTest; + +INSTANTIATE_SCROLL_HIT_TEST_SUITE_P(BoxPainterScrollHitTestTest); + +TEST_P(BoxPainterScrollHitTestTest, + ScrollHitTestOrderWithScrollBackgroundAttachment) { SetBodyInnerHTML(R"HTML( <style> ::-webkit-scrollbar { display: none; } @@ -63,21 +66,36 @@ // As a reminder, "background-attachment: scroll" does not move when the // container's scroll offset changes. - // The scroll hit test should be after the non-scrolling (attachment: - // scroll) container background so that it does not prevent squashing the - // non-scrolling container background into the root layer. - EXPECT_THAT(RootPaintController().GetDisplayItemList(), - ElementsAre(IsSameId(&ViewScrollingBackgroundClient(), - kDocumentBackgroundType), - IsSameId(&container, kBackgroundType), - IsSameId(&container, kScrollHitTestType), - IsSameId(&child, kBackgroundType))); + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + // The scroll hit test should be after the non-scrolling (attachment: + // scroll) container background so that it does not prevent squashing the + // non-scrolling container background into the root layer. + EXPECT_THAT(RootPaintController().GetDisplayItemList(), + ElementsAre(IsSameId(&ViewScrollingBackgroundClient(), + kDocumentBackgroundType), + IsSameId(&container, kBackgroundType), + IsSameId(&container, kScrollHitTestType), + IsSameId(&child, kBackgroundType))); + } else { + // Because the frame composited scrolls, no scroll hit test display item is + // needed. + const auto* non_scrolling_layer = To<LayoutBlock>(container) + .Layer() + ->GetCompositedLayerMapping() + ->MainGraphicsLayer(); + EXPECT_THAT(non_scrolling_layer->GetPaintController().GetDisplayItemList(), + ElementsAre(IsSameId(&container, kBackgroundType))); + const auto* scrolling_layer = To<LayoutBlock>(container) + .Layer() + ->GetCompositedLayerMapping() + ->ScrollingContentsLayer(); + EXPECT_THAT(scrolling_layer->GetPaintController().GetDisplayItemList(), + ElementsAre(IsSameId(&child, kBackgroundType))); + } } -TEST_P(BoxPainterTest, ScrollHitTestOrderWithLocalBackgroundAttachment) { - // Only CompositeAfterPaint supports scroll hit test display items. - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; +TEST_P(BoxPainterScrollHitTestTest, + ScrollHitTestOrderWithLocalBackgroundAttachment) { SetBodyInnerHTML(R"HTML( <style> ::-webkit-scrollbar { display: none; } @@ -105,18 +123,36 @@ // As a reminder, "background-attachment: local" moves when the container's // scroll offset changes. - // The scroll hit test should be before the scrolling (attachment: local) - // container background so that it does not prevent squashing the scrolling - // background into the scrolling contents. - EXPECT_THAT(RootPaintController().GetDisplayItemList(), - ElementsAre(IsSameId(&ViewScrollingBackgroundClient(), - kDocumentBackgroundType), - IsSameId(&container, kScrollHitTestType), - IsSameId(container_scrolling_client, kBackgroundType), - IsSameId(&child, kBackgroundType))); + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + // The scroll hit test should be before the scrolling (attachment: local) + // container background so that it does not prevent squashing the scrolling + // background into the scrolling contents. + EXPECT_THAT( + RootPaintController().GetDisplayItemList(), + ElementsAre( + IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType), + IsSameId(&container, kScrollHitTestType), + IsSameId(container_scrolling_client, kBackgroundType), + IsSameId(&child, kBackgroundType))); + } else { + // Because the frame composited scrolls, no scroll hit test display item is + // needed. + const auto* non_scrolling_layer = + container.Layer()->GetCompositedLayerMapping()->MainGraphicsLayer(); + EXPECT_TRUE(non_scrolling_layer->GetPaintController() + .GetDisplayItemList() + .IsEmpty()); + const auto* scrolling_layer = container.Layer() + ->GetCompositedLayerMapping() + ->ScrollingContentsLayer(); + EXPECT_THAT( + scrolling_layer->GetPaintController().GetDisplayItemList(), + ElementsAre(IsSameId(container_scrolling_client, kBackgroundType), + IsSameId(&child, kBackgroundType))); + } } -TEST_P(BoxPainterTest, ScrollHitTestProperties) { +TEST_P(BoxPainterScrollHitTestTest, ScrollHitTestProperties) { // This test depends on the CompositeAfterPaint behavior of painting solid // color backgrounds into both the non-scrolled and scrolled spaces. if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) @@ -159,8 +195,11 @@ kBackgroundType), IsSameId(&child, kBackgroundType))); + HitTestData scroll_hit_test_data; const auto& scrolling_contents_properties = container.FirstFragment().ContentsProperties(); + scroll_hit_test_data.SetScrollHitTest( + &scrolling_contents_properties.Transform(), IntRect(0, 0, 200, 200)); EXPECT_THAT( paint_chunks, ElementsAre( @@ -173,7 +212,8 @@ kNonScrollingBackgroundChunkType), container.FirstFragment().LocalBorderBoxProperties()), IsPaintChunk(2, 3, PaintChunk::Id(container, kScrollHitTestType), - container.FirstFragment().LocalBorderBoxProperties()), + container.FirstFragment().LocalBorderBoxProperties(), + scroll_hit_test_data), IsPaintChunk(3, 5, PaintChunk::Id(container, kScrollingBackgroundChunkType), scrolling_contents_properties))); @@ -216,7 +256,7 @@ RootPaintController() .GetDisplayItemList()[scroll_hit_test_chunk.begin_index]); EXPECT_EQ(&contents_transform, - &scroll_hit_test_display_item.scroll_offset_node()); + scroll_hit_test_display_item.scroll_offset_node()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc index 036dae0..a51a1cc 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -1930,7 +1930,14 @@ // expensive. bool paints_hit_test = has_painted_content || GetLayoutObject().HasEffectiveAllowedTouchAction(); - graphics_layer_->SetPaintsHitTest(paints_hit_test); + // TODO(pdr): When PaintNonFastScrollableRegions supports painting plugins + // that request wheel events, this should be updated to check: + // GetPluginContainer(GetLayoutObject())->WantsWheelEvents()). + bool paints_scroll_hit_test = + RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled() && + (owning_layer_.GetScrollableArea() && + owning_layer_.GetScrollableArea()->ScrollsOverflow()); + graphics_layer_->SetPaintsHitTest(paints_hit_test || paints_scroll_hit_test); if (scrolling_layer_) { // m_scrollingLayer never has backing store.
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index d09938d..f10650c 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -256,7 +256,9 @@ // Record the scroll hit test after the background so background squashing // is not affected. Hit test order would be equivalent if this were // immediately before the background. - // if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + // TODO(pdr): Uncomment this and support non-fast scrollable regions for + // NGBoxFragments (see: https://crbug.com/864567). + // if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) // PaintScrollHitTestDisplayItem(paint_info); // We're done. We don't bother painting any children.
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc b/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc index 58932ae..ee0e5c9 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
@@ -372,7 +372,10 @@ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(); EXPECT_FALSE(target_layer->NeedsRepaint()); EXPECT_TRUE(PaintWithoutCommit()); - EXPECT_EQ(2, NumCachedNewItems()); + if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) + EXPECT_EQ(3, NumCachedNewItems()); + else + EXPECT_EQ(2, NumCachedNewItems()); CommitAndFinishCycle(); // |target| is still partially painted. @@ -408,7 +411,10 @@ // a partially painted layer will trigger repaint. EXPECT_FALSE(target_layer->NeedsRepaint()); EXPECT_TRUE(PaintWithoutCommit()); - EXPECT_EQ(2, NumCachedNewItems()); + if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) + EXPECT_EQ(3, NumCachedNewItems()); + else + EXPECT_EQ(2, NumCachedNewItems()); CommitAndFinishCycle(); // |target| is still partially painted.
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index 4410740..1a8150aa 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -2150,7 +2150,7 @@ // PaintPropertyTreeBuilder::updateScrollAndScrollTranslation). GetLayoutBox()->SetNeedsPaintPropertyUpdate(); - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) { // Scroll hit test display items depend on whether the box scrolls overflow. // The scroll hit test display items paint in the background phase // (see: BoxPainter::PaintBoxDecorationBackground).
diff --git a/third_party/blink/renderer/core/paint/view_painter.cc b/third_party/blink/renderer/core/paint/view_painter.cc index aca247e..19d1007c 100644 --- a/third_party/blink/renderer/core/paint/view_painter.cc +++ b/third_party/blink/renderer/core/paint/view_painter.cc
@@ -38,7 +38,7 @@ bool has_touch_action_rect = layout_view_.HasEffectiveAllowedTouchAction(); bool paints_scroll_hit_test = - RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && + RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled() && (layout_view_.GetScrollableArea() && layout_view_.GetScrollableArea()->ScrollsOverflow()); if (!layout_view_.HasBoxDecorationBackground() && !has_touch_action_rect && @@ -84,11 +84,29 @@ *background_client); } - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) { + bool needs_scroll_hit_test = true; + if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + // Pre-CompositeAfterPaint, there is no need to emit scroll hit test + // display items for composited scrollers because these display items are + // only used to create non-fast scrollable regions for non-composited + // scrollers. With CompositeAfterPaint, we always paint the scroll hit + // test display items but ignore the non-fast region if the scroll was + // composited in PaintArtifactCompositor::UpdateNonFastScrollableRegions. + if (layout_view_.HasLayer() && + layout_view_.Layer()->GetCompositedLayerMapping() && + layout_view_.Layer() + ->GetCompositedLayerMapping() + ->HasScrollingLayer()) { + needs_scroll_hit_test = false; + } + } + // Record the scroll hit test after the non-scrolling background so // background squashing is not affected. Hit test order would be equivalent // if this were immediately before the non-scrolling background. - if (paints_scroll_hit_test && !painting_scrolling_background) { + if (paints_scroll_hit_test && !painting_scrolling_background && + needs_scroll_hit_test) { BoxPainter(layout_view_) .RecordScrollHitTestData(paint_info, *background_client); }
diff --git a/third_party/blink/renderer/core/paint/view_painter_test.cc b/third_party/blink/renderer/core/paint/view_painter_test.cc index e9b0e28..19650fd 100644 --- a/third_party/blink/renderer/core/paint/view_painter_test.cc +++ b/third_party/blink/renderer/core/paint/view_painter_test.cc
@@ -120,7 +120,11 @@ RunFixedBackgroundTest(true); } -TEST_P(ViewPainterTest, DocumentBackgroundWithScroll) { +using ViewPainterScrollHitTestTest = PaintControllerPaintTest; + +INSTANTIATE_SCROLL_HIT_TEST_SUITE_P(ViewPainterScrollHitTestTest); + +TEST_P(ViewPainterScrollHitTestTest, DocumentBackgroundWithScroll) { SetBodyInnerHTML(R"HTML( <style>::-webkit-scrollbar { display: none }</style> <div style='height: 5000px'></div> @@ -135,6 +139,11 @@ ElementsAre(IsSameId(&GetLayoutView(), DisplayItem::kScrollHitTest), IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType))); + HitTestData scroll_hit_test_data; + const auto& scrolling_contents_properties = + GetLayoutView().FirstFragment().ContentsProperties(); + scroll_hit_test_data.SetScrollHitTest( + &scrolling_contents_properties.Transform(), IntRect(0, 0, 800, 600)); EXPECT_THAT( RootPaintController().PaintChunks(), ElementsAre( @@ -142,13 +151,15 @@ 0, 1, PaintChunk::Id(*GetLayoutView().Layer(), DisplayItem::kLayerChunkBackground), - GetLayoutView().FirstFragment().LocalBorderBoxProperties()), - IsPaintChunk( - 1, 2, - PaintChunk::Id(ViewScrollingBackgroundClient(), - kDocumentBackgroundType), - GetLayoutView().FirstFragment().ContentsProperties()))); + GetLayoutView().FirstFragment().LocalBorderBoxProperties(), + scroll_hit_test_data), + IsPaintChunk(1, 2, + PaintChunk::Id(ViewScrollingBackgroundClient(), + kDocumentBackgroundType), + scrolling_contents_properties))); } else { + // Because the frame composited scrolls, no scroll hit test display item is + // needed. EXPECT_THAT(RootPaintController().GetDisplayItemList(), ElementsAre(IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType))); @@ -161,7 +172,7 @@ } } -TEST_P(ViewPainterTest, FrameScrollHitTestProperties) { +TEST_P(ViewPainterScrollHitTestTest, FrameScrollHitTestProperties) { // This test depends on the CompositeAfterPaint behavior of painting solid // color backgrounds into both the non-scrolled and scrolled spaces. if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) @@ -191,6 +202,9 @@ const auto& paint_chunks = RootPaintController().PaintChunks(); const auto& view_contents_properties = GetLayoutView().FirstFragment().ContentsProperties(); + HitTestData scroll_hit_test_data; + scroll_hit_test_data.SetScrollHitTest(&view_contents_properties.Transform(), + IntRect(0, 0, 800, 600)); EXPECT_THAT( paint_chunks, ElementsAre( @@ -198,7 +212,8 @@ 0, 1, PaintChunk::Id(*GetLayoutView().Layer(), DisplayItem::kLayerChunkBackground), - GetLayoutView().FirstFragment().LocalBorderBoxProperties()), + GetLayoutView().FirstFragment().LocalBorderBoxProperties(), + scroll_hit_test_data), IsPaintChunk(1, 2, PaintChunk::Id(ViewScrollingBackgroundClient(), kDocumentBackgroundType), @@ -233,7 +248,7 @@ RootPaintController() .GetDisplayItemList()[scroll_hit_test_chunk.begin_index]); EXPECT_EQ(&contents_transform, - &scroll_hit_test_display_item.scroll_offset_node()); + scroll_hit_test_display_item.scroll_offset_node()); } class ViewPainterTouchActionRectTest : public ViewPainterTest { @@ -284,6 +299,9 @@ HitTestData non_scrolling_hit_test_data; non_scrolling_hit_test_data.touch_action_rects.emplace_back( LayoutRect(0, 0, 800, 600)); + HitTestData scroll_hit_test_data; + scroll_hit_test_data.SetScrollHitTest(&scrolling_properties.Transform(), + IntRect(0, 0, 800, 600)); EXPECT_THAT( RootPaintController().PaintChunks(), ElementsAre( @@ -296,7 +314,8 @@ IsPaintChunk( 1, 2, PaintChunk::Id(GetLayoutView(), DisplayItem::kScrollHitTest), - GetLayoutView().FirstFragment().LocalBorderBoxProperties()), + GetLayoutView().FirstFragment().LocalBorderBoxProperties(), + scroll_hit_test_data), IsPaintChunk( 2, 4, PaintChunk::Id(scrolling_client, kDocumentBackgroundType), scrolling_properties, view_hit_test_data), @@ -352,6 +371,9 @@ scrolling_hit_test_data.touch_action_rects.emplace_back( LayoutRect(0, 0, 800, 3000)); if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + HitTestData scroll_hit_test_data; + scroll_hit_test_data.SetScrollHitTest(&scrolling_properties.Transform(), + IntRect(0, 0, 800, 600)); EXPECT_THAT( RootPaintController().PaintChunks(), ElementsAre( @@ -361,7 +383,7 @@ non_scrolling_properties, view_hit_test_data), IsPaintChunk(2, 3, PaintChunk::Id(*view, DisplayItem::kScrollHitTest), - non_scrolling_properties), + non_scrolling_properties, scroll_hit_test_data), IsPaintChunk(3, 5, PaintChunk::Id(*html->Layer(), kNonScrollingBackgroundChunkType),
diff --git a/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc b/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc index 8ee3c96..17f28ce 100644 --- a/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc +++ b/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc
@@ -126,12 +126,27 @@ fetch_options), export_value_(v8::Isolate::GetCurrent(), value) {} -// TODO(sasebree) Implement this method +// This is the definition of [[EvaluationSteps]] As per the synthetic module +// spec https://heycam.github.io/webidl/#synthetic-module-records +// It is responsible for setting the default export of the provided module to +// the value wrapped by the ValueWrapperSyntheticModuleScript v8::MaybeLocal<v8::Value> ValueWrapperSyntheticModuleScript::EvaluationSteps( v8::Local<v8::Context> context, v8::Local<v8::Module> module) { - NOTREACHED(); - return v8::MaybeLocal<v8::Value>(); + v8::Isolate* isolate = context->GetIsolate(); + ScriptState* script_state = ScriptState::From(context); + Modulator* modulator = Modulator::From(script_state); + ModuleRecord record = ModuleRecord(isolate, module, KURL()); + ModuleRecordResolver* module_record_resolver = + modulator->GetModuleRecordResolver(); + const ValueWrapperSyntheticModuleScript* + value_wrapper_synthetic_module_script = + static_cast<const ValueWrapperSyntheticModuleScript*>( + module_record_resolver->GetModuleScriptFromModuleRecord(record)); + module->SetSyntheticModuleExport( + V8String(isolate, "default"), + value_wrapper_synthetic_module_script->export_value_.NewLocal(isolate)); + return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); } String ValueWrapperSyntheticModuleScript::InlineSourceTextForCSP() const {
diff --git a/third_party/blink/renderer/core/scroll/scrolling_test.cc b/third_party/blink/renderer/core/scroll/scrolling_test.cc index 45e18070..d02af8b 100644 --- a/third_party/blink/renderer/core/scroll/scrolling_test.cc +++ b/third_party/blink/renderer/core/scroll/scrolling_test.cc
@@ -23,6 +23,10 @@ namespace blink { +namespace { +constexpr double kBeginFrameDelaySeconds = 0.5; +} + class FractionalScrollSimTest : public SimTest { public: FractionalScrollSimTest() : fractional_scroll_offsets_for_test_(true) {} @@ -109,7 +113,7 @@ // The callback is executed when the animation finishes at // ScrollAnimator::TickAnimation. Compositor().BeginFrame(); - Compositor().BeginFrame(0.3); + Compositor().BeginFrame(kBeginFrameDelaySeconds); ASSERT_TRUE(finished); } @@ -151,7 +155,7 @@ // The callback is executed when the animation finishes at // ScrollAnimator::TickAnimation. Compositor().BeginFrame(); - Compositor().BeginFrame(0.3); + Compositor().BeginFrame(kBeginFrameDelaySeconds); ASSERT_TRUE(finished); } @@ -193,7 +197,7 @@ // The callback is executed when the animation finishes at // ScrollAnimator::TickAnimation. Compositor().BeginFrame(); - Compositor().BeginFrame(0.3); + Compositor().BeginFrame(kBeginFrameDelaySeconds); ASSERT_TRUE(finished); } @@ -241,7 +245,7 @@ // The callback is executed when the animation finishes at // ScrollAnimator::TickAnimation. - Compositor().BeginFrame(0.3); + Compositor().BeginFrame(kBeginFrameDelaySeconds); ASSERT_TRUE(finished); }
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index ad853e1b..bc8fe818 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -2218,12 +2218,42 @@ return nullptr; } - // Update lifecycle to kPrePaintClean. This includes the compositing update - // and ScrollingCoordinator::UpdateAfterPaint, which computes the non-fast - // scrollable region. + // Update lifecycle. This includes the compositing update and + // ScrollingCoordinator::UpdateAfterPaint, which computes the non-fast + // scrollable region. For CompositeAfterPaint, this includes running + // PaintArtifactCompositor which updates the non-fast regions. frame->View()->UpdateAllLifecyclePhases( DocumentLifecycle::LifecycleUpdateReason::kTest); + if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) { + auto* pac = document->View()->GetPaintArtifactCompositorForTesting(); + auto* layer_tree_host = pac->RootLayer()->layer_tree_host(); + // Ensure |cc::TransformTree| has updated the correct ToScreen transforms. + layer_tree_host->UpdateLayers(); + + Vector<IntRect> layer_non_fast_scrollable_rects; + for (auto* layer : *layer_tree_host) { + const cc::Region& non_fast_region = layer->non_fast_scrollable_region(); + for (const gfx::Rect& non_fast_rect : non_fast_region) { + gfx::RectF layer_rect(non_fast_rect); + + // Map |layer_rect| into screen space. + layer_rect.Offset(layer->offset_to_transform_parent()); + auto& transform_tree = + layer->layer_tree_host()->property_trees()->transform_tree; + transform_tree.UpdateTransforms(layer->transform_tree_index()); + const gfx::Transform& to_screen = + transform_tree.ToScreen(layer->transform_tree_index()); + to_screen.TransformRect(&layer_rect); + + layer_non_fast_scrollable_rects.push_back( + IntRect(ToEnclosingRect(layer_rect))); + } + } + + return DOMRectList::Create(layer_non_fast_scrollable_rects); + } + GraphicsLayer* layer = frame->View()->LayoutViewport()->LayerForScrolling(); if (!layer) return DOMRectList::Create();
diff --git a/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc b/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc index 4108f9b..f34eb90 100644 --- a/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc +++ b/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc
@@ -135,6 +135,13 @@ ScriptPromiseResolver* resolver, base::Optional<Vector<mojom::blink::ContactInfoPtr>> contacts) { ScriptState* script_state = resolver->GetScriptState(); + + if (!script_state->ContextIsValid()) { + // This can happen if the page is programmatically redirected while + // contacts are still being chosen. + return; + } + ScriptState::Scope scope(script_state); contact_picker_in_use_ = false;
diff --git a/third_party/blink/renderer/modules/content_index/content_index.idl b/third_party/blink/renderer/modules/content_index/content_index.idl index b124306..fd8f1f8 100644 --- a/third_party/blink/renderer/modules/content_index/content_index.idl +++ b/third_party/blink/renderer/modules/content_index/content_index.idl
@@ -8,7 +8,7 @@ Exposed=(Window,Worker), RuntimeEnabled=ContentIndex ] interface ContentIndex { - [CallWith=ScriptState] Promise<void> add(ContentDescription description); - [CallWith=ScriptState, ImplementedAs=deleteDescription] Promise<void> delete(DOMString id); - [CallWith=ScriptState] Promise<sequence<ContentDescription>> getDescriptions(); + [CallWith=ScriptState, MeasureAs=ContentIndexAdd] Promise<void> add(ContentDescription description); + [CallWith=ScriptState, MeasureAs=ContentIndexDelete, ImplementedAs=deleteDescription] Promise<void> delete(DOMString id); + [CallWith=ScriptState, MeasureAs=ContentIndexGet] Promise<sequence<ContentDescription>> getDescriptions(); }; \ No newline at end of file
diff --git a/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css b/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css index 26cbd81..e839835 100644 --- a/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css +++ b/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css
@@ -1028,13 +1028,16 @@ background-image: -webkit-image-set(url(ic_arrow_back.svg) 1x); } +label[pseudo="-internal-media-controls-text-track-list-item"] * { + pointer-events: none; +} + label[pseudo="-internal-media-controls-text-track-list-item"] input { -webkit-appearance: none; width: 18px; height: 18px; margin: 15px; float: right; - pointer-events: none; } label[pseudo="-internal-media-controls-text-track-list-item"] input:checked {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.cc b/third_party/blink/renderer/modules/webaudio/audio_buffer.cc index fd85f8425..9bd9585 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_buffer.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.cc
@@ -236,7 +236,7 @@ void AudioBuffer::copyFromChannel(NotShared<DOMFloat32Array> destination, int32_t channel_number, - uint32_t start_in_channel, + uint32_t buffer_offset, ExceptionState& exception_state) { if (channel_number < 0 || static_cast<uint32_t>(channel_number) >= channels_.size()) { @@ -253,18 +253,13 @@ DOMFloat32Array* channel_data = channels_[channel_number].Get(); - if (start_in_channel >= channel_data->length()) { - exception_state.ThrowDOMException( - DOMExceptionCode::kIndexSizeError, - ExceptionMessages::IndexOutsideRange( - "startInChannel", start_in_channel, 0U, - ExceptionMessages::kInclusiveBound, channel_data->length(), - ExceptionMessages::kExclusiveBound)); - + if (buffer_offset >= channel_data->length()) { + // Nothing to copy if the buffer offset is past the end of the AudioBuffer. return; } - unsigned count = channel_data->length() - start_in_channel; + unsigned int count = channel_data->length() - buffer_offset; + count = std::min(destination.View()->length(), count); const float* src = channel_data->Data(); @@ -272,8 +267,10 @@ DCHECK(src); DCHECK(dst); + DCHECK_LE(count, channel_data->length()); + DCHECK_LE(buffer_offset + count, channel_data->length()); - memcpy(dst, src + start_in_channel, count * sizeof(*src)); + memcpy(dst, src + buffer_offset, count * sizeof(*src)); } void AudioBuffer::copyToChannel(NotShared<DOMFloat32Array> source, @@ -284,7 +281,7 @@ void AudioBuffer::copyToChannel(NotShared<DOMFloat32Array> source, int32_t channel_number, - uint32_t start_in_channel, + uint32_t buffer_offset, ExceptionState& exception_state) { if (channel_number < 0 || static_cast<uint32_t>(channel_number) >= channels_.size()) { @@ -300,27 +297,23 @@ DOMFloat32Array* channel_data = channels_[channel_number].Get(); - if (start_in_channel >= channel_data->length()) { - exception_state.ThrowDOMException( - DOMExceptionCode::kIndexSizeError, - ExceptionMessages::IndexOutsideRange( - "startInChannel", start_in_channel, 0U, - ExceptionMessages::kInclusiveBound, channel_data->length(), - ExceptionMessages::kExclusiveBound)); - + if (buffer_offset >= channel_data->length()) { + // Nothing to copy if the buffer offset is past the end of the AudioBuffer. return; } - unsigned count = channel_data->length() - start_in_channel; - count = std::min(source.View()->length(), count); + unsigned int count = channel_data->length() - buffer_offset; + count = std::min(source.View()->length(), count); const float* src = source.View()->Data(); float* dst = channel_data->Data(); DCHECK(src); DCHECK(dst); + DCHECK_LE(buffer_offset + count, channel_data->length()); + DCHECK_LE(count, source.View()->length()); - memcpy(dst + start_in_channel, src, count * sizeof(*dst)); + memcpy(dst + buffer_offset, src, count * sizeof(*dst)); } void AudioBuffer::Zero() {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.h b/third_party/blink/renderer/modules/webaudio/audio_buffer.h index 1eb87af1..a96522d 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_buffer.h +++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.h
@@ -95,14 +95,14 @@ ExceptionState&); void copyFromChannel(NotShared<DOMFloat32Array>, int32_t channel_number, - uint32_t start_in_channel, + uint32_t buffer_offset, ExceptionState&); void copyToChannel(NotShared<DOMFloat32Array>, int32_t channel_number, ExceptionState&); void copyToChannel(NotShared<DOMFloat32Array>, int32_t channel_number, - uint32_t start_in_channel, + uint32_t buffer_offset, ExceptionState&); void Zero();
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.idl b/third_party/blink/renderer/modules/webaudio/audio_buffer.idl index d5546d6..54e002a 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_buffer.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.idl
@@ -40,6 +40,6 @@ // Channel access readonly attribute unsigned long numberOfChannels; [HighEntropy, Measure, RaisesException] Float32Array getChannelData(unsigned long channelIndex); - [HighEntropy, Measure, RaisesException] void copyFromChannel(Float32Array destination, long channelNumber, optional unsigned long startInChannel = 0); - [RaisesException] void copyToChannel(Float32Array source, long channelNumber, optional unsigned long startInChannel = 0); + [HighEntropy, Measure, RaisesException] void copyFromChannel(Float32Array destination, long channelNumber, optional unsigned long bufferOffset = 0); + [RaisesException] void copyToChannel(Float32Array source, long channelNumber, optional unsigned long bufferOffset = 0); };
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc b/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc index e292f93..e4208de4 100644 --- a/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc +++ b/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
@@ -73,6 +73,8 @@ FailMock(reason, level, location.get()); } MOCK_METHOD0(Disconnect, void()); + MOCK_METHOD0(ApplyBackpressure, void()); + MOCK_METHOD0(RemoveBackpressure, void()); MockWebSocketChannel() = default; };
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel.h b/third_party/blink/renderer/modules/websockets/websocket_channel.h index 3acf01ee..5c90167 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel.h +++ b/third_party/blink/renderer/modules/websockets/websocket_channel.h
@@ -52,6 +52,7 @@ enum class SendResult { SENT_SYNCHRONOUSLY, CALLBACK_WILL_BE_CALLED }; WebSocketChannel() = default; + virtual ~WebSocketChannel() = default; enum CloseEventCode { kCloseEventCodeNotSpecified = -1, @@ -101,7 +102,14 @@ // Do not call any methods after calling this method. virtual void Disconnect() = 0; // Will suppress didClose(). - virtual ~WebSocketChannel() = default; + // Clients can call ApplyBackpressure() to indicate that they want to stop + // receiving new messages. WebSocketChannelClient::DidReceive*Message() may + // still be called after this, until existing flow control quota is used up. + virtual void ApplyBackpressure() = 0; + + // Clients should call RemoveBackpressure() after calling ApplyBackpressure() + // to indicate that they are ready to receive new messages. + virtual void RemoveBackpressure() = 0; virtual void Trace(blink::Visitor* visitor) {}
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc index 00e365e..7cf1e8f1 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -194,11 +194,7 @@ client_(client), identifier_(CreateUniqueIdentifier()), execution_context_(execution_context), - sending_quota_(0), - received_data_size_for_flow_control_(0), - sent_size_of_top_message_(0), location_at_construction_(std::move(location)), - throttle_passed_(false), file_reading_task_runner_( execution_context->GetTaskRunner(TaskType::kFileReading)) { if (auto* scope = DynamicTo<WorkerGlobalScope>(*execution_context_)) @@ -416,6 +412,15 @@ identifier_ = 0; } +void WebSocketChannelImpl::ApplyBackpressure() { + backpressure_ = true; +} + +void WebSocketChannelImpl::RemoveBackpressure() { + backpressure_ = false; + AddReceiveFlowControlIfNecessary(); +} + WebSocketChannelImpl::Message::Message(const std::string& text, base::OnceClosure completion_callback) : type(kMessageTypeText), @@ -692,7 +697,8 @@ } received_data_size_for_flow_control_ += size; - AddReceiveFlowControlIfNecessary(); + if (!backpressure_) + AddReceiveFlowControlIfNecessary(); const size_t message_size_so_far = (receiving_message_data_ ? receiving_message_data_->size() : 0) + size;
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h index 5df0e81..d0d232e 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
@@ -105,6 +105,8 @@ mojom::ConsoleMessageLevel, std::unique_ptr<SourceLocation>) override; void Disconnect() override; + void ApplyBackpressure() override; + void RemoveBackpressure() override; ExecutionContext* GetExecutionContext(); @@ -227,24 +229,25 @@ Member<BlobLoader> blob_loader_; HeapDeque<Member<Message>> messages_; scoped_refptr<SharedBuffer> receiving_message_data_; - Member<ExecutionContext> execution_context_; + const Member<ExecutionContext> execution_context_; - bool receiving_message_type_is_text_; - uint64_t sending_quota_; - uint64_t received_data_size_for_flow_control_; - wtf_size_t sent_size_of_top_message_; + bool backpressure_ = false; + bool receiving_message_type_is_text_ = false; + bool throttle_passed_ = false; + uint64_t sending_quota_ = 0; + uint64_t received_data_size_for_flow_control_ = 0; + wtf_size_t sent_size_of_top_message_ = 0; FrameScheduler::SchedulingAffectingFeatureHandle feature_handle_for_scheduler_; - std::unique_ptr<SourceLocation> location_at_construction_; + const std::unique_ptr<const SourceLocation> location_at_construction_; network::mojom::blink::WebSocketHandshakeRequestPtr handshake_request_; std::unique_ptr<WebSocketHandshakeThrottle> handshake_throttle_; // This field is only initialised if the object is still waiting for a // throttle response when DidConnect is called. std::unique_ptr<ConnectInfo> connect_info_; - bool throttle_passed_; - scoped_refptr<base::SingleThreadTaskRunner> file_reading_task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> file_reading_task_runner_; base::Optional<uint64_t> receive_quota_threshold_; };
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc index fab05d2..7988bff 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc
@@ -36,6 +36,8 @@ namespace blink { +constexpr uint64_t kInitialReceiveFlowControlQuota = 65536; + typedef testing::StrictMock<testing::MockFunction<void(int)>> Checkpoint; class MockWebSocketChannelClient @@ -165,7 +167,8 @@ InSequence s; EXPECT_CALL(*Handle(), Connect(KURL("ws://localhost/"), _, _, _, ChannelImpl())); - EXPECT_CALL(*Handle(), AddReceiveFlowControlQuota(65536)); + EXPECT_CALL(*Handle(), + AddReceiveFlowControlQuota(kInitialReceiveFlowControlQuota)); EXPECT_CALL(*ChannelClient(), DidConnect(String("a"), String("b"))); } EXPECT_TRUE(Channel()->Connect(KURL("ws://localhost/"), "x")); @@ -234,7 +237,8 @@ KURLEq("http://example.com/"), _, ChannelImpl())) .WillOnce(SaveArg<1>(&protocols)); EXPECT_CALL(checkpoint, Call(1)); - EXPECT_CALL(*Handle(), AddReceiveFlowControlQuota(65536)); + EXPECT_CALL(*Handle(), + AddReceiveFlowControlQuota(kInitialReceiveFlowControlQuota)); EXPECT_CALL(*ChannelClient(), DidConnect(String("a"), String("b"))); } @@ -719,6 +723,32 @@ Handle(), true, WebSocketHandle::kMessageTypeBinary, "\x80\xff", 2); } +TEST_F(WebSocketChannelImplTest, receiveWithBackpressure) { + Connect(); + std::string data(kInitialReceiveFlowControlQuota, 'a'); + Checkpoint checkpoint; + { + InSequence s; + EXPECT_CALL(*ChannelClient(), DidReceiveTextMessage(_)); + EXPECT_CALL(checkpoint, Call(1)); + EXPECT_CALL(*Handle(), + AddReceiveFlowControlQuota(kInitialReceiveFlowControlQuota)); + EXPECT_CALL(*Handle(), + AddReceiveFlowControlQuota(kInitialReceiveFlowControlQuota)); + EXPECT_CALL(*ChannelClient(), DidReceiveTextMessage(_)); + } + + ChannelImpl()->ApplyBackpressure(); + ChannelImpl()->DidReceiveData(Handle(), true, + WebSocketHandle::kMessageTypeText, data.data(), + data.size()); + checkpoint.Call(1); + ChannelImpl()->RemoveBackpressure(); + ChannelImpl()->DidReceiveData(Handle(), true, + WebSocketHandle::kMessageTypeText, data.data(), + data.size()); +} + TEST_F(WebSocketChannelImplTest, closeFromBrowser) { Connect(); Checkpoint checkpoint;
diff --git a/third_party/blink/renderer/modules/xr/xr_input_source.h b/third_party/blink/renderer/modules/xr/xr_input_source.h index f75b45b5..bd535f4 100644 --- a/third_party/blink/renderer/modules/xr/xr_input_source.h +++ b/third_party/blink/renderer/modules/xr/xr_input_source.h
@@ -55,6 +55,7 @@ XRSpace* targetRaySpace() const; XRSpace* gripSpace() const; Gamepad* gamepad() const { return gamepad_; } + Vector<String> profiles() const { return profiles_; } uint32_t source_id() const { return state_.source_id; } @@ -129,6 +130,7 @@ Member<XRTargetRaySpace> target_ray_space_; Member<XRGripSpace> grip_space_; Member<Gamepad> gamepad_; + Vector<String> profiles_; std::unique_ptr<TransformationMatrix> base_pose_matrix_;
diff --git a/third_party/blink/renderer/modules/xr/xr_input_source.idl b/third_party/blink/renderer/modules/xr/xr_input_source.idl index a3b5000..8e17e13 100644 --- a/third_party/blink/renderer/modules/xr/xr_input_source.idl +++ b/third_party/blink/renderer/modules/xr/xr_input_source.idl
@@ -24,4 +24,5 @@ [SameObject] readonly attribute XRSpace targetRaySpace; [SameObject] readonly attribute XRSpace? gripSpace; [SameObject, Measure] readonly attribute Gamepad? gamepad; + [SameObject] readonly attribute FrozenArray<DOMString> profiles; };
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc index 3164c9b..8edddd8 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -132,12 +132,13 @@ } const TransformPaintPropertyNode& -PaintArtifactCompositor::ScrollTranslationForPendingLayer( +PaintArtifactCompositor::ScrollOffsetTranslationForLayer( const PaintArtifact& paint_artifact, const PendingLayer& pending_layer) { - if (const auto* scroll_translation = ScrollTranslationForScrollHitTestLayer( - paint_artifact, pending_layer)) { - return *scroll_translation; + if (const auto* scroll_hit_test = + ScrollHitTestForLayer(paint_artifact, pending_layer)) { + if (scroll_hit_test->scroll_offset) + return *scroll_hit_test->scroll_offset; } const auto& transform = pending_layer.property_tree_state.Transform(); // TODO(pdr): This could be a performance issue because it crawls up the @@ -146,8 +147,8 @@ return transform.NearestScrollTranslationNode(); } -const TransformPaintPropertyNode* -PaintArtifactCompositor::ScrollTranslationForScrollHitTestLayer( +const HitTestData::ScrollHitTest* +PaintArtifactCompositor::ScrollHitTestForLayer( const PaintArtifact& paint_artifact, const PendingLayer& pending_layer) { auto paint_chunks = @@ -157,29 +158,29 @@ if (first_paint_chunk.size() != 1) return nullptr; - const auto& display_item = - paint_artifact.GetDisplayItemList()[first_paint_chunk.begin_index]; - if (!display_item.IsScrollHitTest()) + const HitTestData* hit_test_data = first_paint_chunk.hit_test_data.get(); + if (!hit_test_data) return nullptr; - const auto& scroll_hit_test_display_item = - static_cast<const ScrollHitTestDisplayItem&>(display_item); - return &scroll_hit_test_display_item.scroll_offset_node(); + return base::OptionalOrNullptr(hit_test_data->scroll_hit_test); } scoped_refptr<cc::Layer> PaintArtifactCompositor::ScrollHitTestLayerForPendingLayer( const PaintArtifact& paint_artifact, const PendingLayer& pending_layer) { - const auto* scroll_offset_node = - ScrollTranslationForScrollHitTestLayer(paint_artifact, pending_layer); - if (!scroll_offset_node) + const auto* scroll_hit_test = + ScrollHitTestForLayer(paint_artifact, pending_layer); + if (!scroll_hit_test) + return nullptr; + const auto* scroll_offset = scroll_hit_test->scroll_offset; + if (!scroll_offset) return nullptr; - // We don't decomposite scroll transform nodes. + // We shouldn't decomposite scroll transform nodes. DCHECK_EQ(FloatPoint(), pending_layer.offset_of_decomposited_transforms); - const auto& scroll_node = *scroll_offset_node->ScrollNode(); + const auto& scroll_node = *scroll_offset->ScrollNode(); auto scroll_element_id = scroll_node.GetCompositorElementId(); scoped_refptr<cc::Layer> scroll_layer; @@ -197,7 +198,8 @@ // TODO(pdr): The scroll layer's bounds are currently set to the clipped // container bounds but this does not include the border. We may want to // change this behavior to make non-composited and composited hit testing - // match (see: crbug.com/753124). + // match (see: crbug.com/753124). To do this, use + // |scroll_hit_test->scroll_container_bounds|. auto bounds = scroll_node.ContainerRect().Size(); // Mark the layer as scrollable. // TODO(pdr): When CAP launches this parameter for bounds will not be needed. @@ -302,15 +304,61 @@ rect)) { continue; } - FloatRect visible_rect = rect.Rect(); - visible_rect.Move(-layer_offset.x(), -layer_offset.y()); - touch_action_in_layer_space.Union(touch_action_rect.allowed_touch_action, - EnclosingIntRect(visible_rect)); + rect.MoveBy(FloatPoint(-layer_offset.x(), -layer_offset.y())); + touch_action_in_layer_space.Union( + touch_action_rect.allowed_touch_action, + (gfx::Rect)EnclosingIntRect(rect.Rect())); } } layer->SetTouchActionRegion(std::move(touch_action_in_layer_space)); } +void PaintArtifactCompositor::UpdateNonFastScrollableRegions( + cc::Layer* layer, + // TODO(wangxianzhu): Remove this parameter and use + // layer->offset_to_transform_parent() after we fully launch + // BlinkGenPropertyTrees. + const gfx::Vector2dF& layer_offset, + const PropertyTreeState& layer_state, + const PaintChunkSubset& paint_chunks) { + cc::Region non_fast_scrollable_regions_in_layer_space; + for (const auto& chunk : paint_chunks) { + // Add any non-fast scrollable hit test data from the paint chunk. + const auto* hit_test_data = chunk.hit_test_data.get(); + if (!hit_test_data || !hit_test_data->scroll_hit_test) + continue; + + // Skip the scroll hit test rect if it is for scrolling this cc::Layer. This + // is only needed for CompositeAfterPaint because pre-CompositeAfterPaint + // does not paint scroll hit test data for composited scrollers. + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + if (layer->scrollable()) { + const auto* scroll_offset = + hit_test_data->scroll_hit_test->scroll_offset; + if (scroll_offset) { + const auto& scroll_node = *scroll_offset->ScrollNode(); + auto scroll_element_id = scroll_node.GetCompositorElementId(); + if (layer->element_id() == scroll_element_id) + continue; + } + } + } + + const auto& bounds = + hit_test_data->scroll_hit_test->scroll_container_bounds; + auto rect = FloatClipRect(FloatRect(bounds)); + const auto& chunk_state = chunk.properties.GetPropertyTreeState(); + if (!GeometryMapper::LocalToAncestorVisualRect(chunk_state, layer_state, + rect)) { + continue; + } + rect.MoveBy(FloatPoint(-layer_offset.x(), -layer_offset.y())); + non_fast_scrollable_regions_in_layer_space.Union( + (gfx::Rect)EnclosingIntRect(rect.Rect())); + } + layer->SetNonFastScrollableRegion(non_fast_scrollable_regions_in_layer_space); +} + bool PaintArtifactCompositor::HasComposited( CompositorElementId element_id) const { // |Update| creates PropertyTrees on the LayerTreeHost to represent the @@ -581,10 +629,11 @@ // Case A: The next chunk belongs to the current group but no subgroup. const auto& last_display_item = paint_artifact.GetDisplayItemList()[chunk_it->begin_index]; + bool item_for_scrolling = last_display_item.IsScrollHitTest(); bool requires_own_layer = last_display_item.IsForeignLayer() || // TODO(pdr): This should require a direct // compositing reason. - last_display_item.IsScrollHitTest(); + item_for_scrolling; pending_layers_.emplace_back( *chunk_it, chunk_it - paint_artifact.PaintChunks().begin(), requires_own_layer); @@ -849,10 +898,11 @@ // The scroll translation node of a scroll hit test layer may not be // referenced by any pending layer's property tree state. Disallow // decomposition of it (and its ancestors). - if (const auto* scroll_translation = - ScrollTranslationForScrollHitTestLayer(paint_artifact, - pending_layer)) - mark_not_decompositable(scroll_translation); + if (const auto* scroll_hit_test = + ScrollHitTestForLayer(paint_artifact, pending_layer)) { + if (const auto* scroll_offset = scroll_hit_test->scroll_offset) + mark_not_decompositable(scroll_offset); + } } } @@ -945,13 +995,16 @@ paint_artifact, pending_layer, new_content_layer_clients, new_scroll_hit_test_layers); - // Pre-CompositeAfterPaint, touch action rects are updated through - // ScrollingCoordinator::UpdateLayerTouchActionRects. + // In Pre-CompositeAfterPaint, touch action rects and non-fast scrollable + // regions are updated through ScrollingCoordinator. if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { auto paint_chunks = paint_artifact->GetPaintChunkSubset( pending_layer.paint_chunk_indices); UpdateTouchActionRects(layer.get(), layer->offset_to_transform_parent(), property_state, paint_chunks); + UpdateNonFastScrollableRegions(layer.get(), + layer->offset_to_transform_parent(), + property_state, paint_chunks); } layer->SetLayerTreeHost(root_layer_->layer_tree_host()); @@ -966,7 +1019,7 @@ // The compositor scroll node is not directly stored in the property tree // state but can be created via the scroll offset translation node. const auto& scroll_translation = - ScrollTranslationForPendingLayer(*paint_artifact, pending_layer); + ScrollOffsetTranslationForLayer(*paint_artifact, pending_layer); int scroll_id = property_tree_manager.EnsureCompositorScrollNode(scroll_translation);
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h index e08cf3bc..135615b 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
@@ -185,6 +185,14 @@ const PropertyTreeState& layer_state, const PaintChunkSubset& paint_chunks); + // Update the cc::Layer's non-fast scrollable region from the non-fast regions + // in the paint chunks. + static void UpdateNonFastScrollableRegions( + cc::Layer*, + const gfx::Vector2dF& layer_offset, + const PropertyTreeState& layer_state, + const PaintChunkSubset& paint_chunks); + void SetNeedsUpdate() { needs_update_ = true; } bool NeedsUpdate() const { return needs_update_; } void ClearNeedsUpdateForTesting() { needs_update_ = false; } @@ -265,15 +273,14 @@ bool PropertyTreeStateChanged(const PropertyTreeState&) const; - const TransformPaintPropertyNode& ScrollTranslationForPendingLayer( + const TransformPaintPropertyNode& ScrollOffsetTranslationForLayer( const PaintArtifact&, const PendingLayer&); // If the pending layer is a special scroll hit test layer, return the - // associated scroll offset translation node. - const TransformPaintPropertyNode* ScrollTranslationForScrollHitTestLayer( - const PaintArtifact&, - const PendingLayer&); + // associated hit test information. + const HitTestData::ScrollHitTest* ScrollHitTestForLayer(const PaintArtifact&, + const PendingLayer&); // Finds an existing or creates a new scroll hit test layer for the pending // layer, returning nullptr if the layer is not a scroll hit test layer.
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc index de0ca749..f782b654 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -187,7 +187,8 @@ // Scroll hit test layers are marked as scrollable for hit testing but are // in the unscrolled transform space (scroll offset's parent). artifact.Chunk(*scroll_offset.Parent(), clip, effect) - .ScrollHitTest(scroll_offset); + .ScrollHitTest(&scroll_offset, + scroll_offset.ScrollNode()->ContainerRect()); } // Returns the |num|th scrollable layer. In CompositeAfterPaint, this will be
diff --git a/third_party/blink/renderer/platform/graphics/hit_test_rect.h b/third_party/blink/renderer/platform/graphics/hit_test_rect.h index 28f282d4..258b684 100644 --- a/third_party/blink/renderer/platform/graphics/hit_test_rect.h +++ b/third_party/blink/renderer/platform/graphics/hit_test_rect.h
@@ -11,10 +11,8 @@ namespace blink { +// TODO(pdr): Rename this TouchActionRect. struct PLATFORM_EXPORT HitTestRect { - // HitTestRect is a class shared by touch action region, wheel event handler - // region and non fast scrollable region. Wheel event handler region and - // non-fast scrollable rects use a |allowed_touch_action| of none. LayoutRect rect; TouchAction allowed_touch_action;
diff --git a/third_party/blink/renderer/platform/graphics/paint/display_item.h b/third_party/blink/renderer/platform/graphics/paint/display_item.h index c248132..15d9fe40 100644 --- a/third_party/blink/renderer/platform/graphics/paint/display_item.h +++ b/third_party/blink/renderer/platform/graphics/paint/display_item.h
@@ -127,6 +127,8 @@ // be painted. kHitTest, + // Used both for specifying the paint-order scroll location, and for non- + // composited scroll hit testing (see: scroll_hit_test_display_item.h). kScrollHitTest, kLayerChunkBackground,
diff --git a/third_party/blink/renderer/platform/graphics/paint/hit_test_data.cc b/third_party/blink/renderer/platform/graphics/paint/hit_test_data.cc index 2e3570b1..6e5c255 100644 --- a/third_party/blink/renderer/platform/graphics/paint/hit_test_data.cc +++ b/third_party/blink/renderer/platform/graphics/paint/hit_test_data.cc
@@ -9,7 +9,7 @@ namespace blink { -static String HitTestRectsAsString(HitTestRects rects) { +static String HitTestRectsAsString(const Vector<HitTestRect>& rects) { StringBuilder sb; sb.Append("["); bool first = true; @@ -36,19 +36,13 @@ printed_top_level_field = true; } - if (!wheel_event_handler_region.IsEmpty()) { + if (scroll_hit_test) { if (printed_top_level_field) sb.Append(", "); - sb.Append("wheel_event_handler_region: "); - sb.Append(HitTestRectsAsString(wheel_event_handler_region)); - printed_top_level_field = true; - } - - if (!non_fast_scrollable_region.IsEmpty()) { - if (printed_top_level_field) - sb.Append(", "); - sb.Append("non_fast_scrollable_region: "); - sb.Append(HitTestRectsAsString(non_fast_scrollable_region)); + sb.AppendFormat( + "scroll_hit_test: \"%s\" with offset %p", + scroll_hit_test->scroll_container_bounds.ToString().Utf8().data(), + scroll_hit_test->scroll_offset); printed_top_level_field = true; }
diff --git a/third_party/blink/renderer/platform/graphics/paint/hit_test_data.h b/third_party/blink/renderer/platform/graphics/paint/hit_test_data.h index 3c2c086..824d939 100644 --- a/third_party/blink/renderer/platform/graphics/paint/hit_test_data.h +++ b/third_party/blink/renderer/platform/graphics/paint/hit_test_data.h
@@ -6,34 +6,44 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_HIT_TEST_DATA_H_ #include "third_party/blink/renderer/platform/graphics/hit_test_rect.h" +#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h" #include "third_party/blink/renderer/platform/platform_export.h" namespace blink { -using HitTestRects = Vector<HitTestRect>; - struct PLATFORM_EXPORT HitTestData { - HitTestRects touch_action_rects; - HitTestRects wheel_event_handler_region; - HitTestRects non_fast_scrollable_region; + Vector<HitTestRect> touch_action_rects; + struct ScrollHitTest { + const TransformPaintPropertyNode* scroll_offset; + IntRect scroll_container_bounds; + bool operator==(const ScrollHitTest& rhs) const { + return scroll_offset == rhs.scroll_offset && + scroll_container_bounds == rhs.scroll_container_bounds; + } + }; + base::Optional<ScrollHitTest> scroll_hit_test; HitTestData() = default; HitTestData(const HitTestData& other) : touch_action_rects(other.touch_action_rects), - wheel_event_handler_region(other.wheel_event_handler_region), - non_fast_scrollable_region(other.non_fast_scrollable_region) {} + scroll_hit_test(other.scroll_hit_test) {} bool operator==(const HitTestData& rhs) const { return touch_action_rects == rhs.touch_action_rects && - wheel_event_handler_region == rhs.wheel_event_handler_region && - non_fast_scrollable_region == rhs.non_fast_scrollable_region; + scroll_hit_test == rhs.scroll_hit_test; } - void Append(const HitTestRect& rect) { - // TODO(836905): Support other types of hit testing. + void AppendTouchActionRect(const HitTestRect& rect) { touch_action_rects.push_back(rect); } + void SetScrollHitTest(const TransformPaintPropertyNode* scroll_offset, + const IntRect& scroll_container_bounds) { + DCHECK(!scroll_offset || scroll_offset->ScrollNode()); + scroll_hit_test = base::make_optional( + ScrollHitTest{scroll_offset, scroll_container_bounds}); + } + bool operator!=(const HitTestData& rhs) const { return !(*this == rhs); } String ToString() const;
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc b/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc index 753fe20..be5ce07 100644 --- a/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc +++ b/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc
@@ -11,6 +11,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" #include "third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.h" +#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/skia/include/core/SkRegion.h" @@ -67,7 +68,31 @@ const auto& hit_test = static_cast<const HitTestDisplayItem&>(item); if (!chunk.hit_test_data) chunk.hit_test_data = std::make_unique<HitTestData>(); - chunk.hit_test_data->Append(hit_test.GetHitTestRect()); + chunk.hit_test_data->AppendTouchActionRect(hit_test.GetHitTestRect()); + } + +#if DCHECK_IS_ON() + if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) { + // Because ScrollHitTestDisplayItems force new paint chunks (see: + // PaintChunker::IncrementDisplayItemIndex), they should only be the first + // item in a paint chunk. + DCHECK(!item.IsScrollHitTest() || item.Equals(*items.begin())); + } +#endif + } + + if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) { + // Because ScrollHitTestDisplayItems force new paint chunks (see: + // PaintChunker::IncrementDisplayItemIndex), they should only be the first + // item in a paint chunk. + if (items.begin()->IsScrollHitTest()) { + const auto& scroll_hit_test_item = + static_cast<const ScrollHitTestDisplayItem&>(*items.begin()); + if (!chunk.hit_test_data) + chunk.hit_test_data = std::make_unique<HitTestData>(); + chunk.hit_test_data->SetScrollHitTest( + scroll_hit_test_item.scroll_offset_node(), + scroll_hit_test_item.scroll_container_bounds()); } }
diff --git a/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.cc b/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.cc index 6128797..4a04ec12 100644 --- a/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.cc +++ b/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.cc
@@ -12,46 +12,57 @@ ScrollHitTestDisplayItem::ScrollHitTestDisplayItem( const DisplayItemClient& client, - const TransformPaintPropertyNode& scroll_offset_node) - : DisplayItem(client, kScrollHitTest, sizeof(*this)), - scroll_offset_node_(scroll_offset_node) { - DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - // The scroll offset transform node should have an associated scroll node. - DCHECK(scroll_offset_node_.ScrollNode()); + DisplayItem::Type type, + const TransformPaintPropertyNode* scroll_offset_node, + const IntRect& scroll_container_bounds) + : DisplayItem(client, type, sizeof(*this)), + scroll_offset_node_(scroll_offset_node), + scroll_container_bounds_(scroll_container_bounds) { + DCHECK(RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()); + DCHECK(IsScrollHitTest()); } ScrollHitTestDisplayItem::~ScrollHitTestDisplayItem() = default; bool ScrollHitTestDisplayItem::Equals(const DisplayItem& other) const { return DisplayItem::Equals(other) && - &scroll_node() == - &static_cast<const ScrollHitTestDisplayItem&>(other).scroll_node(); + scroll_offset_node() == + static_cast<const ScrollHitTestDisplayItem&>(other) + .scroll_offset_node() && + scroll_container_bounds() == + static_cast<const ScrollHitTestDisplayItem&>(other) + .scroll_container_bounds(); } #if DCHECK_IS_ON() void ScrollHitTestDisplayItem::PropertiesAsJSON(JSONObject& json) const { DisplayItem::PropertiesAsJSON(json); - json.SetString("scrollOffsetNode", - String::Format("%p", &scroll_offset_node_)); + json.SetString("scrollOffsetNode", String::Format("%p", scroll_offset_node_)); + json.SetString("scrollContainerBounds", scroll_container_bounds_.ToString()); } #endif void ScrollHitTestDisplayItem::Record( GraphicsContext& context, const DisplayItemClient& client, - const TransformPaintPropertyNode& scroll_offset_node) { + DisplayItem::Type type, + const TransformPaintPropertyNode* scroll_offset_node, + const IntRect& scroll_container_bounds) { PaintController& paint_controller = context.GetPaintController(); // The scroll hit test should be in the non-scrolled transform space and // therefore should not be scrolled by the associated scroll offset. DCHECK_NE(&paint_controller.CurrentPaintChunkProperties().Transform(), - &scroll_offset_node); + scroll_offset_node); if (paint_controller.DisplayItemConstructionIsDisabled()) return; + if (paint_controller.UseCachedItemIfPossible(client, type)) + return; + paint_controller.CreateAndAppend<ScrollHitTestDisplayItem>( - client, scroll_offset_node); + client, type, scroll_offset_node, scroll_container_bounds); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h b/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h index 082b202..cd115e2 100644 --- a/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h +++ b/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h
@@ -14,25 +14,47 @@ class GraphicsContext; -// Placeholder display item for creating a special cc::Layer marked as being -// scrollable in PaintArtifactCompositor. A display item is needed because -// scroll hit testing must be in paint order. +// Display item for marking a region as scrollable. This should be emitted in +// the non-scrolling paint property tree state (in other words, this item should +// not scroll). A display item is needed because hit testing is in paint order. // -// The scroll hit test display item keeps track of the scroll offset translation -// node which also has a reference to the associated scroll node. The scroll hit -// test display item should be in the non-scrolled transform space and therefore -// should not be scrolled by the associated scroll offset transform. +// This serves three purposes: +// 1. Creating non-fast scrollable regions for non-composited scrollers. +// (When PaintNonFastScrollableRegions is enabled). +// Scrollable areas create a non-fast scrollable region in the +// non-scrolling paint property tree state. Pre-CompositeAfterPaint, we skip +// painting these for composited scrollers. With CompositeAfterPaint, we +// paint the non-fast item and later ignore it if the scroller was composited +// (see: PaintArtifactCompositor::UpdateNonFastScrollableRegions). +// +// 2. Creating non-fast scrollable regions for plugins and resize handles. +// (When PaintNonFastScrollableRegions is enabled). +// Plugins that have blocking event handlers and resize handles both need to +// prevent composited scrolling. A different display item type is used +// (kPluginScrollHitTest and kResizerScrollHitTest) to disambiguate multiple +// scroll hit test display items (e.g., if a scroller is non-composited and +// has a resizer). +// +// 3. Creating cc::Layers marked as being scrollable. +// (when CompositeAfterPaint is enabled). +// A single cc::Layer must be marked as being "scrollable", and this display +// item is used by PaintArtifactCompositor to create the scrollable cc::Layer. class PLATFORM_EXPORT ScrollHitTestDisplayItem final : public DisplayItem { public: - ScrollHitTestDisplayItem( - const DisplayItemClient&, - const TransformPaintPropertyNode& scroll_offset_node); + ScrollHitTestDisplayItem(const DisplayItemClient&, + DisplayItem::Type, + const TransformPaintPropertyNode* scroll_offset_node, + const IntRect& scroll_container_bounds); ~ScrollHitTestDisplayItem() override; - const TransformPaintPropertyNode& scroll_offset_node() const { + const TransformPaintPropertyNode* scroll_offset_node() const { return scroll_offset_node_; } + const IntRect& scroll_container_bounds() const { + return scroll_container_bounds_; + } + // DisplayItem bool Equals(const DisplayItem&) const override; #if DCHECK_IS_ON() @@ -41,17 +63,26 @@ // Create and append a ScrollHitTestDisplayItem onto the context. This is // similar to a recorder class (e.g., DrawingRecorder) but just emits a single - // item. + // item. If no |scroll_offset_node| is passed in, this display item will only + // be used for creating a non-fast-scrollable-region. static void Record(GraphicsContext&, const DisplayItemClient&, - const TransformPaintPropertyNode& scroll_offset_node); + DisplayItem::Type, + const TransformPaintPropertyNode* scroll_offset_node, + const IntRect& scroll_container_bounds); - private: - const ScrollPaintPropertyNode& scroll_node() const { - return *scroll_offset_node_.ScrollNode(); + const ScrollPaintPropertyNode* scroll_node() const { + return scroll_offset_node_->ScrollNode(); } - const TransformPaintPropertyNode& scroll_offset_node_; + private: + // The scroll offset transform node if this ScrollHitTestDisplayItem could be + // used for composited scrolling, or null if it is only used to prevent + // composited scrolling. + const TransformPaintPropertyNode* scroll_offset_node_; + // The bounds of the scroll container, including scrollbars. We cannot use + // scroll_node().container_rect() because it does not include scrollbars. + const IntRect scroll_container_bounds_; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc index 0dd41b7c..5d6c793 100644 --- a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc +++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
@@ -134,7 +134,7 @@ ? static_cast<double>(current().marked_bytes) / current_.object_size_in_bytes_before_sweeping : 0.0; - current_.gc_nested_in_v8_ = gc_nested_in_v8_; + current_.gc_nested_in_v8 = gc_nested_in_v8_; gc_nested_in_v8_ = base::TimeDelta(); // Reset the current state. static_assert(std::is_trivially_copyable<Event>::value,
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.h b/third_party/blink/renderer/platform/heap/heap_stats_collector.h index 709cb4e..7da80ced 100644 --- a/third_party/blink/renderer/platform/heap/heap_stats_collector.h +++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.h
@@ -278,7 +278,7 @@ size_t partition_alloc_bytes_before_sweeping = 0; double live_object_rate = 0; size_t wrapper_count_before_sweeping = 0; - base::TimeDelta gc_nested_in_v8_; + base::TimeDelta gc_nested_in_v8; }; // Indicates a new garbage collection cycle. @@ -348,7 +348,6 @@ // Statistics for the previously running garbage collection. const Event& previous() const { return previous_; } - void RegisterObserver(ThreadHeapStatsObserver* observer); void UnregisterObserver(ThreadHeapStatsObserver* observer);
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc index b5aab047..26fc059 100644 --- a/third_party/blink/renderer/platform/heap/heap_test.cc +++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -1565,6 +1565,101 @@ TestSupportingGC::PreciselyCollectGarbage(); } +#if DCHECK_IS_ON() +class ResurrectingPreFinalizer + : public GarbageCollected<ResurrectingPreFinalizer> { + USING_PRE_FINALIZER(ResurrectingPreFinalizer, Dispose); + + public: + enum TestType { + kHeapVectorMember, + kHeapHashSetMember, + kHeapHashSetWeakMember + }; + + class GlobalStorage : public GarbageCollected<GlobalStorage> { + public: + GlobalStorage() { + // Reserve storage upfront to avoid allocations during pre-finalizer + // insertion. + vector_member.ReserveCapacity(32); + hash_set_member.ReserveCapacityForSize(32); + hash_set_weak_member.ReserveCapacityForSize(32); + } + + void Trace(Visitor* visitor) { + visitor->Trace(vector_member); + visitor->Trace(hash_set_member); + visitor->Trace(hash_set_weak_member); + } + + HeapVector<Member<LinkedObject>> vector_member; + HeapHashSet<Member<LinkedObject>> hash_set_member; + HeapHashSet<WeakMember<LinkedObject>> hash_set_weak_member; + }; + + ResurrectingPreFinalizer(TestType test_type, + GlobalStorage* storage, + LinkedObject* object_that_dies) + : test_type_(test_type), + storage_(storage), + object_that_dies_(object_that_dies) {} + + void Trace(Visitor* visitor) { + visitor->Trace(storage_); + visitor->Trace(object_that_dies_); + } + + private: + void Dispose() { EXPECT_DEATH(Test(), ""); } + + void Test() { + switch (test_type_) { + case TestType::kHeapVectorMember: + storage_->vector_member.push_back(object_that_dies_); + break; + case TestType::kHeapHashSetMember: + storage_->hash_set_member.insert(object_that_dies_); + break; + case TestType::kHeapHashSetWeakMember: + storage_->hash_set_weak_member.insert(object_that_dies_); + break; + } + } + + TestType test_type_; + Member<GlobalStorage> storage_; + Member<LinkedObject> object_that_dies_; +}; + +TEST(HeapDeathTest, DiesOnResurrectedHeapVectorMember) { + Persistent<ResurrectingPreFinalizer::GlobalStorage> storage( + MakeGarbageCollected<ResurrectingPreFinalizer::GlobalStorage>()); + MakeGarbageCollected<ResurrectingPreFinalizer>( + ResurrectingPreFinalizer::kHeapVectorMember, storage.Get(), + MakeGarbageCollected<LinkedObject>()); + TestSupportingGC::PreciselyCollectGarbage(); +} + +TEST(HeapDeathTest, DiesOnResurrectedHeapHashSetMember) { + Persistent<ResurrectingPreFinalizer::GlobalStorage> storage( + MakeGarbageCollected<ResurrectingPreFinalizer::GlobalStorage>()); + MakeGarbageCollected<ResurrectingPreFinalizer>( + ResurrectingPreFinalizer::kHeapHashSetMember, storage.Get(), + MakeGarbageCollected<LinkedObject>()); + TestSupportingGC::PreciselyCollectGarbage(); +} + +TEST(HeapDeathTest, DiesOnResurrectedHeapHashSetWeakMember) { + Persistent<ResurrectingPreFinalizer::GlobalStorage> storage( + MakeGarbageCollected<ResurrectingPreFinalizer::GlobalStorage>()); + MakeGarbageCollected<ResurrectingPreFinalizer>( + ResurrectingPreFinalizer::kHeapHashSetWeakMember, storage.Get(), + MakeGarbageCollected<LinkedObject>()); + TestSupportingGC::PreciselyCollectGarbage(); +} +#endif // DCHECK_IS_ON() + class LargeMixin : public GarbageCollected<LargeMixin>, public Mixin { USING_GARBAGE_COLLECTED_MIXIN(LargeMixin);
diff --git a/third_party/blink/renderer/platform/heap/marking_verifier_test.cc b/third_party/blink/renderer/platform/heap/marking_verifier_test.cc index 16ef9ef0..b5ad847 100644 --- a/third_party/blink/renderer/platform/heap/marking_verifier_test.cc +++ b/third_party/blink/renderer/platform/heap/marking_verifier_test.cc
@@ -11,6 +11,7 @@ namespace blink { +#if DCHECK_IS_ON() class MarkingVerifierDeathTest : public TestSupportingGC {}; namespace { @@ -23,34 +24,17 @@ enum TestType { kMember, kWeakMember, - kHeapVectorMember, - kHeapHashSetMember, - kHeapHashSetWeakMember }; class GlobalStorage : public GarbageCollected<GlobalStorage> { public: - GlobalStorage() { - // Reserve storage upfront to avoid allocations during pre-finalizer - // insertion. - vector_member.ReserveCapacity(32); - hash_set_member.ReserveCapacityForSize(32); - hash_set_weak_member.ReserveCapacityForSize(32); - } - void Trace(Visitor* visitor) { visitor->Trace(strong); visitor->Trace(weak); - visitor->Trace(vector_member); - visitor->Trace(hash_set_member); - visitor->Trace(hash_set_weak_member); } Member<LinkedObject> strong; WeakMember<LinkedObject> weak; - HeapVector<Member<LinkedObject>> vector_member; - HeapHashSet<Member<LinkedObject>> hash_set_member; - HeapHashSet<WeakMember<LinkedObject>> hash_set_weak_member; }; ResurrectingPreFinalizer(TestType test_type, @@ -74,15 +58,6 @@ case TestType::kWeakMember: storage_->weak = object_that_dies_; break; - case TestType::kHeapVectorMember: - storage_->vector_member.push_back(object_that_dies_); - break; - case TestType::kHeapHashSetMember: - storage_->hash_set_member.insert(object_that_dies_); - break; - case TestType::kHeapHashSetWeakMember: - storage_->hash_set_weak_member.insert(object_that_dies_); - break; } } @@ -118,44 +93,6 @@ ASSERT_DEATH_IF_SUPPORTED(PreciselyCollectGarbage(), "MarkingVerifier: Encountered unmarked object."); } - -TEST_F(MarkingVerifierDeathTest, DiesOnResurrectedHeapVectorMember) { - if (!ThreadState::Current()->VerifyMarkingEnabled()) - return; - - Persistent<ResurrectingPreFinalizer::GlobalStorage> storage( - MakeGarbageCollected<ResurrectingPreFinalizer::GlobalStorage>()); - MakeGarbageCollected<ResurrectingPreFinalizer>( - ResurrectingPreFinalizer::kHeapVectorMember, storage.Get(), - MakeGarbageCollected<LinkedObject>()); - ASSERT_DEATH_IF_SUPPORTED(PreciselyCollectGarbage(), - "MarkingVerifier: Encountered unmarked object."); -} - -TEST_F(MarkingVerifierDeathTest, DiesOnResurrectedHeapHashSetMember) { - if (!ThreadState::Current()->VerifyMarkingEnabled()) - return; - - Persistent<ResurrectingPreFinalizer::GlobalStorage> storage( - MakeGarbageCollected<ResurrectingPreFinalizer::GlobalStorage>()); - MakeGarbageCollected<ResurrectingPreFinalizer>( - ResurrectingPreFinalizer::kHeapHashSetMember, storage.Get(), - MakeGarbageCollected<LinkedObject>()); - ASSERT_DEATH_IF_SUPPORTED(PreciselyCollectGarbage(), - "MarkingVerifier: Encountered unmarked object."); -} - -TEST_F(MarkingVerifierDeathTest, DiesOnResurrectedHeapHashSetWeakMember) { - if (!ThreadState::Current()->VerifyMarkingEnabled()) - return; - - Persistent<ResurrectingPreFinalizer::GlobalStorage> storage( - MakeGarbageCollected<ResurrectingPreFinalizer::GlobalStorage>()); - MakeGarbageCollected<ResurrectingPreFinalizer>( - ResurrectingPreFinalizer::kHeapHashSetWeakMember, storage.Get(), - MakeGarbageCollected<LinkedObject>()); - ASSERT_DEATH_IF_SUPPORTED(PreciselyCollectGarbage(), - "MarkingVerifier: Encountered unmarked object."); -} +#endif // DCHECK_IS_ON() } // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc index 5092207..bfc70c9 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -637,7 +637,7 @@ } if (sweep_completed) { - PostSweep(); + NotifySweepDone(); } } @@ -884,7 +884,7 @@ if (!IsSweepingInProgress()) { // Sweeping was finished during the atomic pause. Update statistics needs to // run outside of the top-most stats scope. - UpdateStatisticsAfterSweeping(); + PostSweep(); } } @@ -918,7 +918,7 @@ if (!was_in_atomic_pause) LeaveAtomicPause(); } - PostSweep(); + NotifySweepDone(); } void ThreadState::SynchronizeAndFinishConcurrentSweeping() { @@ -1011,7 +1011,7 @@ UMA_HISTOGRAM_TIMES("BlinkGC.TimeForIncrementalMarking", event.incremental_marking_time()); UMA_HISTOGRAM_TIMES("BlinkGC.TimeForMarking", event.marking_time()); - UMA_HISTOGRAM_TIMES("BlinkGC.TimeForNestedInV8", event.gc_nested_in_v8_); + UMA_HISTOGRAM_TIMES("BlinkGC.TimeForNestedInV8", event.gc_nested_in_v8); UMA_HISTOGRAM_TIMES("BlinkGC.TimeForSweepingForeground", event.foreground_sweeping_time()); UMA_HISTOGRAM_TIMES("BlinkGC.TimeForSweepingBackground", @@ -1110,30 +1110,29 @@ } // namespace -void ThreadState::UpdateStatisticsAfterSweeping() { - DCHECK(!IsSweepingInProgress()); - DCHECK(Heap().stats_collector()->is_started()); - Heap().stats_collector()->NotifySweepingCompleted(); - if (IsMainThread()) - UpdateHistograms(Heap().stats_collector()->previous()); - // Emit trace counters for all threads. - UpdateTraceCounters(*Heap().stats_collector()); +void ThreadState::NotifySweepDone() { + DCHECK(CheckThread()); + SetGCPhase(GCPhase::kNone); + if (!in_atomic_pause()) { + PostSweep(); + } } void ThreadState::PostSweep() { - DCHECK(CheckThread()); - - SetGCPhase(GCPhase::kNone); + DCHECK(!in_atomic_pause()); + DCHECK(!IsSweepingInProgress()); gc_age_++; for (auto* const observer : observers_) observer->OnCompleteSweepDone(); - if (!in_atomic_pause()) { - // Immediately update the statistics if running outside of the atomic pause. - UpdateStatisticsAfterSweeping(); - } + Heap().stats_collector()->NotifySweepingCompleted(); + + if (IsMainThread()) + UpdateHistograms(Heap().stats_collector()->previous()); + // Emit trace counters for all threads. + UpdateTraceCounters(*Heap().stats_collector()); } void ThreadState::SafePoint(BlinkGC::StackState stack_state) {
diff --git a/third_party/blink/renderer/platform/heap/thread_state.h b/third_party/blink/renderer/platform/heap/thread_state.h index 6b0ae29..13dc93fb 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.h +++ b/third_party/blink/renderer/platform/heap/thread_state.h
@@ -293,6 +293,7 @@ void CompleteSweep(); void FinishSnapshot(); + void NotifySweepDone(); void PostSweep(); // Returns whether it is currently allowed to allocate an object. Mainly used @@ -500,8 +501,6 @@ BlinkGC::SweepingType, BlinkGC::GCReason); - void UpdateStatisticsAfterSweeping(); - // The version is needed to be able to start incremental marking. void MarkPhasePrologue(BlinkGC::StackState, BlinkGC::MarkingType,
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index e9fb575..06c015a 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -435,12 +435,14 @@ // Synchronous requests should not work with throttling or stopping. Also, // disables throttling for the case that can be used for aka long-polling - // requests, but allows stopping for long-polling requests. + // requests, but allows stopping for long-polling requests. We don't want + // to throttle a request with keepalive set because such a request is + // expected to work even when a frame is freezed/detached. // Top level frame main resource loads are also not throttleable or // stoppable. We also disable throttling and stopping for non-http[s] // requests. if (resource_->Options().synchronous_policy == kRequestSynchronously || - !request.Url().ProtocolIsInHTTPFamily()) { + request.GetKeepalive() || !request.Url().ProtocolIsInHTTPFamily()) { throttle_option = ResourceLoadScheduler::ThrottleOption::kCanNotBeStoppedOrThrottled; } else if (!IsThrottlableRequestContext(request.GetRequestContext())) {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 84e99de4..2fa46a4583 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1145,6 +1145,11 @@ // Android does not have support for PagePopup status: {"Android": "", "default": "stable"}, }, + // See: https://docs.google.com/document/d/1IyYJ6bVF7KZq96b_s5NrAzGtVoBXn_LQnya9y4yT3iw/view + { + name: "PaintNonFastScrollableRegions", + implied_by: ["CompositeAfterPaint"], + }, { name: "PaintUnderInvalidationChecking", settable_from_internals: true, @@ -1614,6 +1619,9 @@ status: "experimental" }, { + name: "UseWindowsSystemColors", + }, + { name: "V8IdleTasks", }, {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.cc index 9a6a2c4..7c682ce 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder.cc
@@ -226,15 +226,7 @@ // with frames. DCHECK(GetFrameSchedulerForQueue(queue)); const MainThreadTaskQueue::QueueType queue_type = queue->queue_type(); - // TODO(altimin): Remove kDefault once there is no per-frame kDefault queue. - DCHECK(queue_type == MainThreadTaskQueue::QueueType::kDefault || - queue_type == MainThreadTaskQueue::QueueType::kFrameLoading || - queue_type == MainThreadTaskQueue::QueueType::kFrameLoadingControl || - queue_type == MainThreadTaskQueue::QueueType::kFrameThrottleable || - queue_type == MainThreadTaskQueue::QueueType::kFrameDeferrable || - queue_type == MainThreadTaskQueue::QueueType::kFramePausable || - queue_type == MainThreadTaskQueue::QueueType::kFrameUnpausable || - queue_type == MainThreadTaskQueue::QueueType::kIdle); + DCHECK(MainThreadTaskQueue::IsPerFrameTaskQueue(queue_type)); const std::string histogram_name = std::string("RendererScheduler.TimeRunningOtherFramesWhileTaskReady.") +
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc index 7f0d859..e4d579a 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc
@@ -70,6 +70,40 @@ return nullptr; } +// static +bool MainThreadTaskQueue::IsPerFrameTaskQueue( + MainThreadTaskQueue::QueueType queue_type) { + switch (queue_type) { + // TODO(altimin): Remove kDefault once there is no per-frame kDefault queue. + case MainThreadTaskQueue::QueueType::kDefault: + case MainThreadTaskQueue::QueueType::kFrameLoading: + case MainThreadTaskQueue::QueueType::kFrameLoadingControl: + case MainThreadTaskQueue::QueueType::kFrameThrottleable: + case MainThreadTaskQueue::QueueType::kFrameDeferrable: + case MainThreadTaskQueue::QueueType::kFramePausable: + case MainThreadTaskQueue::QueueType::kFrameUnpausable: + case MainThreadTaskQueue::QueueType::kIdle: + case MainThreadTaskQueue::QueueType::kWebScheduling: + return true; + case MainThreadTaskQueue::QueueType::kControl: + case MainThreadTaskQueue::QueueType::kUnthrottled: + case MainThreadTaskQueue::QueueType::kCompositor: + case MainThreadTaskQueue::QueueType::kTest: + case MainThreadTaskQueue::QueueType::kV8: + case MainThreadTaskQueue::QueueType::kIPC: + case MainThreadTaskQueue::QueueType::kInput: + case MainThreadTaskQueue::QueueType::kDetached: + case MainThreadTaskQueue::QueueType::kCleanup: + case MainThreadTaskQueue::QueueType::kOther: + return false; + case MainThreadTaskQueue::QueueType::kCount: + NOTREACHED(); + return false; + } + NOTREACHED(); + return false; +} + MainThreadTaskQueue::QueueClass MainThreadTaskQueue::QueueClassForQueueType( QueueType type) { switch (type) {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h index 9ff2606..c7d2c20 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
@@ -86,6 +86,11 @@ // lifetime. static const char* NameForQueueType(QueueType queue_type); + // Returns true if task queues of the given queue type can be created on a + // per-frame basis, and false if they are only created on a shared basis for + // the entire main thread. + static bool IsPerFrameTaskQueue(QueueType); + // High-level category used by MainThreadScheduler to make scheduling // decisions. enum class QueueClass {
diff --git a/third_party/blink/renderer/platform/testing/paint_test_configurations.h b/third_party/blink/renderer/platform/testing/paint_test_configurations.h index 81c3300c..93c3686 100644 --- a/third_party/blink/renderer/platform/testing/paint_test_configurations.h +++ b/third_party/blink/renderer/platform/testing/paint_test_configurations.h
@@ -16,6 +16,7 @@ kCompositeAfterPaint = 1 << 1, kUnderInvalidationChecking = 1 << 2, kFastBorderRadius = 1 << 3, + kPaintNonFastScrollableRegions = 1 << 4, }; class PaintTestConfigurations @@ -23,14 +24,21 @@ private ScopedBlinkGenPropertyTreesForTest, private ScopedCompositeAfterPaintForTest, private ScopedPaintUnderInvalidationCheckingForTest, - private ScopedFastBorderRadiusForTest { + private ScopedFastBorderRadiusForTest, + private ScopedPaintNonFastScrollableRegionsForTest { public: PaintTestConfigurations() : ScopedBlinkGenPropertyTreesForTest(GetParam() & kBlinkGenPropertyTrees), ScopedCompositeAfterPaintForTest(GetParam() & kCompositeAfterPaint), ScopedPaintUnderInvalidationCheckingForTest(GetParam() & kUnderInvalidationChecking), - ScopedFastBorderRadiusForTest(GetParam() & kFastBorderRadius) {} + ScopedFastBorderRadiusForTest(GetParam() & kFastBorderRadius), + // Because PaintNonFastScrollableRegions is implied by + // CompositeAfterPaint (see: runtime_eanbled_features.json5), we must + // enable the scoped flag for (PNFSR || CAP). + ScopedPaintNonFastScrollableRegionsForTest( + GetParam() & kPaintNonFastScrollableRegions || + GetParam() & kCompositeAfterPaint) {} ~PaintTestConfigurations() { // Must destruct all objects before toggling back feature flags. WebHeap::CollectAllGarbageForTesting(); @@ -55,6 +63,11 @@ kBlinkGenPropertyTrees | kCompositeAfterPaint, \ kBlinkGenPropertyTrees | kFastBorderRadius)) +#define INSTANTIATE_SCROLL_HIT_TEST_SUITE_P(test_class) \ + INSTANTIATE_TEST_SUITE_P( \ + All, test_class, \ + ::testing::Values(kPaintNonFastScrollableRegions, kCompositeAfterPaint)) + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_PAINT_TEST_CONFIGURATIONS_H_
diff --git a/third_party/blink/renderer/platform/testing/test_paint_artifact.cc b/third_party/blink/renderer/platform/testing/test_paint_artifact.cc index ae2f359..a52c83f 100644 --- a/third_party/blink/renderer/platform/testing/test_paint_artifact.cc +++ b/third_party/blink/renderer/platform/testing/test_paint_artifact.cc
@@ -79,8 +79,9 @@ } TestPaintArtifact& TestPaintArtifact::ScrollHitTest( - const TransformPaintPropertyNode& scroll_offset) { - return ScrollHitTest(NewClient(), scroll_offset); + const TransformPaintPropertyNode* scroll_offset, + const IntRect& scroll_container_bounds) { + return ScrollHitTest(NewClient(), scroll_offset, scroll_container_bounds); } TestPaintArtifact& TestPaintArtifact::RectDrawing(FakeDisplayItemClient& client, @@ -102,9 +103,11 @@ TestPaintArtifact& TestPaintArtifact::ScrollHitTest( FakeDisplayItemClient& client, - const TransformPaintPropertyNode& scroll_offset) { + const TransformPaintPropertyNode* scroll_offset, + const IntRect& scroll_container_bounds) { display_item_list_.AllocateAndConstruct<ScrollHitTestDisplayItem>( - client, scroll_offset); + client, DisplayItem::kScrollHitTest, scroll_offset, + scroll_container_bounds); return *this; }
diff --git a/third_party/blink/renderer/platform/testing/test_paint_artifact.h b/third_party/blink/renderer/platform/testing/test_paint_artifact.h index 57255bb..838ab969 100644 --- a/third_party/blink/renderer/platform/testing/test_paint_artifact.h +++ b/third_party/blink/renderer/platform/testing/test_paint_artifact.h
@@ -94,7 +94,8 @@ // automatically created client. TestPaintArtifact& RectDrawing(const FloatRect& bounds, Color color); TestPaintArtifact& ScrollHitTest( - const TransformPaintPropertyNode& scroll_offset); + const TransformPaintPropertyNode* scroll_offset, + const IntRect& scroll_container_bounds); TestPaintArtifact& ForeignLayer(scoped_refptr<cc::Layer> layer, const FloatPoint& offset); @@ -105,7 +106,8 @@ Color); TestPaintArtifact& ScrollHitTest( FakeDisplayItemClient&, - const TransformPaintPropertyNode& scroll_offset); + const TransformPaintPropertyNode* scroll_offset, + const IntRect& scroll_container_bounds); // Sets fake bounds for the last paint chunk. Note that the bounds will be // overwritten when the PaintArtifact is constructed if the chunk has any
diff --git a/third_party/blink/renderer/platform/wtf/forward.h b/third_party/blink/renderer/platform/wtf/forward.h index 71c32147..17c1688 100644 --- a/third_party/blink/renderer/platform/wtf/forward.h +++ b/third_party/blink/renderer/platform/wtf/forward.h
@@ -45,6 +45,7 @@ class AtomicString; class BigInt64Array; class BigUint64Array; +class CaseMap; class Float32Array; class Float64Array; class Int8Array; @@ -55,6 +56,7 @@ class StringBuilder; class StringImpl; class StringView; +class TextOffsetMap; class TextStream; class Uint8Array; class Uint8ClampedArray; @@ -71,6 +73,7 @@ using WTF::AtomicString; using WTF::BigInt64Array; using WTF::BigUint64Array; +using WTF::CaseMap; using WTF::Float32Array; using WTF::Float64Array; using WTF::Int8Array; @@ -81,6 +84,7 @@ using WTF::StringBuilder; using WTF::StringImpl; using WTF::StringView; +using WTF::TextOffsetMap; using WTF::Uint8Array; using WTF::Uint8ClampedArray; using WTF::Uint16Array;
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint index 66c80dc..3a68809 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint +++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
@@ -1,7 +1,6 @@ # Expectations for CompositeAfterPaint # See: https://docs.google.com/document/d/1QCM912Dr6u38DqyQqd7pxQxDy8FFOoWMMDq7uAXqKdA/view Bug(none) http/tests/devtools/tracing/ [ Skip ] -Bug(none) scrollingcoordinator/ [ Skip ] Bug(none) virtual/disable-blink-gen-property-trees/ [ Skip ] @@ -19,6 +18,10 @@ Bug(none) virtual/threaded/printing/ [ Skip ] Bug(none) virtual/threaded/http/tests/devtools/tracing/ [ Skip ] +# Because PaintNonFastScrollableRegions implies CompositeAfterPaint, these tests +# have already been run as part of the non-virtual test suite. +Bug(none) virtual/paint-non-fast-scrollable-regions/ [ Skip ] + # Fail before CompositeAfterPaint but pass with it. crbug.com/472330 fast/borders/border-image-outset-split-inline-vertical-lr.html [ Pass ] crbug.com/736052 compositing/overflow/composited-scroll-with-fractional-translation.html [ Pass ] @@ -502,6 +505,19 @@ crbug.com/979369 svg/masking/mask-type-luminance.svg [ Failure ] crbug.com/979369 svg/masking/mask-type-not-set.svg [ Failure ] +# CompositeAfterPaint incorrectly composites all scrollers, and these do not +# produce non-fast scrollable regions, so there are differences in the non-fast +# regions compared to pre-CompositeAfterPaint. +crbug.com/980290 scrollingcoordinator/donot-compute-non-fast-scrollable-region-for-hidden-frames.html [ Failure ] +crbug.com/980290 scrollingcoordinator/non-fast-scrollable-region-nested.html [ Failure ] +crbug.com/980290 scrollingcoordinator/non-fast-scrollable-region-scaled-iframe.html [ Failure ] +crbug.com/980290 scrollingcoordinator/non-fast-scrollable-region-transformed-iframe.html [ Failure ] +crbug.com/980290 scrollingcoordinator/non-fast-scrollable-transform-changed.html [ Failure ] +crbug.com/980290 scrollingcoordinator/non-fast-scrollable-visibility-change.html [ Failure ] + +# Need to support painting non-fast scrollable regions for plugins. +crbug.com/864567 scrollingcoordinator/plugin-with-wheel-handler.html [ Failure ] + # These failures need to be triaged and are being added to unblock the CQ (see: https://crbug.com/966981). crbug.com/966981 virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-disabled-frame-no-scroll-manual.tentative.html [ Failure ] crbug.com/966981 virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-main-frame-manual.tentative.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 2c190958..d4810f0 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -137,8 +137,25 @@ Bug(none) virtual/composite-after-paint/paint/background/ [ Pass ] Bug(none) virtual/composite-after-paint/paint/filters/ [ Pass ] Bug(none) virtual/composite-after-paint/paint/frames [ Pass ] +Bug(none) virtual/composite-after-paint/scrollingcoordinator [ Pass ] # --- End CompositeAfterPaint Tests -- +# CompositeAfterPaint incorrectly composites all scrollers, and these do not +# produce non-fast scrollable regions, so there are differences in the non-fast +# regions compared to pre-CompositeAfterPaint. +crbug.com/980290 virtual/composite-after-paint/scrollingcoordinator/donot-compute-non-fast-scrollable-region-for-hidden-frames.html [ Failure ] +crbug.com/980290 virtual/composite-after-paint/scrollingcoordinator/non-fast-scrollable-region-nested.html [ Failure ] +crbug.com/980290 virtual/composite-after-paint/scrollingcoordinator/non-fast-scrollable-region-scaled-iframe.html [ Failure ] +crbug.com/980290 virtual/composite-after-paint/scrollingcoordinator/non-fast-scrollable-region-transformed-iframe.html [ Failure ] +crbug.com/980290 virtual/composite-after-paint/scrollingcoordinator/non-fast-scrollable-transform-changed.html [ Failure ] +crbug.com/980290 virtual/composite-after-paint/scrollingcoordinator/non-fast-scrollable-visibility-change.html [ Failure ] + +# Need to support painting non-fast scrollable regions for plugins. +crbug.com/864567 virtual/composite-after-paint/scrollingcoordinator/plugin-with-wheel-handler.html [ Failure ] +crbug.com/864567 virtual/paint-non-fast-scrollable-regions/scrollingcoordinator/plugin-with-wheel-handler.html [ Failure ] +crbug.com/864567 virtual/paint-non-fast-scrollable-regions/scrollingcoordinator/donot-compute-non-fast-scrollable-region-for-hidden-frames.html [ Failure ] +crbug.com/864567 virtual/paint-non-fast-scrollable-regions/scrollingcoordinator/non-fast-scrollable-region-nested.html [ Failure ] + # Subpixel differences crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-color-5.html [ Failure ] crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ] @@ -2922,6 +2939,7 @@ crbug.com/492511 [ Mac ] fast/text/international/arabic-justify.html [ Failure ] ### Tests added for non-fast scrolling regions that break as a result of compositor scrolling. +# TODO(pdr): Mark these as passing when PaintNonFastScrollableRegions launches. crbug.com/817600 virtual/threaded/fast/scrolling/non-composited-scroller-in-scrolled-absolute-scroller.html [ Failure ] crbug.com/817600 virtual/threaded/fast/scrolling/non-composited-scroller-in-scrolled-position-fixed-scroller.html [ Failure ] crbug.com/817600 virtual/threaded/fast/scrolling/non-composited-scroller-in-sticky.html [ Failure ] @@ -3296,6 +3314,8 @@ crbug.com/785230 external/wpt/css/css-text-decor/text-decoration-thickness-vertical-002.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Mac10.10 ] external/wpt/workers/data-url-shared.html [ Crash ] +crbug.com/626703 [ Mac10.12 ] external/wpt/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv.html [ Timeout ] crbug.com/626703 [ Win7 ] external/wpt/pointerevents/pointerevent_touch-action-svg-none-test_touch.html [ Timeout ] crbug.com/626703 [ Win7 ] external/wpt/pointerevents/extension/pointerevent_touch-action-pan-right-css_touch.html [ Timeout ] crbug.com/626703 [ Mac10.11 ] external/wpt/shape-detection/detection-security-test.https.html [ Timeout ] @@ -6369,14 +6389,6 @@ crbug.com/986477 [ Win ] external/wpt/cookies/path/match.html [ Pass Timeout ] crbug.com/986477 [ Win ] virtual/samesite-by-default-cookies/external/wpt/cookies/path/match.html [ Pass Timeout ] -# Sheriff 2019-07-23 -crbug.com/986019 animations/web-animations/animation-state-changes-positive-playback-rate.html [ Pass Failure ] -crbug.com/986019 virtual/threaded/animations/web-animations/animation-state-changes-positive-playback-rate.html [ Pass Failure ] -crbug.com/986019 virtual/disable-blink-gen-property-trees/animations/web-animations/animation-state-changes-positive-playback-rate.html [ Pass Failure ] -crbug.com/986666 animations/web-animations/animation-state-changes-negative-playback-rate.html [ Pass Failure ] -crbug.com/986666 virtual/threaded/animations/web-animations/animation-state-changes-negative-playback-rate.html [ Pass Failure ] -crbug.com/986666 virtual/disable-blink-gen-property-trees/animations/web-animations/animation-state-changes-negative-playback-rate.html [ Pass Failure ] - # Sheriff 2019-07-24 crbug.com/986019 animations/play-state.html [ Pass Timeout ] crbug.com/986019 virtual/threaded/animations/play-state.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index db973a8..9e6a9188 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -313,6 +313,16 @@ "args": ["--enable-blink-features=CompositeAfterPaint"] }, { + "prefix": "composite-after-paint", + "base": "scrollingcoordinator", + "args": ["--enable-blink-features=CompositeAfterPaint"] + }, + { + "prefix": "paint-non-fast-scrollable-regions", + "base": "scrollingcoordinator", + "args": ["--enable-blink-features=PaintNonFastScrollableRegions"] + }, + { "prefix": "scalefactor200", "base": "fast/hidpi/static", "args": ["--force-device-scale-factor=2"]
diff --git a/third_party/blink/web_tests/animations/web-animations/animation-state-changes-negative-playback-rate.html b/third_party/blink/web_tests/animations/web-animations/animation-state-changes-negative-playback-rate.html index 3da67627..1f9c92c 100644 --- a/third_party/blink/web_tests/animations/web-animations/animation-state-changes-negative-playback-rate.html +++ b/third_party/blink/web_tests/animations/web-animations/animation-state-changes-negative-playback-rate.html
@@ -264,7 +264,7 @@ var animation = runningAnimation(); animation.currentTime = 1000; assert_times_equal(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime)); - assert_equals(animation.currentTime, 1000); + assert_times_equal(animation.currentTime, 1000); assert_false(animation.pending); assert_equals(animation.playState, 'running'); }, "Setting currentTime on a running animation"); @@ -327,7 +327,7 @@ var animation = pausedAnimation(); animation.currentTime = 1000; assert_unresolved(animation.startTime); - assert_equals(animation.currentTime, 1000); + assert_times_equal(animation.currentTime, 1000); assert_true(animation.pending); assert_equals(animation.playState, 'paused'); }, "Setting currentTime on a paused animation"); @@ -390,7 +390,7 @@ var animation = finishedAnimation(); animation.currentTime = 1000; assert_times_equal(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime)); - assert_equals(animation.currentTime, 1000); + assert_times_equal(animation.currentTime, 1000); assert_false(animation.pending); assert_equals(animation.playState, 'running'); }, "Setting currentTime on a finished animation");
diff --git a/third_party/blink/web_tests/animations/web-animations/animation-state-changes-positive-playback-rate.html b/third_party/blink/web_tests/animations/web-animations/animation-state-changes-positive-playback-rate.html index a5d34b5..0bc33e64 100644 --- a/third_party/blink/web_tests/animations/web-animations/animation-state-changes-positive-playback-rate.html +++ b/third_party/blink/web_tests/animations/web-animations/animation-state-changes-positive-playback-rate.html
@@ -59,7 +59,7 @@ test(function(t) { var animation = createRunningAnimation(t); - assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_times_equal(animation.startTime, document.timeline.currentTime - animation.currentTime); assert_equals(animation.currentTime, 0); assert_equals(animation.playState, 'running'); }, "Play state is running after playing and setting start time of a canceled animation"); @@ -73,7 +73,7 @@ test(function(t) { var animation = createFinishedAnimation(t); - assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_times_equal(animation.startTime, document.timeline.currentTime - animation.currentTime); assert_equals(animation.currentTime, 100000); assert_equals(animation.playState, 'finished'); }, "Play state is finished after playing and finishing a cancelled animation"); @@ -109,7 +109,7 @@ test(function(t) { var animation = createIdleAnimation(t); animation.finish(); - assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_times_equal(animation.startTime, document.timeline.currentTime - animation.currentTime); assert_equals(animation.currentTime, 100000); assert_false(animation.pending); assert_equals(animation.playState, 'finished'); @@ -136,8 +136,8 @@ test(function(t) { var animation = createIdleAnimation(t); animation.startTime = document.timeline.currentTime - 1000; - assert_equals(animation.startTime, document.timeline.currentTime - 1000); - assert_equals(animation.currentTime, 1000); + assert_times_equal(animation.startTime, document.timeline.currentTime - 1000); + assert_times_equal(animation.currentTime, 1000); assert_false(animation.pending); assert_equals(animation.playState, 'running'); }, "Setting startTime on an idle animation"); @@ -172,7 +172,7 @@ test(function(t) { var animation = createPendingStartTimeAnimation(t); animation.finish(); - assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_times_equal(animation.startTime, document.timeline.currentTime - animation.currentTime); assert_equals(animation.currentTime, 100000); assert_false(animation.pending); assert_equals(animation.playState, 'finished'); @@ -199,8 +199,8 @@ test(function(t) { var animation = createPendingStartTimeAnimation(t); animation.startTime = document.timeline.currentTime - 1000; - assert_equals(animation.startTime, document.timeline.currentTime - 1000); - assert_equals(animation.currentTime, 1000); + assert_times_equal(animation.startTime, document.timeline.currentTime - 1000); + assert_times_equal(animation.currentTime, 1000); assert_false(animation.pending); assert_equals(animation.playState, 'running'); }, "Setting startTime on a pending starttime animation"); @@ -237,7 +237,7 @@ test(function(t) { var animation = createRunningAnimation(t); animation.finish(); - assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_times_equal(animation.startTime, document.timeline.currentTime - animation.currentTime); assert_equals(animation.currentTime, 100000); assert_false(animation.pending); assert_equals(animation.playState, 'finished'); @@ -256,7 +256,7 @@ test(function(t) { var animation = createRunningAnimation(t); animation.currentTime = 1000; - assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_times_equal(animation.startTime, document.timeline.currentTime - animation.currentTime); assert_equals(animation.currentTime, 1000); assert_false(animation.pending); assert_equals(animation.playState, 'running'); @@ -265,8 +265,8 @@ test(function(t) { var animation = createRunningAnimation(t); animation.startTime = document.timeline.currentTime - 1000; - assert_equals(animation.startTime, document.timeline.currentTime - 1000); - assert_equals(animation.currentTime, 1000); + assert_times_equal(animation.startTime, document.timeline.currentTime - 1000); + assert_times_equal(animation.currentTime, 1000); assert_false(animation.pending); assert_equals(animation.playState, 'running'); }, "Setting startTime on a running animation"); @@ -300,7 +300,7 @@ test(function(t) { var animation = createPausedAnimation(t); animation.finish(); - assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_times_equal(animation.startTime, document.timeline.currentTime - animation.currentTime); assert_equals(animation.currentTime, 100000); assert_equals(animation.playState, 'finished'); }, "Calling finish() on a paused animation"); @@ -325,8 +325,8 @@ test(function(t) { var animation = createPausedAnimation(t); animation.startTime = document.timeline.currentTime - 1000; - assert_equals(animation.startTime, document.timeline.currentTime - 1000); - assert_equals(animation.currentTime, 1000); + assert_times_equal(animation.startTime, document.timeline.currentTime - 1000); + assert_times_equal(animation.currentTime, 1000); assert_equals(animation.playState, 'running'); }, "Setting startTime on a paused animation"); @@ -360,7 +360,7 @@ test(function(t) { var animation = createFinishedAnimation(t); animation.finish(); - assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_times_equal(animation.startTime, document.timeline.currentTime - animation.currentTime); assert_equals(animation.currentTime, 100000); assert_false(animation.pending); assert_equals(animation.playState, 'finished'); @@ -378,7 +378,7 @@ test(function(t) { var animation = createFinishedAnimation(t); animation.currentTime = 1000; - assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_times_equal(animation.startTime, document.timeline.currentTime - animation.currentTime); assert_equals(animation.currentTime, 1000); assert_false(animation.pending); assert_equals(animation.playState, 'running');
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index dd0086d..7c7fe24 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -167896,6 +167896,15 @@ "service-workers/service-worker/resources/import-relative.xsl": [ [] ], + "service-workers/service-worker/resources/import-scripts-404-after-update-plus-update-worker.js": [ + [] + ], + "service-workers/service-worker/resources/import-scripts-404-after-update.js": [ + [] + ], + "service-workers/service-worker/resources/import-scripts-404.js": [ + [] + ], "service-workers/service-worker/resources/import-scripts-diff-resource-map-worker.js": [ [] ], @@ -168421,6 +168430,9 @@ "service-workers/service-worker/update-after-oneday.https-expected.txt": [ [] ], + "service-workers/service-worker/update-import-scripts.https-expected.txt": [ + [] + ], "service-workers/service-worker/update-recovery.https-expected.txt": [ [] ], @@ -279500,6 +279512,12 @@ } ] ], + "service-workers/service-worker/update-import-scripts.https.html": [ + [ + "service-workers/service-worker/update-import-scripts.https.html", + {} + ] + ], "service-workers/service-worker/update-missing-import-scripts.https.html": [ [ "service-workers/service-worker/update-missing-import-scripts.https.html", @@ -319945,7 +319963,7 @@ "testharness" ], "animation-worklet/idlharness.any-expected.txt": [ - "1bfd8054e8190921d5feebf38d120048d16df80a", + "2aa4f5b7f0e8849abd7a704982c3e4ea6ac8a5cb", "support" ], "animation-worklet/idlharness.any.js": [ @@ -319953,7 +319971,7 @@ "testharness" ], "animation-worklet/idlharness.any.worker-expected.txt": [ - "aa1341f0a73d1648332a12dca70b2d7bb015ec2e", + "a4793b0d2fdb50a005ec781b201f86ed70e2e187", "support" ], "animation-worklet/inactive-timeline.https.html": [ @@ -441893,7 +441911,7 @@ "support" ], "interfaces/animation-worklet.idl": [ - "32988e11506d14930a27b3b77dc3a8435bdf4269", + "615a21c76fd1f59910ba5867d4de097e6ecd917e", "support" ], "interfaces/appmanifest.idl": [ @@ -442129,7 +442147,7 @@ "support" ], "interfaces/media-capabilities.idl": [ - "00a9e62028a8e455a50f25a6f426aa901bb007d3", + "e66309187f467045c44f9083a51f0d610bcc7019", "support" ], "interfaces/media-source.idl": [ @@ -442149,7 +442167,7 @@ "support" ], "interfaces/mediasession.idl": [ - "565eab7b02715ee2b20e06992292a136bfc5bf22", + "5466300b6b48829493518fd4dd9f995509d7d337", "support" ], "interfaces/mediastream-recording.idl": [ @@ -442197,7 +442215,7 @@ "support" ], "interfaces/payment-request.idl": [ - "f8bd336dbe3b22223030a60cdd36be93067b3a9f", + "fefdc6f361774180c6672b6407e6cfa63dd3669d", "support" ], "interfaces/performance-timeline.idl": [ @@ -442209,7 +442227,7 @@ "support" ], "interfaces/picture-in-picture.idl": [ - "164ec02a9cf208e3c56da82a9629b3bb674f27f0", + "09b3b50c19bb4ab4a28e5d84dc3ed23d1c3c0298", "support" ], "interfaces/pointerevents-extension.idl": [ @@ -442233,7 +442251,7 @@ "support" ], "interfaces/push-api.idl": [ - "2fd5e27896ca95a546b26b9675483cb9bde07758", + "74725a3025680c91af9d44d6aec80b89519d217f", "support" ], "interfaces/referrer-policy.idl": [ @@ -442329,7 +442347,7 @@ "support" ], "interfaces/wake-lock.idl": [ - "21a3406f5894629ab5838dcf85474043c5138867", + "5bccbe8f9b7cd6464e60343b64bea477c4069057", "support" ], "interfaces/wasm-js-api.idl": [ @@ -442349,7 +442367,7 @@ "support" ], "interfaces/web-nfc.idl": [ - "a50d53b57cd1bfa0fb44b8921c215dbc8d51279f", + "838520858220a45f3929ff558d9898af7a800353", "support" ], "interfaces/web-share.idl": [ @@ -442357,7 +442375,7 @@ "support" ], "interfaces/webaudio.idl": [ - "7b78b19669a43c089b8e9f53b17e5cc2e3bfa528", + "19d807894231de9f3522f3845f44e212b9708580", "support" ], "interfaces/webauthn.idl": [ @@ -442385,7 +442403,7 @@ "support" ], "interfaces/webrtc-stats.idl": [ - "29604eafc2f4bff2ab1c0790cf7411589aefc214", + "48ebc187bc4814156eeb61810dbc01355e13de90", "support" ], "interfaces/webrtc.idl": [ @@ -443837,31 +443855,31 @@ "reftest" ], "mathml/relations/css-styling/padding-border-margin/border-001.html": [ - "79714db1c331b761edc235df191e9c3fdbd2244c", + "83eb924d82389008846adaca6eae35b450849a6f", "testharness" ], "mathml/relations/css-styling/padding-border-margin/border-002.html": [ - "4168c3cdb942d903598d50013443de041b019af2", + "cbf3efe096697bf543b4326a3467ae3b18501a58", "testharness" ], "mathml/relations/css-styling/padding-border-margin/helper.js": [ - "d3f4b261a75ad7706edc65793bd15661aa866b47", + "c7b4b0a1b49dc0bada186df03e0f79432462ed12", "support" ], "mathml/relations/css-styling/padding-border-margin/margin-001.html": [ - "1fa43927d6c4c0625478bf30de0540ed2c9a6ebf", + "c674d4c829e414067e02384ef06d38a44ba96e4f", "testharness" ], "mathml/relations/css-styling/padding-border-margin/margin-002.html": [ - "8631be586e472965bcecdb955e6eb98de78415b5", + "78e99c42cca58a60d8adf13f99dd95dc0db84462", "testharness" ], "mathml/relations/css-styling/padding-border-margin/padding-001.html": [ - "679834d4381f64bccdbde1e18039ed49a4586908", + "f195d4794030dcb0ee3770a446301466a7950a7e", "testharness" ], "mathml/relations/css-styling/padding-border-margin/padding-002.html": [ - "eadff36b460565f175f135a40bff3b6cfea8ba21", + "073faa1aeb3e7d25415a2827c77a911d40fbee5b", "testharness" ], "mathml/relations/css-styling/padding-border-margin/padding-border-margin-001-ref.html": [ @@ -443869,7 +443887,7 @@ "support" ], "mathml/relations/css-styling/padding-border-margin/padding-border-margin-001.html": [ - "6c878d6ee4785f26cd401b626283d04649e093ad", + "be918dee5108123f66ed1a8e75ec965b4b67b916", "reftest" ], "mathml/relations/css-styling/visibility-001-ref.html": [ @@ -470232,6 +470250,18 @@ "063a62d03143a32f44365bf1e7b08d283ae52895", "support" ], + "service-workers/service-worker/resources/import-scripts-404-after-update-plus-update-worker.js": [ + "e9899d8e7274ea8b65623e019411700ec65dbc84", + "support" + ], + "service-workers/service-worker/resources/import-scripts-404-after-update.js": [ + "b569346035ac11c557a1e19d6bf9ba8b90597539", + "support" + ], + "service-workers/service-worker/resources/import-scripts-404.js": [ + "19c7a4b8e561b3d95f10496e92a2c7264d693815", + "support" + ], "service-workers/service-worker/resources/import-scripts-diff-resource-map-worker.js": [ "0fdcb0fcf80ad7f0dffa284c5b77178bdad95ef6", "support" @@ -470837,7 +470867,7 @@ "support" ], "service-workers/service-worker/resources/update-worker.py": [ - "446d547ca78277c69795233f0d7c0f64125059d8", + "d25179304a73660122036e5d5fec2067dc61597a", "support" ], "service-workers/service-worker/resources/update/update-after-oneday.https.html": [ @@ -471036,6 +471066,14 @@ "6628dba6ee7d11ae0cd45941c726df017afb9336", "testharness" ], + "service-workers/service-worker/update-import-scripts.https-expected.txt": [ + "b475dd41f044cd410cb057764f7c330c0fafd9cf", + "support" + ], + "service-workers/service-worker/update-import-scripts.https.html": [ + "e0bbb12bd675b636116ef5f81447904cddd922d9", + "testharness" + ], "service-workers/service-worker/update-missing-import-scripts.https.html": [ "66e8bfac751e835af8e543fc5289697c15ac118d", "testharness"
diff --git a/third_party/blink/web_tests/external/wpt/animation-worklet/idlharness.any-expected.txt b/third_party/blink/web_tests/external/wpt/animation-worklet/idlharness.any-expected.txt index 1bfd805..2aa4f5b7 100644 --- a/third_party/blink/web_tests/external/wpt/animation-worklet/idlharness.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/animation-worklet/idlharness.any-expected.txt
@@ -4,8 +4,6 @@ PASS Partial namespace CSS: valid exposure set PASS Partial interface AnimationEffect: original interface defined FAIL Partial interface AnimationEffect: valid exposure set Partial AnimationEffect interface is exposed to 'AnimationWorklet', the original interface is not. -PASS StatelessAnimator interface: existence and properties of interface object -PASS StatefulAnimator interface: existence and properties of interface object PASS AnimationWorkletGlobalScope interface: existence and properties of interface object FAIL WorkletAnimation interface: existence and properties of interface object assert_equals: prototype of WorkletAnimation is not Animation expected function "function Animation() { [native code] }" but got function "function () { [native code] }" FAIL WorkletAnimation interface object length assert_equals: wrong value for WorkletAnimation.length expected 1 but got 2
diff --git a/third_party/blink/web_tests/external/wpt/animation-worklet/idlharness.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/animation-worklet/idlharness.any.worker-expected.txt index aa1341f..a4793b0d 100644 --- a/third_party/blink/web_tests/external/wpt/animation-worklet/idlharness.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/animation-worklet/idlharness.any.worker-expected.txt
@@ -4,8 +4,6 @@ PASS Partial namespace CSS: valid exposure set PASS Partial interface AnimationEffect: original interface defined FAIL Partial interface AnimationEffect: valid exposure set Partial AnimationEffect interface is exposed to 'AnimationWorklet', the original interface is not. -PASS StatelessAnimator interface: existence and properties of interface object -PASS StatefulAnimator interface: existence and properties of interface object PASS AnimationWorkletGlobalScope interface: existence and properties of interface object PASS WorkletAnimation interface: existence and properties of interface object FAIL WorkletAnimation must be primary interface of new WorkletAnimation("name") assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: WorkletAnimation is not defined"
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/zero-available-space-float-positioning.html b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/zero-available-space-float-positioning.html new file mode 100644 index 0000000..62ace6d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/zero-available-space-float-positioning.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<link rel="help" href="https://www.w3.org/TR/CSS22/visudet.html#float-width" title="10.3.5 Floating, non-replaced elements"> +<link rel="match" href="../../reference/ref-filled-green-100px-square-only.html"> +<p>Test passes if there is a filled green square.</p> +<div style="width: 0px;"> + <div style="float: left; width: 100px; height: 50px; background: green;"></div> + <div style="float: left; width: 100px; height: 50px; background: green;"></div> +</div> +
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/animation-worklet.idl b/third_party/blink/web_tests/external/wpt/interfaces/animation-worklet.idl index 32988e1..615a21c 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/animation-worklet.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/animation-worklet.idl
@@ -8,16 +8,6 @@ [SameObject] readonly attribute Worklet animationWorklet; }; -[Exposed=AnimationWorklet, Global=AnimationWorklet, Constructor (optional any options)] -interface StatelessAnimator { -}; - -[Exposed=AnimationWorklet, Global=AnimationWorklet, -Constructor (optional any options, optional any state)] -interface StatefulAnimator { - any state(); -}; - [ Global=(Worklet,AnimationWorklet), Exposed=AnimationWorklet ] interface AnimationWorkletGlobalScope : WorkletGlobalScope { void registerAnimator(DOMString name, AnimatorInstanceConstructor animatorCtor);
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/media-capabilities.idl b/third_party/blink/web_tests/external/wpt/interfaces/media-capabilities.idl index 00a9e620..e663091 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/media-capabilities.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/media-capabilities.idl
@@ -1,7 +1,7 @@ // GENERATED CONTENT - DO NOT EDIT // Content was automatically extracted by Reffy into reffy-reports // (https://github.com/tidoust/reffy-reports) -// Source: Media Capabilities (https://wicg.github.io/media-capabilities/) +// Source: Media Capabilities (https://w3c.github.io/media-capabilities/) dictionary MediaConfiguration { VideoConfiguration video;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/mediasession.idl b/third_party/blink/web_tests/external/wpt/interfaces/mediasession.idl index 565eab7..5466300b 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/mediasession.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/mediasession.idl
@@ -1,7 +1,7 @@ // GENERATED CONTENT - DO NOT EDIT // Content was automatically extracted by Reffy into reffy-reports // (https://github.com/tidoust/reffy-reports) -// Source: Media Session Standard (https://wicg.github.io/mediasession/) +// Source: Media Session Standard (https://w3c.github.io/mediasession/) [Exposed=Window] partial interface Navigator {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/payment-request.idl b/third_party/blink/web_tests/external/wpt/interfaces/payment-request.idl index f8bd336..fefdc6f 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/payment-request.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/payment-request.idl
@@ -3,7 +3,7 @@ // (https://github.com/tidoust/reffy-reports) // Source: Payment Request API (https://w3c.github.io/payment-request/) -[Constructor(sequence<PaymentMethodData> methodData, PaymentDetailsInit details, optional PaymentOptions options), +[Constructor(sequence<PaymentMethodData> methodData, PaymentDetailsInit details, optional PaymentOptions options = {}), SecureContext, Exposed=Window] interface PaymentRequest : EventTarget { [NewObject] @@ -138,7 +138,7 @@ }; [SecureContext, Exposed=Window] -interface PaymentResponse : EventTarget { +interface PaymentResponse : EventTarget { [Default] object toJSON(); readonly attribute DOMString requestId; @@ -153,7 +153,7 @@ [NewObject] Promise<void> complete(optional PaymentComplete result = "unknown"); [NewObject] - Promise<void> retry(optional PaymentValidationErrors errorFields); + Promise<void> retry(optional PaymentValidationErrors errorFields = {}); attribute EventHandler onpayerdetailchange; }; @@ -171,7 +171,7 @@ DOMString phone; }; -[Constructor(DOMString type, optional MerchantValidationEventInit eventInitDict), +[Constructor(DOMString type, optional MerchantValidationEventInit eventInitDict = {}), SecureContext, Exposed=Window] interface MerchantValidationEvent : Event { readonly attribute DOMString methodName; @@ -184,7 +184,7 @@ USVString validationURL = ""; }; -[Constructor(DOMString type, optional PaymentMethodChangeEventInit eventInitDict), SecureContext, Exposed=Window] +[Constructor(DOMString type, optional PaymentMethodChangeEventInit eventInitDict = {}), SecureContext, Exposed=Window] interface PaymentMethodChangeEvent : PaymentRequestUpdateEvent { readonly attribute DOMString methodName; readonly attribute object? methodDetails; @@ -195,7 +195,7 @@ object? methodDetails = null; }; -[Constructor(DOMString type, optional PaymentRequestUpdateEventInit eventInitDict), SecureContext, Exposed=Window] +[Constructor(DOMString type, optional PaymentRequestUpdateEventInit eventInitDict = {}), SecureContext, Exposed=Window] interface PaymentRequestUpdateEvent : Event { void updateWith(Promise<PaymentDetailsUpdate> detailsPromise); };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/picture-in-picture.idl b/third_party/blink/web_tests/external/wpt/interfaces/picture-in-picture.idl index 164ec02a..09b3b50c 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/picture-in-picture.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/picture-in-picture.idl
@@ -1,7 +1,7 @@ // GENERATED CONTENT - DO NOT EDIT // Content was automatically extracted by Reffy into reffy-reports // (https://github.com/tidoust/reffy-reports) -// Source: Picture-in-Picture (https://wicg.github.io/picture-in-picture/) +// Source: Picture-in-Picture (https://w3c.github.io/picture-in-picture/) partial interface HTMLVideoElement { [NewObject] Promise<PictureInPictureWindow> requestPictureInPicture();
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/push-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/push-api.idl index 2fd5e27..74725a3 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/push-api.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/push-api.idl
@@ -12,9 +12,9 @@ interface PushManager { [SameObject] static readonly attribute FrozenArray<DOMString> supportedContentEncodings; - Promise<PushSubscription> subscribe(optional PushSubscriptionOptionsInit options); + Promise<PushSubscription> subscribe(optional PushSubscriptionOptionsInit options = {}); Promise<PushSubscription?> getSubscription(); - Promise<PushPermissionState> permissionState(optional PushSubscriptionOptionsInit options); + Promise<PushPermissionState> permissionState(optional PushSubscriptionOptionsInit options = {}); }; [Exposed=(Window,Worker), SecureContext] @@ -64,7 +64,7 @@ attribute EventHandler onpushsubscriptionchange; }; -[Constructor(DOMString type, optional PushEventInit eventInitDict), Exposed=ServiceWorker, SecureContext] +[Constructor(DOMString type, optional PushEventInit eventInitDict = {}), Exposed=ServiceWorker, SecureContext] interface PushEvent : ExtendableEvent { readonly attribute PushMessageData? data; }; @@ -75,13 +75,13 @@ PushMessageDataInit data; }; -[Constructor(DOMString type, optional PushSubscriptionChangeInit eventInitDict), Exposed=ServiceWorker, SecureContext] +[Constructor(DOMString type, optional PushSubscriptionChangeEventInit eventInitDict = {}), Exposed=ServiceWorker, SecureContext] interface PushSubscriptionChangeEvent : ExtendableEvent { readonly attribute PushSubscription? newSubscription; readonly attribute PushSubscription? oldSubscription; }; -dictionary PushSubscriptionChangeInit : ExtendableEventInit { +dictionary PushSubscriptionChangeEventInit : ExtendableEventInit { PushSubscription newSubscription = null; PushSubscription oldSubscription = null; };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/wake-lock.idl b/third_party/blink/web_tests/external/wpt/interfaces/wake-lock.idl index 21a3406..5bccbe8 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/wake-lock.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/wake-lock.idl
@@ -9,10 +9,10 @@ enum WakeLockType { "screen", "system" }; -[SecureContext, Exposed=(DedicatedWorker,Window)] +[SecureContext, Exposed=(DedicatedWorker, Window)] interface WakeLock { [Exposed=Window] static Promise<PermissionState> requestPermission(WakeLockType type); - static Promise<void> request(WakeLockType type, optional WakeLockRequestOptions options); + static Promise<void> request(WakeLockType type, optional WakeLockRequestOptions options = {}); }; dictionary WakeLockRequestOptions {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl b/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl index a50d53b..8385208 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl
@@ -3,14 +3,27 @@ // (https://github.com/tidoust/reffy-reports) // Source: Web NFC API (https://w3c.github.io/web-nfc/) -dictionary NDEFMessage { +[Constructor(NDEFMessageInit messageInit), Exposed=Window] +interface NDEFMessage { + readonly attribute USVString url; + readonly attribute FrozenArray<NDEFRecord> records; +}; + +dictionary NDEFMessageInit { USVString url; - sequence<NDEFRecord> records; + sequence<NDEFRecordInit> records; }; typedef (DOMString or unrestricted double or ArrayBuffer or Dictionary) NDEFRecordData; -dictionary NDEFRecord { +[Constructor(NDEFRecordInit recordInit), Exposed=Window] +interface NDEFRecord { + readonly attribute NDEFRecordType recordType; + readonly attribute USVString mediaType; + NDEFRecordData data(); +}; + +dictionary NDEFRecordInit { NDEFRecordType recordType; USVString mediaType; NDEFRecordData data; @@ -24,14 +37,14 @@ "opaque" }; -typedef (DOMString or ArrayBuffer or NDEFMessage) NDEFMessageSource; +typedef (DOMString or ArrayBuffer or NDEFMessageInit) NDEFMessageSource; [Constructor(), SecureContext, Exposed=Window] interface NFCWriter { - Promise<void> push(NDEFMessageSource message, optional NFCPushOptions options); + Promise<void> push(NDEFMessageSource message, optional NFCPushOptions options={}); }; -[Constructor(optional NFCReaderOptions options), SecureContext, Exposed=Window] +[Constructor(optional NFCReaderOptions options={}), SecureContext, Exposed=Window] interface NFCReader : EventTarget { attribute EventHandler onreading; attribute EventHandler onerror; @@ -43,12 +56,12 @@ [Constructor(DOMString type, NFCReadingEventInit readingEventInitDict), SecureContext, Exposed=Window] interface NFCReadingEvent : Event { readonly attribute DOMString serialNumber; - readonly attribute object message; // NDEFMessage + [SameObject] readonly attribute NDEFMessage message; }; dictionary NFCReadingEventInit : EventInit { DOMString? serialNumber = ""; - required NDEFMessage message; + required NDEFMessageInit message; }; [Constructor(DOMString type, NFCErrorEventInit errorEventInitDict), SecureContext, Exposed=Window]
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webaudio.idl b/third_party/blink/web_tests/external/wpt/interfaces/webaudio.idl index 7b78b19..19d8078 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webaudio.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webaudio.idl
@@ -581,7 +581,7 @@ unsigned long numberOfOutputs = 1; sequence<unsigned long> outputChannelCount; record<DOMString, double> parameterData; - object? processorOptions = null; + object processorOptions; }; [Exposed=AudioWorklet,
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl index 29604ea..48ebc18 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl
@@ -65,26 +65,26 @@ }; dictionary RTCInboundRtpStreamStats : RTCReceivedRtpStreamStats { - DOMString trackId; - DOMString receiverId; - DOMString remoteId; - unsigned long framesDecoded; - unsigned long keyFramesDecoded; - unsigned long long qpSum; - double totalDecodeTime; - DOMHighResTimeStamp lastPacketReceivedTimestamp; - double averageRtcpInterval; - unsigned long fecPacketsReceived; - unsigned long fecPacketsDiscarded; - unsigned long long bytesReceived; - unsigned long packetsFailedDecryption; - unsigned long packetsDuplicated; - record<USVString, unsigned long> perDscpPacketsReceived; - unsigned long nackCount; - unsigned long firCount; - unsigned long pliCount; - unsigned long sliCount; - }; + DOMString trackId; + DOMString receiverId; + DOMString remoteId; + unsigned long framesDecoded; + unsigned long keyFramesDecoded; + unsigned long long qpSum; + double totalDecodeTime; + DOMHighResTimeStamp lastPacketReceivedTimestamp; + double averageRtcpInterval; + unsigned long fecPacketsReceived; + unsigned long fecPacketsDiscarded; + unsigned long long bytesReceived; + unsigned long packetsFailedDecryption; + unsigned long packetsDuplicated; + record<USVString, unsigned long> perDscpPacketsReceived; + unsigned long nackCount; + unsigned long firCount; + unsigned long pliCount; + unsigned long sliCount; +}; dictionary RTCRemoteInboundRtpStreamStats : RTCReceivedRtpStreamStats { DOMString localId; @@ -126,11 +126,11 @@ }; enum RTCQualityLimitationReason { - "none", - "cpu", - "bandwidth", - "other", - }; + "none", + "cpu", + "bandwidth", + "other", +}; dictionary RTCRemoteOutboundRtpStreamStats : RTCSentRtpStreamStats { DOMString localId; @@ -277,7 +277,6 @@ long priority; DOMString url; DOMString relayProtocol; - boolean deleted = false; }; enum RTCNetworkType { @@ -336,24 +335,24 @@ }; dictionary RTCStunServerConnectionStats : RTCStats { - DOMString url; - long port; - DOMString protocol; - RTCNetworkType networkType; - unsigned long totalRequestsSent; - unsigned long totalResponsesReceived; - double totalRoundTripTime; - }; + DOMString url; + long port; + DOMString protocol; + RTCNetworkType networkType; + unsigned long totalRequestsSent; + unsigned long totalResponsesReceived; + double totalRoundTripTime; +}; partial dictionary RTCIceCandidateStats { - boolean isRemote; - }; + boolean isRemote; +}; partial dictionary RTCIceCandidatePairStats { - double totalRtt; - double currentRtt; - unsigned long long priority; - }; +double totalRtt; +double currentRtt; +unsigned long long priority; +}; partial dictionary RTCRtpStreamStats { DOMString mediaType;
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/border-001.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/border-001.html index 79714db..83eb924d 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/border-001.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/border-001.html
@@ -7,6 +7,7 @@ <meta name="assert" content="Verify that border is taken into account."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> <script src="helper.js"></script> <script> var epsilon = 1; @@ -16,6 +17,7 @@ function runTests() { test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); var s = measureSpaceAround("mrow-border") assert_approx_equals(s.left, 20, epsilon, "left border"); assert_approx_equals(s.right, 30, epsilon, "right border"); @@ -28,6 +30,21 @@ }, "Border properties on mrow"); test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_dir()); + var s = measureSpaceAround("mrow-border-rtl") + assert_approx_equals(s.left, 20, epsilon, "left border"); + assert_approx_equals(s.right, 30, epsilon, "right border"); + assert_approx_equals(s.top, 40, epsilon, "top border"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom border"); + var b = document.getElementById("mrow-border-rtl"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width"); + assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height"); + }, "Border properties on mrow (rtl)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); var s = measureSpaceAround("mrow-border-shorthand") assert_approx_equals(s.left, 20, epsilon, "left border"); assert_approx_equals(s.right, 20, epsilon, "right border"); @@ -40,6 +57,7 @@ }, "Border properties on mrow (shorthand)"); test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); var s = measureSpaceAround("mrow-border-logical") assert_approx_equals(s.left, 20, epsilon, "left border"); assert_approx_equals(s.right, 30, epsilon, "right border"); @@ -52,6 +70,21 @@ }, "Border properties on mrow (logical)"); test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_dir()); + var s = measureSpaceAround("mrow-border-logical-rtl") + assert_approx_equals(s.left, 30, epsilon, "left border"); + assert_approx_equals(s.right, 20, epsilon, "right border"); + assert_approx_equals(s.top, 40, epsilon, "top border"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom border"); + var b = document.getElementById("mrow-border-logical-rtl"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width"); + assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height"); + }, "Border properties on mrow (logical, rtl)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); var s = measureSpaceAround("mrow-border-logical-shorthand") assert_approx_equals(s.left, 20, epsilon, "left border"); assert_approx_equals(s.right, 20, epsilon, "right border"); @@ -83,6 +116,19 @@ </math> </p> <p> + <math dir="rtl"> + <mrow> + <mrow id="mrow-border-rtl" + style="border-left: 20px solid transparent; + border-right: 30px solid transparent; + border-top: 40px solid transparent; + border-bottom: 50px solid transparent;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> <math> <mrow> <mrow id="mrow-border-shorthand" @@ -106,6 +152,19 @@ </math> </p> <p> + <math dir="rtl"> + <mrow> + <mrow id="mrow-border-logical-rtl" + style="border-inline-start: 20px solid transparent; + border-inline-end: 30px solid transparent; + border-block-start: 40px solid transparent; + border-block-end: 50px solid transparent;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> <math> <mrow> <mrow id="mrow-border-logical-shorthand"
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/border-002.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/border-002.html index 4168c3c..cbf3efe 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/border-002.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/border-002.html
@@ -22,12 +22,13 @@ continue; var style = "border-left: 30px solid; border-right: 40px solid; border-top: 50px solid; border-bottom: 60px solid;"; + var styleRTL = `direction: rtl; ${style}`; if (FragmentHelper.isEmpty(tag)) { test(function() { var s = compareSizeWithAndWithoutStyle(tag, style); - assert_approx_equals(s.width_delta, 30 + 40, epsilon, "left/right border"); - assert_approx_equals(s.height_delta, 50 + 60, epsilon, "top/bottom border"); + assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "left/right border"); + assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "top/bottom border"); }, `Border properties on ${tag}`); continue; } @@ -38,7 +39,19 @@ assert_approx_equals(s.right_delta, 40, epsilon, "right border"); assert_approx_equals(s.top_delta, 50, epsilon, "top border"); assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom border"); + assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "element height"); }, `Border properties on ${tag}`); + + test(function() { + var s = compareSpaceWithAndWithoutStyle(tag, styleRTL); + assert_approx_equals(s.left_delta, 30, epsilon, "left border"); + assert_approx_equals(s.right_delta, 40, epsilon, "right border"); + assert_approx_equals(s.top_delta, 50, epsilon, "top border"); + assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom border"); + assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "element height"); + }, `Border properties on ${tag} (rtl)`); } done();
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/helper.js b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/helper.js index d3f4b261..c7b4b0a1 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/helper.js +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/helper.js
@@ -30,16 +30,18 @@ var styleElement = FragmentHelper.element(styleMath); styleElement.setAttribute("style", style); var styleChild = FragmentHelper.forceNonEmptyElement(styleElement); - var styleBox = styleMath.getBoundingClientRect(); + var styleMathBox = styleMath.getBoundingClientRect(); + var styleElementBox = styleElement.getBoundingClientRect(); var styleChildBox = styleChild.getBoundingClientRect(); - var styleSpace = spaceBetween(styleChildBox, styleBox); + var styleSpace = spaceBetween(styleChildBox, styleMathBox); var noStyleMath = div.lastElementChild; var noStyleElement = FragmentHelper.element(noStyleMath); var noStyleChild = FragmentHelper.forceNonEmptyElement(noStyleElement); - var noStyleBox = noStyleMath.getBoundingClientRect(); + var noStyleMathBox = noStyleMath.getBoundingClientRect(); + var noStyleElementBox = noStyleElement.getBoundingClientRect(); var noStyleChildBox = noStyleChild.getBoundingClientRect(); - var noStyleSpace = spaceBetween(noStyleChildBox, noStyleBox); + var noStyleSpace = spaceBetween(noStyleChildBox, noStyleMathBox); div.style = "display: none;"; // Hide the div after measurement. @@ -47,7 +49,9 @@ left_delta: styleSpace.left - noStyleSpace.left, right_delta: styleSpace.right - noStyleSpace.right, top_delta: styleSpace.top - noStyleSpace.top, - bottom_delta: styleSpace.bottom - noStyleSpace.bottom + bottom_delta: styleSpace.bottom - noStyleSpace.bottom, + element_width_delta: styleElementBox.width - noStyleElementBox.width, + element_height_delta: styleElementBox.height - noStyleElementBox.height }; } @@ -64,16 +68,20 @@ var styleMath = div.firstElementChild; var styleElement = FragmentHelper.element(styleMath); styleElement.setAttribute("style", style); - var styleBox = styleMath.getBoundingClientRect(); + var styleMathBox = styleMath.getBoundingClientRect(); + var styleElementBox = styleElement.getBoundingClientRect(); var noStyleMath = div.lastElementChild; var noStyleElement = FragmentHelper.element(noStyleMath); - var noStyleBox = noStyleMath.getBoundingClientRect(); + var noStyleMathBox = noStyleMath.getBoundingClientRect(); + var noStyleElementBox = noStyleElement.getBoundingClientRect(); div.style = "display: none;"; // Hide the div after measurement. return { - width_delta: styleBox.width - noStyleBox.width, - height_delta: styleBox.height - noStyleBox.height + width_delta: styleMathBox.width - noStyleMathBox.width, + height_delta: styleMathBox.height - noStyleMathBox.height, + element_width_delta: styleElementBox.width - noStyleElementBox.width, + element_height_delta: styleElementBox.height - noStyleElementBox.height }; };
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/margin-001.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/margin-001.html index 1fa4392..c674d4c8 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/margin-001.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/margin-001.html
@@ -7,6 +7,7 @@ <meta name="assert" content="Verify that margin is taken into account."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> <script src="helper.js"></script> <script> var epsilon = 1; @@ -16,6 +17,7 @@ function runTests() { test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); var s = measureSpaceAround("mrow-margin") assert_approx_equals(s.left, 20, epsilon, "left margin"); assert_approx_equals(s.right, 30, epsilon, "right margin"); @@ -28,6 +30,21 @@ }, "Margin properties on mrow"); test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_dir()); + var s = measureSpaceAround("mrow-margin-rtl") + assert_approx_equals(s.left, 20, epsilon, "left margin"); + assert_approx_equals(s.right, 30, epsilon, "right margin"); + assert_approx_equals(s.top, 40, epsilon, "top margin"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom margin"); + var b = document.getElementById("mrow-margin-rtl"). + getBoundingClientRect(); + assert_approx_equals(b.width, 50, epsilon, "element width"); + assert_approx_equals(b.height, 50, epsilon, "element height"); + }, "Margin properties on mrow (rtl)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); var s = measureSpaceAround("mrow-margin-shorthand") assert_approx_equals(s.left, 20, epsilon, "left margin"); assert_approx_equals(s.right, 20, epsilon, "right margin"); @@ -40,6 +57,7 @@ }, "Margin properties on mrow (shorthand)"); test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); var s = measureSpaceAround("mrow-margin-logical") assert_approx_equals(s.left, 20, epsilon, "left margin"); assert_approx_equals(s.right, 30, epsilon, "right margin"); @@ -52,6 +70,21 @@ }, "Margin properties on mrow (logical)"); test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_dir()); + var s = measureSpaceAround("mrow-margin-logical-rtl") + assert_approx_equals(s.left, 20, epsilon, "left margin"); + assert_approx_equals(s.right, 30, epsilon, "right margin"); + assert_approx_equals(s.top, 40, epsilon, "top margin"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom margin"); + var b = document.getElementById("mrow-margin-logical-rtl"). + getBoundingClientRect(); + assert_approx_equals(b.width, 50, epsilon, "element width"); + assert_approx_equals(b.height, 50, epsilon, "element height"); + }, "Margin properties on mrow (logical, rtl)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); var s = measureSpaceAround("mrow-margin-logical-shorthand") assert_approx_equals(s.left, 20, epsilon, "left margin"); assert_approx_equals(s.right, 20, epsilon, "right margin"); @@ -83,6 +116,19 @@ </math> </p> <p> + <math dir="rtl"> + <mrow> + <mrow id="mrow-margin-rtl" + style="margin-left: 20px; + margin-right: 30px; + margin-top: 40px; + margin-bottom: 50px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> <math> <mrow> <mrow id="mrow-margin-shorthand" @@ -106,6 +152,19 @@ </math> </p> <p> + <math dir="rtl"> + <mrow> + <mrow id="mrow-margin-logical-rtl" + style="margin-inline-start: 20px; + margin-inline-end: 30px; + margin-block-start: 40px; + margin-block-end: 50px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> <math> <mrow> <mrow id="mrow-margin-logical-shorthand"
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/margin-002.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/margin-002.html index 8631be5..78e99c42 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/margin-002.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/margin-002.html
@@ -22,12 +22,15 @@ continue; var style = "margin-left: 30px; margin-right: 40px; margin-top: 50px; margin-bottom: 60px;"; + var styleRTL = `direction: rtl; ${style}`; if (FragmentHelper.isEmpty(tag)) { test(function() { var s = compareSizeWithAndWithoutStyle(tag, style); assert_approx_equals(s.width_delta, 30 + 40, epsilon, "left/right margin"); assert_approx_equals(s.height_delta, 50 + 60, epsilon, "top/bottom margin"); + assert_approx_equals(s.element_width_delta, 0, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 0, epsilon, "element height"); }, `Margin properties on ${tag}`); continue; } @@ -38,7 +41,19 @@ assert_approx_equals(s.right_delta, 40, epsilon, "right margin"); assert_approx_equals(s.top_delta, 50, epsilon, "top margin"); assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom margin"); + assert_approx_equals(s.element_width_delta, 0, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 0, epsilon, "element height"); }, `Margin properties on ${tag}`); + + test(function() { + var s = compareSpaceWithAndWithoutStyle(tag, styleRTL); + assert_approx_equals(s.left_delta, 30, epsilon, "left margin"); + assert_approx_equals(s.right_delta, 40, epsilon, "right margin"); + assert_approx_equals(s.top_delta, 50, epsilon, "top margin"); + assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom margin"); + assert_approx_equals(s.element_width_delta, 0, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 0, epsilon, "element height"); + }, `Margin properties on ${tag} (rtl)`); } done();
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/padding-001.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/padding-001.html index 679834d4..f195d47 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/padding-001.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/padding-001.html
@@ -7,6 +7,7 @@ <meta name="assert" content="Verify that padding is taken into account."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> <script src="helper.js"></script> <script> var epsilon = 1; @@ -16,6 +17,7 @@ function runTests() { test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); var s = measureSpaceAround("mrow-padding") assert_approx_equals(s.left, 20, epsilon, "left padding"); assert_approx_equals(s.right, 30, epsilon, "right padding"); @@ -28,6 +30,21 @@ }, "Padding properties on mrow"); test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_dir()); + var s = measureSpaceAround("mrow-padding-rtl") + assert_approx_equals(s.left, 20, epsilon, "left padding"); + assert_approx_equals(s.right, 30, epsilon, "right padding"); + assert_approx_equals(s.top, 40, epsilon, "top padding"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom padding"); + var b = document.getElementById("mrow-padding-rtl"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width"); + assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height"); + }, "Padding properties on mrow (rtl)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); var s = measureSpaceAround("mrow-padding-shorthand") assert_approx_equals(s.left, 20, epsilon, "left padding"); assert_approx_equals(s.right, 20, epsilon, "right padding"); @@ -40,6 +57,7 @@ }, "Padding properties on mrow (shorthand)"); test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); var s = measureSpaceAround("mrow-padding-logical") assert_approx_equals(s.left, 20, epsilon, "left padding"); assert_approx_equals(s.right, 30, epsilon, "right padding"); @@ -52,6 +70,21 @@ }, "Padding properties on mrow (logical)"); test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_dir()); + var s = measureSpaceAround("mrow-padding-logical-rtl") + assert_approx_equals(s.left, 30, epsilon, "left padding"); + assert_approx_equals(s.right, 20, epsilon, "right padding"); + assert_approx_equals(s.top, 40, epsilon, "top padding"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom padding"); + var b = document.getElementById("mrow-padding-logical-rtl"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width"); + assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height"); + }, "Padding properties on mrow (logical, rtl)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); var s = measureSpaceAround("mrow-padding-logical-shorthand") assert_approx_equals(s.left, 20, epsilon, "left padding"); assert_approx_equals(s.right, 20, epsilon, "right padding"); @@ -83,6 +116,19 @@ </math> </p> <p> + <math dir="rtl"> + <mrow> + <mrow id="mrow-padding-rtl" + style="padding-left: 20px; + padding-right: 30px; + padding-top: 40px; + padding-bottom: 50px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> <math> <mrow> <mrow id="mrow-padding-shorthand" @@ -106,6 +152,19 @@ </math> </p> <p> + <math dir="rtl"> + <mrow> + <mrow id="mrow-padding-logical-rtl" + style="padding-inline-start: 20px; + padding-inline-end: 30px; + padding-block-start: 40px; + padding-block-end: 50px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> <math> <mrow> <mrow id="mrow-padding-logical-shorthand"
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/padding-002.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/padding-002.html index eadff36..073faa1ae 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/padding-002.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/padding-002.html
@@ -22,12 +22,13 @@ continue; var style = "padding-left: 30px; padding-right: 40px; padding-top: 50px; padding-bottom: 60px;"; + var styleRTL = `direction: rtl; ${style}`; if (FragmentHelper.isEmpty(tag)) { test(function() { var s = compareSizeWithAndWithoutStyle(tag, style); - assert_approx_equals(s.width_delta, 30 + 40, epsilon, "left/right padding"); - assert_approx_equals(s.height_delta, 50 + 60, epsilon, "top/bottom padding"); + assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "left/right padding"); + assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "top/bottom padding"); }, `Padding properties on ${tag}`); continue; } @@ -38,7 +39,19 @@ assert_approx_equals(s.right_delta, 40, epsilon, "right padding"); assert_approx_equals(s.top_delta, 50, epsilon, "top padding"); assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom padding"); + assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "element height"); }, `Padding properties on ${tag}`); + + test(function() { + var s = compareSpaceWithAndWithoutStyle(tag, styleRTL); + assert_approx_equals(s.left_delta, 30, epsilon, "left padding"); + assert_approx_equals(s.right_delta, 40, epsilon, "right padding"); + assert_approx_equals(s.top_delta, 50, epsilon, "top padding"); + assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom padding"); + assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "element height"); + }, `Padding properties on ${tag} (rtl)`); } done();
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001.html index 6c878d6e..be918de 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001.html
@@ -11,7 +11,7 @@ <p>This test passes if you see a purple square of side 100px, surrounded by a 10px blue padding, surrounded by a 10px blue/yellow dashed border, itself surrounded by a 10px pink margin.</p> - <div style="background: pink; position: absolute; left: 200px; left: 10px; top: 3em;"> + <div style="background: pink; position: absolute; left: 10px; top: 3em;"> <math> <mrow style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px;"> <mspace width="100px" height="100px" style="background: purple;"></mspace>
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel-expected.txt b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel-expected.txt deleted file mode 100644 index 85e66d4..0000000 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel-expected.txt +++ /dev/null
@@ -1,60 +0,0 @@ -This is a testharness.js-based test. -Found 56 tests; 51 PASS, 5 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS # AUDIT TASK RUNNER STARTED. -PASS > [initialize] -PASS Initialized values contains only the constant -1. -PASS < [initialize] All assertions passed. (total 1 assertions) -PASS > [copyFrom-exceptions] -PASS AudioBuffer.prototype.copyFromChannel does exist. -PASS 0: buffer = context.createBuffer(3, 16, context.sampleRate) did not throw an exception. -PASS 1: buffer.copyFromChannel(null, 0) threw TypeError: "Failed to execute 'copyFromChannel' on 'AudioBuffer': parameter 1 is not of type 'Float32Array'.". -PASS 2: buffer.copyFromChannel(context, 0) threw TypeError: "Failed to execute 'copyFromChannel' on 'AudioBuffer': parameter 1 is not of type 'Float32Array'.". -PASS 3: buffer.copyFromChannel(x, -1) threw IndexSizeError: "Failed to execute 'copyFromChannel' on 'AudioBuffer': The channelNumber provided (-1) is outside the range [0, 2].". -PASS 4: buffer.copyFromChannel(x, 3) threw IndexSizeError: "Failed to execute 'copyFromChannel' on 'AudioBuffer': The channelNumber provided (3) is outside the range [0, 2].". -PASS 5: buffer.copyFromChannel(x, 0, -1) threw IndexSizeError: "Failed to execute 'copyFromChannel' on 'AudioBuffer': The startInChannel provided (4294967295) is outside the range [0, 16).". -FAIL X 6: buffer.copyFromChannel(x, 0, 16) incorrectly threw IndexSizeError: "Failed to execute 'copyFromChannel' on 'AudioBuffer': The startInChannel provided (16) is outside the range [0, 16).". assert_true: expected true got false -PASS 7: buffer.copyFromChannel(x, 3) threw IndexSizeError: "Failed to execute 'copyFromChannel' on 'AudioBuffer': The channelNumber provided (3) is outside the range [0, 2].". -PASS 8: buffer.copyFromChannel(SharedArrayBuffer view, 0) threw TypeError: "Failed to execute 'copyFromChannel' on 'AudioBuffer': The provided ArrayBufferView value must not be shared.". -PASS 9: buffer.copyFromChannel(SharedArrayBuffer view, 0, 0) threw TypeError: "Failed to execute 'copyFromChannel' on 'AudioBuffer': The provided ArrayBufferView value must not be shared.". -FAIL < [copyFrom-exceptions] 1 out of 11 assertions were failed. assert_true: expected true got false -PASS > [copyTo-exceptions] -PASS AudioBuffer.prototype.copyToChannel does exist. -PASS 0: buffer.copyToChannel(null, 0) threw TypeError: "Failed to execute 'copyToChannel' on 'AudioBuffer': parameter 1 is not of type 'Float32Array'.". -PASS 1: buffer.copyToChannel(context, 0) threw TypeError: "Failed to execute 'copyToChannel' on 'AudioBuffer': parameter 1 is not of type 'Float32Array'.". -PASS 2: buffer.copyToChannel(x, -1) threw IndexSizeError: "Failed to execute 'copyToChannel' on 'AudioBuffer': The channelNumber provided (-1) is outside the range [0, 2].". -PASS 3: buffer.copyToChannel(x, 3) threw IndexSizeError: "Failed to execute 'copyToChannel' on 'AudioBuffer': The channelNumber provided (3) is outside the range [0, 2].". -PASS 4: buffer.copyToChannel(x, 0, -1) threw IndexSizeError: "Failed to execute 'copyToChannel' on 'AudioBuffer': The startInChannel provided (4294967295) is outside the range [0, 16).". -FAIL X 5: buffer.copyToChannel(x, 0, 16) incorrectly threw IndexSizeError: "Failed to execute 'copyToChannel' on 'AudioBuffer': The startInChannel provided (16) is outside the range [0, 16).". assert_true: expected true got false -PASS 6: buffer.copyToChannel(x, 3) threw IndexSizeError: "Failed to execute 'copyToChannel' on 'AudioBuffer': The channelNumber provided (3) is outside the range [0, 2].". -PASS 7: buffer.copyToChannel(SharedArrayBuffer view, 0) threw TypeError: "Failed to execute 'copyToChannel' on 'AudioBuffer': The provided ArrayBufferView value must not be shared.". -PASS 8: buffer.copyToChannel(SharedArrayBuffer view, 0, 0) threw TypeError: "Failed to execute 'copyToChannel' on 'AudioBuffer': The provided ArrayBufferView value must not be shared.". -FAIL < [copyTo-exceptions] 1 out of 10 assertions were failed. assert_true: expected true got false -PASS > [copyFrom-validate] -PASS buffer.copyFromChannel(dst8, 0) is identical to the array [1,2,3,4,5,6,7,8]. -PASS buffer.copyFromChannel(dst8, 1) is identical to the array [2,3,4,5,6,7,8,9]. -PASS buffer.copyFromChannel(dst8, 2) is identical to the array [3,4,5,6,7,8,9,10]. -PASS buffer.copyFromChannel(dst8, 0, 1) is identical to the array [2,3,4,5,6,7,8,9]. -PASS buffer.copyFromChannel(dst8, 1, 1) is identical to the array [3,4,5,6,7,8,9,10]. -PASS buffer.copyFromChannel(dst8, 2, 1) is identical to the array [4,5,6,7,8,9,10,11]. -PASS buffer.copyFromChannel(dst8, 0, 11) is identical to the array [12,13,14,15,16,-1,-1,-1]. -PASS buffer.copyFromChannel(dst8, 1, 11) is identical to the array [13,14,15,16,17,-1,-1,-1]. -PASS buffer.copyFromChannel(dst8, 2, 11) is identical to the array [14,15,16,17,18,-1,-1,-1]. -PASS buffer.copyFromChannel(dst26, 0) is identical to the array [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16...]. -PASS buffer.copyFromChannel(dst26, 1) is identical to the array [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17...]. -PASS buffer.copyFromChannel(dst26, 2) is identical to the array [3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18...]. -PASS < [copyFrom-validate] All assertions passed. (total 12 assertions) -PASS > [copyTo-validate] -PASS buffer = createConstantBuffer(context, 16, [-1,-1,-1]) did not throw an exception. -PASS buffer.copyToChannel(src, 0) is identical to the array [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16...]. -PASS buffer.copyToChannel(src, 1) is identical to the array [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16...]. -PASS buffer.copyToChannel(src, 2) is identical to the array [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16...]. -PASS buffer.copyToChannel(src10, 0) is identical to the array [1,2,3,4,5,6,7,8,9,10,-1,-1,-1,-1,-1,-1...]. -PASS buffer.copyToChannel(src10, 1) is identical to the array [1,2,3,4,5,6,7,8,9,10,-1,-1,-1,-1,-1,-1...]. -PASS buffer.copyToChannel(src10, 2) is identical to the array [1,2,3,4,5,6,7,8,9,10,-1,-1,-1,-1,-1,-1...]. -PASS buffer.copyToChannel(src10, 0, 5) is identical to the array [-1,-1,-1,-1,-1,1,2,3,4,5,6,7,8,9,10,-1...]. -PASS buffer.copyToChannel(src10, 1, 5) is identical to the array [-1,-1,-1,-1,-1,1,2,3,4,5,6,7,8,9,10,-1...]. -PASS buffer.copyToChannel(src10, 2, 5) is identical to the array [-1,-1,-1,-1,-1,1,2,3,4,5,6,7,8,9,10,-1...]. -PASS < [copyTo-validate] All assertions passed. (total 10 assertions) -FAIL # AUDIT TASK RUNNER FINISHED: 2 out of 5 tasks were failed. assert_true: expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html index a1a5f3fc..4f9a998 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html
@@ -137,7 +137,7 @@ ; should(() => { buffer.copyFromChannel(x, 0, -1); - }, '5: buffer.copyFromChannel(x, 0, -1)').throw(DOMException, 'IndexSizeError'); + }, '5: buffer.copyFromChannel(x, 0, -1)').notThrow(); should( () => { buffer.copyFromChannel(x, 0, bufferLength); @@ -192,7 +192,7 @@ .throw(DOMException, 'IndexSizeError'); should(() => { buffer.copyToChannel(x, 0, -1); - }, '4: buffer.copyToChannel(x, 0, -1)').throw(DOMException, 'IndexSizeError'); + }, '4: buffer.copyToChannel(x, 0, -1)').notThrow(); should( () => { buffer.copyToChannel(x, 0, bufferLength);
diff --git a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt index 519a938a..b4ff722 100644 --- a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 202 tests; 199 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 202 tests; 200 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS Partial interface Navigator: original interface defined PASS Partial dictionary WebGLContextAttributes: original dictionary defined @@ -145,7 +145,7 @@ PASS XRInputSource interface: attribute targetRaySpace PASS XRInputSource interface: attribute gripSpace PASS XRInputSource interface: attribute gamepad -FAIL XRInputSource interface: attribute profiles assert_true: The prototype object must have a property "profiles" expected true got false +PASS XRInputSource interface: attribute profiles PASS XRInputSourceArray interface: existence and properties of interface object PASS XRInputSourceArray interface object length PASS XRInputSourceArray interface object name
diff --git a/third_party/blink/web_tests/fast/css/css2-system-color.html b/third_party/blink/web_tests/fast/css/css2-system-color.html new file mode 100644 index 0000000..ca291f3 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/css2-system-color.html
@@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html> +<meta name="assert" content="System color keywords work as expected."> +<link rel="match" href="css2-system-color-expected.html"> +<head> +<title>Color Test</title> +<style> + html { + font-size: 12px; + width: 750px; + } + .box:after { + content: " "; + clear: both; + display: block; + } + .inner { + border-top: solid 1px; + float: right; + width: 620px; + } + .text { + float: left; + } +</style> +</head> +<body> + <div class="box"><div class="text">ActiveBorder</div><div class="inner" style="background-color: ActiveBorder"> </div></div> + <div class="box"><div class="text">ActiveCaption</div><div class="inner" style="background-color: ActiveCaption"> </div></div> + <div class="box"><div class="text">AppWorkspace</div><div class="inner" style="background-color: AppWorkspace"> </div></div> + <div class="box"><div class="text">Background</div><div class="inner" style="background-color: Background"> </div></div> + <div class="box"><div class="text">ButtonFace</div><div class="inner" style="background-color: ButtonFace"> </div></div> + <div class="box"><div class="text">ButtonHighlight</div><div class="inner" style="background-color: ButtonHighlight"> </div></div> + <div class="box"><div class="text">ButtonShadow</div><div class="inner" style="background-color: ButtonShadow"> </div></div> + <div class="box"><div class="text">ButtonText</div><div class="inner" style="background-color: ButtonText"> </div></div> + <div class="box"><div class="text">CaptionText</div><div class="inner" style="background-color: CaptionText"> </div></div> + <div class="box"><div class="text">GrayText</div><div class="inner" style="background-color: GrayText"> </div></div> + <div class="box"><div class="text">Highlight</div><div class="inner" style="background-color: Highlight"> </div></div> + <div class="box"><div class="text">HighlightText</div><div class="inner" style="background-color: HighlightText"> </div></div> + <div class="box"><div class="text">InactiveBorder</div><div class="inner" style="background-color: InactiveBorder"> </div></div> + <div class="box"><div class="text">InactiveCaption</div><div class="inner" style="background-color: InactiveCaption"> </div></div> + <div class="box"><div class="text">InactiveCaptionText</div><div class="inner" style="background-color: InactiveCaptionText"> </div></div> + <div class="box"><div class="text">InfoBackground</div><div class="inner" style="background-color: InfoBackground"> </div></div> + <div class="box"><div class="text">InfoText</div><div class="inner" style="background-color: InfoText"> </div></div> + <div class="box"><div class="text">Menu</div><div class="inner" style="background-color: Menu"> </div></div> + <div class="box"><div class="text">MenuText</div><div class="inner" style="background-color: MenuText"> </div></div> + <div class="box"><div class="text">Scrollbar</div><div class="inner" style="background-color: Scrollbar"> </div></div> + <div class="box"><div class="text">ThreeDDarkShadow</div><div class="inner" style="background-color: ThreeDDarkShadow"> </div></div> + <div class="box"><div class="text">ThreeDFace</div><div class="inner" style="background-color: ThreeDFace"> </div></div> + <div class="box"><div class="text">ThreeDHighlight</div><div class="inner" style="background-color: ThreeDHighlight"> </div></div> + <div class="box"><div class="text">ThreeDLightShadow</div><div class="inner" style="background-color: ThreeDLightShadow"> </div></div> + <div class="box"><div class="text">ThreeDShadow</div><div class="inner" style="background-color: ThreeDShadow"> </div></div> + <div class="box"><div class="text">Window</div><div class="inner" style="background-color: Window"> </div></div> + <div class="box"><div class="text">WindowFrame</div><div class="inner" style="background-color: WindowFrame"> </div></div> + <div class="box"><div class="text">WindowText</div><div class="inner" style="background-color: WindowText"> </div></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/css2-system-color.html-disabled b/third_party/blink/web_tests/fast/css/css2-system-color.html-disabled deleted file mode 100644 index 41d983a..0000000 --- a/third_party/blink/web_tests/fast/css/css2-system-color.html-disabled +++ /dev/null
@@ -1,60 +0,0 @@ -<html><head><title>Color Test</title> -<style> - html { text-align: center; font-size: 10px; font-family: verdana; } - .content { - border: 1px solid black; - margin: 0 auto; - text-align: left; - width: 750px; - padding: 2px 2px 1px 2px; - } - .box { width: 100%; margin-bottom: 1px; } - .box:after { - content: " "; - display: block; - visibility: hidden; - clear: both; - height: 0.1px; - font-size: 0.1em; - line-height: 0; - } - * html .box { display: inline-block; } - * html .box { height: 1%; } - .box { display: block; } - - .inner { width: 620px; float: right; } - .text { float: left; } -</style> -</head><body> - -<div class="content"> - <div class="box"><div class="text">ActiveBorder</div><div class="inner" style="background-color: ActiveBorder"> </div></div> - <div class="box"><div class="text">ActiveCaption</div><div class="inner" style="background-color: ActiveCaption"> </div></div> - <div class="box"><div class="text">AppWorkspace</div><div class="inner" style="background-color: AppWorkspace"> </div></div> - <div class="box"><div class="text">Background</div><div class="inner" style="background-color: Background"> </div></div> - <div class="box"><div class="text">ButtonFace</div><div class="inner" style="background-color: ButtonFace"> </div></div> - <div class="box"><div class="text">ButtonHighlight</div><div class="inner" style="background-color: ButtonHighlight"> </div></div> - <div class="box"><div class="text">ButtonShadow</div><div class="inner" style="background-color: ButtonShadow"> </div></div> - <div class="box"><div class="text">ButtonText</div><div class="inner" style="background-color: ButtonText"> </div></div> - <div class="box"><div class="text">CaptionText</div><div class="inner" style="background-color: CaptionText"> </div></div> - <div class="box"><div class="text">GrayText</div><div class="inner" style="background-color: GrayText"> </div></div> - <div class="box"><div class="text">Highlight</div><div class="inner" style="background-color: Highlight"> </div></div> - <div class="box"><div class="text">HighlightText</div><div class="inner" style="background-color: HighlightText"> </div></div> - <div class="box"><div class="text">InactiveBorder</div><div class="inner" style="background-color: InactiveBorder"> </div></div> - <div class="box"><div class="text">InactiveCaption</div><div class="inner" style="background-color: InactiveCaption"> </div></div> - <div class="box"><div class="text">InactiveCaptionText</div><div class="inner" style="background-color: InactiveCaptionText"> </div></div> - <div class="box"><div class="text">InfoBackground</div><div class="inner" style="background-color: InfoBackground"> </div></div> - <div class="box"><div class="text">InfoText</div><div class="inner" style="background-color: InfoText"> </div></div> - <div class="box"><div class="text">Menu</div><div class="inner" style="background-color: Menu"> </div></div> - <div class="box"><div class="text">MenuText</div><div class="inner" style="background-color: MenuText"> </div></div> - <div class="box"><div class="text">Scrollbar</div><div class="inner" style="background-color: Scrollbar"> </div></div> - <div class="box"><div class="text">ThreeDDarkShadow</div><div class="inner" style="background-color: ThreeDDarkShadow"> </div></div> - <div class="box"><div class="text">ThreeDFace</div><div class="inner" style="background-color: ThreeDFace"> </div></div> - <div class="box"><div class="text">ThreeDHighlight</div><div class="inner" style="background-color: ThreeDHighlight"> </div></div> - <div class="box"><div class="text">ThreeDLightShadow</div><div class="inner" style="background-color: ThreeDLightShadow"> </div></div> - <div class="box"><div class="text">ThreeDShadow</div><div class="inner" style="background-color: ThreeDShadow"> </div></div> - <div class="box"><div class="text">Window</div><div class="inner" style="background-color: Window"> </div></div> - <div class="box"><div class="text">WindowFrame</div><div class="inner" style="background-color: WindowFrame"> </div></div> - <div class="box"><div class="text">WindowText</div><div class="inner" style="background-color: WindowText"> </div></div> -</div> -</body></html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/fast/scrolling/scrollbars/mouse-scrolling-on-div-scrollbar.html b/third_party/blink/web_tests/fast/scrolling/scrollbars/mouse-scrolling-on-div-scrollbar.html index 575e991..6e5f221 100644 --- a/third_party/blink/web_tests/fast/scrolling/scrollbars/mouse-scrolling-on-div-scrollbar.html +++ b/third_party/blink/web_tests/fast/scrolling/scrollbars/mouse-scrolling-on-div-scrollbar.html
@@ -140,6 +140,12 @@ await mouseDownAt(x, y); assert_equals(standardDivFast.scrollTop, 0, "Mousedown on vertical scrollbar thumb is not expected to scroll."); + await mouseMoveTo(x, y-10); + assert_equals(standardDivFast.scrollTop, 0, "Vertical thumb drag beyond the track should not cause a scroll."); + + await mouseMoveTo(x, y); + assert_equals(standardDivFast.scrollTop, 0, "Vertical thumb drag beyond the track and back should not cause a scroll."); + y += SCROLL_DELTA; await mouseMoveTo(x, y); assert_equals(standardDivFast.scrollTop, 915, "Vertical thumb drag downwards did not scroll as expected."); @@ -159,6 +165,12 @@ await mouseDownAt(x, y); assert_equals(standardDivFast.scrollLeft, 0, "Mousedown on horizontal scrollbar thumb is not expected to scroll."); + await mouseMoveTo(x-10, y); + assert_equals(standardDivFast.scrollLeft, 0, "Horizontal thumb drag beyond the track should not cause a scroll."); + + await mouseMoveTo(x, y); + assert_equals(standardDivFast.scrollLeft, 0, "Horizontal thumb drag beyond the track and back should not cause a scroll."); + x += SCROLL_DELTA; await mouseMoveTo(x, y); assert_equals(standardDivFast.scrollLeft, 915, "Horizontal thumb drag towards the right did not scroll as expected.");
diff --git a/third_party/blink/web_tests/fast/scrolling/scrollbars/mouse-scrolling-on-root-scrollbar.html b/third_party/blink/web_tests/fast/scrolling/scrollbars/mouse-scrolling-on-root-scrollbar.html index 7f6aa8c..b7dcf6f 100644 --- a/third_party/blink/web_tests/fast/scrolling/scrollbars/mouse-scrolling-on-root-scrollbar.html +++ b/third_party/blink/web_tests/fast/scrolling/scrollbars/mouse-scrolling-on-root-scrollbar.html
@@ -85,6 +85,12 @@ await mouseDownAt(x, y); assert_equals(window.scrollY, 0, "Mousedown on vertical scrollbar thumb is not expected to scroll."); + await mouseMoveTo(x, y-10); + assert_equals(window.scrollY, 0, "Vertical thumb drag beyond the track should not cause a scroll."); + + await mouseMoveTo(x, y); + assert_equals(window.scrollY, 0, "Vertical thumb drag beyond the track and back should not cause a scroll."); + y += SCROLL_DELTA; await mouseMoveTo(x, y); // TODO(arakeri): There is currently a 1 px difference when dragging the thumb on the compositor thread @@ -107,6 +113,12 @@ await mouseDownAt(x, y); assert_equals(window.scrollX, 0, "Mousedown on horizontal scrollbar thumb is not expected to scroll."); + await mouseMoveTo(x-10, y); + assert_equals(window.scrollX, 0, "Horizontal thumb drag beyond the track should not cause a scroll."); + + await mouseMoveTo(x, y); + assert_equals(window.scrollX, 0, "Horizontal thumb drag beyond the track and back should not cause a scroll."); + x += SCROLL_DELTA; await mouseMoveTo(x, y); assert_approx_equals(window.scrollX, 133, 1, "Horizontal thumb drag towards the right did not scroll as expected.");
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=UseWindowsSystemColors/fast/css/css2-system-color-expected.html b/third_party/blink/web_tests/flag-specific/enable-blink-features=UseWindowsSystemColors/fast/css/css2-system-color-expected.html new file mode 100644 index 0000000..5039e2c --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=UseWindowsSystemColors/fast/css/css2-system-color-expected.html
@@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html> +<head> +<title>Color Test</title> +<style> + html { + font-size: 12px; + width: 750px; + } + .box:after { + content: " "; + clear: both; + display: block; + } + .inner { + border-top: solid 1px; + float: right; + width: 620px; + } + .text { + float: left; + } +</style> +</head> +<body> + <div class="box"><div class="text">ActiveBorder</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">ActiveCaption</div><div class="inner" style="background-color: rgb(204, 204, 204)"> </div></div> + <div class="box"><div class="text">AppWorkspace</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">Background</div><div class="inner" style="background-color: rgb(99, 99, 206)"> </div></div> + <div class="box"><div class="text">ButtonFace</div><div class="inner" style="background-color: rgb(240, 240, 240)"> </div></div> + <div class="box"><div class="text">ButtonHighlight</div><div class="inner" style="background-color: rgb(221, 221, 221)"> </div></div> + <div class="box"><div class="text">ButtonShadow</div><div class="inner" style="background-color: rgb(136, 136, 136)"> </div></div> + <div class="box"><div class="text">ButtonText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">CaptionText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">GrayText</div><div class="inner" style="background-color: rgb(109, 109, 109)"> </div></div> + <div class="box"><div class="text">Highlight</div><div class="inner" style="background-color: rgb(0, 120, 215)"> </div></div> + <div class="box"><div class="text">HighlightText</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">InactiveBorder</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">InactiveCaption</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">InactiveCaptionText</div><div class="inner" style="background-color: rgb(127, 127, 127)"> </div></div> + <div class="box"><div class="text">InfoBackground</div><div class="inner" style="background-color: rgb(251, 252, 197)"> </div></div> + <div class="box"><div class="text">InfoText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">Menu</div><div class="inner" style="background-color: rgb(247, 247, 247)"> </div></div> + <div class="box"><div class="text">MenuText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">Scrollbar</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">ThreeDDarkShadow</div><div class="inner" style="background-color: rgb(102, 102, 102)"> </div></div> + <div class="box"><div class="text">ThreeDFace</div><div class="inner" style="background-color: rgb(192, 192, 192)"> </div></div> + <div class="box"><div class="text">ThreeDHighlight</div><div class="inner" style="background-color: rgb(221, 221, 221)"> </div></div> + <div class="box"><div class="text">ThreeDLightShadow</div><div class="inner" style="background-color: rgb(192, 192, 192)"> </div></div> + <div class="box"><div class="text">ThreeDShadow</div><div class="inner" style="background-color: rgb(136, 136, 136)"> </div></div> + <div class="box"><div class="text">Window</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">WindowFrame</div><div class="inner" style="background-color: rgb(204, 204, 204)"> </div></div> + <div class="box"><div class="text">WindowText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/platform/linux/fast/css/css2-system-color-expected.html b/third_party/blink/web_tests/platform/linux/fast/css/css2-system-color-expected.html new file mode 100644 index 0000000..b4fcd2fe --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/fast/css/css2-system-color-expected.html
@@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html> +<head> +<title>Color Test</title> +<style> + html { + font-size: 12px; + width: 750px; + } + .box:after { + content: " "; + clear: both; + display: block; + } + .inner { + border-top: solid 1px; + float: right; + width: 620px; + } + .text { + float: left; + } +</style> +</head> +<body> + <div class="box"><div class="text">ActiveBorder</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">ActiveCaption</div><div class="inner" style="background-color: rgb(204, 204, 204)"> </div></div> + <div class="box"><div class="text">AppWorkspace</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">Background</div><div class="inner" style="background-color: rgb(99, 99, 206)"> </div></div> + <div class="box"><div class="text">ButtonFace</div><div class="inner" style="background-color: rgb(192, 192, 192)"> </div></div> + <div class="box"><div class="text">ButtonHighlight</div><div class="inner" style="background-color: rgb(221, 221, 221)"> </div></div> + <div class="box"><div class="text">ButtonShadow</div><div class="inner" style="background-color: rgb(136, 136, 136)"> </div></div> + <div class="box"><div class="text">ButtonText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">CaptionText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">GrayText</div><div class="inner" style="background-color: rgb(128, 128, 128)"> </div></div> + <div class="box"><div class="text">Highlight</div><div class="inner" style="background-color: rgb(181, 213, 255)"> </div></div> + <div class="box"><div class="text">HighlightText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">InactiveBorder</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">InactiveCaption</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">InactiveCaptionText</div><div class="inner" style="background-color: rgb(127, 127, 127)"> </div></div> + <div class="box"><div class="text">InfoBackground</div><div class="inner" style="background-color: rgb(251, 252, 197)"> </div></div> + <div class="box"><div class="text">InfoText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">Menu</div><div class="inner" style="background-color: rgb(247, 247, 247)"> </div></div> + <div class="box"><div class="text">MenuText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">Scrollbar</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">ThreeDDarkShadow</div><div class="inner" style="background-color: rgb(102, 102, 102)"> </div></div> + <div class="box"><div class="text">ThreeDFace</div><div class="inner" style="background-color: rgb(192, 192, 192)"> </div></div> + <div class="box"><div class="text">ThreeDHighlight</div><div class="inner" style="background-color: rgb(221, 221, 221)"> </div></div> + <div class="box"><div class="text">ThreeDLightShadow</div><div class="inner" style="background-color: rgb(192, 192, 192)"> </div></div> + <div class="box"><div class="text">ThreeDShadow</div><div class="inner" style="background-color: rgb(136, 136, 136)"> </div></div> + <div class="box"><div class="text">Window</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">WindowFrame</div><div class="inner" style="background-color: rgb(204, 204, 204)"> </div></div> + <div class="box"><div class="text">WindowText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/platform/mac/fast/css/css2-system-color-expected.html b/third_party/blink/web_tests/platform/mac/fast/css/css2-system-color-expected.html new file mode 100644 index 0000000..af69827a --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/fast/css/css2-system-color-expected.html
@@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html> +<head> +<title>Color Test</title> +<style> + html { + font-size: 12px; + width: 750px; + } + .box:after { + content: " "; + clear: both; + display: block; + } + .inner { + border-top: solid 1px; + float: right; + width: 620px; + } + .text { + float: left; + } +</style> +</head> +<body> + <div class="box"><div class="text">ActiveBorder</div><div class="inner" style="background-color: rgb(59, 153, 252)"> </div></div> + <div class="box"><div class="text">ActiveCaption</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">AppWorkspace</div><div class="inner" style="background-color: rgb(170, 170, 170)"> </div></div> + <div class="box"><div class="text">Background</div><div class="inner" style="background-color: rgb(99, 99, 206)"> </div></div> + <div class="box"><div class="text">ButtonFace</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">ButtonHighlight</div><div class="inner" style="background-color: rgb(233, 233, 233)"> </div></div> + <div class="box"><div class="text">ButtonShadow</div><div class="inner" style="background-color: rgba(159, 160, 159)"> </div></div> + <div class="box"><div class="text">ButtonText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">CaptionText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">GrayText</div><div class="inner" style="background-color: rgb(127, 127, 127)"> </div></div> + <div class="box"><div class="text">Highlight</div><div class="inner" style="background-color: rgb(181, 213, 255)"> </div></div> + <div class="box"><div class="text">HighlightText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">InactiveBorder</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">InactiveCaption</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">InactiveCaptionText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">InfoBackground</div><div class="inner" style="background-color: rgb(251, 252, 197)"> </div></div> + <div class="box"><div class="text">InfoText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">Menu</div><div class="inner" style="background-color: rgb(246, 246, 246)"> </div></div> + <div class="box"><div class="text">MenuText</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">Scrollbar</div><div class="inner" style="background-color: rgb(170, 170, 170)"> </div></div> + <div class="box"><div class="text">ThreeDDarkShadow</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">ThreeDFace</div><div class="inner" style="background-color: rgb(192, 192, 192)"> </div></div> + <div class="box"><div class="text">ThreeDHighlight</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">ThreeDLightShadow</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">ThreeDShadow</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">Window</div><div class="inner" style="background-color: rgb(236, 236, 236)"> </div></div> + <div class="box"><div class="text">WindowFrame</div><div class="inner" style="background-color: rgb(170, 170, 170)"> </div></div> + <div class="box"><div class="text">WindowText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/platform/win/fast/css/css2-system-color-expected.html b/third_party/blink/web_tests/platform/win/fast/css/css2-system-color-expected.html new file mode 100644 index 0000000..b4fcd2fe --- /dev/null +++ b/third_party/blink/web_tests/platform/win/fast/css/css2-system-color-expected.html
@@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html> +<head> +<title>Color Test</title> +<style> + html { + font-size: 12px; + width: 750px; + } + .box:after { + content: " "; + clear: both; + display: block; + } + .inner { + border-top: solid 1px; + float: right; + width: 620px; + } + .text { + float: left; + } +</style> +</head> +<body> + <div class="box"><div class="text">ActiveBorder</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">ActiveCaption</div><div class="inner" style="background-color: rgb(204, 204, 204)"> </div></div> + <div class="box"><div class="text">AppWorkspace</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">Background</div><div class="inner" style="background-color: rgb(99, 99, 206)"> </div></div> + <div class="box"><div class="text">ButtonFace</div><div class="inner" style="background-color: rgb(192, 192, 192)"> </div></div> + <div class="box"><div class="text">ButtonHighlight</div><div class="inner" style="background-color: rgb(221, 221, 221)"> </div></div> + <div class="box"><div class="text">ButtonShadow</div><div class="inner" style="background-color: rgb(136, 136, 136)"> </div></div> + <div class="box"><div class="text">ButtonText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">CaptionText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">GrayText</div><div class="inner" style="background-color: rgb(128, 128, 128)"> </div></div> + <div class="box"><div class="text">Highlight</div><div class="inner" style="background-color: rgb(181, 213, 255)"> </div></div> + <div class="box"><div class="text">HighlightText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">InactiveBorder</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">InactiveCaption</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">InactiveCaptionText</div><div class="inner" style="background-color: rgb(127, 127, 127)"> </div></div> + <div class="box"><div class="text">InfoBackground</div><div class="inner" style="background-color: rgb(251, 252, 197)"> </div></div> + <div class="box"><div class="text">InfoText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">Menu</div><div class="inner" style="background-color: rgb(247, 247, 247)"> </div></div> + <div class="box"><div class="text">MenuText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">Scrollbar</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">ThreeDDarkShadow</div><div class="inner" style="background-color: rgb(102, 102, 102)"> </div></div> + <div class="box"><div class="text">ThreeDFace</div><div class="inner" style="background-color: rgb(192, 192, 192)"> </div></div> + <div class="box"><div class="text">ThreeDHighlight</div><div class="inner" style="background-color: rgb(221, 221, 221)"> </div></div> + <div class="box"><div class="text">ThreeDLightShadow</div><div class="inner" style="background-color: rgb(192, 192, 192)"> </div></div> + <div class="box"><div class="text">ThreeDShadow</div><div class="inner" style="background-color: rgb(136, 136, 136)"> </div></div> + <div class="box"><div class="text">Window</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">WindowFrame</div><div class="inner" style="background-color: rgb(204, 204, 204)"> </div></div> + <div class="box"><div class="text">WindowText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/platform/win7/fast/css/css2-system-color-expected.html b/third_party/blink/web_tests/platform/win7/fast/css/css2-system-color-expected.html new file mode 100644 index 0000000..b4fcd2fe --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/fast/css/css2-system-color-expected.html
@@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html> +<head> +<title>Color Test</title> +<style> + html { + font-size: 12px; + width: 750px; + } + .box:after { + content: " "; + clear: both; + display: block; + } + .inner { + border-top: solid 1px; + float: right; + width: 620px; + } + .text { + float: left; + } +</style> +</head> +<body> + <div class="box"><div class="text">ActiveBorder</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">ActiveCaption</div><div class="inner" style="background-color: rgb(204, 204, 204)"> </div></div> + <div class="box"><div class="text">AppWorkspace</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">Background</div><div class="inner" style="background-color: rgb(99, 99, 206)"> </div></div> + <div class="box"><div class="text">ButtonFace</div><div class="inner" style="background-color: rgb(192, 192, 192)"> </div></div> + <div class="box"><div class="text">ButtonHighlight</div><div class="inner" style="background-color: rgb(221, 221, 221)"> </div></div> + <div class="box"><div class="text">ButtonShadow</div><div class="inner" style="background-color: rgb(136, 136, 136)"> </div></div> + <div class="box"><div class="text">ButtonText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">CaptionText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">GrayText</div><div class="inner" style="background-color: rgb(128, 128, 128)"> </div></div> + <div class="box"><div class="text">Highlight</div><div class="inner" style="background-color: rgb(181, 213, 255)"> </div></div> + <div class="box"><div class="text">HighlightText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">InactiveBorder</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">InactiveCaption</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">InactiveCaptionText</div><div class="inner" style="background-color: rgb(127, 127, 127)"> </div></div> + <div class="box"><div class="text">InfoBackground</div><div class="inner" style="background-color: rgb(251, 252, 197)"> </div></div> + <div class="box"><div class="text">InfoText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">Menu</div><div class="inner" style="background-color: rgb(247, 247, 247)"> </div></div> + <div class="box"><div class="text">MenuText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> + <div class="box"><div class="text">Scrollbar</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">ThreeDDarkShadow</div><div class="inner" style="background-color: rgb(102, 102, 102)"> </div></div> + <div class="box"><div class="text">ThreeDFace</div><div class="inner" style="background-color: rgb(192, 192, 192)"> </div></div> + <div class="box"><div class="text">ThreeDHighlight</div><div class="inner" style="background-color: rgb(221, 221, 221)"> </div></div> + <div class="box"><div class="text">ThreeDLightShadow</div><div class="inner" style="background-color: rgb(192, 192, 192)"> </div></div> + <div class="box"><div class="text">ThreeDShadow</div><div class="inner" style="background-color: rgb(136, 136, 136)"> </div></div> + <div class="box"><div class="text">Window</div><div class="inner" style="background-color: rgb(255, 255, 255)"> </div></div> + <div class="box"><div class="text">WindowFrame</div><div class="inner" style="background-color: rgb(204, 204, 204)"> </div></div> + <div class="box"><div class="text">WindowText</div><div class="inner" style="background-color: rgb(0, 0, 0)"> </div></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/scrollingcoordinator/non-fast-scrollable-region-scaled-iframe.html b/third_party/blink/web_tests/scrollingcoordinator/non-fast-scrollable-region-scaled-iframe.html index 184dd56..35e6c3cc 100644 --- a/third_party/blink/web_tests/scrollingcoordinator/non-fast-scrollable-region-scaled-iframe.html +++ b/third_party/blink/web_tests/scrollingcoordinator/non-fast-scrollable-region-scaled-iframe.html
@@ -35,7 +35,14 @@ runAfterLayoutAndPaint(function(){ nonFastScrollableRects = internals.nonFastScrollableRects(document); shouldBe('nonFastScrollableRects.length', '1'); - shouldBeEqualToString('rectToString(nonFastScrollableRects[0])', '[110, 110, 120, 120]'); + // PaintNonFastScrollableRegions stores the non-fast region in the space + // of the scaled layer but prints it in absolute coordinates so the rect + // is scaled here. + if (internals.runtimeFlags.paintNonFastScrollableRegionsEnabled) { + shouldBeEqualToString('rectToString(nonFastScrollableRects[0])', '[220, 220, 240, 240]'); + } else { + shouldBeEqualToString('rectToString(nonFastScrollableRects[0])', '[110, 110, 120, 120]'); + } drawNonFastScrollableRegionOverlays();
diff --git a/third_party/blink/web_tests/virtual/composite-after-paint/README.md b/third_party/blink/web_tests/virtual/composite-after-paint/README.md new file mode 100644 index 0000000..172c9a3 --- /dev/null +++ b/third_party/blink/web_tests/virtual/composite-after-paint/README.md
@@ -0,0 +1 @@ +This suite runs tests with --enable-blink-features=PaintNonFastScrollableRegions
diff --git a/third_party/blink/web_tests/virtual/composite-after-paint/scrollingcoordinator/README.txt b/third_party/blink/web_tests/virtual/composite-after-paint/scrollingcoordinator/README.txt new file mode 100644 index 0000000..172c9a3 --- /dev/null +++ b/third_party/blink/web_tests/virtual/composite-after-paint/scrollingcoordinator/README.txt
@@ -0,0 +1 @@ +This suite runs tests with --enable-blink-features=PaintNonFastScrollableRegions
diff --git a/third_party/blink/web_tests/virtual/composite-after-paint/scrollingcoordinator/non-fast-scrollable-region-scaled-iframe-expected.txt b/third_party/blink/web_tests/virtual/composite-after-paint/scrollingcoordinator/non-fast-scrollable-region-scaled-iframe-expected.txt new file mode 100644 index 0000000..3b22aa9 --- /dev/null +++ b/third_party/blink/web_tests/virtual/composite-after-paint/scrollingcoordinator/non-fast-scrollable-region-scaled-iframe-expected.txt
@@ -0,0 +1,10 @@ +This test ensures non-fast scrollable areas are calculated correctly when page is scaled. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + +PASS nonFastScrollableRects.length is 1 +PASS rectToString(nonFastScrollableRects[0]) is "[220, 220, 240, 240]" +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/blink/web_tests/virtual/paint-non-fast-scrollable-regions/scrollingcoordinator/README.txt b/third_party/blink/web_tests/virtual/paint-non-fast-scrollable-regions/scrollingcoordinator/README.txt new file mode 100644 index 0000000..172c9a3 --- /dev/null +++ b/third_party/blink/web_tests/virtual/paint-non-fast-scrollable-regions/scrollingcoordinator/README.txt
@@ -0,0 +1 @@ +This suite runs tests with --enable-blink-features=PaintNonFastScrollableRegions
diff --git a/third_party/blink/web_tests/virtual/paint-non-fast-scrollable-regions/scrollingcoordinator/non-fast-scrollable-region-scaled-iframe-expected.txt b/third_party/blink/web_tests/virtual/paint-non-fast-scrollable-regions/scrollingcoordinator/non-fast-scrollable-region-scaled-iframe-expected.txt new file mode 100644 index 0000000..3b22aa9 --- /dev/null +++ b/third_party/blink/web_tests/virtual/paint-non-fast-scrollable-regions/scrollingcoordinator/non-fast-scrollable-region-scaled-iframe-expected.txt
@@ -0,0 +1,10 @@ +This test ensures non-fast scrollable areas are calculated correctly when page is scaled. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + +PASS nonFastScrollableRects.length is 1 +PASS rectToString(nonFastScrollableRects[0]) is "[220, 220, 240, 240]" +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/blink/web_tests/virtual/threaded/external/wpt/animation-worklet/idlharness.any-expected.txt b/third_party/blink/web_tests/virtual/threaded/external/wpt/animation-worklet/idlharness.any-expected.txt new file mode 100644 index 0000000..2aa4f5b7 --- /dev/null +++ b/third_party/blink/web_tests/virtual/threaded/external/wpt/animation-worklet/idlharness.any-expected.txt
@@ -0,0 +1,24 @@ +This is a testharness.js-based test. +PASS idl_test setup +PASS Partial namespace CSS: original namespace defined +PASS Partial namespace CSS: valid exposure set +PASS Partial interface AnimationEffect: original interface defined +FAIL Partial interface AnimationEffect: valid exposure set Partial AnimationEffect interface is exposed to 'AnimationWorklet', the original interface is not. +PASS AnimationWorkletGlobalScope interface: existence and properties of interface object +FAIL WorkletAnimation interface: existence and properties of interface object assert_equals: prototype of WorkletAnimation is not Animation expected function "function Animation() { [native code] }" but got function "function () { [native code] }" +FAIL WorkletAnimation interface object length assert_equals: wrong value for WorkletAnimation.length expected 1 but got 2 +PASS WorkletAnimation interface object name +FAIL WorkletAnimation interface: existence and properties of interface prototype object assert_equals: prototype of WorkletAnimation.prototype is not Animation.prototype expected object "[object Animation]" but got object "[object Object]" +PASS WorkletAnimation interface: existence and properties of interface prototype object's "constructor" property +PASS WorkletAnimation interface: existence and properties of interface prototype object's @@unscopables property +PASS WorkletAnimation interface: attribute animatorName +FAIL WorkletAnimation must be primary interface of new WorkletAnimation("name") assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'WorkletAnimation': 2 arguments required, but only 1 present." +FAIL Stringification of new WorkletAnimation("name") assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'WorkletAnimation': 2 arguments required, but only 1 present." +FAIL WorkletAnimation interface: new WorkletAnimation("name") must inherit property "animatorName" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'WorkletAnimation': 2 arguments required, but only 1 present." +PASS WorkletGroupEffect interface: existence and properties of interface object +PASS WorkletGlobalScope interface: existence and properties of interface object +PASS AnimationEffect interface: member localTime +PASS CSS namespace: operation escape(CSSOMString) +FAIL CSS namespace: attribute animationWorklet assert_own_property: CSS does not have property "animationWorklet" expected property "animationWorklet" missing +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index 3f31c26..5ee3295 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -10685,6 +10685,7 @@ getter gamepad getter gripSpace getter handedness + getter profiles getter targetRayMode getter targetRaySpace method constructor
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 614e957..b15304e2 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -58,6 +58,8 @@ STAMP_FILE = os.path.normpath( os.path.join(LLVM_BUILD_DIR, 'cr_build_revision')) +OLD_STAMP_FILE = os.path.normpath( + os.path.join(LLVM_BUILD_DIR, '..', 'cr_build_revision')) FORCE_HEAD_REVISION_FILE = os.path.normpath(os.path.join(LLVM_BUILD_DIR, '..', 'force_head_revision')) @@ -246,6 +248,12 @@ except: pass + if os.path.exists(OLD_STAMP_FILE): + # Delete the old stamp file so it doesn't look like an old version of clang + # is available in case the user rolls back to an old version of this script + # during a bisect for example (crbug.com/988933). + os.remove(OLD_STAMP_FILE) + expected_stamp = ','.join([PACKAGE_VERSION] + target_os) if ReadStampFile(STAMP_FILE) == expected_stamp: return 0
diff --git a/tools/ipc_fuzzer/message_replay/replay_process.cc b/tools/ipc_fuzzer/message_replay/replay_process.cc index 8849fb3..05ff067 100644 --- a/tools/ipc_fuzzer/message_replay/replay_process.cc +++ b/tools/ipc_fuzzer/message_replay/replay_process.cc
@@ -13,6 +13,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/logging.h" +#include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "build/build_config.h" #include "chrome/common/chrome_switches.h" @@ -119,7 +120,7 @@ InitializeMojo(); io_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + base::Thread::Options(base::MessagePumpType::IO, 0)); #if defined(OS_POSIX) base::GlobalDescriptors* g_fds = base::GlobalDescriptors::GetInstance();
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 87a7087..3138e10 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -9495,6 +9495,17 @@ <int value="3" label="GOOGLE_LOCATION_SERVICE"/> </enum> +<enum name="ContentIndexCategory"> + <summary> + The type of a Content Index entry. Corresponds to + blink.mojom.ContentCategory. + </summary> + <int value="1" label="Home Page"/> + <int value="2" label="Article"/> + <int value="3" label="Video"/> + <int value="4" label="Audio"/> +</enum> + <enum name="ContentResourceType"> <obsolete> Superseded by ContentResourceType2 in December 2015 when SUB_RESOURCE was @@ -24154,6 +24165,9 @@ <int value="2980" label="V8RegExpMatchAllWithNonGlobalRegExp"/> <int value="2981" label="CSSValueOverflowXOverlay"/> <int value="2982" label="CSSValueOverflowYOverlay"/> + <int value="2983" label="ContentIndexAdd"/> + <int value="2984" label="ContentIndexDelete"/> + <int value="2985" label="ContentIndexGet"/> </enum> <enum name="FeaturePolicyAllowlistType">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index d083de25..198f816 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -695,6 +695,16 @@ </summary> </histogram> +<histogram name="AccountManager.LegacySetPrimaryAccountAndUpdateAccountInfo" + enum="BooleanUsage" expires_after="2019-11-05"> + <owner>sinhak@chromium.org</owner> + <summary> + Tracks the usage of the legacy Primary Account setting flow vs the new flow + through Account Manager. This is recorded only once per session, at login + time. + </summary> +</histogram> + <histogram name="AccountManager.Migrations.Result" enum="BooleanSuccess" expires_after="2019-11-05"> <owner>sinhak@chromium.org</owner> @@ -21170,6 +21180,59 @@ <summary>The total number of content captures sent for a document.</summary> </histogram> +<histogram name="ContentIndex.ContentAdded" enum="ContentIndexCategory" + expires_after="M83"> + <owner>rayankans@chromium.org</owner> + <owner>platform-capabilities@chromium.org</owner> + <summary>Records the category of the content when registered.</summary> +</histogram> + +<histogram base="true" name="ContentIndex.ContentDeleteEvent" + enum="ServiceWorkerStatusCode" expires_after="M83"> +<!-- Name completed by histogram_suffixes name="ContentIndexDispatchPhase" --> + + <owner>rayankans@chromium.org</owner> + <owner>platform-capabilities@chromium.org</owner> + <summary> + Records the status of dispatching the `contentdelete` event in every phase + of dispatch. + </summary> +</histogram> + +<histogram name="ContentIndex.ContentOpened" enum="ContentIndexCategory" + expires_after="M83"> + <owner>rayankans@chromium.org</owner> + <owner>platform-capabilities@chromium.org</owner> + <summary>Records the category of the entry clicked on by a user.</summary> +</histogram> + +<histogram base="true" name="ContentIndex.Database" + enum="ServiceWorkerStatusCode" expires_after="M83"> +<!-- Name completed by histogram_suffixes name="ContentIndexDatabaseTask" --> + + <owner>rayankans@chromium.org</owner> + <owner>platform-capabilities@chromium.org</owner> + <summary>Records the result of the database operation.</summary> +</histogram> + +<histogram name="ContentIndex.NumEntriesAvailable" enum="ContentIndexCategory" + expires_after="M83"> + <owner>rayankans@chromium.org</owner> + <owner>platform-capabilities@chromium.org</owner> + <summary> + Records how many entries were found when loaded by the browser. + </summary> +</histogram> + +<histogram name="ContentIndex.RegistrationBlocked" enum="ContentIndexCategory" + expires_after="M83"> + <owner>rayankans@chromium.org</owner> + <owner>platform-capabilities@chromium.org</owner> + <summary> + Records the category of an attempted registration that was blocked. + </summary> +</histogram> + <histogram name="ContentSettings.DefaultAutoplaySetting" enum="ContentSetting"> <owner>mlamouri@chromium.org</owner> <summary>The default autoplay setting at profile open.</summary> @@ -85725,6 +85788,19 @@ </summary> </histogram> +<histogram name="NQE.CongestionAnalyzer.PeakQueueingDelayMappingScore" + units="PercentTotalSamples" expires_after="M82"> + <owner>jfwang@google.com</owner> + <owner>tbansal@chromium.org</owner> + <summary> + Records the score that evaluates the mapping between the count of in-flight + requests to the peak observed queueing delay. The score is the percentage of + total samples that follow the rule 'the more in-flight requests, the higher + peak queueing delay' when a new peak queueing delay mapping sample is + acquired. This is emitted at the end of the current measurement period. + </summary> +</histogram> + <histogram name="NQE.ContentObserver.NetworkQualityMeaningfullyChanged" enum="BooleanChanged" expires_after="M81"> <owner>tbansal@chromium.org</owner> @@ -114577,7 +114653,7 @@ </histogram> <histogram name="SafeBrowsing.V4StoreRead.Result" - enum="SafeBrowsingV4StoreReadResult" expires_after="M77"> + enum="SafeBrowsingV4StoreReadResult" expires_after="2021-07-30"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -114609,7 +114685,7 @@ </histogram> <histogram name="SafeBrowsing.V4StoreWrite.Result" - enum="SafeBrowsingV4StoreWriteResult" expires_after="M77"> + enum="SafeBrowsingV4StoreWriteResult" expires_after="2021-07-30"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -116958,6 +117034,9 @@ <histogram name="SBClientPhishing.ClientDeterminesPhishing" enum="BooleanIsPhishing"> + <obsolete> + Removed in M77 due to lack of use. + </obsolete> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -117130,6 +117209,9 @@ <histogram name="SBClientPhishing.ServerDeterminesPhishing" enum="BooleanIsPhishing" expires_after="M77"> + <obsolete> + Removed in M77 due to lack of use. + </obsolete> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -117139,6 +117221,9 @@ <histogram name="SBClientPhishing.SkipClassificationReason" enum="SBClientPhishingSkipClassificationReason" expires_after="M77"> + <obsolete> + Removed in M77 due to lack of use. + </obsolete> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -133824,19 +133909,31 @@ </summary> </histogram> -<histogram name="SubresourceRedirect.CompressionAttempt.Status" +<histogram name="SubresourceRedirect.CompressionAttempt.ResponseCode" enum="HttpResponseCode" expires_after="M80"> <owner>harrisonsean@chromium.org</owner> <owner>robertogden@chromium.org</owner> <owner>tbansal@chromium.org</owner> <summary> - The status of an attempt to compress an image subresource. The initial - redirect to the compression server will always be logged as a + The server response code of an attempt to compress an image subresource. The + initial redirect to the compression server will always be logged as a HTTP_TEMPORARY_REDIRECT, in addition to logging the return code from the compression server. </summary> </histogram> +<histogram name="SubresourceRedirect.CompressionAttempt.ServerResponded" + enum="Boolean" expires_after="M80"> + <owner>harrisonsean@chromium.org</owner> + <owner>robertogden@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + Whether or not the request to the compression server succeeded at the + network layer. Records true if there was no error at the network layer, + otherwise false. + </summary> +</histogram> + <histogram name="SubresourceRedirect.DidCompress.BytesSaved" units="bytes" expires_after="M80"> <owner>harrisonsean@chromium.org</owner> @@ -157029,6 +157126,23 @@ <affected-histogram name="PLT.LoadType"/> </histogram_suffixes> +<histogram_suffixes name="ContentIndexDatabaseTask" separator="."> + <suffix name="Add" label="Register content"/> + <suffix name="Delete" label="Delete content"/> + <suffix name="GetAllEntries" label="Get all entries"/> + <suffix name="GetDescriptions" label="Get registered content"/> + <suffix name="GetEntry" label="Get a specific entry"/> + <suffix name="GetIcon" label="Get content icon"/> + <affected-histogram name="ContentIndex.Database"/> +</histogram_suffixes> + +<histogram_suffixes name="ContentIndexDispatchPhase" separator="."> + <suffix name="Dispatch" label="Dispatch Service Worker event"/> + <suffix name="Find" label="Find Service Worker"/> + <suffix name="Start" label="Start Service Worker"/> + <affected-histogram name="ContentIndex.ContentDeleteEvent"/> +</histogram_suffixes> + <histogram_suffixes name="ContentSetting" separator="."> <suffix name="Allow" label="Allow"/> <suffix name="AllowThirdParty" label="All third parties allowed on a domain"/>
diff --git a/tools/perf/contrib/oilpan/oilpan_gc_times_unittest.py b/tools/perf/contrib/oilpan/oilpan_gc_times_unittest.py index 19f65e5..455fa67a 100644 --- a/tools/perf/contrib/oilpan/oilpan_gc_times_unittest.py +++ b/tools/perf/contrib/oilpan/oilpan_gc_times_unittest.py
@@ -28,16 +28,12 @@ class OilpanGCTimesTestData(object): - def __init__(self, thread_name): + def __init__(self, page, thread_name): + self._page = page self._model = model.TimelineModel() self._renderer_process = self._model.GetOrCreateProcess(1) self._renderer_thread = self._renderer_process.GetOrCreateThread(2) self._renderer_thread.name = thread_name - self._results = page_test_results.PageTestResults() - - @property - def results(self): - return self._results def AddSlice(self, name, timestamp, duration, args): new_slice = slice_data.Slice( @@ -65,8 +61,20 @@ self._renderer_thread.async_slices.append(new_slice) return new_slice - def ClearResults(self): - self._results = page_test_results.PageTestResults() + def RunMeasurement(self): + # pylint: disable=protected-access + measurement = oilpan_gc_times._OilpanGCTimesBase() + results = page_test_results.PageTestResults() + tab = mock.MagicMock() + with mock.patch( + 'contrib.oilpan.oilpan_gc_times.TimelineModel') as MockTimelineModel: + MockTimelineModel.return_value = self._model + results.WillRunPage(self._page) + try: + measurement.ValidateAndMeasurePage(self._page, tab, results) + finally: + results.DidRunPage(self._page) + return results class OilpanGCTimesTest(page_test_test_case.PageTestTestCase): @@ -95,16 +103,7 @@ return metrics[0].values data = self._GenerateDataForParsingOldFormat() - - measurement = oilpan_gc_times._OilpanGCTimesBase() - - tab = mock.MagicMock() - with mock.patch( - 'contrib.oilpan.oilpan_gc_times.TimelineModel') as MockTimelineModel: - MockTimelineModel.return_value = data._model - measurement.ValidateAndMeasurePage(None, tab, data.results) - - results = data.results + results = data.RunMeasurement() self.assertEquals(3, len(getMetric(results, 'oilpan_precise_mark'))) self.assertEquals(3, len(getMetric(results, 'oilpan_precise_lazy_sweep'))) self.assertEquals(3, len(getMetric(results, @@ -128,16 +127,7 @@ return metrics[0].values data = self._GenerateDataForParsing() - - measurement = oilpan_gc_times._OilpanGCTimesBase() - measurement._timeline_model = data._model - tab = mock.MagicMock() - with mock.patch( - 'contrib.oilpan.oilpan_gc_times.TimelineModel') as MockTimelineModel: - MockTimelineModel.return_value = data._model - measurement.ValidateAndMeasurePage(None, tab, data.results) - - results = data.results + results = data.RunMeasurement() self.assertEquals(4, len(getMetric(results, 'oilpan_precise_mark'))) self.assertEquals(4, len(getMetric(results, 'oilpan_precise_lazy_sweep'))) self.assertEquals(4, len(getMetric(results, @@ -189,11 +179,7 @@ page = TestOilpanGCTimesPage(page_set) page_set.AddStory(page) - data = OilpanGCTimesTestData('CrRendererMain') - # Pretend we are about to run the tests to silence lower level asserts. - data.results.WillRunPage(page) - - return data + return OilpanGCTimesTestData(page, 'CrRendererMain') def _GenerateDataForParsingOldFormat(self): data = self._GenerateDataForEmptyPageSet()
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 57c66f03..d97741b 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -140,8 +140,7 @@ <item id="interest_feed_send" hash_code="76717919" type="0" content_hash_code="34678180" os_list="linux,windows" file_path="components/feed/core/feed_networking_host.cc"/> <item id="intranet_redirect_detector" hash_code="21785164" type="0" content_hash_code="62025595" os_list="linux,windows" file_path="chrome/browser/intranet_redirect_detector.cc"/> <item id="invalidation_service" hash_code="72354423" type="0" content_hash_code="78425687" os_list="linux,windows" file_path="components/invalidation/impl/gcm_network_channel.cc"/> - <item id="kids_chrome_management_client_classify_url" hash_code="109987793" type="0" deprecated="2019-07-30" content_hash_code="112740597" file_path=""/> - <item id="kids_management_url_checker" hash_code="57474321" type="0" deprecated="2019-07-30" content_hash_code="109271547" file_path=""/> + <item id="kids_chrome_management_client_classify_url" hash_code="109987793" type="0" content_hash_code="112740597" os_list="linux,windows" file_path="chrome/browser/supervised_user/kids_chrome_management/kids_chrome_management_client.cc"/> <item id="lib_address_input" hash_code="50816767" type="0" content_hash_code="57977576" os_list="linux,windows" file_path="third_party/libaddressinput/chromium/chrome_metadata_source.cc"/> <item id="logo_service" hash_code="35473769" type="0" content_hash_code="20271299" os_list="linux,windows" file_path="components/search_provider_logos/logo_service_impl.cc"/> <item id="logo_tracker" hash_code="36859107" type="0" deprecated="2018-12-07" content_hash_code="67588075" file_path=""/>
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index 3ad2e81..0e2aceb4 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -329,6 +329,7 @@ "java/src/org/chromium/ui/widget/TextViewWithLeading.java", "java/src/org/chromium/ui/widget/Toast.java", "java/src/org/chromium/ui/widget/UiWidgetFactory.java", + "java/src/org/chromium/ui/widget/ViewLookupCachingFrameLayout.java", "java/src/org/chromium/ui/widget/ViewRectProvider.java", ] deps = [ @@ -391,6 +392,7 @@ "junit/src/org/chromium/ui/shadows/ShadowAnimatedStateListDrawable.java", "junit/src/org/chromium/ui/text/SpanApplierTest.java", "junit/src/org/chromium/ui/widget/AnchoredPopupWindowTest.java", + "junit/src/org/chromium/ui/widget/ViewLookupCachingFrameLayoutTest.java", ] deps = [ ":ui_java",
diff --git a/ui/android/java/src/org/chromium/ui/widget/ViewLookupCachingFrameLayout.java b/ui/android/java/src/org/chromium/ui/widget/ViewLookupCachingFrameLayout.java new file mode 100644 index 0000000..8066035 --- /dev/null +++ b/ui/android/java/src/org/chromium/ui/widget/ViewLookupCachingFrameLayout.java
@@ -0,0 +1,112 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.ui.widget; + +import android.content.Context; +import android.support.annotation.IdRes; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.util.SparseArray; +import android.view.View; +import android.view.ViewGroup; + +import org.chromium.base.BuildConfig; +import org.chromium.base.VisibleForTesting; + +import java.lang.ref.WeakReference; + +/** + * An {@link OptimizedFrameLayout} that increases the speed of frequent view lookup by ID by caching + * the result of the lookup. Adding or removing a view with the same ID as a cached version will + * cause the cache to be invalidated for that view and cause a re-lookup the next time it is + * queried. The goal of this view type is to be used in cases where child views are frequently + * accessed or reused, for example as part of a {@link android.support.v7.widget.RecyclerView}. The + * logic in the {@link #fastFindViewById(int)} method would be in {@link #findViewById(int)} if + * it weren't final on the {@link View} class. + * + * {@link android.view.ViewGroup.OnHierarchyChangeListener}s cannot be used on ViewGroups that are + * children of this group since they would overwrite the listeners that are critical to this class' + * functionality. + * + * Usage: + * Use the same way that you would use a normal {@link android.widget.FrameLayout}, but instead + * of using {@link #findViewById(int)} to access views, use {@link #fastFindViewById(int)}. + */ +public class ViewLookupCachingFrameLayout extends OptimizedFrameLayout { + /** A map containing views that have had lookup performed on them for quicker access. */ + private final SparseArray<WeakReference<View>> mCachedViews = new SparseArray<>(); + + /** The hierarchy listener responsible for notifying the cache that the tree has changed. */ + @VisibleForTesting + final OnHierarchyChangeListener mListener = new OnHierarchyChangeListener() { + @Override + public void onChildViewAdded(View parent, View child) { + mCachedViews.remove(child.getId()); + setHierarchyListenerOnTree(child, this); + } + + @Override + public void onChildViewRemoved(View parent, View child) { + mCachedViews.remove(child.getId()); + setHierarchyListenerOnTree(child, null); + } + }; + + /** Default constructor for use in XML. */ + public ViewLookupCachingFrameLayout(Context context, AttributeSet atts) { + super(context, atts); + setOnHierarchyChangeListener(mListener); + } + + @Override + public void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) { + assert listener == mListener : "Hierarchy change listeners cannot be set for this group!"; + super.setOnHierarchyChangeListener(listener); + } + + /** + * Set the hierarchy listener that invalidates relevant parts of the cache when subtrees change. + * @param view The root of the tree to attach listeners to. + * @param listener The listener to attach (null to unset). + */ + private void setHierarchyListenerOnTree(View view, OnHierarchyChangeListener listener) { + if (!(view instanceof ViewGroup)) return; + + ViewGroup group = (ViewGroup) view; + group.setOnHierarchyChangeListener(listener); + for (int i = 0; i < group.getChildCount(); i++) { + setHierarchyListenerOnTree(group.getChildAt(i), listener); + } + } + + /** + * Does the same thing as {@link #findViewById(int)} but caches the result if not null. + * Subsequent lookups are cheaper as a result. Adding or removing a child view invalidates + * the cache for the ID of the view removed and causes a re-lookup. + * @param id The ID of the view to lookup. + * @return The view if it exists. + */ + @Nullable + public View fastFindViewById(@IdRes int id) { + WeakReference<View> ref = mCachedViews.get(id); + View view = null; + if (ref != null) view = ref.get(); + if (view == null) view = findViewById(id); + if (BuildConfig.DCHECK_IS_ON) { + assert view == findViewById(id) : "View caching logic is broken!"; + assert ref == null + || ref.get() != null : "Cache held reference to garbage collected view!"; + } + + if (view != null) mCachedViews.put(id, new WeakReference<>(view)); + + return view; + } + + @VisibleForTesting + SparseArray<WeakReference<View>> getCache() { + return mCachedViews; + } +}
diff --git a/ui/android/junit/src/org/chromium/ui/widget/ViewLookupCachingFrameLayoutTest.java b/ui/android/junit/src/org/chromium/ui/widget/ViewLookupCachingFrameLayoutTest.java new file mode 100644 index 0000000..ab6bd0ab --- /dev/null +++ b/ui/android/junit/src/org/chromium/ui/widget/ViewLookupCachingFrameLayoutTest.java
@@ -0,0 +1,170 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.ui.widget; + +import static org.junit.Assert.assertEquals; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; + +/** Unit tests for the {@link org.chromium.ui.widget.ViewLookupCachingFrameLayout}. */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class ViewLookupCachingFrameLayoutTest { + private static final int VIEW1_ID = 10; + private static final int VIEW2_ID = 20; + + private ViewLookupCachingFrameLayout mCachingLayout; + private View mView1; + private View mViewWithSameIdAs1; + private View mView2; + private ViewGroup mGroup; + + @Before + public void setUp() { + Context context = RuntimeEnvironment.systemContext; + mCachingLayout = new ViewLookupCachingFrameLayout(context, null); + + mView1 = new View(context); + mView1.setId(VIEW1_ID); + + mViewWithSameIdAs1 = new View(context); + mViewWithSameIdAs1.setId(VIEW1_ID); + + mView2 = new View(context); + mView2.setId(VIEW2_ID); + + mGroup = new FrameLayout(context); + + assertEquals("Cache should be empty.", 0, mCachingLayout.getCache().size()); + } + + @Test + public void testAddViewAndLookup() { + mCachingLayout.addView(mView1); + + assertEquals("Cache should be empty; no lookups have occurred.", 0, + mCachingLayout.getCache().size()); + + assertEquals( + "Lookup found the wrong view.", mView1, mCachingLayout.fastFindViewById(VIEW1_ID)); + + assertEquals("The cache should contain the view.", mView1, + mCachingLayout.getCache().get(VIEW1_ID).get()); + } + + @Test + public void testAddNestedViewAddSameId() { + mCachingLayout.addView(mGroup); + mGroup.addView(mView1); + + assertEquals("View lookup methods should agree.", mCachingLayout.findViewById(VIEW1_ID), + mCachingLayout.fastFindViewById(VIEW1_ID)); + assertEquals("The cache should contain the first view.", mView1, + mCachingLayout.getCache().get(VIEW1_ID).get()); + + // Add the second view earlier in the hierarchy than the original. + mGroup.addView(mViewWithSameIdAs1, 0); + + assertEquals("Cache should be empty.", 0, mCachingLayout.getCache().size()); + + assertEquals("View lookup methods should agree.", mCachingLayout.findViewById(VIEW1_ID), + mCachingLayout.fastFindViewById(VIEW1_ID)); + assertEquals("The cache should contain the view that was added second.", mViewWithSameIdAs1, + mCachingLayout.getCache().get(VIEW1_ID).get()); + } + + @Test + public void testAddNestedViewRemove() { + mCachingLayout.addView(mGroup); + mGroup.addView(mView1); + + assertEquals( + "Lookup found the wrong view.", mView1, mCachingLayout.fastFindViewById(VIEW1_ID)); + + assertEquals("The cache should contain the view.", mView1, + mCachingLayout.getCache().get(VIEW1_ID).get()); + + mGroup.removeView(mView1); + + assertEquals("Cache should be empty.", 0, mCachingLayout.getCache().size()); + assertEquals("The view should not longer be in the hierarchy.", null, + mCachingLayout.fastFindViewById(VIEW1_ID)); + } + + @Test + public void testAddItemWithSameId() { + mCachingLayout.addView(mView1); + + assertEquals( + "Lookup found the wrong view.", mView1, mCachingLayout.fastFindViewById(VIEW1_ID)); + + assertEquals("The cache should contain the view.", mView1, + mCachingLayout.getCache().get(VIEW1_ID).get()); + + mCachingLayout.addView(mViewWithSameIdAs1); + + assertEquals("Cache should be empty.", 0, mCachingLayout.getCache().size()); + } + + @Test + public void testAddNestedItemWithSameId() { + mCachingLayout.addView(mGroup); + mGroup.addView(mView1); + + assertEquals( + "Lookup found the wrong view.", mView1, mCachingLayout.fastFindViewById(VIEW1_ID)); + + assertEquals("The cache should contain the view.", mView1, + mCachingLayout.getCache().get(VIEW1_ID).get()); + + mGroup.addView(mViewWithSameIdAs1); + + assertEquals("Cache should be empty.", 0, mCachingLayout.getCache().size()); + } + + @Test + public void testAddItemWithDifferentId() { + mCachingLayout.addView(mView1); + mCachingLayout.addView(mView2); + + assertEquals( + "Lookup found the wrong view.", mView1, mCachingLayout.fastFindViewById(VIEW1_ID)); + assertEquals( + "Lookup found the wrong view.", mView2, mCachingLayout.fastFindViewById(VIEW2_ID)); + + assertEquals("The cache should contain the first view.", mView1, + mCachingLayout.getCache().get(VIEW1_ID).get()); + assertEquals("The cache should contain the second view.", mView2, + mCachingLayout.getCache().get(VIEW2_ID).get()); + } + + @Test + public void testRemoveItem() { + mCachingLayout.addView(mView1); + + assertEquals( + "Lookup found the wrong view.", mView1, mCachingLayout.fastFindViewById(VIEW1_ID)); + + assertEquals("The cache should contain the first view.", mView1, + mCachingLayout.getCache().get(VIEW1_ID).get()); + + mCachingLayout.removeView(mView1); + + assertEquals("Cache should be empty.", 0, mCachingLayout.getCache().size()); + assertEquals("The view should not longer be in the hierarchy.", null, + mCachingLayout.fastFindViewById(VIEW1_ID)); + } +}
diff --git a/ui/base/ime/chromeos/BUILD.gn b/ui/base/ime/chromeos/BUILD.gn index 70b0370..4f7b42974 100644 --- a/ui/base/ime/chromeos/BUILD.gn +++ b/ui/base/ime/chromeos/BUILD.gn
@@ -51,6 +51,7 @@ ] deps = [ + "//build:branding_buildflags", "//chromeos/constants", "//chromeos/ime:gencode", "//chromeos/services/ime/public/mojom",
diff --git a/ui/base/ime/chromeos/extension_ime_util.cc b/ui/base/ime/chromeos/extension_ime_util.cc index b62f66d..2d3a92b 100644 --- a/ui/base/ime/chromeos/extension_ime_util.cc +++ b/ui/base/ime/chromeos/extension_ime_util.cc
@@ -5,6 +5,7 @@ #include "ui/base/ime/chromeos/extension_ime_util.h" #include "base/strings/string_util.h" +#include "build/branding_buildflags.h" namespace chromeos { @@ -26,6 +27,26 @@ namespace extension_ime_util { +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) +const char kXkbExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; +const char kM17nExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; +const char kHangulExtensionId[] = "bdgdidmhaijohebebipajioienkglgfo"; +const char kMozcExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; +const char kT13nExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; +const char kChinesePinyinExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; +const char kChineseZhuyinExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; +const char kChineseCangjieExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; +#else +const char kXkbExtensionId[] = "fgoepimhcoialccpbmpnnblemnepkkao"; +const char kM17nExtensionId[] = "jhffeifommiaekmbkkjlpmilogcfdohp"; +const char kHangulExtensionId[] = "bdgdidmhaijohebebipajioienkglgfo"; +const char kMozcExtensionId[] = "bbaiamgfapehflhememkfglaehiobjnk"; +const char kT13nExtensionId[] = "gjaehgfemfahhmlgpdfknkhdnemmolop"; +const char kChinesePinyinExtensionId[] = "cpgalbafkoofkjmaeonnfijgpfennjjn"; +const char kChineseZhuyinExtensionId[] = "ekbifjdfhkmdeeajnolmgdlmkllopefi"; +const char kChineseCangjieExtensionId[] = "aeebooiibjahgpgmhkeocbeekccfknbj"; +#endif + const char kBrailleImeExtensionId[] = "jddehjeebkoimngcbdkaahpobgicbffp"; const char kBrailleImeExtensionPath[] = "chromeos/braille_ime"; const char kBrailleImeEngineId[] =
diff --git a/ui/base/ime/chromeos/extension_ime_util.h b/ui/base/ime/chromeos/extension_ime_util.h index 60c6bd81..247a10c 100644 --- a/ui/base/ime/chromeos/extension_ime_util.h +++ b/ui/base/ime/chromeos/extension_ime_util.h
@@ -15,25 +15,17 @@ // Extension IME related utilities. namespace extension_ime_util { -#if defined(GOOGLE_CHROME_BUILD) -const char kXkbExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; -const char kM17nExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; -const char kHangulExtensionId[] = "bdgdidmhaijohebebipajioienkglgfo"; -const char kMozcExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; -const char kT13nExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; -const char kChinesePinyinExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; -const char kChineseZhuyinExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; -const char kChineseCangjieExtensionId[] = "jkghodnilhceideoidjikpgommlajknk"; -#else -const char kXkbExtensionId[] = "fgoepimhcoialccpbmpnnblemnepkkao"; -const char kM17nExtensionId[] = "jhffeifommiaekmbkkjlpmilogcfdohp"; -const char kHangulExtensionId[] = "bdgdidmhaijohebebipajioienkglgfo"; -const char kMozcExtensionId[] = "bbaiamgfapehflhememkfglaehiobjnk"; -const char kT13nExtensionId[] = "gjaehgfemfahhmlgpdfknkhdnemmolop"; -const char kChinesePinyinExtensionId[] = "cpgalbafkoofkjmaeonnfijgpfennjjn"; -const char kChineseZhuyinExtensionId[] = "ekbifjdfhkmdeeajnolmgdlmkllopefi"; -const char kChineseCangjieExtensionId[] = "aeebooiibjahgpgmhkeocbeekccfknbj"; -#endif +COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) extern const char kXkbExtensionId[]; +COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) extern const char kM17nExtensionId[]; +COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) extern const char kHangulExtensionId[]; +COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) extern const char kMozcExtensionId[]; +COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) extern const char kT13nExtensionId[]; +COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) +extern const char kChinesePinyinExtensionId[]; +COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) +extern const char kChineseZhuyinExtensionId[]; +COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) +extern const char kChineseCangjieExtensionId[]; // Extension id, path (relative to |chrome::DIR_RESOURCES|) and IME engine // id for the builtin-in Braille IME extension.
diff --git a/ui/events/ozone/evdev/event_thread_evdev.cc b/ui/events/ozone/evdev/event_thread_evdev.cc index 6f120bc1..99aa8998 100644 --- a/ui/events/ozone/evdev/event_thread_evdev.cc +++ b/ui/events/ozone/evdev/event_thread_evdev.cc
@@ -9,7 +9,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" @@ -83,7 +83,7 @@ thread_.reset( new EvdevThread(std::move(dispatcher), cursor, std::move(callback))); base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_UI; + thread_options.message_pump_type = base::MessagePumpType::UI; thread_options.priority = base::ThreadPriority::DISPLAY; if (!thread_->StartWithOptions(thread_options)) LOG(FATAL) << "Failed to create input thread";
diff --git a/ui/gl/gl_version_info.cc b/ui/gl/gl_version_info.cc index 0f6cbf3..b10615be 100644 --- a/ui/gl/gl_version_info.cc +++ b/ui/gl/gl_version_info.cc
@@ -79,7 +79,7 @@ is_es3 = false; } else { major_version = 3; - minor_version = 0; + minor_version = 2; } } }
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc index 2164b74..edb9a32 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.cc +++ b/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -11,7 +11,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "ui/display/types/display_mode.h" @@ -122,7 +122,7 @@ void DrmThread::Start(base::OnceClosure binding_completer) { complete_early_binding_requests_ = std::move(binding_completer); base::Thread::Options thread_options; - thread_options.message_loop_type = base::MessageLoop::TYPE_IO; + thread_options.message_pump_type = base::MessagePumpType::IO; thread_options.priority = base::ThreadPriority::DISPLAY; if (!StartWithOptions(thread_options))
diff --git a/ui/views/controls/editable_combobox/editable_combobox_unittest.cc b/ui/views/controls/editable_combobox/editable_combobox_unittest.cc index 927416a..54eab4cb 100644 --- a/ui/views/controls/editable_combobox/editable_combobox_unittest.cc +++ b/ui/views/controls/editable_combobox/editable_combobox_unittest.cc
@@ -193,6 +193,18 @@ container->AddChildView(dummy_focusable_view_); widget_->Show(); +#if defined(OS_MACOSX) + // The event loop needs to be flushed here, otherwise in various tests: + // 1. The actual showing of the native window backing the widget gets delayed + // until a spin of the event loop. + // 2. The combobox menu object is triggered, and it starts listening for the + // "window did become key" notification as a sign that it lost focus and + // should close. + // 3. The event loop is spun, and the actual showing of the native window + // triggers the close of the menu opened from within the window. + base::RunLoop().RunUntilIdle(); +#endif + event_generator_ = std::make_unique<ui::test::EventGenerator>(GetRootWindow(widget_)); event_generator_->set_target(ui::test::EventGenerator::Target::WINDOW);
diff --git a/ui/views/controls/menu/menu_cocoa_watcher_mac.h b/ui/views/controls/menu/menu_cocoa_watcher_mac.h index 96e5522..b39fb3d 100644 --- a/ui/views/controls/menu/menu_cocoa_watcher_mac.h +++ b/ui/views/controls/menu/menu_cocoa_watcher_mac.h
@@ -13,20 +13,25 @@ namespace views { -// This class executes a callback when a native menu begins tracking. With -// native menus, each one automatically closes when a new one begins tracking. -// This allows Views menus to tie into this behavior. +// This class executes a callback when a native menu begins tracking, or when a +// new window takes focus. With native menus, each one automatically closes when +// a new one begins tracking, and MenuPreTargetHandlerAura::OnWindowActivated() +// closes menus when new windows take focus. This allows Views menus to have the +// correct behavior. class VIEWS_EXPORT MenuCocoaWatcherMac { public: explicit MenuCocoaWatcherMac(base::OnceClosure callback); ~MenuCocoaWatcherMac(); private: + void ExecuteCallback(); + // The closure to call when the notification comes in. base::OnceClosure callback_; - // The token representing the notification observer. - id observer_token_; + // Tokens representing the notification observers. + id observer_token_other_menu_; + id observer_token_new_window_focus_; DISALLOW_COPY_AND_ASSIGN(MenuCocoaWatcherMac); };
diff --git a/ui/views/controls/menu/menu_cocoa_watcher_mac.mm b/ui/views/controls/menu/menu_cocoa_watcher_mac.mm index da563e6a4..b282c290 100644 --- a/ui/views/controls/menu/menu_cocoa_watcher_mac.mm +++ b/ui/views/controls/menu/menu_cocoa_watcher_mac.mm
@@ -5,6 +5,7 @@ #include "ui/views/controls/menu/menu_cocoa_watcher_mac.h" #import <Cocoa/Cocoa.h> +#include <dispatch/dispatch.h> #import <utility> @@ -12,17 +13,36 @@ MenuCocoaWatcherMac::MenuCocoaWatcherMac(base::OnceClosure callback) : callback_(std::move(callback)) { - observer_token_ = [[NSNotificationCenter defaultCenter] + observer_token_other_menu_ = [[NSNotificationCenter defaultCenter] addObserverForName:NSMenuDidBeginTrackingNotification object:[NSApp mainMenu] queue:nil usingBlock:^(NSNotification* notification) { - std::move(this->callback_).Run(); + ExecuteCallback(); + }]; + observer_token_new_window_focus_ = [[NSNotificationCenter defaultCenter] + addObserverForName:NSWindowDidBecomeKeyNotification + object:nil + queue:nil + usingBlock:^(NSNotification* notification) { + ExecuteCallback(); }]; } MenuCocoaWatcherMac::~MenuCocoaWatcherMac() { - [[NSNotificationCenter defaultCenter] removeObserver:observer_token_]; + [[NSNotificationCenter defaultCenter] + removeObserver:observer_token_other_menu_]; + [[NSNotificationCenter defaultCenter] + removeObserver:observer_token_new_window_focus_]; +} + +void MenuCocoaWatcherMac::ExecuteCallback() { + __block base::OnceClosure callback = std::move(callback_); + dispatch_async(dispatch_get_main_queue(), ^{ + if (callback) { + std::move(callback).Run(); + } + }); } } // namespace views
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index 354216c..bceec6f1 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -475,7 +475,7 @@ #if defined(OS_MACOSX) menu_cocoa_watcher_ = std::make_unique<MenuCocoaWatcherMac>(base::BindOnce( - &MenuController::Cancel, base::Unretained(this), ExitType::kAll)); + &MenuController::Cancel, this->AsWeakPtr(), ExitType::kAll)); #endif // Reset current state.
diff --git a/ui/views/widget/native_widget_mac.h b/ui/views/widget/native_widget_mac.h index e64872d3..6db556b 100644 --- a/ui/views/widget/native_widget_mac.h +++ b/ui/views/widget/native_widget_mac.h
@@ -225,6 +225,9 @@ friend class test::HitTestNativeWidgetMac; friend class views::test::WidgetTest; + class ZoomFocusMonitor; + std::unique_ptr<ZoomFocusMonitor> zoom_focus_monitor_; + internal::NativeWidgetDelegate* delegate_; std::unique_ptr<NativeWidgetMacNSWindowHost> ns_window_host_;
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index c3de7e7e..f948242 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -4,7 +4,9 @@ #include "ui/views/widget/native_widget_mac.h" +#include <ApplicationServices/ApplicationServices.h> #import <Cocoa/Cocoa.h> +#include <CoreFoundation/CoreFoundation.h> #include <utility> @@ -106,11 +108,29 @@ } // namespace +// Implements zoom following focus for macOS accessibility zoom. +class NativeWidgetMac::ZoomFocusMonitor : public FocusChangeListener { + public: + ZoomFocusMonitor() = default; + ~ZoomFocusMonitor() override {} + void OnWillChangeFocus(View* focused_before, View* focused_now) override {} + void OnDidChangeFocus(View* focused_before, View* focused_now) override { + if (!focused_now || !UAZoomEnabled()) + return; + // Web content handles its own zooming. + if (strcmp("WebView", focused_now->GetClassName()) == 0) + return; + NSRect rect = NSRectFromCGRect(focused_now->GetBoundsInScreen().ToCGRect()); + UAZoomChangeFocus(&rect, nullptr, kUAZoomFocusTypeOther); + } +}; + //////////////////////////////////////////////////////////////////////////////// // NativeWidgetMac, public: NativeWidgetMac::NativeWidgetMac(internal::NativeWidgetDelegate* delegate) - : delegate_(delegate), + : zoom_focus_monitor_(std::make_unique<ZoomFocusMonitor>()), + delegate_(delegate), ns_window_host_(new NativeWidgetMacNSWindowHost(this)), ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) {} @@ -122,6 +142,8 @@ } void NativeWidgetMac::WindowDestroying() { + if (auto* focus_manager = GetWidget()->GetFocusManager()) + focus_manager->RemoveFocusChangeListener(zoom_focus_monitor_.get()); OnWindowDestroying(GetNativeWindow()); delegate_->OnNativeWidgetDestroying(); } @@ -208,6 +230,9 @@ if (auto* focus_manager = GetWidget()->GetFocusManager()) { GetNSWindowMojo()->MakeFirstResponder(); ns_window_host_->SetFocusManager(focus_manager); + // Non-top-level widgets use the the top level widget's focus manager. + if (GetWidget() == GetTopLevelWidget()) + focus_manager->AddFocusChangeListener(zoom_focus_monitor_.get()); } ns_window_host_->CreateCompositor(params);