diff --git a/DEPS b/DEPS index d0d37fd9..10ec65dc 100644 --- a/DEPS +++ b/DEPS
@@ -195,11 +195,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': '3eb813e0cc134767a10e9efd4811fc519eccb280', + 'skia_revision': '647a9bd7c253140cb93c04d0741cdc71c3c7faf3', # 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': 'e0d5b2a8208346a0c10ac96bfef2a78311b7f7a0', + 'v8_revision': '399a0ebae81cb9627e481b7764a10c648a15180c', # 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. @@ -207,7 +207,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'ee7ae7aba2c91034b6304dcad1df5823ff3d5702', + 'angle_revision': 'edea3d95c99625197acd9b1326fabd885eb5e260', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -266,7 +266,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'f46b7d67f8f26acccc89e44b210a313ba7e96ff1', + 'devtools_frontend_revision': '2daeda990573d4ec2d19fd27f234df2cf5160874', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -318,7 +318,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '6db3a24c19e7580a0aaee7aff8a52c16489c6abe', + 'dawn_revision': '75e5ed6161fcb3a79cbf584c273ff7eac84956a9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -836,7 +836,7 @@ }, 'src/third_party/breakpad/breakpad': - Var('chromium_git') + '/breakpad/breakpad.git' + '@' + 'e3a62dc5502dec6ab451061769d7efaf5b7ffba8', + Var('chromium_git') + '/breakpad/breakpad.git' + '@' + '9c4671f2e3a63c0f155d9b2511192d0b5fa7f760', 'src/third_party/byte_buddy': { 'packages': [ @@ -1254,7 +1254,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '4f973a50bbbc59c19795cea52d33f1c01d388767', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '06f3474ec4dc88c8fd2d329089c0bbdd36b3f6f5', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1332,7 +1332,7 @@ 'packages': [ { 'package': 'fuchsia/third_party/aemu/linux-amd64', - 'version': 'laU2vAii09mMfCaTLtA8O6UYjPdUXy0B-0zzOR0OPekC' + 'version': 'e3-wbMXwDkejPE6v6BbVayEu9ikm4GVS2rHZkzAxpYgC' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -1486,7 +1486,7 @@ }, 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'edd7f9e94d43312ee839e7bed9acc5d8eda7ae81', + Var('webrtc_git') + '/src.git' + '@' + '3a5612a8de0b776f6152e04d96f850bfc511765e', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1558,7 +1558,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@aad83522fd172502e4b3783190db56538bb706bd', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@faa49d773432b6dff200754efc023cb1a3ac1896', 'condition': 'checkout_src_internal', }, @@ -1566,7 +1566,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'mkV9yCGYkfTE2DLD-MHNfrrbpo8vMhrcvgRQwtJGUjMC', + 'version': 'uJOBjWHF-V8jOwZMkbWeP1rWi_kNv9l_Fsc2gObjg3wC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/apps/ui/views/app_window_frame_view.cc b/apps/ui/views/app_window_frame_view.cc index ccedbcc..75c7c36 100644 --- a/apps/ui/views/app_window_frame_view.cc +++ b/apps/ui/views/app_window_frame_view.cc
@@ -53,7 +53,9 @@ void AppWindowFrameView::Init() { if (draw_frame_) { ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - auto close_button = std::make_unique<views::ImageButton>(this); + auto close_button = std::make_unique<views::ImageButton>(); + close_button->set_callback( + base::BindRepeating(&views::Widget::Close, base::Unretained(widget_))); close_button->SetImage( views::Button::STATE_NORMAL, rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE).ToImageSkia()); @@ -67,7 +69,9 @@ l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE)); close_button_ = AddChildView(std::move(close_button)); // STATE_NORMAL images are set in SetButtonImagesForFrame, not here. - auto maximize_button = std::make_unique<views::ImageButton>(this); + auto maximize_button = std::make_unique<views::ImageButton>(); + maximize_button->set_callback(base::BindRepeating( + &views::Widget::Maximize, base::Unretained(widget_))); maximize_button->SetImage( views::Button::STATE_HOVERED, rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_H).ToImageSkia()); @@ -80,7 +84,9 @@ maximize_button->SetAccessibleName( l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE)); maximize_button_ = AddChildView(std::move(maximize_button)); - auto restore_button = std::make_unique<views::ImageButton>(this); + auto restore_button = std::make_unique<views::ImageButton>(); + restore_button->set_callback(base::BindRepeating( + &views::Widget::Restore, base::Unretained(widget_))); restore_button->SetImage( views::Button::STATE_HOVERED, rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE_H).ToImageSkia()); @@ -90,7 +96,9 @@ restore_button->SetAccessibleName( l10n_util::GetStringUTF16(IDS_APP_ACCNAME_RESTORE)); restore_button_ = AddChildView(std::move(restore_button)); - auto minimize_button = std::make_unique<views::ImageButton>(this); + auto minimize_button = std::make_unique<views::ImageButton>(); + minimize_button->set_callback(base::BindRepeating( + &views::Widget::Minimize, base::Unretained(widget_))); minimize_button->SetImage( views::Button::STATE_HOVERED, rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE_H).ToImageSkia()); @@ -345,19 +353,6 @@ return max_size; } -void AppWindowFrameView::ButtonPressed(views::Button* sender, - const ui::Event& event) { - DCHECK(draw_frame_); - if (sender == close_button_) - widget_->Close(); - else if (sender == maximize_button_) - widget_->Maximize(); - else if (sender == restore_button_) - widget_->Restore(); - else if (sender == minimize_button_) - widget_->Minimize(); -} - SkColor AppWindowFrameView::CurrentFrameColor() { return widget_->IsActive() ? active_frame_color_ : inactive_frame_color_; }
diff --git a/apps/ui/views/app_window_frame_view.h b/apps/ui/views/app_window_frame_view.h index 8c4c610..a043948 100644 --- a/apps/ui/views/app_window_frame_view.h +++ b/apps/ui/views/app_window_frame_view.h
@@ -22,10 +22,6 @@ class Point; } -namespace ui { -class Event; -} - namespace views { class ImageButton; class Widget; @@ -34,8 +30,7 @@ namespace apps { // A frameless or non-Ash, non-panel NonClientFrameView for app windows. -class AppWindowFrameView : public views::NonClientFrameView, - public views::ButtonListener { +class AppWindowFrameView : public views::NonClientFrameView { public: static const char kViewClassName[]; @@ -81,9 +76,6 @@ gfx::Size GetMinimumSize() const override; gfx::Size GetMaximumSize() const override; - // views::ButtonListener implementation. - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // Some button images we use depend on the color of the frame. This // will set these images based on the color of the frame. void SetButtonImagesForFrame();
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index c7863b9..1be5717 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -2171,6 +2171,7 @@ "wm/default_window_resizer_unittest.cc", "wm/desks/autotest_desks_api_unittests.cc", "wm/desks/desks_unittests.cc", + "wm/desks/root_window_desk_switch_animator_unittest.cc", "wm/drag_window_resizer_unittest.cc", "wm/fullscreen_window_finder_unittest.cc", "wm/gestures/back_gesture/back_gesture_affordance_unittest.cc", @@ -2540,6 +2541,8 @@ "wm/cursor_manager_test_api.h", "wm/desks/desks_test_util.cc", "wm/desks/desks_test_util.h", + "wm/desks/root_window_desk_switch_animator_test_api.cc", + "wm/desks/root_window_desk_switch_animator_test_api.h", "wm/gestures/back_gesture/test_back_gesture_contextual_nudge_delegate.cc", "wm/gestures/back_gesture/test_back_gesture_contextual_nudge_delegate.h", "wm/lock_state_controller_test_api.cc",
diff --git a/ash/app_list/model/app_list_item.h b/ash/app_list/model/app_list_item.h index 7c74a2e..c0c64e7 100644 --- a/ash/app_list/model/app_list_item.h +++ b/ash/app_list/model/app_list_item.h
@@ -19,8 +19,6 @@ #include "components/sync/model/string_ordinal.h" #include "ui/gfx/image/image_skia.h" -class FastShowPickler; - namespace ash { enum class AppListConfigType; class AppListControllerImpl; @@ -88,11 +86,12 @@ bool has_notification_badge() const { return has_notification_badge_; } + void UpdateBadgeForTesting(bool has_badge) { UpdateBadge(has_badge); } + protected: // Subclasses also have mutable access to the metadata ptr. AppListItemMetadata* metadata() { return metadata_.get(); } - friend class ::FastShowPickler; friend class AppListControllerImpl; friend class AppListItemList; friend class AppListItemListTest;
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc index 4c9ae3b..01632e9 100644 --- a/ash/app_list/views/app_list_item_view.cc +++ b/ash/app_list/views/app_list_item_view.cc
@@ -973,6 +973,10 @@ layer()->SetFillsBoundsOpaquely(false); } +bool AppListItemView::HasNotificationBadge() { + return item_weak_->has_notification_badge(); +} + void AppListItemView::FireMouseDragTimerForTest() { mouse_drag_timer_.FireNow(); }
diff --git a/ash/app_list/views/app_list_item_view.h b/ash/app_list/views/app_list_item_view.h index b729e45..9dcc3650 100644 --- a/ash/app_list/views/app_list_item_view.h +++ b/ash/app_list/views/app_list_item_view.h
@@ -141,6 +141,8 @@ // Ensures this item view has its own layer. void EnsureLayer(); + bool HasNotificationBadge(); + void FireMouseDragTimerForTest(); bool FireTouchDragTimerForTest();
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 06f1467..5a456b9 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -1432,6 +1432,8 @@ selected_view_ = new_selection; selected_view_->SchedulePaint(); selected_view_->NotifyAccessibilityEvent(ax::mojom::Event::kFocus, true); + if (selected_view_->HasNotificationBadge()) + AnnounceItemNotificationBadge(selected_view_->title()->GetText()); } GridIndex AppsGridView::GetIndexOfView(const AppListItemView* view) const { @@ -3794,6 +3796,17 @@ drop_view->title()->GetText(), drop_view->is_folder()); } +void AppsGridView::AnnounceItemNotificationBadge( + const base::string16& selected_view_title) { + // Set a11y name to announce the notification badge for the focused item. + auto* announcement_view = + contents_view_->app_list_view()->announcement_view(); + announcement_view->GetViewAccessibility().OverrideName( + l10n_util::GetStringFUTF16(IDS_APP_LIST_APP_FOCUS_NOTIFICATION_BADGE, + selected_view_title)); + announcement_view->NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true); +} + void AppsGridView::AnnounceFolderDrop(const base::string16& moving_view_title, const base::string16& target_view_title, bool target_is_folder) {
diff --git a/ash/app_list/views/apps_grid_view.h b/ash/app_list/views/apps_grid_view.h index 0d0abbe..844a370 100644 --- a/ash/app_list/views/apps_grid_view.h +++ b/ash/app_list/views/apps_grid_view.h
@@ -708,6 +708,10 @@ // folder or creating a folder with two apps. void MaybeCreateFolderDroppingAccessibilityEvent(); + // Modifies the announcement view to verbalize that the focused view has new + // updates, based on the item having a notification badge. + void AnnounceItemNotificationBadge(const base::string16& selected_view_title); + // Modifies the announcement view to verbalize that the current drag will move // |moving_view_title| and create a folder or move it into an existing folder // with |target_view_title|.
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index 78ee9c2..2309778 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -336,6 +336,8 @@ progress, GetBackgroundColorForState(current_state), GetBackgroundColorForState(target_state)); UpdateBackgroundColor(color); + search_box()->SetTextColor( + AppListColorProvider::Get()->GetSearchBoxTextColor()); } void SearchBoxView::UpdateLayout(double progress,
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index fc73e6c..3dbf0b7 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -2271,6 +2271,18 @@ <message name="IDS_ASH_LOGIN_MANUAL_LOCK_MESSAGE" desc="Message shown to user indicating that their parent locked the device."> Your parent locked this device </message> + <message name="IDS_ASH_LOGIN_MULTI_PROFILES_RESTRICTED_POLICY_TITLE" desc="Text that is shown on the title of the bubble shown for user pod which is not allowed in multi-profiles session."> + Can't set up multiple sign-in + </message> + <message name="IDS_ASH_LOGIN_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG" desc="Text that is shown on the bubble shown for user pod which is not allowed in multi-profiles session because of not-allowed policy or because of usage policy-pushed certificates."> + The administrator for this account has disallowed multiple sign-in. + </message> + <message name="IDS_ASH_LOGIN_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG" desc="Text that is shown on the bubble shown for user pod which is not allowed in multi-profiles session because of primary-only policy."> + The administrator for this account requires this account to be the first signed-in account in a multiple sign-in session. + </message> + <message name="IDS_ASH_LOGIN_MULTI_PROFILES_OWNER_PRIMARY_ONLY_MSG" desc="Text that is shown on the bubble shown for owner user pod which is not allowed in multi-profiles session because it has to be primary user in the session."> + This owner account has to be the first signed-in account in a multiple sign-in session. + </message> <message name="IDS_ASH_LOGIN_PUBLIC_ACCOUNT_MONITORING_INFO" desc="Text shown in the warning dialog after user clicks on the learn more link, notifying the user of potential security and privacy implications of using the device"> The admin of this device has the ability to: </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_LOGIN_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG.png.sha1 b/ash/ash_strings_grd/IDS_ASH_LOGIN_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG.png.sha1 new file mode 100644 index 0000000..ffe5a24 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_LOGIN_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG.png.sha1
@@ -0,0 +1 @@ +ebbdb5407ce393e8453a620a09fc6484b65a7559 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_LOGIN_MULTI_PROFILES_OWNER_PRIMARY_ONLY_MSG.png.sha1 b/ash/ash_strings_grd/IDS_ASH_LOGIN_MULTI_PROFILES_OWNER_PRIMARY_ONLY_MSG.png.sha1 new file mode 100644 index 0000000..ba2d48f --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_LOGIN_MULTI_PROFILES_OWNER_PRIMARY_ONLY_MSG.png.sha1
@@ -0,0 +1 @@ +733e28a6ba361723f3d558a2ee4e431f5d3fe69f \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_LOGIN_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG.png.sha1 b/ash/ash_strings_grd/IDS_ASH_LOGIN_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG.png.sha1 new file mode 100644 index 0000000..39279e4 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_LOGIN_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG.png.sha1
@@ -0,0 +1 @@ +88156671eb7402544a2096bce16b7d039a9a81d8 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_LOGIN_MULTI_PROFILES_RESTRICTED_POLICY_TITLE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_LOGIN_MULTI_PROFILES_RESTRICTED_POLICY_TITLE.png.sha1 new file mode 100644 index 0000000..39279e4 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_LOGIN_MULTI_PROFILES_RESTRICTED_POLICY_TITLE.png.sha1
@@ -0,0 +1 @@ +88156671eb7402544a2096bce16b7d039a9a81d8 \ No newline at end of file
diff --git a/ash/clipboard/views/clipboard_history_item_view.cc b/ash/clipboard/views/clipboard_history_item_view.cc index 7954faf..3436de2 100644 --- a/ash/clipboard/views/clipboard_history_item_view.cc +++ b/ash/clipboard/views/clipboard_history_item_view.cc
@@ -35,49 +35,10 @@ // The size of the `DeleteButton`. constexpr int kDeleteButtonSizeDip = 16; -// The view responding to mouse click or gesture tap events. -class MainButton : public views::Button { - public: - explicit MainButton(ash::ClipboardHistoryItemView* container) - : Button(container), container_(container) { - SetFocusBehavior(views::View::FocusBehavior::ALWAYS); - SetAccessibleName(base::ASCIIToUTF16(std::string(GetClassName()))); - } - MainButton(const MainButton& rhs) = delete; - MainButton& operator=(const MainButton& rhs) = delete; - ~MainButton() override = default; - - private: - // views::Button: - const char* GetClassName() const override { return "MainButton"; } - - void PaintButtonContents(gfx::Canvas* canvas) override { - if (!container_->IsSelected()) - return; - - // Highlight the background when the menu item is selected or pressed. - cc::PaintFlags flags; - flags.setAntiAlias(true); - - const ui::NativeTheme::ColorId color_id = - ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor; - flags.setColor(GetNativeTheme()->GetSystemColor(color_id)); - - flags.setStyle(cc::PaintFlags::kFill_Style); - canvas->DrawRect(GetLocalBounds(), flags); - } - - // The parent view. - ash::ClipboardHistoryItemView* const container_; -}; - } // namespace namespace ash { -//////////////////////////////////////////////////////////////////////////////// -// ClipboardHistoryItemView::ContentsView - ClipboardHistoryItemView::ContentsView::ContentsView( ClipboardHistoryItemView* container) : container_(container) { @@ -111,12 +72,48 @@ gfx::ToEnclosedRect(rect_in_delete_button)); } -//////////////////////////////////////////////////////////////////////////////// -// ClipboardHistoryItemView::DeleteButton +// The view responding to mouse click or gesture tap events. +class ash::ClipboardHistoryItemView::MainButton : public views::Button { + public: + explicit MainButton(ClipboardHistoryItemView* container) + : Button(), container_(container) { + SetFocusBehavior(views::View::FocusBehavior::ALWAYS); + SetAccessibleName(base::ASCIIToUTF16(std::string(GetClassName()))); + } + MainButton(const MainButton& rhs) = delete; + MainButton& operator=(const MainButton& rhs) = delete; + ~MainButton() override = default; + + private: + // views::Button: + const char* GetClassName() const override { return "MainButton"; } + + void PaintButtonContents(gfx::Canvas* canvas) override { + if (!container_->IsSelected()) + return; + + // Highlight the background when the menu item is selected or pressed. + cc::PaintFlags flags; + flags.setAntiAlias(true); + + const ui::NativeTheme::ColorId color_id = + ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor; + flags.setColor(GetNativeTheme()->GetSystemColor(color_id)); + + flags.setStyle(cc::PaintFlags::kFill_Style); + canvas->DrawRect(GetLocalBounds(), flags); + } + + // The parent view. + ash::ClipboardHistoryItemView* const container_; +}; ClipboardHistoryItemView::DeleteButton::DeleteButton( - views::ButtonListener* listener) - : views::ImageButton(listener) { + ClipboardHistoryItemView* listener) + : views::ImageButton() { + set_callback(base::BindRepeating(&ClipboardHistoryItemView::ExecuteCommand, + base::Unretained(listener), + ClipboardHistoryUtil::kDeleteCommandId)); SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); SetAccessibleName(base::ASCIIToUTF16(std::string(GetClassName()))); SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER); @@ -134,9 +131,6 @@ return "DeleteButton"; } -//////////////////////////////////////////////////////////////////////////////// -// ClipboardHistoryItemView - // static std::unique_ptr<ClipboardHistoryItemView> ClipboardHistoryItemView::CreateFromClipboardHistoryItem( @@ -169,6 +163,12 @@ // Ensures that MainButton is below any other child views. main_button_ = AddChildView(std::make_unique<MainButton>(this)); + main_button_->set_callback(base::BindRepeating( + [](ClipboardHistoryItemView* item, views::MenuItemView* container, + const ui::Event& event) { + item->ExecuteCommand(container->GetCommand(), event); + }, + base::Unretained(this), container_)); contents_view_ = AddChildView(CreateContentsView()); @@ -195,15 +195,11 @@ return gfx::Size(preferred_width, GetHeightForWidth(preferred_width)); } -void ClipboardHistoryItemView::ButtonPressed(views::Button* sender, - const ui::Event& event) { - DCHECK(sender == contents_view_->delete_button() || sender == main_button_); - const int command_id = sender == contents_view_->delete_button() - ? ClipboardHistoryUtil::kDeleteCommandId - : container_->GetCommand(); +void ClipboardHistoryItemView::ExecuteCommand(int command_id, + const ui::Event& event) { views::MenuDelegate* delegate = container_->GetDelegate(); DCHECK(delegate->IsCommandEnabled(command_id)); - delegate->ExecuteCommand(command_id, event.flags()); + container_->GetDelegate()->ExecuteCommand(command_id, event.flags()); } } // namespace ash
diff --git a/ash/clipboard/views/clipboard_history_item_view.h b/ash/clipboard/views/clipboard_history_item_view.h index b35c463..d83726c 100644 --- a/ash/clipboard/views/clipboard_history_item_view.h +++ b/ash/clipboard/views/clipboard_history_item_view.h
@@ -17,8 +17,7 @@ class ClipboardHistoryResourceManager; // The base class for menu items of the clipboard history menu. -class ClipboardHistoryItemView : public views::View, - public views::ButtonListener { +class ClipboardHistoryItemView : public views::View { public: static std::unique_ptr<ClipboardHistoryItemView> CreateFromClipboardHistoryItem( @@ -41,10 +40,12 @@ void OnSelectionChanged(); protected: + class MainButton; + // The button to delete the menu item and its corresponding clipboard data. class DeleteButton : public views::ImageButton { public: - explicit DeleteButton(views::ButtonListener* listener); + explicit DeleteButton(ClipboardHistoryItemView* listener); DeleteButton(const DeleteButton& rhs) = delete; DeleteButton& operator=(const DeleteButton& rhs) = delete; ~DeleteButton() override; @@ -98,14 +99,14 @@ // views::View: gfx::Size CalculatePreferredSize() const override; - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; + // Executes |command_id| on the delegate. + void ExecuteCommand(int command_id, const ui::Event& event); views::MenuItemView* const container_; ContentsView* contents_view_ = nullptr; - views::View* main_button_ = nullptr; + MainButton* main_button_ = nullptr; views::PropertyChangedSubscription subscription_; };
diff --git a/ash/display/cursor_window_controller.cc b/ash/display/cursor_window_controller.cc index 08964e5..153db45 100644 --- a/ash/display/cursor_window_controller.cc +++ b/ash/display/cursor_window_controller.cc
@@ -35,6 +35,7 @@ #include "ui/display/screen.h" #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/dip_util.h" +#include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/views/widget/widget.h" @@ -321,16 +322,17 @@ ui::GetScaleForScaleFactor(ui::GetSupportedScaleFactor(original_scale)); gfx::ImageSkia image; + gfx::Point hot_point_in_physical_pixels; if (cursor_.type() == ui::mojom::CursorType::kCustom) { const SkBitmap& bitmap = cursor_.custom_bitmap(); if (bitmap.isNull()) return; image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); - hot_point_ = cursor_.custom_hotspot(); + hot_point_in_physical_pixels = cursor_.custom_hotspot(); } else { int resource_id; if (!ui::GetCursorDataFor(cursor_size_, cursor_.type(), cursor_scale, - &resource_id, &hot_point_)) { + &resource_id, &hot_point_in_physical_pixels)) { return; } image = @@ -350,14 +352,17 @@ resized = gfx::ImageSkiaOperations::CreateResizedImage( image, skia::ImageOperations::ResizeMethod::RESIZE_GOOD, gfx::ScaleToCeiledSize(image.size(), rescale)); - hot_point_ = gfx::ScaleToCeiledPoint(hot_point_, rescale); + hot_point_in_physical_pixels = + gfx::ScaleToCeiledPoint(hot_point_in_physical_pixels, rescale); } const gfx::ImageSkiaRep& image_rep = resized.GetRepresentation(cursor_scale); delegate_->SetCursorImage(resized.size(), gfx::ImageSkia(gfx::ImageSkiaRep( GetAdjustedBitmap(image_rep), cursor_scale))); - hot_point_ = gfx::ConvertPointToDIP(cursor_scale, hot_point_); + // TODO(danakj): Should this be rounded? Or kept as a floating point? + hot_point_ = gfx::ToFlooredPoint( + gfx::ConvertPointToDips(hot_point_in_physical_pixels, cursor_scale)); if (cursor_view_widget_) { static_cast<cursor::CursorView*>(cursor_view_widget_->GetContentsView())
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index 434ebb2..b60b6ea 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -591,6 +591,9 @@ if (user_info.auth_type == proximity_auth::mojom::AuthType::ONLINE_SIGN_IN) force_online_sign_in = true; show_pin_pad_for_password = user_info.show_pin_pad_for_password; + disable_auth = !user_info.is_multiprofile_allowed && + Shell::Get()->session_controller()->GetSessionState() == + session_manager::SessionState::LOGIN_SECONDARY; } LockContentsView::UserState::UserState(UserState&&) = default;
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc index eb71b59c..d4f4cf6 100644 --- a/ash/login/ui/login_auth_user_view.cc +++ b/ash/login/ui/login_auth_user_view.cc
@@ -25,6 +25,7 @@ #include "ash/login/ui/views_utils.h" #include "ash/public/cpp/login_constants.h" #include "ash/resources/vector_icons/vector_icons.h" +#include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/model/clock_model.h" @@ -122,7 +123,8 @@ constexpr int kDisabledAuthMessageVerticalBorderDp = 16; constexpr int kDisabledAuthMessageHorizontalBorderDp = 16; constexpr int kDisabledAuthMessageChildrenSpacingDp = 4; -constexpr int kDisabledAuthMessageWidthDp = 204; +constexpr int kDisabledAuthMessageTimeWidthDp = 204; +constexpr int kDisabledAuthMessageMultiprofileWidthDp = 304; constexpr int kDisabledAuthMessageHeightDp = 98; constexpr int kDisabledAuthMessageIconSizeDp = 24; constexpr int kDisabledAuthMessageTitleFontSizeDeltaDp = 3; @@ -681,7 +683,14 @@ DisabledAuthMessageView* const view_; }; - DisabledAuthMessageView() { + // If the reason of disabled auth is multiprofile policy, then we can already + // set the text and message. Otherwise, in case of disabled auth because of + // time limit exceeded on child account, we wait for SetAuthDisabledMessage to + // be called. + DisabledAuthMessageView(bool shown_because_of_multiprofile_policy, + MultiProfileUserBehavior multiprofile_policy) + : shown_because_of_multiprofile_policy_( + shown_because_of_multiprofile_policy) { SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical, gfx::Insets(kDisabledAuthMessageVerticalBorderDp, @@ -689,16 +698,20 @@ kDisabledAuthMessageChildrenSpacingDp)); SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false); - SetPreferredSize( - gfx::Size(kDisabledAuthMessageWidthDp, kDisabledAuthMessageHeightDp)); + SetPreferredSize(gfx::Size(shown_because_of_multiprofile_policy + ? kDisabledAuthMessageMultiprofileWidthDp + : kDisabledAuthMessageTimeWidthDp, + kDisabledAuthMessageHeightDp)); SetFocusBehavior(FocusBehavior::ALWAYS); - message_icon_ = new views::ImageView(); - message_icon_->SetPreferredSize(gfx::Size(kDisabledAuthMessageIconSizeDp, - kDisabledAuthMessageIconSizeDp)); - message_icon_->SetImage( - gfx::CreateVectorIcon(kLockScreenTimeLimitMoonIcon, - kDisabledAuthMessageIconSizeDp, SK_ColorWHITE)); - AddChildView(message_icon_); + if (!shown_because_of_multiprofile_policy) { + message_icon_ = new views::ImageView(); + message_icon_->SetPreferredSize(gfx::Size( + kDisabledAuthMessageIconSizeDp, kDisabledAuthMessageIconSizeDp)); + message_icon_->SetImage( + gfx::CreateVectorIcon(kLockScreenTimeLimitMoonIcon, + kDisabledAuthMessageIconSizeDp, SK_ColorWHITE)); + AddChildView(message_icon_); + } auto decorate_label = [](views::Label* label) { label->SetSubpixelRenderingEnabled(false); @@ -724,6 +737,27 @@ decorate_label(message_contents_); message_contents_->SetMultiLine(true); AddChildView(message_contents_); + + if (shown_because_of_multiprofile_policy) { + message_title_->SetText(l10n_util::GetStringUTF16( + IDS_ASH_LOGIN_MULTI_PROFILES_RESTRICTED_POLICY_TITLE)); + switch (multiprofile_policy) { + case MultiProfileUserBehavior::PRIMARY_ONLY: + message_contents_->SetText(l10n_util::GetStringUTF16( + IDS_ASH_LOGIN_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG)); + break; + case MultiProfileUserBehavior::NOT_ALLOWED: + message_contents_->SetText(l10n_util::GetStringUTF16( + IDS_ASH_LOGIN_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG)); + break; + case MultiProfileUserBehavior::OWNER_PRIMARY_ONLY: + message_contents_->SetText(l10n_util::GetStringUTF16( + IDS_ASH_LOGIN_MULTI_PROFILES_OWNER_PRIMARY_ONLY_MSG)); + break; + default: + NOTREACHED(); + } + } } ~DisabledAuthMessageView() override = default; @@ -731,6 +765,9 @@ // Set the parameters needed to render the message. void SetAuthDisabledMessage(const AuthDisabledData& auth_disabled_data, bool use_24hour_clock) { + // Do not do anything if message is already shown. + if (shown_because_of_multiprofile_policy_) + return; LockScreenMessage message = GetLockScreenMessage( auth_disabled_data.reason, auth_disabled_data.auth_reenabled_time, auth_disabled_data.device_used_time, use_24hour_clock); @@ -758,6 +795,10 @@ views::Label* message_title_; views::Label* message_contents_; views::ImageView* message_icon_; + // Used in case a child account has triggered the disabled auth message + // because of time limit exceeded while it also has disabled auth by + // multiprofile policy. + bool shown_because_of_multiprofile_policy_ = false; DISALLOW_COPY_AND_ASSIGN(DisabledAuthMessageView); }; @@ -1025,7 +1066,12 @@ /*multiline*/ false); online_sign_in_message_ = online_sign_in_message.get(); - auto disabled_auth_message = std::make_unique<DisabledAuthMessageView>(); + bool shown_because_of_multiprofile_policy = + !user.is_multiprofile_allowed && + Shell::Get()->session_controller()->GetSessionState() == + session_manager::SessionState::LOGIN_SECONDARY; + auto disabled_auth_message = std::make_unique<DisabledAuthMessageView>( + shown_because_of_multiprofile_policy, user.multiprofile_policy); disabled_auth_message_ = disabled_auth_message.get(); auto locked_tpm_message_view = std::make_unique<LockedTpmMessageView>();
diff --git a/ash/login/ui/login_palette.cc b/ash/login/ui/login_palette.cc index 6c5368d..e1a84b08 100644 --- a/ash/login/ui/login_palette.cc +++ b/ash/login/ui/login_palette.cc
@@ -4,20 +4,33 @@ #include "ash/login/ui/login_palette.h" #include "ash/public/cpp/login_constants.h" +#include "ash/style/ash_color_provider.h" #include "ui/gfx/color_palette.h" namespace ash { LoginPalette CreateDefaultLoginPalette() { + auto* color_provider = AshColorProvider::Get(); + auto background_color = color_provider->GetBackgroundColor(); + const AshColorProvider::RippleAttributes ripple_attributes = + color_provider->GetRippleAttributes(background_color); + // Convert transparency level from [0 ; 1] to [0 ; 255]. + U8CPU inkdrop_opacity = 255 * ripple_attributes.inkdrop_opacity; + U8CPU highlight_opacity = 255 * ripple_attributes.highlight_opacity; return LoginPalette( - {.password_text_color = SK_ColorWHITE, + {.password_text_color = color_provider->GetContentLayerColor( + AshColorProvider::ContentLayerType::kTextColorPrimary), .password_placeholder_text_color = login_constants::kAuthMethodsTextColor, .password_background_color = SK_ColorTRANSPARENT, - .button_enabled_color = login_constants::kButtonEnabledColor, - .pin_ink_drop_highlight_color = SkColorSetA(SK_ColorWHITE, 0x0A), - .pin_ink_drop_ripple_color = SkColorSetA(SK_ColorWHITE, 0x0F), - .pin_backspace_icon_color = gfx::kGoogleGrey200}); + .button_enabled_color = color_provider->GetContentLayerColor( + AshColorProvider::ContentLayerType::kIconColorPrimary), + .button_annotation_color = color_provider->GetContentLayerColor( + AshColorProvider::ContentLayerType::kTextColorSecondary), + .pin_ink_drop_highlight_color = + SkColorSetA(ripple_attributes.base_color, highlight_opacity), + .pin_ink_drop_ripple_color = + SkColorSetA(ripple_attributes.base_color, inkdrop_opacity)}); } LoginPalette CreateInSessionAuthPalette() { @@ -26,9 +39,9 @@ .password_placeholder_text_color = SK_ColorDKGRAY, .password_background_color = SK_ColorTRANSPARENT, .button_enabled_color = SK_ColorDKGRAY, + .button_annotation_color = SK_ColorDKGRAY, .pin_ink_drop_highlight_color = SkColorSetA(SK_ColorDKGRAY, 0x0A), - .pin_ink_drop_ripple_color = SkColorSetA(SK_ColorDKGRAY, 0x0F), - .pin_backspace_icon_color = SK_ColorDKGRAY}); + .pin_ink_drop_ripple_color = SkColorSetA(SK_ColorDKGRAY, 0x0F)}); } } // namespace ash
diff --git a/ash/login/ui/login_palette.h b/ash/login/ui/login_palette.h index 3d3d9dd..e35c44c 100644 --- a/ash/login/ui/login_palette.h +++ b/ash/login/ui/login_palette.h
@@ -19,9 +19,9 @@ SkColor password_placeholder_text_color; SkColor password_background_color; SkColor button_enabled_color; + SkColor button_annotation_color; SkColor pin_ink_drop_highlight_color; SkColor pin_ink_drop_ripple_color; - SkColor pin_backspace_icon_color; }; // For login screen and lock screen.
diff --git a/ash/login/ui/login_pin_view.cc b/ash/login/ui/login_pin_view.cc index 1562682..c6cafb10 100644 --- a/ash/login/ui/login_pin_view.cc +++ b/ash/login/ui/login_pin_view.cc
@@ -209,20 +209,19 @@ label->SetEnabledColor(palette.button_enabled_color); label->SetAutoColorReadabilityEnabled(false); label->SetSubpixelRenderingEnabled(false); - label->SetFontList(base_font_list.Derive(8, gfx::Font::FontStyle::NORMAL, - gfx::Font::Weight::LIGHT)); + label->SetFontList(base_font_list.Derive(8 /*size_delta*/, gfx::Font::FontStyle::NORMAL, + gfx::Font::Weight::NORMAL)); AddChildView(label); if (show_sub_label) { views::Label* sub_label = new views::Label( GetButtonSubLabelForNumber(value), views::style::CONTEXT_BUTTON, - views::style::STYLE_PRIMARY); - sub_label->SetEnabledColor(SkColorSetA( - palette.button_enabled_color, login_constants::kButtonDisabledAlpha)); + views::style::STYLE_SECONDARY); + sub_label->SetEnabledColor(palette.button_annotation_color); sub_label->SetAutoColorReadabilityEnabled(false); sub_label->SetSubpixelRenderingEnabled(false); - sub_label->SetFontList(base_font_list.Derive( - -3, gfx::Font::FontStyle::NORMAL, gfx::Font::Weight::NORMAL)); + sub_label->SetFontList(base_font_list.Derive(-1 /*size_delta*/, gfx::Font::FontStyle::NORMAL, + gfx::Font::Weight::NORMAL)); AddChildView(sub_label); } } @@ -249,7 +248,7 @@ palette_(palette) { image_ = new views::ImageView(); image_->SetImage(gfx::CreateVectorIcon(kLockScreenBackspaceIcon, - palette_.pin_backspace_icon_color)); + palette_.button_enabled_color)); AddChildView(image_); SetEnabled(false); } @@ -263,7 +262,7 @@ } void OnEnabledChanged() { - SkColor color = palette_.pin_backspace_icon_color; + SkColor color = palette_.button_enabled_color; if (!GetEnabled()) { AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr); color = SkColorSetA(color, login_constants::kButtonDisabledAlpha);
diff --git a/ash/magnifier/magnification_controller.cc b/ash/magnifier/magnification_controller.cc index e4e5351..1ebd94d 100644 --- a/ash/magnifier/magnification_controller.cc +++ b/ash/magnifier/magnification_controller.cc
@@ -27,7 +27,6 @@ #include "ui/base/ime/chromeos/ime_bridge.h" #include "ui/base/ime/input_method.h" #include "ui/base/ime/text_input_client.h" -#include "ui/compositor/dip_util.h" #include "ui/compositor/layer.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/display/display.h" @@ -35,6 +34,7 @@ #include "ui/events/event.h" #include "ui/events/gestures/gesture_provider_aura.h" #include "ui/events/types/event_type.h" +#include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -593,13 +593,14 @@ return SendEvent(continuation, &event); } -bool MagnificationController::Redraw(const gfx::PointF& position, - float scale, - bool animate) { - const gfx::PointF position_in_dip = - ui::ConvertPointToDIP(root_window_->layer(), position); - return RedrawDIP(position_in_dip, scale, - animate ? kDefaultAnimationDurationInMs : 0, +bool MagnificationController::Redraw( + const gfx::PointF& position_in_physical_pixels, + float scale, + bool animate) { + gfx::PointF position = + gfx::ConvertPointToDips(position_in_physical_pixels, + root_window_->layer()->device_scale_factor()); + return RedrawDIP(position, scale, animate ? kDefaultAnimationDurationInMs : 0, kDefaultAnimationTweenType); }
diff --git a/ash/magnifier/magnification_controller.h b/ash/magnifier/magnification_controller.h index 92040d2..85e12526 100644 --- a/ash/magnifier/magnification_controller.h +++ b/ash/magnifier/magnification_controller.h
@@ -172,7 +172,7 @@ // given scale. Returns true if the window is changed; otherwise, false. // These methods should be called internally just after the scale and/or // the position are changed to redraw the window. - bool Redraw(const gfx::PointF& position, float scale, bool animate); + bool Redraw(const gfx::PointF& position_in_pixels, float scale, bool animate); // Redraws the magnification window with the given origin position in dip and // the given scale. Returns true if the window is changed; otherwise, false.
diff --git a/ash/public/cpp/holding_space/holding_space_client.h b/ash/public/cpp/holding_space/holding_space_client.h index 7296c60..62fd334 100644 --- a/ash/public/cpp/holding_space/holding_space_client.h +++ b/ash/public/cpp/holding_space/holding_space_client.h
@@ -31,6 +31,10 @@ virtual void CopyImageToClipboard(const HoldingSpaceItem& item, SuccessCallback callback) = 0; + // Attempts to open the Downloads folder. + // Success is returned via the supplied `callback`. + virtual void OpenDownloads(SuccessCallback callback) = 0; + // Attempts to open the specified holding space `item`. // Success is returned via the supplied `callback`. virtual void OpenItem(const HoldingSpaceItem& item,
diff --git a/ash/public/cpp/login_constants.h b/ash/public/cpp/login_constants.h index 681438e4..5b46aef4 100644 --- a/ash/public/cpp/login_constants.h +++ b/ash/public/cpp/login_constants.h
@@ -54,9 +54,6 @@ // show/hide animation. constexpr int kChangeUserAnimationDurationMs = 300; -// Color of enabled buttons. -constexpr SkColor kButtonEnabledColor = SK_ColorWHITE; - // An alpha value for disabled buttons. // In specs this is listed as 34% = 0x57 / 0xFF. constexpr SkAlpha kButtonDisabledAlpha = 0x57;
diff --git a/ash/wm/desks/DEPS b/ash/wm/desks/DEPS new file mode 100644 index 0000000..221cf15 --- /dev/null +++ b/ash/wm/desks/DEPS
@@ -0,0 +1,8 @@ +specific_include_rules = { + "root_window_desk_switch_animator_test_api.cc": [ + # These tests create a fake viz::CopyOutputTextureResult to avoid the async + # way of waiting for a layer output request. So this needs to explicity + # depend on gpu/command_buffer/common. + "+gpu/command_buffer/common", + ], +}
diff --git a/ash/wm/desks/root_window_desk_switch_animator.cc b/ash/wm/desks/root_window_desk_switch_animator.cc index 679a44db..47a80c0 100644 --- a/ash/wm/desks/root_window_desk_switch_animator.cc +++ b/ash/wm/desks/root_window_desk_switch_animator.cc
@@ -29,9 +29,6 @@ namespace { -// The space between the starting and ending desks screenshots in dips. -constexpr int kDesksSpacing = 50; - // The maximum number of times to retry taking a screenshot for either the // starting or the ending desks. After this maximum number is reached, we ignore // a failed screenshot request and proceed with next phases. @@ -50,12 +47,6 @@ // desk change. constexpr int kTouchpadSwipeLengthForDeskChange = 100; -// The animation layer has extra padding at its two edges. The width in dips is -// a ratio of the root window width. This padding is to notify users there are -// no more desks on that side by showing a black region as we swipe -// continuously. -constexpr float kEdgePaddingRatio = 0.15f; - // The amount, by which the detached old layers of the removed desk's windows, // is translated vertically during the for-remove desk switch animation. constexpr int kRemovedDeskWindowYTranslation = 20;
diff --git a/ash/wm/desks/root_window_desk_switch_animator.h b/ash/wm/desks/root_window_desk_switch_animator.h index b398b7d2..ab42a90 100644 --- a/ash/wm/desks/root_window_desk_switch_animator.h +++ b/ash/wm/desks/root_window_desk_switch_animator.h
@@ -7,6 +7,7 @@ #include <memory> +#include "ash/ash_export.h" #include "base/memory/weak_ptr.h" #include "ui/compositor/layer_animation_observer.h" @@ -157,7 +158,8 @@ // slightly more to accommodate the continuous desk animations feature. The base // algorithm is still valid, but once the features are near completion these // need to be updated. -class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver { +class ASH_EXPORT RootWindowDeskSwitchAnimator + : public ui::ImplicitAnimationObserver { public: class Delegate { public: @@ -179,6 +181,15 @@ virtual ~Delegate() = default; }; + // The space between the starting and ending desks screenshots in dips. + static constexpr int kDesksSpacing = 50; + + // The animation layer has extra padding at its two edges. The width in dips + // is a ratio of the root window width. This padding is to notify users there + // are no more desks on that side by showing a black region as we swipe + // continuously. + static constexpr float kEdgePaddingRatio = 0.15f; + RootWindowDeskSwitchAnimator(aura::Window* root, int starting_desk_index, int ending_desk_index, @@ -235,6 +246,8 @@ void OnImplicitAnimationsCompleted() override; private: + friend class RootWindowDeskSwitchAnimatorTestApi; + // Completes the first phase of the animation using the given |layer| as the // screenshot layer of the starting desk. This layer will be parented to the // animation layer, which will be setup with its initial transform according
diff --git a/ash/wm/desks/root_window_desk_switch_animator_test_api.cc b/ash/wm/desks/root_window_desk_switch_animator_test_api.cc new file mode 100644 index 0000000..852fb66 --- /dev/null +++ b/ash/wm/desks/root_window_desk_switch_animator_test_api.cc
@@ -0,0 +1,85 @@ +// Copyright 2020 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 "ash/wm/desks/root_window_desk_switch_animator_test_api.h" + +#include <memory> + +#include "ash/wm/desks/root_window_desk_switch_animator.h" +#include "base/strings/string_number_conversions.h" +#include "components/viz/common/frame_sinks/copy_output_result.h" +#include "gpu/command_buffer/common/mailbox.h" +#include "gpu/command_buffer/common/sync_token.h" +#include "ui/aura/window.h" +#include "ui/compositor/layer.h" +#include "ui/compositor/layer_tree_owner.h" +#include "ui/gfx/color_space.h" + +namespace ash { + +namespace { + +int g_mailbox_id = 0; + +// Creates a blank copy output result the size of |root_window|. +std::unique_ptr<viz::CopyOutputResult> CreateCopyOutputResult( + aura::Window* root_window) { + std::string mailbox_name = + "mailboxname" + base::NumberToString(g_mailbox_id++); + gpu::Mailbox mailbox; + mailbox.SetName(reinterpret_cast<const int8_t*>(mailbox_name.c_str())); + + std::unique_ptr<viz::CopyOutputResult> copy_result = + std::make_unique<viz::CopyOutputTextureResult>( + root_window->bounds(), mailbox, gpu::SyncToken(), + gfx::ColorSpace::CreateSRGB(), + viz::SingleReleaseCallback::Create(base::DoNothing())); + + DCHECK(!copy_result->IsEmpty()); + return copy_result; +} + +} // namespace + +RootWindowDeskSwitchAnimatorTestApi::RootWindowDeskSwitchAnimatorTestApi( + RootWindowDeskSwitchAnimator* animator) + : animator_(animator) { + DCHECK(animator_); +} + +RootWindowDeskSwitchAnimatorTestApi::~RootWindowDeskSwitchAnimatorTestApi() = + default; + +void RootWindowDeskSwitchAnimatorTestApi::OnStartingDeskScreenshotTaken() { + animator_->OnStartingDeskScreenshotTaken( + CreateCopyOutputResult(animator_->root_window_)); +} + +void RootWindowDeskSwitchAnimatorTestApi::OnEndingDeskScreenshotTaken() { + animator_->OnEndingDeskScreenshotTaken( + CreateCopyOutputResult(animator_->root_window_)); +} + +ui::Layer* RootWindowDeskSwitchAnimatorTestApi::GetAnimationLayer() { + return animator_->animation_layer_owner_->root(); +} + +ui::Layer* +RootWindowDeskSwitchAnimatorTestApi::GetScreenshotLayerOfDeskWithIndex( + int desk_index) { + auto screenshot_layers = animator_->screenshot_layers_; + + DCHECK_GE(desk_index, 0); + DCHECK_LT(desk_index, int{screenshot_layers.size()}); + + ui::Layer* layer = screenshot_layers[desk_index]; + DCHECK(layer); + return layer; +} + +int RootWindowDeskSwitchAnimatorTestApi::GetEndingDeskIndex() const { + return animator_->ending_desk_index_; +} + +} // namespace ash
diff --git a/ash/wm/desks/root_window_desk_switch_animator_test_api.h b/ash/wm/desks/root_window_desk_switch_animator_test_api.h new file mode 100644 index 0000000..a9942a2 --- /dev/null +++ b/ash/wm/desks/root_window_desk_switch_animator_test_api.h
@@ -0,0 +1,45 @@ +// Copyright 2020 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 ASH_WM_DESKS_ROOT_WINDOW_DESK_SWITCH_ANIMATOR_TEST_API_H_ +#define ASH_WM_DESKS_ROOT_WINDOW_DESK_SWITCH_ANIMATOR_TEST_API_H_ + +namespace ui { +class Layer; +} + +namespace ash { + +class RootWindowDeskSwitchAnimator; + +// Use the api in this class to test the internals of +// RootWindowDeskSwitchAnimator. +class RootWindowDeskSwitchAnimatorTestApi { + public: + explicit RootWindowDeskSwitchAnimatorTestApi( + RootWindowDeskSwitchAnimator* animator); + RootWindowDeskSwitchAnimatorTestApi( + const RootWindowDeskSwitchAnimatorTestApi&) = delete; + RootWindowDeskSwitchAnimatorTestApi& operator=( + const RootWindowDeskSwitchAnimatorTestApi&) = delete; + ~RootWindowDeskSwitchAnimatorTestApi(); + + // Triggers the path taken when a screenshot is taken. Uses a blank + // viz::CopyOutputResult and is synchronous. + void OnStartingDeskScreenshotTaken(); + void OnEndingDeskScreenshotTaken(); + + // Getters for the layers associated with the animation. + ui::Layer* GetAnimationLayer(); + ui::Layer* GetScreenshotLayerOfDeskWithIndex(int desk_index); + + int GetEndingDeskIndex() const; + + private: + RootWindowDeskSwitchAnimator* const animator_; +}; + +} // namespace ash + +#endif // ASH_WM_DESKS_ROOT_WINDOW_DESK_SWITCH_ANIMATOR_TEST_API_H_
diff --git a/ash/wm/desks/root_window_desk_switch_animator_unittest.cc b/ash/wm/desks/root_window_desk_switch_animator_unittest.cc new file mode 100644 index 0000000..27ecdfe --- /dev/null +++ b/ash/wm/desks/root_window_desk_switch_animator_unittest.cc
@@ -0,0 +1,318 @@ +// Copyright 2020 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 "ash/wm/desks/root_window_desk_switch_animator.h" + +#include <memory> + +#include "ash/public/cpp/ash_features.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "ash/wm/desks/root_window_desk_switch_animator_test_api.h" +#include "base/test/scoped_feature_list.h" +#include "ui/compositor/layer.h" +#include "ui/compositor/scoped_animation_duration_scale_mode.h" + +namespace ash { + +namespace { + +// Computes the animation layer expected size. Each screenshot is the size of +// the primary root window, and there is spacing between each screenshot, which +// are children of the animation layer. The animation layer has padding on each +// end. +gfx::Size ComputeAnimationLayerExpectedSize(int expected_screenshots) { + const gfx::Size root_window_size = + Shell::GetPrimaryRootWindow()->bounds().size(); + const int edge_padding = + std::round(RootWindowDeskSwitchAnimator::kEdgePaddingRatio * + root_window_size.width()); + gfx::Size expected_size = root_window_size; + expected_size.set_width(root_window_size.width() * expected_screenshots + + RootWindowDeskSwitchAnimator::kDesksSpacing * + (expected_screenshots - 1) + + 2 * edge_padding); + return expected_size; +} + +// Computes where |child_layer| is shown in root window coordinates. This is +// done by applying its parent's transform to it. |child_layer| itself is not +// expected to have a transform and its grandparent is the root window. If +// |use_target_transform| is false apply the parent's current transform, +// otherwise apply the parent's target transform (the expected transform at the +// end of an ongoing animation). +gfx::Rect GetVisibleBounds(ui::Layer* child_layer, + ui::Layer* animating_layer, + bool use_target_transform = false) { + DCHECK_EQ(animating_layer, child_layer->parent()); + DCHECK(child_layer->transform().IsIdentity()); + DCHECK_EQ(Shell::GetPrimaryRootWindow()->layer(), animating_layer->parent()); + + const gfx::Transform animating_layer_transform = + use_target_transform ? animating_layer->GetTargetTransform() + : animating_layer->transform(); + DCHECK(animating_layer_transform.IsIdentityOr2DTranslation()); + gfx::RectF bounds(child_layer->bounds()); + animating_layer_transform.TransformRect(&bounds); + return gfx::ToRoundedRect(bounds); +} + +gfx::Rect GetTargetVisibleBounds(ui::Layer* child_layer, + ui::Layer* animating_layer) { + return GetVisibleBounds(child_layer, animating_layer, + /*use_target_transform=*/true); +} + +} // namespace + +class RootWindowDeskSwitchAnimatorTest + : public AshTestBase, + public RootWindowDeskSwitchAnimator::Delegate { + public: + RootWindowDeskSwitchAnimatorTest() = default; + RootWindowDeskSwitchAnimatorTest(const RootWindowDeskSwitchAnimatorTest&) = + delete; + RootWindowDeskSwitchAnimatorTest& operator=( + const RootWindowDeskSwitchAnimatorTest&) = delete; + ~RootWindowDeskSwitchAnimatorTest() override = default; + + RootWindowDeskSwitchAnimatorTestApi* test_api() { return test_api_.get(); } + RootWindowDeskSwitchAnimator* animator() { return animator_.get(); } + + int starting_desk_screenshot_taken_count() const { + return starting_desk_screenshot_taken_count_; + } + int ending_desk_screenshot_taken_count() const { + return ending_desk_screenshot_taken_count_; + } + + // Creates an animator from the given indices on the primary root window. + // Creates a test api for the animator as well. + void InitAnimator(int starting_desk_index, int ending_desk_index) { + animator_ = std::make_unique<RootWindowDeskSwitchAnimator>( + Shell::GetPrimaryRootWindow(), starting_desk_index, ending_desk_index, + this, /*for_remove=*/false); + test_api_ = + std::make_unique<RootWindowDeskSwitchAnimatorTestApi>(animator_.get()); + } + + // AshTestBase: + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature( + features::kEnhancedDeskAnimations); + AshTestBase::SetUp(); + } + + // RootWindowDeskSwitchAnimator::Delegate: + void OnStartingDeskScreenshotTaken(int ending_desk_index) override { + ++starting_desk_screenshot_taken_count_; + } + + void OnEndingDeskScreenshotTaken() override { + ++ending_desk_screenshot_taken_count_; + } + + void OnDeskSwitchAnimationFinished() override {} + + private: + base::test::ScopedFeatureList scoped_feature_list_; + + // The RootWindowDeskSwitchAnimator we are testing. + std::unique_ptr<RootWindowDeskSwitchAnimator> animator_; + + // The support test api associated with |animator_|. + std::unique_ptr<RootWindowDeskSwitchAnimatorTestApi> test_api_; + + int starting_desk_screenshot_taken_count_ = 0; + int ending_desk_screenshot_taken_count_ = 0; +}; + +// Tests a simple animation from one desk to another. +TEST_F(RootWindowDeskSwitchAnimatorTest, SimpleAnimation) { + InitAnimator(1, 2); + test_api()->OnStartingDeskScreenshotTaken(); + test_api()->OnEndingDeskScreenshotTaken(); + + // Tests that a simple animation has 2 screenshots, one for each desk. + EXPECT_EQ(1, starting_desk_screenshot_taken_count()); + EXPECT_EQ(1, ending_desk_screenshot_taken_count()); + + // Tests that the animation layer is the expected size. + auto* animation_layer = test_api()->GetAnimationLayer(); + EXPECT_EQ(2u, animation_layer->children().size()); + EXPECT_EQ(ComputeAnimationLayerExpectedSize(2), + animation_layer->bounds().size()); + + // Tests that the screenshot associated with desk index 1 is the one that is + // shown at the beginning of the animation. + EXPECT_EQ(Shell::GetPrimaryRootWindow()->bounds(), + GetVisibleBounds(test_api()->GetScreenshotLayerOfDeskWithIndex(1), + animation_layer)); + + // Tests that the screenshot associated with desk index 2 is the one that is + // shown at the end of the animation. + animator()->StartAnimation(); + EXPECT_EQ(Shell::GetPrimaryRootWindow()->bounds(), + GetVisibleBounds(test_api()->GetScreenshotLayerOfDeskWithIndex(2), + animation_layer)); + EXPECT_EQ(2, test_api()->GetEndingDeskIndex()); +} + +// Tests a chained animation where the replaced animation already has a +// screenshot layer stored. +TEST_F(RootWindowDeskSwitchAnimatorTest, ChainedAnimationNoNewScreenshot) { + InitAnimator(1, 2); + test_api()->OnStartingDeskScreenshotTaken(); + test_api()->OnEndingDeskScreenshotTaken(); + + // Replacing needs to be done while a current animation is underway, otherwise + // it will have no effect. + ui::ScopedAnimationDurationScaleMode non_zero( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + animator()->StartAnimation(); + // Replacing with an animation going back to desk index 1. No new screenshot + // is needed. + bool needs_screenshot = animator()->ReplaceAnimation(1); + EXPECT_FALSE(needs_screenshot); + + // Tests that no new screenshot was taken as it already existed. + auto* animation_layer = test_api()->GetAnimationLayer(); + EXPECT_EQ(2u, animation_layer->children().size()); + EXPECT_EQ(1, starting_desk_screenshot_taken_count()); + EXPECT_EQ(1, ending_desk_screenshot_taken_count()); + + // Tests that the screenshot associated with desk index 1 is the one that is + // shown at the end of the animation. + animator()->StartAnimation(); + EXPECT_EQ( + Shell::GetPrimaryRootWindow()->bounds(), + GetTargetVisibleBounds(test_api()->GetScreenshotLayerOfDeskWithIndex(1), + animation_layer)); +} + +// Tests a chained animation where we are adding an animation to the right of +// the current animating desks, causing the animation layer to shift left. +TEST_F(RootWindowDeskSwitchAnimatorTest, ChainedAnimationMovingLeft) { + InitAnimator(1, 2); + test_api()->OnStartingDeskScreenshotTaken(); + test_api()->OnEndingDeskScreenshotTaken(); + + // Replacing needs to be done while a current animation is underway, otherwise + // it will have no effect. + ui::ScopedAnimationDurationScaleMode non_zero( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + // Tests that the animation layer originally has 2 children. + auto* animation_layer = test_api()->GetAnimationLayer(); + EXPECT_EQ(2u, animation_layer->children().size()); + + animator()->StartAnimation(); + + // Replace the current animation to one that goes to desk index 3. + EXPECT_EQ(2, test_api()->GetEndingDeskIndex()); + bool needs_screenshot = animator()->ReplaceAnimation(3); + ASSERT_TRUE(needs_screenshot); + EXPECT_EQ(3, test_api()->GetEndingDeskIndex()); + + // Take a screenshot at the new ending desk. Test that the animation layer now + // has 3 children. + test_api()->OnEndingDeskScreenshotTaken(); + EXPECT_EQ(1, starting_desk_screenshot_taken_count()); + EXPECT_EQ(2, ending_desk_screenshot_taken_count()); + EXPECT_EQ(3u, animation_layer->children().size()); + EXPECT_EQ(ComputeAnimationLayerExpectedSize(3), + animation_layer->bounds().size()); + + animator()->StartAnimation(); + // Tests that the screenshot associated with desk index 3 is the one that is + // shown at the end of the animation. + EXPECT_EQ( + Shell::GetPrimaryRootWindow()->bounds(), + GetTargetVisibleBounds(test_api()->GetScreenshotLayerOfDeskWithIndex(3), + animation_layer)); +} + +// Tests a chained animation where we are adding an animation to the left of +// the current animating desks, causing the animation layer to shift right. +TEST_F(RootWindowDeskSwitchAnimatorTest, ChainedAnimationMovingRight) { + InitAnimator(3, 2); + test_api()->OnStartingDeskScreenshotTaken(); + test_api()->OnEndingDeskScreenshotTaken(); + + // Replacing needs to be done while a current animation is underway, otherwise + // it will have no effect. + ui::ScopedAnimationDurationScaleMode non_zero( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + animator()->StartAnimation(); + + // Replace the current animation to one that goes to desk index 1. + EXPECT_EQ(2, test_api()->GetEndingDeskIndex()); + bool needs_screenshot = animator()->ReplaceAnimation(1); + ASSERT_TRUE(needs_screenshot); + EXPECT_EQ(1, test_api()->GetEndingDeskIndex()); + + // Take a screenshot at the new ending desk. Test that the animation layer now + // has 3 children. + test_api()->OnEndingDeskScreenshotTaken(); + EXPECT_EQ(1, starting_desk_screenshot_taken_count()); + EXPECT_EQ(2, ending_desk_screenshot_taken_count()); + auto* animation_layer = test_api()->GetAnimationLayer(); + EXPECT_EQ(3u, animation_layer->children().size()); + EXPECT_EQ(ComputeAnimationLayerExpectedSize(3), + animation_layer->bounds().size()); + + animator()->StartAnimation(); + // Tests that the screenshot associated with desk index 1 is the one that is + // shown at the end of the animation. + EXPECT_EQ( + Shell::GetPrimaryRootWindow()->bounds(), + GetTargetVisibleBounds(test_api()->GetScreenshotLayerOfDeskWithIndex(1), + animation_layer)); +} + +// Tests a complex animation which multiple animations are started and replaced. +TEST_F(RootWindowDeskSwitchAnimatorTest, MultipleReplacements) { + InitAnimator(1, 2); + test_api()->OnStartingDeskScreenshotTaken(); + test_api()->OnEndingDeskScreenshotTaken(); + + // Replacing needs to be done while a current animation is underway, otherwise + // it will have no effect. + ui::ScopedAnimationDurationScaleMode non_zero( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + animator()->StartAnimation(); + + // Replace all the indices in the list one at a time. + auto animation_indices = {1, 0, 1, 2, 1, 2, 3, 2, 1}; + ui::Layer* animation_layer = test_api()->GetAnimationLayer(); + for (int index : animation_indices) { + if (animator()->ReplaceAnimation(index)) + test_api()->OnEndingDeskScreenshotTaken(); + EXPECT_EQ(index, test_api()->GetEndingDeskIndex()); + + // Start the replacement animation. The new animation should have a target + // transform such that the desk at |index| is visible on animation end. + animator()->StartAnimation(); + EXPECT_EQ(Shell::GetPrimaryRootWindow()->bounds(), + GetTargetVisibleBounds( + test_api()->GetScreenshotLayerOfDeskWithIndex(index), + animation_layer)); + } + + // Only 4 screenshots are taken as they are reused. + EXPECT_EQ(1, starting_desk_screenshot_taken_count()); + EXPECT_EQ(3, ending_desk_screenshot_taken_count()); + + // Tests that the screenshot associated with desk index 1 is the one that is + // shown at the end of the animation. + EXPECT_EQ( + Shell::GetPrimaryRootWindow()->bounds(), + GetTargetVisibleBounds(test_api()->GetScreenshotLayerOfDeskWithIndex(1), + animation_layer)); +} + +} // namespace ash
diff --git a/base/allocator/partition_allocator/partition_alloc.cc b/base/allocator/partition_allocator/partition_alloc.cc index a0290d4..f51d9f0 100644 --- a/base/allocator/partition_allocator/partition_alloc.cc +++ b/base/allocator/partition_allocator/partition_alloc.cc
@@ -845,6 +845,15 @@ stats.total_resident_bytes += direct_mapped_allocations_total_size; stats.total_active_bytes += direct_mapped_allocations_total_size; + + stats.has_thread_cache = !is_light_dump && with_thread_cache; + if (stats.has_thread_cache) { + internal::ThreadCacheRegistry::Instance().DumpStats( + true, &stats.current_thread_cache_stats); + internal::ThreadCacheRegistry::Instance().DumpStats( + false, &stats.all_thread_caches_stats); + } + dumper->PartitionDumpTotals(partition_name, &stats); }
diff --git a/base/allocator/partition_allocator/partition_alloc.h b/base/allocator/partition_allocator/partition_alloc.h index f79d27f..ef13436 100644 --- a/base/allocator/partition_allocator/partition_alloc.h +++ b/base/allocator/partition_allocator/partition_alloc.h
@@ -240,6 +240,10 @@ size_t total_active_bytes; // Total active bytes in the partition. size_t total_decommittable_bytes; // Total bytes that could be decommitted. size_t total_discardable_bytes; // Total bytes that could be discarded. + + bool has_thread_cache; + internal::ThreadCacheStats current_thread_cache_stats; + internal::ThreadCacheStats all_thread_caches_stats; }; // Struct used to retrieve memory statistics about a partition bucket. Used by
diff --git a/base/allocator/partition_allocator/thread_cache.cc b/base/allocator/partition_allocator/thread_cache.cc index a22a878..e1a91e7f 100644 --- a/base/allocator/partition_allocator/thread_cache.cc +++ b/base/allocator/partition_allocator/thread_cache.cc
@@ -29,6 +29,59 @@ } // namespace // static +ThreadCacheRegistry& ThreadCacheRegistry::Instance() { + static NoDestructor<ThreadCacheRegistry> instance; + return *instance.get(); +} + +ThreadCacheRegistry::ThreadCacheRegistry() = default; + +void ThreadCacheRegistry::RegisterThreadCache(ThreadCache* cache) { + AutoLock scoped_locker(GetLock()); + cache->next_ = nullptr; + cache->prev_ = nullptr; + + ThreadCache* previous_head = list_head_; + list_head_ = cache; + cache->next_ = previous_head; + if (previous_head) + previous_head->prev_ = cache; +} + +void ThreadCacheRegistry::UnregisterThreadCache(ThreadCache* cache) { + AutoLock scoped_locker(GetLock()); + if (cache->prev_) + cache->prev_->next_ = cache->next_; + if (cache->next_) + cache->next_->prev_ = cache->prev_; + if (cache == list_head_) + list_head_ = cache->next_; +} + +void ThreadCacheRegistry::DumpStats(bool my_thread_only, + ThreadCacheStats* stats) { + memset(reinterpret_cast<void*>(stats), 0, sizeof(ThreadCacheStats)); + + AutoLock scoped_locker(GetLock()); + if (my_thread_only) { + auto* tcache = ThreadCache::Get(); + if (!tcache) + return; + tcache->AccumulateStats(stats); + } else { + ThreadCache* tcache = list_head_; + while (tcache) { + // Racy, as other threads are still allocating. This is not an issue, + // since we are only interested in statistics. However, this means that + // count is not necessarily equal to hits + misses for the various types + // of events. + tcache->AccumulateStats(stats); + tcache = tcache->next_; + } + } +} + +// static void ThreadCache::Init(PartitionRoot<ThreadSafe>* root) { bool ok = PartitionTlsCreate(&g_thread_cache_key, DeleteThreadCache); PA_CHECK(ok); @@ -62,7 +115,7 @@ void* buffer = root->RawAlloc(bucket, PartitionAllocZeroFill, sizeof(ThreadCache), &allocated_size, &already_zeroed); - ThreadCache* tcache = new (buffer) ThreadCache(); + ThreadCache* tcache = new (buffer) ThreadCache(root); // This may allocate. PartitionTlsSet(g_thread_cache_key, tcache); @@ -70,10 +123,37 @@ return tcache; } +ThreadCache::ThreadCache(PartitionRoot<ThreadSafe>* root) + : buckets_(), stats_(), root_(root), next_(nullptr), prev_(nullptr) { + ThreadCacheRegistry::Instance().RegisterThreadCache(this); +} + ThreadCache::~ThreadCache() { + ThreadCacheRegistry::Instance().UnregisterThreadCache(this); Purge(); } +void ThreadCache::AccumulateStats(ThreadCacheStats* stats) const { + stats->alloc_count += stats_.alloc_count; + stats->alloc_hits += stats_.alloc_hits; + stats->alloc_misses += stats_.alloc_misses; + + stats->alloc_miss_empty += stats_.alloc_miss_empty; + stats->alloc_miss_too_large += stats_.alloc_miss_too_large; + + stats->cache_fill_count += stats_.cache_fill_count; + stats->cache_fill_hits += stats_.cache_fill_hits; + stats->cache_fill_misses += stats_.cache_fill_misses; + stats->cache_fill_bucket_full += stats_.cache_fill_bucket_full; + stats->cache_fill_too_large += stats_.cache_fill_too_large; + + for (size_t i = 0; i < kBucketCount; i++) { + stats->bucket_total_memory += + buckets_[i].count * root_->buckets[i].slot_size; + } + stats->metadata_overhead += sizeof(*this); +} + void ThreadCache::Purge() { for (Bucket& bucket : buckets_) { size_t count = bucket.count;
diff --git a/base/allocator/partition_allocator/thread_cache.h b/base/allocator/partition_allocator/thread_cache.h index 3f29721..bfb2f5e 100644 --- a/base/allocator/partition_allocator/thread_cache.h +++ b/base/allocator/partition_allocator/thread_cache.h
@@ -14,7 +14,9 @@ #include "base/allocator/partition_allocator/partition_tls.h" #include "base/base_export.h" #include "base/gtest_prod_util.h" +#include "base/no_destructor.h" #include "base/partition_alloc_buildflags.h" +#include "base/synchronization/lock.h" namespace base { @@ -24,6 +26,68 @@ extern BASE_EXPORT PartitionTlsKey g_thread_cache_key; +// Most of these are not populated if PA_ENABLE_THREAD_CACHE_STATISTICS is not +// defined. +struct ThreadCacheStats { + uint64_t alloc_count; // Total allocation requests. + uint64_t alloc_hits; // Thread cache hits. + uint64_t alloc_misses; // Thread cache misses. + + // Allocation failure details: + uint64_t alloc_miss_empty; + uint64_t alloc_miss_too_large; + + // Cache fill details: + uint64_t cache_fill_count; + uint64_t cache_fill_hits; + uint64_t cache_fill_misses; + uint64_t cache_fill_bucket_full; + uint64_t cache_fill_too_large; + + // Memory cost: + uint64_t bucket_total_memory; + uint64_t metadata_overhead; +}; + +// Global registry of all ThreadCache instances. +// +// This class cannot allocate in the (Un)registerThreadCache() functions, as +// they are called from ThreadCache constructor, which is from within the +// allocator. However the other members can allocate. +class BASE_EXPORT ThreadCacheRegistry { + public: + static ThreadCacheRegistry& Instance(); + ~ThreadCacheRegistry() = delete; + + void RegisterThreadCache(ThreadCache* cache); + void UnregisterThreadCache(ThreadCache* cache); + // Prints statistics for all thread caches, or this thread's only. + void DumpStats(bool my_thread_only, ThreadCacheStats* stats); + static Lock& GetLock() { return Instance().lock_; } + + private: + friend class NoDestructor<ThreadCacheRegistry>; + ThreadCacheRegistry(); + + Lock lock_; + ThreadCache* list_head_ GUARDED_BY(GetLock()) = nullptr; +}; + +// Optional statistics collection. +#if DCHECK_IS_ON() +#define PA_ENABLE_THREAD_CACHE_STATISTICS 1 +#endif + +#if defined(PA_ENABLE_THREAD_CACHE_STATISTICS) +#define INCREMENT_COUNTER(counter) ++counter +#define GET_COUNTER(counter) counter +#else +#define INCREMENT_COUNTER(counter) \ + do { \ + } while (0) +#define GET_COUNTER(counter) 0 +#endif // defined(PA_ENABLE_THREAD_CACHE_STATISTICS) + // Per-thread cache. *Not* threadsafe, must only be accessed from a single // thread. // @@ -44,6 +108,7 @@ static ThreadCache* Get() { return reinterpret_cast<ThreadCache*>(PartitionTlsGet(g_thread_cache_key)); } + // Create a new ThreadCache associated with |root|. // Must be called without the partition locked, as this may allocate. static ThreadCache* Create(PartitionRoot<ThreadSafe>* root); @@ -79,13 +144,14 @@ // Empties the cache. // The Partition lock must *not* be held when calling this. void Purge(); + void AccumulateStats(ThreadCacheStats* stats) const; size_t bucket_count_for_testing(size_t index) const { return buckets_[index].count; } private: - ThreadCache() = default; + explicit ThreadCache(PartitionRoot<ThreadSafe>* root); struct Bucket { size_t count; @@ -103,20 +169,39 @@ static constexpr size_t kMaxCountPerBucket = 100; Bucket buckets_[kBucketCount]; + ThreadCacheStats stats_; + PartitionRoot<ThreadSafe>* root_; + // Intrusive list since ThreadCacheRegistry::RegisterThreadCache() cannot + // allocate. + ThreadCache* next_ GUARDED_BY(ThreadCacheRegistry::GetLock()); + ThreadCache* prev_ GUARDED_BY(ThreadCacheRegistry::GetLock()); + + friend class ThreadCacheRegistry; FRIEND_TEST_ALL_PREFIXES(ThreadCacheTest, LargeAllocationsAreNotCached); FRIEND_TEST_ALL_PREFIXES(ThreadCacheTest, MultipleThreadCaches); + FRIEND_TEST_ALL_PREFIXES(ThreadCacheTest, RecordStats); + FRIEND_TEST_ALL_PREFIXES(ThreadCacheTest, ThreadCacheRegistry); + FRIEND_TEST_ALL_PREFIXES(ThreadCacheTest, MultipleThreadCachesAccounting); }; ALWAYS_INLINE bool ThreadCache::MaybePutInCache(void* address, size_t bucket_index) { - if (bucket_index >= kBucketCount) + INCREMENT_COUNTER(stats_.cache_fill_count); + + if (bucket_index >= kBucketCount) { + INCREMENT_COUNTER(stats_.cache_fill_too_large); + INCREMENT_COUNTER(stats_.cache_fill_misses); return false; + } auto& bucket = buckets_[bucket_index]; - if (bucket.count >= kMaxCountPerBucket) + if (bucket.count >= kMaxCountPerBucket) { + INCREMENT_COUNTER(stats_.cache_fill_bucket_full); + INCREMENT_COUNTER(stats_.cache_fill_misses); return false; + } PA_DCHECK(bucket.count != 0 || bucket.freelist_head == nullptr); @@ -124,26 +209,37 @@ entry->next = PartitionFreelistEntry::Encode(bucket.freelist_head); bucket.freelist_head = entry; bucket.count++; + + INCREMENT_COUNTER(stats_.cache_fill_hits); return true; } ALWAYS_INLINE void* ThreadCache::GetFromCache(size_t bucket_index) { + INCREMENT_COUNTER(stats_.alloc_count); // Only handle "small" allocations. - if (bucket_index >= kBucketCount) + if (bucket_index >= kBucketCount) { + INCREMENT_COUNTER(stats_.alloc_miss_too_large); + INCREMENT_COUNTER(stats_.alloc_misses); return nullptr; + } auto& bucket = buckets_[bucket_index]; auto* result = bucket.freelist_head; if (!result) { PA_DCHECK(bucket.count == 0); + INCREMENT_COUNTER(stats_.alloc_miss_empty); + INCREMENT_COUNTER(stats_.alloc_misses); return nullptr; } + PA_DCHECK(bucket.count != 0); auto* next = EncodedPartitionFreelistEntry::Decode(result->next); PA_DCHECK(result != next); bucket.count--; PA_DCHECK(bucket.count != 0 || !next); bucket.freelist_head = next; + + INCREMENT_COUNTER(stats_.alloc_hits); return result; }
diff --git a/base/allocator/partition_allocator/thread_cache_unittest.cc b/base/allocator/partition_allocator/thread_cache_unittest.cc index cd2272b..1b5cdba 100644 --- a/base/allocator/partition_allocator/thread_cache_unittest.cc +++ b/base/allocator/partition_allocator/thread_cache_unittest.cc
@@ -42,6 +42,18 @@ OnceClosure f_; }; +class DeltaCounter { + public: + explicit DeltaCounter(uint64_t& value) + : current_value_(value), initial_value_(value) {} + void Reset() { initial_value_ = current_value_; } + uint64_t Delta() const { return current_value_ - initial_value_; } + + private: + uint64_t& current_value_; + uint64_t initial_value_; +}; + // Need to be a global object without a destructor, because the cache is a // global object with a destructor (to handle thread destruction), and the // PartitionRoot has to outlive it. @@ -68,9 +80,13 @@ class ThreadCacheTest : public ::testing::Test { protected: void SetUp() override { + // Make sure there is a thread cache. + void* data = g_root->Alloc(1, ""); + g_root->Free(data); + auto* tcache = g_root->thread_cache_for_testing(); - if (tcache) - tcache->Purge(); + ASSERT_TRUE(tcache); + tcache->Purge(); } void TearDown() override {} }; @@ -154,16 +170,27 @@ EXPECT_EQ(1u, tcache->bucket_count_for_testing(bucket_index)); } -#if ENABLE_THREAD_CACHE_STATISTICS // Required to record hits and misses. +#if defined(PA_ENABLE_THREAD_CACHE_STATISTICS) // Required to record hits and + // misses. TEST_F(ThreadCacheTest, LargeAllocationsAreNotCached) { auto* tcache = g_root->thread_cache_for_testing(); - size_t hits_before = tcache ? tcache->hits_ : 0; + DeltaCounter alloc_miss_counter{tcache->stats_.alloc_misses}; + DeltaCounter alloc_miss_too_large_counter{ + tcache->stats_.alloc_miss_too_large}; + DeltaCounter cache_fill_counter{tcache->stats_.cache_fill_count}; + DeltaCounter cache_fill_misses_counter{tcache->stats_.cache_fill_misses}; + DeltaCounter cache_fill_too_large_counter{ + tcache->stats_.cache_fill_too_large}; FillThreadCacheAndReturnIndex(100 * 1024); tcache = g_root->thread_cache_for_testing(); - EXPECT_EQ(hits_before, tcache->hits_); + EXPECT_EQ(1u, alloc_miss_counter.Delta()); + EXPECT_EQ(1u, alloc_miss_too_large_counter.Delta()); + EXPECT_EQ(1u, cache_fill_counter.Delta()); + EXPECT_EQ(1u, cache_fill_misses_counter.Delta()); + EXPECT_EQ(1u, cache_fill_too_large_counter.Delta()); } -#endif +#endif // defined(PA_ENABLE_THREAD_CACHE_STATISTICS) TEST_F(ThreadCacheTest, DirectMappedAllocationsAreNotCached) { FillThreadCacheAndReturnIndex(1024 * 1024); @@ -217,6 +244,106 @@ g_root->Free(tmp); } +TEST_F(ThreadCacheTest, ThreadCacheRegistry) { + const size_t kTestSize = 100; + auto* parent_thread_tcache = g_root->thread_cache_for_testing(); + ASSERT_TRUE(parent_thread_tcache); + + LambdaThreadDelegate delegate{BindLambdaForTesting([&]() { + EXPECT_FALSE(g_root->thread_cache_for_testing()); // No allocations yet. + FillThreadCacheAndReturnIndex(kTestSize); + auto* tcache = g_root->thread_cache_for_testing(); + EXPECT_TRUE(tcache); + + AutoLock lock(ThreadCacheRegistry::GetLock()); + EXPECT_EQ(tcache->prev_, nullptr); + EXPECT_EQ(tcache->next_, parent_thread_tcache); + })}; + + PlatformThreadHandle thread_handle; + PlatformThread::Create(0, &delegate, &thread_handle); + PlatformThread::Join(thread_handle); + + AutoLock lock(ThreadCacheRegistry::GetLock()); + EXPECT_EQ(parent_thread_tcache->prev_, nullptr); + EXPECT_EQ(parent_thread_tcache->next_, nullptr); +} + +#if defined(PA_ENABLE_THREAD_CACHE_STATISTICS) +TEST_F(ThreadCacheTest, RecordStats) { + const size_t kTestSize = 100; + auto* tcache = g_root->thread_cache_for_testing(); + DeltaCounter alloc_counter{tcache->stats_.alloc_count}; + DeltaCounter alloc_hits_counter{tcache->stats_.alloc_hits}; + DeltaCounter alloc_miss_counter{tcache->stats_.alloc_misses}; + + DeltaCounter alloc_miss_empty_counter{tcache->stats_.alloc_miss_empty}; + + DeltaCounter cache_fill_counter{tcache->stats_.cache_fill_count}; + DeltaCounter cache_fill_hits_counter{tcache->stats_.cache_fill_hits}; + DeltaCounter cache_fill_misses_counter{tcache->stats_.cache_fill_misses}; + DeltaCounter cache_fill_bucket_full_counter{ + tcache->stats_.cache_fill_bucket_full}; + + // Cache has been purged, first allocation is a miss. + void* data = g_root->Alloc(kTestSize, ""); + EXPECT_EQ(1u, alloc_counter.Delta()); + EXPECT_EQ(1u, alloc_miss_counter.Delta()); + EXPECT_EQ(0u, alloc_hits_counter.Delta()); + + // Cache fill worked. + g_root->Free(data); + EXPECT_EQ(1u, cache_fill_counter.Delta()); + EXPECT_EQ(1u, cache_fill_hits_counter.Delta()); + EXPECT_EQ(0u, cache_fill_misses_counter.Delta()); + + tcache->Purge(); + cache_fill_counter.Reset(); + // Bucket full accounting. + size_t bucket_index = FillThreadCacheAndReturnIndex( + kTestSize, ThreadCache::kMaxCountPerBucket + 10); + EXPECT_EQ(ThreadCache::kMaxCountPerBucket + 10, cache_fill_counter.Delta()); + EXPECT_EQ(10u, cache_fill_bucket_full_counter.Delta()); + EXPECT_EQ(10u, cache_fill_misses_counter.Delta()); + + // Memory footprint. + size_t allocated_size = g_root->buckets[bucket_index].slot_size; + ThreadCacheStats stats; + ThreadCacheRegistry::Instance().DumpStats(true, &stats); + EXPECT_EQ(allocated_size * ThreadCache::kMaxCountPerBucket, + stats.bucket_total_memory); + EXPECT_EQ(sizeof(ThreadCache), stats.metadata_overhead); +} + +TEST_F(ThreadCacheTest, MultipleThreadCachesAccounting) { + const size_t kTestSize = 100; + void* data = g_root->Alloc(kTestSize, ""); + g_root->Free(data); + uint64_t alloc_count = g_root->thread_cache_for_testing()->stats_.alloc_count; + + LambdaThreadDelegate delegate{BindLambdaForTesting([&]() { + EXPECT_FALSE(g_root->thread_cache_for_testing()); // No allocations yet. + size_t bucket_index = FillThreadCacheAndReturnIndex(kTestSize); + + ThreadCacheStats stats; + ThreadCacheRegistry::Instance().DumpStats(false, &stats); + size_t allocated_size = g_root->buckets[bucket_index].slot_size; + // 2* for this thread and the parent one. + EXPECT_EQ(2 * allocated_size, stats.bucket_total_memory); + EXPECT_EQ(2 * sizeof(ThreadCache), stats.metadata_overhead); + + uint64_t this_thread_alloc_count = + g_root->thread_cache_for_testing()->stats_.alloc_count; + EXPECT_EQ(alloc_count + this_thread_alloc_count, stats.alloc_count); + })}; + + PlatformThreadHandle thread_handle; + PlatformThread::Create(0, &delegate, &thread_handle); + PlatformThread::Join(thread_handle); +} + +#endif // defined(PA_ENABLE_THREAD_CACHE_STATISTICS) + } // namespace internal } // namespace base
diff --git a/base/containers/flat_tree.h b/base/containers/flat_tree.h index ce6e92b..1d779f2c 100644 --- a/base/containers/flat_tree.h +++ b/base/containers/flat_tree.h
@@ -36,8 +36,8 @@ // Implementation ------------------------------------------------------------- -// Implementation of a sorted vector for backing flat_set and flat_map. Do not -// use directly. +// Implementation for the sorted associative flat_set and flat_map using a +// sorted vector as the backing store. Do not use directly. // // The use of "value" in this is like std::map uses, meaning it's the thing // contained (in the case of map it's a <Kay, Mapped> pair). The Key is how @@ -156,6 +156,9 @@ // -------------------------------------------------------------------------- // Iterators. + // + // Iterators follow the ordering defined by the key comparator used in + // construction of the flat_tree. iterator begin(); const_iterator begin() const;
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index a07a2a2..4fe13aa 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -89,7 +89,7 @@ # nonsensical for said projects. clang_use_default_sample_profile = chrome_pgo_phase == 0 && build_with_chromium && is_official_build && - (is_android || is_desktop_linux) + (is_android || chromeos_is_browser_only) # This configuration is used to select a default profile in Chrome OS based on # the microarchitectures we are using. This is only used if
diff --git a/build/config/compiler/pgo/pgo.gni b/build/config/compiler/pgo/pgo.gni index f616b88..c8c053c 100644 --- a/build/config/compiler/pgo/pgo.gni +++ b/build/config/compiler/pgo/pgo.gni
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") + declare_args() { # Specify the current PGO phase. # Here's the different values that can be used: @@ -9,7 +11,8 @@ # 1 : Used during the PGI (instrumentation) phase. # 2 : Used during the PGO (optimization) phase. chrome_pgo_phase = 0 - if (is_official_build && (is_win || is_mac)) { + if (is_official_build && + (is_win || is_mac || (is_desktop_linux && !chromeos_is_browser_only))) { chrome_pgo_phase = 2 }
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 41ac39e..d548668 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20200923.0.1 +0.20200923.2.1
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 909146b..91d4afc9 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -1446,7 +1446,10 @@ "java/src/org/chromium/chrome/browser/suggestions/tile/TileGroupDelegateImpl.java", "java/src/org/chromium/chrome/browser/suggestions/tile/TileRenderer.java", "java/src/org/chromium/chrome/browser/suggestions/tile/TileView.java", - "java/src/org/chromium/chrome/browser/suggestions/tile/TileWithTextView.java", + "java/src/org/chromium/chrome/browser/suggestions/tile/TileViewBinder.java", + "java/src/org/chromium/chrome/browser/suggestions/tile/TileViewCoordinator.java", + "java/src/org/chromium/chrome/browser/suggestions/tile/TileViewMediator.java", + "java/src/org/chromium/chrome/browser/suggestions/tile/TileViewProperties.java", "java/src/org/chromium/chrome/browser/suggestions/tile/TopSitesTileView.java", "java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java", "java/src/org/chromium/chrome/browser/survey/SurveyController.java", @@ -1574,6 +1577,9 @@ "java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressViewBinder.java", "java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java", "java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java", + "java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediator.java", + "java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonProperties.java", + "java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonViewBinder.java", "java/src/org/chromium/chrome/browser/toolbar/top/ActionModeController.java", "java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java", "java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbarAnimationDelegate.java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index 6ebc66b1..2c30654 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -235,6 +235,7 @@ "junit/src/org/chromium/chrome/browser/toolbar/LocationBarModelTest.java", "junit/src/org/chromium/chrome/browser/toolbar/ToolbarTabControllerImplTest.java", "junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinatorTest.java", + "junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java", "junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonTest.java", "junit/src/org/chromium/chrome/browser/toolbar/top/OptionalBrowsingModeButtonControllerTest.java", "junit/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediatorUnitTest.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index a42141c..4cb17d2 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -73,6 +73,7 @@ "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java", + "javatests/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivityTest.java", "javatests/src/org/chromium/chrome/browser/browserservices/OriginVerifierTest.java", "javatests/src/org/chromium/chrome/browser/browserservices/QualityEnforcerTest.java", "javatests/src/org/chromium/chrome/browser/browserservices/RunningInChromeTest.java",
diff --git a/chrome/android/expectations/lint-suppressions.xml b/chrome/android/expectations/lint-suppressions.xml index a914d69..83de1d5 100644 --- a/chrome/android/expectations/lint-suppressions.xml +++ b/chrome/android/expectations/lint-suppressions.xml
@@ -18,14 +18,6 @@ <ignore regexp="chrome/android/java/res_base/xml/network_security_config.xml"/> <ignore regexp="android_webview/tools/system_webview_shell/apk/res/xml/network_security_config.xml"/> </issue> - <issue id="ContentDescription"> - <!--TODO(crbug.com/1044658): This suppression was added blindly, and needs investigated.--> - <ignore regexp="components/browser_ui/contacts_picker/android/java/res/layout/contacts_list_item_view.xml"/> - <!--TODO(crbug.com/1044658): This suppression was added blindly, and needs investigated.--> - <ignore regexp="components/browser_ui/photo_picker/android/java/res/layout/photo_picker_dialog.xml"/> - <!--TODO(crbug.com/1044658): This suppression was added blindly, and needs investigated.--> - <ignore regexp="components/browser_ui/photo_picker/android/java/res/layout/video_player.xml"/> - </issue> <issue id="CustomViewStyleable"> <!-- TODO(crbug.com/1077861): Old code, good to fix. --> <ignore regexp="components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/BoundedLinearLayout.java"/> @@ -38,11 +30,6 @@ <!-- TODO(crbug.com/1082222): Fix --> <ignore regexp="chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/header/HeaderProcessor.java"/> </issue> - <issue id="DuplicateIds" severity="Fatal"> - <!--TODO(crbug.com/1044658): This suppression was added blindly, and needs investigated.--> - <ignore regexp="chrome/android/java/res/menu/main_menu.xml"/> - <ignore regexp="chrome/android/java/res/menu/main_menu_regroup.xml"/> - </issue> <issue id="DrawAllocation"> <ignore regexp="content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java"/> <ignore regexp="content/public/android/java/src/org/chromium/content/browser/PopupZoomer.java"/> @@ -109,10 +96,6 @@ <ignore regexp="components/browser_ui/strings/android/browser_ui_strings_grd"/> <ignore regexp="clank/third_party/chime/chime_systemtray_strings_grd.resources.zip"/> </issue> - <issue id="IncludeLayoutParam"> - <!--TODO(crbug.com/1044658): This suppression was added blindly, and needs investigated.--> - <ignore regexp="chrome/android/java/res/layout/start_top_toolbar.xml"/> - </issue> <issue id="InsecureBaseConfiguration"> <!-- See https://crbug.com/827265 and comment in the file for context. --> <ignore regexp="chrome/android/java/res_base/xml/network_security_config.xml"/> @@ -147,8 +130,6 @@ <ignore regexp="toolbar_background.9.png"/> <!-- Only used by FirstRunFlowSequencer guarded by tablet form-factor. --> <ignore regexp="window_background.xml"/> - <!--TODO(crbug.com/1044658): This suppression was added blindly, and needs investigated.--> - <ignore regexp="chrome/android/java/res/layout-sw360dp/preference_spinner_single_line.xml"/> </issue> <issue id="MissingPermission" severity="ignore"/> <issue id="MissingQuantity" severity="ignore"/> @@ -196,11 +177,6 @@ <issue id="ResourceAsColor" severity="ignore"/> <issue id="RtlCompat" severity="ignore"/> <issue id="RtlEnabled" severity="ignore"/> - <issue id="RtlHardcoded"> - <!--TODO(crbug.com/1044658): This suppression was added blindly, and needs - investigated.--> - <ignore regexp="chrome/android/java/res/layout/sheet_tab_toolbar.xml"/> - </issue> <issue id="RtlSymmetry" severity="ignore"/> <issue id="SetJavaScriptEnabled" severity="ignore"/> <issue id="SignatureOrSystemPermissions" severity="ignore"/> @@ -225,6 +201,7 @@ translated. This avoids blocking translation updates. --> <issue id="Typos" severity="ignore"/> <issue id="TypographyDashes"> + <!-- The double dash in the following file is a command line flag. --> <ignore regexp="chrome/app/policy/android/values-v21/restriction_values.xml"/> </issue> <issue id="UnusedIds" severity="ignore"/> @@ -343,16 +320,6 @@ <ignore regexp="The resource `R.drawable.*_expand_.*` appears to be unused"/> <!-- 1 string used by Android's policies system, pulled from app directly --> <ignore regexp="restriction_values.xml"/> - <!--TODO(crbug.com/1044658): This suppression was added blindly, and needs investigated.--> - <ignore regexp="../obj/components/strings/components_strings_grd.resources.zip/values/components_strings.xml"/> - <!--TODO(crbug.com/1044658): This suppression was added blindly, and needs investigated.--> - <ignore regexp="chrome/android/java/res/values/dimens.xml"/> - <!--TODO(crbug.com/1044658): This suppression was added blindly, and needs investigated.--> - <ignore regexp="chrome/android/java/res/layout-sw360dp/preference_spinner_single_line.xml"/> - <!--TODO(crbug.com/1044658): This suppression was added blindly, and needs investigated.--> - <ignore regexp="chrome/android/java/res/values/styles.xml"/> - <!--TODO(crbug.com/1044658): This suppression was added blindly, and needs investigated.--> - <ignore regexp="chrome/android/java/res/layout/tab_switcher_action_menu_layout.xml"/> <!--TODO(crbug.com/1052375): Remove this suppression once ConnectionInfoPopAndroid moves to components.--> <ignore regexp="components/page_info/android/java/res/drawable-hdpi/pageinfo_*"/> <!--TODO(crbug.com/1052375): Remove this suppression once PermissionParamsListBuilder moves to components.-->
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantProgressBarIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantProgressBarIntegrationTest.java index f230d536..8ab42c6 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantProgressBarIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantProgressBarIntegrationTest.java
@@ -189,20 +189,20 @@ .addChoices(Choice.newBuilder().setChip( ChipProto.newBuilder().setText("Next")))) .build()); - list.add((ActionProto) ActionProto.newBuilder() - .setShowProgressBar(ShowProgressBarProto.newBuilder().setActiveStep(1)) - .build()); + list.add( + (ActionProto) ActionProto.newBuilder() + .setShowProgressBar( + ShowProgressBarProto.newBuilder().setActiveStepIdentifier("icon_2")) + .build()); list.add((ActionProto) ActionProto.newBuilder() .setPrompt(PromptProto.newBuilder() .setMessage("Next Step") .addChoices(Choice.newBuilder().setChip( ChipProto.newBuilder().setText("Next")))) .build()); - list.add( - (ActionProto) ActionProto.newBuilder() - .setShowProgressBar( - ShowProgressBarProto.newBuilder().setActiveStepIdentifier("icon_4")) - .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setShowProgressBar(ShowProgressBarProto.newBuilder().setActiveStep(4)) + .build()); list.add((ActionProto) ActionProto.newBuilder() .setPrompt(PromptProto.newBuilder() .setMessage("Final Step")
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java index 50365fb..0484fc92 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
@@ -918,8 +918,10 @@ @MediumTest @Features.EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID + "<Study"}) @CommandLineFlags.Add({"force-fieldtrials=Study/Group", START_SURFACE_BASE_PARAMS + "/single"}) - @DisableIf.Build(supported_abis_includes = "x86", message = "https://crbug.com/1119899") - public void testUndoClosureInDialog_WithStartSurface() throws Exception { + @DisableIf.Build(supported_abis_includes = "x86", sdk_is_greater_than = 23, + sdk_is_less_than = 26, message = "crbug.com/1119899, crbug.com/1131545") + public void + testUndoClosureInDialog_WithStartSurface() throws Exception { // Create a tab group with 2 tabs. finishActivity(mActivityTestRule.getActivity()); createThumbnailBitmapAndWriteToFile(0);
diff --git a/chrome/android/java/res/layout/fre_tosanduma.xml b/chrome/android/java/res/layout/fre_tosanduma.xml index 950c6bb..8d0c7fb 100644 --- a/chrome/android/java/res/layout/fre_tosanduma.xml +++ b/chrome/android/java/res/layout/fre_tosanduma.xml
@@ -44,7 +44,7 @@ <TextView android:id="@+id/title" android:text="@string/fre_welcome" - style="@style/FreTitle" /> + style="@style/FreWelcomePageTitle" /> <!-- The FrameLayout here is to facilitate adding a proper content description for the loading view. During development, it didn't seem possible to override the @@ -124,7 +124,7 @@ android:paddingEnd="@dimen/fre_button_padding" android:text="@string/fre_accept_continue" android:animateLayoutChanges="true" - style="@style/FilledButton.Flat" /> + style="@style/FreAcceptTosButton" /> <!-- Same location as the button; marginBottom is adjusted for the different size. --> <ProgressBar
diff --git a/chrome/android/java/res/layout/sheet_tab_toolbar.xml b/chrome/android/java/res/layout/sheet_tab_toolbar.xml index 3393b34..c0549639 100644 --- a/chrome/android/java/res/layout/sheet_tab_toolbar.xml +++ b/chrome/android/java/res/layout/sheet_tab_toolbar.xml
@@ -109,7 +109,7 @@ android:layout_toStartOf="@id/open_in_new_tab" android:layout_toEndOf="@id/security_icon" android:layout_below="@id/title" - android:layout_marginLeft="4dp" + android:layout_marginStart="4dp" android:textAlignment="viewStart" android:ellipsize="start" android:singleLine="true"
diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/res/menu/main_menu.xml index ae2c404..763b6e785 100644 --- a/chrome/android/java/res/menu/main_menu.xml +++ b/chrome/android/java/res/menu/main_menu.xml
@@ -124,7 +124,7 @@ <item android:id="@id/new_tab_menu_id" android:title="@string/menu_new_tab" android:icon="@drawable/ic_add_box_rounded_corner" /> - <item android:id="@+id/new_incognito_tab_menu_id" + <item android:id="@id/new_incognito_tab_menu_id" android:title="@string/menu_new_incognito_tab" android:icon="@drawable/incognito_simple" /> <item android:id="@+id/close_all_tabs_menu_id" @@ -147,28 +147,28 @@ <item android:id="@id/new_tab_menu_id" android:title="@string/menu_new_tab" android:icon="@drawable/ic_add_box_rounded_corner" /> - <item android:id="@+id/new_incognito_tab_menu_id" + <item android:id="@id/new_incognito_tab_menu_id" android:title="@string/menu_new_incognito_tab" android:icon="@drawable/incognito_simple" /> - <item android:id="@+id/all_bookmarks_menu_id" + <item android:id="@id/all_bookmarks_menu_id" android:title="@string/menu_bookmarks" android:icon="@drawable/btn_star_filled" /> - <item android:id="@+id/recent_tabs_menu_id" + <item android:id="@id/recent_tabs_menu_id" android:title="@string/menu_recent_tabs" android:icon="@drawable/devices_black_24dp" /> - <item android:id="@+id/open_history_menu_id" + <item android:id="@id/open_history_menu_id" android:title="@string/menu_history" android:icon="@drawable/ic_history_googblue_24dp" /> - <item android:id="@+id/downloads_menu_id" + <item android:id="@id/downloads_menu_id" android:title="@string/menu_downloads" android:icon="@drawable/infobar_download_complete" /> - <item android:id="@+id/close_all_tabs_menu_id" + <item android:id="@id/close_all_tabs_menu_id" android:title="@string/menu_close_all_tabs" android:icon="@drawable/btn_close_white" /> - <item android:id="@+id/close_all_incognito_tabs_menu_id" + <item android:id="@id/close_all_incognito_tabs_menu_id" android:title="@string/menu_close_all_incognito_tabs" android:icon="@drawable/btn_close_white" /> - <item android:id="@+id/menu_group_tabs" + <item android:id="@id/menu_group_tabs" android:title="@string/menu_group_tabs" android:icon="@drawable/ic_widgets" /> <item android:id="@id/preferences_id" @@ -182,7 +182,7 @@ <item android:id="@id/new_tab_menu_id" android:title="@string/menu_new_tab" android:icon="@drawable/ic_add_box_rounded_corner" /> - <item android:id="@+id/new_incognito_tab_menu_id" + <item android:id="@id/new_incognito_tab_menu_id" android:title="@string/menu_new_incognito_tab" android:icon="@drawable/incognito_simple" /> <item android:id="@id/preferences_id"
diff --git a/chrome/android/java/res/menu/main_menu_regroup.xml b/chrome/android/java/res/menu/main_menu_regroup.xml index faa3fd2d..73ce5605 100644 --- a/chrome/android/java/res/menu/main_menu_regroup.xml +++ b/chrome/android/java/res/menu/main_menu_regroup.xml
@@ -76,7 +76,7 @@ <item android:id="@+id/recent_tabs_menu_id" android:title="@string/menu_recent_tabs" android:icon="@drawable/devices_black_24dp" /> - <item android:id="@+id/divider_line_id" + <item android:id="@id/divider_line_id" android:title="@null" /> <item android:id="@+id/share_row_menu_id" android:title="@null"> @@ -114,7 +114,7 @@ <item android:id="@+id/paint_preview_show_id" android:title="@string/menu_paint_preview_show" android:icon="@drawable/ic_photo_camera" /> - <item android:id="@+id/divider_line_id" + <item android:id="@id/divider_line_id" android:title="@null" /> <item android:id="@+id/reader_mode_prefs_id" android:title="@string/menu_reader_mode_prefs" @@ -141,7 +141,7 @@ <item android:id="@id/new_tab_menu_id" android:title="@string/menu_new_tab" android:icon="@drawable/ic_add_box_rounded_corner" /> - <item android:id="@+id/new_incognito_tab_menu_id" + <item android:id="@id/new_incognito_tab_menu_id" android:title="@string/menu_new_incognito_tab" android:icon="@drawable/incognito_simple" /> <item android:id="@+id/close_all_tabs_menu_id" @@ -164,32 +164,32 @@ <item android:id="@id/new_tab_menu_id" android:title="@string/menu_new_tab" android:icon="@drawable/ic_add_box_rounded_corner" /> - <item android:id="@+id/new_incognito_tab_menu_id" + <item android:id="@id/new_incognito_tab_menu_id" android:title="@string/menu_new_incognito_tab" android:icon="@drawable/incognito_simple" /> - <item android:id="@+id/divider_line_id" + <item android:id="@id/divider_line_id" android:title="@null" /> - <item android:id="@+id/open_history_menu_id" + <item android:id="@id/open_history_menu_id" android:title="@string/menu_history" android:icon="@drawable/ic_history_googblue_24dp" /> - <item android:id="@+id/downloads_menu_id" + <item android:id="@id/downloads_menu_id" android:title="@string/menu_downloads" android:icon="@drawable/infobar_download_complete" /> - <item android:id="@+id/all_bookmarks_menu_id" + <item android:id="@id/all_bookmarks_menu_id" android:title="@string/menu_bookmarks" android:icon="@drawable/btn_star_filled" /> - <item android:id="@+id/recent_tabs_menu_id" + <item android:id="@id/recent_tabs_menu_id" android:title="@string/menu_recent_tabs" android:icon="@drawable/devices_black_24dp" /> - <item android:id="@+id/divider_line_id" + <item android:id="@id/divider_line_id" android:title="@null" /> - <item android:id="@+id/close_all_tabs_menu_id" + <item android:id="@id/close_all_tabs_menu_id" android:title="@string/menu_close_all_tabs" android:icon="@drawable/btn_close_white" /> - <item android:id="@+id/close_all_incognito_tabs_menu_id" + <item android:id="@id/close_all_incognito_tabs_menu_id" android:title="@string/menu_close_all_incognito_tabs" android:icon="@drawable/btn_close_white" /> - <item android:id="@+id/menu_group_tabs" + <item android:id="@id/menu_group_tabs" android:title="@string/menu_group_tabs" android:icon="@drawable/ic_widgets" /> <item android:id="@id/preferences_id" @@ -203,7 +203,7 @@ <item android:id="@id/new_tab_menu_id" android:title="@string/menu_new_tab" android:icon="@drawable/ic_add_box_rounded_corner" /> - <item android:id="@+id/new_incognito_tab_menu_id" + <item android:id="@id/new_incognito_tab_menu_id" android:title="@string/menu_new_incognito_tab" android:icon="@drawable/incognito_simple" /> <item android:id="@id/preferences_id"
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 382dff50..502191ec0 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -91,7 +91,6 @@ <!-- Preview tab dimensions --> <dimen name="preview_tab_favicon_size">24dp</dimen> - <dimen name="preview_tab_security_icon_size">22dp</dimen> <!-- Sheet tab toolbar dimensions --> <dimen name="sheet_tab_toolbar_height">70dp</dimen> @@ -267,7 +266,6 @@ <dimen name="sei_location_bar_status_extra_padding_width">4dp</dimen> <dimen name="tablet_toolbar_start_padding">4dp</dimen> - <dimen name="tablet_toolbar_end_padding">6dp</dimen> <dimen name="toolbar_optional_button_animation_translation">10dp</dimen> <!-- Bottom controls dimensions --> @@ -289,10 +287,7 @@ <dimen name="omnibox_suggestion_semicompact_padding">8dp</dimen> <dimen name="omnibox_suggestion_compact_padding">6dp</dimen> <dimen name="omnibox_suggestion_list_padding_bottom">8dp</dimen> - <dimen name="omnibox_suggestion_first_line_text_size">16sp</dimen> - <dimen name="omnibox_suggestion_second_line_text_size">14sp</dimen> <dimen name="omnibox_suggestion_start_offset_without_icon">18dp</dimen> - <dimen name="omnibox_suggestion_start_offset_with_icon">56dp</dimen> <dimen name="omnibox_suggestion_36dp_icon_size">36dp</dimen> <dimen name="omnibox_suggestion_24dp_icon_size">24dp</dimen> @@ -305,7 +300,6 @@ <dimen name="omnibox_suggestion_icon_area_size">56dp</dimen> <dimen name="omnibox_suggestion_action_icon_width">48dp</dimen> - <dimen name="omnibox_suggestion_text_vertical_padding">5dp</dimen> <dimen name="omnibox_suggestion_refine_view_modern_end_padding">4dp</dimen> <!-- Adding search engine logo to the omnibox. --> @@ -401,7 +395,6 @@ <dimen name="explore_sites_dense_title_right_icon_margin_start">4dp</dimen> <dimen name="explore_sites_dense_title_right_tile_view_width">108dp</dimen> <dimen name="explore_sites_dense_title_right_tile_view_height">40dp</dimen> - <dimen name="explore_sites_dense_title_right_title_height">32dp</dimen> <dimen name="explore_sites_dense_title_right_title_margin_start">40dp</dimen> <dimen name="explore_sites_dense_title_right_title_margin_top">4dp</dimen> @@ -472,7 +465,6 @@ <dimen name="pref_autofill_dropdown_bottom_margin">16dp</dimen> <dimen name="pref_autofill_touch_target_padding">15dp</dimen> - <dimen name="pref_list_padding_kitkat">16dp</dimen> <dimen name="pref_spinner_padding_end">8dp</dimen> <dimen name="pref_languages_add_button_padding">24dp</dimen> @@ -535,8 +527,6 @@ <dimen name="download_manager_horizontal_margin">16dp</dimen> <dimen name="download_manager_prefetch_vertical_margin">12dp</dimen> <dimen name="download_manager_section_title_padding_top">16dp</dimen> - <dimen name="download_manager_section_title_padding_bottom">0dp</dimen> - <dimen name="download_manager_section_title_padding_image">8dp</dimen> <!-- The corner radius is calculated by subtracting the hairline border width from the background card corner radius. --> <dimen name="download_manager_thumbnail_corner_radius">7dp</dimen> @@ -553,7 +543,6 @@ <!-- History Navigation UI Item --> <dimen name="navigation_bubble_size">44dp</dimen> - <dimen name="navigation_bubble_radius">22dp</dimen> <dimen name="navigation_bubble_arrow_size">32dp</dimen> <dimen name="navigation_bubble_start_padding">2dp</dimen> <dimen name="navigation_bubble_top_padding">4dp</dimen>
diff --git a/chrome/android/java/res/values/styles.xml b/chrome/android/java/res/values/styles.xml index 59da8156..2573c80 100644 --- a/chrome/android/java/res/values/styles.xml +++ b/chrome/android/java/res/values/styles.xml
@@ -227,6 +227,14 @@ </style> <!-- First Run Experience --> + <!-- Avoid using @font/accent_font, a downloaded font, on text that could appear in the first + couple of frames of app start. It may not be ready yet, see https://crbug.com/1119990 --> + <style name="TextAppearance.FreFirstFrameTitle" parent="TextAppearance.Headline.Primary" > + <item name="android:fontFamily">sans-serif</item> + </style> + <style name="TextAppearance.FreFirstFrameButton" parent="TextAppearance.Button.Text.Filled"> + <item name="android:fontFamily">sans-serif</item> + </style> <style name="FreTitle"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> @@ -234,6 +242,12 @@ <item name="android:lineSpacingMultiplier">1.4</item> <item name="android:textAppearance">@style/TextAppearance.Headline.Primary</item> </style> + <style name="FreWelcomePageTitle" parent="FreTitle"> + <item name="android:textAppearance">@style/TextAppearance.FreFirstFrameTitle</item> + </style> + <style name="FreAcceptTosButton" parent="FilledButton.Flat"> + <item name="android:textAppearance">@style/TextAppearance.FreFirstFrameButton</item> + </style> <!-- Web Notifications --> <style name="TextAppearance.Notification" @@ -364,10 +378,6 @@ parent="TextAppearance.TextLarge.Primary"> <item name="android:textStyle">bold</item> </style> - <style name="TextAppearance.PaymentRequestErrorText"> - <item name="android:textColor">@color/default_text_color_error</item> - <item name="android:textSize">@dimen/text_size_large</item> - </style> <!-- Autofill Card --> <style name="TextAppearance.AutofillCardErrorMessage"> @@ -505,11 +515,6 @@ <item name="android:textColor">?android:attr/textColorPrimary</item> </style> - <!-- New Tab Page --> - <style name="NewTabPageRecyclerView"> - <item name="android:colorEdgeEffect" tools:targetApi="21">@color/modern_grey_300</item> - </style> - <!-- Use style="..." for the following search box style as textColorHint can not use android:textAppearance="...". textColorHint is defined in a parent theme therefore can not be overridden by appearance. @@ -603,12 +608,6 @@ </style> <!-- Omnibox suggestions --> - <!-- TODO(mdjones): Use unified styles for omnibox suggestions: crbug.com/915785 --> - <style name="TextAppearance.OmniboxSuggestionSecondLine"> - <item name="android:textSize">@dimen/omnibox_suggestion_second_line_text_size</item> - <item name="android:textColor">@color/suggestion_url_dark_modern</item> - </style> - <style name="TextAppearance.OmniboxAnswerDescriptionNegativeSmall"> <item name="android:textSize">@dimen/text_size_small</item> <item name="android:textColor">@color/answers_description_text_negative</item> @@ -619,13 +618,6 @@ <item name="android:textColor">@color/answers_description_text_positive</item> </style> - <style name="OmniboxSuggestionIconButton"> - <item name="android:background">?attr/selectableItemBackground</item> - <item name="android:layout_width">@dimen/min_touch_target_size</item> - <item name="android:layout_height">@dimen/omnibox_suggestion_comfortable_height</item> - <item name="tint">@color/default_icon_color</item> - </style> - <style name="OmniboxIcon" parent="LocationBarButton"> <item name="android:layout_width">@dimen/location_bar_start_icon_width</item> <item name="android:layout_height">match_parent</item>
diff --git a/chrome/android/java/res/xml/main_preferences.xml b/chrome/android/java/res/xml/main_preferences.xml index 6398570f..659b46d 100644 --- a/chrome/android/java/res/xml/main_preferences.xml +++ b/chrome/android/java/res/xml/main_preferences.xml
@@ -34,11 +34,13 @@ <org.chromium.components.browser_ui.settings.ChromeBasePreference android:key="manage_sync" android:order="5" + android:layout="@layout/account_management_account_row" android:title="@string/sync_category_title" app:isPreferenceVisible="false"/> <org.chromium.components.browser_ui.settings.ChromeBasePreference android:key="google_services" android:order="6" + android:layout="@layout/account_management_account_row" android:title="@string/prefs_google_services" android:icon="@drawable/ic_google_services_48dp" android:fragment="org.chromium.chrome.browser.sync.settings.GoogleServicesSettings"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index b31e321..1e8697a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -561,8 +561,9 @@ } } mLayoutManager = new LayoutManagerChromePhone(compositorViewHolder, mContentContainer, - mStartSurface, getTabContentManagerSupplier(), mOverviewModeBehaviorSupplier); + mStartSurface, getTabContentManagerSupplier()); mOverviewModeController = mLayoutManager; + mOverviewModeBehaviorSupplier.set(mOverviewModeController); } } @@ -571,10 +572,10 @@ try (TraceEvent e = TraceEvent.scoped( "ChromeTabbedActivity.setupCompositorContentPreNativeForTablet")) { - mLayoutManager = - new LayoutManagerChromeTablet(getCompositorViewHolder(), mContentContainer, - getTabContentManagerSupplier(), mOverviewModeBehaviorSupplier); + mLayoutManager = new LayoutManagerChromeTablet( + getCompositorViewHolder(), mContentContainer, getTabContentManagerSupplier()); mOverviewModeController = mLayoutManager; + mOverviewModeBehaviorSupplier.set(mOverviewModeController); } } @@ -838,7 +839,7 @@ if (!mPendingInitialTabCreation && !(TabUiFeatureUtilities.supportInstantStart(isTablet()) && shouldShowTabSwitcherOnStart())) { - setInitialOverviewState(); + setInitialOverviewStateAsync(); } if (TabUiFeatureUtilities.isConditionalTabStripEnabled() @@ -915,7 +916,14 @@ } } - private void setInitialOverviewState() { + // Posts a call to setInitialOverviewStateSync that will trigger after observers of + // mOverviewModeBehaviorSupplier have a chance to process the supplied OverviewModeBehavior and + // add themselves as observers. + private void setInitialOverviewStateAsync() { + mOverviewModeBehaviorSupplier.onAvailable((unused) -> setInitalOverviewStateSync()); + } + + private void setInitalOverviewStateSync() { boolean isOverviewVisible = mOverviewModeController.overviewVisible(); if (shouldShowTabSwitcherOnStart() && !isOverviewVisible) { @@ -1127,7 +1135,7 @@ if (hasStartWithNativeBeenCalled() && !(TabUiFeatureUtilities.supportInstantStart(isTablet()) && shouldShowTabSwitcherOnStart())) { - setInitialOverviewState(); + setInitialOverviewStateAsync(); } } @@ -1512,7 +1520,7 @@ if (shouldShowTabSwitcherOnStart()) { mLayoutManager.setTabModelSelector(mTabModelSelectorImpl); mIsAccessibilityTabSwitcherEnabled = DeviceClassManager.enableAccessibilityLayout(); - setInitialOverviewState(); + setInitialOverviewStateAsync(); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java index a58cbf1..183a2ab 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java
@@ -14,6 +14,7 @@ import org.chromium.chrome.browser.ChromeApplication; import org.chromium.chrome.browser.customtabs.CustomTabsConnection; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; +import org.chromium.webapk.lib.common.WebApkConstants; /** * Launched by Trusted Web Activity apps when the user clears data. @@ -28,11 +29,14 @@ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - launchSettings(); + + String urlToLaunchSettingsFor = getIntent().getData().toString(); + boolean isWebApk = getIntent().getBooleanExtra(WebApkConstants.EXTRA_IS_WEBAPK, false); + launchSettings(urlToLaunchSettingsFor, isWebApk); finish(); } - private void launchSettings() { + private void launchSettings(@Nullable String urlToLaunchSettingsFor, boolean isWebApk) { String packageName = getClientPackageName(); if (packageName == null) { logNoPackageName(); @@ -41,7 +45,13 @@ } new TrustedWebActivityUmaRecorder(ChromeBrowserInitializer.getInstance()) .recordOpenedSettingsViaManageSpace(); - TrustedWebActivitySettingsLauncher.launchForPackageName(this, packageName); + + if (isWebApk) { + TrustedWebActivitySettingsLauncher.launchForWebApkPackageName( + this, packageName, urlToLaunchSettingsFor); + } else { + TrustedWebActivitySettingsLauncher.launchForPackageName(this, packageName); + } } @Nullable
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivitySettingsLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivitySettingsLauncher.java index 8e31acf4..59bb8a5b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivitySettingsLauncher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivitySettingsLauncher.java
@@ -13,10 +13,12 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.settings.SettingsLauncher; import org.chromium.chrome.browser.settings.SettingsLauncherImpl; +import org.chromium.chrome.browser.webapps.ChromeWebApkHost; import org.chromium.components.browser_ui.site_settings.AllSiteSettings; import org.chromium.components.browser_ui.site_settings.SettingsNavigationSource; import org.chromium.components.browser_ui.site_settings.SingleWebsiteSettings; import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory; +import org.chromium.components.webapk.lib.client.WebApkValidator; import java.util.ArrayList; import java.util.Collection; @@ -33,13 +35,8 @@ * able to work with each of them. */ public static void launchForPackageName(Context context, String packageName) { - int applicationUid; - try { - applicationUid = context.getPackageManager().getApplicationInfo(packageName, 0).uid; - } catch (PackageManager.NameNotFoundException e) { - Log.d(TAG, "Package " + packageName + " not found"); - return; - } + Integer applicationUid = getApplicationUid(context, packageName); + if (applicationUid == null) return; ClientAppDataRegister register = new ClientAppDataRegister(); Collection<String> domains = register.getDomainsForRegisteredUid(applicationUid); @@ -52,6 +49,33 @@ } /** + * Launches site-settings for a WebApk with a given package name and associated url. + */ + public static void launchForWebApkPackageName( + Context context, String packageName, String webApkUrl) { + if (!WebApkValidator.canWebApkHandleUrl(context, packageName, webApkUrl)) { + Log.d(TAG, "WebApk " + packageName + " can't handle url " + webApkUrl); + return; + } + if (getApplicationUid(context, packageName) == null) return; + + // Handle the case when settings are selected but Chrome was not running. + ChromeWebApkHost.init(); + openSingleWebsitePrefs(context, webApkUrl); + } + + private static Integer getApplicationUid(Context context, String packageName) { + int applicationUid; + try { + applicationUid = context.getPackageManager().getApplicationInfo(packageName, 0).uid; + } catch (PackageManager.NameNotFoundException e) { + Log.d(TAG, "Package " + packageName + " not found"); + return null; + } + return applicationUid; + } + + /** * Same as above, but with list of associated origins and domains already retrieved. */ public static void launch(Context context, Collection<String> origins,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java index 17b939d6..90225ac8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -14,7 +14,6 @@ import org.chromium.base.ObserverList; import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.supplier.ObservableSupplier; -import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; @@ -77,7 +76,6 @@ private boolean mCreateOverviewLayout; protected ObservableSupplier<TabContentManager> mTabContentManagerSupplier; - private final OneshotSupplierImpl<OverviewModeBehavior> mOverviewModeBehaviorSupplier; /** * Creates the {@link LayoutManagerChrome} instance. @@ -89,8 +87,7 @@ */ public LayoutManagerChrome(LayoutManagerHost host, ViewGroup contentContainer, boolean createOverviewLayout, @Nullable StartSurface startSurface, - ObservableSupplier<TabContentManager> tabContentManagerSupplier, - OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier) { + ObservableSupplier<TabContentManager> tabContentManagerSupplier) { super(host, contentContainer, tabContentManagerSupplier); Context context = host.getContext(); LayoutRenderHost renderHost = host.getLayoutRenderHost(); @@ -122,8 +119,10 @@ @Override public void onStateChanged(@OverviewModeState int overviewModeState, boolean shouldShowTabSwitcherToolbar) { - notifyObserversStateChanged( - overviewModeState, shouldShowTabSwitcherToolbar); + for (OverviewModeObserver observer : mOverviewModeObservers) { + observer.onOverviewModeStateChanged( + overviewModeState, shouldShowTabSwitcherToolbar); + } } }); final ObservableSupplier<? extends BrowserControlsStateProvider> @@ -135,9 +134,6 @@ mCreateOverviewLayout = true; } } - - mOverviewModeBehaviorSupplier = overviewModeBehaviorSupplier; - mOverviewModeBehaviorSupplier.set(this); } /** @@ -282,7 +278,9 @@ if (isOverviewLayout(layoutBeingShown)) { boolean showToolbar = animate && (!mEnableAnimations || getTabModelSelector().getCurrentModel().getCount() <= 0); - notifyObserversStartedShowing(showToolbar); + for (OverviewModeObserver observer : mOverviewModeObservers) { + observer.onOverviewModeStartedShowing(showToolbar); + } } } @@ -300,7 +298,9 @@ boolean creatingNtp = layoutBeingHidden == mOverviewLayout && mCreatingNtp; - notifyObserversStartedHiding(showToolbar, creatingNtp); + for (OverviewModeObserver observer : mOverviewModeObservers) { + observer.onOverviewModeStartedHiding(showToolbar, creatingNtp); + } } } @@ -309,7 +309,9 @@ super.doneShowing(); if (isOverviewLayout(getActiveLayout())) { - notifyObserversFinishedShowing(); + for (OverviewModeObserver observer : mOverviewModeObservers) { + observer.onOverviewModeFinishedShowing(); + } } } @@ -325,7 +327,9 @@ super.doneHiding(); if (isOverviewLayout(layoutBeingHidden)) { - notifyObserversFinishedHiding(); + for (OverviewModeObserver observer : mOverviewModeObservers) { + observer.onOverviewModeFinishedHiding(); + } } } @@ -592,46 +596,4 @@ .closeTab(lastTab, tab, false, false, false); } } - - private void notifyObserversStartedShowing(boolean showToolbar) { - mOverviewModeBehaviorSupplier.onAvailable((unused) -> { - for (OverviewModeObserver overviewModeObserver : mOverviewModeObservers) { - overviewModeObserver.onOverviewModeStartedShowing(showToolbar); - } - }); - } - - private void notifyObserversFinishedShowing() { - mOverviewModeBehaviorSupplier.onAvailable((unused) -> { - for (OverviewModeObserver overviewModeObserver : mOverviewModeObservers) { - overviewModeObserver.onOverviewModeFinishedShowing(); - } - }); - } - - private void notifyObserversStartedHiding(boolean showToolbar, boolean creatingNtp) { - mOverviewModeBehaviorSupplier.onAvailable((unused) -> { - for (OverviewModeObserver overviewModeObserver : mOverviewModeObservers) { - overviewModeObserver.onOverviewModeStartedHiding(showToolbar, creatingNtp); - } - }); - } - - private void notifyObserversFinishedHiding() { - mOverviewModeBehaviorSupplier.onAvailable((unused) -> { - for (OverviewModeObserver overviewModeObserver : mOverviewModeObservers) { - overviewModeObserver.onOverviewModeFinishedHiding(); - } - }); - } - - private void notifyObserversStateChanged( - @OverviewModeState int overviewModeState, boolean shouldShowTabSwitcherToolbar) { - mOverviewModeBehaviorSupplier.onAvailable((unused) -> { - for (OverviewModeObserver overviewModeObserver : mOverviewModeObservers) { - overviewModeObserver.onOverviewModeStateChanged( - overviewModeState, shouldShowTabSwitcherToolbar); - } - }); - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java index dd6da30..96432f40 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java
@@ -8,7 +8,6 @@ import android.view.ViewGroup; import org.chromium.base.supplier.ObservableSupplier; -import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.compositor.layouts.phone.SimpleAnimationLayout; @@ -42,10 +41,8 @@ */ public LayoutManagerChromePhone(LayoutManagerHost host, ViewGroup contentContainer, StartSurface startSurface, - ObservableSupplier<TabContentManager> tabContentManagerSupplier, - OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier) { - super(host, contentContainer, true, startSurface, tabContentManagerSupplier, - overviewModeBehaviorSupplier); + ObservableSupplier<TabContentManager> tabContentManagerSupplier) { + super(host, contentContainer, true, startSurface, tabContentManagerSupplier); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java index 0070bf2..4786a436 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
@@ -7,7 +7,6 @@ import android.view.ViewGroup; import org.chromium.base.supplier.ObservableSupplier; -import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.chrome.R; import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; @@ -38,10 +37,8 @@ * @param tabContentManagerSupplier Supplier of the {@link TabContentManager} instance. */ public LayoutManagerChromeTablet(LayoutManagerHost host, ViewGroup contentContainer, - ObservableSupplier<TabContentManager> tabContentManagerSupplier, - OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier) { - super(host, contentContainer, false, null, tabContentManagerSupplier, - overviewModeBehaviorSupplier); + ObservableSupplier<TabContentManager> tabContentManagerSupplier) { + super(host, contentContainer, false, null, tabContentManagerSupplier); mTabStripLayoutHelperManager = new StripLayoutHelperManager( host.getContext(), this, mHost.getLayoutRenderHost(), () -> mTitleCache);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesTileView.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesTileView.java index 0cdb47c..2a503ad 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesTileView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesTileView.java
@@ -16,13 +16,13 @@ import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import org.chromium.chrome.R; -import org.chromium.chrome.browser.suggestions.tile.TileWithTextView; +import org.chromium.chrome.browser.suggestions.tile.TileView; import org.chromium.components.browser_ui.widget.RoundedIconGenerator; /** * View for a category name and site tiles. */ -public class ExploreSitesTileView extends TileWithTextView { +public class ExploreSitesTileView extends TileView { private static final int TITLE_LINES = 2; private final int mIconCornerRadius;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java index 099e075..afce66f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java
@@ -124,6 +124,8 @@ return "3G"; case ConnectionType.CONNECTION_4G: return "4G"; + case ConnectionType.CONNECTION_5G: + return "5G"; case ConnectionType.CONNECTION_NONE: return "NONE"; case ConnectionType.CONNECTION_BLUETOOTH:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDataCache.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDataCache.java index 52860b0..0a481ee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDataCache.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDataCache.java
@@ -197,8 +197,8 @@ ThreadUtils.assertOnUiThread(); if (mObservers.isEmpty()) { if (mProfileDataSource != null) { - updateCacheFromProfileDataSource(); mProfileDataSource.addObserver(this); + updateCacheFromProfileDataSource(); } else { ProfileDownloader.addObserver(this); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/SuggestionsTileView.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/SuggestionsTileView.java index 9f0358b4..3c58c38 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/SuggestionsTileView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/SuggestionsTileView.java
@@ -16,7 +16,7 @@ * The view for a site suggestion tile. Displays the title of the site beneath a large icon. If a * large icon isn't available, displays a rounded rectangle with a single letter in its place. */ -public class SuggestionsTileView extends TileWithTextView { +public class SuggestionsTileView extends TileView { /** The data currently associated to this tile. */ private SiteSuggestion mData;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileView.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileView.java index 68d274c..5de8426a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileView.java
@@ -9,6 +9,7 @@ import android.util.AttributeSet; import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.TextView; import org.chromium.chrome.R; @@ -19,6 +20,7 @@ */ public class TileView extends FrameLayout { private ImageView mBadgeView; + private TextView mTitleView; protected ImageView mIconView; /** @@ -34,17 +36,21 @@ mIconView = findViewById(R.id.tile_view_icon); mBadgeView = findViewById(R.id.offline_badge); + mTitleView = findViewById(R.id.tile_view_title); } /** - * Initializes the view. This should be called immediately after inflation. + * Initializes the view. Non-MVC components should call this immediately after inflation. * + * @param title The title of the tile. * @param showOfflineBadge Whether to show the offline badge. * @param icon The icon to display on the tile. + * @param titleLines The number of text lines to use for the tile title. */ - public void initialize(boolean showOfflineBadge, Drawable icon) { + void initialize(String title, boolean showOfflineBadge, Drawable icon, int titleLines) { setOfflineBadgeVisibility(showOfflineBadge); setIconDrawable(icon); + setTitle(title, titleLines); } /** @@ -55,7 +61,13 @@ } /** Shows or hides the offline badge to reflect the offline availability. */ - public void setOfflineBadgeVisibility(boolean showOfflineBadge) { + void setOfflineBadgeVisibility(boolean showOfflineBadge) { mBadgeView.setVisibility(showOfflineBadge ? VISIBLE : GONE); } + + /** Sets the title text and number lines. */ + public void setTitle(String title, int titleLines) { + mTitleView.setLines(titleLines); + mTitleView.setText(title); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileViewBinder.java new file mode 100644 index 0000000..94d888c --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileViewBinder.java
@@ -0,0 +1,55 @@ +// Copyright 2020 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.chrome.browser.suggestions.tile; + +import android.view.View; +import android.view.ViewGroup.MarginLayoutParams; +import android.widget.ImageView; +import android.widget.TextView; + +import org.chromium.chrome.R; +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; + +/** Binder wiring for the TileView. */ +public class TileViewBinder { + /** @see PropertyModelChangeProcessor.ViewBinder#bind(Object, Object, Object) */ + public static void bind(PropertyModel model, TileView view, PropertyKey propertyKey) { + if (propertyKey == TileViewProperties.TITLE) { + final TextView textView = view.findViewById(R.id.tile_view_title); + textView.setText(model.get(TileViewProperties.TITLE)); + } else if (propertyKey == TileViewProperties.TITLE_LINES) { + final TextView textView = view.findViewById(R.id.tile_view_title); + textView.setLines(model.get(TileViewProperties.TITLE_LINES)); + } else if (propertyKey == TileViewProperties.ICON) { + final ImageView iconView = view.findViewById(R.id.tile_view_icon); + iconView.setImageDrawable(model.get(TileViewProperties.ICON)); + } else if (propertyKey == TileViewProperties.BADGE_VISIBLE) { + final View badgeView = view.findViewById(R.id.offline_badge); + final boolean isVisible = model.get(TileViewProperties.BADGE_VISIBLE); + badgeView.setVisibility(isVisible ? View.VISIBLE : View.GONE); + } else if (propertyKey == TileViewProperties.SHOW_LARGE_ICON) { + final boolean useLargeIcon = model.get(TileViewProperties.SHOW_LARGE_ICON); + final int iconEdgeSize = view.getResources().getDimensionPixelSize(useLargeIcon + ? R.dimen.tile_view_icon_size + : R.dimen.tile_view_icon_size_modern); + final int iconTopMarginSize = view.getResources().getDimensionPixelOffset(useLargeIcon + ? R.dimen.tile_view_icon_background_margin_top_modern + : R.dimen.tile_view_icon_margin_top_modern); + final View iconView = view.findViewById(R.id.tile_view_icon); + final MarginLayoutParams params = (MarginLayoutParams) iconView.getLayoutParams(); + params.width = iconEdgeSize; + params.height = iconEdgeSize; + params.topMargin = iconTopMarginSize; + iconView.setLayoutParams(params); + } else if (propertyKey == TileViewProperties.ON_CLICK) { + view.setOnClickListener(model.get(TileViewProperties.ON_CLICK)); + } else if (propertyKey == TileViewProperties.ON_LONG_CLICK) { + view.setOnLongClickListener(model.get(TileViewProperties.ON_LONG_CLICK)); + } else if (propertyKey == TileViewProperties.ON_CREATE_CONTEXT_MENU) { + view.setOnCreateContextMenuListener( + model.get(TileViewProperties.ON_CREATE_CONTEXT_MENU)); + } + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileViewCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileViewCoordinator.java new file mode 100644 index 0000000..2e5296c5 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileViewCoordinator.java
@@ -0,0 +1,103 @@ +// Copyright 2020 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.chrome.browser.suggestions.tile; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.LayoutRes; + +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyModelChangeProcessor; + +/** + * Coordinator for the TileView. + */ +public class TileViewCoordinator { + private final TileView mView; + private final TileViewMediator mMediator; + + public TileViewCoordinator(Context context, @LayoutRes int tileLayoutRes, ViewGroup parent) { + mView = (TileView) LayoutInflater.from(context).inflate(tileLayoutRes, parent, false); + PropertyModel model = new PropertyModel(); + PropertyModelChangeProcessor.create(model, mView, TileViewBinder::bind); + mMediator = new TileViewMediator(model); + } + + /** + * Set the Tile Title. + * The title will be shown in at most TITLE_LINES lines. + * + * @param title Title to be displayed. + */ + public void setTitle(String title) { + mMediator.setTitle(title); + } + + /** + * Set the max number of lines for the TextView showing the TITLE. + * + * @param lines Maximum number of lines that can be used to present the Title. + */ + public void setTitleLines(int lines) { + mMediator.setTitleLines(lines); + } + + /** + * Set the Tile Icon. + * + * @param icon Icon to show within the tile. + */ + public void setIcon(Drawable icon) { + mMediator.setIcon(icon); + } + + /** + * Set whether the Icon Badge should be visible. + * + * @param badgeVisible Whether icon badge should be visible. + */ + public void setBadgeVisible(boolean badgeVisible) { + mMediator.setBadgeVisible(badgeVisible); + } + + /** + * Set whether Tile should present a large Icon. + * + * @param showLargeIcon Whether Tile Icon should be large. + */ + public void setShowLargeIcon(boolean showLargeIcon) { + mMediator.setShowLargeIcon(showLargeIcon); + } + + /** + * Set the handler receiving click events. + * + * @param listener Handler receiving click events. + */ + public void setOnClickListener(View.OnClickListener listener) { + mMediator.setOnClickListener(listener); + } + + /** + * Set the handler receiving long click events. + * + * @param listener Handler receiving long click events. + */ + public void setOnLongClickListener(View.OnLongClickListener listener) { + mMediator.setOnLongClickListener(listener); + } + + /** + * Set the handler receiving context menu create events. + * + * @param listener Handler receiving context menu create events. + */ + public void setOnCreateContextMenuListener(View.OnCreateContextMenuListener listener) { + mMediator.setOnCreateContextMenuListener(listener); + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileViewMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileViewMediator.java new file mode 100644 index 0000000..a85f297 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileViewMediator.java
@@ -0,0 +1,96 @@ +// Copyright 2020 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.chrome.browser.suggestions.tile; + +import android.graphics.drawable.Drawable; +import android.view.View; + +import org.chromium.ui.modelutil.PropertyModel; + +/** + * Mediator for the TileView. + */ +class TileViewMediator { + private final PropertyModel mModel; + + /** + * Create new TileViewMediator object. + */ + TileViewMediator(PropertyModel model) { + mModel = model; + } + + /** + * Set the Tile Title. + * The title will be shown in at most TITLE_LINES lines. + * + * @param title Title to be displayed. + */ + void setTitle(String title) { + mModel.set(TileViewProperties.TITLE, title); + } + + /** + * Set the max number of lines for the TextView showing the TITLE. + * + * @param lines Maximum number of lines that can be used to present the Title. + */ + void setTitleLines(int lines) { + mModel.set(TileViewProperties.TITLE_LINES, lines); + } + + /** + * Set the Tile Icon. + * + * @param icon Icon to show within the tile. + */ + void setIcon(Drawable icon) { + mModel.set(TileViewProperties.ICON, icon); + } + + /** + * Set whether the Icon Badge should be visible. + * + * @param badgeVisible Whether icon badge should be visible. + */ + void setBadgeVisible(boolean badgeVisible) { + mModel.set(TileViewProperties.BADGE_VISIBLE, badgeVisible); + } + + /** + * Set whether Tile should present a large Icon. + * + * @param showLargeIcon Whether Tile Icon should be large. + */ + void setShowLargeIcon(boolean showLargeIcon) { + mModel.set(TileViewProperties.SHOW_LARGE_ICON, showLargeIcon); + } + + /** + * Set the handler receiving click events. + * + * @param listener Handler receiving click events. + */ + void setOnClickListener(View.OnClickListener listener) { + mModel.set(TileViewProperties.ON_CLICK, listener); + } + + /** + * Set the handler receiving long click events. + * + * @param listener Handler receiving long click events. + */ + void setOnLongClickListener(View.OnLongClickListener listener) { + mModel.set(TileViewProperties.ON_LONG_CLICK, listener); + } + + /** + * Set the handler receiving context menu create events. + * + * @param listener Handler receiving context menu create events. + */ + void setOnCreateContextMenuListener(View.OnCreateContextMenuListener listener) { + mModel.set(TileViewProperties.ON_CREATE_CONTEXT_MENU, listener); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileViewProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileViewProperties.java new file mode 100644 index 0000000..11d52c1c --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileViewProperties.java
@@ -0,0 +1,47 @@ +// Copyright 2020 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.chrome.browser.suggestions.tile; + +import android.graphics.drawable.Drawable; +import android.view.View; + +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableIntPropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey; + +/** TileView properties. */ +final class TileViewProperties { + /** The title of the tile. */ + public static final WritableObjectPropertyKey<String> TITLE = new WritableObjectPropertyKey<>(); + + /** Maximum number of lines used to present the title. */ + public static final WritableIntPropertyKey TITLE_LINES = new WritableIntPropertyKey(); + + /** The primary icon used by the tile. */ + public static final WritableObjectPropertyKey<Drawable> ICON = + new WritableObjectPropertyKey<>(); + + /** Whether Tile should present a large icon. */ + public static final WritableBooleanPropertyKey SHOW_LARGE_ICON = + new WritableBooleanPropertyKey(); + + /** Badge visibility. */ + public static final WritableBooleanPropertyKey BADGE_VISIBLE = new WritableBooleanPropertyKey(); + + /** Handler receiving click events. */ + public static final WritableObjectPropertyKey<View.OnClickListener> ON_CLICK = + new WritableObjectPropertyKey<>(); + + /** Handler receiving long-click events. */ + public static final WritableObjectPropertyKey<View.OnLongClickListener> ON_LONG_CLICK = + new WritableObjectPropertyKey<>(); + + /** Handler receiving context menu call events. */ + public static final WritableObjectPropertyKey<View.OnCreateContextMenuListener> + ON_CREATE_CONTEXT_MENU = new WritableObjectPropertyKey<>(); + + public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {ICON, TITLE, TITLE_LINES, + BADGE_VISIBLE, SHOW_LARGE_ICON, ON_CLICK, ON_LONG_CLICK, ON_CREATE_CONTEXT_MENU}; +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileWithTextView.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileWithTextView.java deleted file mode 100644 index 2a7435a1..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileWithTextView.java +++ /dev/null
@@ -1,54 +0,0 @@ -// 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. - -package org.chromium.chrome.browser.suggestions.tile; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.widget.TextView; - -import org.chromium.chrome.R; - -/** - * The view for a tile with icon and text. - * - * Displays the title of the site beneath a large icon. - */ -public class TileWithTextView extends TileView { - private TextView mTitleView; - - /** - * Constructor for inflating from XML. - */ - public TileWithTextView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - - mTitleView = findViewById(R.id.tile_view_title); - } - - /** - * Initializes the view. This should be called immediately after inflation. - * - * @param title The title of the tile. - * @param showOfflineBadge Whether to show the offline badge. - * @param icon The icon to display on the tile. - * @param titleLines The number of text lines to use for the tile title. - */ - public void initialize(String title, boolean showOfflineBadge, Drawable icon, int titleLines) { - super.initialize(showOfflineBadge, icon); - setTitle(title, titleLines); - } - - /** Sets the title text and number lines. */ - public void setTitle(String title, int titleLines) { - mTitleView.setLines(titleLines); - mTitleView.setText(title); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java index 5ae72ba..8f958b6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java
@@ -13,7 +13,6 @@ import android.os.UserManager; import androidx.annotation.Nullable; -import androidx.appcompat.content.res.AppCompatResources; import androidx.fragment.app.DialogFragment; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; @@ -309,11 +308,12 @@ private ChromeBasePreference createAddAccountPreference() { ChromeBasePreference addAccountPreference = new ChromeBasePreference(getStyledContext()); addAccountPreference.setLayoutResource(R.layout.account_management_account_row); - addAccountPreference.setIcon( - AppCompatResources.getDrawable(requireContext(), R.drawable.ic_add_circle_40dp)); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY)) { + addAccountPreference.setIcon(R.drawable.ic_person_add_40dp); addAccountPreference.setTitle(R.string.signin_add_account_to_device); } else { + addAccountPreference.setIcon(R.drawable.ic_add_circle_40dp); addAccountPreference.setTitle(R.string.account_management_add_account_title); } addAccountPreference.setOnPreferenceClickListener(preference -> {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java index 99b6c5a..c647d74 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java
@@ -25,7 +25,6 @@ import androidx.core.view.ViewCompat; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.ThemeColorProvider.TintObserver; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper.MenuButtonState; @@ -51,12 +50,10 @@ private boolean mHighlightingMenu; private PulseDrawable mHighlightDrawable; - private boolean mSuppressAppMenuUpdateBadge; private AnimatorSet mMenuBadgeAnimatorSet; private boolean mIsMenuBadgeAnimationRunning; /** A provider that notifies components when the theme color changes.*/ - private ThemeColorProvider mThemeColorProvider; private BitmapDrawable mMenuImageButtonAnimationDrawable; private BitmapDrawable mUpdateBadgeAnimationDrawable; @@ -98,7 +95,6 @@ if (mUpdateBadgeView == null) return; mUpdateBadgeView.setVisibility(visible ? View.VISIBLE : View.GONE); if (visible) updateImageResources(); - updateContentDescription(visible); } @Override @@ -147,14 +143,12 @@ * Show the update badge on the app menu button. * @param animate Whether to animate the showing of the update badge. */ - public void showAppMenuUpdateBadgeIfAvailable(boolean animate) { - if (mUpdateBadgeView == null || mMenuImageButton == null || mSuppressAppMenuUpdateBadge - || !isBadgeAvailable()) { + void showAppMenuUpdateBadge(boolean animate) { + if (mUpdateBadgeView == null || mMenuImageButton == null) { return; } updateImageResources(); - updateContentDescription(true); if (!animate || mIsMenuBadgeAnimationRunning) { setUpdateBadgeVisibility(true); return; @@ -190,9 +184,8 @@ * Remove the update badge on the app menu button. * @param animate Whether to animate the hiding of the update badge. */ - public void removeAppMenuUpdateBadge(boolean animate) { + void removeAppMenuUpdateBadge(boolean animate) { if (mUpdateBadgeView == null || !isShowingAppMenuUpdateBadge()) return; - updateContentDescription(false); if (!animate) { setUpdateBadgeVisibility(false); @@ -229,51 +222,21 @@ } /** - * @param suppress Whether to prevent the update badge from being show. This is currently only - * used to prevent the badge from being shown in the tablet tab switcher. - */ - public void setAppMenuUpdateBadgeSuppressed(boolean suppress) { - mSuppressAppMenuUpdateBadge = suppress; - if (mSuppressAppMenuUpdateBadge) { - removeAppMenuUpdateBadge(false); - } else { - showAppMenuUpdateBadgeIfAvailable(false); - } - } - - /** * @return Whether the update badge is showing. */ - public boolean isShowingAppMenuUpdateBadge() { + boolean isShowingAppMenuUpdateBadge() { return mUpdateBadgeView != null && mUpdateBadgeView.getVisibility() == View.VISIBLE; } - private static boolean isBadgeAvailable() { - return UpdateMenuItemHelper.getInstance().getUiState().buttonState != null; - } - - /** - * Sets the content description for the menu button. - * @param isUpdateBadgeVisible Whether the update menu badge is visible. - */ - private void updateContentDescription(boolean isUpdateBadgeVisible) { - if (isUpdateBadgeVisible) { - MenuButtonState buttonState = - UpdateMenuItemHelper.getInstance().getUiState().buttonState; - assert buttonState != null : "No button state when trying to show the badge."; - mMenuImageButton.setContentDescription( - getResources().getString(buttonState.menuContentDescription)); - } else { - mMenuImageButton.setContentDescription( - getResources().getString(R.string.accessibility_toolbar_btn_menu)); - } + void updateContentDescription(String description) { + mMenuImageButton.setContentDescription(description); } /** * Sets the menu button's background depending on whether or not we are highlighting and whether * or not we are using light or dark assets. */ - public void setMenuButtonHighlightDrawable() { + private void updateMenuButtonHighlightDrawable() { // Return if onFinishInflate didn't finish if (mMenuImageButton == null) return; @@ -294,15 +257,9 @@ } } - public void setMenuButtonHighlight(boolean highlight) { + void setMenuButtonHighlight(boolean highlight) { mHighlightingMenu = highlight; - setMenuButtonHighlightDrawable(); - } - - public void setThemeColorProvider(ThemeColorProvider themeColorProvider) { - mThemeColorProvider = themeColorProvider; - mThemeColorProvider.addTintObserver(this); - onTintChanged(themeColorProvider.getTint(), themeColorProvider.useLight()); + updateMenuButtonHighlightDrawable(); } /** @@ -322,13 +279,7 @@ ApiCompatibilityUtils.setImageTintList(mMenuImageButton, tintList); mUseLightDrawables = useLight; updateImageResources(); - } - - public void destroy() { - if (mThemeColorProvider != null) { - mThemeColorProvider.removeTintObserver(this); - mThemeColorProvider = null; - } + updateMenuButtonHighlightDrawable(); } @VisibleForTesting
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java index 3e2ce39..3b57b8e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java
@@ -5,54 +5,39 @@ package org.chromium.chrome.browser.toolbar.menu_button; import android.app.Activity; -import android.content.res.ColorStateList; import android.view.View.OnKeyListener; + import androidx.annotation.IdRes; import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; -import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.base.metrics.RecordUserAction; + import org.chromium.base.supplier.ObservableSupplier; -import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.OneshotSupplier; import org.chromium.base.supplier.Supplier; -import org.chromium.chrome.R; import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; -import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; -import org.chromium.chrome.browser.omnibox.LocationBar; +import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ShowBadgeProperty; +import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ThemeProperty; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator; -import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler; -import org.chromium.chrome.browser.ui.appmenu.AppMenuObserver; -import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate; import org.chromium.ui.UiUtils; -import org.chromium.ui.util.TokenHolder; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyModelChangeProcessor; /** * Root component for the app menu button on the toolbar. Owns the MenuButton view and handles * changes to its visual state, e.g. showing/hiding the app update badge. */ -public class MenuButtonCoordinator implements AppMenuObserver { +public class MenuButtonCoordinator { public interface SetFocusFunction { void setFocus(boolean focus, int reason); } - private @Nullable AppMenuPropertiesDelegate mAppMenuPropertiesDelegate; - private AppMenuButtonHelper mAppMenuButtonHelper; - private ObservableSupplierImpl<AppMenuButtonHelper> mAppMenuButtonHelperSupplier; - private AppMenuHandler mAppMenuHandler; - private final BrowserStateBrowserControlsVisibilityDelegate mControlsVisibilityDelegate; private final Activity mActivity; - private int mFullscreenMenuToken = TokenHolder.INVALID_TOKEN; - private int mFullscreenHighlightToken = TokenHolder.INVALID_TOKEN; - private final SetFocusFunction mSetUrlBarFocusFunction; - private Runnable mRequestRenderRunnable; - private Runnable mUpdateStateChangedListener; - private final boolean mShouldShowAppUpdateBadge; - private Supplier<Boolean> mIsInOverviewModeSupplier; - private ThemeColorProvider mThemeColorProvider; + private final PropertyModel mPropertyModel; + private MenuButtonMediator mMediator; + private AppMenuButtonHelper mAppMenuButtonHelper; private MenuButton mMenuButton; + private PropertyModelChangeProcessor mChangeProcessor; /** * @param appMenuCoordinatorSupplier Supplier for the AppMenuCoordinator, which owns all other @@ -75,18 +60,27 @@ Runnable requestRenderRunnable, boolean shouldShowAppUpdateBadge, Supplier<Boolean> isInOverviewModeSupplier, ThemeColorProvider themeColorProvider, @IdRes int menuButtonId) { - mControlsVisibilityDelegate = controlsVisibilityDelegate; mActivity = activity; - mSetUrlBarFocusFunction = setUrlBarFocusFunction; - appMenuCoordinatorSupplier.onAvailable(this::onAppMenuInitialized); - mRequestRenderRunnable = requestRenderRunnable; - mShouldShowAppUpdateBadge = shouldShowAppUpdateBadge; - mIsInOverviewModeSupplier = isInOverviewModeSupplier; mMenuButton = mActivity.findViewById(menuButtonId); - mAppMenuButtonHelperSupplier = new ObservableSupplierImpl<>(); - mThemeColorProvider = themeColorProvider; + mPropertyModel = new PropertyModel.Builder(MenuButtonProperties.ALL_KEYS) + .with(MenuButtonProperties.SHOW_UPDATE_BADGE, + new ShowBadgeProperty(false, false)) + .with(MenuButtonProperties.THEME, + new ThemeProperty(themeColorProvider.getTint(), + themeColorProvider.useLight())) + .with(MenuButtonProperties.IS_VISIBLE, true) + .build(); + mMediator = new MenuButtonMediator(mPropertyModel, shouldShowAppUpdateBadge, + () + -> mActivity.isFinishing() || mActivity.isDestroyed(), + requestRenderRunnable, themeColorProvider, isInOverviewModeSupplier, + controlsVisibilityDelegate, setUrlBarFocusFunction, appMenuCoordinatorSupplier, + mActivity.getResources()); + mMediator.getMenuButtonHelperSupplier().addObserver( + (helper) -> mAppMenuButtonHelper = helper); if (mMenuButton != null) { - mMenuButton.setThemeColorProvider(themeColorProvider); + mChangeProcessor = PropertyModelChangeProcessor.create( + mPropertyModel, mMenuButton, new MenuButtonViewBinder()); } } @@ -96,11 +90,8 @@ * @param isLoading Whether the current page is loading. */ public void updateReloadingState(boolean isLoading) { - if (mMenuButton == null || mAppMenuPropertiesDelegate == null || mAppMenuHandler == null) { - return; - } - mAppMenuPropertiesDelegate.loadingStateChanged(isLoading); - mAppMenuHandler.menuItemContentChanged(R.id.icon_row_menu_id); + if (mMediator == null) return; + mMediator.updateReloadingState(isLoading); } /** @@ -122,10 +113,8 @@ assert mMenuButton == null; assert menuButton != null; mMenuButton = menuButton; - if (mAppMenuButtonHelper != null) { - mMenuButton.setAppMenuButtonHelper(mAppMenuButtonHelper); - } - mMenuButton.setThemeColorProvider(mThemeColorProvider); + mChangeProcessor = PropertyModelChangeProcessor.create( + mPropertyModel, menuButton, new MenuButtonViewBinder()); } /** @@ -153,23 +142,11 @@ } /** - * Set the tint list on the underlying MenuButton view. Present for legacy reasons only; don't - * add new usages. - */ - @Deprecated - public void setImageTintList(ColorStateList colorStateList) { - // TODO(https://crbug.com/1086676): Remove the need for these null checks and replace with - // an assert that the MenuButtonCoordinator isn't destroyed. - if (mMenuButton == null) return; - ApiCompatibilityUtils.setImageTintList(mMenuButton.getImageButton(), colorStateList); - } - - /** * @param isClickable Whether the underlying MenuButton view should be clickable. */ public void setClickable(boolean isClickable) { - if (mMenuButton == null) return; - mMenuButton.setClickable(isClickable); + if (mMediator == null) return; + mMediator.setClickable(isClickable); } /** @@ -182,20 +159,18 @@ } public void destroy() { - if (mAppMenuButtonHelper != null) { - mAppMenuHandler.removeObserver(this); - mAppMenuButtonHelper = null; + if (mMediator != null) { + mMediator.destroy(); + mMediator = null; } - if (mUpdateStateChangedListener != null) { - UpdateMenuItemHelper.getInstance().unregisterObserver(mUpdateStateChangedListener); - mUpdateStateChangedListener = null; + if (mChangeProcessor != null) { + mChangeProcessor.destroy(); + mChangeProcessor = null; } - if (mMenuButton != null) { - mMenuButton.destroy(); - mMenuButton = null; - } + mMenuButton = null; + mAppMenuButtonHelper = null; } /** @@ -203,15 +178,14 @@ * dependencies that require native, e.g. the UpdateMenuItemHelper. */ public void onNativeInitialized() { - if (mShouldShowAppUpdateBadge) { - mUpdateStateChangedListener = this::updateStateChanged; - UpdateMenuItemHelper.getInstance().registerObserver(mUpdateStateChangedListener); - } + if (mMediator == null) return; + mMediator.onNativeInitialized(); } @Nullable public ObservableSupplier<AppMenuButtonHelper> getMenuButtonHelperSupplier() { - return mAppMenuButtonHelperSupplier; + if (mMediator == null) return null; + return mMediator.getMenuButtonHelperSupplier(); } /** @@ -219,110 +193,17 @@ * @param isSuppressed */ public void setAppMenuUpdateBadgeSuppressed(boolean isSuppressed) { - if (mMenuButton == null) return; - mMenuButton.setAppMenuUpdateBadgeSuppressed(isSuppressed); + if (mMediator == null) return; + mMediator.setAppMenuUpdateBadgeSuppressed(isSuppressed); } /** * Set the visibility of the MenuButton controlled by this coordinator. - * @param visibility Visibility state flag, e.g. GONE or VISIBLE. + * @param visible Visibility state, true for visible and false for hidden. */ - public void setVisibility(int visibility) { - if (mMenuButton == null) return; - mMenuButton.setVisibility(visibility); - } - /** - * @see MenuButton#setMenuButtonHighlightDrawable(). - */ - public void setMenuButtonHighlightDrawable() { - if (mMenuButton == null) return; - mMenuButton.setMenuButtonHighlightDrawable(); - } - - @Override - public void onMenuVisibilityChanged(boolean isVisible) { - if (isVisible) { - // Defocus here to avoid handling focus in multiple places, e.g., when the - // forward button is pressed. (see crbug.com/414219) - mSetUrlBarFocusFunction.setFocus(false, LocationBar.OmniboxFocusReason.UNFOCUS); - - if (!mIsInOverviewModeSupplier.get() && isShowingAppMenuUpdateBadge()) { - // The app menu badge should be removed the first time the menu is opened. - mMenuButton.removeAppMenuUpdateBadge(true); - mRequestRenderRunnable.run(); - } - - mFullscreenMenuToken = - mControlsVisibilityDelegate.showControlsPersistentAndClearOldToken( - mFullscreenMenuToken); - } else { - mControlsVisibilityDelegate.releasePersistentShowingToken(mFullscreenMenuToken); - } - - if (isVisible && mMenuButton != null && mMenuButton.isShowingAppMenuUpdateBadge()) { - UpdateMenuItemHelper.getInstance().onMenuButtonClicked(); - } - } - - @Override - public void onMenuHighlightChanged(boolean isHighlighting) { - if (mMenuButton != null) { - mMenuButton.setMenuButtonHighlight(isHighlighting); - } - - if (isHighlighting) { - mFullscreenHighlightToken = - mControlsVisibilityDelegate.showControlsPersistentAndClearOldToken( - mFullscreenHighlightToken); - } else { - mControlsVisibilityDelegate.releasePersistentShowingToken(mFullscreenHighlightToken); - } - } - - /** - * Called when the app menu and related properties delegate are available. - * - * @param appMenuCoordinator The coordinator for interacting with the menu. - */ - private void onAppMenuInitialized(AppMenuCoordinator appMenuCoordinator) { - assert mAppMenuHandler == null; - AppMenuHandler appMenuHandler = appMenuCoordinator.getAppMenuHandler(); - - mAppMenuHandler = appMenuHandler; - mAppMenuHandler.addObserver(this); - mAppMenuButtonHelper = mAppMenuHandler.createAppMenuButtonHelper(); - mAppMenuButtonHelper.setOnAppMenuShownListener( - () -> { RecordUserAction.record("MobileToolbarShowMenu"); }); - if (mMenuButton != null) { - mMenuButton.setAppMenuButtonHelper(mAppMenuButtonHelper); - } - - mAppMenuButtonHelperSupplier.set(mAppMenuButtonHelper); - mAppMenuPropertiesDelegate = appMenuCoordinator.getAppMenuPropertiesDelegate(); - } - - /** - * @return Whether the badge is showing (either in the toolbar). - */ - private boolean isShowingAppMenuUpdateBadge() { - return mMenuButton != null && mMenuButton.isShowingAppMenuUpdateBadge(); - } - - @VisibleForTesting - void updateStateChanged() { - if (mMenuButton == null || mActivity.isFinishing() || mActivity.isDestroyed() - || !mShouldShowAppUpdateBadge) { - return; - } - - UpdateMenuItemHelper.MenuButtonState buttonState = - UpdateMenuItemHelper.getInstance().getUiState().buttonState; - if (buttonState != null) { - mMenuButton.showAppMenuUpdateBadgeIfAvailable(true); - mRequestRenderRunnable.run(); - } else { - mMenuButton.removeAppMenuUpdateBadge(false); - } + public void setVisibility(boolean visible) { + if (mMediator == null) return; + mMediator.setVisibility(visible); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediator.java new file mode 100644 index 0000000..80a88e52 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediator.java
@@ -0,0 +1,272 @@ +// Copyright 2020 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.chrome.browser.toolbar.menu_button; + +import android.content.res.ColorStateList; +import android.content.res.Resources; + +import androidx.annotation.Nullable; + +import org.chromium.base.Callback; +import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.base.supplier.OneshotSupplier; +import org.chromium.base.supplier.Supplier; +import org.chromium.chrome.browser.ThemeColorProvider; +import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; +import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; +import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper.MenuButtonState; +import org.chromium.chrome.browser.omnibox.LocationBar; +import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator.SetFocusFunction; +import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ShowBadgeProperty; +import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ThemeProperty; +import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; +import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator; +import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler; +import org.chromium.chrome.browser.ui.appmenu.AppMenuObserver; +import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.util.TokenHolder; + +/** + * Mediator for the MenuButton. Listens for MenuButton state changes and drives corresponding + * changes to the property model that backs the MenuButton view. + */ +class MenuButtonMediator implements AppMenuObserver { + private OneshotSupplier<AppMenuCoordinator> mAppMenuCoordinatorSupplier; + private Callback<AppMenuCoordinator> mAppMenuCoordinatorSupplierObserver; + private @Nullable AppMenuPropertiesDelegate mAppMenuPropertiesDelegate; + private AppMenuButtonHelper mAppMenuButtonHelper; + private ObservableSupplierImpl<AppMenuButtonHelper> mAppMenuButtonHelperSupplier; + private AppMenuHandler mAppMenuHandler; + private final BrowserStateBrowserControlsVisibilityDelegate mControlsVisibilityDelegate; + private final SetFocusFunction mSetUrlBarFocusFunction; + private final PropertyModel mPropertyModel; + private final Runnable mRequestRenderRunnable; + private final ThemeColorProvider mThemeColorProvider; + private boolean mShouldShowAppUpdateBadge; + private Runnable mUpdateStateChangedListener; + private Supplier<Boolean> mIsActivityFinishingSupplier; + private int mFullscreenMenuToken = TokenHolder.INVALID_TOKEN; + private int mFullscreenHighlightToken = TokenHolder.INVALID_TOKEN; + private Supplier<Boolean> mIsInOverviewModeSupplier; + private boolean mSuppressAppMenuUpdateBadge; + private Resources mResources; + + /** + * @param appMenuCoordinatorSupplier Supplier for the AppMenuCoordinator, which owns all other + * app menu MVC components. + * @param controlsVisibilityDelegate Delegate for forcing persistent display of browser + * controls. + * @param setUrlBarFocusFunction Function that allows setting focus on the url bar. + * @param requestRenderRunnable Runnable that requests a re-rendering of the compositor view + * containing the app menu button. + * @param shouldShowAppUpdateBadge Whether the app menu update badge should be shown if there is + * a pending update. + * @param isInOverviewModeSupplier Supplier of overview mode state. + * @param themeColorProvider Provider of theme color changes. + * @param resources Resources object to use to obtain, e.g. localized strings. + * @param shouldShowAppUpdateBadge Whether the "update available" badge should ever be shown. + * @param isActivityFinishingSupplier Supplier for knowing if the embedding activity is in the + * process of finishing or has already been destroyed. + * @param propertyModel Model to write property changes to. + */ + MenuButtonMediator(PropertyModel propertyModel, boolean shouldShowAppUpdateBadge, + Supplier<Boolean> isActivityFinishingSupplier, Runnable requestRenderRunnable, + ThemeColorProvider themeColorProvider, Supplier<Boolean> isInOverviewModeSupplier, + BrowserStateBrowserControlsVisibilityDelegate controlsVisibilityDelegate, + SetFocusFunction setUrlBarFocusFunction, + OneshotSupplier<AppMenuCoordinator> appMenuCoordinatorSupplier, Resources resources) { + mPropertyModel = propertyModel; + mShouldShowAppUpdateBadge = shouldShowAppUpdateBadge; + mIsActivityFinishingSupplier = isActivityFinishingSupplier; + mRequestRenderRunnable = requestRenderRunnable; + mThemeColorProvider = themeColorProvider; + mIsInOverviewModeSupplier = isInOverviewModeSupplier; + mControlsVisibilityDelegate = controlsVisibilityDelegate; + mSetUrlBarFocusFunction = setUrlBarFocusFunction; + mThemeColorProvider.addTintObserver(this::onTintChanged); + mAppMenuCoordinatorSupplierObserver = this::onAppMenuInitialized; + mAppMenuCoordinatorSupplier = appMenuCoordinatorSupplier; + mAppMenuCoordinatorSupplier.onAvailable(mAppMenuCoordinatorSupplierObserver); + mResources = resources; + mAppMenuButtonHelperSupplier = new ObservableSupplierImpl<>(); + } + + @Override + public void onMenuVisibilityChanged(boolean isVisible) { + if (isVisible) { + // Defocus here to avoid handling focus in multiple places, e.g., when the + // forward button is pressed. (see crbug.com/414219) + mSetUrlBarFocusFunction.setFocus(false, LocationBar.OmniboxFocusReason.UNFOCUS); + + if (!mIsInOverviewModeSupplier.get() && isShowingAppMenuUpdateBadge()) { + // The app menu badge should be removed the first time the menu is opened. + removeAppMenuUpdateBadge(true); + mRequestRenderRunnable.run(); + } + + mFullscreenMenuToken = + mControlsVisibilityDelegate.showControlsPersistentAndClearOldToken( + mFullscreenMenuToken); + } else { + mControlsVisibilityDelegate.releasePersistentShowingToken(mFullscreenMenuToken); + } + + if (isVisible) { + UpdateMenuItemHelper.getInstance().onMenuButtonClicked(); + } + } + + @Override + public void onMenuHighlightChanged(boolean isHighlighting) { + setMenuButtonHighlight(isHighlighting); + + if (isHighlighting) { + mFullscreenHighlightToken = + mControlsVisibilityDelegate.showControlsPersistentAndClearOldToken( + mFullscreenHighlightToken); + } else { + mControlsVisibilityDelegate.releasePersistentShowingToken(mFullscreenHighlightToken); + } + } + + void setClickable(boolean isClickable) { + mPropertyModel.set(MenuButtonProperties.IS_CLICKABLE, isClickable); + } + + void onNativeInitialized() { + if (mShouldShowAppUpdateBadge) { + mUpdateStateChangedListener = this::updateStateChanged; + UpdateMenuItemHelper.getInstance().registerObserver(mUpdateStateChangedListener); + } + } + + void setMenuButtonHighlight(boolean isHighlighting) { + mPropertyModel.set(MenuButtonProperties.IS_HIGHLIGHTING, isHighlighting); + } + + void setAppMenuUpdateBadgeSuppressed(boolean isSuppressed) { + mSuppressAppMenuUpdateBadge = isSuppressed; + if (isSuppressed) { + removeAppMenuUpdateBadge(false); + } else if (isUpdateAvailable() && mShouldShowAppUpdateBadge) { + showAppMenuUpdateBadge(false); + } + } + + void setVisibility(boolean visible) { + mPropertyModel.set(MenuButtonProperties.IS_VISIBLE, visible); + } + + void updateReloadingState(boolean isLoading) { + if (mAppMenuPropertiesDelegate == null || mAppMenuHandler == null) { + return; + } + mAppMenuPropertiesDelegate.loadingStateChanged(isLoading); + mAppMenuHandler.menuItemContentChanged(org.chromium.chrome.R.id.icon_row_menu_id); + } + + ObservableSupplier<AppMenuButtonHelper> getMenuButtonHelperSupplier() { + return mAppMenuButtonHelperSupplier; + } + + void destroy() { + if (mAppMenuButtonHelper != null) { + mAppMenuHandler.removeObserver(this); + mAppMenuButtonHelper = null; + } + + if (mUpdateStateChangedListener != null) { + UpdateMenuItemHelper.getInstance().unregisterObserver(mUpdateStateChangedListener); + mUpdateStateChangedListener = null; + } + } + + void updateStateChanged() { + if (mIsActivityFinishingSupplier.get() || !mShouldShowAppUpdateBadge) { + return; + } + + if (isUpdateAvailable()) { + showAppMenuUpdateBadge(true); + mRequestRenderRunnable.run(); + } else if (isShowingAppMenuUpdateBadge()) { + removeAppMenuUpdateBadge(true); + } + } + + private void showAppMenuUpdateBadge(boolean animate) { + if (mSuppressAppMenuUpdateBadge) { + return; + } + MenuButtonState buttonState = UpdateMenuItemHelper.getInstance().getUiState().buttonState; + assert buttonState != null : "No button state when trying to show the badge."; + updateContentDescription(true, buttonState.menuContentDescription); + mPropertyModel.set( + MenuButtonProperties.SHOW_UPDATE_BADGE, new ShowBadgeProperty(true, animate)); + } + + private void removeAppMenuUpdateBadge(boolean animate) { + mPropertyModel.set( + MenuButtonProperties.SHOW_UPDATE_BADGE, new ShowBadgeProperty(false, animate)); + + updateContentDescription(false, 0); + } + + private void onTintChanged(ColorStateList tintList, boolean useLight) { + mPropertyModel.set(MenuButtonProperties.THEME, new ThemeProperty(tintList, useLight)); + } + + /** + * Sets the content description for the menu button. + * @param isUpdateBadgeVisible Whether the update menu badge is visible. + * @param badgeContentDescription Resource id of the string to show if the update badge is + * visible. + */ + private void updateContentDescription( + boolean isUpdateBadgeVisible, int badgeContentDescription) { + if (isUpdateBadgeVisible) { + mPropertyModel.set(MenuButtonProperties.CONTENT_DESCRIPTION, + mResources.getString(badgeContentDescription)); + } else { + mPropertyModel.set(MenuButtonProperties.CONTENT_DESCRIPTION, + mResources.getString( + org.chromium.chrome.R.string.accessibility_toolbar_btn_menu)); + } + } + + /** + * Called when the app menu and related properties delegate are available. + * + * @param appMenuCoordinator The coordinator for interacting with the menu. + */ + private void onAppMenuInitialized(AppMenuCoordinator appMenuCoordinator) { + assert mAppMenuHandler == null; + AppMenuHandler appMenuHandler = appMenuCoordinator.getAppMenuHandler(); + + mAppMenuHandler = appMenuHandler; + mAppMenuHandler.addObserver(this); + mAppMenuButtonHelper = mAppMenuHandler.createAppMenuButtonHelper(); + mAppMenuButtonHelper.setOnAppMenuShownListener( + () -> { RecordUserAction.record("MobileToolbarShowMenu"); }); + mPropertyModel.set(MenuButtonProperties.APP_MENU_BUTTON_HELPER, mAppMenuButtonHelper); + + mAppMenuButtonHelperSupplier.set(mAppMenuButtonHelper); + mAppMenuPropertiesDelegate = appMenuCoordinator.getAppMenuPropertiesDelegate(); + } + + /** + * @return Whether the badge is showing (either in the toolbar). + */ + private boolean isShowingAppMenuUpdateBadge() { + return mPropertyModel.get(MenuButtonProperties.SHOW_UPDATE_BADGE).mShowUpdateBadge; + } + + private boolean isUpdateAvailable() { + return UpdateMenuItemHelper.getInstance().getUiState().buttonState != null; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonProperties.java new file mode 100644 index 0000000..b03b11d --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonProperties.java
@@ -0,0 +1,54 @@ +// Copyright 2020 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.chrome.browser.toolbar.menu_button; + +import android.content.res.ColorStateList; + +import androidx.annotation.NonNull; + +import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey; + +class MenuButtonProperties { + static class ThemeProperty { + @NonNull + public ColorStateList mColorStateList; + public boolean mUseLightColors; + + public ThemeProperty(@NonNull ColorStateList colorStateList, boolean useLight) { + mColorStateList = colorStateList; + mUseLightColors = useLight; + } + } + + static class ShowBadgeProperty { + public boolean mShowUpdateBadge; + public boolean mShouldAnimate; + + public ShowBadgeProperty(boolean showUpdateBadge, boolean shouldAnimate) { + mShowUpdateBadge = showUpdateBadge; + mShouldAnimate = shouldAnimate; + } + } + + public static final WritableObjectPropertyKey<AppMenuButtonHelper> APP_MENU_BUTTON_HELPER = + new WritableObjectPropertyKey<>(); + public static final WritableObjectPropertyKey<String> CONTENT_DESCRIPTION = + new WritableObjectPropertyKey<>(); + public static final WritableBooleanPropertyKey IS_CLICKABLE = new WritableBooleanPropertyKey(); + public static final WritableBooleanPropertyKey IS_HIGHLIGHTING = + new WritableBooleanPropertyKey(); + public static final WritableBooleanPropertyKey IS_VISIBLE = new WritableBooleanPropertyKey(); + public static final WritableObjectPropertyKey<ShowBadgeProperty> SHOW_UPDATE_BADGE = + new WritableObjectPropertyKey(true); + public static final WritableObjectPropertyKey<ThemeProperty> THEME = + new WritableObjectPropertyKey<>(true); + + public static final PropertyKey[] ALL_KEYS = + new PropertyKey[] {APP_MENU_BUTTON_HELPER, CONTENT_DESCRIPTION, IS_CLICKABLE, + IS_HIGHLIGHTING, IS_VISIBLE, SHOW_UPDATE_BADGE, THEME}; +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonViewBinder.java new file mode 100644 index 0000000..0693f206 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonViewBinder.java
@@ -0,0 +1,41 @@ +// Copyright 2020 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.chrome.browser.toolbar.menu_button; + +import android.view.View; + +import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ShowBadgeProperty; +import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ThemeProperty; +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyModelChangeProcessor.ViewBinder; + +class MenuButtonViewBinder implements ViewBinder<PropertyModel, MenuButton, PropertyKey> { + @Override + public void bind(PropertyModel model, MenuButton view, PropertyKey propertyKey) { + if (propertyKey == MenuButtonProperties.APP_MENU_BUTTON_HELPER) { + view.setAppMenuButtonHelper(model.get(MenuButtonProperties.APP_MENU_BUTTON_HELPER)); + } else if (propertyKey == MenuButtonProperties.CONTENT_DESCRIPTION) { + view.updateContentDescription(model.get(MenuButtonProperties.CONTENT_DESCRIPTION)); + } else if (propertyKey == MenuButtonProperties.IS_CLICKABLE) { + view.setClickable(model.get(MenuButtonProperties.IS_CLICKABLE)); + } else if (propertyKey == MenuButtonProperties.IS_HIGHLIGHTING) { + view.setMenuButtonHighlight(model.get(MenuButtonProperties.IS_HIGHLIGHTING)); + } else if (propertyKey == MenuButtonProperties.IS_VISIBLE) { + view.setVisibility( + model.get(MenuButtonProperties.IS_VISIBLE) ? View.VISIBLE : View.GONE); + } else if (propertyKey == MenuButtonProperties.SHOW_UPDATE_BADGE) { + ShowBadgeProperty showBadgeProperty = model.get(MenuButtonProperties.SHOW_UPDATE_BADGE); + if (showBadgeProperty.mShowUpdateBadge) { + view.showAppMenuUpdateBadge(showBadgeProperty.mShouldAnimate); + } else { + view.removeAppMenuUpdateBadge(showBadgeProperty.mShouldAnimate); + } + } else if (propertyKey == MenuButtonProperties.THEME) { + ThemeProperty themeProperty = model.get(MenuButtonProperties.THEME); + view.onTintChanged(themeProperty.mColorStateList, themeProperty.mUseLightColors); + } + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java index f06a9df..771d8dc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java
@@ -227,8 +227,7 @@ mView = (StartSurfaceToolbarView) mStub.inflate(); mMenuButtonCoordinator.setMenuButton(mView.findViewById(R.id.menu_button_wrapper)); mMenuButtonCoordinator.setVisibility( - mPropertyModel.get(StartSurfaceToolbarProperties.MENU_IS_VISIBLE) ? View.VISIBLE - : View.GONE); + mPropertyModel.get(StartSurfaceToolbarProperties.MENU_IS_VISIBLE)); mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create( mPropertyModel, mView, StartSurfaceToolbarViewBinder::bind); if (LibraryLoader.getInstance().isInitialized()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java index 8677a7e..e4b1ed43 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java
@@ -118,7 +118,6 @@ mIncognitoToggleTabLayout = null; } if (mMenuButton != null) { - mMenuButton.destroy(); mMenuButton = null; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index 2db46ef..2b196cc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -365,7 +365,7 @@ setLayoutTransition(null); if (getMenuButtonCoordinator() != null) { - getMenuButtonCoordinator().setVisibility(View.VISIBLE); + getMenuButtonCoordinator().setVisibility(true); } inflateTabSwitchingResources(); @@ -1881,7 +1881,7 @@ mToggleTabStackButton.setVisibility(isGone ? GONE : VISIBLE); } - getMenuButtonCoordinator().setVisibility(inTabSwitcherMode ? GONE : VISIBLE); + getMenuButtonCoordinator().setVisibility(!inTabSwitcherMode); triggerUrlFocusAnimation(inTabSwitcherMode && !urlHasFocus()); @@ -2509,8 +2509,7 @@ updateNtpTransitionAnimation(); } - getMenuButtonCoordinator().setMenuButtonHighlightDrawable(); - getMenuButtonCoordinator().setVisibility(View.VISIBLE); + getMenuButtonCoordinator().setVisibility(true); DrawableCompat.setTint(mLocationBarBackground, isIncognito() ? Color.WHITE
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java index 18d8ddb..ce1b7f4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
@@ -499,7 +499,7 @@ void initialize(ToolbarDataProvider toolbarDataProvider, ToolbarTabController tabController, MenuButtonCoordinator menuButtonCoordinator) { super.initialize(toolbarDataProvider, tabController, menuButtonCoordinator); - menuButtonCoordinator.setVisibility(View.VISIBLE); + menuButtonCoordinator.setVisibility(true); } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java index 4f0a64b8..3a75b73c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java
@@ -237,8 +237,7 @@ () -> mActivityTestRule.getActivity().getLayoutManager().hideOverview(false)); Assert.assertFalse("Overview shouldn't be showing.", mActivityTestRule.getActivity().getOverviewModeBehavior().overviewVisible()); - CriteriaHelper.pollUiThread( - () -> !mAppMenuHandler.isAppMenuShowing(), "App menu shouldn't be showing."); + Assert.assertFalse("App menu shouldn't be showing.", mAppMenuHandler.isAppMenuShowing()); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivityTest.java new file mode 100644 index 0000000..970d84e --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivityTest.java
@@ -0,0 +1,99 @@ +// Copyright 2020 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.chrome.browser.browserservices; + +import static junit.framework.Assert.assertTrue; + +import static org.chromium.chrome.browser.browserservices.TrustedWebActivityTestUtil.createSession; +import static org.chromium.chrome.browser.browserservices.TrustedWebActivityTestUtil.spoofVerification; + +import android.app.Activity; +import android.content.ComponentName; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.support.test.InstrumentationRegistry; + +import androidx.browser.customtabs.CustomTabsIntent; +import androidx.browser.customtabs.CustomTabsSession; +import androidx.test.filters.MediumTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.ApplicationStatus; +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.components.webapk.lib.client.WebApkValidator; +import org.chromium.webapk.lib.common.WebApkConstants; + +import java.util.concurrent.TimeoutException; + +/** + * Instrumentation tests for launching site settings for WebApks. + * Site settings are added as a dynamic android shortcut. + * The shortcut launches a {@link ManageTrustedWebActivityDataActivity} + * intent that validates the WebApk and launches the chromium SettingsActivity. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +public class ManageTrustedWebActivityDataActivityTest { + private static final String SETTINGS_ACTIVITY_NAME = + "org.chromium.chrome.browser.settings.SettingsActivity"; + private static final String WEBAPK_TEST_URL = "https://padr31.github.io"; + private static final String TEST_PACKAGE_NAME = + InstrumentationRegistry.getTargetContext().getPackageName(); + + @Test + @MediumTest + public void launchesWebApkSiteSettings() { + Intent siteSettingsIntent = + createWebApkSiteSettingsIntent(TEST_PACKAGE_NAME, Uri.parse(WEBAPK_TEST_URL)); + + WebApkValidator.setDisableValidationForTesting(true); + try { + launchSiteSettingsIntent(siteSettingsIntent); + + // Check settings activity is running. + boolean settingsActivityRunning = false; + for (Activity a : ApplicationStatus.getRunningActivities()) { + String activityName = + a.getPackageManager().getActivityInfo(a.getComponentName(), 0).name; + if (activityName.equals(SETTINGS_ACTIVITY_NAME)) { + settingsActivityRunning = true; + } + } + assertTrue(settingsActivityRunning); + } catch (TimeoutException | PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + } + + private static Intent createWebApkSiteSettingsIntent(String packageName, Uri uri) { + // CustomTabsIntent builder is used just to put in the session extras. + CustomTabsIntent.Builder builder = + new CustomTabsIntent.Builder(CustomTabsSession.createMockSessionForTesting( + new ComponentName(InstrumentationRegistry.getTargetContext(), + ManageTrustedWebActivityDataActivity.class))); + Intent intent = builder.build().intent; + intent.setAction( + "android.support.customtabs.action.ACTION_MANAGE_TRUSTED_WEB_ACTIVITY_DATA"); + intent.setPackage(packageName); + intent.setData(uri); + intent.putExtra(WebApkConstants.EXTRA_IS_WEBAPK, true); + // The following flag is required because the test starts the intent outside of an activity. + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + return intent; + } + + public void launchSiteSettingsIntent(Intent intent) throws TimeoutException { + String url = intent.getData().toString(); + spoofVerification(TEST_PACKAGE_NAME, url); + createSession(intent, TEST_PACKAGE_NAME); + + InstrumentationRegistry.getInstrumentation().startActivitySync(intent); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java index 4dc742b..e3afc44 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
@@ -30,7 +30,6 @@ import org.chromium.base.MathUtils; import org.chromium.base.supplier.ObservableSupplierImpl; -import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.base.test.UiThreadTest; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisabledTest; @@ -167,10 +166,8 @@ ObservableSupplierImpl<TabContentManager> tabContentManagerSupplier = new ObservableSupplierImpl<>(); - OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier = - new OneshotSupplierImpl<>(); - mManagerPhone = new LayoutManagerChromePhone(layoutManagerHost, container, null, - tabContentManagerSupplier, overviewModeBehaviorSupplier); + mManagerPhone = new LayoutManagerChromePhone( + layoutManagerHost, container, null, tabContentManagerSupplier); tabContentManagerSupplier.set(tabContentManager); mManager = mManagerPhone; CompositorAnimationHandler.setTestingMode(true);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java index 8254da2..7e4c6f5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
@@ -8,11 +8,17 @@ import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.ViewMatchers.Visibility.GONE; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility; import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.CoreMatchers.allOf; +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.chromium.chrome.test.util.ViewUtils.onViewWaiting; import static org.chromium.components.content_settings.PrefNames.COOKIE_CONTROLS_MODE; import android.os.Build; @@ -45,6 +51,7 @@ import org.chromium.components.page_info.PageInfoController; import org.chromium.components.page_info.PageInfoFeatureList; import org.chromium.components.user_prefs.UserPrefs; +import org.chromium.content_public.browser.test.util.JavaScriptUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.common.ContentSwitches; import org.chromium.net.test.EmbeddedTestServerRule; @@ -53,6 +60,7 @@ import org.chromium.ui.test.util.RenderTestRule; import java.io.IOException; +import java.util.concurrent.TimeoutException; /** * Tests for PageInfoView. Uses pixel tests to ensure the UI handles different @@ -62,6 +70,12 @@ @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, ContentSwitches.HOST_RESOLVER_RULES + "=MAP * 127.0.0.1"}) public class PageInfoViewTest { + private static final String sSimpleHtml = "/chrome/test/data/android/simple.html"; + private static final String sSiteDataHtml = "/content/test/data/browsing_data/site_data.html"; + + private static String[] sCookieDataTypes = {"Cookie", "LocalStorage", "ServiceWorker", + "CacheStorage", "IndexedDb", "FileSystem", "WebSql"}; + @Rule public ChromeActivityTestRule<ChromeActivity> mActivityTestRule = new ChromeActivityTestRule<>(ChromeActivity.class); @@ -85,8 +99,6 @@ @ClassRule public static DisableAnimationsTestRule disableAnimationsRule = new DisableAnimationsTestRule(); - private final String mPath = "/chrome/test/data/android/simple.html"; - private void loadUrlAndOpenPageInfo(String url) { mActivityTestRule.loadUrl(url); onView(withId(R.id.location_bar_status_icon)).perform(click()); @@ -107,6 +119,23 @@ }); } + private String runJavascriptAsync(String type) throws TimeoutException { + return JavaScriptUtils.runJavascriptWithAsyncResult( + mActivityTestRule.getWebContents(), type); + } + + private void expectHasCookies(boolean hasData) throws TimeoutException { + for (String type : sCookieDataTypes) { + assertEquals(hasData ? "true" : "false", runJavascriptAsync("has" + type + "()")); + } + } + + private void createCookies() throws TimeoutException { + for (String type : sCookieDataTypes) { + runJavascriptAsync("set" + type + "()"); + } + } + private void addSomePermissions(String url) { TestThreadUtils.runOnUiThreadBlocking(() -> { WebsitePreferenceBridge.setContentSettingForPattern(Profile.getLastUsedRegularProfile(), @@ -158,7 +187,7 @@ @Feature({"RenderTest"}) public void testShowOnInsecureHttpWebsite() throws IOException { mTestServerRule.setServerUsesHttps(false); - loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); mRenderTestRule.render(getPageInfoView(), "PageInfo_HttpWebsite"); } @@ -169,7 +198,7 @@ @MediumTest @Feature({"RenderTest"}) public void testShowOnSecureWebsite() throws IOException { - loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); mRenderTestRule.render(getPageInfoView(), "PageInfo_SecureWebsite"); } @@ -181,7 +210,7 @@ @Feature({"RenderTest"}) public void testShowOnExpiredCertificateWebsite() throws IOException { mTestServerRule.setCertificateType(ServerCertificate.CERT_EXPIRED); - loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); mRenderTestRule.render(getPageInfoView(), "PageInfo_ExpiredCertWebsite"); } @@ -206,7 +235,7 @@ public void testShowWithPermissions() throws IOException { mIsSystemLocationSettingEnabled = false; addSomePermissions(mTestServerRule.getServer().getURL("/")); - loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); mRenderTestRule.render(getPageInfoView(), "PageInfo_Permissions"); } @@ -218,7 +247,7 @@ @Feature({"RenderTest"}) public void testShowWithCookieBlocking() throws IOException { setThirdPartyCookieBlocking(CookieControlsMode.BLOCK_THIRD_PARTY); - loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); mRenderTestRule.render(getPageInfoView(), "PageInfo_CookieBlocking"); } @@ -231,7 +260,7 @@ public void testShowWithPermissionsAndCookieBlocking() throws IOException { addSomePermissions(mTestServerRule.getServer().getURL("/")); setThirdPartyCookieBlocking(CookieControlsMode.BLOCK_THIRD_PARTY); - loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); mRenderTestRule.render(getPageInfoView(), "PageInfo_PermissionsAndCookieBlocking"); } @@ -243,7 +272,7 @@ @Feature({"RenderTest"}) public void testShowWithDefaultSettingPermissions() throws IOException { addDefaultSettingPermissions(mTestServerRule.getServer().getURL("/")); - loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); mRenderTestRule.render(getPageInfoView(), "PageInfo_DefaultSettingPermissions"); } @@ -255,7 +284,7 @@ @Feature({"RenderTest"}) @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2) public void testShowOnSecureWebsiteV2() throws IOException { - loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); mRenderTestRule.render(getPageInfoView(), "PageInfo_SecureWebsiteV2"); } @@ -267,7 +296,7 @@ @Feature({"RenderTest"}) @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2) public void testShowConnectionInfoSubpage() throws IOException { - loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); onView(withId(R.id.page_info_connection_row)).perform(click()); mRenderTestRule.render(getPageInfoView(), "PageInfo_ConnectionInfoSubpage"); } @@ -280,7 +309,7 @@ @MediumTest @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2) public void testNoPermissionsSubpage() throws IOException { - loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); View dialog = (View) getPageInfoView().getParent(); onView(withId(R.id.page_info_permissions_row)) .check(matches(withEffectiveVisibility(GONE))); @@ -295,7 +324,7 @@ @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2) public void testShowPermissionsSubpage() throws IOException { addSomePermissions(mTestServerRule.getServer().getURL("/")); - loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); onView(withId(R.id.page_info_permissions_row)).perform(click()); mRenderTestRule.render(getPageInfoView(), "PageInfo_PermissionsSubpage"); } @@ -309,10 +338,34 @@ @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2) public void testShowCookiesSubpage() throws IOException { setThirdPartyCookieBlocking(CookieControlsMode.BLOCK_THIRD_PARTY); - loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath)); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); onView(withId(R.id.page_info_cookies_row)).perform(click()); mRenderTestRule.render(getPageInfoView(), "PageInfo_CookiesSubpage"); } + /** + * Tests clearing cookies on the cookies page of the new PageInfo UI. + */ + @Test + @MediumTest + @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2) + public void testClearCookiesOnSubpage() throws Exception { + mActivityTestRule.loadUrl(mTestServerRule.getServer().getURL(sSiteDataHtml)); + // Create cookies. + expectHasCookies(false); + createCookies(); + expectHasCookies(true); + // Go to cookies subpage. + onView(withId(R.id.location_bar_status_icon)).perform(click()); + onView(withId(R.id.page_info_cookies_row)).perform(click()); + // Check that cookies usage is displayed. + onViewWaiting(allOf(withText(containsString("stored data")), isDisplayed())); + // Clear cookies in page info. + onView(withText("Clear cookies")).perform(click()); + // Wait until the UI navigates back and check cookies are deleted. + onViewWaiting(allOf(withId(R.id.page_info_cookies_row), isDisplayed())); + expectHasCookies(false); + } + // TODO(1071762): Add tests for preview pages, offline pages, offline state and other states. }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java index 82492f8..fcd7a7e4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java
@@ -14,13 +14,14 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.app.ChromeActivity; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.settings.SettingsActivity; import org.chromium.chrome.browser.settings.SettingsActivityTestRule; import org.chromium.chrome.browser.sync.settings.AccountManagementFragment; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.ChromeRenderTestRule; +import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; @RunWith(ChromeJUnit4ClassRunner.class) @@ -45,14 +46,24 @@ public void setUp() { mActivityTestRule.startMainActivityOnBlankPage(); mAccountManagerTestRule.addAndSignInTestAccount(); + mSettingsActivityTestRule.startSettingsActivity(); } @Test @MediumTest @Feature("RenderTest") + @Features.DisableFeatures(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY) public void testAccountManagementFragmentViewLegacy() throws Exception { - SettingsActivity settingsActivity = mSettingsActivityTestRule.startSettingsActivity(); - mRenderTestRule.render(settingsActivity.getMainFragment().getView(), + mRenderTestRule.render(mSettingsActivityTestRule.getFragment().getView(), "account_management_fragment_view_legacy"); } + + @Test + @MediumTest + @Feature("RenderTest") + @Features.EnableFeatures(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY) + public void testAccountManagementFragmentView() throws Exception { + mRenderTestRule.render(mSettingsActivityTestRule.getFragment().getView(), + "account_management_fragment_view"); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java index 2213381ca..0107c421 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.browser.ui.system; -import android.app.Activity; import android.content.res.Resources; import android.graphics.Color; import android.os.Build; @@ -12,7 +11,6 @@ import androidx.annotation.ColorInt; import androidx.test.filters.LargeTest; -import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -36,15 +34,10 @@ import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.ThemeTestUtils; import org.chromium.components.browser_ui.styles.ChromeColors; -import org.chromium.content_public.browser.test.util.Criteria; -import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.UiRestriction; import org.chromium.ui.util.ColorUtils; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - /** * {@link StatusBarColorController} tests. * There are additional status bar color tests in {@link BrandColorTest}. @@ -75,7 +68,7 @@ @Feature({"StatusBar"}) @MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP_MR1) @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) // Status bar is always black on tablets - public void testColorToggleIncongitoInOverview() throws Exception { + public void testColorToggleIncongitoInOverview() { ChromeTabbedActivity activity = mActivityTestRule.getActivity(); Resources resources = activity.getResources(); final int expectedOverviewStandardColor = defaultColorFallbackToBlack( @@ -91,7 +84,8 @@ TestThreadUtils.runOnUiThreadBlocking( () -> { activity.getLayoutManager().showOverview(false /* animate */); }); - waitForStatusBarColor(activity, expectedOverviewIncognitoColor); + ThemeTestUtils.assertStatusBarColor(activity, expectedOverviewIncognitoColor); + TestThreadUtils.runOnUiThreadBlocking( () -> { tabModelSelector.selectModel(false /* incongito */); }); ThemeTestUtils.assertStatusBarColor(activity, expectedOverviewStandardColor); @@ -115,11 +109,11 @@ "/chrome/test/data/android/theme_color_test.html"); mActivityTestRule.loadUrl(pageWithBrandColorUrl); ThemeTestUtils.waitForThemeColor(activity, Color.RED); - waitForStatusBarColor(activity, Color.RED); + ThemeTestUtils.assertStatusBarColor(activity, Color.RED); TestThreadUtils.runOnUiThreadBlocking( () -> { activity.getLayoutManager().showOverview(false /* animate */); }); - waitForStatusBarColor(activity, expectedDefaultStandardColor); + ThemeTestUtils.assertStatusBarColor(activity, expectedDefaultStandardColor); } /** @@ -197,12 +191,4 @@ final int scrimColorOpaque = mScrimColor & 0xFF000000; return ColorUtils.getColorWithOverlay(color, scrimColorOpaque, fraction * scrimColorAlpha); } - - private void waitForStatusBarColor(Activity activity, int expectedColor) - throws ExecutionException, TimeoutException { - CriteriaHelper.pollUiThread(() -> { - Criteria.checkThat( - activity.getWindow().getStatusBarColor(), Matchers.is(expectedColor)); - }, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL, CriteriaHelper.DEFAULT_POLLING_INTERVAL); - } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/DeviceConditionsTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/DeviceConditionsTest.java index 17f75f5a..18b0000 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/DeviceConditionsTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/DeviceConditionsTest.java
@@ -294,11 +294,11 @@ @Test public void testNcnConnectionType() { @ConnectionType - int[] connectionTypes = - new int[] {ConnectionType.CONNECTION_UNKNOWN, ConnectionType.CONNECTION_ETHERNET, - ConnectionType.CONNECTION_WIFI, ConnectionType.CONNECTION_2G, - ConnectionType.CONNECTION_3G, ConnectionType.CONNECTION_4G, - ConnectionType.CONNECTION_NONE, ConnectionType.CONNECTION_BLUETOOTH}; + int[] connectionTypes = new int[] {ConnectionType.CONNECTION_UNKNOWN, + ConnectionType.CONNECTION_ETHERNET, ConnectionType.CONNECTION_WIFI, + ConnectionType.CONNECTION_2G, ConnectionType.CONNECTION_3G, + ConnectionType.CONNECTION_4G, ConnectionType.CONNECTION_NONE, + ConnectionType.CONNECTION_BLUETOOTH, ConnectionType.CONNECTION_5G}; assertEquals(ConnectionType.CONNECTION_LAST + 1, connectionTypes.length); for (@ConnectionType int connectionType : connectionTypes) {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinatorTest.java index a402be5..95c97ab 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinatorTest.java
@@ -4,13 +4,12 @@ package org.chromium.chrome.browser.toolbar.menu_button; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.app.Activity; +import android.widget.ImageButton; import org.junit.Before; import org.junit.Test; @@ -23,12 +22,10 @@ import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; -import org.chromium.chrome.browser.omnibox.LocationBar; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator; import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler; import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate; -import org.chromium.ui.util.TokenHolder; /** * Unit tests for ToolbarAppMenuManager. @@ -50,6 +47,8 @@ @Mock MenuButton mMenuButton; @Mock + ImageButton mImageButton; + @Mock private AppMenuPropertiesDelegate mAppMenuPropertiesDelegate; @Mock private UpdateMenuItemHelper mUpdateMenuItemHelper; @@ -77,6 +76,7 @@ doReturn(mMenuButton) .when(mActivity) .findViewById(org.chromium.chrome.R.id.menu_button_wrapper); + doReturn(mImageButton).when(mMenuButton).getImageButton(); mMenuButtonCoordinator = new MenuButtonCoordinator(mAppMenuSupplier, mControlsVisibilityDelegate, mActivity, mFocusFunction, mRequestRenderRunnable, @@ -85,129 +85,14 @@ } @Test - public void testInitialization() { - mAppMenuSupplier.set(mAppMenuCoordinator); - verify(mAppMenuHandler).addObserver(mMenuButtonCoordinator); - verify(mAppMenuHandler).createAppMenuButtonHelper(); - } - - @Test - public void testSetMenuButton() { - mMenuButtonCoordinator = new MenuButtonCoordinator(mAppMenuSupplier, - mControlsVisibilityDelegate, mActivity, mFocusFunction, mRequestRenderRunnable, - true, () -> false, mThemeColorProvider, org.chromium.chrome.R.id.none); - - mAppMenuSupplier.set(mAppMenuCoordinator); - mMenuButtonCoordinator.setMenuButton(mMenuButton); - - verify(mMenuButton, times(2)).setAppMenuButtonHelper(mAppMenuButtonHelper); - verify(mMenuButton, times(2)).setThemeColorProvider(mThemeColorProvider); - } - - @Test - public void testAppMenuVisiblityChange_badgeShowing() { - mAppMenuSupplier.set(mAppMenuCoordinator); - doReturn(42) - .when(mControlsVisibilityDelegate) - .showControlsPersistentAndClearOldToken(TokenHolder.INVALID_TOKEN); - doReturn(true).when(mMenuButton).isShowingAppMenuUpdateBadge(); - mMenuButtonCoordinator.onMenuVisibilityChanged(true); - - verify(mFocusFunction).setFocus(false, LocationBar.OmniboxFocusReason.UNFOCUS); - verify(mMenuButton).removeAppMenuUpdateBadge(true); - verify(mUpdateMenuItemHelper).onMenuButtonClicked(); - - mMenuButtonCoordinator.onMenuVisibilityChanged(false); - verify(mControlsVisibilityDelegate).releasePersistentShowingToken(42); - } - - @Test - public void testAppMenuHighlightChange() { + public void testEnterKeyPress() { mAppMenuSupplier.set(mAppMenuCoordinator); - doReturn(42) - .when(mControlsVisibilityDelegate) - .showControlsPersistentAndClearOldToken(TokenHolder.INVALID_TOKEN); + mMenuButtonCoordinator.onEnterKeyPress(); + verify(mAppMenuButtonHelper).onEnterKeyPress(mImageButton); - mMenuButtonCoordinator.onMenuHighlightChanged(true); - verify(mMenuButton).setMenuButtonHighlight(true); - - mMenuButtonCoordinator.onMenuHighlightChanged(false); - verify(mMenuButton).setMenuButtonHighlight(false); - verify(mControlsVisibilityDelegate).releasePersistentShowingToken(42); - } - - @Test - public void testAppMenuUpdateBadge() { - mAppMenuSupplier.set(mAppMenuCoordinator); - - doReturn(true).when(mActivity).isDestroyed(); - mMenuButtonCoordinator.updateStateChanged(); - - verify(mMenuButton, never()).showAppMenuUpdateBadgeIfAvailable(anyBoolean()); - verify(mRequestRenderRunnable, never()).run(); - verify(mMenuButton, never()).removeAppMenuUpdateBadge(false); - - doReturn(false).when(mActivity).isDestroyed(); - mMenuButtonCoordinator.updateStateChanged(); - - verify(mMenuButton, never()).showAppMenuUpdateBadgeIfAvailable(anyBoolean()); - verify(mRequestRenderRunnable, never()).run(); - verify(mMenuButton, times(1)).removeAppMenuUpdateBadge(false); - - mMenuUiState.buttonState = new UpdateMenuItemHelper.MenuButtonState(); - mMenuButtonCoordinator.updateStateChanged(); - - verify(mMenuButton).showAppMenuUpdateBadgeIfAvailable(true); - verify(mRequestRenderRunnable).run(); - verify(mMenuButton, times(1)).removeAppMenuUpdateBadge(false); - } - - @Test - public void testAppMenuUpdateBadge_activityShouldNotShow() { - MenuButtonCoordinator newCoordinator = new MenuButtonCoordinator(mAppMenuSupplier, - mControlsVisibilityDelegate, mActivity, mFocusFunction, mRequestRenderRunnable, - false, - () -> false, mThemeColorProvider, org.chromium.chrome.R.id.menu_button_wrapper); - - doReturn(true).when(mActivity).isDestroyed(); - newCoordinator.updateStateChanged(); - - verify(mMenuButton, never()).showAppMenuUpdateBadgeIfAvailable(anyBoolean()); - verify(mRequestRenderRunnable, never()).run(); - verify(mMenuButton, never()).removeAppMenuUpdateBadge(false); - - doReturn(false).when(mActivity).isDestroyed(); - newCoordinator.updateStateChanged(); - - verify(mMenuButton, never()).showAppMenuUpdateBadgeIfAvailable(anyBoolean()); - verify(mRequestRenderRunnable, never()).run(); - verify(mMenuButton, never()).removeAppMenuUpdateBadge(false); - - mMenuUiState.buttonState = new UpdateMenuItemHelper.MenuButtonState(); - newCoordinator.updateStateChanged(); - - verify(mMenuButton, never()).showAppMenuUpdateBadgeIfAvailable(anyBoolean()); - verify(mRequestRenderRunnable, never()).run(); - verify(mMenuButton, never()).removeAppMenuUpdateBadge(false); - } - - @Test - public void testDestroyIsSafe() { mMenuButtonCoordinator.destroy(); - // It should be crash-safe to call public methods, but the results aren't meaningful. - mMenuButtonCoordinator.getMenuButtonHelperSupplier(); - mMenuButtonCoordinator.onMenuHighlightChanged(true); - mMenuButtonCoordinator.onMenuVisibilityChanged(false); - mMenuButtonCoordinator.onNativeInitialized(); - mMenuButtonCoordinator.setAppMenuUpdateBadgeSuppressed(true); - mMenuButtonCoordinator.updateReloadingState(true); - mMenuButtonCoordinator.updateStateChanged(); - } - - @Test - public void testDisableDestroysButton() { - mMenuButtonCoordinator.disableMenuButton(); - verify(mMenuButton).destroy(); + mMenuButtonCoordinator.onEnterKeyPress(); + verify(mAppMenuButtonHelper, times(1)).onEnterKeyPress(mImageButton); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java new file mode 100644 index 0000000..3fdf2628 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java
@@ -0,0 +1,205 @@ +// Copyright 2020 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.chrome.browser.toolbar.menu_button; + +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import android.app.Activity; +import android.content.res.Resources; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import org.chromium.base.supplier.OneshotSupplierImpl; +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.ThemeColorProvider; +import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; +import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; +import org.chromium.chrome.browser.omnibox.LocationBar; +import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ShowBadgeProperty; +import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ThemeProperty; +import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; +import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator; +import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler; +import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.util.TokenHolder; + +/** + * Unit tests for ToolbarAppMenuManager. + */ +@RunWith(BaseRobolectricTestRunner.class) +public class MenuButtonMediatorTest { + @Mock + private BrowserStateBrowserControlsVisibilityDelegate mControlsVisibilityDelegate; + @Mock + private Activity mActivity; + @Mock + private MenuButtonCoordinator.SetFocusFunction mFocusFunction; + @Mock + private AppMenuCoordinator mAppMenuCoordinator; + @Mock + private AppMenuHandler mAppMenuHandler; + @Mock + private AppMenuButtonHelper mAppMenuButtonHelper; + @Mock + private AppMenuPropertiesDelegate mAppMenuPropertiesDelegate; + @Mock + private UpdateMenuItemHelper mUpdateMenuItemHelper; + @Mock + private Runnable mRequestRenderRunnable; + @Mock + ThemeColorProvider mThemeColorProvider; + @Mock + Resources mResources; + + private UpdateMenuItemHelper.MenuUiState mMenuUiState; + private OneshotSupplierImpl<AppMenuCoordinator> mAppMenuSupplier; + private PropertyModel mPropertyModel; + private MenuButtonMediator mMenuButtonMediator; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mPropertyModel = new PropertyModel.Builder(MenuButtonProperties.ALL_KEYS) + .with(MenuButtonProperties.SHOW_UPDATE_BADGE, + new ShowBadgeProperty(false, false)) + .with(MenuButtonProperties.THEME, + new ThemeProperty(mThemeColorProvider.getTint(), + mThemeColorProvider.useLight())) + .with(MenuButtonProperties.IS_VISIBLE, true) + .build(); + doReturn(mAppMenuHandler).when(mAppMenuCoordinator).getAppMenuHandler(); + doReturn(mAppMenuButtonHelper).when(mAppMenuHandler).createAppMenuButtonHelper(); + doReturn(mAppMenuPropertiesDelegate) + .when(mAppMenuCoordinator) + .getAppMenuPropertiesDelegate(); + UpdateMenuItemHelper.setInstanceForTesting(mUpdateMenuItemHelper); + mAppMenuSupplier = new OneshotSupplierImpl<>(); + mMenuUiState = new UpdateMenuItemHelper.MenuUiState(); + doReturn(mMenuUiState).when(mUpdateMenuItemHelper).getUiState(); + + mMenuButtonMediator = new MenuButtonMediator(mPropertyModel, true, + () + -> false, + mRequestRenderRunnable, mThemeColorProvider, + () + -> false, + mControlsVisibilityDelegate, mFocusFunction, mAppMenuSupplier, mResources); + } + + @Test + public void testInitialization() { + mAppMenuSupplier.set(mAppMenuCoordinator); + verify(mAppMenuHandler).addObserver(mMenuButtonMediator); + verify(mAppMenuHandler).createAppMenuButtonHelper(); + } + + @Test + public void testAppMenuVisiblityChange_badgeShowing() { + mAppMenuSupplier.set(mAppMenuCoordinator); + doReturn(42) + .when(mControlsVisibilityDelegate) + .showControlsPersistentAndClearOldToken(TokenHolder.INVALID_TOKEN); + mPropertyModel.set( + MenuButtonProperties.SHOW_UPDATE_BADGE, new ShowBadgeProperty(true, false)); + mMenuButtonMediator.onMenuVisibilityChanged(true); + + verify(mFocusFunction).setFocus(false, LocationBar.OmniboxFocusReason.UNFOCUS); + assertFalse(mPropertyModel.get(MenuButtonProperties.SHOW_UPDATE_BADGE).mShowUpdateBadge); + verify(mUpdateMenuItemHelper).onMenuButtonClicked(); + + mMenuButtonMediator.onMenuVisibilityChanged(false); + verify(mControlsVisibilityDelegate).releasePersistentShowingToken(42); + } + + @Test + public void testAppMenuHighlightChange() { + mAppMenuSupplier.set(mAppMenuCoordinator); + + doReturn(42) + .when(mControlsVisibilityDelegate) + .showControlsPersistentAndClearOldToken(TokenHolder.INVALID_TOKEN); + + mMenuButtonMediator.onMenuHighlightChanged(true); + assertTrue(mPropertyModel.get(MenuButtonProperties.IS_HIGHLIGHTING)); + + mMenuButtonMediator.onMenuHighlightChanged(false); + assertFalse(mPropertyModel.get(MenuButtonProperties.IS_HIGHLIGHTING)); + verify(mControlsVisibilityDelegate).releasePersistentShowingToken(42); + } + + @Test + public void testAppMenuUpdateBadge() { + mAppMenuSupplier.set(mAppMenuCoordinator); + + doReturn(true).when(mActivity).isDestroyed(); + mMenuButtonMediator.updateStateChanged(); + + assertFalse(mPropertyModel.get(MenuButtonProperties.SHOW_UPDATE_BADGE).mShowUpdateBadge); + verify(mRequestRenderRunnable, never()).run(); + + doReturn(false).when(mActivity).isDestroyed(); + mMenuButtonMediator.updateStateChanged(); + + assertFalse(mPropertyModel.get(MenuButtonProperties.SHOW_UPDATE_BADGE).mShowUpdateBadge); + verify(mRequestRenderRunnable, never()).run(); + + mMenuUiState.buttonState = new UpdateMenuItemHelper.MenuButtonState(); + mMenuButtonMediator.updateStateChanged(); + + assertTrue(mPropertyModel.get(MenuButtonProperties.SHOW_UPDATE_BADGE).mShowUpdateBadge); + verify(mRequestRenderRunnable).run(); + } + + @Test + public void testAppMenuUpdateBadge_activityShouldNotShow() { + MenuButtonMediator newMediator = new MenuButtonMediator(mPropertyModel, false, + () + -> false, + mRequestRenderRunnable, mThemeColorProvider, + () + -> false, + mControlsVisibilityDelegate, mFocusFunction, mAppMenuSupplier, mResources); + doReturn(true).when(mActivity).isDestroyed(); + newMediator.updateStateChanged(); + + assertFalse(mPropertyModel.get(MenuButtonProperties.SHOW_UPDATE_BADGE).mShowUpdateBadge); + verify(mRequestRenderRunnable, never()).run(); + + doReturn(false).when(mActivity).isDestroyed(); + newMediator.updateStateChanged(); + + assertFalse(mPropertyModel.get(MenuButtonProperties.SHOW_UPDATE_BADGE).mShowUpdateBadge); + verify(mRequestRenderRunnable, never()).run(); + + mMenuUiState.buttonState = new UpdateMenuItemHelper.MenuButtonState(); + newMediator.updateStateChanged(); + + assertFalse(mPropertyModel.get(MenuButtonProperties.SHOW_UPDATE_BADGE).mShowUpdateBadge); + verify(mRequestRenderRunnable, never()).run(); + } + + @Test + public void testDestroyIsSafe() { + mMenuButtonMediator.destroy(); + // It should be crash-safe to call public methods, but the results aren't meaningful. + mMenuButtonMediator.getMenuButtonHelperSupplier(); + mMenuButtonMediator.onMenuHighlightChanged(true); + mMenuButtonMediator.onMenuVisibilityChanged(false); + mMenuButtonMediator.onNativeInitialized(); + mMenuButtonMediator.setAppMenuUpdateBadgeSuppressed(true); + mMenuButtonMediator.updateReloadingState(true); + mMenuButtonMediator.updateStateChanged(); + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonTest.java index a4f681e..1937e8b7 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonTest.java
@@ -92,7 +92,7 @@ ShadowDrawable darkDrawable = shadowOf(ApiCompatibilityUtils.getDrawable( mActivity.getResources(), mMenuUiState.buttonState.darkBadgeIcon)); - mMenuButton.showAppMenuUpdateBadgeIfAvailable(false); + mMenuButton.showAppMenuUpdateBadge(false); ShadowDrawable drawnDrawable = shadowOf(mMenuButton.getTabSwitcherAnimationDrawable()); assertEquals(drawnDrawable.getCreatedFromResId(), darkDrawable.getCreatedFromResId()); assertNotEquals(drawnDrawable.getCreatedFromResId(), lightDrawable.getCreatedFromResId()); @@ -105,8 +105,7 @@ @Test public void testDrawTabSwitcherAnimationOverlay_updateBadgeNotAvailable() { - mMenuUiState.buttonState = null; - mMenuButton.showAppMenuUpdateBadgeIfAvailable(false); + mMenuButton.removeAppMenuUpdateBadge(false); Bitmap drawnBitmap = ((BitmapDrawable) mMenuButton.getTabSwitcherAnimationDrawable()).getBitmap(); @@ -117,8 +116,7 @@ @Test public void testDrawTabSwitcherAnimationOverlay_correctBoundsAfterThemeChange() { - mMenuUiState.buttonState = null; - mMenuButton.showAppMenuUpdateBadgeIfAvailable(false); + mMenuButton.removeAppMenuUpdateBadge(false); mMenuButton.onTintChanged(mColorStateList, true); // Run a manual layout pass so that mMenuButton's children get assigned sizes.
diff --git a/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkConstants.java b/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkConstants.java index 9751a64..0171d3f 100644 --- a/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkConstants.java +++ b/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkConstants.java
@@ -33,6 +33,7 @@ "org.chromium.chrome.browser.webapk.splash_provided_by_webapk"; // Tells the host browser to relaunch the WebAPK. public static final String EXTRA_RELAUNCH = "org.chromium.webapk.relaunch"; + public static final String EXTRA_IS_WEBAPK = "org.chromium.webapk.is_webapk"; // Must be kept in sync with chrome/browser/android/shortcut_info.h. public static final int SHORTCUT_SOURCE_UNKNOWN = 0;
diff --git a/chrome/android/webapk/shell_apk/AndroidManifest.xml b/chrome/android/webapk/shell_apk/AndroidManifest.xml index a1d47fd..7d43085 100644 --- a/chrome/android/webapk/shell_apk/AndroidManifest.xml +++ b/chrome/android/webapk/shell_apk/AndroidManifest.xml
@@ -59,6 +59,10 @@ {{{raw_intent_filters}}} </activity> + <activity android:name="org.chromium.webapk.shell_apk.ManageDataLauncherActivity" + android:theme="@android:style/Theme.Translucent.NoTitleBar"> + </activity> + <activity android:name="org.chromium.webapk.shell_apk.h2o.H2OOpaqueMainActivity" android:theme="@style/SplashTheme" android:relinquishTaskIdentity="true"
diff --git a/chrome/android/webapk/shell_apk/BUILD.gn b/chrome/android/webapk/shell_apk/BUILD.gn index 79d6fad..36358c0 100644 --- a/chrome/android/webapk/shell_apk/BUILD.gn +++ b/chrome/android/webapk/shell_apk/BUILD.gn
@@ -60,6 +60,7 @@ "src/org/chromium/webapk/shell_apk/IdentityService.java", "src/org/chromium/webapk/shell_apk/InstallHostBrowserDialog.java", "src/org/chromium/webapk/shell_apk/LaunchHostBrowserSelector.java", + "src/org/chromium/webapk/shell_apk/ManageDataLauncherActivity.java", "src/org/chromium/webapk/shell_apk/TransparentLauncherActivity.java", "src/org/chromium/webapk/shell_apk/WebApkSharedPreferences.java", "src/org/chromium/webapk/shell_apk/WebApkUtils.java", @@ -76,6 +77,7 @@ "//chrome/android/webapk/libs/common:splash_java", "//components/webapk/android/libs/common:java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_sdk/androidx_browser:androidx_browser_java", ] } } @@ -151,6 +153,7 @@ android_resources(_resources_target_name) { create_srcjar = false sources = [ + "res/drawable-hdpi/ic_site_settings.png", "res/drawable-hdpi/last_resort_runtime_host_logo.png", "res/drawable-hdpi/notification_badge.png", "res/drawable-hdpi/shortcut_1_icon.png", @@ -158,24 +161,28 @@ "res/drawable-hdpi/shortcut_3_icon.png", "res/drawable-hdpi/shortcut_4_icon.png", "res/drawable-hdpi/splash_icon.xml", + "res/drawable-mdpi/ic_site_settings.png", "res/drawable-mdpi/notification_badge.png", "res/drawable-mdpi/shortcut_1_icon.png", "res/drawable-mdpi/shortcut_2_icon.png", "res/drawable-mdpi/shortcut_3_icon.png", "res/drawable-mdpi/shortcut_4_icon.png", "res/drawable-mdpi/splash_icon.xml", + "res/drawable-xhdpi/ic_site_settings.png", "res/drawable-xhdpi/notification_badge.png", "res/drawable-xhdpi/shortcut_1_icon.png", "res/drawable-xhdpi/shortcut_2_icon.png", "res/drawable-xhdpi/shortcut_3_icon.png", "res/drawable-xhdpi/shortcut_4_icon.png", "res/drawable-xhdpi/splash_icon.xml", + "res/drawable-xxhdpi/ic_site_settings.png", "res/drawable-xxhdpi/notification_badge.png", "res/drawable-xxhdpi/shortcut_1_icon.png", "res/drawable-xxhdpi/shortcut_2_icon.png", "res/drawable-xxhdpi/shortcut_3_icon.png", "res/drawable-xxhdpi/shortcut_4_icon.png", "res/drawable-xxhdpi/splash_icon.xml", + "res/drawable-xxxhdpi/ic_site_settings.png", "res/drawable-xxxhdpi/notification_badge.png", "res/drawable-xxxhdpi/shortcut_1_icon.png", "res/drawable-xxxhdpi/shortcut_2_icon.png",
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java index ea14a9a1..4272935 100644 --- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java +++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java
@@ -4,6 +4,12 @@ package org.chromium.webapk.shell_apk.h2o; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import static org.chromium.webapk.shell_apk.ManageDataLauncherActivity.CHROMIUM_VERSION_SUPPORTS_WEBAPK_MANAGE_SPACE; +import static org.chromium.webapk.shell_apk.ManageDataLauncherActivity.SITE_SETTINGS_SHORTCUT_ID; + import android.app.Activity; import android.app.ActivityManager; import android.content.ComponentName; @@ -11,6 +17,8 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.content.pm.ShortcutInfo; +import android.content.pm.ShortcutManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -40,6 +48,8 @@ import org.chromium.webapk.test.WebApkTestHelper; import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; /** Tests launching WebAPK. */ @RunWith(LocalRobolectricTestRunner.class) @@ -89,8 +99,8 @@ ArrayList<Intent> launchedIntents = launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */, - true /* browserCompatibleWithSplashActivity */, launchIntent, - H2OTransparentLauncherActivity.class); + launchIntent, H2OTransparentLauncherActivity.class, + HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH); Assert.assertEquals(1, launchedIntents.size()); assertIntentIsForBrowserLaunch(launchedIntents.get(0), deepLinkUrl); @@ -115,18 +125,17 @@ launchIntent.setPackage(sWebApkPackageName); ArrayList<Intent> launchedIntents; - launchedIntents = - launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */, - false /* browserCompatibleWithSplashActivity */, launchIntent, - H2OTransparentLauncherActivity.class); + launchedIntents = launchAndCheckBrowserLaunched( + false /* opaqueMainActivityInitiallyEnabled */, launchIntent, + H2OTransparentLauncherActivity.class, BROWSER_H2O_INCOMPATIBLE_VERSION); Assert.assertEquals(1, launchedIntents.size()); assertIntentIsForBrowserLaunch(launchedIntents.get(0), deepLinkUrl); assertOnlyEnabledMainIntentHandler(H2OMainActivity.class); launchedIntents = launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */, - true /* browserCompatibleWithSplashActivity */, launchIntent, - H2OTransparentLauncherActivity.class); + launchIntent, H2OTransparentLauncherActivity.class, + HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH); Assert.assertEquals(5, launchedIntents.size()); assertIntentComponentClassNameEquals(H2OMainActivity.class, launchedIntents.get(0)); Assert.assertEquals(BROWSER_PACKAGE_NAME, launchedIntents.get(1).getPackage()); @@ -136,10 +145,9 @@ assertIntentIsForBrowserLaunch(launchedIntents.get(4), deepLinkUrl); assertOnlyEnabledMainIntentHandler(H2OOpaqueMainActivity.class); - launchedIntents = - launchAndCheckBrowserLaunched(true /* opaqueMainActivityInitiallyEnabled */, - false /* browserCompatibleWithSplashActivity */, launchIntent, - H2OTransparentLauncherActivity.class); + launchedIntents = launchAndCheckBrowserLaunched( + true /* opaqueMainActivityInitiallyEnabled */, launchIntent, + H2OTransparentLauncherActivity.class, BROWSER_H2O_INCOMPATIBLE_VERSION); Assert.assertEquals(2, launchedIntents.size()); assertIntentComponentClassNameEquals(SplashActivity.class, launchedIntents.get(0)); assertIntentIsForBrowserLaunch(launchedIntents.get(1), deepLinkUrl); @@ -147,8 +155,8 @@ launchedIntents = launchAndCheckBrowserLaunched(true /* opaqueMainActivityInitiallyEnabled */, - true /* browserCompatibleWithSplashActivity */, launchIntent, - H2OTransparentLauncherActivity.class); + launchIntent, H2OTransparentLauncherActivity.class, + HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH); Assert.assertEquals(2, launchedIntents.size()); assertIntentComponentClassNameEquals(SplashActivity.class, launchedIntents.get(0)); assertIntentIsForBrowserLaunch(launchedIntents.get(1), deepLinkUrl); @@ -166,16 +174,14 @@ ArrayList<Intent> launchedIntents; launchedIntents = launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */, - false /* browserCompatibleWithSplashActivity */, launchIntent, - H2OMainActivity.class); + launchIntent, H2OMainActivity.class, BROWSER_H2O_INCOMPATIBLE_VERSION); Assert.assertEquals(1, launchedIntents.size()); assertIntentIsForBrowserLaunch(launchedIntents.get(0), DEFAULT_START_URL); assertOnlyEnabledMainIntentHandler(H2OMainActivity.class); - launchedIntents = - launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */, - true /* browserCompatibleWithSplashActivity */, launchIntent, - H2OMainActivity.class); + launchedIntents = launchAndCheckBrowserLaunched( + false /* opaqueMainActivityInitiallyEnabled */, launchIntent, H2OMainActivity.class, + HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH); Assert.assertEquals(4, launchedIntents.size()); Assert.assertEquals(BROWSER_PACKAGE_NAME, launchedIntents.get(0).getPackage()); assertIntentComponentClassNameEquals( @@ -184,10 +190,9 @@ assertIntentIsForBrowserLaunch(launchedIntents.get(3), DEFAULT_START_URL); assertOnlyEnabledMainIntentHandler(H2OOpaqueMainActivity.class); - launchedIntents = - launchAndCheckBrowserLaunched(true /* opaqueMainActivityInitiallyEnabled */, - false /* browserCompatibleWithSplashActivity */, launchIntent, - H2OOpaqueMainActivity.class); + launchedIntents = launchAndCheckBrowserLaunched( + true /* opaqueMainActivityInitiallyEnabled */, launchIntent, + H2OOpaqueMainActivity.class, BROWSER_H2O_INCOMPATIBLE_VERSION); Assert.assertEquals(2, launchedIntents.size()); assertIntentComponentClassNameEquals(SplashActivity.class, launchedIntents.get(0)); assertIntentIsForBrowserLaunch(launchedIntents.get(1), DEFAULT_START_URL); @@ -195,8 +200,8 @@ launchedIntents = launchAndCheckBrowserLaunched(true /* opaqueMainActivityInitiallyEnabled */, - true /* browserCompatibleWithSplashActivity */, launchIntent, - H2OOpaqueMainActivity.class); + launchIntent, H2OOpaqueMainActivity.class, + HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH); Assert.assertEquals(2, launchedIntents.size()); assertIntentComponentClassNameEquals(SplashActivity.class, launchedIntents.get(0)); assertIntentIsForBrowserLaunch(launchedIntents.get(1), DEFAULT_START_URL); @@ -227,10 +232,9 @@ launchIntent.setComponent(new ComponentName(sWebApkPackageName, shareActivityClassName)); launchIntent.putExtra(Intent.EXTRA_TEXT, "subject_value"); - ArrayList<Intent> launchedIntents = - launchAndCheckBrowserLaunched(true /* opaqueMainActivityInitiallyEnabled */, - false /* browserCompatibleWithSplashActivity */, launchIntent, - H2OTransparentLauncherActivity.class); + ArrayList<Intent> launchedIntents = launchAndCheckBrowserLaunched( + true /* opaqueMainActivityInitiallyEnabled */, launchIntent, + H2OTransparentLauncherActivity.class, BROWSER_H2O_INCOMPATIBLE_VERSION); Assert.assertTrue(launchedIntents.size() > 1); Intent browserLaunchIntent = launchedIntents.get(launchedIntents.size() - 1); @@ -257,8 +261,8 @@ ArrayList<Intent> launchedIntents = launchAndCheckBrowserLaunched(true /* opaqueMainActivityInitiallyEnabled */, - true /* browserCompatibleWithSplashActivity */, launchIntent, - H2OTransparentLauncherActivity.class); + launchIntent, H2OTransparentLauncherActivity.class, + HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH); Assert.assertTrue(launchedIntents.size() > 1); Intent browserLaunchIntent = launchedIntents.get(launchedIntents.size() - 1); @@ -284,8 +288,8 @@ ArrayList<Intent> launchedIntents = launchAndCheckBrowserLaunched(true /* opaqueMainActivityInitiallyEnabled */, - true /* browserCompatibleWithSplashActivity */, launchIntent, - H2OTransparentLauncherActivity.class); + launchIntent, H2OTransparentLauncherActivity.class, + HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH); Assert.assertTrue(launchedIntents.size() > 1); Intent browserLaunchIntent = launchedIntents.get(launchedIntents.size() - 1); @@ -384,8 +388,8 @@ ArrayList<Intent> launchedIntents = launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */, - true /* browserCompatibleWithSplashActivity */, launchIntent, - H2OTransparentLauncherActivity.class); + launchIntent, H2OTransparentLauncherActivity.class, + HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH); Assert.assertEquals(1, launchedIntents.size()); assertIntentIsForBrowserLaunch(launchedIntents.get(0), deepLinkUrl); assertOnlyEnabledMainIntentHandler(H2OMainActivity.class); @@ -404,10 +408,9 @@ Intent launchIntent = new Intent(Intent.ACTION_MAIN); launchIntent.setPackage(sWebApkPackageName); - ArrayList<Intent> launchedIntents = - launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */, - true /* browserCompatibleWithSplashActivity */, launchIntent, - H2OMainActivity.class); + ArrayList<Intent> launchedIntents = launchAndCheckBrowserLaunched( + false /* opaqueMainActivityInitiallyEnabled */, launchIntent, H2OMainActivity.class, + HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH); Assert.assertEquals(1, launchedIntents.size()); assertIntentIsForBrowserLaunch(launchedIntents.get(0), DEFAULT_START_URL); assertOnlyEnabledMainIntentHandler(H2OMainActivity.class); @@ -481,6 +484,78 @@ RuntimeEnvironment.application, true /* isNewStyleWebApk */)); } + /** + * Tests that we add site settings shortcuts both when + * opaque main activity is enabled and when it is not enabled. + */ + @Test + @Config(sdk = Build.VERSION_CODES.N_MR1) + public void testAddsSiteSettings() { + registerWebApk(true /* isNewStyleWebApk */); + + Intent launchIntent = new Intent(Intent.ACTION_MAIN); + launchIntent.setPackage(sWebApkPackageName); + + launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */, launchIntent, + H2OMainActivity.class, CHROMIUM_VERSION_SUPPORTS_WEBAPK_MANAGE_SPACE); + + ShortcutManager shortcutManager = mAppContext.getSystemService(ShortcutManager.class); + assertTrue(containsSiteSettingsDynamicShortcut(shortcutManager)); + + shortcutManager.removeAllDynamicShortcuts(); + + launchAndCheckBrowserLaunched(true /* opaqueMainActivityInitiallyEnabled */, launchIntent, + H2OOpaqueMainActivity.class, CHROMIUM_VERSION_SUPPORTS_WEBAPK_MANAGE_SPACE); + assertTrue(containsSiteSettingsDynamicShortcut(shortcutManager)); + } + + /** + * Tests that we remove the shortcut in the case that it was previously + * added but the current version of Chrome no longer supports it. + */ + @Test + @Config(sdk = Build.VERSION_CODES.N_MR1) + public void testRemovesSiteSettingsIfChromeVersionLow() { + registerWebApk(true /* isNewStyleWebApk */); + + Intent launchIntent = new Intent(Intent.ACTION_MAIN); + launchIntent.setPackage(sWebApkPackageName); + + launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */, launchIntent, + H2OMainActivity.class, CHROMIUM_VERSION_SUPPORTS_WEBAPK_MANAGE_SPACE); + + ShortcutManager shortcutManager = mAppContext.getSystemService(ShortcutManager.class); + assertTrue(containsSiteSettingsDynamicShortcut(shortcutManager)); + + launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */, launchIntent, + H2OMainActivity.class, CHROMIUM_VERSION_SUPPORTS_WEBAPK_MANAGE_SPACE - 1); + assertFalse(containsSiteSettingsDynamicShortcut(shortcutManager)); + } + + /** Tests that we do not attempt to add a shortcut on Android versions lower than N. */ + @Test + @Config(sdk = Build.VERSION_CODES.LOLLIPOP) + public void testDoesNotAddSiteSettingsWhenSdkLow() { + registerWebApk(true /* isNewStyleWebApk */); + + Intent launchIntent = new Intent(Intent.ACTION_MAIN); + launchIntent.setPackage(sWebApkPackageName); + + launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */, launchIntent, + H2OMainActivity.class, CHROMIUM_VERSION_SUPPORTS_WEBAPK_MANAGE_SPACE); + + // There is no shortcut manager in Android M. Therefore if + // this test passes, then we did not attempt to add the shortcut. + } + + private static boolean containsSiteSettingsDynamicShortcut(ShortcutManager shortcutManager) { + List<String> shortcutIDs = shortcutManager.getDynamicShortcuts() + .stream() + .map(ShortcutInfo::getId) + .collect(Collectors.toList()); + return shortcutIDs.contains(SITE_SETTINGS_SHORTCUT_ID); + } + /** Checks the name of the intent's component class name. */ private static void assertIntentComponentClassNameEquals(Class expectedClass, Intent intent) { Assert.assertEquals(expectedClass.getName(), intent.getComponent().getClassName()); @@ -511,22 +586,18 @@ * browser is launched and which activities are enabled after the browser launch. * @param opaqueMainActivityInitiallyEnabled Whether H2OOpaqueActivity is enabled at the * beginning of the test case. - * @param browserCompatibleWithSplashActivity Whether the host browser supports the ShellAPK - * showing the splash screen. * @param launchIntent Intent to launch. * @param launchActivity Activity which should receive the launch intent. + * @param browserVersion The version of the Chromium browser to install. * @return List of launched activity intents (including the host browser launch intent). */ private ArrayList<Intent> launchAndCheckBrowserLaunched( - boolean opaqueMainActivityInitiallyEnabled, boolean browserCompatibleWithSplashActivity, - Intent launchIntent, Class<? extends Activity> launchActivity) { + boolean opaqueMainActivityInitiallyEnabled, Intent launchIntent, + Class<? extends Activity> launchActivity, int browserVersion) { changeEnabledActivity(opaqueMainActivityInitiallyEnabled ? H2OOpaqueMainActivity.class : H2OMainActivity.class); - installBrowser(BROWSER_PACKAGE_NAME, - browserCompatibleWithSplashActivity - ? HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH - : BROWSER_H2O_INCOMPATIBLE_VERSION); + installBrowser(BROWSER_PACKAGE_NAME, browserVersion); ArrayList<Intent> launchedIntents = runActivityChain(launchIntent, launchActivity, BROWSER_PACKAGE_NAME);
diff --git a/chrome/android/webapk/shell_apk/res/drawable-hdpi/ic_site_settings.png b/chrome/android/webapk/shell_apk/res/drawable-hdpi/ic_site_settings.png new file mode 100644 index 0000000..ddfa40a --- /dev/null +++ b/chrome/android/webapk/shell_apk/res/drawable-hdpi/ic_site_settings.png Binary files differ
diff --git a/chrome/android/webapk/shell_apk/res/drawable-mdpi/ic_site_settings.png b/chrome/android/webapk/shell_apk/res/drawable-mdpi/ic_site_settings.png new file mode 100644 index 0000000..11bcebf --- /dev/null +++ b/chrome/android/webapk/shell_apk/res/drawable-mdpi/ic_site_settings.png Binary files differ
diff --git a/chrome/android/webapk/shell_apk/res/drawable-xhdpi/ic_site_settings.png b/chrome/android/webapk/shell_apk/res/drawable-xhdpi/ic_site_settings.png new file mode 100644 index 0000000..bfb26bad --- /dev/null +++ b/chrome/android/webapk/shell_apk/res/drawable-xhdpi/ic_site_settings.png Binary files differ
diff --git a/chrome/android/webapk/shell_apk/res/drawable-xxhdpi/ic_site_settings.png b/chrome/android/webapk/shell_apk/res/drawable-xxhdpi/ic_site_settings.png new file mode 100644 index 0000000..52860852 --- /dev/null +++ b/chrome/android/webapk/shell_apk/res/drawable-xxhdpi/ic_site_settings.png Binary files differ
diff --git a/chrome/android/webapk/shell_apk/res/drawable-xxxhdpi/ic_site_settings.png b/chrome/android/webapk/shell_apk/res/drawable-xxxhdpi/ic_site_settings.png new file mode 100644 index 0000000..8cba619 --- /dev/null +++ b/chrome/android/webapk/shell_apk/res/drawable-xxxhdpi/ic_site_settings.png Binary files differ
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java index 720e9b9..db1b0ff7 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java
@@ -34,8 +34,6 @@ * Otherwise, launches the host browser in tabbed mode. */ public static void launch(Activity activity, HostBrowserLauncherParams params) { - Log.v(TAG, "WebAPK Launch URL: " + params.getStartUrl()); - if (HostBrowserUtils.shouldLaunchInTab(params)) { launchInTab(activity.getApplicationContext(), params); return; @@ -48,6 +46,8 @@ /** Launches host browser in WebAPK mode. */ public static void launchBrowserInWebApkMode(Activity activity, HostBrowserLauncherParams params, Bundle extraExtras, int flags, boolean expectResult) { + ManageDataLauncherActivity.updateSiteSettingsShortcut( + activity.getApplicationContext(), params); Intent intent = new Intent(); intent.setAction(ACTION_START_WEBAPK); intent.setPackage(params.getHostBrowserPackageName()); @@ -102,6 +102,7 @@ /** Launches a WebAPK in its runtime host browser as a tab. */ private static void launchInTab(Context context, HostBrowserLauncherParams params) { + ManageDataLauncherActivity.updateSiteSettingsShortcut(context, params); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(params.getStartUrl())); intent.setPackage(params.getHostBrowserPackageName()); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/ManageDataLauncherActivity.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/ManageDataLauncherActivity.java new file mode 100644 index 0000000..211ce8b --- /dev/null +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/ManageDataLauncherActivity.java
@@ -0,0 +1,230 @@ +// Copyright 2020 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.webapk.shell_apk; + +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ShortcutInfo; +import android.content.pm.ShortcutManager; +import android.graphics.drawable.Icon; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.view.Gravity; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.ProgressBar; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.browser.customtabs.CustomTabsClient; +import androidx.browser.customtabs.CustomTabsIntent; +import androidx.browser.customtabs.CustomTabsServiceConnection; +import androidx.browser.customtabs.CustomTabsSession; + +import org.chromium.webapk.lib.common.WebApkConstants; + +import java.util.Collections; + +/** + * A convenience class for adding site setting shortcuts into WebApks. + * The shortcut opens the web browser's site settings for the url + * associated to the WebApk. + */ +public class ManageDataLauncherActivity extends Activity { + private static final String TAG = "ManageDataLauncher"; + + public static final String ACTION_SITE_SETTINGS = + "android.support.customtabs.action.ACTION_MANAGE_TRUSTED_WEB_ACTIVITY_DATA"; + + public static final String SITE_SETTINGS_SHORTCUT_ID = + "android.support.customtabs.action.SITE_SETTINGS_SHORTCUT"; + + private static final String EXTRA_SITE_SETTINGS_URL = "SITE_SETTINGS_URL"; + private static final String EXTRA_PROVIDER_PACKAGE = "PROVIDER_PACKAGE"; + + public static final int CHROMIUM_VERSION_SUPPORTS_WEBAPK_MANAGE_SPACE = 87; + + @Nullable + private String mProviderPackage; + + @Nullable + private CustomTabsServiceConnection mConnection; + + @Nullable + private Uri mUrl; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mProviderPackage = getIntent().getStringExtra(EXTRA_PROVIDER_PACKAGE); + mUrl = Uri.parse(getIntent().getStringExtra(EXTRA_SITE_SETTINGS_URL)); + + if (!supportsManageSpace(this, mProviderPackage)) { + handleNoSupportForManageSpace(); + return; + } + setContentView(createLoadingView()); + + mConnection = new CustomTabsServiceConnection() { + @Override + public void onCustomTabsServiceConnected( + ComponentName componentName, CustomTabsClient client) { + if (!isFinishing()) { + launchSettings(client.newSession(null)); + } + } + + @Override + public void onServiceDisconnected(ComponentName componentName) {} + }; + CustomTabsClient.bindCustomTabsService(this, mProviderPackage, mConnection); + } + + /** + * Returns the url of the page for which the settings will be shown. + * The url must be provided as an intent extra to {@link ManageDataLauncherActivity}. + */ + @Nullable + private Uri getWebApkStartUrl() { + return mUrl; + } + + /** + * Returns a view with a loading spinner. + */ + @NonNull + private View createLoadingView() { + ProgressBar progressBar = new ProgressBar(this); + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); + params.gravity = Gravity.CENTER; + progressBar.setLayoutParams(params); + FrameLayout layout = new FrameLayout(this); + layout.addView(progressBar); + return layout; + } + + /** + * Called if a TWA provider doesn't support manage space feature. The default behavior is to + * show a toast telling the user where the data is stored. + */ + private void handleNoSupportForManageSpace() { + String appName; + try { + ApplicationInfo info = getPackageManager().getApplicationInfo(mProviderPackage, 0); + appName = getPackageManager().getApplicationLabel(info).toString(); + } catch (PackageManager.NameNotFoundException e) { + appName = mProviderPackage; + } + + Toast.makeText(this, getString(R.string.no_support_for_manage_space, appName), + Toast.LENGTH_LONG) + .show(); + finish(); + } + + @Override + protected void onStop() { + super.onStop(); + if (mConnection != null) { + unbindService(mConnection); + } + finish(); + } + + private void launchSettings(CustomTabsSession session) { + boolean success = + launchBrowserSiteSettings(this, session, mProviderPackage, getWebApkStartUrl()); + if (success) { + finish(); + } else { + handleNoSupportForManageSpace(); + } + } + + private static boolean launchBrowserSiteSettings( + Activity activity, CustomTabsSession session, String packageName, Uri defaultUri) { + // A Custom Tabs Session is required so that the browser can verify this app's identity. + Intent intent = new CustomTabsIntent.Builder().setSession(session).build().intent; + intent.setAction(ACTION_SITE_SETTINGS); + intent.setPackage(packageName); + intent.setData(defaultUri); + intent.putExtra(WebApkConstants.EXTRA_IS_WEBAPK, true); + try { + activity.startActivity(intent); + return true; + } catch (ActivityNotFoundException e) { + return false; + } + } + + private static boolean supportsManageSpace(Context context, String providerPackage) { + return HostBrowserUtils.queryHostBrowserMajorChromiumVersion(context, providerPackage) + >= CHROMIUM_VERSION_SUPPORTS_WEBAPK_MANAGE_SPACE; + } + + /** + * Returns the {@link ShortcutInfo} for a dynamic shortcut into site settings, + * provided that {@link ManageDataLauncherActivity} is present in the manifest + * and an Intent for managing site settings is available. + * + * Otherwise returns null if {@link ManageDataLauncherActivity} is not launchable + * or if shortcuts are not supported by the Android SDK version. + * + * The shortcut returned does not specify an activity. Thus when the shortcut is added, + * the app's main activity will be used by default. This activity needs to define the + * MAIN action and LAUNCHER category in order to attach the shortcut. + */ + @NonNull + @TargetApi(Build.VERSION_CODES.N_MR1) + private static ShortcutInfo createSiteSettingsShortcutInfo( + Context context, String url, String providerPackage) { + Intent siteSettingsIntent = new Intent(context, ManageDataLauncherActivity.class); + // Intent needs to have an action set, we can set an arbitrary action. + siteSettingsIntent.setAction(ACTION_SITE_SETTINGS); + siteSettingsIntent.putExtra(EXTRA_SITE_SETTINGS_URL, url); + siteSettingsIntent.putExtra(EXTRA_PROVIDER_PACKAGE, providerPackage); + + return new ShortcutInfo.Builder(context, SITE_SETTINGS_SHORTCUT_ID) + .setShortLabel(context.getString(R.string.site_settings_short_label)) + .setLongLabel(context.getString(R.string.site_settings_long_label)) + .setIcon(Icon.createWithResource(context, R.drawable.ic_site_settings)) + .setIntent(siteSettingsIntent) + .build(); + } + + /** + * Adds dynamic shortcut to site settings if the twa provider and android version supports it. + * + * Removes previously added site settings shortcut if it is no longer supported, e.g. the user + * changed their default browser. + */ + public static void updateSiteSettingsShortcut( + Context context, HostBrowserLauncherParams params) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) return; + + ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class); + + // Remove potentially existing shortcut if package does not support shortcuts. + if (!supportsManageSpace(context, params.getHostBrowserPackageName())) { + shortcutManager.removeDynamicShortcuts(Collections.singletonList( + ManageDataLauncherActivity.SITE_SETTINGS_SHORTCUT_ID)); + return; + } + + ShortcutInfo shortcut = createSiteSettingsShortcutInfo( + context, params.getStartUrl(), params.getHostBrowserPackageName()); + shortcutManager.addDynamicShortcuts(Collections.singletonList(shortcut)); + } +}
diff --git a/chrome/android/webapk/strings/android_webapk_strings.grd b/chrome/android/webapk/strings/android_webapk_strings.grd index 06a43b3..f718b07c 100644 --- a/chrome/android/webapk/strings/android_webapk_strings.grd +++ b/chrome/android/webapk/strings/android_webapk_strings.grd
@@ -167,6 +167,15 @@ </translations> <release allow_pseudo="false" seq="1"> <messages fallback_to_english="true"> + <message name="IDS_SITE_SETTINGS_LONG_LABEL" desc="Site settings Android app shortcut title to display on devices with larger screens. (ideally less than 25 characters)"> + Manage website settings + </message> + <message name="IDS_SITE_SETTINGS_SHORT_LABEL" desc="Site settings Android app shortcut title. (ideally less than 10 characters)"> + Site settings + </message> + <message name="IDS_NO_SUPPORT_FOR_MANAGE_SPACE" desc="Text to show in a toast when a user clicks on a site settings shortcut but managing space is not suported by the browser."> + Managing space not supported by: <ph name="BROWSER_PACKAGE">%1$s<ex>org.chromium.chrome</ex></ph>. + </message> <!-- Select host browser dialog --> <message name="IDS_CHOOSE_HOST_BROWSER_DIALOG_TITLE" desc="Title for the host browser picker dialog, which is used to ask users to pick a browser to launch the installed WebAPK."> <ph name="APP_NAME">%1$s<ex>Progressive Web Apps</ex></ph> requires a web browser
diff --git a/chrome/android/webapk/strings/android_webapk_strings_grd/IDS_NO_SUPPORT_FOR_MANAGE_SPACE.png.sha1 b/chrome/android/webapk/strings/android_webapk_strings_grd/IDS_NO_SUPPORT_FOR_MANAGE_SPACE.png.sha1 new file mode 100644 index 0000000..3a924d2 --- /dev/null +++ b/chrome/android/webapk/strings/android_webapk_strings_grd/IDS_NO_SUPPORT_FOR_MANAGE_SPACE.png.sha1
@@ -0,0 +1 @@ +27bfe4a6c6d5159b982fb1246904e72f9149db09 \ No newline at end of file
diff --git a/chrome/android/webapk/strings/android_webapk_strings_grd/IDS_SITE_SETTINGS_LONG_LABEL.png.sha1 b/chrome/android/webapk/strings/android_webapk_strings_grd/IDS_SITE_SETTINGS_LONG_LABEL.png.sha1 new file mode 100644 index 0000000..f721993 --- /dev/null +++ b/chrome/android/webapk/strings/android_webapk_strings_grd/IDS_SITE_SETTINGS_LONG_LABEL.png.sha1
@@ -0,0 +1 @@ +ac7345c9eee8154458660df14df05782b2678ba8 \ No newline at end of file
diff --git a/chrome/android/webapk/strings/android_webapk_strings_grd/IDS_SITE_SETTINGS_SHORT_LABEL.png.sha1 b/chrome/android/webapk/strings/android_webapk_strings_grd/IDS_SITE_SETTINGS_SHORT_LABEL.png.sha1 new file mode 100644 index 0000000..f721993 --- /dev/null +++ b/chrome/android/webapk/strings/android_webapk_strings_grd/IDS_SITE_SETTINGS_SHORT_LABEL.png.sha1
@@ -0,0 +1 @@ +ac7345c9eee8154458660df14df05782b2678ba8 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index c298f0e..39a77e19 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -1349,6 +1349,7 @@ <message name="IDS_WILCO_NOTIFICATION_LEARN_MORE" desc="Label on button in various Wilco notification."> Learn More </message> + <!-- Multi-profiles related strings, should be synced with corresponding Ash strings until they get removed. --> <message name="IDS_MULTI_PROFILES_RESTRICTED_POLICY_TITLE" desc="Text that is shown on the title of the bubble shown for user pod which is not allowed in multi-profiles session."> Can't set up multiple sign-in </message>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 56f377a..5b823748 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -10682,7 +10682,7 @@ Exit Incognito </message> <message name="IDS_INCOGNITO_PROFILE_MENU_CLOSE_BUTTON_NEW" desc="The text of the button offering to close all incognito windows."> - Close incognito + Close Incognito </message> <!-- Guest Profile Menu bubble. --> @@ -10692,10 +10692,10 @@ other {# open windows} } </message> - <message name="IDS_GUEST_PROFILE_MENU_CLOSE_BUTTON" desc="The text of the button offering to close all guest windows."> + <message name="IDS_GUEST_PROFILE_MENU_CLOSE_BUTTON" desc="The text of the button offering to close all guest windows. The number in ICU syntax represents the number of open guest windows, but it is not used in the English text and can be used to choose singular/plural in translation to other languages, if needed.[ICU Syntax]"> {0, plural, - =1 {Close guest} - other {Close guest} + =1 {Close Guest} + other {Close Guest} } </message>
diff --git a/chrome/app/generated_resources_grd/IDS_GUEST_PROFILE_MENU_CLOSE_BUTTON.png.sha1 b/chrome/app/generated_resources_grd/IDS_GUEST_PROFILE_MENU_CLOSE_BUTTON.png.sha1 index 08c7a63e..7d41243 100644 --- a/chrome/app/generated_resources_grd/IDS_GUEST_PROFILE_MENU_CLOSE_BUTTON.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_GUEST_PROFILE_MENU_CLOSE_BUTTON.png.sha1
@@ -1 +1 @@ -d5e17649bc7e9f520e5b682e04146df8a2e1e5c4 \ No newline at end of file +3499540316dd284fdafc7e51eca3f422c326da2d \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_INCOGNITO_PROFILE_MENU_CLOSE_BUTTON_NEW.png.sha1 b/chrome/app/generated_resources_grd/IDS_INCOGNITO_PROFILE_MENU_CLOSE_BUTTON_NEW.png.sha1 index 316baa2..9bed08b 100644 --- a/chrome/app/generated_resources_grd/IDS_INCOGNITO_PROFILE_MENU_CLOSE_BUTTON_NEW.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_INCOGNITO_PROFILE_MENU_CLOSE_BUTTON_NEW.png.sha1
@@ -1 +1 @@ -2baf2a11aadf5ce9d562f1417ee7d3ab2c404779 \ No newline at end of file +6bb00a404baf88687babf5a74b01a0802ba7bd52 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 3bb0e5f..1fe267a 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -169,8 +169,6 @@ "background_sync/background_sync_controller_impl.h", "background_sync/background_sync_metrics.cc", "background_sync/background_sync_metrics.h", - "background_sync/background_sync_permission_context.cc", - "background_sync/background_sync_permission_context.h", "background_sync/periodic_background_sync_permission_context.cc", "background_sync/periodic_background_sync_permission_context.h", "bad_message.cc", @@ -1939,6 +1937,7 @@ "//components/assist_ranker", "//components/autofill/content/browser", "//components/autofill/core/browser", + "//components/background_sync", "//components/background_task_scheduler", "//components/blocked_content", "//components/blocklist/opt_out_blocklist", @@ -2151,6 +2150,7 @@ "//components/user_manager", "//components/user_prefs", "//components/variations", + "//components/variations:variations_mojom", "//components/variations/field_trial_config", "//components/variations/net", "//components/variations/proto", @@ -3127,6 +3127,7 @@ "//components/assist_ranker/proto", "//components/autofill_assistant/browser", "//components/autofill_assistant/browser:proto", + "//components/background_sync", "//components/bookmarks/common/android", "//components/browser_ui/contacts_picker/android", "//components/browser_ui/photo_picker/android", @@ -3952,7 +3953,6 @@ "//chrome/services/sharing/public/cpp", "//chrome/services/sharing/public/mojom", "//chrome/services/sharing/public/proto", - "//chrome/services/speech:buildflags", "//components/download/quarantine", "//components/feedback", "//components/image_fetcher/core",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 0c085e5..1793e97d 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -33,7 +33,6 @@ "+chrome/services/printing/public", "+chrome/services/sharing/public", "+chrome/services/removable_storage_writer/public", - "+chrome/services/speech/buildflags.h", "+chrome/services/util_win/public", "+chromeos", "+components/about_ui", @@ -47,6 +46,7 @@ "+components/autofill/core/browser", "+components/autofill/core/common", "+components/background_task_scheduler", + "+components/background_sync", "+components/base32", "+components/blocked_content", "+components/blocklist/opt_out_blocklist",
diff --git a/chrome/browser/background_sync/OWNERS b/chrome/browser/background_sync/OWNERS index ef947b20..557d3a6b 100644 --- a/chrome/browser/background_sync/OWNERS +++ b/chrome/browser/background_sync/OWNERS
@@ -1,10 +1 @@ -iclelland@chromium.org -jkarlin@chromium.org -nator@chromium.org -peter@chromium.org -rayankans@chromium.org - -per-file *permission_context*=file://components/permissions/PERMISSIONS_OWNERS - -# COMPONENT: Blink>BackgroundSync -# TEAM: platform-capabilities@chromium.org +file://components/background_sync/OWNERS
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc index 05988e8..126b9b5 100644 --- a/chrome/browser/chrome_browser_interface_binders.cc +++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -120,6 +120,7 @@ #include "chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.h" #include "chrome/browser/ui/webui/read_later/read_later.mojom.h" #include "chrome/browser/ui/webui/read_later/read_later_ui.h" +#include "chrome/browser/ui/webui/settings/settings_ui.h" #include "chrome/browser/ui/webui/tab_search/tab_search.mojom.h" #include "chrome/browser/ui/webui/tab_search/tab_search_ui.h" #include "chrome/common/caption.mojom.h" @@ -609,7 +610,7 @@ customize_themes::mojom::CustomizeThemesHandlerFactory, NewTabPageUI #if !defined(OS_CHROMEOS) , - ProfilePickerUI + ProfilePickerUI, settings::SettingsUI #endif // !defined(OS_CHROMEOS) >(map);
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 2e16364a7..8f912248 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2781,17 +2781,6 @@ } #endif -void ChromeContentBrowserClient::OnSCTReportReady( - content::BrowserContext* browser_context, - const std::string& cache_key) { - auto* sct_reporting_service = - SCTReportingServiceFactory::GetInstance()->GetForBrowserContext( - browser_context); - if (sct_reporting_service) { - sct_reporting_service->OnSCTReportReady(cache_key); - } -} - scoped_refptr<network::SharedURLLoaderFactory> ChromeContentBrowserClient::GetSystemSharedURLLoaderFactory() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 42955c77..f19c06f 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -284,8 +284,6 @@ #if defined(OS_CHROMEOS) void OnTrustAnchorUsed(content::BrowserContext* browser_context) override; #endif - void OnSCTReportReady(content::BrowserContext* browser_context, - const std::string& cache_key) override; scoped_refptr<network::SharedURLLoaderFactory> GetSystemSharedURLLoaderFactory() override; network::mojom::NetworkContext* GetSystemNetworkContext() override;
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_app_list_browsertest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_app_list_browsertest.cc index 7eded55c..9edfff7 100644 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_app_list_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_app_list_browsertest.cc
@@ -12,6 +12,7 @@ #include "ash/public/cpp/test/shell_test_api.h" #include "ash/shell.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/browser.h" @@ -24,6 +25,7 @@ #include "content/public/test/browser_test.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/manager/display_manager.h" @@ -137,6 +139,65 @@ ::testing::Values(kTestAsNormalUser, kTestAsGuestUser)); +class NotificationSpokenFeedbackAppListTest : public SpokenFeedbackAppListTest { + protected: + NotificationSpokenFeedbackAppListTest() { + scoped_features_.InitWithFeatures({::features::kNotificationIndicator}, {}); + } + ~NotificationSpokenFeedbackAppListTest() = default; + + void SetUpCommandLine(base::CommandLine* command_line) override { + SpokenFeedbackAppListTest::SetUpCommandLine(command_line); + command_line->AppendSwitch(ash::switches::kAshEnableTabletMode); + } + + void SetNotificationBadgeForApp(const std::string& id, bool has_badge) { + auto* model = ash::Shell::Get()->app_list_controller()->GetModel(); + auto* item = model->FindItem(id); + + item->UpdateBadgeForTesting(has_badge); + } + + private: + base::test::ScopedFeatureList scoped_features_; +}; + +INSTANTIATE_TEST_SUITE_P(TestAsNormalAndGuestUser, + NotificationSpokenFeedbackAppListTest, + ::testing::Values(kTestAsNormalUser, + kTestAsGuestUser)); + +// Checks that when an app list item with a notification badge is focused, an +// announcement is made that the item has new updates. +IN_PROC_BROWSER_TEST_P(NotificationSpokenFeedbackAppListTest, + AppListItemNotificationBadgeAnnounced) { + PopulateApps(1); + SetNotificationBadgeForApp("Item 0", true); + + EnableChromeVox(); + + sm_.Call( + [this]() { EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); }); + sm_.ExpectSpeech("Shelf"); + // Press space on the launcher button in shelf, this opens peeking + // launcher. + sm_.Call([this]() { SendKeyPressWithSearch(ui::VKEY_SPACE); }); + sm_.ExpectSpeech("Launcher, partial view"); + // Move focus to expand all apps button. + sm_.Call([this]() { SendKeyPressWithSearch(ui::VKEY_UP); }); + sm_.ExpectSpeech("Expand to all apps"); + // Press space on expand arrow to go to fullscreen launcher. + sm_.Call([this]() { SendKeyPressWithSearch(ui::VKEY_SPACE); }); + sm_.ExpectSpeech("Launcher, all apps"); + + // Move focus to 1st app; + sm_.Call([this]() { SendKeyPressWithSearch(ui::VKEY_RIGHT); }); + + // Check that the announcmenet for items with a notification badge occurs. + sm_.ExpectSpeech("Item 0 has new updates."); + sm_.Replay(); +} + // Checks that entering and exiting tablet mode with a browser window open does // not generate an accessibility event. IN_PROC_BROWSER_TEST_P(
diff --git a/chrome/browser/chromeos/login/arc_terms_of_service_browsertest.cc b/chrome/browser/chromeos/login/arc_terms_of_service_browsertest.cc index 53990c8a..c3ca287b 100644 --- a/chrome/browser/chromeos/login/arc_terms_of_service_browsertest.cc +++ b/chrome/browser/chromeos/login/arc_terms_of_service_browsertest.cc
@@ -41,7 +41,6 @@ #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/dbus/session_manager/fake_session_manager_client.h" #include "components/arc/arc_prefs.h" @@ -165,11 +164,7 @@ class ArcTermsOfServiceScreenTest : public OobeBaseTest { public: - ArcTermsOfServiceScreenTest() { - // To reuse existing wizard controller in the flow. - feature_list_.InitAndEnableFeature( - chromeos::features::kOobeScreensPriority); - } + ArcTermsOfServiceScreenTest() = default; ~ArcTermsOfServiceScreenTest() override = default; void RegisterAdditionalRequestHandlers() override { @@ -326,7 +321,6 @@ LoginManagerMixin login_manager_mixin_{&mixin_host_}; - base::test::ScopedFeatureList feature_list_; DISALLOW_COPY_AND_ASSIGN(ArcTermsOfServiceScreenTest); };
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc index 3103d39..9e0f8bca 100644 --- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc +++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
@@ -32,6 +32,18 @@ #include "components/policy/core/common/cloud/device_management_service.h" #include "services/network/public/cpp/shared_url_loader_factory.h" +// This is used for logs that may not be strictly necessary but are of great use +// because they will log whether determinations are needed or not, along with +// some context. The information used to be logged using VLOG(1), and therefore +// was not available in customer logs. Because the only other logs have some +// ambiguity (e.g. there will not be a log if the device decides it does not +// need to make a determination), troubleshooting is difficult. If this changes, +// this can be made VLOG(1) again. +// +// We use LOG(WARNING) to guarantee that the messages will be into feedback +// reports. +#define LOG_DETERMINATION() LOG(WARNING) + namespace chromeos { namespace { @@ -571,7 +583,7 @@ } if (embargo_state == system::FactoryPingEmbargoState::kNotPassed) { LOG(WARNING) << "Skip Initial State Determination because the device is in " - "the embargo period (" + "the embargo period (" << system_clock_log_info << ")."; RecordInitialEnrollmentRequirement( InitialEnrollmentRequirementHistogramValue::kNotRequiredInEmbargoPeriod, @@ -583,14 +595,13 @@ InitialEnrollmentRequirementHistogramValue::kRequired, system_clock_sync_state_); - VLOG(1) << "Initial State Determination required."; return InitialStateDeterminationRequirement::kRequired; } void AutoEnrollmentController::DetermineAutoEnrollmentCheckType() { // Skip everything if neither FRE nor Initial Enrollment are enabled. if (!IsEnabled()) { - LOGIN_LOG(EVENT) << "Auto-enrollment disabled."; + LOG(WARNING) << "Auto-enrollment disabled."; auto_enrollment_check_type_ = AutoEnrollmentCheckType::kNone; return; } @@ -598,7 +609,7 @@ // Skip everything if GAIA is disabled. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kDisableGaiaServices)) { - LOGIN_LOG(EVENT) << "Auto-enrollment disabled: command line (gaia)."; + LOG(WARNING) << "Auto-enrollment disabled: command line (gaia)."; auto_enrollment_check_type_ = AutoEnrollmentCheckType::kNone; return; } @@ -606,11 +617,11 @@ // Determine whether to do an FRE check or an initial state determination. // FRE has precedence since managed devices must go through an FRE check. fre_requirement_ = GetFRERequirement(); - VLOG(1) << FRERequirementToString(fre_requirement_); + LOG_DETERMINATION() << FRERequirementToString(fre_requirement_); if (ShouldDoFRECheck(command_line, fre_requirement_)) { // FRE has precedence over Initial Enrollment. - LOGIN_LOG(EVENT) << "Proceeding with FRE check."; + LOG(WARNING) << "Proceeding with FRE check."; auto_enrollment_check_type_ = AutoEnrollmentCheckType::kForcedReEnrollment; return; } @@ -618,7 +629,7 @@ // The device is in consumer mode, check whether an initial state // determination is in order. if (ShouldDoInitialEnrollmentCheck()) { - LOGIN_LOG(EVENT) << "Proceeding with Initial State Determination."; + LOG(WARNING) << "Proceeding with Initial State Determination."; auto_enrollment_check_type_ = AutoEnrollmentCheckType::kInitialStateDetermination; return; @@ -635,19 +646,19 @@ // Skip FRE check if modulus configuration is not present. if (!command_line->HasSwitch(switches::kEnterpriseEnrollmentInitialModulus) && !command_line->HasSwitch(switches::kEnterpriseEnrollmentModulusLimit)) { - LOGIN_LOG(EVENT) << "FRE disabled through command line (config)."; + LOG(WARNING) << "FRE disabled through command line (config)."; return false; } // Skip FRE check if it is not enabled by command-line switches. if (!IsFREEnabled()) { - LOGIN_LOG(EVENT) << "FRE disabled."; + LOG(WARNING) << "FRE disabled."; return false; } // Skip FRE check if explicitly not required to check. if (fre_requirement == FRERequirement::kExplicitlyNotRequired) { - LOGIN_LOG(EVENT) << "FRE disabled for device in consumer mode."; + LOG(WARNING) << "FRE disabled for device in consumer mode."; return false; } @@ -663,7 +674,7 @@ // Skip Initial State Determination if it is not enabled according to // command-line flags. if (!IsInitialEnrollmentEnabled()) { - VLOG(1) << "Initial Enrollment is disabled."; + LOG(WARNING) << "Initial Enrollment is disabled."; return false; } @@ -671,10 +682,13 @@ // device state. if (GetInitialStateDeterminationRequirement() == InitialStateDeterminationRequirement::kNotRequired) { - VLOG(1) << "Initial State Determination is not required."; + // Warnings have been logged for all the reasons not to do the check. + LOG_DETERMINATION() << "Initial State Determination is not required."; return false; } + // Nothing has been logged, but the caller will log so this can stay as VLOG. + LOG_DETERMINATION() << "Initial State Determination required."; return true; } @@ -705,8 +719,7 @@ } return; case DeviceSettingsService::OWNERSHIP_TAKEN: - LOGIN_LOG(EVENT) - << "Device already owned, skipping auto-enrollment check."; + LOG(WARNING) << "Device already owned, skipping auto-enrollment check."; UpdateState(policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT); return; case DeviceSettingsService::OWNERSHIP_UNKNOWN: @@ -763,7 +776,7 @@ ->GetSharedURLLoaderFactory(), state_keys.front(), power_initial, power_limit); - LOGIN_LOG(EVENT) << "Starting auto-enrollment client for FRE."; + LOG(WARNING) << "Starting auto-enrollment client for FRE."; client_->Start(); } @@ -804,14 +817,14 @@ serial_number, rlz_brand_code, power_initial, power_limit, kInitialEnrollmentModulusPowerOutdatedServer); - LOGIN_LOG(EVENT) << "Starting auto-enrollment client for Initial Enrollment."; + LOG(WARNING) << "Starting auto-enrollment client for Initial Enrollment."; client_->Start(); } void AutoEnrollmentController::UpdateState( policy::AutoEnrollmentState new_state) { - LOGIN_LOG(EVENT) << "New auto-enrollment state: " - << AutoEnrollmentStateToString(new_state); + LOG(WARNING) << "New auto-enrollment state: " + << AutoEnrollmentStateToString(new_state); state_ = new_state; // Stop the safeguard timer once a result comes in.
diff --git a/chrome/browser/chromeos/login/screens/app_downloading_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/app_downloading_screen_browsertest.cc index 07c9ff6..ad2bcc1 100644 --- a/chrome/browser/chromeos/login/screens/app_downloading_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/app_downloading_screen_browsertest.cc
@@ -25,7 +25,6 @@ #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chrome/grit/generated_resources.h" -#include "chromeos/constants/chromeos_features.h" #include "components/arc/arc_prefs.h" #include "components/prefs/pref_service.h" #include "content/public/test/browser_test.h" @@ -35,11 +34,7 @@ class AppDownloadingScreenTest : public OobeBaseTest { public: - AppDownloadingScreenTest() { - // To reuse existing wizard controller in the flow. - feature_list_.InitAndEnableFeature( - chromeos::features::kOobeScreensPriority); - } + AppDownloadingScreenTest() = default; ~AppDownloadingScreenTest() override = default; // OobeBaseTest: @@ -83,8 +78,6 @@ base::OnceClosure screen_exit_callback_; - base::test::ScopedFeatureList feature_list_; - LoginManagerMixin login_manager_{&mixin_host_}; };
diff --git a/chrome/browser/chromeos/login/screens/assistant_optin_flow_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/assistant_optin_flow_screen_browsertest.cc index 1ec89f5..c657035 100644 --- a/chrome/browser/chromeos/login/screens/assistant_optin_flow_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/assistant_optin_flow_screen_browsertest.cc
@@ -28,7 +28,6 @@ #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chrome/common/chrome_paths.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/services/assistant/public/cpp/assistant_prefs.h" #include "chromeos/services/assistant/public/cpp/assistant_settings.h" @@ -300,11 +299,7 @@ class AssistantOptInFlowTest : public OobeBaseTest { public: - AssistantOptInFlowTest() { - // To reuse existing wizard controller in the flow. - feature_list_.InitAndEnableFeature( - chromeos::features::kOobeScreensPriority); - } + AssistantOptInFlowTest() = default; ~AssistantOptInFlowTest() override = default; void RegisterAdditionalRequestHandlers() override { @@ -434,8 +429,6 @@ base::OnceClosure screen_exit_callback_; AssistantOptInFlowScreen::ScreenExitCallback original_callback_; - base::test::ScopedFeatureList feature_list_; - LoginManagerMixin login_manager_{&mixin_host_}; };
diff --git a/chrome/browser/chromeos/login/screens/discover_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/discover_screen_browsertest.cc index 27af721..e7baa11 100644 --- a/chrome/browser/chromeos/login/screens/discover_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/discover_screen_browsertest.cc
@@ -19,7 +19,6 @@ #include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/ui/webui/chromeos/login/discover_screen_handler.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/login/auth/stub_authenticator_builder.h" #include "components/user_manager/user_type.h" #include "content/public/test/browser_test.h" @@ -31,10 +30,6 @@ public testing::WithParamInterface<user_manager::UserType> { public: DiscoverScreenTest() { - // To reuse existing wizard controller in the flow. - feature_list_.InitAndEnableFeature( - chromeos::features::kOobeScreensPriority); - if (GetParam() == user_manager::USER_TYPE_CHILD) { fake_gaia_ = std::make_unique<FakeGaiaMixin>(&mixin_host_, embedded_test_server()); @@ -116,7 +111,6 @@ std::move(screen_exit_callback_).Run(); } - base::test::ScopedFeatureList feature_list_; DiscoverScreen::ScreenExitCallback original_callback_; bool screen_exited_ = false; base::RepeatingClosure screen_exit_callback_;
diff --git a/chrome/browser/chromeos/login/screens/family_link_notice_browsertest.cc b/chrome/browser/chromeos/login/screens/family_link_notice_browsertest.cc index 997111f..46a7fa3 100644 --- a/chrome/browser/chromeos/login/screens/family_link_notice_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/family_link_notice_browsertest.cc
@@ -101,9 +101,18 @@ base::test::ScopedFeatureList feature_list_; }; +#if defined(MEMORY_SANITIZER) +// This entire suite is slow enough under MSan that it flakily times out: +// https://crbug.com/1131570 +#define DISABLE_UNDER_MSAN(name) DISABLED_##name +#else +#define DISABLE_UNDER_MSAN(name) name +#endif + // Verify that regular account user should not see family link notice screen // after log in. -IN_PROC_BROWSER_TEST_F(FamilyLinkNoticeScreenTest, RegularAccount) { +IN_PROC_BROWSER_TEST_F(FamilyLinkNoticeScreenTest, + DISABLE_UNDER_MSAN(RegularAccount)) { WizardController::default_controller() ->get_wizard_context_for_testing() ->sign_in_as_child = false; @@ -115,7 +124,8 @@ // Verify user should see family link notice screen when selecting to sign in // as a child account but log in as a regular account. -IN_PROC_BROWSER_TEST_F(FamilyLinkNoticeScreenTest, NonSupervisedChildAccount) { +IN_PROC_BROWSER_TEST_F(FamilyLinkNoticeScreenTest, + DISABLE_UNDER_MSAN(NonSupervisedChildAccount)) { WizardController::default_controller() ->get_wizard_context_for_testing() ->sign_in_as_child = true; @@ -151,7 +161,8 @@ // Verify child account user should not see family link notice screen after log // in. -IN_PROC_BROWSER_TEST_F(FamilyLinkNoticeScreenChildTest, ChildAccount) { +IN_PROC_BROWSER_TEST_F(FamilyLinkNoticeScreenChildTest, + DISABLE_UNDER_MSAN(ChildAccount)) { WizardController::default_controller() ->get_wizard_context_for_testing() ->sign_in_as_child = true; @@ -164,7 +175,7 @@ // Verify child account user should not see family link notice screen after log // in if not selecting sign in as child. IN_PROC_BROWSER_TEST_F(FamilyLinkNoticeScreenChildTest, - ChildAccountSignInAsRegular) { + DISABLE_UNDER_MSAN(ChildAccountSignInAsRegular)) { WizardController::default_controller() ->get_wizard_context_for_testing() ->sign_in_as_child = false; @@ -188,7 +199,8 @@ UserPolicyMixin user_policy_mixin_{&mixin_host_, test_user_.account_id}; }; -IN_PROC_BROWSER_TEST_F(FamilyLinkNoticeScreenManagedTest, ManagedAccount) { +IN_PROC_BROWSER_TEST_F(FamilyLinkNoticeScreenManagedTest, + DISABLE_UNDER_MSAN(ManagedAccount)) { WizardController::default_controller() ->get_wizard_context_for_testing() ->sign_in_as_child = true;
diff --git a/chrome/browser/chromeos/login/screens/marketing_opt_in_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/marketing_opt_in_screen_browsertest.cc index cf7241d..9e80b95 100644 --- a/chrome/browser/chromeos/login/screens/marketing_opt_in_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/marketing_opt_in_screen_browsertest.cc
@@ -163,10 +163,8 @@ }; MarketingOptInScreenTest::MarketingOptInScreenTest() { - // To reuse existing wizard controller in the flow. feature_list_.InitWithFeatures( - {chromeos::features::kOobeScreensPriority, - ::features::kOobeMarketingDoubleOptInCountriesSupported, + {::features::kOobeMarketingDoubleOptInCountriesSupported, ::features::kOobeMarketingAdditionalCountriesSupported}, {}); } @@ -430,9 +428,8 @@ MarketingDisabledExtraCountries() { feature_list_.Reset(); feature_list_.InitWithFeatures( - {chromeos::features::kOobeScreensPriority}, - {::features::kOobeMarketingDoubleOptInCountriesSupported, - ::features::kOobeMarketingAdditionalCountriesSupported}); + {}, {::features::kOobeMarketingDoubleOptInCountriesSupported, + ::features::kOobeMarketingAdditionalCountriesSupported}); } ~MarketingDisabledExtraCountries() = default; @@ -477,10 +474,8 @@ public: MarketingOptInScreenTestDisabled() { feature_list_.Reset(); - // Enable |kOobeScreensPriority| to reuse existing wizard controller in - // the flow and disable kOobeMarketingScreen to disable marketing screen. - feature_list_.InitWithFeatures({chromeos::features::kOobeScreensPriority}, - {::features::kOobeMarketingScreen}); + // Disable kOobeMarketingScreen to disable marketing screen. + feature_list_.InitWithFeatures({}, {::features::kOobeMarketingScreen}); } ~MarketingOptInScreenTestDisabled() override = default;
diff --git a/chrome/browser/chromeos/login/screens/multidevice_setup_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/multidevice_setup_screen_browsertest.cc index 1bb7d0f..d0c9319 100644 --- a/chrome/browser/chromeos/login/screens/multidevice_setup_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/multidevice_setup_screen_browsertest.cc
@@ -17,7 +17,6 @@ #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/multidevice_setup_screen_handler.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h" #include "content/public/test/browser_test.h" @@ -25,11 +24,7 @@ class MultiDeviceSetupScreenTest : public OobeBaseTest { public: - MultiDeviceSetupScreenTest() { - // To reuse existing wizard controller in the flow. - feature_list_.InitAndEnableFeature( - chromeos::features::kOobeScreensPriority); - } + MultiDeviceSetupScreenTest() = default; ~MultiDeviceSetupScreenTest() override = default; void SetUpOnMainThread() override { @@ -118,8 +113,6 @@ bool screen_exited_ = false; base::RepeatingClosure screen_exit_callback_; - - base::test::ScopedFeatureList feature_list_; std::unique_ptr<multidevice_setup::FakeMultiDeviceSetupClient> fake_multidevice_setup_client_;
diff --git a/chrome/browser/chromeos/login/screens/recommend_apps_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/recommend_apps_screen_browsertest.cc index 5acc6de..d76181c9 100644 --- a/chrome/browser/chromeos/login/screens/recommend_apps_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/recommend_apps_screen_browsertest.cc
@@ -32,7 +32,6 @@ #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chrome/browser/ui/webui/chromeos/login/recommend_apps_screen_handler.h" -#include "chromeos/constants/chromeos_features.h" #include "components/account_id/account_id.h" #include "components/arc/arc_prefs.h" #include "components/prefs/pref_service.h" @@ -112,11 +111,7 @@ class RecommendAppsScreenTest : public OobeBaseTest { public: - RecommendAppsScreenTest() { - // To reuse existing wizard controller in the flow. - feature_list_.InitAndEnableFeature( - chromeos::features::kOobeScreensPriority); - } + RecommendAppsScreenTest() = default; ~RecommendAppsScreenTest() override = default; // OobeBaseTest: @@ -254,8 +249,6 @@ recommend_apps_fetcher_factory_; base::OnceClosure screen_exit_callback_; - - base::test::ScopedFeatureList feature_list_; }; IN_PROC_BROWSER_TEST_F(RecommendAppsScreenTest, BasicSelection) {
diff --git a/chrome/browser/chromeos/login/screens/sync_consent_browsertest.cc b/chrome/browser/chromeos/login/screens/sync_consent_browsertest.cc index 1c05749c..6301782 100644 --- a/chrome/browser/chromeos/login/screens/sync_consent_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/sync_consent_browsertest.cc
@@ -128,11 +128,7 @@ public: SyncConsentTest() : force_branded_build_( - SyncConsentScreen::ForceBrandedBuildForTesting(true)) { - // To reuse existing wizard controller in the flow. - feature_list_.InitAndEnableFeature( - chromeos::features::kOobeScreensPriority); - } + SyncConsentScreen::ForceBrandedBuildForTesting(true)) {} ~SyncConsentTest() override = default; void SetUpOnMainThread() override { @@ -251,7 +247,6 @@ LoginManagerMixin login_manager_mixin_{&mixin_host_}; std::unique_ptr<base::AutoReset<bool>> force_branded_build_; - base::test::ScopedFeatureList feature_list_; DISALLOW_COPY_AND_ASSIGN(SyncConsentTest); };
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc index ac46eeb..18410d0 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
@@ -36,7 +36,6 @@ #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/user_creation_screen_handler.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/login/auth/user_context.h" #include "components/startup_metric_utils/browser/startup_metric_utils.h" #include "components/user_manager/user.h" @@ -207,15 +206,10 @@ // screens to show. ObserveOobeUI(); - if (features::IsOobeScreensPriorityEnabled()) { - if (wizard_controller_->is_initialized()) - wizard_controller_->AdvanceToScreen(first_screen); - else - wizard_controller_->Init(first_screen); - } else { - wizard_controller_ = std::make_unique<WizardController>(); + if (wizard_controller_->is_initialized()) + wizard_controller_->AdvanceToScreen(first_screen); + else wizard_controller_->Init(first_screen); - } } WizardController* LoginDisplayHostMojo::GetWizardController() {
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc index 141f314..093fa5c 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
@@ -77,7 +77,6 @@ #include "chrome/grit/browser_resources.h" #include "chromeos/audio/chromeos_sounds.h" #include "chromeos/constants/chromeos_constants.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/dbus/session_manager/session_manager_client.h" #include "chromeos/login/login_state/login_state.h" @@ -586,7 +585,7 @@ SetOobeProgressBarVisible(oobe_progress_bar_visible_); // Create and show the wizard. - if (features::IsOobeScreensPriorityEnabled() && wizard_controller_) { + if (wizard_controller_) { wizard_controller_->AdvanceToScreen(first_screen); } else { wizard_controller_ = std::make_unique<WizardController>();
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index 1ed23ce..d8d116a 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -151,7 +151,6 @@ #include "chrome/common/pref_names.h" #include "chromeos/audio/cras_audio_handler.h" #include "chromeos/constants/chromeos_constants.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/constants/devicetype.h" #include "chromeos/dbus/dbus_thread_manager.h" @@ -1641,7 +1640,7 @@ } void WizardController::AdvanceToScreen(OobeScreenId screen_id) { - if (features::IsOobeScreensPriorityEnabled() && !CanNavigateTo(screen_id)) { + if (!CanNavigateTo(screen_id)) { LOG(WARNING) << "Cannot advance to screen : " << screen_id << " as it's priority is less than the current screen : " << current_screen_->screen_id();
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc index 1c50b6f..a19bd5d 100644 --- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -76,7 +76,6 @@ #include "chrome/grit/generated_resources.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/audio/cras_audio_handler.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/dbus/constants/dbus_switches.h" #include "chromeos/dbus/cryptohome/fake_cryptohome_client.h" @@ -1917,19 +1916,13 @@ class WizardControllerScreenPriorityOOBETest : public OobeBaseTest { protected: - WizardControllerScreenPriorityOOBETest() { - feature_list_.InitAndEnableFeature( - chromeos::features::kOobeScreensPriority); - } + WizardControllerScreenPriorityOOBETest() = default; ~WizardControllerScreenPriorityOOBETest() override = default; void CheckCurrentScreen(OobeScreenId screen) { EXPECT_EQ(WizardController::default_controller()->GetScreen(screen), WizardController::default_controller()->current_screen()); } - - private: - base::test::ScopedFeatureList feature_list_; }; IN_PROC_BROWSER_TEST_F(WizardControllerScreenPriorityOOBETest, @@ -1960,8 +1953,6 @@ protected: WizardControllerScreenPriorityTest() { login_manager_mixin_.AppendRegularUsers(1); - feature_list_.InitAndEnableFeature( - chromeos::features::kOobeScreensPriority); } ~WizardControllerScreenPriorityTest() override = default; @@ -1978,7 +1969,6 @@ } private: - base::test::ScopedFeatureList feature_list_; LoginManagerMixin login_manager_mixin_{&mixin_host_}; LocalStateMixin local_state_mixin_{&mixin_host_, this}; };
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 3f31e08..05ee0a0b 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
@@ -30,7 +30,7 @@ namespace off_hours { DeviceOffHoursController::DeviceOffHoursController() - : timer_(std::make_unique<base::OneShotTimer>()), + : timer_(std::make_unique<util::WallClockTimer>()), clock_(base::DefaultClock::GetInstance()) { auto* system_clock_client = chromeos::SystemClockClient::Get(); if (system_clock_client) { @@ -39,17 +39,11 @@ base::BindOnce(&DeviceOffHoursController::SystemClockInitiallyAvailable, weak_ptr_factory_.GetWeakPtr())); } - - if (chromeos::PowerManagerClient::Get()) - chromeos::PowerManagerClient::Get()->AddObserver(this); } DeviceOffHoursController::~DeviceOffHoursController() { if (chromeos::SystemClockClient::Get()) chromeos::SystemClockClient::Get()->RemoveObserver(this); - - if (chromeos::PowerManagerClient::Get()) - chromeos::PowerManagerClient::Get()->RemoveObserver(this); } void DeviceOffHoursController::AddObserver(Observer* observer) { @@ -64,7 +58,7 @@ base::Clock* clock, const base::TickClock* timer_clock) { clock_ = clock; - timer_ = std::make_unique<base::OneShotTimer>(timer_clock); + timer_ = std::make_unique<util::WallClockTimer>(clock, timer_clock); } bool DeviceOffHoursController::IsCurrentSessionAllowedOnlyForOffHours() const { @@ -111,13 +105,6 @@ UpdateOffHoursMode(); } -void DeviceOffHoursController::SuspendDone( - const base::TimeDelta& sleep_duration) { - // Triggered when device wakes up. "OffHours" state could be changed during - // sleep mode and should be updated after that. - UpdateOffHoursMode(); -} - void DeviceOffHoursController::NotifyOffHoursEndTimeChanged() const { VLOG(1) << "OffHours end time is changed to " << off_hours_end_time_; for (auto& observer : observers_) @@ -179,7 +166,7 @@ void DeviceOffHoursController::StartOffHoursTimer(base::TimeDelta delay) { DCHECK_GT(delay, base::TimeDelta()); DVLOG(1) << "OffHours mode timer starts for " << delay; - timer_->Start(FROM_HERE, delay, + timer_->Start(FROM_HERE, clock_->Now() + delay, base::BindOnce(&DeviceOffHoursController::UpdateOffHoursMode, weak_ptr_factory_.GetWeakPtr())); }
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 0a1b488d..90f7720 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
@@ -13,8 +13,7 @@ #include "base/observer_list.h" #include "base/time/clock.h" #include "base/time/time.h" -#include "base/timer/timer.h" -#include "chromeos/dbus/power/power_manager_client.h" +#include "base/util/timer/wall_clock_timer.h" #include "chromeos/dbus/system_clock/system_clock_client.h" #include "chromeos/policy/weekly_time/weekly_time_interval.h" #include "components/policy/proto/chrome_device_policy.pb.h" @@ -37,8 +36,7 @@ // // "OffHours" mode is never on until device time is synchronized with // network time because in this case device time could be incorrect. -class DeviceOffHoursController : public chromeos::SystemClockClient::Observer, - public chromeos::PowerManagerClient::Observer { +class DeviceOffHoursController : public chromeos::SystemClockClient::Observer { public: // Observer interface. class Observer { @@ -75,9 +73,6 @@ // when "OffHours" mode is off. base::Time GetOffHoursEndTime() const { return off_hours_end_time_; } - // chromeos::PowerManagerClient::Observer: - void SuspendDone(const base::TimeDelta& sleep_duration) override; - // chromeos::SystemClockClient::Observer: void SystemClockUpdated() override; @@ -130,7 +125,7 @@ // Timer for updating device settings at the begin of next “OffHours” interval // or at the end of current "OffHours" interval. - std::unique_ptr<base::OneShotTimer> timer_; + std::unique_ptr<util::WallClockTimer> timer_; // Used for testing purposes, otherwise it's an instance of // base::DefaultClock.
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 c21383a4..5120caa 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
@@ -9,13 +9,14 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "base/power_monitor/test/fake_power_monitor_source.h" #include "base/test/simple_test_clock.h" #include "base/test/simple_test_tick_clock.h" +#include "base/test/task_environment.h" #include "base/time/tick_clock.h" #include "base/time/time.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/settings/device_settings_test_helper.h" -#include "chromeos/dbus/power/fake_power_manager_client.h" #include "chromeos/dbus/system_clock/system_clock_client.h" #include "components/policy/proto/chrome_device_policy.pb.h" @@ -102,7 +103,9 @@ class DeviceOffHoursControllerSimpleTest : public chromeos::DeviceSettingsTestBase { protected: - DeviceOffHoursControllerSimpleTest() = default; + DeviceOffHoursControllerSimpleTest() + : chromeos::DeviceSettingsTestBase( + base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} ~DeviceOffHoursControllerSimpleTest() override = default; void SetUp() override { @@ -323,21 +326,34 @@ system_clock_client()->NotifyObserversSystemClockUpdated(); // Clocks are set to 1970-01-01 00:00:00 UTC, Thursday. test_clock_.SetNow(base::Time::UnixEpoch()); - test_tick_clock_.SetNowTicks(base::TimeTicks::UnixEpoch()); - device_off_hours_controller()->SetClockForTesting(&test_clock_, - &test_tick_clock_); + device_off_hours_controller()->SetClockForTesting( + &test_clock_, task_environment_.GetMockTickClock()); } void AdvanceTestClock(TimeDelta duration) { test_clock_.Advance(duration); - test_tick_clock_.Advance(duration); + task_environment_.FastForwardBy(duration); + + task_environment_.RunUntilIdle(); + base::RunLoop().RunUntilIdle(); + } + + void SuspendFor(TimeDelta duration) { + fake_power_monitor_source_.Suspend(); + + test_clock_.Advance(duration); + + fake_power_monitor_source_.Resume(); + + task_environment_.RunUntilIdle(); + base::RunLoop().RunUntilIdle(); } base::Clock* clock() { return &test_clock_; } private: base::SimpleTestClock test_clock_; - base::SimpleTestTickClock test_tick_clock_; + base::test::ScopedFakePowerMonitorSource fake_power_monitor_source_; DISALLOW_COPY_AND_ASSIGN(DeviceOffHoursControllerFakeClockTest); }; @@ -364,7 +380,7 @@ EXPECT_FALSE(device_off_hours_controller()->is_off_hours_mode()); } -TEST_F(DeviceOffHoursControllerFakeClockTest, CheckSendSuspendDone) { +TEST_F(DeviceOffHoursControllerFakeClockTest, CheckUnderSuspend) { system_clock_client()->SetServiceIsAvailable(true); int current_day_of_week = ExtractDayOfWeek(clock()->Now()); LOG(ERROR) << "day " << current_day_of_week; @@ -379,12 +395,10 @@ UpdateDeviceSettings(); EXPECT_FALSE(device_off_hours_controller()->is_off_hours_mode()); - AdvanceTestClock(kDay); - power_manager_client()->SendSuspendDone(); + SuspendFor(kDay); EXPECT_TRUE(device_off_hours_controller()->is_off_hours_mode()); AdvanceTestClock(kHour); - power_manager_client()->SendSuspendDone(); EXPECT_FALSE(device_off_hours_controller()->is_off_hours_mode()); }
diff --git a/chrome/browser/chromeos/scanning/lorgnette_scanner_manager.h b/chrome/browser/chromeos/scanning/lorgnette_scanner_manager.h index 9c1fdf2d..36160d4 100644 --- a/chrome/browser/chromeos/scanning/lorgnette_scanner_manager.h +++ b/chrome/browser/chromeos/scanning/lorgnette_scanner_manager.h
@@ -26,7 +26,7 @@ using GetScannerNamesCallback = base::OnceCallback<void(std::vector<std::string> scanner_names)>; using GetScannerCapabilitiesCallback = base::OnceCallback<void( - base::Optional<lorgnette::ScannerCapabilities> capabilities)>; + const base::Optional<lorgnette::ScannerCapabilities>& capabilities)>; using PageCallback = base::RepeatingCallback<void(std::string scan_data)>; using ScanCallback = base::OnceCallback<void(bool success)>;
diff --git a/chrome/browser/chromeos/scanning/lorgnette_scanner_manager_unittest.cc b/chrome/browser/chromeos/scanning/lorgnette_scanner_manager_unittest.cc index 570b07d..4049952f 100644 --- a/chrome/browser/chromeos/scanning/lorgnette_scanner_manager_unittest.cc +++ b/chrome/browser/chromeos/scanning/lorgnette_scanner_manager_unittest.cc
@@ -202,7 +202,8 @@ } void GetScannerCapabilitiesCallback( - base::Optional<lorgnette::ScannerCapabilities> scanner_capabilities) { + const base::Optional<lorgnette::ScannerCapabilities>& + scanner_capabilities) { scanner_capabilities_ = scanner_capabilities; run_loop_->Quit(); }
diff --git a/chrome/browser/chromeos/scanning/scan_service.cc b/chrome/browser/chromeos/scanning/scan_service.cc index 8f82114..c4a2c6b8 100644 --- a/chrome/browser/chromeos/scanning/scan_service.cc +++ b/chrome/browser/chromeos/scanning/scan_service.cc
@@ -78,7 +78,7 @@ void ScanService::OnScannerCapabilitiesReceived( GetScannerCapabilitiesCallback callback, - base::Optional<lorgnette::ScannerCapabilities> capabilities) { + const base::Optional<lorgnette::ScannerCapabilities>& capabilities) { if (!capabilities) { LOG(ERROR) << "Failed to get scanner capabilities."; std::move(callback).Run(mojo_ipc::ScannerCapabilities::New());
diff --git a/chrome/browser/chromeos/scanning/scan_service.h b/chrome/browser/chromeos/scanning/scan_service.h index 6f5d1b3..aff3d2b 100644 --- a/chrome/browser/chromeos/scanning/scan_service.h +++ b/chrome/browser/chromeos/scanning/scan_service.h
@@ -54,7 +54,7 @@ // LorgnetteScannerManager::GetScannerCapabilities(). void OnScannerCapabilitiesReceived( GetScannerCapabilitiesCallback callback, - base::Optional<lorgnette::ScannerCapabilities> capabilities); + const base::Optional<lorgnette::ScannerCapabilities>& capabilities); // Map of scanner IDs to display names. Used to pass the correct display name // to LorgnetteScannerManager when clients provide an ID.
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.cc b/chrome/browser/chromeos/settings/device_settings_test_helper.cc index 37103957..a973e85 100644 --- a/chrome/browser/chromeos/settings/device_settings_test_helper.cc +++ b/chrome/browser/chromeos/settings/device_settings_test_helper.cc
@@ -38,6 +38,10 @@ DeviceSettingsTestBase::DeviceSettingsTestBase() : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP) {} +DeviceSettingsTestBase::DeviceSettingsTestBase( + base::test::TaskEnvironment::TimeSource time) + : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP, time) {} + DeviceSettingsTestBase::~DeviceSettingsTestBase() { CHECK(teardown_called_); } @@ -116,8 +120,4 @@ service->OnTPMTokenReady(true /* token is enabled */); } -FakePowerManagerClient* DeviceSettingsTestBase::power_manager_client() { - return FakePowerManagerClient::Get(); -} - } // namespace chromeos
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.h b/chrome/browser/chromeos/settings/device_settings_test_helper.h index 0d2352d65..f382bb7 100644 --- a/chrome/browser/chromeos/settings/device_settings_test_helper.h +++ b/chrome/browser/chromeos/settings/device_settings_test_helper.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/strings/string_util.h" +#include "base/test/task_environment.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/policy/device_policy_builder.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" @@ -25,7 +26,6 @@ namespace chromeos { class DBusThreadManagerSetter; -class FakePowerManagerClient; // Wraps the singleton device settings and initializes it to the point where it // reports OWNERSHIP_NONE for the ownership status. @@ -46,6 +46,7 @@ class DeviceSettingsTestBase : public testing::Test { protected: DeviceSettingsTestBase(); + explicit DeviceSettingsTestBase(base::test::TaskEnvironment::TimeSource time); ~DeviceSettingsTestBase() override; // testing::Test: @@ -64,8 +65,6 @@ void InitOwner(const AccountId& account_id, bool tpm_is_ready); - FakePowerManagerClient* power_manager_client(); - content::BrowserTaskEnvironment task_environment_; std::unique_ptr<policy::DevicePolicyBuilder> device_policy_;
diff --git a/chrome/browser/component_updater/soda_component_installer.cc b/chrome/browser/component_updater/soda_component_installer.cc index 03a746fc..80da745 100644 --- a/chrome/browser/component_updater/soda_component_installer.cc +++ b/chrome/browser/component_updater/soda_component_installer.cc
@@ -11,7 +11,6 @@ #include "chrome/browser/component_updater/soda_en_us_component_installer.h" #include "chrome/browser/component_updater/soda_ja_jp_component_installer.h" #include "chrome/common/pref_names.h" -#include "chrome/services/speech/buildflags.h" #include "components/component_updater/component_updater_service.h" #include "components/crx_file/id_util.h" #include "components/soda/constants.h" @@ -137,64 +136,65 @@ if (!base::FeatureList::IsEnabled(media::kLiveCaption)) return; -#if BUILDFLAG(ENABLE_SODA) - auto installer = base::MakeRefCounted<ComponentInstaller>( - std::make_unique<SODAComponentInstallerPolicy>(base::BindRepeating( - [](ComponentUpdateService* cus, PrefService* prefs, - const base::FilePath& install_dir) { + if (base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption)) { + auto installer = base::MakeRefCounted<ComponentInstaller>( + std::make_unique<SODAComponentInstallerPolicy>(base::BindRepeating( + [](ComponentUpdateService* cus, PrefService* prefs, + const base::FilePath& install_dir) { content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT}) ->PostTask(FROM_HERE, base::BindOnce(&UpdateSODAInstallDirPref, prefs, install_dir)); - }, - cus, prefs))); + }, + cus, prefs))); - if (prefs->GetBoolean(prefs::kLiveCaptionEnabled)) { - installer->Register(cus, std::move(callback)); - } else { - // Register and uninstall the SODA component to delete the previously - // installed SODA files. - if (!prefs->GetFilePath(prefs::kSodaBinaryPath).empty()) { - installer->Register( - cus, - base::BindOnce( - [](ComponentUpdateService* cus, PrefService* prefs) { - if (component_updater::UninstallSODAComponent(cus, prefs)) { - prefs->SetFilePath(prefs::kSodaBinaryPath, base::FilePath()); - prefs->SetFilePath(prefs::kSodaEnUsConfigPath, - base::FilePath()); - } - }, - cus, prefs)); + if (prefs->GetBoolean(prefs::kLiveCaptionEnabled)) { + installer->Register(cus, std::move(callback)); + } else { + // Register and uninstall the SODA component to delete the previously + // installed SODA files. + if (!prefs->GetFilePath(prefs::kSodaBinaryPath).empty()) { + installer->Register( + cus, + base::BindOnce( + [](ComponentUpdateService* cus, PrefService* prefs) { + if (component_updater::UninstallSODAComponent(cus, prefs)) { + prefs->SetFilePath(prefs::kSodaBinaryPath, + base::FilePath()); + prefs->SetFilePath(prefs::kSodaEnUsConfigPath, + base::FilePath()); + } + }, + cus, prefs)); + } } } -#endif } void RegisterSodaLanguageComponent(ComponentUpdateService* cus, PrefService* prefs) { DCHECK_CURRENTLY_ON(BrowserThread::UI); -#if BUILDFLAG(ENABLE_SODA) - speech::LanguageCode language = speech::GetLanguageCode( - prefs->GetString(prefs::kLiveCaptionLanguageCode)); - switch (language) { - case speech::LanguageCode::kNone: - // Do nothing. - break; - case speech::LanguageCode::kEnUs: - RegisterSodaEnUsComponent( - cus, prefs, - base::BindOnce(&SodaEnUsComponentInstallerPolicy:: - UpdateSodaEnUsComponentOnDemand)); - break; - case speech::LanguageCode::kJaJp: - RegisterSodaJaJpComponent( - cus, prefs, - base::BindOnce(&SodaJaJpComponentInstallerPolicy:: - UpdateSodaJaJpComponentOnDemand)); - break; + if (base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption)) { + speech::LanguageCode language = speech::GetLanguageCode( + prefs->GetString(prefs::kLiveCaptionLanguageCode)); + switch (language) { + case speech::LanguageCode::kNone: + // Do nothing. + break; + case speech::LanguageCode::kEnUs: + RegisterSodaEnUsComponent( + cus, prefs, + base::BindOnce(&SodaEnUsComponentInstallerPolicy:: + UpdateSodaEnUsComponentOnDemand)); + break; + case speech::LanguageCode::kJaJp: + RegisterSodaJaJpComponent( + cus, prefs, + base::BindOnce(&SodaJaJpComponentInstallerPolicy:: + UpdateSodaJaJpComponentOnDemand)); + break; + } } -#endif } bool UninstallSODAComponent(ComponentUpdateService* cus, PrefService* prefs) {
diff --git a/chrome/browser/component_updater/soda_en_us_component_installer.cc b/chrome/browser/component_updater/soda_en_us_component_installer.cc index 8b326ea69..2e3c6510 100644 --- a/chrome/browser/component_updater/soda_en_us_component_installer.cc +++ b/chrome/browser/component_updater/soda_en_us_component_installer.cc
@@ -9,7 +9,6 @@ #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/common/pref_names.h" -#include "chrome/services/speech/buildflags.h" #include "components/component_updater/component_updater_service.h" #include "components/crx_file/id_util.h" #include "components/soda/constants.h" @@ -136,25 +135,25 @@ PrefService* prefs, base::OnceClosure callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); -#if BUILDFLAG(ENABLE_SODA) - if (!prefs->GetBoolean(prefs::kLiveCaptionEnabled) || - !base::FeatureList::IsEnabled(media::kLiveCaption)) { - return; - } + if (base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption)) { + if (!prefs->GetBoolean(prefs::kLiveCaptionEnabled) || + !base::FeatureList::IsEnabled(media::kLiveCaption)) { + return; + } - auto installer = base::MakeRefCounted<ComponentInstaller>( - std::make_unique<SodaEnUsComponentInstallerPolicy>(base::BindRepeating( - [](ComponentUpdateService* cus, PrefService* prefs, - const base::FilePath& install_dir) { + auto installer = base::MakeRefCounted<ComponentInstaller>( + std::make_unique<SodaEnUsComponentInstallerPolicy>(base::BindRepeating( + [](ComponentUpdateService* cus, PrefService* prefs, + const base::FilePath& install_dir) { content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT}) ->PostTask(FROM_HERE, base::BindOnce(&UpdateSodaEnUsInstallDirPref, prefs, install_dir)); - }, - cus, prefs))); + }, + cus, prefs))); - installer->Register(cus, std::move(callback)); -#endif + installer->Register(cus, std::move(callback)); + } } bool UninstallSodaEnUsComponent(ComponentUpdateService* cus,
diff --git a/chrome/browser/component_updater/soda_ja_jp_component_installer.cc b/chrome/browser/component_updater/soda_ja_jp_component_installer.cc index 9f0ef8f..3ba3273 100644 --- a/chrome/browser/component_updater/soda_ja_jp_component_installer.cc +++ b/chrome/browser/component_updater/soda_ja_jp_component_installer.cc
@@ -9,7 +9,6 @@ #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/common/pref_names.h" -#include "chrome/services/speech/buildflags.h" #include "components/component_updater/component_updater_service.h" #include "components/crx_file/id_util.h" #include "components/soda/constants.h" @@ -136,25 +135,25 @@ PrefService* prefs, base::OnceClosure callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); -#if BUILDFLAG(ENABLE_SODA) - if (!prefs->GetBoolean(prefs::kLiveCaptionEnabled) || - !base::FeatureList::IsEnabled(media::kLiveCaption)) { - return; - } + if (base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption)) { + if (!prefs->GetBoolean(prefs::kLiveCaptionEnabled) || + !base::FeatureList::IsEnabled(media::kLiveCaption)) { + return; + } - auto installer = base::MakeRefCounted<ComponentInstaller>( - std::make_unique<SodaJaJpComponentInstallerPolicy>(base::BindRepeating( - [](ComponentUpdateService* cus, PrefService* prefs, - const base::FilePath& install_dir) { + auto installer = base::MakeRefCounted<ComponentInstaller>( + std::make_unique<SodaJaJpComponentInstallerPolicy>(base::BindRepeating( + [](ComponentUpdateService* cus, PrefService* prefs, + const base::FilePath& install_dir) { content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT}) ->PostTask(FROM_HERE, base::BindOnce(&UpdateSodaJaJpInstallDirPref, prefs, install_dir)); - }, - cus, prefs))); + }, + cus, prefs))); - installer->Register(cus, std::move(callback)); -#endif + installer->Register(cus, std::move(callback)); + } } bool UninstallSodaJaJpComponent(ComponentUpdateService* cus,
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.cc index 180db45..92a8191f 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.cc +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "chrome/browser/extensions/api/platform_keys/platform_keys_api.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/enterprise_platform_keys.h" #include "chromeos/lacros/lacros_chrome_service_impl.h" @@ -29,6 +30,7 @@ } const char kLacrosNotImplementedError[] = "not-implemented-yet-for-lacros"; +const char kUnsupportedProfile[] = "unsupported-profile"; } // namespace @@ -69,4 +71,46 @@ } } +ExtensionFunction::ResponseAction +EnterprisePlatformKeysChallengeUserKeyFunction::Run() { + std::unique_ptr<api_epk::ChallengeUserKey::Params> params( + api_epk::ChallengeUserKey::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params); + + // This API is used in security-sensitive contexts and attests against a + // particular user. Since the attestation is done by ash, we need to ensure + // that the user for ash is the same as the user for lacros. We do this by + // restricting the API to the default profile, which is guaranteed to be the + // same user. + if (!Profile::FromBrowserContext(browser_context())->IsDefaultProfile()) + return RespondNow(Error(kUnsupportedProfile)); + + // TODO(https://crbug.com/1113443): This implementation needs to check if the + // extension is allowlisted via the AttestationExtensionAllowlist policy. + auto c = base::BindOnce(&EnterprisePlatformKeysChallengeUserKeyFunction:: + OnChallengeAttestationOnlyKeystore, + this); + chromeos::LacrosChromeServiceImpl::Get() + ->keystore_service_remote() + ->ChallengeAttestationOnlyKeystore(StringFromVector(params->challenge), + crosapi::mojom::KeystoreType::kUser, + /*migrate=*/params->register_key, + std::move(c)); + return RespondLater(); +} + +void EnterprisePlatformKeysChallengeUserKeyFunction:: + OnChallengeAttestationOnlyKeystore(ResultPtr result) { + using Result = crosapi::mojom::ChallengeAttestationOnlyKeystoreResult; + switch (result->which()) { + case Result::Tag::ERROR_MESSAGE: + Respond(Error(result->get_error_message())); + return; + case Result::Tag::CHALLENGE_RESPONSE: + Respond(ArgumentList(api_epk::ChallengeUserKey::Results::Create( + VectorFromString(result->get_challenge_response())))); + return; + } +} + } // namespace extensions
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.h b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.h index a52392fc..de72116 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.h +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.h
@@ -63,9 +63,13 @@ }; class EnterprisePlatformKeysChallengeUserKeyFunction - : public LacrosNotImplementedExtensionFunction { + : public ExtensionFunction { private: ~EnterprisePlatformKeysChallengeUserKeyFunction() override = default; + ResponseAction Run() override; + + using ResultPtr = crosapi::mojom::ChallengeAttestationOnlyKeystoreResultPtr; + void OnChallengeAttestationOnlyKeystore(ResultPtr result); DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeUserKey", ENTERPRISE_PLATFORMKEYS_CHALLENGEUSERKEY) };
diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc index 96c5a377..02de4e64 100644 --- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc +++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc
@@ -626,6 +626,21 @@ const std::unordered_set<std::string> active_ids(GetEnabledIMEs(ime_state)); const std::unordered_set<std::string> allowed_ids(GetAllowedIMEs(ime_state)); + + // Collator used to sort display names in the given locale. + UErrorCode error = U_ZERO_ERROR; + const std::string app_locale = g_browser_process->GetApplicationLocale(); + std::unique_ptr<icu::Collator> collator( + icu::Collator::createInstance(icu::Locale(app_locale.c_str()), error)); + if (U_FAILURE(error)) { + collator.reset(); + } + + // Map of sorted [display name -> input methods]. + std::map<base::string16, language_settings_private::InputMethod, + l10n_util::StringComparator<base::string16>> + input_map(l10n_util::StringComparator<base::string16>(collator.get())); + for (const auto& descriptor : descriptors) { language_settings_private::InputMethod input_method; input_method.id = descriptor.id(); @@ -642,7 +657,12 @@ allowed_ids.count(input_method.id) == 0) { input_method.is_prohibited_by_policy.reset(new bool(true)); } - input_methods->push_back(std::move(input_method)); + input_map[base::UTF8ToUTF16(util->GetLocalizedDisplayName(descriptor))] = + std::move(input_method); + } + + for (auto& entry : input_map) { + input_methods->push_back(std::move(entry.second)); } } #endif
diff --git a/chrome/browser/extensions/blocklist.cc b/chrome/browser/extensions/blocklist.cc index 72b0480..cc678a6 100644 --- a/chrome/browser/extensions/blocklist.cc +++ b/chrome/browser/extensions/blocklist.cc
@@ -131,13 +131,14 @@ DISALLOW_COPY_AND_ASSIGN(SafeBrowsingClientImpl); }; -void CheckOneExtensionState(const Blocklist::IsBlocklistedCallback& callback, +void CheckOneExtensionState(Blocklist::IsBlocklistedCallback callback, const Blocklist::BlocklistStateMap& state_map) { - callback.Run(state_map.empty() ? NOT_BLOCKLISTED : state_map.begin()->second); + std::move(callback).Run(state_map.empty() ? NOT_BLOCKLISTED + : state_map.begin()->second); } void GetMalwareFromBlocklistStateMap( - const Blocklist::GetMalwareIDsCallback& callback, + Blocklist::GetMalwareIDsCallback callback, const Blocklist::BlocklistStateMap& state_map) { std::set<std::string> malware; for (const auto& state_pair : state_map) { @@ -149,7 +150,7 @@ malware.insert(state_pair.first); } } - callback.Run(malware); + std::move(callback).Run(malware); } } // namespace @@ -191,12 +192,12 @@ } void Blocklist::GetBlocklistedIDs(const std::set<std::string>& ids, - const GetBlocklistedIDsCallback& callback) { + GetBlocklistedIDsCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (ids.empty() || !GetDatabaseManager().get()) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, BlocklistStateMap())); + FROM_HERE, base::BindOnce(std::move(callback), BlocklistStateMap())); return; } @@ -205,25 +206,26 @@ // extensions returned by SafeBrowsing will then be passed to // GetBlocklistStateIDs to get the particular BlocklistState for each id. SafeBrowsingClientImpl::Start( - ids, - base::Bind(&Blocklist::GetBlocklistStateForIDs, AsWeakPtr(), callback)); + ids, base::BindOnce(&Blocklist::GetBlocklistStateForIDs, AsWeakPtr(), + std::move(callback))); } void Blocklist::GetMalwareIDs(const std::set<std::string>& ids, - const GetMalwareIDsCallback& callback) { - GetBlocklistedIDs(ids, - base::Bind(&GetMalwareFromBlocklistStateMap, callback)); + GetMalwareIDsCallback callback) { + GetBlocklistedIDs(ids, base::BindOnce(&GetMalwareFromBlocklistStateMap, + std::move(callback))); } void Blocklist::IsBlocklisted(const std::string& extension_id, - const IsBlocklistedCallback& callback) { + IsBlocklistedCallback callback) { std::set<std::string> check; check.insert(extension_id); - GetBlocklistedIDs(check, base::Bind(&CheckOneExtensionState, callback)); + GetBlocklistedIDs( + check, base::BindOnce(&CheckOneExtensionState, std::move(callback))); } void Blocklist::GetBlocklistStateForIDs( - const GetBlocklistedIDsCallback& callback, + GetBlocklistedIDsCallback callback, const std::set<std::string>& blocklisted_ids) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -242,7 +244,7 @@ } if (ids_unknown_state.empty()) { - callback.Run(extensions_state); + std::move(callback).Run(extensions_state); } else { // After the extension blocklist states have been downloaded, call this // functions again, but prevent infinite cycle in case server is offline @@ -251,12 +253,12 @@ RequestExtensionsBlocklistState( ids_unknown_state, base::BindOnce(&Blocklist::ReturnBlocklistStateMap, AsWeakPtr(), - callback, blocklisted_ids)); + std::move(callback), blocklisted_ids)); } } void Blocklist::ReturnBlocklistStateMap( - const GetBlocklistedIDsCallback& callback, + GetBlocklistedIDsCallback callback, const std::set<std::string>& blocklisted_ids) { BlocklistStateMap extensions_state; for (const auto& blocklisted_id : blocklisted_ids) { @@ -267,7 +269,7 @@ // we silently skip it. } - callback.Run(extensions_state); + std::move(callback).Run(extensions_state); } void Blocklist::RequestExtensionsBlocklistState(
diff --git a/chrome/browser/extensions/blocklist.h b/chrome/browser/extensions/blocklist.h index 2ae4feb..dd18a88 100644 --- a/chrome/browser/extensions/blocklist.h +++ b/chrome/browser/extensions/blocklist.h
@@ -64,12 +64,12 @@ using BlocklistStateMap = std::map<std::string, BlocklistState>; using GetBlocklistedIDsCallback = - base::Callback<void(const BlocklistStateMap&)>; + base::OnceCallback<void(const BlocklistStateMap&)>; using GetMalwareIDsCallback = - base::Callback<void(const std::set<std::string>&)>; + base::OnceCallback<void(const std::set<std::string>&)>; - using IsBlocklistedCallback = base::Callback<void(BlocklistState)>; + using IsBlocklistedCallback = base::OnceCallback<void(BlocklistState)>; explicit Blocklist(ExtensionPrefs* prefs); @@ -86,18 +86,18 @@ // For a synchronous version which ONLY CHECKS CURRENTLY INSTALLED EXTENSIONS // see ExtensionPrefs::IsExtensionBlocklisted. void GetBlocklistedIDs(const std::set<std::string>& ids, - const GetBlocklistedIDsCallback& callback); + GetBlocklistedIDsCallback callback); // From the subset of extension IDs passed in via |ids|, select the ones // marked in the blocklist as BLOCKLISTED_MALWARE and asynchronously pass // to |callback|. Basically, will call GetBlocklistedIDs and filter its // results. void GetMalwareIDs(const std::set<std::string>& ids, - const GetMalwareIDsCallback& callback); + GetMalwareIDsCallback callback); // More convenient form of GetBlocklistedIDs for checking a single extension. void IsBlocklisted(const std::string& extension_id, - const IsBlocklistedCallback& callback); + IsBlocklistedCallback callback); // Used to mock BlocklistStateFetcher in unit tests. Blocklist owns the // |fetcher|. @@ -126,7 +126,7 @@ void NotifyObservers(); - void GetBlocklistStateForIDs(const GetBlocklistedIDsCallback& callback, + void GetBlocklistStateForIDs(GetBlocklistedIDsCallback callback, const std::set<std::string>& blocklisted_ids); void RequestExtensionsBlocklistState(const std::set<std::string>& ids, @@ -134,7 +134,7 @@ void OnBlocklistStateReceived(const std::string& id, BlocklistState state); - void ReturnBlocklistStateMap(const GetBlocklistedIDsCallback& callback, + void ReturnBlocklistStateMap(GetBlocklistedIDsCallback callback, const std::set<std::string>& blocklisted_ids); base::ObserverList<Observer>::Unchecked observers_;
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc b/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc index f6bfb7c..f03e32d 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc +++ b/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc
@@ -131,7 +131,8 @@ auto fake_timer = std::make_unique<base::MockOneShotTimer>(); fake_timer_ = fake_timer.get(); metrics_ = std::make_unique<ForceInstalledMetrics>( - registry_, profile_, tracker_.get(), std::move(fake_timer)); + registry(), profile(), force_installed_tracker(), + std::move(fake_timer)); } void SetupExtensionManagementPref() { @@ -140,32 +141,32 @@ .Set("installation_mode", "allowed") .Set(ExternalProviderImpl::kExternalUpdateUrl, kExtensionUpdateUrl) .Build(); - prefs_->SetManagedPref(pref_names::kExtensionManagement, - DictionaryBuilder() - .Set(kExtensionId1, std::move(extension_entry)) - .Build()); + prefs()->SetManagedPref(pref_names::kExtensionManagement, + DictionaryBuilder() + .Set(kExtensionId1, std::move(extension_entry)) + .Build()); } // Report downloading manifest stage for both the extensions. void ReportDownloadingManifestStage() { - install_stage_tracker_->ReportDownloadingStage( + install_stage_tracker()->ReportDownloadingStage( kExtensionId1, ExtensionDownloaderDelegate::Stage::DOWNLOADING_MANIFEST); - install_stage_tracker_->ReportDownloadingStage( + install_stage_tracker()->ReportDownloadingStage( kExtensionId2, ExtensionDownloaderDelegate::Stage::DOWNLOADING_MANIFEST); } void ReportInstallationStarted(base::Optional<base::TimeDelta> install_time) { - install_stage_tracker_->ReportDownloadingStage( + install_stage_tracker()->ReportDownloadingStage( kExtensionId1, ExtensionDownloaderDelegate::Stage::MANIFEST_LOADED); - install_stage_tracker_->ReportDownloadingStage( + install_stage_tracker()->ReportDownloadingStage( kExtensionId1, ExtensionDownloaderDelegate::Stage::DOWNLOADING_CRX); if (install_time) task_environment_.FastForwardBy(install_time.value()); - install_stage_tracker_->ReportDownloadingStage( + install_stage_tracker()->ReportDownloadingStage( kExtensionId1, ExtensionDownloaderDelegate::Stage::FINISHED); - install_stage_tracker_->ReportInstallationStage( + install_stage_tracker()->ReportInstallationStage( kExtensionId1, InstallStageTracker::Stage::INSTALLING); } @@ -195,9 +196,9 @@ auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); histogram_tester_.ExpectTotalCount(kLoadTimeStats, 0); - tracker_->OnExtensionLoaded(profile_, ext1.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); histogram_tester_.ExpectTotalCount(kLoadTimeStats, 0); - tracker_->OnExtensionLoaded(profile_, ext2.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); histogram_tester_.ExpectTotalCount(kLoadTimeStats, 1); histogram_tester_.ExpectTotalCount(kTimedOutStats, 0); @@ -208,7 +209,7 @@ histogram_tester_.ExpectTotalCount(kFailureCrxInstallErrorStats, 0); histogram_tester_.ExpectUniqueSample( kTotalCountStats, - prefs_->GetManagedPref(pref_names::kInstallForceList)->DictSize(), 1); + prefs()->GetManagedPref(pref_names::kInstallForceList)->DictSize(), 1); } // Verifies that failure is reported for the extensions which are listed in @@ -218,7 +219,7 @@ SetupForceList(); SetupExtensionManagementPref(); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); - tracker_->OnExtensionLoaded(profile_, ext2.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. EXPECT_FALSE(fake_timer_->IsRunning()); @@ -230,7 +231,7 @@ TEST_F(ForceInstalledMetricsTest, ExtensionsInstallationTimedOut) { SetupForceList(); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - registry_->AddEnabled(ext1.get()); + registry()->AddEnabled(ext1.get()); EXPECT_TRUE(fake_timer_->IsRunning()); fake_timer_->Fire(); // Metrics are reported due to timeout. @@ -244,7 +245,7 @@ histogram_tester_.ExpectTotalCount(kFailureCrxInstallErrorStats, 0); histogram_tester_.ExpectUniqueSample( kTotalCountStats, - prefs_->GetManagedPref(pref_names::kInstallForceList)->DictSize(), 1); + prefs()->GetManagedPref(pref_names::kInstallForceList)->DictSize(), 1); } // Reporting the time for downloading the manifest of an extension and verifying @@ -255,11 +256,11 @@ const base::TimeDelta manifest_download_time = base::TimeDelta::FromMilliseconds(200); task_environment_.FastForwardBy(manifest_download_time); - install_stage_tracker_->ReportDownloadingStage( + install_stage_tracker()->ReportDownloadingStage( kExtensionId1, ExtensionDownloaderDelegate::Stage::MANIFEST_LOADED); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, ext1.get()); - install_stage_tracker_->ReportFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); + install_stage_tracker()->ReportFailure( kExtensionId2, InstallStageTracker::FailureReason::MANIFEST_INVALID); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. @@ -277,8 +278,8 @@ const base::TimeDelta install_time = base::TimeDelta::FromMilliseconds(200); ReportInstallationStarted(install_time); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, ext1.get()); - install_stage_tracker_->ReportFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); + install_stage_tracker()->ReportFailure( kExtensionId2, InstallStageTracker::FailureReason::MANIFEST_INVALID); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. @@ -292,15 +293,15 @@ ExtensionsCrxDownloadTimeWhenFetchedFromCache) { SetupForceList(); ReportDownloadingManifestStage(); - install_stage_tracker_->ReportDownloadingStage( + install_stage_tracker()->ReportDownloadingStage( kExtensionId1, ExtensionDownloaderDelegate::Stage::MANIFEST_LOADED); - install_stage_tracker_->ReportDownloadingStage( + install_stage_tracker()->ReportDownloadingStage( kExtensionId1, ExtensionDownloaderDelegate::Stage::FINISHED); - install_stage_tracker_->ReportInstallationStage( + install_stage_tracker()->ReportInstallationStage( kExtensionId1, InstallStageTracker::Stage::INSTALLING); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, ext1.get()); - install_stage_tracker_->ReportFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); + install_stage_tracker()->ReportFailure( kExtensionId2, InstallStageTracker::FailureReason::MANIFEST_INVALID); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. @@ -316,34 +317,34 @@ SetupForceList(); ReportDownloadingManifestStage(); ReportInstallationStarted(base::nullopt); - install_stage_tracker_->ReportCRXInstallationStage( + install_stage_tracker()->ReportCRXInstallationStage( kExtensionId1, InstallationStage::kVerification); const base::TimeDelta installation_stage_time = base::TimeDelta::FromMilliseconds(200); task_environment_.FastForwardBy(installation_stage_time); - install_stage_tracker_->ReportCRXInstallationStage( + install_stage_tracker()->ReportCRXInstallationStage( kExtensionId1, InstallationStage::kCopying); task_environment_.FastForwardBy(installation_stage_time); - install_stage_tracker_->ReportCRXInstallationStage( + install_stage_tracker()->ReportCRXInstallationStage( kExtensionId1, InstallationStage::kUnpacking); task_environment_.FastForwardBy(installation_stage_time); - install_stage_tracker_->ReportCRXInstallationStage( + install_stage_tracker()->ReportCRXInstallationStage( kExtensionId1, InstallationStage::kCheckingExpectations); task_environment_.FastForwardBy(installation_stage_time); - install_stage_tracker_->ReportCRXInstallationStage( + install_stage_tracker()->ReportCRXInstallationStage( kExtensionId1, InstallationStage::kFinalizing); task_environment_.FastForwardBy(installation_stage_time); - install_stage_tracker_->ReportCRXInstallationStage( + install_stage_tracker()->ReportCRXInstallationStage( kExtensionId1, InstallationStage::kComplete); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, ext1.get()); - install_stage_tracker_->ReportFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); + install_stage_tracker()->ReportFailure( kExtensionId2, InstallStageTracker::FailureReason::MANIFEST_INVALID); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. @@ -371,12 +372,12 @@ ExtensionsInstalledButNotLoadedUniqueDisableReason) { SetupForceList(); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - registry_->AddDisabled(ext1.get()); - ExtensionPrefs::Get(profile_)->AddDisableReason( + registry()->AddDisabled(ext1.get()); + ExtensionPrefs::Get(profile())->AddDisableReason( kExtensionId1, disable_reason::DisableReason::DISABLE_NOT_VERIFIED); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); - registry_->AddEnabled(ext2.get()); - tracker_->OnExtensionLoaded(profile_, ext2.get()); + registry()->AddEnabled(ext2.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); // ForceInstalledMetrics should still keep running as kExtensionId1 is // installed but not loaded. EXPECT_TRUE(fake_timer_->IsRunning()); @@ -391,14 +392,14 @@ ExtensionsInstalledButNotLoadedMultipleDisableReason) { SetupForceList(); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - registry_->AddDisabled(ext1.get()); - ExtensionPrefs::Get(profile_)->AddDisableReasons( + registry()->AddDisabled(ext1.get()); + ExtensionPrefs::Get(profile())->AddDisableReasons( kExtensionId1, disable_reason::DisableReason::DISABLE_NOT_VERIFIED | disable_reason::DisableReason::DISABLE_UNSUPPORTED_REQUIREMENT); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); - registry_->AddEnabled(ext2.get()); - tracker_->OnExtensionLoaded(profile_, ext2.get()); + registry()->AddEnabled(ext2.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); // ForceInstalledMetrics should still keep running as kExtensionId1 is // installed but not loaded. EXPECT_TRUE(fake_timer_->IsRunning()); @@ -415,10 +416,10 @@ ExtensionsInstalledButNotLoadedNoDisableReason) { SetupForceList(); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - registry_->AddEnabled(ext1.get()); + registry()->AddEnabled(ext1.get()); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); - registry_->AddEnabled(ext2.get()); - tracker_->OnExtensionLoaded(profile_, ext2.get()); + registry()->AddEnabled(ext2.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); // ForceInstalledMetrics should still keep running as kExtensionId1 is // installed but not loaded. EXPECT_TRUE(fake_timer_->IsRunning()); @@ -430,10 +431,10 @@ TEST_F(ForceInstalledMetricsTest, ExtensionForceInstalledAndBlocklisted) { SetupForceList(); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - registry_->AddBlocklisted(ext1.get()); + registry()->AddBlocklisted(ext1.get()); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); - registry_->AddEnabled(ext2.get()); - tracker_->OnExtensionLoaded(profile_, ext2.get()); + registry()->AddEnabled(ext2.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); // ForceInstalledMetrics should still keep running as kExtensionId1 is // installed but not loaded. EXPECT_TRUE(fake_timer_->IsRunning()); @@ -458,7 +459,7 @@ TEST_F(ForceInstalledMetricsTest, ForcedExtensionsAddedAfterManualExtensions) { // Report failure for an extension which is not in forced list. - install_stage_tracker_->ReportFailure( + install_stage_tracker()->ReportFailure( kExtensionId3, InstallStageTracker::FailureReason::INVALID_ID); // ForceInstalledMetrics should keep running as the forced extensions are // still not loaded. @@ -466,9 +467,9 @@ SetupForceList(); auto ext = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, ext.get()); - tracker_->OnExtensionReady(profile_, ext.get()); - install_stage_tracker_->ReportFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), ext.get()); + force_installed_tracker()->OnExtensionReady(profile(), ext.get()); + install_stage_tracker()->ReportFailure( kExtensionId2, InstallStageTracker::FailureReason::INVALID_ID); // ForceInstalledMetrics shuts down timer because kExtensionId1 was loaded and // kExtensionId2 was failed. @@ -480,9 +481,9 @@ TEST_F(ForceInstalledMetricsTest, ExtensionsInstallationTimedOutDifferentReasons) { SetupForceList(); - install_stage_tracker_->ReportFailure( + install_stage_tracker()->ReportFailure( kExtensionId1, InstallStageTracker::FailureReason::INVALID_ID); - install_stage_tracker_->ReportCrxInstallError( + install_stage_tracker()->ReportCrxInstallError( kExtensionId2, InstallStageTracker::FailureReason::CRX_INSTALL_ERROR_OTHER, CrxInstallErrorDetail::UNEXPECTED_ID); @@ -503,7 +504,7 @@ CrxInstallErrorDetail::UNEXPECTED_ID, 1); histogram_tester_.ExpectUniqueSample( kTotalCountStats, - prefs_->GetManagedPref(pref_names::kInstallForceList)->DictSize(), 1); + prefs()->GetManagedPref(pref_names::kInstallForceList)->DictSize(), 1); } // Reporting SandboxedUnpackerFailureReason when the force installed extension @@ -511,9 +512,9 @@ TEST_F(ForceInstalledMetricsTest, ExtensionsCrxInstallErrorSandboxUnpackFailure) { SetupForceList(); - install_stage_tracker_->ReportSandboxedUnpackerFailureReason( + install_stage_tracker()->ReportSandboxedUnpackerFailureReason( kExtensionId1, SandboxedUnpackerFailureReason::CRX_FILE_NOT_READABLE); - install_stage_tracker_->ReportSandboxedUnpackerFailureReason( + install_stage_tracker()->ReportSandboxedUnpackerFailureReason( kExtensionId2, SandboxedUnpackerFailureReason::UNZIP_FAILED); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. @@ -532,12 +533,12 @@ TEST_F(ForceInstalledMetricsTest, ExtensionsNoUpdatesInfoReporting) { SetupForceList(); - install_stage_tracker_->ReportInfoOnNoUpdatesFailure(kExtensionId1, - "disabled by client"); - install_stage_tracker_->ReportFailure( + install_stage_tracker()->ReportInfoOnNoUpdatesFailure(kExtensionId1, + "disabled by client"); + install_stage_tracker()->ReportFailure( kExtensionId1, InstallStageTracker::FailureReason::CRX_FETCH_URL_EMPTY); - install_stage_tracker_->ReportInfoOnNoUpdatesFailure(kExtensionId2, ""); - install_stage_tracker_->ReportFailure( + install_stage_tracker()->ReportInfoOnNoUpdatesFailure(kExtensionId2, ""); + install_stage_tracker()->ReportFailure( kExtensionId2, InstallStageTracker::FailureReason::CRX_FETCH_URL_EMPTY); // ForceInstalledMetrics shuts down timer because all extension are either @@ -558,11 +559,11 @@ ExtensionLoadedThenFailedWithAlreadyInstalledError) { SetupForceList(); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, ext1.get()); - install_stage_tracker_->ReportFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); + install_stage_tracker()->ReportFailure( kExtensionId1, InstallStageTracker::FailureReason::ALREADY_INSTALLED); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); - tracker_->OnExtensionLoaded(profile_, ext2.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. EXPECT_FALSE(fake_timer_->IsRunning()); @@ -576,13 +577,13 @@ TEST_F(ForceInstalledMetricsTest, ExtensionsReady) { SetupForceList(); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, ext1.get()); - tracker_->OnExtensionReady(profile_, ext1.get()); - install_stage_tracker_->ReportFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); + force_installed_tracker()->OnExtensionReady(profile(), ext1.get()); + install_stage_tracker()->ReportFailure( kExtensionId1, InstallStageTracker::FailureReason::ALREADY_INSTALLED); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); - tracker_->OnExtensionLoaded(profile_, ext2.get()); - tracker_->OnExtensionReady(profile_, ext2.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); + force_installed_tracker()->OnExtensionReady(profile(), ext2.get()); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. EXPECT_FALSE(fake_timer_->IsRunning()); @@ -593,11 +594,11 @@ TEST_F(ForceInstalledMetricsTest, ExtensionsStuck) { SetupForceList(); - install_stage_tracker_->ReportInstallationStage( + install_stage_tracker()->ReportInstallationStage( kExtensionId1, InstallStageTracker::Stage::PENDING); - install_stage_tracker_->ReportInstallationStage( + install_stage_tracker()->ReportInstallationStage( kExtensionId2, InstallStageTracker::Stage::DOWNLOADING); - install_stage_tracker_->ReportDownloadingStage( + install_stage_tracker()->ReportDownloadingStage( kExtensionId2, ExtensionDownloaderDelegate::Stage::PENDING); EXPECT_TRUE(fake_timer_->IsRunning()); fake_timer_->Fire(); @@ -613,17 +614,17 @@ histogram_tester_.ExpectTotalCount(kFailureCrxInstallErrorStats, 0); histogram_tester_.ExpectUniqueSample( kTotalCountStats, - prefs_->GetManagedPref(pref_names::kInstallForceList)->DictSize(), 1); + prefs()->GetManagedPref(pref_names::kInstallForceList)->DictSize(), 1); } TEST_F(ForceInstalledMetricsTest, ExtensionStuckInCreatedStage) { SetupForceList(); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, extension.get()); - install_stage_tracker_->ReportInstallationStage( + force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); + install_stage_tracker()->ReportInstallationStage( kExtensionId2, InstallStageTracker::Stage::CREATED); - install_stage_tracker_->ReportInstallCreationStage( + install_stage_tracker()->ReportInstallCreationStage( kExtensionId2, InstallStageTracker::InstallCreationStage:: NOTIFIED_FROM_MANAGEMENT_INITIAL_CREATION_FORCED); EXPECT_TRUE(fake_timer_->IsRunning()); @@ -646,7 +647,7 @@ user_manager::ScopedUserManager scoped_user_manager( base::WrapUnique(fake_user_manager)); const AccountId account_id = - AccountId::FromUserEmail(profile_->GetProfileUserName()); + AccountId::FromUserEmail(profile()->GetProfileUserName()); user_manager::User* user = fake_user_manager->AddPublicAccountUser(account_id); fake_user_manager->UserLoggedIn(account_id, user->username_hash(), @@ -654,9 +655,9 @@ false /* is_child */); chromeos::ProfileHelper::Get()->SetProfileToUserMappingForTesting(user); SetupForceList(); - install_stage_tracker_->ReportFailure( + install_stage_tracker()->ReportFailure( kExtensionId1, InstallStageTracker::FailureReason::INVALID_ID); - install_stage_tracker_->ReportCrxInstallError( + install_stage_tracker()->ReportCrxInstallError( kExtensionId2, InstallStageTracker::FailureReason::CRX_INSTALL_ERROR_OTHER, CrxInstallErrorDetail::UNEXPECTED_ID); @@ -674,16 +675,16 @@ user_manager::ScopedUserManager scoped_user_manager( base::WrapUnique(fake_user_manager)); const AccountId account_id = - AccountId::FromUserEmail(profile_->GetProfileUserName()); + AccountId::FromUserEmail(profile()->GetProfileUserName()); user_manager::User* user = fake_user_manager->AddGuestUser(); fake_user_manager->UserLoggedIn(account_id, user->username_hash(), false /* browser_restart */, false /* is_child */); chromeos::ProfileHelper::Get()->SetProfileToUserMappingForTesting(user); SetupForceList(); - install_stage_tracker_->ReportFailure( + install_stage_tracker()->ReportFailure( kExtensionId1, InstallStageTracker::FailureReason::INVALID_ID); - install_stage_tracker_->ReportCrxInstallError( + install_stage_tracker()->ReportCrxInstallError( kExtensionId2, InstallStageTracker::FailureReason::CRX_INSTALL_ERROR_OTHER, CrxInstallErrorDetail::UNEXPECTED_ID); @@ -698,13 +699,13 @@ TEST_F(ForceInstalledMetricsTest, ExtensionsAreDownloading) { SetupForceList(); - install_stage_tracker_->ReportInstallationStage( + install_stage_tracker()->ReportInstallationStage( kExtensionId1, InstallStageTracker::Stage::DOWNLOADING); - install_stage_tracker_->ReportDownloadingStage( + install_stage_tracker()->ReportDownloadingStage( kExtensionId1, ExtensionDownloaderDelegate::Stage::DOWNLOADING_MANIFEST); - install_stage_tracker_->ReportInstallationStage( + install_stage_tracker()->ReportInstallationStage( kExtensionId2, InstallStageTracker::Stage::DOWNLOADING); - install_stage_tracker_->ReportDownloadingStage( + install_stage_tracker()->ReportDownloadingStage( kExtensionId2, ExtensionDownloaderDelegate::Stage::DOWNLOADING_CRX); EXPECT_TRUE(fake_timer_->IsRunning()); fake_timer_->Fire(); @@ -724,7 +725,7 @@ ExtensionDownloaderDelegate::Stage::DOWNLOADING_CRX, 1); histogram_tester_.ExpectUniqueSample( kTotalCountStats, - prefs_->GetManagedPref(pref_names::kInstallForceList)->DictSize(), 1); + prefs()->GetManagedPref(pref_names::kInstallForceList)->DictSize(), 1); } // Error Codes in case of CRX_FETCH_FAILED. @@ -734,10 +735,10 @@ kFetchTries); ExtensionDownloaderDelegate::FailureData data2( -net::Error::ERR_INVALID_ARGUMENT, kFetchTries); - install_stage_tracker_->ReportFetchError( + install_stage_tracker()->ReportFetchError( kExtensionId1, InstallStageTracker::FailureReason::CRX_FETCH_FAILED, data1); - install_stage_tracker_->ReportFetchError( + install_stage_tracker()->ReportFetchError( kExtensionId2, InstallStageTracker::FailureReason::CRX_FETCH_FAILED, data2); // ForceInstalledMetrics shuts down timer because all extension are either @@ -758,10 +759,10 @@ kFetchTries); ExtensionDownloaderDelegate::FailureData data2( -net::Error::ERR_INVALID_ARGUMENT, kFetchTries); - install_stage_tracker_->ReportFetchError( + install_stage_tracker()->ReportFetchError( kExtensionId1, InstallStageTracker::FailureReason::MANIFEST_FETCH_FAILED, data1); - install_stage_tracker_->ReportFetchError( + install_stage_tracker()->ReportFetchError( kExtensionId2, InstallStageTracker::FailureReason::MANIFEST_FETCH_FAILED, data2); // ForceInstalledMetrics shuts down timer because all extension are either @@ -782,8 +783,8 @@ SetupForceList(); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, extension.get()); - install_stage_tracker_->ReportManifestInvalidFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); + install_stage_tracker()->ReportManifestInvalidFailure( kExtensionId2, ExtensionDownloaderDelegate::FailureData( ManifestInvalidError::INVALID_PROTOCOL_ON_GUPDATE_TAG)); @@ -801,8 +802,8 @@ SetupForceList(); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, extension.get()); - install_stage_tracker_->ReportManifestInvalidFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); + install_stage_tracker()->ReportManifestInvalidFailure( kExtensionId2, ExtensionDownloaderDelegate::FailureData( ManifestInvalidError::BAD_APP_STATUS, "error-unknownApplication")); @@ -825,8 +826,8 @@ SetupForceList(); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, extension.get()); - install_stage_tracker_->ReportCrxInstallError( + force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); + install_stage_tracker()->ReportCrxInstallError( kExtensionId2, InstallStageTracker::FailureReason::CRX_INSTALL_ERROR_DECLINED, CrxInstallErrorDetail::KIOSK_MODE_ONLY); @@ -848,15 +849,15 @@ // Set TYPE_EXTENSION and TYPE_THEME as the allowed extension types. std::unique_ptr<base::Value> list = ListBuilder().Append("extension").Append("theme").Build(); - prefs_->SetManagedPref(pref_names::kAllowedTypes, std::move(list)); + prefs()->SetManagedPref(pref_names::kAllowedTypes, std::move(list)); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, extension.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); // Hosted app is not a valid extension type, so this should report an error. - install_stage_tracker_->ReportExtensionType(kExtensionId2, - Manifest::Type::TYPE_HOSTED_APP); - install_stage_tracker_->ReportCrxInstallError( + install_stage_tracker()->ReportExtensionType(kExtensionId2, + Manifest::Type::TYPE_HOSTED_APP); + install_stage_tracker()->ReportCrxInstallError( kExtensionId2, InstallStageTracker::FailureReason::CRX_INSTALL_ERROR_DECLINED, CrxInstallErrorDetail::DISALLOWED_BY_POLICY); @@ -879,14 +880,14 @@ // Set TYPE_EXTENSION and TYPE_THEME as the allowed extension types. std::unique_ptr<base::Value> list = ListBuilder().Append("extension").Append("theme").Build(); - prefs_->SetManagedPref(pref_names::kAllowedTypes, std::move(list)); + prefs()->SetManagedPref(pref_names::kAllowedTypes, std::move(list)); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, extension.get()); - install_stage_tracker_->ReportExtensionType(kExtensionId2, - Manifest::Type::TYPE_EXTENSION); - install_stage_tracker_->ReportCrxInstallError( + force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); + install_stage_tracker()->ReportExtensionType(kExtensionId2, + Manifest::Type::TYPE_EXTENSION); + install_stage_tracker()->ReportCrxInstallError( kExtensionId2, InstallStageTracker::FailureReason::CRX_INSTALL_ERROR_DECLINED, CrxInstallErrorDetail::DISALLOWED_BY_POLICY); @@ -904,9 +905,9 @@ // extension fails to install with failure reason CRX_INSTALL_ERROR. TEST_F(ForceInstalledMetricsTest, NonMisconfigurationFailurePresent) { SetupForceList(); - install_stage_tracker_->ReportFailure( + install_stage_tracker()->ReportFailure( kExtensionId1, InstallStageTracker::FailureReason::INVALID_ID); - install_stage_tracker_->ReportCrxInstallError( + install_stage_tracker()->ReportCrxInstallError( kExtensionId2, InstallStageTracker::FailureReason::CRX_INSTALL_ERROR_DECLINED, CrxInstallErrorDetail::KIOSK_MODE_ONLY); @@ -925,13 +926,13 @@ TEST_F(ForceInstalledMetricsTest, NonMisconfigurationFailureNotPresentReplacedByArcAppErrorArcEnabled) { // Enable ARC++ for this profile. - prefs_->SetManagedPref(arc::prefs::kArcEnabled, - std::make_unique<base::Value>(true)); + prefs()->SetManagedPref(arc::prefs::kArcEnabled, + std::make_unique<base::Value>(true)); SetupForceList(); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, extension.get()); - install_stage_tracker_->ReportFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); + install_stage_tracker()->ReportFailure( kExtensionId2, InstallStageTracker::FailureReason::REPLACED_BY_ARC_APP); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. @@ -946,13 +947,13 @@ TEST_F(ForceInstalledMetricsTest, NonMisconfigurationFailureNotPresentReplacedByArcAppErrorArcDisabled) { // Enable ARC++ for this profile. - prefs_->SetManagedPref(arc::prefs::kArcEnabled, - std::make_unique<base::Value>(false)); + prefs()->SetManagedPref(arc::prefs::kArcEnabled, + std::make_unique<base::Value>(false)); SetupForceList(); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, extension.get()); - install_stage_tracker_->ReportFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); + install_stage_tracker()->ReportFailure( kExtensionId2, InstallStageTracker::FailureReason::REPLACED_BY_ARC_APP); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. @@ -970,8 +971,8 @@ SetupForceList(); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, extension.get()); - install_stage_tracker_->ReportFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); + install_stage_tracker()->ReportFailure( kExtensionId2, InstallStageTracker::FailureReason::NOT_PERFORMING_NEW_INSTALL); // ForceInstalledMetrics shuts down timer because all extension are either @@ -989,9 +990,9 @@ SetupForceList(); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, extension.get()); - install_stage_tracker_->ReportInfoOnNoUpdatesFailure(kExtensionId2, ""); - install_stage_tracker_->ReportFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); + install_stage_tracker()->ReportInfoOnNoUpdatesFailure(kExtensionId2, ""); + install_stage_tracker()->ReportFailure( kExtensionId2, InstallStageTracker::FailureReason::CRX_FETCH_URL_EMPTY); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. @@ -1007,10 +1008,10 @@ SetupForceList(); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, extension.get()); - install_stage_tracker_->ReportInfoOnNoUpdatesFailure(kExtensionId2, - "rate limit"); - install_stage_tracker_->ReportFailure( + force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); + install_stage_tracker()->ReportInfoOnNoUpdatesFailure(kExtensionId2, + "rate limit"); + install_stage_tracker()->ReportFailure( kExtensionId2, InstallStageTracker::FailureReason::CRX_FETCH_URL_EMPTY); // ForceInstalledMetrics shuts down timer because all extension are either // loaded or failed. @@ -1033,12 +1034,12 @@ TEST_F(ForceInstalledMetricsTest, CachedExtensions) { SetupForceList(); - install_stage_tracker_->ReportDownloadingCacheStatus( + install_stage_tracker()->ReportDownloadingCacheStatus( kExtensionId1, ExtensionDownloaderDelegate::CacheStatus::CACHE_HIT); - install_stage_tracker_->ReportDownloadingCacheStatus( + install_stage_tracker()->ReportDownloadingCacheStatus( kExtensionId2, ExtensionDownloaderDelegate::CacheStatus::CACHE_MISS); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - registry_->AddEnabled(ext1.get()); + registry()->AddEnabled(ext1.get()); EXPECT_TRUE(fake_timer_->IsRunning()); fake_timer_->Fire(); // If an extension was installed successfully, don't mention it in statistics.
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_test_base.cc b/chrome/browser/extensions/forced_extensions/force_installed_test_base.cc index fe392521..f09b3548 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_test_base.cc +++ b/chrome/browser/extensions/forced_extensions/force_installed_test_base.cc
@@ -11,7 +11,6 @@ #include "chrome/browser/extensions/forced_extensions/force_installed_tracker.h" #include "chrome/browser/extensions/forced_extensions/install_stage_tracker.h" #include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile.h" #include "components/policy/core/common/policy_service_impl.h" #include "components/prefs/pref_service.h" #include "components/sync_preferences/testing_pref_service_syncable.h" @@ -54,7 +53,8 @@ prefs_ = profile_->GetTestingPrefService(); registry_ = ExtensionRegistry::Get(profile_); install_stage_tracker_ = InstallStageTracker::Get(profile_); - tracker_ = std::make_unique<ForceInstalledTracker>(registry_, profile_); + force_installed_tracker_ = + std::make_unique<ForceInstalledTracker>(registry_, profile_); } void ForceInstalledTestBase::SetupForceList() {
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_test_base.h b/chrome/browser/extensions/forced_extensions/force_installed_test_base.h index 6fe9b71..1e4b143a 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_test_base.h +++ b/chrome/browser/extensions/forced_extensions/force_installed_test_base.h
@@ -5,13 +5,12 @@ #ifndef CHROME_BROWSER_EXTENSIONS_FORCED_EXTENSIONS_FORCE_INSTALLED_TEST_BASE_H_ #define CHROME_BROWSER_EXTENSIONS_FORCED_EXTENSIONS_FORCE_INSTALLED_TEST_BASE_H_ +#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" #include "components/policy/core/common/mock_configuration_policy_provider.h" #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" -class TestingProfile; - namespace sync_preferences { class TestingPrefServiceSyncable; } @@ -44,6 +43,20 @@ // kInstallForceList preference. void SetupEmptyForceList(); + Profile* profile() const { return profile_; } + + sync_preferences::TestingPrefServiceSyncable* prefs() const { return prefs_; } + + ExtensionRegistry* registry() const { return registry_; } + + InstallStageTracker* install_stage_tracker() const { + return install_stage_tracker_; + } + + ForceInstalledTracker* force_installed_tracker() const { + return force_installed_tracker_.get(); + } + static const char kExtensionId1[]; static const char kExtensionId2[]; static const char kExtensionName1[]; @@ -52,13 +65,15 @@ content::BrowserTaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + + private: policy::MockConfigurationPolicyProvider policy_provider_; std::unique_ptr<TestingProfileManager> profile_manager_; TestingProfile* profile_; sync_preferences::TestingPrefServiceSyncable* prefs_; ExtensionRegistry* registry_; InstallStageTracker* install_stage_tracker_; - std::unique_ptr<ForceInstalledTracker> tracker_; + std::unique_ptr<ForceInstalledTracker> force_installed_tracker_; }; } // namespace extensions
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_tracker_unittest.cc b/chrome/browser/extensions/forced_extensions/force_installed_tracker_unittest.cc index 8e55ea3..5ad4090 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_tracker_unittest.cc +++ b/chrome/browser/extensions/forced_extensions/force_installed_tracker_unittest.cc
@@ -24,7 +24,7 @@ void SetUp() override { ForceInstalledTestBase::SetUp(); - scoped_observer_.Add(tracker_.get()); + scoped_observer_.Add(force_installed_tracker()); } // ForceInstalledTracker::Observer overrides: @@ -60,21 +60,21 @@ auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); EXPECT_FALSE(loaded_called_); EXPECT_FALSE(ready_called_); - EXPECT_FALSE(tracker_->IsDoneLoading()); + EXPECT_FALSE(force_installed_tracker()->IsDoneLoading()); - tracker_->OnExtensionLoaded(profile_, ext1.get()); - tracker_->OnExtensionLoaded(profile_, ext2.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); EXPECT_TRUE(loaded_called_); EXPECT_FALSE(ready_called_); - EXPECT_TRUE(tracker_->IsDoneLoading()); - EXPECT_FALSE(tracker_->IsReady()); + EXPECT_TRUE(force_installed_tracker()->IsDoneLoading()); + EXPECT_FALSE(force_installed_tracker()->IsReady()); - tracker_->OnExtensionReady(profile_, ext1.get()); - tracker_->OnExtensionReady(profile_, ext2.get()); + force_installed_tracker()->OnExtensionReady(profile(), ext1.get()); + force_installed_tracker()->OnExtensionReady(profile(), ext2.get()); EXPECT_TRUE(loaded_called_); EXPECT_TRUE(ready_called_); - EXPECT_TRUE(tracker_->IsDoneLoading()); - EXPECT_TRUE(tracker_->IsReady()); + EXPECT_TRUE(force_installed_tracker()->IsDoneLoading()); + EXPECT_TRUE(force_installed_tracker()->IsReady()); } // This test verifies that OnForceInstalledExtensionsLoaded() is not called till @@ -82,15 +82,15 @@ TEST_F(ForceInstalledTrackerTest, ExtensionPendingInstall) { SetupForceList(); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, ext1.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); EXPECT_FALSE(loaded_called_); EXPECT_FALSE(ready_called_); - EXPECT_FALSE(tracker_->IsDoneLoading()); + EXPECT_FALSE(force_installed_tracker()->IsDoneLoading()); - tracker_->OnExtensionReady(profile_, ext1.get()); + force_installed_tracker()->OnExtensionReady(profile(), ext1.get()); EXPECT_FALSE(loaded_called_); EXPECT_FALSE(ready_called_); - EXPECT_FALSE(tracker_->IsDoneLoading()); + EXPECT_FALSE(force_installed_tracker()->IsDoneLoading()); } // This test verifies that applying a new policy value for force installed @@ -102,12 +102,12 @@ SetupForceList(); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); - tracker_->OnExtensionLoaded(profile_, ext1.get()); - tracker_->OnExtensionLoaded(profile_, ext2.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); EXPECT_TRUE(loaded_called_); - tracker_->OnExtensionReady(profile_, ext1.get()); - tracker_->OnExtensionReady(profile_, ext2.get()); + force_installed_tracker()->OnExtensionReady(profile(), ext1.get()); + force_installed_tracker()->OnExtensionReady(profile(), ext2.get()); EXPECT_TRUE(ready_called_); SetupEmptyForceList(); @@ -120,12 +120,12 @@ TEST_F(ForceInstalledTrackerTest, ExtensionsInstallationFailed) { SetupForceList(); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, ext1.get()); - tracker_->OnExtensionInstallationFailed( + force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); + force_installed_tracker()->OnExtensionInstallationFailed( kExtensionId2, InstallStageTracker::FailureReason::INVALID_ID); EXPECT_TRUE(loaded_called_); EXPECT_FALSE(ready_called_); - EXPECT_TRUE(tracker_->IsDoneLoading()); + EXPECT_TRUE(force_installed_tracker()->IsDoneLoading()); } // This test tracks the status of the force installed extensions in @@ -133,22 +133,22 @@ // failed. TEST_F(ForceInstalledTrackerTest, ExtensionsStatus) { SetupForceList(); - EXPECT_EQ(tracker_->extensions().at(kExtensionId1).status, + EXPECT_EQ(force_installed_tracker()->extensions().at(kExtensionId1).status, ForceInstalledTracker::ExtensionStatus::PENDING); - EXPECT_EQ(tracker_->extensions().at(kExtensionId2).status, + EXPECT_EQ(force_installed_tracker()->extensions().at(kExtensionId2).status, ForceInstalledTracker::ExtensionStatus::PENDING); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); - tracker_->OnExtensionLoaded(profile_, ext1.get()); - tracker_->OnExtensionInstallationFailed( + force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); + force_installed_tracker()->OnExtensionInstallationFailed( kExtensionId2, InstallStageTracker::FailureReason::INVALID_ID); - EXPECT_EQ(tracker_->extensions().at(kExtensionId1).status, + EXPECT_EQ(force_installed_tracker()->extensions().at(kExtensionId1).status, ForceInstalledTracker::ExtensionStatus::LOADED); - EXPECT_EQ(tracker_->extensions().at(kExtensionId2).status, + EXPECT_EQ(force_installed_tracker()->extensions().at(kExtensionId2).status, ForceInstalledTracker::ExtensionStatus::FAILED); - tracker_->OnExtensionReady(profile_, ext1.get()); - EXPECT_EQ(tracker_->extensions().at(kExtensionId1).status, + force_installed_tracker()->OnExtensionReady(profile(), ext1.get()); + EXPECT_EQ(force_installed_tracker()->extensions().at(kExtensionId1).status, ForceInstalledTracker::ExtensionStatus::READY); }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 4446c323..cf1b09f0 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -467,11 +467,6 @@ "expiry_milestone": 91 }, { - "name": "change-tab-switcher-position", - "owners": [ "ewannpv", "gambard", "bling-flags" ], - "expiry_milestone": 87 - }, - { "name": "chrome-share-highlights-android", "owners": [ "gayane" ], "expiry_milestone": 88 @@ -3908,6 +3903,11 @@ "expiry_milestone": 80 }, { + "name": "restore-gaia-cookies-if-deleted", + "owners": [ "fernandex", "chrome-signin-team" ], + "expiry_milestone": 96 + }, + { "name": "restrict-gamepad-access", "owners": [ "//device/gamepad/OWNERS", "jameshollyer@chromium.org" ], "expiry_milestone": 89
diff --git a/chrome/browser/media/router/discovery/dial/dial_registry.cc b/chrome/browser/media/router/discovery/dial/dial_registry.cc index ae3f1d2..6fdc2194 100644 --- a/chrome/browser/media/router/discovery/dial/dial_registry.cc +++ b/chrome/browser/media/router/discovery/dial/dial_registry.cc
@@ -368,6 +368,7 @@ case network::mojom::ConnectionType::CONNECTION_2G: case network::mojom::ConnectionType::CONNECTION_3G: case network::mojom::ConnectionType::CONNECTION_4G: + case network::mojom::ConnectionType::CONNECTION_5G: case network::mojom::ConnectionType::CONNECTION_ETHERNET: case network::mojom::ConnectionType::CONNECTION_WIFI: case network::mojom::ConnectionType::CONNECTION_UNKNOWN:
diff --git a/chrome/browser/metrics/perf/metric_collector.cc b/chrome/browser/metrics/perf/metric_collector.cc index 01fca98..acd2d20 100644 --- a/chrome/browser/metrics/perf/metric_collector.cc +++ b/chrome/browser/metrics/perf/metric_collector.cc
@@ -282,6 +282,11 @@ AddToUmaHistogram(CollectionAttemptStatus::PROTOBUF_NOT_PARSED); return; } + // Don't save the profile if there are no samples. + if (perf_data_proto.stats().num_sample_events() == 0) { + AddToUmaHistogram(CollectionAttemptStatus::SESSION_HAS_ZERO_SAMPLES); + return; + } RemoveUnknownFieldsFromMessagesWithStrings(&perf_data_proto); sampled_profile->mutable_perf_data()->Swap(&perf_data_proto);
diff --git a/chrome/browser/metrics/perf/metric_collector.h b/chrome/browser/metrics/perf/metric_collector.h index 05ab4ec..6585c3d 100644 --- a/chrome/browser/metrics/perf/metric_collector.h +++ b/chrome/browser/metrics/perf/metric_collector.h
@@ -88,6 +88,7 @@ ALREADY_COLLECTING, UNABLE_TO_COLLECT, DATA_COLLECTION_FAILED, + SESSION_HAS_ZERO_SAMPLES, NUM_OUTCOMES };
diff --git a/chrome/browser/metrics/perf/metric_collector_unittest.cc b/chrome/browser/metrics/perf/metric_collector_unittest.cc index 7faef79..9cb55a0 100644 --- a/chrome/browser/metrics/perf/metric_collector_unittest.cc +++ b/chrome/browser/metrics/perf/metric_collector_unittest.cc
@@ -15,6 +15,7 @@ #include "base/memory/scoped_refptr.h" #include "base/task/post_task.h" #include "base/test/bind_test_util.h" +#include "base/test/metrics/histogram_tester.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" @@ -78,9 +79,9 @@ public: TestMetricCollector() : TestMetricCollector(CollectionParams()) {} explicit TestMetricCollector(const CollectionParams& collection_params) - : MetricCollector("UMA.CWP.TestData", collection_params) {} + : MetricCollector("Test", collection_params) {} - const char* ToolName() const override { return "test"; } + const char* ToolName() const override { return "Test"; } base::WeakPtr<MetricCollector> GetWeakPtr() override { return weak_factory_.GetWeakPtr(); } @@ -93,6 +94,7 @@ } using MetricCollector::collection_params; + using MetricCollector::CollectionAttemptStatus; using MetricCollector::CurrentTimerDelay; using MetricCollector::Init; using MetricCollector::IsRunning; @@ -179,22 +181,50 @@ TEST_F(MetricCollectorTest, EmptyProtosAreNotSaved) { auto sampled_profile = std::make_unique<SampledProfile>(); sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION); + base::HistogramTester histogram_tester; metric_collector_->SaveSerializedPerfProto(std::move(sampled_profile), std::string()); task_environment_.RunUntilIdle(); EXPECT_TRUE(cached_profile_data_.empty()); + histogram_tester.ExpectUniqueSample( + "ChromeOS.CWP.CollectTest", + TestMetricCollector::CollectionAttemptStatus::ILLEGAL_DATA_RETURNED, 1); +} + +TEST_F(MetricCollectorTest, ProtosWithNoSamplesAreNotSaved) { + auto sampled_profile = std::make_unique<SampledProfile>(); + sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION); + base::HistogramTester histogram_tester; + + PerfDataProto proto = GetExamplePerfDataProto(); + PerfDataProto_PerfEventStats* stats = proto.mutable_stats(); + stats->set_num_sample_events(0); + + metric_collector_->SaveSerializedPerfProto(std::move(sampled_profile), + proto.SerializeAsString()); + task_environment_.RunUntilIdle(); + + EXPECT_TRUE(cached_profile_data_.empty()); + histogram_tester.ExpectUniqueSample( + "ChromeOS.CWP.CollectTest", + TestMetricCollector::CollectionAttemptStatus::SESSION_HAS_ZERO_SAMPLES, + 1); } TEST_F(MetricCollectorTest, PerfDataProto) { auto sampled_profile = std::make_unique<SampledProfile>(); sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION); + base::HistogramTester histogram_tester; metric_collector_->SaveSerializedPerfProto( std::move(sampled_profile), perf_data_proto_.SerializeAsString()); task_environment_.RunUntilIdle(); ASSERT_EQ(1U, cached_profile_data_.size()); + histogram_tester.ExpectUniqueSample( + "ChromeOS.CWP.CollectTest", + TestMetricCollector::CollectionAttemptStatus::SUCCESS, 1); const SampledProfile& profile = cached_profile_data_[0]; EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION, profile.trigger_event());
diff --git a/chrome/browser/metrics/perf/perf_events_collector.cc b/chrome/browser/metrics/perf/perf_events_collector.cc index c56e8e2..f6ae53a2 100644 --- a/chrome/browser/metrics/perf/perf_events_collector.cc +++ b/chrome/browser/metrics/perf/perf_events_collector.cc
@@ -87,6 +87,12 @@ bugfix_version); } +// Returns if a micro-architecture supports the cycles:ppp event. +bool MicroarchitectureHasCyclesPPPEvent(const std::string& uarch) { + return uarch == "Goldmont" || uarch == "GoldmontPlus" || + uarch == "Broadwell" || uarch == "Kabylake" || uarch == "Tigerlake"; +} + // Returns if a micro-architecture supports LBR callgraph profiling. bool MicroarchitectureHasLBRCallgraph(const std::string& uarch) { return uarch == "Haswell" || uarch == "Broadwell" || uarch == "Skylake" || @@ -103,6 +109,16 @@ // Hopefully we never need a space in a command argument. const char kPerfCommandDelimiter[] = " "; +// Collect precise=3 (:ppp) cycle events on microarchitectures that support it. +const char kPerfCyclesPPPCmd[] = "perf record -a -e cycles:ppp -c 1000003"; + +const char kPerfFPCallgraphPPPCmd[] = + "perf record -a -e cycles:ppp -g -c 4000037"; + +const char kPerfLBRCallgraphPPPCmd[] = + "perf record -a -e cycles:ppp -c 4000037 --call-graph lbr"; + +// Collect default (imprecise) cycle events everywhere else. const char kPerfCyclesCmd[] = "perf record -a -e cycles -c 1000003"; const char kPerfFPCallgraphCmd[] = "perf record -a -e cycles -g -c 4000037"; @@ -156,6 +172,9 @@ const char* itlb_miss_cycles_cmd = kPerfITLBMissCyclesCmdIvyBridge; const char* dtlb_miss_cycles_cmd = kPerfDTLBMissCyclesCmdIvyBridge; const char* lbr_cmd = kPerfLBRCmd; + const char* cycles_cmd = kPerfCyclesCmd; + const char* fp_callgraph_cmd = kPerfFPCallgraphCmd; + const char* lbr_callgraph_cmd = kPerfLBRCallgraphCmd; if (cpu_uarch == "Skylake" || cpu_uarch == "Kabylake" || cpu_uarch == "Tigerlake" || cpu_uarch == "GoldmontPlus") { @@ -171,6 +190,28 @@ cpu_uarch == "Goldmont" || cpu_uarch == "GoldmontPlus") { lbr_cmd = kPerfLBRCmdAtom; } + if (MicroarchitectureHasCyclesPPPEvent(cpu_uarch)) { + cycles_cmd = kPerfCyclesPPPCmd; + fp_callgraph_cmd = kPerfFPCallgraphPPPCmd; + lbr_callgraph_cmd = kPerfLBRCallgraphPPPCmd; + } + + cmds.emplace_back(WeightAndValue(50.0, cycles_cmd)); + + // Haswell and newer big Intel cores support LBR callstack profiling. This + // requires kernel support, which was added in kernel 4.4, and it was + // backported to kernel 3.18. Collect LBR callstack profiling where + // supported in addition to FP callchains. The former works with binaries + // compiled with frame pointers disabled, but it only captures callchains + // after profiling is enabled, so it's likely missing the lower frames of + // the callstack. + if (MicroarchitectureHasLBRCallgraph(cpu_uarch) && + KernelReleaseHasLBRCallgraph(cpuid.release)) { + cmds.emplace_back(WeightAndValue(10.0, fp_callgraph_cmd)); + cmds.emplace_back(WeightAndValue(10.0, lbr_callgraph_cmd)); + } else { + cmds.emplace_back(WeightAndValue(20.0, fp_callgraph_cmd)); + } if (cpu_uarch == "IvyBridge" || cpu_uarch == "Haswell" || cpu_uarch == "Broadwell" || cpu_uarch == "SandyBridge" || @@ -178,30 +219,15 @@ cpu_uarch == "Tigerlake" || cpu_uarch == "Silvermont" || cpu_uarch == "Airmont" || cpu_uarch == "Goldmont" || cpu_uarch == "GoldmontPlus") { - cmds.push_back(WeightAndValue(50.0, kPerfCyclesCmd)); - // Haswell and newer big Intel cores support LBR callstack profiling. This - // requires kernel support, which was added in kernel 4.4, and it was - // backported to kernel 3.18. Collect LBR callstack profiling where - // supported in addition to FP callchains. The former works with binaries - // compiled with frame pointers disabled, but it only captures callchains - // after profiling is enabled, so it's likely missing the lower frames of - // the callstack. - if (MicroarchitectureHasLBRCallgraph(cpu_uarch) && - KernelReleaseHasLBRCallgraph(cpuid.release)) { - cmds.push_back(WeightAndValue(10.0, kPerfFPCallgraphCmd)); - cmds.push_back(WeightAndValue(10.0, kPerfLBRCallgraphCmd)); - } else { - cmds.push_back(WeightAndValue(20.0, kPerfFPCallgraphCmd)); - } - cmds.push_back(WeightAndValue(15.0, lbr_cmd)); - cmds.push_back(WeightAndValue(5.0, itlb_miss_cycles_cmd)); - cmds.push_back(WeightAndValue(5.0, dtlb_miss_cycles_cmd)); + cmds.emplace_back(WeightAndValue(15.0, lbr_cmd)); + cmds.emplace_back(WeightAndValue(5.0, itlb_miss_cycles_cmd)); + cmds.emplace_back(WeightAndValue(5.0, dtlb_miss_cycles_cmd)); // Only Goldmont and GoldmontPlus support precise events on last level cache // misses. if (cpu_uarch == "Goldmont" || cpu_uarch == "GoldmontPlus") { - cmds.push_back(WeightAndValue(5.0, kPerfLLCMissesPreciseCmd)); + cmds.emplace_back(WeightAndValue(5.0, kPerfLLCMissesPreciseCmd)); } else { - cmds.push_back(WeightAndValue(5.0, kPerfLLCMissesCmd)); + cmds.emplace_back(WeightAndValue(5.0, kPerfLLCMissesCmd)); } return cmds; } @@ -209,12 +235,11 @@ // non-Intel CPUs such as AMD, since the event code provided for LLC is // Intel specific. if (cpuid.vendor=="GenuineIntel"){ - cmds.push_back(WeightAndValue(75.0, kPerfCyclesCmd)); - cmds.push_back(WeightAndValue(5.0, kPerfLLCMissesCmd)); + cmds.emplace_back(WeightAndValue(25.0, cycles_cmd)); + cmds.emplace_back(WeightAndValue(5.0, kPerfLLCMissesCmd)); } else { - cmds.push_back(WeightAndValue(80.0, kPerfCyclesCmd)); + cmds.emplace_back(WeightAndValue(30.0, cycles_cmd)); } - cmds.push_back(WeightAndValue(20.0, kPerfFPCallgraphCmd)); return cmds; } @@ -246,13 +271,13 @@ if (cpuid.arch == "x86" || // 32-bit x86, or... cpuid.arch == "armv7l" || // ARM32 cpuid.arch == "aarch64") { // ARM64 - cmds.push_back(WeightAndValue(80.0, kPerfCyclesCmd)); - cmds.push_back(WeightAndValue(20.0, kPerfFPCallgraphCmd)); + cmds.emplace_back(WeightAndValue(80.0, kPerfCyclesCmd)); + cmds.emplace_back(WeightAndValue(20.0, kPerfFPCallgraphCmd)); return cmds; } // Unknown CPUs - cmds.push_back(WeightAndValue(1.0, kPerfCyclesCmd)); + cmds.emplace_back(WeightAndValue(1.0, kPerfCyclesCmd)); return cmds; }
diff --git a/chrome/browser/metrics/perf/perf_events_collector_unittest.cc b/chrome/browser/metrics/perf/perf_events_collector_unittest.cc index 77a8088..ac0e42eb 100644 --- a/chrome/browser/metrics/perf/perf_events_collector_unittest.cc +++ b/chrome/browser/metrics/perf/perf_events_collector_unittest.cc
@@ -16,6 +16,7 @@ #include "base/metrics/field_trial.h" #include "base/task/post_task.h" #include "base/test/bind_test_util.h" +#include "base/test/metrics/histogram_tester.h" #include "chrome/browser/metrics/perf/cpu_identity.h" #include "chrome/browser/metrics/perf/windowed_incognito_observer.h" #include "components/variations/variations_associated_data.h" @@ -32,6 +33,11 @@ const char kPerfFPCallgraphCmd[] = "perf record -a -e cycles -g -c 4000037"; const char kPerfLBRCallgraphCmd[] = "perf record -a -e cycles -c 4000037 --call-graph lbr"; +const char kPerfCyclesPPPCmd[] = "perf record -a -e cycles:ppp -c 1000003"; +const char kPerfFPCallgraphPPPCmd[] = + "perf record -a -e cycles:ppp -g -c 4000037"; +const char kPerfLBRCallgraphPPPCmd[] = + "perf record -a -e cycles:ppp -c 4000037 --call-graph lbr"; const char kPerfLBRCmd[] = "perf record -a -e r20c4 -b -c 200011"; const char kPerfLBRCmdAtom[] = "perf record -a -e rc4 -b -c 300001"; const char kPerfITLBMissCyclesCmdIvyBridge[] = @@ -150,6 +156,7 @@ public: TestPerfCollector() = default; + using MetricCollector::CollectionAttemptStatus; using MetricCollector::CollectPerfDataAfterSessionRestore; using MetricCollector::OnJankStarted; using MetricCollector::OnJankStopped; @@ -264,11 +271,15 @@ EXPECT_TRUE(perf_collector_->IsRunning()); // Pretend the cache is full. perf_collector_->AddCachedDataDelta(4 * 1024 * 1024); + base::HistogramTester histogram_tester; // Advance the clock by a periodic collection interval. We shouldn't find a // profile because the cache is full. task_environment_.FastForwardBy(kPeriodicCollectionInterval); EXPECT_TRUE(cached_profile_data_.empty()); + histogram_tester.ExpectUniqueSample( + "ChromeOS.CWP.CollectPerf", + TestPerfCollector::CollectionAttemptStatus::NOT_READY_TO_COLLECT, 1); } // Simulate opening and closing of incognito window in between calls to @@ -304,6 +315,7 @@ EXPECT_GT(profile1.cpu_max_frequency_mhz_size(), 0); cached_profile_data_.clear(); + base::HistogramTester histogram_tester; sampled_profile = std::make_unique<SampledProfile>(); sampled_profile->set_trigger_event(SampledProfile::RESUME_FROM_SUSPEND); // An incognito window opens. @@ -314,6 +326,9 @@ task_environment_.RunUntilIdle(); EXPECT_TRUE(cached_profile_data_.empty()); + histogram_tester.ExpectUniqueSample( + "ChromeOS.CWP.CollectPerf", + TestPerfCollector::CollectionAttemptStatus::INCOGNITO_LAUNCHED, 1); sampled_profile = std::make_unique<SampledProfile>(); sampled_profile->set_trigger_event(SampledProfile::RESUME_FROM_SUSPEND); @@ -483,10 +498,10 @@ std::vector<RandomSelector::WeightAndValue> cmds = internal::GetDefaultCommandsForCpu(cpuid); ASSERT_GE(cmds.size(), 3UL); - EXPECT_EQ(cmds[0].value, kPerfCyclesCmd); + EXPECT_EQ(cmds[0].value, kPerfCyclesPPPCmd); // We have both FP and LBR based callstacks. - EXPECT_EQ(cmds[1].value, kPerfFPCallgraphCmd); - EXPECT_EQ(cmds[2].value, kPerfLBRCallgraphCmd); + EXPECT_EQ(cmds[1].value, kPerfFPCallgraphPPPCmd); + EXPECT_EQ(cmds[2].value, kPerfLBRCallgraphPPPCmd); auto found = std::find_if(cmds.begin(), cmds.end(), [](const RandomSelector::WeightAndValue& cmd) -> bool { @@ -516,13 +531,13 @@ std::vector<RandomSelector::WeightAndValue> cmds = internal::GetDefaultCommandsForCpu(cpuid); ASSERT_GE(cmds.size(), 2UL); - EXPECT_EQ(cmds[0].value, kPerfCyclesCmd); - EXPECT_EQ(cmds[1].value, kPerfFPCallgraphCmd); + EXPECT_EQ(cmds[0].value, kPerfCyclesPPPCmd); + EXPECT_EQ(cmds[1].value, kPerfFPCallgraphPPPCmd); // No LBR callstacks because the microarchitecture doesn't support it. auto found = std::find_if(cmds.begin(), cmds.end(), [](const RandomSelector::WeightAndValue& cmd) -> bool { - return cmd.value == kPerfLBRCallgraphCmd; + return cmd.value == kPerfLBRCallgraphPPPCmd; }); EXPECT_EQ(cmds.end(), found); found = std::find_if(cmds.begin(), cmds.end(), @@ -553,13 +568,13 @@ std::vector<RandomSelector::WeightAndValue> cmds = internal::GetDefaultCommandsForCpu(cpuid); ASSERT_GE(cmds.size(), 2UL); - EXPECT_EQ(cmds[0].value, kPerfCyclesCmd); - EXPECT_EQ(cmds[1].value, kPerfFPCallgraphCmd); + EXPECT_EQ(cmds[0].value, kPerfCyclesPPPCmd); + EXPECT_EQ(cmds[1].value, kPerfFPCallgraphPPPCmd); // No LBR callstacks because the microarchitecture doesn't support it. auto found = std::find_if(cmds.begin(), cmds.end(), [](const RandomSelector::WeightAndValue& cmd) -> bool { - return cmd.value == kPerfLBRCallgraphCmd; + return cmd.value == kPerfLBRCallgraphPPPCmd; }); EXPECT_EQ(cmds.end(), found); found = std::find_if(cmds.begin(), cmds.end(),
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc index feeddbaf..e80dd7c 100644 --- a/chrome/browser/metrics/ukm_browsertest.cc +++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -1094,7 +1094,8 @@ // Make sure that pending data is deleted when user deletes history. // Keep in sync with testHistoryDelete in ios/chrome/browser/metrics/ // ukm_egtest.mm. -IN_PROC_BROWSER_TEST_F(UkmBrowserTest, HistoryDeleteCheck) { +// Quite flaky: https://crbug.com/1131541 +IN_PROC_BROWSER_TEST_F(UkmBrowserTest, DISABLED_HistoryDeleteCheck) { ukm::UkmTestHelper ukm_test_helper(GetUkmService()); MetricsConsentOverride metrics_consent(true);
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc index fe69ac2..4c776f1 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
@@ -3179,10 +3179,18 @@ << share_target.device_name; if (share_target.is_incoming) { + if (last_incoming_metadata_ && + last_incoming_metadata_->first.id == share_target.id) { + last_incoming_metadata_.reset(); + } incoming_share_target_info_map_.erase(share_target.id); // Clear legacy incoming payloads to release resource nearby_connections_manager_->ClearIncomingPayloads(); } else { + if (last_outgoing_metadata_ && + last_outgoing_metadata_->first.id == share_target.id) { + last_outgoing_metadata_.reset(); + } // Find the endpoint id that matches the given share target. base::Optional<std::string> endpoint_id; auto it = outgoing_share_target_info_map_.find(share_target.id);
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index 2ae70ec45..082cff3 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -42,6 +42,7 @@ #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" +#include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/network_service_instance.h" @@ -737,6 +738,13 @@ network_context_params->enable_certificate_reporting = true; network_context_params->enable_expect_ct_reporting = true; + // Initialize the network context to do SCT auditing only if the current + // profile is opted in to Safe Browsing Extended Reporting. + if (!profile_->IsOffTheRecord() && + safe_browsing::IsExtendedReportingEnabled(*profile_->GetPrefs())) { + network_context_params->enable_sct_auditing = true; + } + network_context_params->ct_policy = GetCTPolicy(); #if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED)
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc index 7df1c47..c53056f7 100644 --- a/chrome/browser/net/system_network_context_manager.cc +++ b/chrome/browser/net/system_network_context_manager.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/component_updater/tls_deprecation_config_component_installer.h" #include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include "chrome/browser/ssl/sct_reporting_service.h" #include "chrome/browser/ssl/ssl_config_service_manager.h" #include "chrome/common/channel_info.h" #include "chrome/common/chrome_features.h" @@ -520,6 +521,9 @@ // Asynchronously reapply the most recently received TLS deprecation config. component_updater::TLSDeprecationConfigComponentInstallerPolicy:: ReconfigureAfterNetworkRestart(); + + // Configure SCT Auditing in the NetworkService. + SCTReportingService::ReconfigureAfterNetworkRestart(); } void SystemNetworkContextManager::DisableQuic() {
diff --git a/chrome/browser/net/variations_http_headers_browsertest.cc b/chrome/browser/net/variations_http_headers_browsertest.cc index 073c312..da8d32e6 100644 --- a/chrome/browser/net/variations_http_headers_browsertest.cc +++ b/chrome/browser/net/variations_http_headers_browsertest.cc
@@ -13,6 +13,7 @@ #include "base/path_service.h" #include "base/run_loop.h" #include "base/strings/strcat.h" +#include "base/test/scoped_feature_list.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -36,6 +37,8 @@ #include "components/signin/public/identity_manager/identity_test_utils.h" #include "components/variations/net/variations_http_headers.h" #include "components/variations/proto/study.pb.h" +#include "components/variations/variations.mojom.h" +#include "components/variations/variations_features.h" #include "components/variations/variations_ids_provider.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" @@ -305,6 +308,28 @@ DISALLOW_COPY_AND_ASSIGN(VariationsHttpHeadersBrowserTest); }; +// Used for testing the kRestrictGoogleWebVisibility feature. +class VariationsHttpHeadersBrowserTestWithRestrictedVisibility + : public VariationsHttpHeadersBrowserTest, + public testing::WithParamInterface<bool> { + public: + VariationsHttpHeadersBrowserTestWithRestrictedVisibility() { + if (GetParam()) { + scoped_feature_list_.InitAndEnableFeature( + variations::internal::kRestrictGoogleWebVisibility); + } else { + scoped_feature_list_.InitAndDisableFeature( + variations::internal::kRestrictGoogleWebVisibility); + } + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; + + DISALLOW_COPY_AND_ASSIGN( + VariationsHttpHeadersBrowserTestWithRestrictedVisibility); +}; + std::unique_ptr<net::test_server::HttpResponse> VariationsHttpHeadersBrowserTest::RequestHandler( const net::test_server::HttpRequest& request) { @@ -382,18 +407,67 @@ "t1", default_name, variations::GOOGLE_WEB_PROPERTIES_SIGNED_IN, 123)); auto* provider = variations::VariationsIdsProvider::GetInstance(); + variations::mojom::VariationsHeadersPtr signed_in_headers = + provider->GetClientDataHeaders(/*is_signed_in=*/true); + variations::mojom::VariationsHeadersPtr signed_out_headers = + provider->GetClientDataHeaders(/*is_signed_in=*/false); - EXPECT_NE( - provider->GetClientDataHeader( - /*is_signed_in=*/true, variations::Study_GoogleWebVisibility_ANY), - provider->GetClientDataHeader( - /*is_signed_in=*/false, variations::Study_GoogleWebVisibility_ANY)); - EXPECT_NE(provider->GetClientDataHeader( - /*is_signed_in=*/true, - variations::Study_GoogleWebVisibility_FIRST_PARTY), - provider->GetClientDataHeader( - /*is_signed_in=*/false, - variations::Study_GoogleWebVisibility_FIRST_PARTY)); + EXPECT_NE(signed_in_headers->headers_map.at( + variations::mojom::GoogleWebVisibility::ANY), + signed_out_headers->headers_map.at( + variations::mojom::GoogleWebVisibility::ANY)); + EXPECT_NE(signed_in_headers->headers_map.at( + variations::mojom::GoogleWebVisibility::FIRST_PARTY), + signed_out_headers->headers_map.at( + variations::mojom::GoogleWebVisibility::FIRST_PARTY)); +} + +// Creates FieldTrials associatedd with the FIRST_PARTY IDCollectionKeys and +// their corresponding ANY_CONTEXT keys. +void CreateFieldTrialsWithDifferentVisibilities() { + scoped_refptr<base::FieldTrial> trial_1(CreateTrialAndAssociateId( + "t1", "g1", variations::GOOGLE_WEB_PROPERTIES_ANY_CONTEXT, 11)); + scoped_refptr<base::FieldTrial> trial_2(CreateTrialAndAssociateId( + "t2", "g2", variations::GOOGLE_WEB_PROPERTIES_FIRST_PARTY, 22)); + scoped_refptr<base::FieldTrial> trial_3(CreateTrialAndAssociateId( + "t3", "g3", variations::GOOGLE_WEB_PROPERTIES_TRIGGER_ANY_CONTEXT, 33)); + scoped_refptr<base::FieldTrial> trial_4(CreateTrialAndAssociateId( + "t4", "g4", variations::GOOGLE_WEB_PROPERTIES_TRIGGER_FIRST_PARTY, 44)); + + auto* provider = variations::VariationsIdsProvider::GetInstance(); + variations::mojom::VariationsHeadersPtr signed_in_headers = + provider->GetClientDataHeaders(/*is_signed_in=*/true); + variations::mojom::VariationsHeadersPtr signed_out_headers = + provider->GetClientDataHeaders(/*is_signed_in=*/false); + + if (base::FeatureList::IsEnabled( + variations::internal::kRestrictGoogleWebVisibility)) { + EXPECT_NE(signed_in_headers->headers_map.at( + variations::mojom::GoogleWebVisibility::ANY), + signed_in_headers->headers_map.at( + variations::mojom::GoogleWebVisibility::FIRST_PARTY)); + EXPECT_NE(signed_out_headers->headers_map.at( + variations::mojom::GoogleWebVisibility::ANY), + signed_out_headers->headers_map.at( + variations::mojom::GoogleWebVisibility::FIRST_PARTY)); + } else { + // When kRestrictGoogleWebVisibility is disabled, the transmission of + // VariationIDs is not restricted. This is the status quo implementation. + // + // This means that IDs associated with the FIRST_PARTY IDCollectionKeys are + // treated as if they were associated with their corresponding ANY_CONTEXT + // IDCollectionKeys. For example, when the feature is disabled, IDs + // associated with GOOGLE_WEB_PROPERTIES_FIRST_PARTY are transmitted when + // IDs associated with GOOGLE_WEB_PROPERTIES_ANY_CONTEXT are. + EXPECT_EQ(signed_in_headers->headers_map.at( + variations::mojom::GoogleWebVisibility::ANY), + signed_in_headers->headers_map.at( + variations::mojom::GoogleWebVisibility::FIRST_PARTY)); + EXPECT_EQ(signed_out_headers->headers_map.at( + variations::mojom::GoogleWebVisibility::ANY), + signed_out_headers->headers_map.at( + variations::mojom::GoogleWebVisibility::FIRST_PARTY)); + } } } // namespace @@ -448,10 +522,13 @@ base::Optional<std::string> header = GetReceivedHeader(GetGoogleUrl(), "X-Client-Data"); ASSERT_TRUE(header); - EXPECT_EQ( - *header, - variations::VariationsIdsProvider::GetInstance()->GetClientDataHeader( - /*is_signed_in=*/true, variations::Study_GoogleWebVisibility_ANY)); + + variations::mojom::VariationsHeadersPtr headers = + variations::VariationsIdsProvider::GetInstance()->GetClientDataHeaders( + /*is_signed_in=*/true); + + EXPECT_EQ(*header, headers->headers_map.at( + variations::mojom::GoogleWebVisibility::ANY)); } IN_PROC_BROWSER_TEST_F(VariationsHttpHeadersBrowserTest, UserNotSignedIn) { @@ -465,10 +542,42 @@ base::Optional<std::string> header = GetReceivedHeader(GetGoogleUrl(), "X-Client-Data"); ASSERT_TRUE(header); - EXPECT_EQ( - *header, - variations::VariationsIdsProvider::GetInstance()->GetClientDataHeader( - /*is_signed_in=*/false, variations::Study_GoogleWebVisibility_ANY)); + + variations::mojom::VariationsHeadersPtr headers = + variations::VariationsIdsProvider::GetInstance()->GetClientDataHeaders( + /*is_signed_in=*/false); + + EXPECT_EQ(*header, headers->headers_map.at( + variations::mojom::GoogleWebVisibility::ANY)); +} + +INSTANTIATE_TEST_SUITE_P( + VariationsHttpHeadersBrowserTest, + VariationsHttpHeadersBrowserTestWithRestrictedVisibility, + testing::Bool()); + +IN_PROC_BROWSER_TEST_P(VariationsHttpHeadersBrowserTestWithRestrictedVisibility, + TestRestrictGoogleWebVisibilityInThirdPartyContexts) { + // Ensure GetClientDataHeader() returns different values when + // kRestrictGoogleWebVisibility is enabled and the same values otherwise. + CreateFieldTrialsWithDifferentVisibilities(); + + ui_test_utils::NavigateToURL(browser(), GetGoogleUrl()); + base::Optional<std::string> header = + GetReceivedHeader(GetGoogleUrl(), "X-Client-Data"); + ASSERT_TRUE(header); + + variations::mojom::GoogleWebVisibility web_visibility = + base::FeatureList::IsEnabled( + variations::internal::kRestrictGoogleWebVisibility) + ? variations::mojom::GoogleWebVisibility::FIRST_PARTY + : variations::mojom::GoogleWebVisibility::ANY; + + variations::mojom::VariationsHeadersPtr headers = + variations::VariationsIdsProvider::GetInstance()->GetClientDataHeaders( + /*is_signed_in=*/false); + + EXPECT_EQ(*header, headers->headers_map.at(web_visibility)); } IN_PROC_BROWSER_TEST_F(
diff --git a/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewPlayer.java b/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewPlayer.java index 295c392..1602312 100644 --- a/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewPlayer.java +++ b/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewPlayer.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.paint_preview; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.content.res.Resources; import android.graphics.Point; import android.os.Handler; @@ -42,6 +44,7 @@ TabbedPaintPreviewPlayer.class; private static final int SNACKBAR_DURATION_MS = 8 * 1000; + private static final int CROSS_FADE_DURATION_MS = 500; private static final int DEFAULT_INITIAL_REMOVE_DELAY_MS = 0; private static final String INITIAL_REMOVE_DELAY_PARAM = "initial_remove_delay_ms"; @@ -55,6 +58,7 @@ private TabbedPaintPreviewObserver mObserver; private long mLastShownSnackBarTime; private boolean mDidStartRestore; + private boolean mFadingOut; private int mSnackbarShownCount; private TabbedPaintPreviewMetricsHelper mMetricsHelper; @@ -205,16 +209,30 @@ PaintPreviewCompositorUtils.stopWarmCompositor(); mOnDismissed = null; mInitializing = false; - if (mTab == null || mPlayerManager == null) return; + if (mTab == null || mPlayerManager == null || mFadingOut) return; + mFadingOut = true; Point scrollPosition = mPlayerManager.getScrollPosition(); if (mTab.getWebContents() != null && scrollPosition != null) { mTab.getWebContents().getEventForwarder().scrollTo(scrollPosition.x, scrollPosition.y); } - - mTab.getTabViewManager().removeTabViewProvider(this); - mPlayerManager.destroy(); - mPlayerManager = null; + boolean needsAnimation = exitCause == ExitCause.TAB_FINISHED_LOADING + || exitCause == ExitCause.SNACK_BAR_ACTION + || exitCause == ExitCause.PULL_TO_REFRESH; + getView() + .animate() + .alpha(0f) + .setDuration(needsAnimation ? CROSS_FADE_DURATION_MS : 0) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mTab.getTabViewManager().removeTabViewProvider( + TabbedPaintPreviewPlayer.this); + mPlayerManager.destroy(); + mPlayerManager = null; + mFadingOut = false; + } + }); mMetricsHelper.recordExitMetrics(exitCause, mSnackbarShownCount); }
diff --git a/chrome/browser/payments/android/service_worker_payment_app_bridge.cc b/chrome/browser/payments/android/service_worker_payment_app_bridge.cc index 2d4ac9ba..8cdceb8 100644 --- a/chrome/browser/payments/android/service_worker_payment_app_bridge.cc +++ b/chrome/browser/payments/android/service_worker_payment_app_bridge.cc
@@ -26,6 +26,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/installed_payment_apps_finder.h" #include "content/public/browser/payment_app_provider.h" +#include "content/public/browser/payment_app_provider_util.h" #include "content/public/browser/web_contents.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/public/mojom/payments/payment_app.mojom.h" @@ -125,9 +126,9 @@ content::WebContents* web_contents = content::WebContents::FromJavaWebContents(jweb_contents); DCHECK(web_contents); // Verified in Java before invoking this function. - content::PaymentAppProvider::GetInstance()->OnClosingOpenedWindow( - web_contents, - static_cast<payments::mojom::PaymentEventResponseType>(reason)); + content::PaymentAppProvider::GetOrCreateForWebContents(web_contents) + ->OnClosingOpenedWindow( + static_cast<payments::mojom::PaymentEventResponseType>(reason)); } static jlong @@ -138,7 +139,6 @@ // payment app associated with this scope. Since this getter is called inside // PaymentApp::getUkmSourceId() function which in turn gets called for the // invoked app inside PaymentRequestImpl::openPaymentHandlerWindowInternal. - return content::PaymentAppProvider::GetInstance() - ->GetSourceIdForPaymentAppFromScope( - url::GURLAndroid::ToNativeGURL(env, jscope).get()->GetOrigin()); + return content::PaymentAppProviderUtil::GetSourceIdForPaymentAppFromScope( + url::GURLAndroid::ToNativeGURL(env, jscope).get()->GetOrigin()); }
diff --git a/chrome/browser/permissions/permission_manager_factory.cc b/chrome/browser/permissions/permission_manager_factory.cc index 4617a0d..2047d500 100644 --- a/chrome/browser/permissions/permission_manager_factory.cc +++ b/chrome/browser/permissions/permission_manager_factory.cc
@@ -7,7 +7,6 @@ #include "build/build_config.h" #include "chrome/browser/accessibility/accessibility_permission_context.h" #include "chrome/browser/background_fetch/background_fetch_permission_context.h" -#include "chrome/browser/background_sync/background_sync_permission_context.h" #include "chrome/browser/background_sync/periodic_background_sync_permission_context.h" #include "chrome/browser/clipboard/clipboard_read_write_permission_context.h" #include "chrome/browser/clipboard/clipboard_sanitized_write_permission_context.h" @@ -30,6 +29,7 @@ #include "chrome/common/buildflags.h" #include "chrome/common/url_constants.h" #include "chrome/common/webui_url_constants.h" +#include "components/background_sync/background_sync_permission_context.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/permissions/contexts/font_access_permission_context.h" #include "components/permissions/contexts/webxr_permission_context.h"
diff --git a/chrome/browser/predictors/prefetch_manager.cc b/chrome/browser/predictors/prefetch_manager.cc index 5e2d639..3996b04 100644 --- a/chrome/browser/predictors/prefetch_manager.cc +++ b/chrome/browser/predictors/prefetch_manager.cc
@@ -30,8 +30,6 @@ namespace { -// TODO(crbug.com/1095842): Update the annotation once URL allowlist/blocklist -// are observed to limit the scope of the requests. const net::NetworkTrafficAnnotationTag kPrefetchTrafficAnnotation = net::DefineNetworkTrafficAnnotation("predictive_prefetch", R"( @@ -59,11 +57,21 @@ "B) Disable Lite Mode under Settings > Advanced > Lite mode, or " "C) Disable 'Make searches and browsing better' under Settings > " " Sync and Google services > Make searches and browsing better" - policy_exception_justification: "To be implemented" + chrome_policy { + URLBlacklist { + URLBlacklist: { entries: '*' } + } + } + chrome_policy { + URLWhitelist { + URLWhitelist { } + } + } } comments: "This feature can be safely disabled, but enabling it may result in " - "faster page loads." + "faster page loads. Using either URLBlacklist or URLWhitelist policies " + "(or a combination of both) limits the scope of these requests." )"); } // namespace
diff --git a/chrome/browser/prerender/isolated/isolated_prerender_network_context_client.cc b/chrome/browser/prerender/isolated/isolated_prerender_network_context_client.cc index 0cc60256..b2fc0b9 100644 --- a/chrome/browser/prerender/isolated/isolated_prerender_network_context_client.cc +++ b/chrome/browser/prerender/isolated/isolated_prerender_network_context_client.cc
@@ -97,6 +97,3 @@ #if defined(OS_CHROMEOS) void IsolatedPrerenderNetworkContextClient::OnTrustAnchorUsed() {} #endif - -void IsolatedPrerenderNetworkContextClient::OnSCTReportReady( - const std::string& cache_key) {}
diff --git a/chrome/browser/prerender/isolated/isolated_prerender_network_context_client.h b/chrome/browser/prerender/isolated/isolated_prerender_network_context_client.h index a2d0ccc..09029c6 100644 --- a/chrome/browser/prerender/isolated/isolated_prerender_network_context_client.h +++ b/chrome/browser/prerender/isolated/isolated_prerender_network_context_client.h
@@ -72,7 +72,6 @@ #if defined(OS_CHROMEOS) void OnTrustAnchorUsed() override; #endif - void OnSCTReportReady(const std::string& cache_key) override; }; #endif // CHROME_BROWSER_PRERENDER_ISOLATED_ISOLATED_PRERENDER_NETWORK_CONTEXT_CLIENT_H_
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index b5ab7685..c1a1bd9 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc
@@ -30,6 +30,7 @@ #include "components/sync/driver/sync_driver_switches.h" #include "components/sync/driver/sync_service.h" #include "components/variations/proto/study.pb.h" +#include "components/variations/variations.mojom.h" #include "components/variations/variations_client.h" #include "components/variations/variations_ids_provider.h" #include "content/public/browser/notification_service.h" @@ -93,13 +94,10 @@ return browser_context_->IsOffTheRecord(); } - // TODO(crbug/1094303): Update the signature to accept a - // variations::Study_GoogleWebVisibility and pass the given value to - // GetClientDataHeader(). - std::string GetVariationsHeader() const override { + variations::mojom::VariationsHeadersPtr GetVariationsHeaders() + const override { return variations::VariationsIdsProvider::GetInstance() - ->GetClientDataHeader(IsSignedIn(), - variations::Study_GoogleWebVisibility_ANY); + ->GetClientDataHeaders(IsSignedIn()); } private:
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing.js index 79873b2..d83d976 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing.js
@@ -943,13 +943,13 @@ // Only consider selection moves. const intent = intents.find( - i => i.command == chrome.automation.EventCommandType.MOVE_SELECTION); + i => i.command == chrome.automation.IntentCommandType.MOVE_SELECTION); if (!intent) { return false; } if (intent.textBoundary == - chrome.automation.EventTextBoundaryType.CHARACTER) { + chrome.automation.IntentTextBoundaryType.CHARACTER) { this.updateIntraLineState_(cur); // Read character to the right of the cursor. It is assumed to be a new @@ -962,9 +962,9 @@ } if (intent.textBoundary == - chrome.automation.EventTextBoundaryType.LINE_START || + chrome.automation.IntentTextBoundaryType.LINE_START || intent.textBoundary == - chrome.automation.EventTextBoundaryType.LINE_END) { + chrome.automation.IntentTextBoundaryType.LINE_END) { this.updateIntraLineState_(cur); this.speakCurrentRichLine_(prev); return true;
diff --git a/chrome/browser/resources/downloads/item.js b/chrome/browser/resources/downloads/item.js index b7f873d..1d5b3e4 100644 --- a/chrome/browser/resources/downloads/item.js +++ b/chrome/browser/resources/downloads/item.js
@@ -30,649 +30,649 @@ import {IconLoader} from './icon_loader.js'; Polymer({ - is: 'downloads-item', + is: 'downloads-item', - _template: html`{__html_template__}`, + _template: html`{__html_template__}`, - behaviors: [ - FocusRowBehavior, - ], + behaviors: [ + FocusRowBehavior, + ], - /** Used by FocusRowBehavior. */ - overrideCustomEquivalent: true, + /** Used by FocusRowBehavior. */ + overrideCustomEquivalent: true, - properties: { - /** @type {!downloads.Data} */ - data: Object, + properties: { + /** @type {!downloads.Data} */ + data: Object, - /** @private */ - completelyOnDisk_: { - computed: 'computeCompletelyOnDisk_(' + - 'data.state, data.fileExternallyRemoved)', - type: Boolean, - value: true, - }, - - /** @private */ - controlledBy_: { - computed: 'computeControlledBy_(data.byExtId, data.byExtName)', - type: String, - value: '', - }, - - /** @private */ - controlRemoveFromListAriaLabel_: { - type: String, - computed: 'computeControlRemoveFromListAriaLabel_(data.fileName)', - }, - - /** @private */ - isActive_: { - computed: 'computeIsActive_(' + - 'data.state, data.fileExternallyRemoved)', - type: Boolean, - value: true, - }, - - /** @private */ - isDangerous_: { - computed: 'computeIsDangerous_(data.state)', - type: Boolean, - value: false, - }, - - /** @private */ - isMalware_: { - computed: 'computeIsMalware_(isDangerous_, data.dangerType)', - type: Boolean, - value: false, - }, - - /** @private */ - isInProgress_: { - computed: 'computeIsInProgress_(data.state)', - type: Boolean, - value: false, - }, - - /** @private */ - pauseOrResumeText_: { - computed: 'computePauseOrResumeText_(isInProgress_, data.resume)', - type: String, - observer: 'updatePauseOrResumeClass_', - }, - - /** @private */ - showCancel_: { - computed: 'computeShowCancel_(data.state)', - type: Boolean, - value: false, - }, - - /** @private */ - showProgress_: { - computed: 'computeShowProgress_(showCancel_, data.percent)', - type: Boolean, - value: false, - }, - - /** @private */ - showOpenNow_: { - computed: 'computeShowOpenNow_(data.state)', - type: Boolean, - value: false, - }, - - useFileIcon_: Boolean, - }, - - hostAttributes: { - role: 'row', - }, - - observers: [ - // TODO(dbeam): this gets called way more when I observe data.byExtId - // and data.byExtName directly. Why? - 'observeControlledBy_(controlledBy_)', - 'observeIsDangerous_(isDangerous_, data)', - 'restoreFocusAfterCancelIfNeeded_(data)', - ], - - /** @private {downloads.mojom.PageHandlerInterface} */ - mojoHandler_: null, - - /** @private {boolean} */ - restoreFocusAfterCancel_: false, - - /** @override */ - attached() { - afterNextRender(this, function() { - IronA11yAnnouncer.requestAvailability(); - }); - }, - - /** @override */ - ready() { - this.mojoHandler_ = BrowserProxy.getInstance().handler; - this.content = this.$.content; - }, - - focusOnRemoveButton() { - focusWithoutInk(this.$.remove); - }, - - /** Overrides FocusRowBehavior. */ - getCustomEquivalent(sampleElement) { - if (sampleElement.getAttribute('focus-type') === 'cancel') { - return this.$$('[focus-type="retry"]'); - } - if (sampleElement.getAttribute('focus-type') === 'retry') { - return this.$$('[focus-type="pauseOrResume"]'); - } - return null; - }, - - /** @return {!HTMLElement} */ - getFileIcon() { - return /** @type {!HTMLElement} */ (this.$['file-icon']); - }, - - /** - * @param {string} url - * @return {string} A reasonably long URL. - * @private - */ - chopUrl_(url) { - return url.slice(0, 300); + /** @private */ + completelyOnDisk_: { + computed: 'computeCompletelyOnDisk_(' + + 'data.state, data.fileExternallyRemoved)', + type: Boolean, + value: true, }, /** @private */ - computeClass_() { - const classes = []; - - if (this.isActive_) { - classes.push('is-active'); - } - - if (this.isDangerous_) { - classes.push('dangerous'); - } - - if (this.showProgress_) { - classes.push('show-progress'); - } - - return classes.join(' '); - }, - - /** - * @return {boolean} - * @private - */ - computeCompletelyOnDisk_() { - return this.data.state === States.COMPLETE && - !this.data.fileExternallyRemoved; - }, - - /** - * @return {string} - * @private - */ - computeControlledBy_() { - if (!this.data.byExtId || !this.data.byExtName) { - return ''; - } - - const url = `chrome://extensions/?id=${this.data.byExtId}`; - const name = this.data.byExtName; - return loadTimeData.getStringF('controlledByUrl', url, HTMLEscape(name)); - }, - - /** - * @return {string} - * @private - */ - computeControlRemoveFromListAriaLabel_() { - return loadTimeData.getStringF( - 'controlRemoveFromListAriaLabel', this.data.fileName); - }, - - /** - * @return {string} - * @private - */ - computeDate_() { - assert(typeof this.data.hideDate === 'boolean'); - if (this.data.hideDate) { - return ''; - } - return assert(this.data.sinceString || this.data.dateString); - }, - - /** @private @return {boolean} */ - computeDescriptionVisible_() { - return this.computeDescription_() !== ''; - }, - - /** - * @return {string} - * @private - */ - computeDescription_() { - const data = this.data; - - switch (data.state) { - case States.COMPLETE: - switch (data.dangerType) { - case DangerType.DEEP_SCANNED_SAFE: - return loadTimeData.getString('deepScannedSafeDesc'); - case DangerType.DEEP_SCANNED_OPENED_DANGEROUS: - return loadTimeData.getString('deepScannedOpenedDangerousDesc'); - } - break; - - case States.MIXED_CONTENT: - return loadTimeData.getString('mixedContentDownloadDesc'); - - case States.DANGEROUS: - const fileName = data.fileName; - switch (data.dangerType) { - case DangerType.DANGEROUS_FILE: - return loadTimeData.getString('dangerFileDesc'); - - case DangerType.DANGEROUS_URL: - case DangerType.DANGEROUS_CONTENT: - case DangerType.DANGEROUS_HOST: - return loadTimeData.getString('dangerDownloadDesc'); - - case DangerType.UNCOMMON_CONTENT: - return loadTimeData.getString('dangerUncommonDesc'); - - case DangerType.POTENTIALLY_UNWANTED: - return loadTimeData.getString('dangerSettingsDesc'); - - case DangerType.SENSITIVE_CONTENT_WARNING: - return loadTimeData.getString('sensitiveContentWarningDesc'); - } - break; - - case States.ASYNC_SCANNING: - return loadTimeData.getString('asyncScanningDownloadDesc'); - - case States.IN_PROGRESS: - case States.PAUSED: // Fallthrough. - return data.progressStatusText; - - case States.INTERRUPTED: - switch (data.dangerType) { - case DangerType.SENSITIVE_CONTENT_BLOCK: - return loadTimeData.getString('sensitiveContentBlockedDesc'); - case DangerType.BLOCKED_TOO_LARGE: - return loadTimeData.getString('blockedTooLargeDesc'); - case DangerType.BLOCKED_PASSWORD_PROTECTED: - return loadTimeData.getString('blockedPasswordProtectedDesc'); - } - } - - return ''; - }, - - /** - * @return {string} - * @private - */ - computeIcon_() { - if (this.data) { - const dangerType = this.data.dangerType; - if ((loadTimeData.getBoolean('requestsApVerdicts') && - dangerType === DangerType.UNCOMMON_CONTENT) || - dangerType === DangerType.SENSITIVE_CONTENT_WARNING) { - return 'cr:warning'; - } - - const ERROR_TYPES = [ - DangerType.SENSITIVE_CONTENT_BLOCK, - DangerType.BLOCKED_TOO_LARGE, - DangerType.BLOCKED_PASSWORD_PROTECTED, - ]; - if (ERROR_TYPES.includes(dangerType)) { - return 'cr:error'; - } - - if (this.data.state === States.ASYNC_SCANNING) { - return 'cr:info'; - } - } - if (this.isDangerous_) { - return 'cr:error'; - } - if (!this.useFileIcon_) { - return 'cr:insert-drive-file'; - } - return ''; - }, - - /** - * @return {string} - * @private - */ - computeIconColor_() { - if (this.data) { - const dangerType = this.data.dangerType; - if ((loadTimeData.getBoolean('requestsApVerdicts') && - dangerType === DangerType.UNCOMMON_CONTENT) || - dangerType === DangerType.SENSITIVE_CONTENT_WARNING) { - return 'yellow'; - } - - const WARNING_TYPES = [ - DangerType.SENSITIVE_CONTENT_BLOCK, - DangerType.BLOCKED_TOO_LARGE, - DangerType.BLOCKED_PASSWORD_PROTECTED, - ]; - if (WARNING_TYPES.includes(dangerType)) { - return 'red'; - } - - if (this.data.state === States.ASYNC_SCANNING) { - return 'grey'; - } - } - if (this.isDangerous_) { - return 'red'; - } - if (!this.useFileIcon_) { - return 'paper-grey'; - } - return ''; - }, - - /** - * @return {boolean} - * @private - */ - computeIsActive_() { - return this.data.state !== States.CANCELLED && - this.data.state !== States.INTERRUPTED && - !this.data.fileExternallyRemoved; - }, - - /** - * @return {boolean} - * @private - */ - computeIsDangerous_() { - return this.data.state === States.DANGEROUS || - this.data.state === States.MIXED_CONTENT; - }, - - /** - * @return {boolean} - * @private - */ - computeIsInProgress_() { - return this.data.state === States.IN_PROGRESS; - }, - - /** - * @return {boolean} - * @private - */ - computeIsMalware_() { - return this.isDangerous_ && - (this.data.dangerType === DangerType.DANGEROUS_CONTENT || - this.data.dangerType === DangerType.DANGEROUS_HOST || - this.data.dangerType === DangerType.DANGEROUS_URL || - this.data.dangerType === DangerType.POTENTIALLY_UNWANTED); + controlledBy_: { + computed: 'computeControlledBy_(data.byExtId, data.byExtName)', + type: String, + value: '', }, /** @private */ - toggleButtonClass_() { - this.$$('#pauseOrResume') - .classList.toggle( - 'action-button', - this.pauseOrResumeText_ === - loadTimeData.getString('controlResume')); + controlRemoveFromListAriaLabel_: { + type: String, + computed: 'computeControlRemoveFromListAriaLabel_(data.fileName)', }, /** @private */ - updatePauseOrResumeClass_() { - if (!this.pauseOrResumeText_) { - return; - } - - // Wait for dom-if to switch to true, in case the text has just changed - // from empty. - beforeNextRender(this, () => this.toggleButtonClass_()); + isActive_: { + computed: 'computeIsActive_(' + + 'data.state, data.fileExternallyRemoved)', + type: Boolean, + value: true, }, - /** - * @return {string} - * @private - */ - computePauseOrResumeText_() { - if (this.data === undefined) { - return ''; - } + /** @private */ + isDangerous_: { + computed: 'computeIsDangerous_(data.state)', + type: Boolean, + value: false, + }, - if (this.isInProgress_) { - return loadTimeData.getString('controlPause'); - } - if (this.data.resume) { - return loadTimeData.getString('controlResume'); - } + /** @private */ + isMalware_: { + computed: 'computeIsMalware_(isDangerous_, data.dangerType)', + type: Boolean, + value: false, + }, + + /** @private */ + isInProgress_: { + computed: 'computeIsInProgress_(data.state)', + type: Boolean, + value: false, + }, + + /** @private */ + pauseOrResumeText_: { + computed: 'computePauseOrResumeText_(isInProgress_, data.resume)', + type: String, + observer: 'updatePauseOrResumeClass_', + }, + + /** @private */ + showCancel_: { + computed: 'computeShowCancel_(data.state)', + type: Boolean, + value: false, + }, + + /** @private */ + showProgress_: { + computed: 'computeShowProgress_(showCancel_, data.percent)', + type: Boolean, + value: false, + }, + + /** @private */ + showOpenNow_: { + computed: 'computeShowOpenNow_(data.state)', + type: Boolean, + value: false, + }, + + useFileIcon_: Boolean, + }, + + hostAttributes: { + role: 'row', + }, + + observers: [ + // TODO(dbeam): this gets called way more when I observe data.byExtId + // and data.byExtName directly. Why? + 'observeControlledBy_(controlledBy_)', + 'observeIsDangerous_(isDangerous_, data)', + 'restoreFocusAfterCancelIfNeeded_(data)', + ], + + /** @private {downloads.mojom.PageHandlerInterface} */ + mojoHandler_: null, + + /** @private {boolean} */ + restoreFocusAfterCancel_: false, + + /** @override */ + attached() { + afterNextRender(this, function() { + IronA11yAnnouncer.requestAvailability(); + }); + }, + + /** @override */ + ready() { + this.mojoHandler_ = BrowserProxy.getInstance().handler; + this.content = this.$.content; + }, + + focusOnRemoveButton() { + focusWithoutInk(this.$.remove); + }, + + /** Overrides FocusRowBehavior. */ + getCustomEquivalent(sampleElement) { + if (sampleElement.getAttribute('focus-type') === 'cancel') { + return this.$$('[focus-type="retry"]'); + } + if (sampleElement.getAttribute('focus-type') === 'retry') { + return this.$$('[focus-type="pauseOrResume"]'); + } + return null; + }, + + /** @return {!HTMLElement} */ + getFileIcon() { + return /** @type {!HTMLElement} */ (this.$['file-icon']); + }, + + /** + * @param {string} url + * @return {string} A reasonably long URL. + * @private + */ + chopUrl_(url) { + return url.slice(0, 300); + }, + + /** @private */ + computeClass_() { + const classes = []; + + if (this.isActive_) { + classes.push('is-active'); + } + + if (this.isDangerous_) { + classes.push('dangerous'); + } + + if (this.showProgress_) { + classes.push('show-progress'); + } + + return classes.join(' '); + }, + + /** + * @return {boolean} + * @private + */ + computeCompletelyOnDisk_() { + return this.data.state === States.COMPLETE && + !this.data.fileExternallyRemoved; + }, + + /** + * @return {string} + * @private + */ + computeControlledBy_() { + if (!this.data.byExtId || !this.data.byExtName) { return ''; - }, + } - /** - * @return {string} - * @private - */ - computeRemoveStyle_() { - const canDelete = loadTimeData.getBoolean('allowDeletingHistory'); - const hideRemove = this.isDangerous_ || this.showCancel_ || !canDelete; - return hideRemove ? 'visibility: hidden' : ''; - }, + const url = `chrome://extensions/?id=${this.data.byExtId}`; + const name = this.data.byExtName; + return loadTimeData.getStringF('controlledByUrl', url, HTMLEscape(name)); + }, - /** - * @return {boolean} - * @private - */ - computeShowCancel_() { - return this.data.state === States.IN_PROGRESS || - this.data.state === States.PAUSED || - this.data.state === States.ASYNC_SCANNING; - }, + /** + * @return {string} + * @private + */ + computeControlRemoveFromListAriaLabel_() { + return loadTimeData.getStringF( + 'controlRemoveFromListAriaLabel', this.data.fileName); + }, - /** - * @return {boolean} - * @private - */ - computeShowProgress_() { - return this.showCancel_ && this.data.percent >= -1 && - this.data.state !== States.ASYNC_SCANNING; - }, - - /** - * @return {boolean} - * @private - */ - computeShowOpenNow_() { - const allowOpenNow = loadTimeData.getBoolean('allowOpenNow'); - return this.data.state === States.ASYNC_SCANNING && allowOpenNow; - }, - - /** - * @return {string} - * @private - */ - computeTag_() { - switch (this.data.state) { - case States.CANCELLED: - return loadTimeData.getString('statusCancelled'); - - case States.INTERRUPTED: - return this.data.lastReasonText; - - case States.COMPLETE: - return this.data.fileExternallyRemoved ? - loadTimeData.getString('statusRemoved') : - ''; - } - + /** + * @return {string} + * @private + */ + computeDate_() { + assert(typeof this.data.hideDate === 'boolean'); + if (this.data.hideDate) { return ''; - }, + } + return assert(this.data.sinceString || this.data.dateString); + }, - /** - * @return {boolean} - * @private - */ - isIndeterminate_() { - return this.data.percent === -1; - }, + /** @private @return {boolean} */ + computeDescriptionVisible_() { + return this.computeDescription_() !== ''; + }, - /** @private */ - observeControlledBy_() { - this.$['controlled-by'].innerHTML = this.controlledBy_; - if (this.controlledBy_) { - const link = this.$$('#controlled-by a'); - link.setAttribute('focus-row-control', ''); - link.setAttribute('focus-type', 'controlledBy'); - } - }, + /** + * @return {string} + * @private + */ + computeDescription_() { + const data = this.data; - /** @private */ - observeIsDangerous_() { - if (!this.data) { - return; + switch (data.state) { + case States.COMPLETE: + switch (data.dangerType) { + case DangerType.DEEP_SCANNED_SAFE: + return loadTimeData.getString('deepScannedSafeDesc'); + case DangerType.DEEP_SCANNED_OPENED_DANGEROUS: + return loadTimeData.getString('deepScannedOpenedDangerousDesc'); + } + break; + + case States.MIXED_CONTENT: + return loadTimeData.getString('mixedContentDownloadDesc'); + + case States.DANGEROUS: + const fileName = data.fileName; + switch (data.dangerType) { + case DangerType.DANGEROUS_FILE: + return loadTimeData.getString('dangerFileDesc'); + + case DangerType.DANGEROUS_URL: + case DangerType.DANGEROUS_CONTENT: + case DangerType.DANGEROUS_HOST: + return loadTimeData.getString('dangerDownloadDesc'); + + case DangerType.UNCOMMON_CONTENT: + return loadTimeData.getString('dangerUncommonDesc'); + + case DangerType.POTENTIALLY_UNWANTED: + return loadTimeData.getString('dangerSettingsDesc'); + + case DangerType.SENSITIVE_CONTENT_WARNING: + return loadTimeData.getString('sensitiveContentWarningDesc'); + } + break; + + case States.ASYNC_SCANNING: + return loadTimeData.getString('asyncScanningDownloadDesc'); + + case States.IN_PROGRESS: + case States.PAUSED: // Fallthrough. + return data.progressStatusText; + + case States.INTERRUPTED: + switch (data.dangerType) { + case DangerType.SENSITIVE_CONTENT_BLOCK: + return loadTimeData.getString('sensitiveContentBlockedDesc'); + case DangerType.BLOCKED_TOO_LARGE: + return loadTimeData.getString('blockedTooLargeDesc'); + case DangerType.BLOCKED_PASSWORD_PROTECTED: + return loadTimeData.getString('blockedPasswordProtectedDesc'); + } + } + + return ''; + }, + + /** + * @return {string} + * @private + */ + computeIcon_() { + if (this.data) { + const dangerType = this.data.dangerType; + if ((loadTimeData.getBoolean('requestsApVerdicts') && + dangerType === DangerType.UNCOMMON_CONTENT) || + dangerType === DangerType.SENSITIVE_CONTENT_WARNING) { + return 'cr:warning'; } - const OVERRIDDEN_ICON_TYPES = [ + const ERROR_TYPES = [ DangerType.SENSITIVE_CONTENT_BLOCK, DangerType.BLOCKED_TOO_LARGE, DangerType.BLOCKED_PASSWORD_PROTECTED, ]; - - if (this.isDangerous_) { - this.$.url.removeAttribute('href'); - this.useFileIcon_ = false; - } else if (OVERRIDDEN_ICON_TYPES.includes(this.data.dangerType)) { - this.useFileIcon_ = false; - } else if (this.data.state === States.ASYNC_SCANNING) { - this.useFileIcon_ = false; - } else { - this.$.url.href = assert(this.data.url); - const path = this.data.filePath; - IconLoader.getInstance() - .loadIcon(this.$['file-icon'], path) - .then(success => { - if (path === this.data.filePath && this.data.state !== - States.ASYNC_SCANNING) { - this.useFileIcon_ = success; - } - }); + if (ERROR_TYPES.includes(dangerType)) { + return 'cr:error'; } - }, - /** @private */ - onCancelTap_() { - this.restoreFocusAfterCancel_ = true; - this.mojoHandler_.cancel(this.data.id); - }, - - /** @private */ - onDiscardDangerousTap_() { - this.mojoHandler_.discardDangerous(this.data.id); - }, - - /** @private */ - onOpenNowTap_() { - this.mojoHandler_.openDuringScanningRequiringGesture(this.data.id); - }, - - /** - * @private - * @param {Event} e - */ - onDragStart_(e) { - e.preventDefault(); - this.mojoHandler_.drag(this.data.id); - }, - - /** - * @param {Event} e - * @private - */ - onFileLinkTap_(e) { - e.preventDefault(); - this.mojoHandler_.openFileRequiringGesture(this.data.id); - }, - - /** @private */ - onUrlTap_() { - chrome.send('metricsHandler:recordAction', - ['Downloads_OpenUrlOfDownloadedItem']); - }, - - /** @private */ - onPauseOrResumeTap_() { - if (this.isInProgress_) { - this.mojoHandler_.pause(this.data.id); - } else { - this.mojoHandler_.resume(this.data.id); + if (this.data.state === States.ASYNC_SCANNING) { + return 'cr:info'; } - }, + } + if (this.isDangerous_) { + return 'cr:error'; + } + if (!this.useFileIcon_) { + return 'cr:insert-drive-file'; + } + return ''; + }, - /** @private */ - onRemoveTap_() { - this.mojoHandler_.remove(this.data.id); - const pieces = loadTimeData.getSubstitutedStringPieces( - loadTimeData.getString('toastRemovedFromList'), this.data.fileName); - pieces.forEach(p => { - // Make the file name collapsible. - p.collapsible = !!p.arg; - }); - const canUndo = !this.data.isDangerous && !this.data.isMixedContent; - getToastManager().showForStringPieces( - /** - * @type {!Array<{collapsible: boolean, - * value: string, - * arg: (string|null)}>} - */ - (pieces), /* hideSlotted= */ !canUndo); - if (canUndo) { - this.fire('iron-announce', { - text: loadTimeData.getString('undoDescription'), - }); + /** + * @return {string} + * @private + */ + computeIconColor_() { + if (this.data) { + const dangerType = this.data.dangerType; + if ((loadTimeData.getBoolean('requestsApVerdicts') && + dangerType === DangerType.UNCOMMON_CONTENT) || + dangerType === DangerType.SENSITIVE_CONTENT_WARNING) { + return 'yellow'; } - }, - /** @private */ - onRetryTap_() { - this.mojoHandler_.retryDownload(this.data.id); - }, - - /** @private */ - onSaveDangerousTap_() { - this.mojoHandler_.saveDangerousRequiringGesture(this.data.id); - }, - - /** @private */ - onShowTap_() { - this.mojoHandler_.show(this.data.id); - }, - - /** @private */ - restoreFocusAfterCancelIfNeeded_() { - if (!this.restoreFocusAfterCancel_) { - return; + const WARNING_TYPES = [ + DangerType.SENSITIVE_CONTENT_BLOCK, + DangerType.BLOCKED_TOO_LARGE, + DangerType.BLOCKED_PASSWORD_PROTECTED, + ]; + if (WARNING_TYPES.includes(dangerType)) { + return 'red'; } - this.restoreFocusAfterCancel_ = false; - setTimeout(() => { - const element = this.getFocusRow().getFirstFocusable('retry'); - if (element) { - element.focus(); - } + + if (this.data.state === States.ASYNC_SCANNING) { + return 'grey'; + } + } + if (this.isDangerous_) { + return 'red'; + } + if (!this.useFileIcon_) { + return 'paper-grey'; + } + return ''; + }, + + /** + * @return {boolean} + * @private + */ + computeIsActive_() { + return this.data.state !== States.CANCELLED && + this.data.state !== States.INTERRUPTED && + !this.data.fileExternallyRemoved; + }, + + /** + * @return {boolean} + * @private + */ + computeIsDangerous_() { + return this.data.state === States.DANGEROUS || + this.data.state === States.MIXED_CONTENT; + }, + + /** + * @return {boolean} + * @private + */ + computeIsInProgress_() { + return this.data.state === States.IN_PROGRESS; + }, + + /** + * @return {boolean} + * @private + */ + computeIsMalware_() { + return this.isDangerous_ && + (this.data.dangerType === DangerType.DANGEROUS_CONTENT || + this.data.dangerType === DangerType.DANGEROUS_HOST || + this.data.dangerType === DangerType.DANGEROUS_URL || + this.data.dangerType === DangerType.POTENTIALLY_UNWANTED); + }, + + /** @private */ + toggleButtonClass_() { + this.$$('#pauseOrResume') + .classList.toggle( + 'action-button', + this.pauseOrResumeText_ === + loadTimeData.getString('controlResume')); + }, + + /** @private */ + updatePauseOrResumeClass_() { + if (!this.pauseOrResumeText_) { + return; + } + + // Wait for dom-if to switch to true, in case the text has just changed + // from empty. + beforeNextRender(this, () => this.toggleButtonClass_()); + }, + + /** + * @return {string} + * @private + */ + computePauseOrResumeText_() { + if (this.data === undefined) { + return ''; + } + + if (this.isInProgress_) { + return loadTimeData.getString('controlPause'); + } + if (this.data.resume) { + return loadTimeData.getString('controlResume'); + } + return ''; + }, + + /** + * @return {string} + * @private + */ + computeRemoveStyle_() { + const canDelete = loadTimeData.getBoolean('allowDeletingHistory'); + const hideRemove = this.isDangerous_ || this.showCancel_ || !canDelete; + return hideRemove ? 'visibility: hidden' : ''; + }, + + /** + * @return {boolean} + * @private + */ + computeShowCancel_() { + return this.data.state === States.IN_PROGRESS || + this.data.state === States.PAUSED || + this.data.state === States.ASYNC_SCANNING; + }, + + /** + * @return {boolean} + * @private + */ + computeShowProgress_() { + return this.showCancel_ && this.data.percent >= -1 && + this.data.state !== States.ASYNC_SCANNING; + }, + + /** + * @return {boolean} + * @private + */ + computeShowOpenNow_() { + const allowOpenNow = loadTimeData.getBoolean('allowOpenNow'); + return this.data.state === States.ASYNC_SCANNING && allowOpenNow; + }, + + /** + * @return {string} + * @private + */ + computeTag_() { + switch (this.data.state) { + case States.CANCELLED: + return loadTimeData.getString('statusCancelled'); + + case States.INTERRUPTED: + return this.data.lastReasonText; + + case States.COMPLETE: + return this.data.fileExternallyRemoved ? + loadTimeData.getString('statusRemoved') : + ''; + } + + return ''; + }, + + /** + * @return {boolean} + * @private + */ + isIndeterminate_() { + return this.data.percent === -1; + }, + + /** @private */ + observeControlledBy_() { + this.$['controlled-by'].innerHTML = this.controlledBy_; + if (this.controlledBy_) { + const link = this.$$('#controlled-by a'); + link.setAttribute('focus-row-control', ''); + link.setAttribute('focus-type', 'controlledBy'); + } + }, + + /** @private */ + observeIsDangerous_() { + if (!this.data) { + return; + } + + const OVERRIDDEN_ICON_TYPES = [ + DangerType.SENSITIVE_CONTENT_BLOCK, + DangerType.BLOCKED_TOO_LARGE, + DangerType.BLOCKED_PASSWORD_PROTECTED, + ]; + + if (this.isDangerous_) { + this.$.url.removeAttribute('href'); + this.useFileIcon_ = false; + } else if (OVERRIDDEN_ICON_TYPES.includes(this.data.dangerType)) { + this.useFileIcon_ = false; + } else if (this.data.state === States.ASYNC_SCANNING) { + this.useFileIcon_ = false; + } else { + this.$.url.href = assert(this.data.url); + const path = this.data.filePath; + IconLoader.getInstance() + .loadIcon(this.$['file-icon'], path) + .then(success => { + if (path === this.data.filePath && + this.data.state !== States.ASYNC_SCANNING) { + this.useFileIcon_ = success; + } + }); + } + }, + + /** @private */ + onCancelTap_() { + this.restoreFocusAfterCancel_ = true; + this.mojoHandler_.cancel(this.data.id); + }, + + /** @private */ + onDiscardDangerousTap_() { + this.mojoHandler_.discardDangerous(this.data.id); + }, + + /** @private */ + onOpenNowTap_() { + this.mojoHandler_.openDuringScanningRequiringGesture(this.data.id); + }, + + /** + * @private + * @param {Event} e + */ + onDragStart_(e) { + e.preventDefault(); + this.mojoHandler_.drag(this.data.id); + }, + + /** + * @param {Event} e + * @private + */ + onFileLinkTap_(e) { + e.preventDefault(); + this.mojoHandler_.openFileRequiringGesture(this.data.id); + }, + + /** @private */ + onUrlTap_() { + chrome.send( + 'metricsHandler:recordAction', ['Downloads_OpenUrlOfDownloadedItem']); + }, + + /** @private */ + onPauseOrResumeTap_() { + if (this.isInProgress_) { + this.mojoHandler_.pause(this.data.id); + } else { + this.mojoHandler_.resume(this.data.id); + } + }, + + /** @private */ + onRemoveTap_() { + this.mojoHandler_.remove(this.data.id); + const pieces = loadTimeData.getSubstitutedStringPieces( + loadTimeData.getString('toastRemovedFromList'), this.data.fileName); + pieces.forEach(p => { + // Make the file name collapsible. + p.collapsible = !!p.arg; + }); + const canUndo = !this.data.isDangerous && !this.data.isMixedContent; + getToastManager().showForStringPieces( + /** + * @type {!Array<{collapsible: boolean, + * value: string, + * arg: (string|null)}>} + */ + (pieces), /* hideSlotted= */ !canUndo); + if (canUndo) { + this.fire('iron-announce', { + text: loadTimeData.getString('undoDescription'), }); } - }); + }, + + /** @private */ + onRetryTap_() { + this.mojoHandler_.retryDownload(this.data.id); + }, + + /** @private */ + onSaveDangerousTap_() { + this.mojoHandler_.saveDangerousRequiringGesture(this.data.id); + }, + + /** @private */ + onShowTap_() { + this.mojoHandler_.show(this.data.id); + }, + + /** @private */ + restoreFocusAfterCancelIfNeeded_() { + if (!this.restoreFocusAfterCancel_) { + return; + } + this.restoreFocusAfterCancel_ = false; + setTimeout(() => { + const element = this.getFocusRow().getFirstFocusable('retry'); + if (element) { + element.focus(); + } + }); + }, +});
diff --git a/chrome/browser/resources/nearby_share/app.js b/chrome/browser/resources/nearby_share/app.js index de293a40..ed03cf6 100644 --- a/chrome/browser/resources/nearby_share/app.js +++ b/chrome/browser/resources/nearby_share/app.js
@@ -76,7 +76,6 @@ listeners: { 'change-page': 'onChangePage_', 'close': 'onClose_', - 'onboarding-complete': 'onOnboardingComplete_', }, /** @@ -115,13 +114,4 @@ onClose_(event) { chrome.send('close'); }, - - /** - * Handler for when onboarding is completed. - * @param {!Event} event - * @private - */ - onOnboardingComplete_(event) { - this.getViewManager_().switchView(Page.DISCOVERY); - }, });
diff --git a/chrome/browser/resources/nearby_share/shared/BUILD.gn b/chrome/browser/resources/nearby_share/shared/BUILD.gn index 8a1940eb..d4d1c195 100644 --- a/chrome/browser/resources/nearby_share/shared/BUILD.gn +++ b/chrome/browser/resources/nearby_share/shared/BUILD.gn
@@ -49,7 +49,6 @@ js_library("nearby_onboarding_page") { deps = [ - ":nearby_page_template", ":nearby_share_settings_behavior", "//third_party/polymer/v1_0/components-chromium/iron-icon:iron-icon-extracted", "//ui/webui/resources/cr_elements/cr_input:cr_input", @@ -75,7 +74,6 @@ js_library("nearby_visibility_page") { deps = [ ":nearby_contact_visibility", - ":nearby_page_template", ":nearby_share_settings_behavior", "//ui/webui/resources/js:i18n_behavior", ] @@ -139,7 +137,6 @@ js_library("nearby_onboarding_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.m.js" ] deps = [ - ":nearby_page_template.m", ":nearby_share_settings_behavior.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_link_row:cr_link_row.m", @@ -176,7 +173,6 @@ sources = [ "$root_gen_dir/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.m.js" ] deps = [ ":nearby_contact_visibility.m", - ":nearby_page_template.m", ":nearby_share_settings_behavior.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:i18n_behavior.m",
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html b/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html index a6ceee7..0d7061b3 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html +++ b/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html
@@ -10,7 +10,6 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="nearby_contact_manager.html"> -<link rel="import" href="nearby_page_template.html"> <link rel="import" href="nearby_share_settings_behavior.html"> <link rel="import" href="nearby_shared_icons.html"> @@ -144,7 +143,7 @@ } .contacts-section { - height: 100px; + height: 150px; margin-block-end: 8px; margin-block-start: 8px; }
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js b/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js index efe38cb..4fe4e054 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js +++ b/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js
@@ -286,6 +286,8 @@ * @private */ genFakeContacts_(numContacts) { + this.contactsPending = false; + this.contactsFailed = false; clearTimeout(this.downloadTimeoutId_); const fakeContacts = []; for (let i = 0; i < numContacts; i++) { @@ -297,7 +299,6 @@ }); } this.contacts = fakeContacts; - this.contactsState = ContactsState.HAS_CONTACTS; }, /**
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.html b/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.html index f1a460b..f48b543 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.html +++ b/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.html
@@ -4,13 +4,28 @@ <link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="./nearby_page_template.html"> <link rel="import" href="./nearby_share_settings_behavior.html"> <dom-module id="nearby-onboarding-page"> <template> <style include="cr-icons cr-shared-style"></style> <style> + :host { + --nearby-page-space-block: 26px; + --nearby-page-space-inline: 32px; + --nearby-page-space-large-inline: 42px; + } + + #page-container { + display: flex; + flex-direction: column; + height: 100%; + } + + #header { + padding: 30px; + } + #center-content { box-sizing: border-box; display: flex; @@ -19,6 +34,15 @@ overflow: hidden; } + #page-title { + font-size: 125%; + font-weight: normal; + } + + #page-sub-title { + font-weight: normal; + } + #splash-image-column { height: 200px; margin: 10px; @@ -42,14 +66,22 @@ padding-inline-end: 10px; padding-inline-start: 10px; } + + #actions { + margin-block-end: var(--nearby-page-space-block); + margin-block-start: 17px; + margin-inline-end: var(--nearby-page-space-inline); + margin-inline-start: var(--nearby-page-space-inline); + text-align: end; + } </style> - <nearby-page-template title="$i18n{nearbyShareOnboardingPageTitle}" - sub-title="$i18n{nearbyShareOnboardingPageSubtitle}" - action-button-label="$i18n{nearbyShareActionsNext}" - action-button-event-name="next" - cancel-button-label="$i18n{nearbyShareActionsCancel}" - cancel-button-event-name="close"> - <div id=center-content slot="content"> + <div id="page-container"> + <div id="header"> + <h1 id="page-title">$i18n{nearbyShareOnboardingPageTitle}</h1> + <h4 id="page-sub-title">$i18n{nearbyShareOnboardingPageSubtitle}</h4> + </div> + + <div id=center-content> <iron-icon id="splash-image-column" icon="nearby-images:nearby-onboarding-splash"> </iron-icon> @@ -59,7 +91,16 @@ </cr-input> </div> </div> - </nearby-page-template> + + <div id="actions"> + <cr-button class="cancel-button" on-click="onCloseTap_"> + $i18n{nearbyShareActionsCancel} + </cr-button> + <cr-button id="next-button" class="action-button" on-click="onNextTap_"> + $i18n{nearbyShareActionsNext} + </cr-button> + </div> + </div> </template> <script src="nearby_onboarding_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.js b/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.js index 3a24618..fe8c0e6b 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.js +++ b/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.js
@@ -19,15 +19,12 @@ } }, - listeners: { - 'next': 'onNext_', - }, - - /** - * @private - */ - onNext_() { + onNextTap_() { this.set('settings.deviceName', this.$.deviceName.value); this.fire('change-page', {page: 'visibility'}); }, + + onCloseTap_() { + this.fire('close'); + }, });
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_page_template.html b/chrome/browser/resources/nearby_share/shared/nearby_page_template.html index 049c077..718e3004 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_page_template.html +++ b/chrome/browser/resources/nearby_share/shared/nearby_page_template.html
@@ -13,14 +13,14 @@ #pageContainer { display: flex; flex-direction: column; - height: 100%; + height: 385px; + padding-block-end: var(--nearby-page-space-block); + padding-block-start: var(--nearby-page-space-block); } #header { margin-inline-end: var(--nearby-page-space-inline); margin-inline-start: var(--nearby-page-space-inline); - padding-block-end: var(--nearby-page-space-block); - padding-block-start: var(--nearby-page-space-block); } #contentContainer { @@ -37,12 +37,10 @@ } #actions { - display: flex; - justify-content: flex-end; - padding-block-end: var(--nearby-page-space-block); padding-block-start: var(--nearby-page-space-block); padding-inline-end: var(--nearby-page-space-inline); padding-inline-start: var(--nearby-page-space-inline); + text-align: end; } #utilityButton {
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.html b/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.html index e82c274..ebdba92 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.html +++ b/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.html
@@ -9,6 +9,22 @@ <template> <style include="cr-icons cr-shared-style"></style> <style> + :host { + --nearby-page-space-block: 26px; + --nearby-page-space-inline: 32px; + --nearby-page-space-large-inline: 42px; + } + + #page-container { + display: flex; + flex-direction: column; + height: 100%; + } + + #header { + padding: 30px; + } + #center-content { box-sizing: border-box; display: flex; @@ -18,21 +34,54 @@ margin-inline-start: 24px; overflow: hidden; } + + #page-title { + font-size: 125%; + font-weight: normal; + } + + #page-sub-title { + font-weight: normal; + } + + #actions { + display: flex; + margin-block-end: var(--nearby-page-space-block); + margin-block-start: 17px; + margin-inline-end: var(--nearby-page-space-inline); + margin-inline-start: var(--nearby-page-space-inline); + text-align: end; + } + + #manage-contacts-button { + margin-inline-end: auto; + } </style> - <nearby-page-template title="$i18n{nearbyShareVisibilityPageTitle}" - sub-title="$i18n{nearbyShareVisibilityPageSubtitle}" - action-button-label="$i18n{nearbyShareActionsConfirm}" - action-button-event-name="next" - cancel-button-label="$i18n{nearbyShareActionsCancel}" - cancel-button-event-name="close" - utility-button-label="$i18n{nearbyShareVisibilityPageManageContacts}" - utility-button-event-name="manage-contacts"> - <div id=center-content slot="content"> + <div id="page-container"> + <div id="header"> + <h1 id="page-title">$i18n{nearbyShareVisibilityPageTitle}</h1> + <h4 id="page-sub-title">$i18n{nearbyShareVisibilityPageSubtitle}</h4> + </div> + + <div id=center-content> <nearby-contact-visibility id="contactVisibility" settings="{{settings}}"> </nearby-contact-visibility> </div> - </nearby-page-template> + + <div id="actions"> + <cr-button id="manage-contacts-button" on-click="onManageContactsTap_"> + $i18n{nearbyShareVisibilityPageManageContacts} + </cr-button> + <cr-button id="cancel-button" class="cancel-button" + on-click="onCloseTap_"> + $i18n{nearbyShareActionsCancel} + </cr-button> + <cr-button id="next-button" class="action-button" on-click="onNextTap_"> + $i18n{nearbyShareActionsConfirm} + </cr-button> + </div> + </div> </template> <script src="nearby_visibility_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.js b/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.js index 4585452..985ff16 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.js +++ b/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.js
@@ -24,21 +24,18 @@ } }, - listeners: { - 'next': 'onNext_', - 'manage-contacts': 'onManageContacts_' - }, - - /** @private */ - onNext_() { + onNextTap_() { this.set('settings.enabled', true); - this.fire('onboarding-complete'); + this.fire('change-page', {page: 'discovery'}); }, - /** @private */ - onManageContacts_() { + onCloseTap_() { + this.fire('close'); + }, + + onManageContactsTap_() { // TODO(vecore): this is not a final link - window.open('https://contacts.google.com', '_blank'); + window.open('https://contacts.google.com'); }, });
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn index 2c3ac52..77e8782 100644 --- a/chrome/browser/resources/settings/BUILD.gn +++ b/chrome/browser/resources/settings/BUILD.gn
@@ -4,7 +4,7 @@ import("//chrome/common/features.gni") import("//third_party/closure_compiler/compile_js.gni") -import("//tools/grit/grit_rule.gni") +import("//tools/grit/preprocess_grit.gni") import("//tools/polymer/html_to_js.gni") import("//tools/polymer/polymer.gni") import("//ui/webui/resources/tools/js_modulizer.gni") @@ -13,12 +13,11 @@ import("settings.gni") if (optimize_webui) { - settings_pak_file = "settings_resources.pak" - unpak_folder = "settings_resources.unpak" + preprocess_folder = "preprocessed" optimize_webui("build_polymer3") { host = "settings" - input = rebase_path("$target_gen_dir/$unpak_folder", root_build_dir) + input = rebase_path("$target_gen_dir/$preprocess_folder", root_build_dir) js_module_in_files = [ "settings.js", "lazy_load.js", @@ -30,36 +29,254 @@ ] deps = [ - ":unpak", + ":preprocess", + ":preprocess_generated", "../../../../ui/webui/resources:preprocess", ] - excludes = [ "chrome://resources/js/cr.m.js" ] + excludes = [ + "chrome://resources/js/cr.m.js", + "chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js", + "chrome://resources/mojo/skia/public/mojom/skcolor.mojom-lite.js", + ] } - unpak("unpak") { - pak_file = settings_pak_file - out_folder = unpak_folder - - deps = [ ":flattened_resources" ] - } - - grit("flattened_resources") { - source = "settings_resources.grd" - - grit_flags = [ - "-E", - "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir), + preprocess_grit("preprocess") { + in_folder = "./" + out_folder = "$target_gen_dir/$preprocess_folder" + in_files = [ + "a11y_page/captions_browser_proxy.js", + "appearance_page/appearance_browser_proxy.js", + "autofill_page/merge_exceptions_store_copies_behavior.js", + "autofill_page/merge_passwords_store_copies_behavior.js", + "autofill_page/multi_store_exception_entry.js", + "autofill_page/multi_store_id_handler.js", + "autofill_page/multi_store_password_ui_entry.js", + "autofill_page/password_check_behavior.js", + "autofill_page/password_manager_proxy.js", + "autofill_page/show_password_behavior.js", + "chrome_cleanup_page/chrome_cleanup_proxy.js", + "clear_browsing_data_dialog/clear_browsing_data_browser_proxy.js", + "controls/settings_idle_load.js", + "downloads_page/downloads_browser_proxy.js", + "ensure_lazy_loaded.js", + "hats_browser_proxy.js", + "i18n_setup.js", + "incompatible_applications_page/incompatible_applications_browser_proxy.js", + "lazy_load.js", + "metrics_browser_proxy.js", + "on_startup_page/on_startup_browser_proxy.js", + "on_startup_page/startup_urls_page_browser_proxy.js", + "open_window_proxy.js", + "page_visibility.js", + "privacy_page/security_keys_browser_proxy.js", + "reset_page/reset_browser_proxy.js", + "route.js", + "safety_check_page/safety_check_browser_proxy.js", + "settings_page/main_page_behavior.js", + "settings_routes.js", + "settings.js", + "site_settings/constants.js", + "site_settings/cookie_info.js", + "site_settings/local_data_browser_proxy.js", + "site_settings/site_settings_behavior.js", + "site_settings/site_settings_prefs_browser_proxy.js", + "site_settings/website_usage_browser_proxy.js", ] + if (is_chromeos) { + in_files += [ + "autofill_page/blocking_request_manager.js", + "languages_page/languages_metrics_proxy.js", + "site_settings/android_info_browser_proxy.js", + ] + } else { + in_files += [ + "default_browser_page/default_browser_browser_proxy.js", + "people_page/import_data_browser_proxy.js", + "people_page/manage_profile_browser_proxy.js", + "printing_page/printing_browser_proxy.js", + "system_page/system_page_browser_proxy.js", + ] + } + } + + preprocess_grit("preprocess_generated") { deps = [ ":polymer3_elements" ] - defines = chrome_grit_defines - outputs = [ - "grit/settings_resources.h", - "grit/settings_resources_map.cc", - "grit/settings_resources_map.h", - settings_pak_file, + in_folder = target_gen_dir + out_folder = "$target_gen_dir/$preprocess_folder" + in_files = [ + "a11y_page/a11y_page.js", + "a11y_page/captions_subpage.m.js", + "about_page/about_page_browser_proxy.m.js", + "about_page/about_page.js", + "appearance_page/appearance_fonts_page.js", + "appearance_page/appearance_page.js", + "appearance_page/fonts_browser_proxy.m.js", + "appearance_page/home_url_input.js", + "autofill_page/autofill_page.js", + "autofill_page/avatar_icon.js", + "autofill_page/payments_list.js", + "autofill_page/credit_card_list_entry.js", + "autofill_page/upi_id_list_entry.js", + "autofill_page/passwords_shared_css.js", + "autofill_page/credit_card_edit_dialog.js", + "autofill_page/autofill_section.js", + "autofill_page/address_edit_dialog.js", + "autofill_page/password_check.js", + "autofill_page/password_check_edit_dialog.js", + "autofill_page/password_check_edit_disclaimer_dialog.js", + "autofill_page/password_check_list_item.js", + "autofill_page/password_list_item.js", + "autofill_page/passwords_list_handler.js", + "autofill_page/password_remove_confirmation_dialog.js", + "autofill_page/passwords_section.js", + "autofill_page/passwords_device_section.js", + "autofill_page/password_edit_dialog.js", + "autofill_page/password_move_to_account_dialog.js", + "autofill_page/password_remove_dialog.js", + "autofill_page/passwords_export_dialog.js", + "autofill_page/payments_section.js", + "basic_page/basic_page.js", + "clear_browsing_data_dialog/clear_browsing_data_dialog.js", + "clear_browsing_data_dialog/history_deletion_dialog.js", + "clear_browsing_data_dialog/installed_app_checkbox.js", + "clear_browsing_data_dialog/passwords_deletion_dialog.js", + "controls/controlled_button.m.js", + "controls/controlled_radio_button.m.js", + "controls/extension_controlled_indicator.m.js", + "controls/password_prompt_dialog.m.js", + "controls/settings_boolean_control_behavior.m.js", + "controls/settings_checkbox.js", + "controls/settings_dropdown_menu.m.js", + "controls/pref_control_behavior.m.js", + "controls/settings_radio_group.m.js", + "controls/settings_slider.m.js", + "controls/settings_textarea.m.js", + "controls/settings_toggle_button.m.js", + "downloads_page/downloads_page.js", + "extension_control_browser_proxy.m.js", + "global_scroll_target_behavior.m.js", + "icons.m.js", + "languages_page/languages.m.js", + "languages_page/languages_browser_proxy.m.js", + "languages_page/add_languages_dialog.js", + "languages_page/languages_page.js", + "lifetime_browser_proxy.m.js", + "settings_menu/settings_menu.js", + "on_startup_page/on_startup_page.js", + "on_startup_page/startup_url_dialog.js", + "on_startup_page/startup_url_entry.js", + "on_startup_page/startup_urls_page.js", + "people_page/sync_account_control.m.js", + "people_page/sync_browser_proxy.m.js", + "people_page/sync_encryption_options.m.js", + "people_page/people_page.js", + "people_page/profile_info_browser_proxy.m.js", + "people_page/signout_dialog.m.js", + "people_page/sync_controls.m.js", + "people_page/sync_page.m.js", + "prefs/prefs.m.js", + "prefs/prefs_behavior.m.js", + "prefs/prefs_types.m.js", + "prefs/pref_util.m.js", + "printing_page/cloud_printers.js", + "printing_page/printing_page.js", + "privacy_page/collapse_radio_button.js", + "privacy_page/cookies_page.js", + "privacy_page/do_not_track_toggle.js", + "privacy_page/privacy_page.js", + "privacy_page/personalization_options.m.js", + "privacy_page/privacy_page_browser_proxy.m.js", + "privacy_page/secure_dns.js", + "privacy_page/secure_dns_input.js", + "privacy_page/security_page.js", + "privacy_page/disable_safebrowsing_dialog.js", + "privacy_page/security_keys_bio_enroll_dialog.js", + "privacy_page/security_keys_credential_management_dialog.js", + "privacy_page/security_keys_pin_field.js", + "privacy_page/security_keys_reset_dialog.js", + "privacy_page/security_keys_set_pin_dialog.js", + "privacy_page/security_keys_subpage.js", + "reset_page/reset_page.js", + "reset_page/reset_profile_dialog.js", + "reset_page/reset_profile_banner.js", + "router.m.js", + "safety_check_page/safety_check_child.js", + "safety_check_page/safety_check_extensions_child.js", + "safety_check_page/safety_check_page.js", + "safety_check_page/safety_check_passwords_child.js", + "safety_check_page/safety_check_safe_browsing_child.js", + "safety_check_page/safety_check_updates_child.js", + "search_engines_page/search_engines_browser_proxy.m.js", + "search_engines_page/omnibox_extension_entry.js", + "search_engines_page/search_engine_dialog.js", + "search_engines_page/search_engine_entry_css.js", + "search_engines_page/search_engine_entry.js", + "search_engines_page/search_engines_list.js", + "search_engines_page/search_engines_page.js", + "search_page/search_page.js", + "search_settings.m.js", + "settings_main/settings_main.js", + "settings_page/settings_animated_pages.m.js", + "settings_page/settings_section.m.js", + "settings_page/settings_subpage.m.js", + "settings_ui/settings_ui.js", + "setting_id_param_util.m.js", + "settings_page_css.m.js", + "settings_shared_css.m.js", + "settings_vars_css.m.js", + "site_favicon.js", + "site_settings/add_site_dialog.js", + "site_settings/all_sites.js", + "site_settings/all_sites_icons.js", + "site_settings/category_default_setting.js", + "site_settings/category_setting_exceptions.js", + "site_settings/chooser_exception_list.js", + "site_settings/chooser_exception_list_entry.js", + "site_settings/clear_storage_dialog_css.js", + "site_settings/edit_exception_dialog.js", + "site_settings/media_picker.js", + "site_settings/pdf_documents.js", + "site_settings/protocol_handlers.js", + "site_settings/settings_category_default_radio_group.js", + "site_settings/site_data.js", + "site_settings/site_data_details_subpage.js", + "site_settings/site_data_entry.js", + "site_settings/site_details.js", + "site_settings/site_details_permission.js", + "site_settings/site_entry.js", + "site_settings/site_list.js", + "site_settings/site_list_entry.js", + "site_settings/zoom_levels.js", + "site_settings_page/recent_site_permissions.js", + "site_settings_page/site_settings_list.js", + "site_settings_page/site_settings_page.js", ] - output_dir = "$root_gen_dir/chrome/browser/resources/settings" + + if (is_win) { + in_files += [ + "chrome_cleanup_page/chrome_cleanup_page.js", + "chrome_cleanup_page/items_to_remove_list.js", + "incompatible_applications_page/incompatible_applications_page.js", + "incompatible_applications_page/incompatible_application_item.js", + "safety_check_page/safety_check_chrome_cleaner_child.js", + ] + } + + if (!is_mac) { + in_files += [ "languages_page/edit_dictionary_page.js" ] + } + + if (is_chromeos) { + in_files += [ "people_page/account_manager_browser_proxy.m.js" ] + } else { + in_files += [ + "default_browser_page/default_browser_page.js", + "people_page/import_data_dialog.js", + "people_page/manage_profile.js", + "system_page/system_page.js", + ] + } } }
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/nearby_share_page/BUILD.gn index 5c74974..638c67e 100644 --- a/chrome/browser/resources/settings/chromeos/nearby_share_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/BUILD.gn
@@ -78,9 +78,7 @@ ":nearby_share_confirm_page", ":nearby_share_high_visibility_page", ":nearby_share_receive_manager", - "//chrome/browser/resources/nearby_share/shared:nearby_onboarding_page", "//chrome/browser/resources/nearby_share/shared:nearby_share_settings_behavior", - "//chrome/browser/resources/nearby_share/shared:nearby_visibility_page", "//ui/webui/resources/cr_elements/cr_button:cr_button", "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog", "//ui/webui/resources/cr_elements/cr_view_manager:cr_view_manager", @@ -219,9 +217,7 @@ ":nearby_share_confirm_page.m", ":nearby_share_high_visibility_page.m", ":nearby_share_receive_manager.m", - "//chrome/browser/resources/nearby_share/shared:nearby_onboarding_page.m", "//chrome/browser/resources/nearby_share/shared:nearby_share_settings_behavior.m", - "//chrome/browser/resources/nearby_share/shared:nearby_visibility_page.m", "//ui/webui/resources/cr_elements/cr_button:cr_button.m", "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", "//ui/webui/resources/cr_elements/cr_view_manager:cr_view_manager.m",
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.html b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.html index 78810385..e389068 100644 --- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.html +++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.html
@@ -4,9 +4,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/cr_elements/cr_view_manager/cr_view_manager.html"> <link rel="import" href="chrome://resources/html/assert.html"> -<link rel="import" href="../../shared/nearby_onboarding_page.html"> <link rel="import" href="../../shared/nearby_share_settings_behavior.html"> -<link rel="import" href="../../shared/nearby_visibility_page.html"> <link rel="import" href="nearby_share_confirm_page.html"> <link rel="import" href="nearby_share_high_visibility_page.html"> <link rel="import" href="nearby_share_receive_manager.html"> @@ -14,9 +12,8 @@ <dom-module id="nearby-share-receive-dialog"> <template> <style> - cr-dialog::part(dialog) { - height: 600px; - width: 512px; + #content { + height: 400px; } </style> <cr-dialog id="dialog" show-on-attach> @@ -29,12 +26,6 @@ share-target="[[shareTarget]]" connection-token="[[connectionToken]]"> </nearby-share-confirm-page> - <nearby-onboarding-page id="[[Page.ONBOARDING]]" slot="view" - settings="{{settings}}"> - </nearby-onboarding-page> - <nearby-visibility-page id="[[Page.VISIBILITY]]" slot="view" - settings="{{settings}}"> - </nearby-visibility-page> </cr-view-manager> </div> </cr-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.js b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.js index 1b36a69..f9f34cb 100644 --- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.js +++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.js
@@ -4,27 +4,15 @@ /** * @fileoverview - * 'nearby-share-receive-dialog' shows two main pages: - * - high visibility receive page - * - Non-contact confirm page (contacts are confirmed w/ a notification) - * - * This dialog also supports showing the onboarding flow and will automatically - * show onboarding if the feature is turned off and one of the two main pages is - * requested. - * - * By default this dialog will not show anything until the caller calls one of - * the following: - * - showOnboarding() - * - showHighVisibilityPage() - * - showConfirmPage() + * 'nearby-share-receive-dialog' shows two pages: + * 1) high visibility receive page + * 2) Non-contact confirm page (contacts are confirmed w/ a notification) */ /** @enum {string} */ const Page = { HIGH_VISIBILITY: 'high-visibility', CONFIRM: 'confirm', - ONBOARDING: 'onboarding', - VISIBILITY: 'visibility', }; Polymer({ @@ -60,29 +48,12 @@ 'change-page': 'onChangePage_', 'cancel': 'onCancel_', 'confirm': 'onConfirm_', - 'onboarding-complete': 'onOnboardingComplete_', 'reject': 'onReject_', }, - observers: [ - 'onSettingsChanged_(settings.*)', - ], - /** @private {boolean} */ closing_: false, - /** - * What should happen once we get settings values from mojo. - * @private {?function()} - * */ - postSettingsCallback: null, - - /** - * What should happen once onboarding is complete. - * @private {?function()} - * */ - postOnboardingCallback: null, - /** @private {?nearbyShare.mojom.ReceiveManagerInterface} */ receiveManager_: null, @@ -96,6 +67,10 @@ this.receiveManager_ = nearby_share.getReceiveManager(); this.observerReceiver_ = nearby_share.observeReceiveManager( /** @type {!nearbyShare.mojom.ReceiveObserverInterface} */ (this)); + // Request to enter high visibility mode if we have been attached. + this.receiveManager_.enterHighVisibility(); + // TODO(vecore): determine if we need to run onboarding first or not.. + this.showHighVisibilityPage(); }, /** @override */ @@ -135,21 +110,6 @@ }, /** - * @param {PolymerDeepPropertyChange} change a change record - * @private - */ - onSettingsChanged_(change) { - if (change.path != 'settings.enabled') { - return; - } - - if (this.postSettingsCallback) { - this.postSettingsCallback(); - this.postSettingsCallback = null; - } - }, - - /** * @return {!CrViewManagerElement} the view manager * @private */ @@ -175,71 +135,21 @@ }, /** - * Defers running a callback for page navigation in the case that we do not - * yet have a settings.enabled value from mojo or if Nearby Share is not - * enabled yet and we need to run the onboarding flow first. - * @param {function()} callback - * @return {boolean} true if the callback has been scheduled for later, false - * if it did not need to be deferred and can be called now. - */ - deferCallIfNecessary(callback) { - const haveSettings = !this.settings || this.settings.enabled === undefined; - if (haveSettings) { - // Let onSettingsChanged_ handle the navigation because we don't know yet - // if the feature is enabled and we might need to show onboarding. - this.postSettingsCallback = callback; - return true; - } - - if (!this.settings.enabled) { - // We need to show onboarding first because nearby is not enabled, but we - // need to run the callback post onboarding. - this.postOnboardingCallback = callback; - this.getViewManager_().switchView(Page.ONBOARDING); - return true; - } - // We know the feature is enabled so no need to defer the call. - return false; - }, - - /** - * Call to show the onboarding flow and then close when complete. - */ - showOnboarding() { - // Setup the callback to close this dialog when onboarding is complete. - this.postOnboardingCallback = this.close_.bind(this); - this.getViewManager_().switchView(Page.ONBOARDING); - }, - - /** - * Call to show the high visibility page. + * Call to show the high visibility page */ showHighVisibilityPage() { - // Check if we need to wait for settings values from mojo or if we need to - // run onboarding first before showing the page. - if (this.deferCallIfNecessary(this.showHighVisibilityPage.bind(this))) { - return; - } - - // Request to enter high visibility mode and show the page. - this.receiveManager_.enterHighVisibility(); this.getViewManager_().switchView(Page.HIGH_VISIBILITY); }, /** - * Call to show the share target configuration page. + * Call to show the share target configuration page */ showConfirmPage() { - // Check if we need to wait for settings values from mojo or if we need to - // run onboarding first before showing the page. - if (this.deferCallIfNecessary(this.showConfirmPage.bind(this))) { - return; - } this.getViewManager_().switchView(Page.CONFIRM); }, /** - * Child views can fire a 'change-page' event to trigger a page change. + * Child views can fire a 'change-page' event to trigger a page change * @param {!CustomEvent<!{page: Page}>} event * @private */ @@ -266,16 +176,6 @@ }, /** @private */ - onOnboardingComplete_() { - if (!this.postOnboardingCallback) { - return; - } - - this.postOnboardingCallback(); - this.postOnboardingCallback = null; - }, - - /** @private */ onReject_() { assert(this.shareTarget); this.receiveManager_.reject(this.shareTarget.id).then((success) => {
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.js b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.js index 26c229d..37e5dc7 100644 --- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.js +++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.js
@@ -281,12 +281,6 @@ this.$$('#receiveDialog').showConfirmPage(); } - if (queryParams.has('onboarding')) { - this.showReceiveDialog_ = true; - Polymer.dom.flush(); - this.$$('#receiveDialog').showOnboarding(); - } - this.attemptDeepLink(); },
diff --git a/chrome/browser/resources/settings/people_page/BUILD.gn b/chrome/browser/resources/settings/people_page/BUILD.gn index 3c26454c..0359f48 100644 --- a/chrome/browser/resources/settings/people_page/BUILD.gn +++ b/chrome/browser/resources/settings/people_page/BUILD.gn
@@ -153,6 +153,7 @@ "..:route", "..:router.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_components/customize_themes", ] }
diff --git a/chrome/browser/resources/settings/people_page/manage_profile.html b/chrome/browser/resources/settings/people_page/manage_profile.html index eb2277ca..05cd9cb 100644 --- a/chrome/browser/resources/settings/people_page/manage_profile.html +++ b/chrome/browser/resources/settings/people_page/manage_profile.html
@@ -3,7 +3,7 @@ --cr-input-error-display: none; } - #selector { + #avatarSelector { margin: 16px 48px; } </style> @@ -27,6 +27,10 @@ </cr-toggle> </div> </template> - <cr-profile-avatar-selector id="selector" avatars="[[availableIcons]]" + <template is="dom-if" if="[[isCustomizeThemesVisible_]]"> + <cr-customize-themes id="themeSelector" auto-confirm-theme-changes> + </cr-customize-themes> + </template> + <cr-profile-avatar-selector id="avatarSelector" avatars="[[availableIcons]]" selected-avatar="{{profileAvatar_}}" ignore-modified-key-events> </cr-profile-avatar-selector>
diff --git a/chrome/browser/resources/settings/people_page/manage_profile.js b/chrome/browser/resources/settings/people_page/manage_profile.js index cf752eda..731ac21e 100644 --- a/chrome/browser/resources/settings/people_page/manage_profile.js +++ b/chrome/browser/resources/settings/people_page/manage_profile.js
@@ -10,6 +10,7 @@ import 'chrome://resources/cr_elements/cr_input/cr_input.m.js'; import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js'; import 'chrome://resources/cr_elements/shared_style_css.m.js'; +import 'chrome://resources/cr_components/customize_themes/customize_themes.js'; import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; import 'chrome://resources/polymer/v3_0/paper-styles/shadow.js'; import '../settings_shared_css.m.js'; @@ -77,6 +78,15 @@ isProfileShortcutSettingVisible_: Boolean, /** + * True if the customize themes feature is enabled. + * @private + */ + isCustomizeThemesVisible_: { + type: Boolean, + value: () => loadTimeData.getBoolean('profileThemeSelectorEnabled') + }, + + /** * TODO(dpapad): Move this back to the HTML file when the Polymer2 version * of the code is deleted. Because of "\" being a special character in a JS * string, can't satisfy both Polymer2 and Polymer3 at the same time from
diff --git a/chrome/browser/resources/settings/settings_resources_v3.grdp b/chrome/browser/resources/settings/settings_resources_v3.grdp index f6cea43..ab5f774e 100644 --- a/chrome/browser/resources/settings/settings_resources_v3.grdp +++ b/chrome/browser/resources/settings/settings_resources_v3.grdp
@@ -4,858 +4,858 @@ <include name="IDR_SETTINGS_A11Y_PAGE_A11Y_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/a11y_page/a11y_page.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <if expr="not is_macosx and not chromeos"> <include name="IDR_SETTINGS_A11Y_PAGE_CAPTIONS_SUBPAGE_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/a11y_page/captions_subpage.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> </if> <if expr="is_win or is_macosx"> <include name="IDR_SETTINGS_A11Y_PAGE_CAPTIONS_BROWSER_PROXY_JS" file="a11y_page/captions_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> </if> <include name="IDR_SETTINGS_ABOUT_PAGE_ABOUT_PAGE_BROWSER_PROXY_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/about_page/about_page_browser_proxy.m.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_ABOUT_PAGE_ABOUT_PAGE_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/about_page/about_page.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_APPEARANCE_PAGE_APPEARANCE_BROWSER_PROXY_JS" file="appearance_page/appearance_browser_proxy.js" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_APPEARANCE_PAGE_APPEARANCE_FONTS_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_APPEARANCE_PAGE_APPEARANCE_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/appearance_page/appearance_page.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_APPEARANCE_PAGE_FONTS_BROWSER_PROXY_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/appearance_page/fonts_browser_proxy.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_APPEARANCE_PAGE_HOME_URL_INPUT_JS" file="${root_gen_dir}/chrome/browser/resources/settings/appearance_page/home_url_input.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_AUTOFILL_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/autofill_page.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_AVATAR_ICON_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/avatar_icon.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PAYMENTS_LIST_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/payments_list.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_CREDIT_CARD_LIST_ENTRY_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/credit_card_list_entry.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_UPI_ID_LIST_ENTRY_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/upi_id_list_entry.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORDS_SHARED_CSS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/passwords_shared_css.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_CREDIT_CARD_EDIT_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/credit_card_edit_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_AUTOFILL_SECTION_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/autofill_section.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_ADDRESS_EDIT_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/address_edit_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <if expr="chromeos"> <include name="IDR_SETTINGS_AUTOFILL_PAGE_BLOCKING_REQUEST_MANAGER_JS" file="autofill_page/blocking_request_manager.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> </if> <include name="IDR_SETTINGS_AUTOFILL_PAGE_MERGE_EXCEPTIONS_STORE_COPIES_BEHAVIOR_JS" file="autofill_page/merge_exceptions_store_copies_behavior.js" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_MERGE_PASSWORDS_STORE_COPIES_BEHAVIOR_JS" file="autofill_page/merge_passwords_store_copies_behavior.js" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_MULTI_STORE_EXCEPTION_ENTRY_JS" file="autofill_page/multi_store_exception_entry.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_MULTI_STORE_ID_HANDLER_JS" file="autofill_page/multi_store_id_handler.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_MULTI_STORE_PASSWORD_UI_ENTRY_JS" file="autofill_page/multi_store_password_ui_entry.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_CHECK_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_check.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_CHECK_BEHAVIOR_JS" file="autofill_page/password_check_behavior.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_CHECK_EDIT_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_CHECK_EDIT_DISCLAIMER_DIALOG_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_check_edit_disclaimer_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_CHECK_LIST_ITEM_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_check_list_item.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true"/> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_LIST_ITEM_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_list_item.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true"/> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORDS_LIST_HANDLER_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/passwords_list_handler.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true"/> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_MANAGER_PROXY_JS" file="autofill_page/password_manager_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_REMOVE_CONFIRMATION_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_remove_confirmation_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORDS_SECTION_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/passwords_section.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORDS_DEVICE_SECTION_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/passwords_device_section.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_EDIT_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_edit_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_move_to_account_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_REMOVE_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_remove_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORDS_EXPORT_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/passwords_export_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PAYMENTS_SECTION_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/payments_section.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_SHOW_PASSWORD_BEHAVIOR_JS" file="autofill_page/show_password_behavior.js" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_BASIC_PAGE_BASIC_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/basic_page/basic_page.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <if expr="is_win"> <include name="IDR_SETTINGS_CHROME_CLEANUP_PROXY_JS" file="chrome_cleanup_page/chrome_cleanup_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CHROME_CLEANUP_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_CHROME_CLEANUP_ITEMS_TO_REMOVE_LIST_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chrome_cleanup_page/items_to_remove_list.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> </if> <include name="IDR_SETTINGS_CLEAR_BROWSING_DATA_DIALOG_CLEAR_BROWSING_DATA_BROWSER_PROXY_M_JS" file="clear_browsing_data_dialog/clear_browsing_data_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CLEAR_BROWSING_DATA_DIALOG_CLEAR_BROWSING_DATA_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_CLEAR_BROWSING_DATA_DIALOG_HISTORY_DELETION_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CLEAR_BROWSING_DATA_DIALOG_INSTALLED_APP_CHECKBOX_JS" file="${root_gen_dir}/chrome/browser/resources/settings/clear_browsing_data_dialog/installed_app_checkbox.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CLEAR_BROWSING_DATA_DIALOG_PASSWORDS_DELETION_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/clear_browsing_data_dialog/passwords_deletion_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_CONTROLLED_BUTTON_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/controlled_button.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_CONTROLLED_RADIO_BUTTON_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/controlled_radio_button.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_EXTENSION_CONTROLLED_INDICATOR_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/extension_controlled_indicator.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_PASSWORD_PROMPT_DIALOG_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/password_prompt_dialog.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_SETTINGS_BOOLEAN_CONTROL_BEHAVIOR_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_SETTINGS_CHECKBOX_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/settings_checkbox.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_SETTINGS_DROPDOWN_MENU_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/settings_dropdown_menu.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_SETTINGS_IDLE_LOAD_JS" file="controls/settings_idle_load.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_PREF_CONTROL_BEHAVIOR_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/pref_control_behavior.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_SETTINGS_RADIO_GROUP_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/settings_radio_group.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_SETTINGS_SLIDER_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/settings_slider.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_SETTINGS_TEXTAREA_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/settings_textarea.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_SETTINGS_TOGGLE_BUTTON_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/settings_toggle_button.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <if expr="not chromeos"> <include name="IDR_SETTINGS_DEFAULT_BROWSER_BROWSER_PROXY_JS" file="default_browser_page/default_browser_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_DEFAULT_BROWSER_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/default_browser_page/default_browser_page.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> </if> <include name="IDR_SETTINGS_DOWNLOADS_PAGE_DOWNLOADS_BROWSER_PROXY_JS" file="downloads_page/downloads_browser_proxy.js" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_DOWNLOADS_PAGE_DOWNLOADS_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/downloads_page/downloads_page.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_ENSURE_LAZY_LOADED_JS" file="ensure_lazy_loaded.js" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_EXTENSION_CONTROL_BROWSER_PROXY_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/extension_control_browser_proxy.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_GLOBAL_SCROLL_TARGET_BEHAVIOR_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/global_scroll_target_behavior.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_HATS_BROWSER_PROXY_JS" file="hats_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_I18N_SETUP_JS" file="i18n_setup.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_ICONS_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/icons.m.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <if expr="is_win and _google_chrome"> <include name="IDR_SETTINGS_INCOMPATIBLE_APPLICATIONS_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/incompatible_applications_page/incompatible_applications_page.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_INCOMPATIBLE_APPLICATIONS_BROWSER_PROXY_JS" file="incompatible_applications_page/incompatible_applications_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_INCOMPATIBLE_APPLICATIONS_INCOMPATIBLE_APPLICATION_ITEM_JS" file="${root_gen_dir}/chrome/browser/resources/settings/incompatible_applications_page/incompatible_application_item.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> </if> <include name="IDR_SETTINGS_LANGUAGES_PAGE_LANGUAGES_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/languages_page/languages.m.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_LANGUAGES_PAGE_LANGUAGES_BROWSER_PROXY_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/languages_page/languages_browser_proxy.m.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_LANGUAGES_PAGE_ADD_LANGUAGES_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/languages_page/add_languages_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <if expr="chromeos"> <include name="IDR_SETTINGS_LANGUAGES_PAGE_LANGUAGES_METRICS_PROXY_JS" file="languages_page/languages_metrics_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> </if> <include name="IDR_SETTINGS_LANGUAGES_PAGE_LANGUAGES_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/languages_page/languages_page.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <if expr="not is_macosx"> <include name="IDR_SETTINGS_LANGUAGES_PAGE_EDIT_DICTIONARY_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> </if> <include name="IDR_SETTINGS_LAZY_LOAD_V3_JS" file="lazy_load.js" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_LIFETIME_BROWSER_PROXY_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/lifetime_browser_proxy.m.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_MENU_SETTINGS_MENU_JS" file="${root_gen_dir}/chrome/browser/resources/settings/settings_menu/settings_menu.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_METRICS_BROWSER_PROXY_JS" file="metrics_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_ON_STARTUP_PAGE_ON_STARTUP_BROWSER_PROXY_JS" file="on_startup_page/on_startup_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_ON_STARTUP_PAGE_ON_STARTUP_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/on_startup_page/on_startup_page.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_ON_STARTUP_PAGE_STARTUP_URL_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_ON_STARTUP_PAGE_STARTUP_URL_ENTRY_JS" file="${root_gen_dir}/chrome/browser/resources/settings/on_startup_page/startup_url_entry.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_ON_STARTUP_PAGE_STARTUP_URLS_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_ON_STARTUP_PAGE_STARTUP_URLS_PAGE_BROWSER_PROXY_JS" file="on_startup_page/startup_urls_page_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_OPEN_WINDOW_PROXY_JS" file="open_window_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PAGE_VISIBILITY_JS" file="page_visibility.js" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <if expr="not chromeos"> <include name="IDR_SETTINGS_PEOPLE_PAGE_IMPORT_DATA_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/people_page/import_data_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PEOPLE_PAGE_IMPORT_DATA_BROWSER_PROXY_JS" file="people_page/import_data_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PEOPLE_PAGE_MANAGE_PROFILE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/people_page/manage_profile.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PEOPLE_PAGE_MANAGE_PROFILE_BROWSER_PROXY_JS" file="people_page/manage_profile_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> </if> <if expr="chromeos"> <include name="IDR_SETTINGS_PEOPLE_PAGE_ACCOUNT_MANAGER_BROWSER_PROXY_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/people_page/account_manager_browser_proxy.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> </if> <include name="IDR_SETTINGS_PEOPLE_PAGE_SYNC_ACCOUNT_CONTROL_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/people_page/sync_account_control.m.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PEOPLE_PAGE_SYNC_BROWSER_PROXY_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/people_page/sync_browser_proxy.m.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_PEOPLE_PAGE_SYNC_ENCRYPTION_OPTIONS_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/people_page/sync_encryption_options.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PEOPLE_PAGE_PEOPLE_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/people_page/people_page.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PEOPLE_PAGE_PROFILE_INFO_BROWSER_PROXY_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/people_page/profile_info_browser_proxy.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PEOPLE_PAGE_SIGNOUT_DIALOG_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/people_page/signout_dialog.m.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PEOPLE_PAGE_SYNC_CONTROLS_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/people_page/sync_controls.m.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PEOPLE_PAGE_SYNC_PAGE_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/people_page/sync_page.m.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PREFS_PREFS_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/prefs/prefs.m.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PREFS_PREFS_BEHAVIOR_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/prefs/prefs_behavior.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PREFS_PREFS_TYPES_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/prefs/prefs_types.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PREFS_PREF_UTIL_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/prefs/pref_util.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRINTING_PAGE_CLOUD_PRINTERS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/printing_page/cloud_printers.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRINTING_PAGE_PRINTING_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/printing_page/printing_page.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_COLLAPSE_RADIO_BUTTON_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/collapse_radio_button.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_COOKIES_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/cookies_page.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_DO_NOT_TRACK_TOGGLE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/do_not_track_toggle.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_PRIVACY_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/privacy_page.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_PERSONALIZATION_OPTIONS_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/personalization_options.m.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_BROWSER_PROXY_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.m.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_SECURE_DNS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/secure_dns.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_SECURE_DNS_INPUT_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/secure_dns_input.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_SECURITY_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/security_page.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_DISABLE_SAFEBROWSING_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/disable_safebrowsing_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_SECURITY_KEYS_BIO_ENROLL_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_SECURITY_KEYS_BROWSER_PROXY_JS" file="privacy_page/security_keys_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_SECURITY_KEYS_PIN_FIELD_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_SECURITY_KEYS_RESET_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/security_keys_reset_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_SECURITY_KEYS_SET_PIN_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_SECURITY_KEYS_SUBPAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/security_keys_subpage.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_RESET_PAGE_RESET_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/reset_page/reset_page.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_RESET_PAGE_RESET_PROFILE_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_RESET_PAGE_RESET_PROFILE_BANNER_JS" file="${root_gen_dir}/chrome/browser/resources/settings/reset_page/reset_profile_banner.js" use_base_dir="false" - compress="false" type="BINDATA"/> + type="BINDATA"/> <include name="IDR_SETTINGS_RESET_PAGE_RESET_BROWSER_PROXY_JS" file="reset_page/reset_browser_proxy.js" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_ROUTE_JS" file="route.js" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_ROUTER_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/router.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_BROWSER_PROXY_JS" file="safety_check_page/safety_check_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_CHILD_JS" file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_child.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <if expr="is_win"> <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_CHROME_CLEANER_CHILD_JS" file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_chrome_cleaner_child.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> </if> <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_EXTENSIONS_CHILD_JS" file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_extensions_child.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_PAGE_JS" preprocess="true" file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_page.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_PASSWORDS_CHILD_JS" file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_SAFE_BROWSING_CHILD_JS" file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_safe_browsing_child.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_UPDATES_CHILD_JS" file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SEARCH_ENGINES_BROWSER_PROXY_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/search_engines_page/search_engines_browser_proxy.m.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_SEARCH_ENGINES_PAGE_OMNIBOX_EXTENSION_ENTRY_JS" file="${root_gen_dir}/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SEARCH_ENGINES_PAGE_SEARCH_ENGINE_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SEARCH_ENGINES_PAGE_SEARCH_ENGINE_ENTRY_CSS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/search_engines_page/search_engine_entry_css.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SEARCH_ENGINES_PAGE_SEARCH_ENGINE_ENTRY_JS" file="${root_gen_dir}/chrome/browser/resources/settings/search_engines_page/search_engine_entry.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SEARCH_ENGINES_PAGE_SEARCH_ENGINES_LIST_JS" file="${root_gen_dir}/chrome/browser/resources/settings/search_engines_page/search_engines_list.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SEARCH_ENGINES_PAGE_SEARCH_ENGINES_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/search_engines_page/search_engines_page.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SEARCH_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/search_page/search_page.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SEARCH_SETTINGS_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/search_settings.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SETTINGS_MAIN_SETTINGS_MAIN_JS" file="${root_gen_dir}/chrome/browser/resources/settings/settings_main/settings_main.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SETTINGS_PAGE_MAIN_PAGE_BEHAVIOR_JS" file="settings_page/main_page_behavior.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SETTINGS_PAGE_SETTINGS_ANIMATED_PAGES_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/settings_page/settings_animated_pages.m.js" use_base_dir="false" preprocess="true" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SETTINGS_PAGE_SETTINGS_SECTION_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/settings_page/settings_section.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SETTINGS_PAGE_SETTINGS_SUBPAGE_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/settings_page/settings_subpage.m.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_SETTINGS_UI_SETTINGS_UI_JS" file="${root_gen_dir}/chrome/browser/resources/settings/settings_ui/settings_ui.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_SETTING_ID_PARAM_UTIL_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/setting_id_param_util.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SETTINGS_ROUTES_JS" file="settings_routes.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SETTINGS_PAGE_CSS_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/settings_page_css.m.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SETTINGS_SHARED_CSS_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/settings_shared_css.m.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_SETTINGS_VARS_CSS_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/settings_vars_css.m.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_SETTINGS_V3_HTML" file="settings_v3.html" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SETTINGS_V3_JS" file="settings.js" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_SITE_FAVICON_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_favicon.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_ADD_SITE_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/add_site_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_ALL_SITES_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/all_sites.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_ALL_SITES_ICONS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/all_sites_icons.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <if expr="chromeos"> <include name="IDR_SETTINGS_SITE_SETTINGS_ANDROID_INFO_BROWSER_PROXY_JS" file="site_settings/android_info_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> </if> <include name="IDR_SETTINGS_SITE_SETTINGS_CATEGORY_DEFAULT_SETTING_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/category_default_setting.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_CATEGORY_SETTING_EXCEPTIONS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/category_setting_exceptions.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_CHOOSER_EXCEPTION_LIST_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/chooser_exception_list.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_CHOOSER_EXCEPTION_LIST_ENTRY_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/chooser_exception_list_entry.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_CLEAR_STORAGE_DIALOG_CSS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/clear_storage_dialog_css.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_CONSTANTS_JS" file="site_settings/constants.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_COOKIE_INFO_JS" file="site_settings/cookie_info.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_EDIT_EXCEPTION_DIALOG_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/edit_exception_dialog.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_LOCAL_DATA_BROWSER_PROXY_JS" file="site_settings/local_data_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_MEDIA_PICKER_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/media_picker.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_PDF_DOCUMENTS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/pdf_documents.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_PROTOCOL_HANDLERS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/protocol_handlers.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_SITE_SETTINGS_SETTINGS_CATEGORY_DEFAULT_RADIO_GROUP_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_SITE_DATA_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/site_data.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_SITE_DATA_DETAILS_SUBPAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_SITE_DATA_ENTRY_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/site_data_entry.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_SITE_DETAILS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/site_details.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_SITE_SETTINGS_SITE_DETAILS_PERMISSION_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/site_details_permission.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_SITE_ENTRY_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/site_entry.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_SITE_LIST_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/site_list.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_SITE_SETTINGS_SITE_LIST_ENTRY_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/site_list_entry.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_SITE_SETTINGS_SITE_SETTINGS_BEHAVIOR_JS" file="site_settings/site_settings_behavior.js" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_SITE_SETTINGS_SITE_SETTINGS_PREFS_BROWSER_PROXY_JS" file="site_settings/site_settings_prefs_browser_proxy.js" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <include name="IDR_SETTINGS_SITE_SETTINGS_WEBSITE_USAGE_BROWSER_PROXY_JS" file="site_settings/website_usage_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_ZOOM_LEVELS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings/zoom_levels.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_PAGE_RECENT_SITE_PERMISSIONS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_PAGE_SITE_SETTINGS_LIST_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings_page/site_settings_list.js" use_base_dir="false" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SITE_SETTINGS_PAGE_SITE_SETTINGS_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/site_settings_page/site_settings_page.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> <if expr="not chromeos"> <include name="IDR_SETTINGS_PRINTING_PAGE_PRINTING_BROWSER_PROXY_JS" file="printing_page/printing_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SYSTEM_PAGE_BROWSER_PROXY_JS" file="system_page/system_page_browser_proxy.js" - compress="false" type="BINDATA" /> + type="BINDATA" /> <include name="IDR_SETTINGS_SYSTEM_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/system_page/system_page.js" use_base_dir="false" - compress="false" type="BINDATA" + type="BINDATA" preprocess="true" /> </if> </grit-part>
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index f1a2ce5..bc66d15 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -2206,6 +2206,73 @@ DelayedWarningEvent::kWarningNotShown, 1); } +IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest, + KeyPress_ModifierKey_WarningNotShown) { + base::HistogramTester histograms; + NavigateAndAssertNoInterstitial(); + + // Press CTRL+A key. The interstitial should not be shown because we ignore + // the CTRL modifier unless it's CTRL+C or CTRL+V. + content::WebContents* contents = + browser()->tab_strip_model()->GetActiveWebContents(); + content::NativeWebKeyboardEvent event( + blink::WebKeyboardEvent::Type::kRawKeyDown, + blink::WebInputEvent::kControlKey, + blink::WebInputEvent::GetStaticTimeStampForTests()); + event.windows_key_code = ui::VKEY_A; + // Browser expects a non-synthesized event to have an os_event. Make the + // browser ignore this event instead. + event.skip_in_browser = true; + contents->GetRenderViewHost()->GetWidget()->ForwardKeyboardEvent(event); + AssertNoInterstitial(browser(), false); + + // Navigate to about:blank twice to "flush" metrics, if any. The delayed + // warning user interaction observer may not have been deleted after the first + // navigation. + ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); + + histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2); + histograms.ExpectBucketCount(kDelayedWarningsHistogram, + DelayedWarningEvent::kPageLoaded, 1); + histograms.ExpectBucketCount(kDelayedWarningsHistogram, + DelayedWarningEvent::kWarningNotShown, 1); +} + +IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest, + KeyPress_CtrlC_WarningShown) { + base::HistogramTester histograms; + NavigateAndAssertNoInterstitial(); + + // Press CTRL+C. The interstitial should be shown. + content::WebContents* contents = + browser()->tab_strip_model()->GetActiveWebContents(); + content::TestNavigationObserver observer(contents); + + content::NativeWebKeyboardEvent event( + blink::WebKeyboardEvent::Type::kRawKeyDown, + blink::WebInputEvent::kControlKey, + blink::WebInputEvent::GetStaticTimeStampForTests()); + event.windows_key_code = ui::VKEY_C; + event.native_key_code = ui::VKEY_C; + // We don't set event.skip_in_browser = true here because the event will be + // consumed by UserInteractionObserver and not passed to the browser. + contents->GetRenderViewHost()->GetWidget()->ForwardKeyboardEvent(event); + + observer.WaitForNavigationFinished(); + EXPECT_TRUE(WaitForReady(browser())); + + EXPECT_TRUE(ClickAndWaitForDetach(browser(), "primary-button")); + AssertNoInterstitial(browser(), false); // Assert the interstitial is gone + EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank" + browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); + + histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2); + histograms.ExpectBucketCount(kDelayedWarningsHistogram, + DelayedWarningEvent::kPageLoaded, 1); + histograms.ExpectBucketCount(kDelayedWarningsHistogram, + DelayedWarningEvent::kWarningShownOnKeypress, 1); +} + // Similar to KeyPress_ESC_WarningNotShown, but a character key is pressed after // ESC. The warning should be shown. IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest,
diff --git a/chrome/browser/safe_browsing/user_interaction_observer.cc b/chrome/browser/safe_browsing/user_interaction_observer.cc index d773ac3..7e91b01 100644 --- a/chrome/browser/safe_browsing/user_interaction_observer.cc +++ b/chrome/browser/safe_browsing/user_interaction_observer.cc
@@ -16,11 +16,14 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "third_party/blink/public/common/input/web_mouse_event.h" +#include "ui/events/keycodes/keyboard_codes.h" #if BUILDFLAG(ENABLE_EXTENSIONS) #include "extensions/browser/extension_registry.h" #endif // BUILDFLAG(ENABLE_EXTENSIONS) +using blink::WebInputEvent; + namespace { // Id for extension that enables users to report sites to Safe Browsing. const char kPreventElisionExtensionId[] = "jknemblkbdhdcpllfgbfekkdciegfboi"; @@ -303,11 +306,29 @@ } } +bool IsAllowedModifier(const content::NativeWebKeyboardEvent& event) { + const int key_modifiers = + event.GetModifiers() & blink::WebInputEvent::kKeyModifiers; + // If the only modifier is shift, the user may be typing uppercase + // letters. + if (key_modifiers == WebInputEvent::kShiftKey) { + return event.windows_key_code == ui::VKEY_SHIFT; + } + // Disallow CTRL+C and CTRL+V. + if (key_modifiers == WebInputEvent::kControlKey && + (event.windows_key_code == ui::VKEY_C || + event.windows_key_code == ui::VKEY_V)) { + return false; + } + return key_modifiers != 0; +} + bool SafeBrowsingUserInteractionObserver::HandleKeyPress( const content::NativeWebKeyboardEvent& event) { // Allow non-character keys such as ESC. These can be used to exit fullscreen, // for example. - if (!event.IsCharacterKey()) { + if (!event.IsCharacterKey() || event.is_browser_shortcut || + IsAllowedModifier(event)) { return false; } ShowInterstitial(DelayedWarningEvent::kWarningShownOnKeypress);
diff --git a/chrome/browser/service_sandbox_type.h b/chrome/browser/service_sandbox_type.h index 5d39f28e..1fb384b 100644 --- a/chrome/browser/service_sandbox_type.h +++ b/chrome/browser/service_sandbox_type.h
@@ -7,12 +7,9 @@ #include "build/build_config.h" #include "content/public/browser/service_process_host.h" +#include "media/base/media_switches.h" #include "sandbox/policy/sandbox_type.h" -#if !defined(OS_ANDROID) -#include "chrome/services/speech/buildflags.h" -#endif // !defined(OS_ANDROID) - // This file maps service classes to sandbox types. Services which // require a non-utility sandbox can be added here. See // ServiceProcessHost::Launch() for how these templates are consumed. @@ -79,7 +76,6 @@ // media::mojom::SpeechRecognitionService #if !defined(OS_ANDROID) -#if BUILDFLAG(ENABLE_SODA) namespace media { namespace mojom { class SpeechRecognitionService; @@ -89,9 +85,12 @@ template <> inline sandbox::policy::SandboxType content::GetServiceSandboxType<media::mojom::SpeechRecognitionService>() { - return sandbox::policy::SandboxType::kSpeechRecognition; + if (base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption)) { + return sandbox::policy::SandboxType::kSpeechRecognition; + } else { + return sandbox::policy::SandboxType::kUtility; + } } -#endif // BUILDFLAG(ENABLE_SODA) #endif // !defined(OS_ANDROID) // printing::mojom::PrintingService
diff --git a/chrome/browser/speech/speech_recognition_service.cc b/chrome/browser/speech/speech_recognition_service.cc index acc8a787..0802bf7 100644 --- a/chrome/browser/speech/speech_recognition_service.cc +++ b/chrome/browser/speech/speech_recognition_service.cc
@@ -22,9 +22,9 @@ SpeechRecognitionService::SpeechRecognitionService( content::BrowserContext* context) - : context_(context) -{ -} + : context_(context), + enable_soda_( + base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption)) {} SpeechRecognitionService::~SpeechRecognitionService() = default; @@ -35,24 +35,26 @@ } void SpeechRecognitionService::OnNetworkServiceDisconnect() { -#if !BUILDFLAG(ENABLE_SODA) - // If the Speech On-Device API is not enabled, pass the URL loader factory to - // the speech recognition service to allow network requests to the Open Speech - // API. - mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory; - network::mojom::URLLoaderFactoryParamsPtr params = - network::mojom::URLLoaderFactoryParams::New(); - params->process_id = network::mojom::kBrowserProcessId; - params->is_trusted = false; - params->automatically_assign_isolation_info = true; - network::mojom::NetworkContext* network_context = - content::BrowserContext::GetDefaultStoragePartition(context_) - ->GetNetworkContext(); - network_context->CreateURLLoaderFactory( - url_loader_factory.InitWithNewPipeAndPassReceiver(), std::move(params)); - speech_recognition_service_->SetUrlLoaderFactory( - std::move(url_loader_factory)); -#endif // !BUILDFLAG(ENABLE_SODA) + if (!enable_soda_) { + // If the Speech On-Device API + // is not enabled, pass the URL + // loader factory to + // the speech recognition service to allow network requests to the Open + // Speech API. + mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory; + network::mojom::URLLoaderFactoryParamsPtr params = + network::mojom::URLLoaderFactoryParams::New(); + params->process_id = network::mojom::kBrowserProcessId; + params->is_trusted = false; + params->automatically_assign_isolation_info = true; + network::mojom::NetworkContext* network_context = + content::BrowserContext::GetDefaultStoragePartition(context_) + ->GetNetworkContext(); + network_context->CreateURLLoaderFactory( + url_loader_factory.InitWithNewPipeAndPassReceiver(), std::move(params)); + speech_recognition_service_->SetUrlLoaderFactory( + std::move(url_loader_factory)); + } } void SpeechRecognitionService::LaunchIfNotRunning() { @@ -61,20 +63,22 @@ PrefService* prefs = user_prefs::UserPrefs::Get(context_); DCHECK(prefs); -#if BUILDFLAG(ENABLE_SODA) - auto binary_path = prefs->GetFilePath(prefs::kSodaBinaryPath); - auto config_path = SpeechRecognitionService::GetSodaConfigPath(prefs); - if (binary_path.empty() || config_path.empty()) { - LOG(ERROR) << "Unable to find SODA files on the device."; - return; - } -#endif - content::ServiceProcessHost::Launch( - speech_recognition_service_.BindNewPipeAndPassReceiver(), - content::ServiceProcessHost::Options() - .WithDisplayName(IDS_UTILITY_PROCESS_SPEECH_RECOGNITION_SERVICE_NAME) - .Pass()); + if (enable_soda_) { + content::ServiceProcessHost::Launch( + speech_recognition_service_.BindNewPipeAndPassReceiver(), + content::ServiceProcessHost::Options() + .WithDisplayName( + IDS_UTILITY_PROCESS_SPEECH_RECOGNITION_SERVICE_NAME) + .Pass()); + } else { + content::ServiceProcessHost::Launch( + speech_recognition_service_.BindNewPipeAndPassReceiver(), + content::ServiceProcessHost::Options() + .WithDisplayName( + IDS_UTILITY_PROCESS_SPEECH_RECOGNITION_SERVICE_NAME) + .Pass()); + } // Ensure that if the interface is ever disconnected (e.g. the service // process crashes) or goes idle for a short period of time -- meaning there @@ -85,9 +89,17 @@ speech_recognition_service_.reset_on_idle_timeout(kIdleProcessTimeout); speech_recognition_service_client_.reset(); -#if BUILDFLAG(ENABLE_SODA) - speech_recognition_service_->SetSodaPath(binary_path, config_path); -#endif + + if (enable_soda_) { + auto binary_path = prefs->GetFilePath(prefs::kSodaBinaryPath); + auto config_path = SpeechRecognitionService::GetSodaConfigPath(prefs); + if (binary_path.empty() || config_path.empty()) { + LOG(ERROR) << "Unable to find SODA files on the device."; + return; + } + speech_recognition_service_->SetSodaPath(binary_path, config_path); + } + speech_recognition_service_->BindSpeechRecognitionServiceClient( speech_recognition_service_client_.BindNewPipeAndPassRemote()); OnNetworkServiceDisconnect();
diff --git a/chrome/browser/speech/speech_recognition_service.h b/chrome/browser/speech/speech_recognition_service.h index 54a11357..41ad6beb 100644 --- a/chrome/browser/speech/speech_recognition_service.h +++ b/chrome/browser/speech/speech_recognition_service.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_SERVICE_H_ #define CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_SERVICE_H_ -#include "chrome/services/speech/buildflags.h" #include "components/keyed_service/core/keyed_service.h" #include "media/mojo/mojom/speech_recognition_service.mojom.h" #include "mojo/public/cpp/bindings/remote.h" @@ -46,6 +45,10 @@ // The browser context associated with the keyed service. content::BrowserContext* const context_; + // A flag indicating whether to use the Speech On-Device API (SODA) for speech + // recognition. + bool enable_soda_ = false; + // The remote to the speech recognition service. The browser will not launch a // new speech recognition service process if this remote is already bound. mojo::Remote<media::mojom::SpeechRecognitionService>
diff --git a/chrome/browser/ssl/sct_reporting_service.cc b/chrome/browser/ssl/sct_reporting_service.cc index 88e0b18..4aa5e7c3 100644 --- a/chrome/browser/ssl/sct_reporting_service.cc +++ b/chrome/browser/ssl/sct_reporting_service.cc
@@ -4,14 +4,80 @@ #include "chrome/browser/ssl/sct_reporting_service.h" +#include "base/no_destructor.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include "chrome/common/chrome_features.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "content/public/browser/network_service_instance.h" #include "content/public/browser/storage_partition.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "services/network/public/mojom/network_context.mojom.h" #include "services/network/public/mojom/network_service.mojom.h" +constexpr net::NetworkTrafficAnnotationTag kSCTAuditReportTrafficAnnotation = + net::DefineNetworkTrafficAnnotation("sct_auditing", R"( + semantics { + sender: "Safe Browsing" + description: + "When a user connects to a site, opted-in clients may upload " + "a report about the Signed Certificate Timestamps used for meeting " + "Chrome's Certificate Transparency Policy to Safe Browsing to " + "detect misbehaving Certificate Transparency logs. This helps " + "improve the security and trustworthiness of the HTTPS ecosystem." + trigger: + "The browser will upload a report to Google when a connection to a " + "website includes Signed Certificate Timestamps, and the user is " + "opted in to extended reporting." + data: + "The time of the request, the hostname and port being requested, " + "the certificate chain, and the Signed Certificate Timestamps " + "observed on the connection." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: NO + setting: + "Users can enable or disable this feature by enabling or disabling " + "'Enhanced Protection' in Chrome's settings under Security, " + "Safe Browsing, or by enabling or disabling 'Help improve security " + "on the web for everyone' under 'Standard Protection' in Chrome's " + "settings under Security, Safe Browsing. The feature is disabled " + "by default." + chrome_policy { + SafeBrowsingExtendedReportingEnabled { + policy_options {mode: MANDATORY} + SafeBrowsingExtendedReportingEnabled: false + } + } + })"); + +constexpr char kSBSCTAuditingReportURL[] = + "https://safebrowsing.google.com/safebrowsing/clientreport/" + "chrome-sct-auditing"; + +// static +GURL& SCTReportingService::GetReportURLInstance() { + static base::NoDestructor<GURL> instance(kSBSCTAuditingReportURL); + return *instance; +} + +// static +void SCTReportingService::ReconfigureAfterNetworkRestart() { + bool is_sct_auditing_enabled = + base::FeatureList::IsEnabled(features::kSCTAuditing); + double sct_sampling_rate = features::kSCTAuditingSamplingRate.Get(); + mojo::PendingRemote<network::mojom::URLLoaderFactory> factory_client; + SystemNetworkContextManager::GetInstance()->GetURLLoaderFactory()->Clone( + factory_client.InitWithNewPipeAndPassReceiver()); + content::GetNetworkService()->ConfigureSCTAuditing( + is_sct_auditing_enabled, sct_sampling_rate, + SCTReportingService::GetReportURLInstance(), + net::MutableNetworkTrafficAnnotationTag(kSCTAuditReportTrafficAnnotation), + std::move(factory_client)); +} + SCTReportingService::SCTReportingService( safe_browsing::SafeBrowsingService* safe_browsing_service, Profile* profile) @@ -20,6 +86,11 @@ profile_(profile) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // SCT auditing should stay disabled for Incognito/OTR profiles, so we don't + // need to subscribe to the prefs. + if (profile_->IsOffTheRecord()) + return; + // Subscribe to SafeBrowsing preference change notifications. The initial Safe // Browsing state gets emitted to subscribers during Profile creation. safe_browsing_state_subscription_ = @@ -54,18 +125,3 @@ safe_browsing::IsExtendedReportingEnabled(pref_service_); SetReportingEnabled(enabled); } - -void SCTReportingService::OnSCTReportReady(const std::string& cache_key) { - for (TestObserver& observer : test_observers_) - observer.OnSCTReportReady(cache_key); - // TODO(crbug.com/1082860): Send the report using the Safe Browsing network - // context. -} - -void SCTReportingService::AddObserverForTesting(TestObserver* observer) { - test_observers_.AddObserver(observer); -} - -void SCTReportingService::RemoveObserverForTesting(TestObserver* observer) { - test_observers_.RemoveObserver(observer); -}
diff --git a/chrome/browser/ssl/sct_reporting_service.h b/chrome/browser/ssl/sct_reporting_service.h index 51df48e..c260c12b 100644 --- a/chrome/browser/ssl/sct_reporting_service.h +++ b/chrome/browser/ssl/sct_reporting_service.h
@@ -6,9 +6,11 @@ #define CHROME_BROWSER_SSL_SCT_REPORTING_SERVICE_H_ #include "base/callback_list.h" +#include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/observer_list_types.h" #include "components/keyed_service/core/keyed_service.h" +#include "url/gurl.h" class PrefService; class Profile; @@ -19,15 +21,12 @@ // This class observes SafeBrowsing preference changes to enable/disable // reporting. It does this by subscribing to changes in SafeBrowsing and -// extended reporting preferences. It also receives notifications about new -// audit reports added to the SCT auditing cache and handles routing them to -// the correct NetworkContext for sending. +// extended reporting preferences. It also handles configuring SCT auditing in +// the network service. class SCTReportingService : public KeyedService { public: - class TestObserver : public base::CheckedObserver { - public: - virtual void OnSCTReportReady(const std::string& cache_key) = 0; - }; + static GURL& GetReportURLInstance(); + static void ReconfigureAfterNetworkRestart(); SCTReportingService(safe_browsing::SafeBrowsingService* safe_browsing_service, Profile* profile); @@ -39,13 +38,6 @@ // Enables or disables reporting. void SetReportingEnabled(bool enabled); - // Receives notification about a new entry being added to the network - // service's SCT auditing cache under the key `cache_key`. - void OnSCTReportReady(const std::string& cache_key); - - void AddObserverForTesting(TestObserver* observer); - void RemoveObserverForTesting(TestObserver* observer); - private: void OnPreferenceChanged(); @@ -54,8 +46,6 @@ Profile* profile_; std::unique_ptr<base::CallbackList<void(void)>::Subscription> safe_browsing_state_subscription_; - - base::ObserverList<TestObserver> test_observers_; }; #endif // CHROME_BROWSER_SSL_SCT_REPORTING_SERVICE_H_
diff --git a/chrome/browser/ssl/sct_reporting_service_browsertest.cc b/chrome/browser/ssl/sct_reporting_service_browsertest.cc index 22c44ca1..2909e22 100644 --- a/chrome/browser/ssl/sct_reporting_service_browsertest.cc +++ b/chrome/browser/ssl/sct_reporting_service_browsertest.cc
@@ -3,52 +3,90 @@ // found in the LICENSE file. #include "base/test/scoped_feature_list.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/sct_reporting_service.h" #include "chrome/browser/ssl/sct_reporting_service_factory.h" #include "chrome/browser/ui/browser.h" +#include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/network_service_instance.h" #include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/network_service_test_helper.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" -#include "services/network/public/cpp/features.h" +#include "net/test/embedded_test_server/embedded_test_server_connection_listener.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "services/network/test/test_url_loader_factory.h" -// Observer that tracks SCT audit reports that the SCTReportingService has seen. -class CacheNotifyObserver : public SCTReportingService::TestObserver { +namespace { + +class ConnectionListener + : public net::test_server::EmbeddedTestServerConnectionListener { public: - CacheNotifyObserver() = default; - ~CacheNotifyObserver() override = default; - CacheNotifyObserver(const CacheNotifyObserver&) = delete; - CacheNotifyObserver& operator=(const CacheNotifyObserver&) = delete; + ConnectionListener() = default; + ~ConnectionListener() override = default; - // SCTReportingService::TestObserver: - void OnSCTReportReady(const std::string& cache_key) override { - cache_entries_seen_.push_back(cache_key); + ConnectionListener(const ConnectionListener&) = delete; + ConnectionListener& operator=(const ConnectionListener&) = delete; + + // EmbeddedTestServerConnectionListener overrides: + std::unique_ptr<net::StreamSocket> AcceptedSocket( + std::unique_ptr<net::StreamSocket> socket) override { + ++connections_seen_; + if (!quit_closure_.is_null() && + connections_seen_ >= connections_expected_) { + std::move(quit_closure_).Run(); + } + return socket; + } + void ReadFromSocket(const net::StreamSocket& socket, int rv) override {} + void OnResponseCompletedSuccessfully( + std::unique_ptr<net::StreamSocket> socket) override {} + + void WaitForConnections(size_t num_connections) { + if (connections_seen_ >= connections_expected_) + return; + + connections_expected_ = num_connections; + + base::RunLoop run_loop; + quit_closure_ = run_loop.QuitClosure(); + run_loop.Run(); } - const std::vector<std::string>& cache_entries_seen() const { - return cache_entries_seen_; - } + size_t connections_seen() const { return connections_seen_; } private: - std::vector<std::string> cache_entries_seen_; + size_t connections_seen_ = 0; + size_t connections_expected_ = 0; + base::OnceClosure quit_closure_; }; +} // namespace + class SCTReportingServiceBrowserTest : public InProcessBrowserTest { public: SCTReportingServiceBrowserTest() { // Set sampling rate to 1.0 to ensure deterministic behavior. scoped_feature_list_.InitWithFeaturesAndParameters( - {{network::features::kSCTAuditing, - {{network::features::kSCTAuditingSamplingRate.name, "1.0"}}}}, + {{features::kSCTAuditing, + {{features::kSCTAuditingSamplingRate.name, "1.0"}}}}, {}); SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( true); + // We have to initialize the report_server here so we can set the reporting + // URL before the network service is initialized. + ignore_result(report_server()->InitializeAndListen()); + SCTReportingService::GetReportURLInstance() = + report_server()->GetURL("/echo?status=200"); } ~SCTReportingServiceBrowserTest() override { SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( @@ -64,16 +102,18 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); host_resolver()->AddRule("*", "127.0.0.1"); https_server_.AddDefaultHandlers(GetChromeTestDataDir()); + report_server_.AddDefaultHandlers(GetChromeTestDataDir()); + + connection_listener_ = std::make_unique<ConnectionListener>(); + report_server()->SetConnectionListener(connection_listener_.get()); + report_server()->StartAcceptingConnections(); + ASSERT_TRUE(https_server_.Start()); InProcessBrowserTest::SetUpOnMainThread(); } protected: - SCTReportingServiceFactory* factory() { - return SCTReportingServiceFactory::GetInstance(); - } - void SetExtendedReportingEnabled(bool enabled) { browser()->profile()->GetPrefs()->SetBoolean( prefs::kSafeBrowsingScoutReportingEnabled, enabled); @@ -89,95 +129,80 @@ } net::EmbeddedTestServer* https_server() { return &https_server_; } + net::EmbeddedTestServer* report_server() { return &report_server_; } + ConnectionListener* connection_listener() { + return connection_listener_.get(); + } private: net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS}; + net::EmbeddedTestServer report_server_; base::test::ScopedFeatureList scoped_feature_list_; + std::unique_ptr<ConnectionListener> connection_listener_; }; -// Tests that reports should not be enqueued when extended reporting is not -// opted in. +// Tests that reports should not be sent when extended reporting is not opted +// in. IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest, NotOptedIn_ShouldNotEnqueueReport) { SetExtendedReportingEnabled(false); - // Add an observer to track reports that get sent to the embedder. - CacheNotifyObserver observer; - service()->AddObserverForTesting(&observer); - // Visit an HTTPS page. ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); - // Check that no reports are enqueued. - EXPECT_EQ(0u, observer.cache_entries_seen().size()); + // Check that no reports are sent. + EXPECT_EQ(0u, connection_listener()->connections_seen()); // TODO(crbug.com/1107897): Check histograms once they are added. } -// Tests that reports should be enqueued when extended reporting is opted in. +// Tests that reports should be sent when extended reporting is opted in. IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest, OptedIn_ShouldEnqueueReport) { - // SetSafeBrowsingEnabled(true); SetExtendedReportingEnabled(true); - // Add an observer to track reports that get sent to the embedder. - CacheNotifyObserver observer; - service()->AddObserverForTesting(&observer); - - // Visit an HTTPS page. + // Visit an HTTPS page and wait for the report to be sent. ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); + connection_listener()->WaitForConnections(1); - // Check that one report was enqueued. - EXPECT_EQ(1u, observer.cache_entries_seen().size()); + // Check that one report was sent. + EXPECT_EQ(1u, connection_listener()->connections_seen()); } -// Tests that disabling SafeBrowsing entirely should cause reports to not get -// enqueued. +// Tests that disabling Safe Browsing entirely should cause reports to not get +// sent. IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest, DisableSafebrowsing) { SetSafeBrowsingEnabled(false); - CacheNotifyObserver observer; - service()->AddObserverForTesting(&observer); - ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); - EXPECT_EQ(0u, observer.cache_entries_seen().size()); + EXPECT_EQ(0u, connection_listener()->connections_seen()); } -// Tests that we don't enqueue a report for a navigation with a cert error. +// Tests that we don't send a report for a navigation with a cert error. IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest, CertErrorDoesNotEnqueueReport) { SetExtendedReportingEnabled(true); - CacheNotifyObserver observer; - service()->AddObserverForTesting(&observer); - // Visit a page with an invalid cert. ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("invalid.test", "/")); - EXPECT_EQ(0u, observer.cache_entries_seen().size()); + EXPECT_EQ(0u, connection_listener()->connections_seen()); } -// Tests that reports aren't enqueued for Incognito windows. +// Tests that reports aren't sent for Incognito windows. IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest, IncognitoWindow_ShouldNotEnqueueReport) { // Enable SBER in the main profile. SetExtendedReportingEnabled(true); - // Create a new Incognito window and try to enable SBER in it. + // Create a new Incognito window. auto* incognito = CreateIncognitoBrowser(); - incognito->profile()->GetPrefs()->SetBoolean( - prefs::kSafeBrowsingScoutReportingEnabled, true); - - auto* service = - SCTReportingServiceFactory::GetForBrowserContext(incognito->profile()); - CacheNotifyObserver observer; - service->AddObserverForTesting(&observer); ui_test_utils::NavigateToURL(incognito, https_server()->GetURL("/")); - EXPECT_EQ(0u, observer.cache_entries_seen().size()); + EXPECT_EQ(0u, connection_listener()->connections_seen()); } // Tests that disabling Extended Reporting causes the cache to be cleared. @@ -186,25 +211,39 @@ // Enable SCT auditing and enqueue a report. SetExtendedReportingEnabled(true); - // Add an observer to track reports that get sent to the embedder. - CacheNotifyObserver observer; - service()->AddObserverForTesting(&observer); - - // Visit an HTTPS page. + // Visit an HTTPS page and wait for a report to be sent. ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); + connection_listener()->WaitForConnections(1); - // Check that one report was enqueued. - EXPECT_EQ(1u, observer.cache_entries_seen().size()); + // Check that one report was sent. + EXPECT_EQ(1u, connection_listener()->connections_seen()); // Disable Extended Reporting which should clear the underlying cache. SetExtendedReportingEnabled(false); // We can check that the same report gets cached again instead of being - // deduplicated (i.e., the observer should see another cache entry - // notification). + // deduplicated (i.e., another report should be sent). SetExtendedReportingEnabled(true); ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); - EXPECT_EQ(2u, observer.cache_entries_seen().size()); + connection_listener()->WaitForConnections(2); + EXPECT_EQ(2u, connection_listener()->connections_seen()); +} + +// Tests that reports are still sent for opted-in profiles after the network +// service crashes and is restarted. +IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest, + ReportsSentAfterNetworkServiceRestart) { + SetExtendedReportingEnabled(true); + + // Crash the NetworkService to force it to restart. + SimulateNetworkServiceCrash(); + + // Visit an HTTPS page and wait for the report to be sent. + ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); + connection_listener()->WaitForConnections(1); + + // Check that one report was enqueued. + EXPECT_EQ(1u, connection_listener()->connections_seen()); } // TODO(crbug.com/1107975): Add test for "invalid SCTs should not get reported". @@ -216,8 +255,8 @@ public: SCTReportingServiceZeroSamplingRateBrowserTest() { scoped_feature_list_.InitWithFeaturesAndParameters( - {{network::features::kSCTAuditing, - {{network::features::kSCTAuditingSamplingRate.name, "0.0"}}}}, + {{features::kSCTAuditing, + {{features::kSCTAuditingSamplingRate.name, "0.0"}}}}, {}); SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( true); @@ -241,13 +280,9 @@ EmbedderNotNotified) { SetExtendedReportingEnabled(true); - // Add an observer to track reports that get sent to the embedder. - CacheNotifyObserver observer; - service()->AddObserverForTesting(&observer); - // Visit an HTTPS page. ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/")); // Check that no reports are observed. - EXPECT_EQ(0u, observer.cache_entries_seen().size()); + EXPECT_EQ(0u, connection_listener()->connections_seen()); }
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_client_impl.cc b/chrome/browser/ui/ash/holding_space/holding_space_client_impl.cc index 8ef1a67..d19a647 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_client_impl.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_client_impl.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/chromeos/file_manager/app_id.h" #include "chrome/browser/chromeos/file_manager/fileapi_util.h" #include "chrome/browser/chromeos/file_manager/open_util.h" +#include "chrome/browser/chromeos/file_manager/path_util.h" #include "chrome/browser/ui/ash/clipboard_util.h" #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h" #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.h" @@ -69,6 +70,23 @@ std::move(callback))); } +void HoldingSpaceClientImpl::OpenDownloads(SuccessCallback callback) { + auto file_path = file_manager::util::GetDownloadsFolderForProfile(profile_); + if (file_path.empty()) { + std::move(callback).Run(/*success=*/false); + return; + } + file_manager::util::OpenItem( + profile_, file_path, platform_util::OPEN_FOLDER, + base::BindOnce( + [](SuccessCallback callback, + platform_util::OpenOperationResult result) { + const bool success = result == platform_util::OPEN_SUCCEEDED; + std::move(callback).Run(success); + }, + std::move(callback))); +} + void HoldingSpaceClientImpl::OpenItem(const HoldingSpaceItem& item, SuccessCallback callback) { if (item.file_path().empty()) {
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_client_impl.h b/chrome/browser/ui/ash/holding_space/holding_space_client_impl.h index 1dcb6c5cd..b217518 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_client_impl.h +++ b/chrome/browser/ui/ash/holding_space/holding_space_client_impl.h
@@ -24,6 +24,7 @@ // HoldingSpaceClient: void AddScreenshot(const base::FilePath& file_path) override; void CopyImageToClipboard(const HoldingSpaceItem&, SuccessCallback) override; + void OpenDownloads(SuccessCallback callback) override; void OpenItem(const HoldingSpaceItem&, SuccessCallback) override; void ShowItemInFolder(const HoldingSpaceItem&, SuccessCallback) override; void PinItem(const HoldingSpaceItem& item) override;
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc b/chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc index e0b41d3..fb51f354 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc
@@ -100,6 +100,23 @@ } } +// Verifies that `HoldingSpaceClient::OpenDownloads()` works as intended. +IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, OpenDownloads) { + ASSERT_TRUE(HoldingSpaceController::Get()); + + auto* holding_space_client = HoldingSpaceController::Get()->client(); + ASSERT_TRUE(holding_space_client); + + // We expect `HoldingSpaceClient::OpenDownloads()` to succeed. + base::RunLoop run_loop; + holding_space_client->OpenDownloads( + base::BindLambdaForTesting([&run_loop](bool success) { + EXPECT_TRUE(success); + run_loop.Quit(); + })); + run_loop.Run(); +} + // Verifies that `HoldingSpaceClient::OpenItem()` works as intended when // attempting to open holding space items backed by both non-existing and // existing files.
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc index 5665819..e163cd5 100644 --- a/chrome/browser/ui/ui_features.cc +++ b/chrome/browser/ui/ui_features.cc
@@ -42,6 +42,11 @@ const base::Feature kPermissionChip{"PermissionChip", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables the theme selector in the manage profile settings. +// https://crbug.com/1129186 +const base::Feature kProfileThemeSelectorInSettings{ + "ProfileThemeSelectorInSettings", base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables a more prominent active tab title in dark mode to aid with // accessibility. const base::Feature kProminentDarkModeActiveTabTitle{
diff --git a/chrome/browser/ui/ui_features.h b/chrome/browser/ui/ui_features.h index a167fbb..4c9d8500 100644 --- a/chrome/browser/ui/ui_features.h +++ b/chrome/browser/ui/ui_features.h
@@ -34,6 +34,8 @@ extern const base::Feature kPermissionChip; +extern const base::Feature kProfileThemeSelectorInSettings; + extern const base::Feature kProminentDarkModeActiveTabTitle; extern const base::Feature kReadLater;
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc index a7f6b38..fae120b 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -579,7 +579,7 @@ if (store_indicator_icon) { AddSpacerWithSize(GetHorizontalMargin(), /*resize=*/true, layout_manager); - AddChildView(std::move(icon)); + AddChildView(std::move(store_indicator_icon)); } }
diff --git a/chrome/browser/ui/views/certificate_viewer_mac_views.mm b/chrome/browser/ui/views/certificate_viewer_mac_views.mm index 60192b9..0284395 100644 --- a/chrome/browser/ui/views/certificate_viewer_mac_views.mm +++ b/chrome/browser/ui/views/certificate_viewer_mac_views.mm
@@ -2,124 +2,27 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import <Cocoa/Cocoa.h> -#import <SecurityInterface/SFCertificatePanel.h> - -#include "base/mac/foundation_util.h" -#include "base/mac/scoped_cftyperef.h" -#import "base/mac/scoped_nsobject.h" -#include "base/notreached.h" #include "chrome/browser/certificate_viewer.h" + +#include "base/logging.h" #include "components/remote_cocoa/browser/window.h" -#include "net/cert/x509_certificate.h" -#include "net/cert/x509_util_ios_and_mac.h" -#include "net/cert/x509_util_mac.h" - -@interface SSLCertificateViewerMac : NSObject -// Initializes |certificates_| with the certificate chain for a given -// certificate. -- (instancetype)initWithCertificate:(net::X509Certificate*)certificate; - -// Shows the certificate viewer as a Cocoa sheet. -- (void)showCertificateSheet:(NSWindow*)window; - -// Called when the certificate viewer Cocoa sheet is closed. -- (void)sheetDidEnd:(NSWindow*)parent - returnCode:(NSInteger)returnCode - context:(void*)context; -@end - -@implementation SSLCertificateViewerMac { - base::scoped_nsobject<NSArray> _certificates; - base::scoped_nsobject<SFCertificatePanel> _panel; - NSWindow* _remoteViewsCloneWindow; -} - -- (instancetype)initWithCertificate:(net::X509Certificate*)certificate { - if ((self = [super init])) { - base::ScopedCFTypeRef<CFArrayRef> certChain( - net::x509_util::CreateSecCertificateArrayForX509Certificate( - certificate)); - if (!certChain) - return self; - NSArray* certificates = base::mac::CFToNSCast(certChain.get()); - _certificates.reset([certificates retain]); - } - - // Explicitly disable revocation checking, regardless of user preferences - // or system settings. The behaviour of SFCertificatePanel is to call - // SecTrustEvaluate on the certificate(s) supplied, effectively - // duplicating the behaviour of net::X509Certificate::Verify(). However, - // this call stalls the UI if revocation checking is enabled in the - // Keychain preferences or if the cert may be an EV cert. By disabling - // revocation checking, the stall is limited to the time taken for path - // building and verification, which should be minimized due to the path - // being provided in |certificates|. This does not affect normal - // revocation checking from happening, which is controlled by - // net::X509Certificate::Verify() and user preferences, but will prevent - // the certificate viewer UI from displaying which certificate is revoked. - // This is acceptable, as certificate revocation will still be shown in - // the page info bubble if a certificate in the chain is actually revoked. - base::ScopedCFTypeRef<CFMutableArrayRef> policies( - CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); - if (!policies.get()) { - NOTREACHED(); - return self; - } - // Add a basic X.509 policy, in order to match the behaviour of - // SFCertificatePanel when no policies are specified. - base::ScopedCFTypeRef<SecPolicyRef> basicPolicy; - OSStatus status = - net::x509_util::CreateBasicX509Policy(basicPolicy.InitializeInto()); - if (status != noErr) { - NOTREACHED(); - return self; - } - CFArrayAppendValue(policies, basicPolicy.get()); - - status = net::x509_util::CreateRevocationPolicies(false, policies); - if (status != noErr) { - NOTREACHED(); - return self; - } - - _panel.reset([[SFCertificatePanel alloc] init]); - [_panel setPolicies:base::mac::CFToNSCast(policies.get())]; - return self; -} - -- (void)showCertificateSheet:(NSWindow*)window { - // TODO(https://crbug.com/913303): The certificate viewer's interface to - // Cocoa should be wrapped in a mojo interface in order to allow - // instantiating across processes. As a temporary solution, create a - // transparent in-process window to the front. - if (remote_cocoa::IsWindowRemote(window)) { - _remoteViewsCloneWindow = - remote_cocoa::CreateInProcessTransparentClone(window); - window = _remoteViewsCloneWindow; - } - [_panel beginSheetForWindow:window - modalDelegate:self - didEndSelector:@selector(sheetDidEnd:returnCode:context:) - contextInfo:nil - certificates:_certificates - showGroup:YES]; -} - -- (void)sheetDidEnd:(NSWindow*)parent - returnCode:(NSInteger)returnCode - context:(void*)context { - [_remoteViewsCloneWindow close]; - _remoteViewsCloneWindow = nil; - _panel.reset(); -} - -@end +#include "components/remote_cocoa/common/native_widget_ns_window.mojom.h" void ShowCertificateViewer(content::WebContents* web_contents, gfx::NativeWindow parent, net::X509Certificate* cert) { - base::scoped_nsobject<SSLCertificateViewerMac> viewer( - [[SSLCertificateViewerMac alloc] initWithCertificate:cert]); - [viewer showCertificateSheet:parent.GetNativeNSWindow()]; + // The certificate viewer on macOS uses the OS viewer rather than the Views + // implementation (see https://crbug.com/953425), so go through a Mojo + // interface. This calls the platform APIs from the right process in PWAs. + // See https://crbug.com/916815. If this dialog is switched to Views, the Mojo + // call will no longer be needed. + remote_cocoa::mojom::NativeWidgetNSWindow* mojo_window = + remote_cocoa::GetWindowMojoInterface(parent); + if (!mojo_window) { + // Every WebContents window should have a Mojo interface. + LOG(ERROR) << "Could not get window Mojo interface"; + return; + } + + mojo_window->ShowCertificateViewer(cert); }
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc index 5154fcd..951602a5 100644 --- a/chrome/browser/ui/views/collected_cookies_views.cc +++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -425,6 +425,8 @@ content_settings::PageSpecificContentSettings::GetForFrame( web_contents_->GetMainFrame()); + ChromeLayoutProvider* layout_provider = ChromeLayoutProvider::Get(); + // Create the controls that go into the pane. auto allowed_label = std::make_unique<views::Label>( l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_LABEL), @@ -451,10 +453,9 @@ views::GridLayout* layout = pane->SetLayoutManager(std::make_unique<views::GridLayout>()); - pane->SetBorder( - views::CreateEmptyBorder(ChromeLayoutProvider::Get()->GetInsetsMetric( - views::INSETS_DIALOG_SUBSECTION))); - const int vertical_distance = ChromeLayoutProvider::Get()->GetDistanceMetric( + pane->SetBorder(views::CreateEmptyBorder( + layout_provider->GetInsetsMetric(views::INSETS_DIALOG_SUBSECTION))); + const int vertical_distance = layout_provider->GetDistanceMetric( views::DISTANCE_UNRELATED_CONTROL_VERTICAL); const int single_column_layout_id = 0;
diff --git a/chrome/browser/ui/views/in_product_help/feature_promo_bubble_view.cc b/chrome/browser/ui/views/in_product_help/feature_promo_bubble_view.cc index f5a0161..1ae7f48 100644 --- a/chrome/browser/ui/views/in_product_help/feature_promo_bubble_view.cc +++ b/chrome/browser/ui/views/in_product_help/feature_promo_bubble_view.cc
@@ -16,9 +16,9 @@ #include "chrome/browser/ui/views/in_product_help/feature_promo_bubble_timeout.h" #include "chrome/grit/generated_resources.h" #include "components/variations/variations_associated_data.h" -#include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/theme_provider.h" +#include "ui/gfx/color_palette.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/text_utils.h" #include "ui/views/accessibility/view_accessibility.h" @@ -47,7 +47,18 @@ // The insets from the bubble border to the text inside. constexpr gfx::Insets kBubbleContentsInsets(12, 16); +// The insets from the button border to the text inside. constexpr gfx::Insets kBubbleButtonPadding(8, 10); + +// The text color of the button. +constexpr SkColor kBubbleButtonTextColor = SK_ColorWHITE; + +// The focus ring color of the button. +constexpr SkColor kBubbleButtonFocusRingColor = SK_ColorWHITE; + +// The background color of the button when focused. +constexpr SkColor kBubbleButtonFocusedBackgroundColor = + gfx::kGoogleBlue600; } // namespace namespace views { @@ -65,6 +76,9 @@ SetProminent(true); // Button color is the same as IPH bubble's color. SetBgColorOverride(SK_ColorTRANSPARENT); + // Do not grey out button text on blur. + SetTextColor(ButtonState::STATE_DISABLED, kBubbleButtonTextColor); + focus_ring()->SetColor(kBubbleButtonFocusRingColor); } void UpdateBackgroundColor() override { @@ -73,7 +87,8 @@ // Adapted from MdTextButton::UpdateBackgroundColor() ui::NativeTheme* theme = GetNativeTheme(); - SkColor bg_color = SK_ColorTRANSPARENT; + SkColor bg_color = + HasFocus() ? kBubbleButtonFocusedBackgroundColor : SK_ColorTRANSPARENT; if (GetState() == STATE_PRESSED) theme->GetSystemButtonPressedColor(bg_color);
diff --git a/chrome/browser/ui/views/in_product_help/feature_promo_registry.cc b/chrome/browser/ui/views/in_product_help/feature_promo_registry.cc index 86de9d99..1ec1975 100644 --- a/chrome/browser/ui/views/in_product_help/feature_promo_registry.cc +++ b/chrome/browser/ui/views/in_product_help/feature_promo_registry.cc
@@ -87,8 +87,12 @@ params.arrow = views::BubbleBorder::TOP_LEFT; // Turn on IPH Snooze only for Tab Group. - params.allow_snooze = base::FeatureList::IsEnabled( - feature_engagement::kIPHDesktopSnoozeFeature); + if (base::FeatureList::IsEnabled( + feature_engagement::kIPHDesktopSnoozeFeature)) { + params.allow_focus = true; + params.persist_on_blur = true; + params.allow_snooze = true; + } RegisterFeature(feature_engagement::kIPHDesktopTabGroupsNewGroupFeature, params, base::BindRepeating(GetTabGroupsAnchorView));
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index fc0d14e..f71d760 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -1189,6 +1189,12 @@ IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITH_COUNTS_PLURAL}, {"deleteProfileWarningWithoutCounts", IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITHOUT_COUNTS}, + + // Color picker strings: + {"colorPickerLabel", IDS_NTP_CUSTOMIZE_COLOR_PICKER_LABEL}, + {"defaultThemeLabel", IDS_NTP_CUSTOMIZE_DEFAULT_LABEL}, + {"thirdPartyThemeDescription", IDS_NTP_CUSTOMIZE_3PT_THEME_DESC}, + {"uninstallThirdPartyThemeButton", IDS_NTP_CUSTOMIZE_3PT_THEME_UNINSTALL}, }; AddLocalizedStringsBulk(html_source, kLocalizedStrings);
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc index bac67a83f..1a6df05 100644 --- a/chrome/browser/ui/webui/settings/settings_ui.cc +++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -118,6 +118,7 @@ #include "ui/base/ui_base_features.h" #else // !defined(OS_CHROMEOS) #include "chrome/browser/signin/account_consistency_mode_manager.h" +#include "chrome/browser/ui/webui/customize_themes/chrome_customize_themes_handler.h" #include "chrome/browser/ui/webui/settings/settings_default_browser_handler.h" #include "chrome/browser/ui/webui/settings/settings_manage_profile_handler.h" #include "chrome/browser/ui/webui/settings/system_handler.h" @@ -155,7 +156,13 @@ } SettingsUI::SettingsUI(content::WebUI* web_ui) - : content::WebUIController(web_ui), + : +#if !defined(OS_CHROMEOS) + ui::MojoWebUIController(web_ui, /*enable_chrome_send=*/true), + customize_themes_factory_receiver_(this), +#else // !defined(OS_CHROMEOS) + content::WebUIController(web_ui), +#endif webui_load_timer_(web_ui->GetWebContents(), "Settings.LoadDocumentTime.MD", "Settings.LoadCompletedTime.MD") { @@ -311,7 +318,11 @@ // This is the browser settings page. html_source->AddBoolean("isOSSettings", false); -#endif +#else // defined(OS_CHROMEOS) + html_source->AddBoolean( + "profileThemeSelectorEnabled", + base::FeatureList::IsEnabled(features::kProfileThemeSelectorInSettings)); +#endif // !defined(OS_CHROMEOS) AddSettingsPageUIHandler(std::make_unique<AboutHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<ResetSettingsHandler>(profile)); @@ -430,7 +441,16 @@ web_ui()->AddMessageHandler( std::make_unique<chromeos::settings::AndroidAppsHandler>(profile)); } -#endif // defined(OS_CHROMEOS) +#else // defined(OS_CHROMEOS) +void SettingsUI::BindInterface( + mojo::PendingReceiver< + customize_themes::mojom::CustomizeThemesHandlerFactory> + pending_receiver) { + if (customize_themes_factory_receiver_.is_bound()) + customize_themes_factory_receiver_.reset(); + customize_themes_factory_receiver_.Bind(std::move(pending_receiver)); +} +#endif // !defined(OS_CHROMEOS) void SettingsUI::AddSettingsPageUIHandler( std::unique_ptr<content::WebUIMessageHandler> handler) { @@ -448,4 +468,18 @@ } } +#if !defined(OS_CHROMEOS) +void SettingsUI::CreateCustomizeThemesHandler( + mojo::PendingRemote<customize_themes::mojom::CustomizeThemesClient> + pending_client, + mojo::PendingReceiver<customize_themes::mojom::CustomizeThemesHandler> + pending_handler) { + customize_themes_handler_ = std::make_unique<ChromeCustomizeThemesHandler>( + std::move(pending_client), std::move(pending_handler), + web_ui()->GetWebContents(), Profile::FromWebUI(web_ui())); +} +#endif // !defined(OS_CHROMEOS) + +WEB_UI_CONTROLLER_TYPE_IMPL(SettingsUI) + } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/settings_ui.h b/chrome/browser/ui/webui/settings/settings_ui.h index ff4a05c..6da24f5e 100644 --- a/chrome/browser/ui/webui/settings/settings_ui.h +++ b/chrome/browser/ui/webui/settings/settings_ui.h
@@ -6,10 +6,19 @@ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_UI_H_ #include "base/macros.h" +#include "build/build_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/webui_load_timer.h" #include "content/public/browser/web_ui_controller.h" +#if !defined(OS_CHROMEOS) +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "ui/webui/mojo_web_ui_controller.h" +#include "ui/webui/resources/cr_components/customize_themes/customize_themes.mojom.h" +#endif // !defined(OS_CHROMEOS) + namespace content { class WebUIMessageHandler; } // namespace content @@ -18,10 +27,23 @@ class PrefRegistrySyncable; } +#if !defined(OS_CHROMEOS) +class ChromeCustomizeThemesHandler; +#endif // !defined(OS_CHROMEOS) + namespace settings { // The WebUI handler for chrome://settings. -class SettingsUI : public content::WebUIController { +class SettingsUI : +#if !defined(OS_CHROMEOS) + // chrome://settings/manageProfile which only exists on !OS_CHROMEOS + // requires mojo bindings. + public ui::MojoWebUIController, + public customize_themes::mojom::CustomizeThemesHandlerFactory +#else // !defined(OS_CHROMEOS) + public content::WebUIController +#endif // defined(OS_CHROMEOS) +{ public: static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); @@ -32,7 +54,14 @@ // Initializes the WebUI message handlers for CrOS-specific settings that are // still shown in the browser settings UI. void InitBrowserSettingsWebUIHandlers(); -#endif // defined(OS_CHROMEOS) +#else // defined(OS_CHROMEOS) + // Instantiates the implementor of the + // customize_themes::mojom::CustomizeThemesHandlerFactory mojo interface + // passing the pending receiver that will be internally bound. + void BindInterface(mojo::PendingReceiver< + customize_themes::mojom::CustomizeThemesHandlerFactory> + pending_receiver); +#endif // !defined(OS_CHROMEOS) private: void AddSettingsPageUIHandler( @@ -41,8 +70,23 @@ // Makes a request to show a HaTS survey. void TryShowHatsSurveyWithTimeout(); +#if !defined(OS_CHROMEOS) + // customize_themes::mojom::CustomizeThemesHandlerFactory: + void CreateCustomizeThemesHandler( + mojo::PendingRemote<customize_themes::mojom::CustomizeThemesClient> + pending_client, + mojo::PendingReceiver<customize_themes::mojom::CustomizeThemesHandler> + pending_handler) override; + + std::unique_ptr<ChromeCustomizeThemesHandler> customize_themes_handler_; + mojo::Receiver<customize_themes::mojom::CustomizeThemesHandlerFactory> + customize_themes_factory_receiver_; +#endif // !defined(OS_CHROMEOS) + WebuiLoadTimer webui_load_timer_; + WEB_UI_CONTROLLER_TYPE_DECL(); + DISALLOW_COPY_AND_ASSIGN(SettingsUI); };
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index dac9693..38f41e4 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1600840405-46e4cd70bd3de973a171c7f611770f78487d203a.profdata +chrome-linux-master-1600861496-aa5ced2b846bf1462377e76f5270436b4108dec5.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index f1badadf..da3225ae 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -648,6 +648,13 @@ base::FEATURE_DISABLED_BY_DEFAULT}; #endif // defined(OS_CHROMEOS) +// Controls whether SCT audit reports are queued and the rate at which they +// should be sampled. +const base::Feature kSCTAuditing{"SCTAuditing", + base::FEATURE_DISABLED_BY_DEFAULT}; +constexpr base::FeatureParam<double> kSCTAuditingSamplingRate{ + &kSCTAuditing, "sampling_rate", 0.0}; + // Controls whether the user is prompted when sites request attestation. const base::Feature kSecurityKeyAttestationPrompt{ "SecurityKeyAttestationPrompt", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 2efea7f..9d2a166 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -434,6 +434,11 @@ #endif COMPONENT_EXPORT(CHROME_FEATURES) +extern const base::Feature kSCTAuditing; +COMPONENT_EXPORT(CHROME_FEATURES) +extern const base::FeatureParam<double> kSCTAuditingSamplingRate; + +COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kSecurityKeyAttestationPrompt; #if defined(OS_CHROMEOS)
diff --git a/chrome/services/sharing/webrtc/ipc_network_manager.cc b/chrome/services/sharing/webrtc/ipc_network_manager.cc index d4c023a..5d71d364 100644 --- a/chrome/services/sharing/webrtc/ipc_network_manager.cc +++ b/chrome/services/sharing/webrtc/ipc_network_manager.cc
@@ -35,6 +35,7 @@ case net::NetworkChangeNotifier::CONNECTION_2G: case net::NetworkChangeNotifier::CONNECTION_3G: case net::NetworkChangeNotifier::CONNECTION_4G: + case net::NetworkChangeNotifier::CONNECTION_5G: return rtc::ADAPTER_TYPE_CELLULAR; default: return rtc::ADAPTER_TYPE_UNKNOWN;
diff --git a/chrome/services/speech/BUILD.gn b/chrome/services/speech/BUILD.gn index c9c50a5..172c51f 100644 --- a/chrome/services/speech/BUILD.gn +++ b/chrome/services/speech/BUILD.gn
@@ -29,6 +29,7 @@ deps = [ ":buildflags", "//base", + "//chrome/services/speech/soda", "//components/speech", "//content/public/browser:proto", "//mojo/public/cpp/bindings", @@ -36,10 +37,6 @@ "//services/network/public/cpp", "//services/network/public/mojom", ] - - if (enable_soda) { - deps += [ "//chrome/services/soda/internal" ] - } } source_set("unit_tests") {
diff --git a/chrome/services/speech/DEPS b/chrome/services/speech/DEPS index d0c03dc..41a2776 100644 --- a/chrome/services/speech/DEPS +++ b/chrome/services/speech/DEPS
@@ -1,5 +1,4 @@ include_rules = [ - "+chrome/services/soda/internal", "+chrome/services/speech", "+components/speech", "+content/browser/speech",
diff --git a/chrome/services/speech/speech_recognition_recognizer_impl.cc b/chrome/services/speech/speech_recognition_recognizer_impl.cc index 620836f..7c52fe1 100644 --- a/chrome/services/speech/speech_recognition_recognizer_impl.cc +++ b/chrome/services/speech/speech_recognition_recognizer_impl.cc
@@ -10,25 +10,22 @@ #include "base/bind.h" #include "base/containers/span.h" #include "base/files/file_util.h" +#include "chrome/services/speech/soda/soda_client.h" +#include "google_apis/google_api_keys.h" #include "media/base/audio_buffer.h" #include "media/base/audio_sample_types.h" #include "media/base/bind_to_current_loop.h" #include "media/base/limits.h" +#include "media/base/media_switches.h" #include "media/mojo/common/media_type_converters.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" -#if BUILDFLAG(ENABLE_SODA) -#include "chrome/services/soda/internal/soda_client.h" -#include "google_apis/google_api_keys.h" -#endif // BUILDFLAG(ENABLE_SODA) - namespace speech { constexpr char kInvalidAudioDataError[] = "Invalid audio data received."; namespace { -#if BUILDFLAG(ENABLE_SODA) // Callback executed by the SODA library on a speech recognition event. The // callback handle is a void pointer to the SpeechRecognitionRecognizerImpl that // owns the SODA instance. SpeechRecognitionRecognizerImpl owns the SodaClient @@ -43,7 +40,6 @@ ->recognition_event_callback() .Run(std::string(result), is_final); } -#endif // BUILDFLAG(ENABLE_SODA) } // namespace @@ -63,11 +59,11 @@ } bool SpeechRecognitionRecognizerImpl::IsMultichannelSupported() { -#if BUILDFLAG(ENABLE_SODA) - return true; -#else - return false; -#endif // BUILDFLAG(ENABLE_SODA) + if (base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption)) { + return true; + } else { + return false; + } } void SpeechRecognitionRecognizerImpl::OnRecognitionEvent( @@ -86,13 +82,15 @@ recognition_event_callback_ = media::BindToCurrentLoop( base::Bind(&SpeechRecognitionRecognizerImpl::OnRecognitionEvent, weak_factory_.GetWeakPtr())); -#if BUILDFLAG(ENABLE_SODA) - DCHECK(base::PathExists(binary_path)); - soda_client_ = std::make_unique<soda::SodaClient>(binary_path); -#else - cloud_client_ = std::make_unique<CloudSpeechRecognitionClient>( - recognition_event_callback(), std::move(speech_recognition_service_impl)); -#endif // BUILDFLAG(ENABLE_SODA) + enable_soda_ = base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption); + if (enable_soda_) { + DCHECK(base::PathExists(binary_path)); + soda_client_ = std::make_unique<soda::SodaClient>(binary_path); + } else { + cloud_client_ = std::make_unique<CloudSpeechRecognitionClient>( + recognition_event_callback(), + std::move(speech_recognition_service_impl)); + } } void SpeechRecognitionRecognizerImpl::SendAudioToSpeechRecognitionService( @@ -124,41 +122,41 @@ return; } -#if BUILDFLAG(ENABLE_SODA) - DCHECK(soda_client_); - DCHECK(base::PathExists(config_path_)); - if (!soda_client_->IsInitialized() || - soda_client_->DidAudioPropertyChange(sample_rate, channel_count)) { - // Initialize the SODA instance. - auto api_key = google_apis::GetSodaAPIKey(); - std::string language_pack_directory = config_path_.AsUTF8Unsafe(); - SodaConfig config; - config.channel_count = channel_count; - config.sample_rate = sample_rate; - config.language_pack_directory = language_pack_directory.c_str(); - config.callback = RecognitionCallback; - config.callback_handle = this; - config.api_key = api_key.c_str(); - soda_client_->Reset(config); - } + if (enable_soda_) { + DCHECK(soda_client_); + DCHECK(base::PathExists(config_path_)); + if (!soda_client_->IsInitialized() || + soda_client_->DidAudioPropertyChange(sample_rate, channel_count)) { + // Initialize the SODA instance. + auto api_key = google_apis::GetSodaAPIKey(); + std::string language_pack_directory = config_path_.AsUTF8Unsafe(); + SodaConfig config; + config.channel_count = channel_count; + config.sample_rate = sample_rate; + config.language_pack_directory = language_pack_directory.c_str(); + config.callback = RecognitionCallback; + config.callback_handle = this; + config.api_key = api_key.c_str(); + soda_client_->Reset(config); + } - soda_client_->AddAudio(reinterpret_cast<char*>(buffer->data.data()), - buffer_size); -#else - DCHECK(cloud_client_); - if (!cloud_client_->IsInitialized() || - cloud_client_->DidAudioPropertyChange(sample_rate, channel_count)) { - // Initialize the stream. - CloudSpeechConfig config; - config.sample_rate = sample_rate; - config.channel_count = channel_count; - config.language_code = "en-US"; - cloud_client_->Initialize(config); - } + soda_client_->AddAudio(reinterpret_cast<char*>(buffer->data.data()), + buffer_size); + } else { + DCHECK(cloud_client_); + if (!cloud_client_->IsInitialized() || + cloud_client_->DidAudioPropertyChange(sample_rate, channel_count)) { + // Initialize the stream. + CloudSpeechConfig config; + config.sample_rate = sample_rate; + config.channel_count = channel_count; + config.language_code = "en-US"; + cloud_client_->Initialize(config); + } - cloud_client_->AddAudio(base::span<const char>( - reinterpret_cast<char*>(buffer->data.data()), buffer_size)); -#endif // BUILDFLAG(ENABLE_SODA) + cloud_client_->AddAudio(base::span<const char>( + reinterpret_cast<char*>(buffer->data.data()), buffer_size)); + } } } // namespace speech
diff --git a/chrome/services/speech/speech_recognition_recognizer_impl.h b/chrome/services/speech/speech_recognition_recognizer_impl.h index 6f63f7c..a196659 100644 --- a/chrome/services/speech/speech_recognition_recognizer_impl.h +++ b/chrome/services/speech/speech_recognition_recognizer_impl.h
@@ -9,7 +9,6 @@ #include <string> #include "base/memory/weak_ptr.h" -#include "chrome/services/speech/buildflags.h" #include "chrome/services/speech/cloud_speech_recognition_client.h" #include "media/mojo/mojom/speech_recognition_service.mojom.h" #include "mojo/public/cpp/bindings/receiver.h" @@ -66,9 +65,8 @@ // the speech recognition service back to the renderer. mojo::Remote<media::mojom::SpeechRecognitionRecognizerClient> client_remote_; -#if BUILDFLAG(ENABLE_SODA) + bool enable_soda_ = false; std::unique_ptr<soda::SodaClient> soda_client_; -#endif // BUILDFLAG(ENABLE_SODA) std::unique_ptr<CloudSpeechRecognitionClient> cloud_client_;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 4737b2a..2309af19 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3315,7 +3315,6 @@ "../browser/background_fetch/background_fetch_delegate_impl_unittest.cc", "../browser/background_fetch/background_fetch_permission_context_unittest.cc", "../browser/background_sync/background_sync_controller_impl_unittest.cc", - "../browser/background_sync/background_sync_permission_context_unittest.cc", "../browser/background_sync/periodic_background_sync_permission_context_unittest.cc", "../browser/banners/app_banner_settings_helper_unittest.cc", "../browser/bitmap_fetcher/bitmap_fetcher_service_unittest.cc",
diff --git a/chrome/test/chromedriver/client/command_executor.py b/chrome/test/chromedriver/client/command_executor.py index 50e0069..3432c41 100644 --- a/chrome/test/chromedriver/client/command_executor.py +++ b/chrome/test/chromedriver/client/command_executor.py
@@ -81,6 +81,8 @@ _Method.GET, '/session/:sessionId/element/:id/property/:name') GET_ELEMENT_COMPUTED_LABEL = ( _Method.GET, '/session/:sessionId/element/:id/computedlabel') + GET_ELEMENT_COMPUTED_ROLE = ( + _Method.GET, '/session/:sessionId/element/:id/computedrole') ELEMENT_EQUALS = ( _Method.GET, '/session/:sessionId/element/:id/equals/:other') GET_COOKIES = (_Method.GET, '/session/:sessionId/cookie')
diff --git a/chrome/test/chromedriver/client/webelement.py b/chrome/test/chromedriver/client/webelement.py index 4ae9cead..422b226 100644 --- a/chrome/test/chromedriver/client/webelement.py +++ b/chrome/test/chromedriver/client/webelement.py
@@ -37,6 +37,9 @@ def GetComputedLabel(self): return self._Execute(Command.GET_ELEMENT_COMPUTED_LABEL) + def GetComputedRole(self): + return self._Execute(Command.GET_ELEMENT_COMPUTED_ROLE) + def Click(self): self._Execute(Command.CLICK_ELEMENT)
diff --git a/chrome/test/chromedriver/element_commands.cc b/chrome/test/chromedriver/element_commands.cc index 2510ce1..078efff2 100644 --- a/chrome/test/chromedriver/element_commands.cc +++ b/chrome/test/chromedriver/element_commands.cc
@@ -744,47 +744,20 @@ const std::string& element_id, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value) { - Status status = CheckElement(element_id); + std::unique_ptr<base::Value> axNode; + Status status = GetAXNodeByElementId(session, web_view, element_id, &axNode); if (status.IsError()) return status; - int node_id; - std::unique_ptr<base::DictionaryValue> element(CreateElement(element_id)); - status = web_view->GetNodeIdByElement(session->GetCurrentFrameId(), *element, - &node_id); - - if (status.IsError()) - return status; - - base::DictionaryValue body; - body.SetInteger("nodeId", node_id); - body.SetBoolean("fetchRelatives", false); - - std::unique_ptr<base::Value> result; - - status = web_view->SendCommandAndGetResult("Accessibility.getPartialAXTree", - body, &result); - if (status.IsError()) - return status; - - base::Optional<base::Value> nodes = result->ExtractKey("nodes"); - if (!nodes) - return Status(kUnknownError, "No `nodes` found in CDP response"); - - base::Value::ListView nodesList = nodes->GetList(); - if (nodesList.size() != 1) - return Status(kUnknownError, "`nodes` in CDP response is not a list"); - - base::Value* node = &nodesList[0]; // Computed label stores as `name` in the AXTree. - base::Optional<base::Value> name = node->ExtractKey("name"); - if (!name) { + base::Optional<base::Value> nameNode = axNode->ExtractKey("name"); + if (!nameNode) { // No computed label found. Return empty string. *value = std::make_unique<base::Value>(""); return Status(kOk); } - base::Optional<base::Value> nameVal = name->ExtractKey("value"); + base::Optional<base::Value> nameVal = nameNode->ExtractKey("value"); if (!nameVal) return Status(kUnknownError, "No name value found in the node in CDP response"); @@ -794,6 +767,33 @@ return Status(kOk); } +Status ExecuteGetComputedRole(Session* session, + WebView* web_view, + const std::string& element_id, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value) { + std::unique_ptr<base::Value> axNode; + Status status = GetAXNodeByElementId(session, web_view, element_id, &axNode); + if (status.IsError()) + return status; + + base::Optional<base::Value> roleNode = axNode->ExtractKey("role"); + if (!roleNode) { + // No computed role found. Return empty string. + *value = std::make_unique<base::Value>(""); + return Status(kOk); + } + + base::Optional<base::Value> roleVal = roleNode->ExtractKey("value"); + if (!roleVal) + return Status(kUnknownError, + "No role value found in the node in CDP response"); + + *value = std::make_unique<base::Value>(std::move(*roleVal)); + + return Status(kOk); +} + Status ExecuteIsElementDisplayed(Session* session, WebView* web_view, const std::string& element_id,
diff --git a/chrome/test/chromedriver/element_commands.h b/chrome/test/chromedriver/element_commands.h index 45c8fd38..01cf33137 100644 --- a/chrome/test/chromedriver/element_commands.h +++ b/chrome/test/chromedriver/element_commands.h
@@ -154,6 +154,12 @@ const base::DictionaryValue& params, std::unique_ptr<base::Value>* value); +Status ExecuteGetComputedRole(Session* session, + WebView* web_view, + const std::string& element_id, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value); + Status ExecuteIsElementDisplayed(Session* session, WebView* web_view, const std::string& element_id,
diff --git a/chrome/test/chromedriver/element_util.cc b/chrome/test/chromedriver/element_util.cc index 757fc684..6e166882 100644 --- a/chrome/test/chromedriver/element_util.cc +++ b/chrome/test/chromedriver/element_util.cc
@@ -906,3 +906,45 @@ *location = center_location; return Status(kOk); } + +Status GetAXNodeByElementId(Session* session, + WebView* web_view, + const std::string& element_id, + std::unique_ptr<base::Value>* axNode) { + Status status = CheckElement(element_id); + if (status.IsError()) + return status; + + int node_id; + std::unique_ptr<base::DictionaryValue> element(CreateElement(element_id)); + status = web_view->GetNodeIdByElement(session->GetCurrentFrameId(), *element, + &node_id); + + if (status.IsError()) + return status; + + base::DictionaryValue body; + body.SetInteger("nodeId", node_id); + body.SetBoolean("fetchRelatives", false); + + std::unique_ptr<base::Value> result; + + status = web_view->SendCommandAndGetResult("Accessibility.getPartialAXTree", + body, &result); + if (status.IsError()) + return status; + + base::Optional<base::Value> nodes = result->ExtractKey("nodes"); + if (!nodes) + return Status(kUnknownError, "No `nodes` found in CDP response"); + + base::Value::ListView nodesList = nodes->GetList(); + if (nodesList.size() < 1) + return Status(kUnknownError, "Empty nodes list in CDP response"); + + if (nodesList.size() > 1) + return Status(kUnknownError, "Non-unique node in CDP response"); + + *axNode = std::make_unique<base::Value>(std::move(nodesList[0])); + return Status(kOk); +}
diff --git a/chrome/test/chromedriver/element_util.h b/chrome/test/chromedriver/element_util.h index 47f7200..b66e56d 100644 --- a/chrome/test/chromedriver/element_util.h +++ b/chrome/test/chromedriver/element_util.h
@@ -164,4 +164,9 @@ const std::string& element_id, WebPoint* location); +Status GetAXNodeByElementId(Session* session, + WebView* web_view, + const std::string& element_id, + std::unique_ptr<base::Value>* axNode); + #endif // CHROME_TEST_CHROMEDRIVER_ELEMENT_UTIL_H_
diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc index d6f1768..bdece95c 100644 --- a/chrome/test/chromedriver/server/http_handler.cc +++ b/chrome/test/chromedriver/server/http_handler.cc
@@ -304,6 +304,9 @@ CommandMapping(kGet, "session/:sessionId/element/:id/computedlabel", WrapToCommand("GetComputedLabel", base::Bind(&ExecuteGetComputedLabel))), + CommandMapping(kGet, "session/:sessionId/element/:id/computedrole", + WrapToCommand("GetComputedRole", + base::Bind(&ExecuteGetComputedRole))), CommandMapping(kPost, "session/:sessionId/element/:id/click", WrapToCommand("ClickElement", base::BindRepeating(&ExecuteClickElement))),
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index d1f765d..90d471199 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -538,13 +538,37 @@ def testStartStop(self): pass - def testGetComputedLabel(self): - self._driver.Load(self.GetHttpUrlForFile( - '/chromedriver/accessibility.html')) - element = self._driver.FindElement('css selector', '#first-header') - # print >> sys.stdout, "element.GetText: ", element.GetText() - computedLabel = element.GetComputedLabel() - self.assertEquals(computedLabel, 'header content') + def testGetComputedAttributes(self): + self._driver.Load( + self.GetHttpUrlForFile('/chromedriver/accessibility.html')) + + firstHeaderElement = self._driver.FindElement( + 'css selector', '#first-header') + + self.assertEquals(firstHeaderElement.GetComputedLabel(), 'header content') + self.assertEquals(firstHeaderElement.GetComputedRole(), 'heading') + + def testGetComputedAttributesForIgnoredNode(self): + self._driver.Load( + self.GetHttpUrlForFile('/chromedriver/accessibility.html')) + + ignoredHeaderElement = self._driver.FindElement( + 'css selector', '#ignored-header') + + # GetComputedLabel for ignored node should return empty string. + self.assertEquals(ignoredHeaderElement.GetComputedLabel(), '') + self.assertEquals(ignoredHeaderElement.GetComputedRole(), 'Ignored') + + def testGetComputedAttributesForUnrenderedNode(self): + self._driver.Load( + self.GetHttpUrlForFile('/chromedriver/accessibility.html')) + + unrenderedHeaderElement = self._driver.FindElement( + 'css selector', '#unrendered-header') + + # GetComputedLabel for unrendered node should return empty string. + self.assertEquals(unrenderedHeaderElement.GetComputedLabel(), '') + self.assertEquals(unrenderedHeaderElement.GetComputedRole(), 'Ignored') def testLoadUrl(self): self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
diff --git a/chrome/test/data/chromedriver/accessibility.html b/chrome/test/data/chromedriver/accessibility.html index 3dbc1f1..4a6e9ce 100644 --- a/chrome/test/data/chromedriver/accessibility.html +++ b/chrome/test/data/chromedriver/accessibility.html
@@ -1,3 +1,5 @@ <!DOCTYPE html> - <title>Test</title> - <h1 id="first-header">header content</h1> +<title>Test</title> +<h1 id="first-header">header content</h1> +<h1 id="ignored-header" role=presentation>ignored header content</h1> +<h1 id="unrendered-header" hidden>unrendered header content</h1> \ No newline at end of file
diff --git a/chrome/test/data/extensions/api_test/automation/tests/tabs/intents.js b/chrome/test/data/extensions/api_test/automation/tests/tabs/intents.js index dda11d1..8fcec68 100644 --- a/chrome/test/data/extensions/api_test/automation/tests/tabs/intents.js +++ b/chrome/test/data/extensions/api_test/automation/tests/tabs/intents.js
@@ -10,13 +10,13 @@ chrome.automation.EventType.TEXT_SELECTION_CHANGED, (e) => { assertEq(1, e.intents.length); assertEq( - chrome.automation.EventCommandType.SET_SELECTION, + chrome.automation.IntentCommandType.SET_SELECTION, e.intents[0].command); assertEq( - chrome.automation.EventTextBoundaryType.CHARACTER, + chrome.automation.IntentTextBoundaryType.CHARACTER, e.intents[0].textBoundary); assertEq( - chrome.automation.EventMoveDirectionType.FORWARD, + chrome.automation.IntentMoveDirectionType.FORWARD, e.intents[0].moveDirection); chrome.test.succeed(); }, true);
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index dac4c19..97b1f0f1 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -3048,7 +3048,7 @@ "URLBlacklist": { "note": "This policy is deprecated, see http://crbug.com/1095230.", - "os": ["win", "linux", "mac", "chromeos"], + "os": ["win", "linux", "mac", "chromeos", "android"], "policy_pref_mapping_test": [ { "policies": {"URLBlacklist": ["google.com"]}, @@ -3058,7 +3058,7 @@ }, "URLBlocklist": { - "os": ["win", "linux", "mac", "chromeos"], + "os": ["win", "linux", "mac", "chromeos", "android"], "policy_pref_mapping_test": [ { "policies": {"URLBlocklist": ["google.com"]}, @@ -3069,7 +3069,7 @@ "URLWhitelist": { "note": "This policy is deprecated, see http://crbug.com/1095230.", - "os": ["win", "linux", "mac", "chromeos"], + "os": ["win", "linux", "mac", "chromeos", "android"], "policy_pref_mapping_test": [ { "policies": {"URLWhitelist": ["google.com"]}, @@ -3079,7 +3079,7 @@ }, "URLAllowlist": { - "os": ["win", "linux", "mac", "chromeos"], + "os": ["win", "linux", "mac", "chromeos", "android"], "policy_pref_mapping_test": [ { "policies": {"URLAllowlist": ["google.com"]},
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_test.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_test.js index ccfc914..1a8fc8d 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_test.js
@@ -7,7 +7,7 @@ import 'chrome://diagnostics/diagnostics_app.js'; import {SystemDataProviderInterface} from 'chrome://diagnostics/diagnostics_types.js'; -import {fakeBatteryInfo, fakeCpuUsage, fakeSystemInfo} from 'chrome://diagnostics/fake_data.js'; +import {fakeBatteryChargeStatus, fakeBatteryHealth, fakeBatteryInfo, fakeCpuUsage, fakeMemoryUsage, fakeSystemInfo} from 'chrome://diagnostics/fake_data.js'; import {FakeMethodResolver} from 'chrome://diagnostics/fake_method_resolver.js'; import {FakeObservables} from 'chrome://diagnostics/fake_observables.js'; import {FakeSystemDataProvider} from 'chrome://diagnostics/fake_system_data_provider.js'; @@ -119,12 +119,17 @@ /** * @param {!BatteryInfo} batteryInfo + * @param {!BatteryChargeStatus} batteryChargeStatus + * @param {!BatteryHealth} batteryHealth * @return {!Promise} */ - function initializeBatteryStatusCard(batteryInfo) { + function initializeBatteryStatusCard( + batteryInfo, batteryChargeStatus, batteryHealth) { assertFalse(!!batteryStatusElement); // Initialize the fake data. + provider.setFakeBatteryChargeStatus(batteryChargeStatus); + provider.setFakeBatteryHealth(batteryHealth); provider.setFakeBatteryInfo(batteryInfo); // Add the battery status card to the DOM. @@ -136,14 +141,33 @@ } test('BatteryStatusCardPopulated', () => { - return initializeBatteryStatusCard(fakeBatteryInfo).then(() => { - // TODO(zentaro): Update when strings are finalized. - assertEquals( - 'Battery Status', batteryStatusElement.$$('#cardTitle').textContent); - assertEquals( - fakeBatteryInfo.manufacturer, - batteryStatusElement.$$('#manufacturer').textContent); - }); + return initializeBatteryStatusCard( + fakeBatteryInfo, fakeBatteryChargeStatus, fakeBatteryHealth) + .then(() => { + // TODO(zentaro): Update when strings are finalized. + assertEquals( + 'Battery Status', + batteryStatusElement.$$('#cardTitle').textContent); + assertEquals( + fakeBatteryInfo.manufacturer, + batteryStatusElement.$$('#manufacturer').textContent); + assertEquals( + fakeBatteryHealth[0].charge_full_design_milliamp_hours.toString(), + batteryStatusElement.$$('#chargeFullDesign').textContent); + assertEquals( + fakeBatteryChargeStatus[0] + .charge_full_now_milliamp_hours.toString(), + batteryStatusElement.$$('#chargeFullNow').textContent); + assertEquals( + fakeBatteryChargeStatus[0].charge_now_milliamp_hours.toString(), + batteryStatusElement.$$('#chargeNow').textContent); + assertEquals( + fakeBatteryChargeStatus[0].power_time, + batteryStatusElement.$$('#powerTime').textContent); + assertEquals( + fakeBatteryChargeStatus[0].power_adapter_status.toString(), + batteryStatusElement.$$('#adapterStatus').textContent); + }); }); }); @@ -286,9 +310,16 @@ provider = null; }); - function initializeMemoryCard() { + /** + * @param {!MemoryUsage} memoryUsage + * @return {!Promise} + */ + function initializeMemoryCard(memoryUsage) { assertFalse(!!memoryElement); + // Initialize the fake data. + provider.setFakeMemoryUsage(memoryUsage); + // Add the memory card to the DOM. memoryElement = document.createElement('memory-card'); assertTrue(!!memoryElement); @@ -298,9 +329,19 @@ } test('MemoryCardPopulated', () => { - return initializeMemoryCard().then(() => { + return initializeMemoryCard(fakeMemoryUsage).then(() => { // TODO(zentaro): Update when strings are finalized. assertEquals('Memory', memoryElement.$$('#cardTitle').textContent); + + assertEquals( + fakeMemoryUsage[0].total_memory_kib.toString(), + memoryElement.$$('#memoryTotal').textContent); + assertEquals( + fakeMemoryUsage[0].available_memory_kib.toString(), + memoryElement.$$('#memoryAvailable').textContent); + assertEquals( + fakeMemoryUsage[0].free_memory_kib.toString(), + memoryElement.$$('#memoryFree').textContent); }); }); }); @@ -342,6 +383,56 @@ observables.trigger('ObserveFoo_OnFooUpdated'); return resolver.promise; }); + + test('TwoResults', () => { + observables.register('ObserveFoo_OnFooUpdated'); + /** @type !Array<string> */ + const expected = ['bar1', 'bar2']; + observables.setObservableData('ObserveFoo_OnFooUpdated', expected); + + // The first call will get 'bar1', and the second 'bar2'. + let resolver = new PromiseResolver(); + const expectedCallCount = 2; + let callCount = 0; + observables.observe('ObserveFoo_OnFooUpdated', (foo) => { + assertEquals(expected[callCount % expected.length], foo); + callCount++; + if (callCount === expectedCallCount) { + resolver.resolve(); + } + }); + + // Trigger the observer twice. + observables.trigger('ObserveFoo_OnFooUpdated'); + observables.trigger('ObserveFoo_OnFooUpdated'); + return resolver.promise; + }); + + test('ObservableDataWraps', () => { + observables.register('ObserveFoo_OnFooUpdated'); + /** @type !Array<string> */ + const expected = ['bar1', 'bar2']; + observables.setObservableData('ObserveFoo_OnFooUpdated', expected); + + // With 3 calls and 2 observable values the response should cycle + // 'bar1', 'bar2', 'bar1' + let resolver = new PromiseResolver(); + const expectedCallCount = 3; + let callCount = 0; + observables.observe('ObserveFoo_OnFooUpdated', (foo) => { + assertEquals(expected[callCount % expected.length], foo); + callCount++; + if (callCount === expectedCallCount) { + resolver.resolve(); + } + }); + + // Trigger the observer three times. + observables.trigger('ObserveFoo_OnFooUpdated'); + observables.trigger('ObserveFoo_OnFooUpdated'); + observables.trigger('ObserveFoo_OnFooUpdated'); + return resolver.promise; + }); }); @@ -391,6 +482,33 @@ }); }); + test('ObserveBatteryHealth', () => { + provider.setFakeBatteryHealth(fakeBatteryHealth); + + /** @type {!BatteryHealthObserver} */ + const batteryHealthObserverRemote = { + onBatteryHealthUpdated: (batteryHealth) => { + assertDeepEquals(fakeBatteryHealth[0], batteryHealth); + } + }; + + return provider.observeBatteryHealth(batteryHealthObserverRemote); + }); + + test('ObserveBatteryChargeStatus', () => { + provider.setFakeBatteryChargeStatus(fakeBatteryChargeStatus); + + /** @type {!BatteryChargeStatusObserver} */ + const batteryChargeStatusObserverRemote = { + onBatteryChargeStatusUpdated: (batteryChargeStatus) => { + assertDeepEquals(fakeBatteryChargeStatus[0], batteryChargeStatus); + } + }; + + return provider.observeBatteryChargeStatus( + batteryChargeStatusObserverRemote); + }); + test('ObserveCpuUsage', () => { provider.setFakeCpuUsage(fakeCpuUsage); @@ -403,4 +521,17 @@ return provider.observeCpuUsage(cpuObserverRemote); }); + + test('ObserveMemoryUsage', () => { + provider.setFakeMemoryUsage(fakeMemoryUsage); + + /** @type {!MemoryUsageObserver} */ + const memoryUsageObserverRemote = { + onMemoryUsageUpdated: (memoryUsage) => { + assertDeepEquals(fakeMemoryUsage[0], memoryUsage); + } + }; + + return provider.observeMemoryUsage(memoryUsageObserverRemote); + }); });
diff --git a/chrome/test/data/webui/nearby_share/shared/nearby_onboarding_page_test.js b/chrome/test/data/webui/nearby_share/shared/nearby_onboarding_page_test.js index 4c1a1b8..25c00f2 100644 --- a/chrome/test/data/webui/nearby_share/shared/nearby_onboarding_page_test.js +++ b/chrome/test/data/webui/nearby_share/shared/nearby_onboarding_page_test.js
@@ -16,14 +16,10 @@ let element; /** @type {!string} */ const deviceName = 'Test\'s Device'; - /** @type {!nearby_share.FakeContactManager} */ - const fakeContactManager = new nearby_share.FakeContactManager(); setup(function() { document.body.innerHTML = ''; - nearby_share.setContactManagerForTesting(fakeContactManager); - element = /** @type {!NearbyOnboardingPageElement} */ ( document.createElement('nearby-onboarding-page')); element.settings = {
diff --git a/chrome/test/data/webui/nearby_share/shared/nearby_visibility_page_test.js b/chrome/test/data/webui/nearby_share/shared/nearby_visibility_page_test.js index 7fa896c..77c4dbd 100644 --- a/chrome/test/data/webui/nearby_share/shared/nearby_visibility_page_test.js +++ b/chrome/test/data/webui/nearby_share/shared/nearby_visibility_page_test.js
@@ -7,7 +7,6 @@ // #import {setNearbyShareSettingsForTesting} from 'chrome://nearby/shared/nearby_share_settings.m.js'; // #import {FakeNearbyShareSettings} from './fake_nearby_share_settings.m.js'; // #import {assertEquals, assertTrue, assertFalse} from '../../chai_assert.js'; -// #import {waitAfterNextRender, isChildVisible} from '../../test_util.m.js'; // clang-format on suite('nearby-visibility-page', function() { @@ -31,10 +30,8 @@ test('Renders visibility page', async function() { assertFalse(visibility_page.settings.enabled); - await test_util.waitAfterNextRender(visibility_page); - // Action button on the page template sets settings.enabled to true. - const page_template = visibility_page.$$('nearby-page-template'); - page_template.$$('#actionButton').click(); + // Next button sets settings.enabled to true + visibility_page.$$('#next-button').click(); assertTrue(visibility_page.settings.enabled); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/nearby_share_receive_dialog_tests.js b/chrome/test/data/webui/settings/chromeos/nearby_share_receive_dialog_tests.js index 166eeb230..4cec0a3 100644 --- a/chrome/test/data/webui/settings/chromeos/nearby_share_receive_dialog_tests.js +++ b/chrome/test/data/webui/settings/chromeos/nearby_share_receive_dialog_tests.js
@@ -5,41 +5,29 @@ // clang-format off // #import {assertEquals} from '../../chai_assert.js'; // #import {isChildVisible, waitAfterNextRender} from '../../test_util.m.js'; -// #import {setReceiveManagerForTesting, setContactManagerForTesting} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {setReceiveManagerForTesting} from 'chrome://os-settings/chromeos/os_settings.js'; // #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {FakeContactManager} from '../../nearby_share/shared/fake_nearby_contact_manager.m.js'; // #import {FakeReceiveManager} from './fake_receive_manager.m.js' // clang-format on suite('NearbyShare', function() { - /** @type {!NearbyShareReceiveDialogElement} */ - let dialog; - /** @type {!FakeReceiveManager} */ - let fakeReceiveManager; - /** @type {!nearby_share.FakeContactManager} */ - let fakeContactManager; + /** @type {?NearbyShareReceiveDialogElement} */ + let dialog = null; + /** @type {?FakeReceiveManager} */ + let fakeReceiveManager = null; - /** - * This allows both sub-suites to share the same setup logic but with a - * different enabled state which changes the routing of the first view. - * @param {boolean} enabled The value of the enabled setting. - */ - function sharedSetup(enabled) { + setup(function() { fakeReceiveManager = new nearby_share.FakeReceiveManager(); - fakeContactManager = new nearby_share.FakeContactManager(); - nearby_share.setReceiveManagerForTesting(fakeReceiveManager); - nearby_share.setContactManagerForTesting(fakeContactManager); - PolymerTest.clearBody(); - dialog = document.createElement('nearby-share-receive-dialog'); - dialog.settings = { - enabled: enabled, - }; document.body.appendChild(dialog); Polymer.dom.flush(); - } + }); + + teardown(function() { + dialog.remove(); + }); /** * @param {string} selector @@ -49,127 +37,53 @@ return test_util.isChildVisible(dialog, selector, false); } - /** - * - * @param {string} page page element name - * @param {*} button button selector (i.e. #actionButton) - */ - function getButton(page, button) { - return dialog.$$(page).$$('nearby-page-template').$$(button); - } + test('show high visibility page, get a target, accept', async function() { + // When attached we enter high visibility mode by default + assertTrue(isVisible('nearby-share-high-visibility-page')); + assertFalse(isVisible('nearby-share-confirm-page')); + // If a share target comes in, we show it. + const target = + fakeReceiveManager.simulateShareTargetArrival('testName', '1234'); + const confirmPage = dialog.$$('nearby-share-confirm-page'); + Polymer.dom.flush(); - suite('EnabledTests', function() { - setup(function() { - sharedSetup(true); - dialog.showHighVisibilityPage(); - Polymer.dom.flush(); - }); + assertEquals( + target.name, confirmPage.$$('#shareTargetName').textContent.trim()); + assertEquals('1234', confirmPage.$$('#connectionToken').textContent.trim()); - teardown(function() { - dialog.remove(); - }); - - test('show high visibility page, get a target, accept', async function() { - // When attached we enter high visibility mode by default - assertTrue(isVisible('nearby-share-high-visibility-page')); - assertFalse(isVisible('nearby-share-confirm-page')); - // If a share target comes in, we show it. - const target = - fakeReceiveManager.simulateShareTargetArrival('testName', '1234'); - const confirmPage = dialog.$$('nearby-share-confirm-page'); - Polymer.dom.flush(); - - assertEquals( - target.name, confirmPage.$$('#shareTargetName').textContent.trim()); - assertEquals( - '1234', confirmPage.$$('#connectionToken').textContent.trim()); - - confirmPage.$$('nearby-page-template').$$('#actionButton').click(); - const shareTargetId = await fakeReceiveManager.whenCalled('accept'); - assertEquals(target.id, shareTargetId); - }); - - test('show high visibility page, get a target, reject', async function() { - // When attached we enter high visibility mode by default - assertTrue(isVisible('nearby-share-high-visibility-page')); - assertFalse(isVisible('nearby-share-confirm-page')); - // If a share target comes in, we show it. - const target = - fakeReceiveManager.simulateShareTargetArrival('testName', '1234'); - const confirmPage = dialog.$$('nearby-share-confirm-page'); - Polymer.dom.flush(); - - assertEquals( - target.name, confirmPage.$$('#shareTargetName').textContent.trim()); - assertEquals( - '1234', confirmPage.$$('#connectionToken').textContent.trim()); - - confirmPage.$$('nearby-page-template').$$('#cancelButton').click(); - const shareTargetId = await fakeReceiveManager.whenCalled('reject'); - assertEquals(target.id, shareTargetId); - }); - - test( - 'show high visibility page, exitHighVisibility, closes dialog', - async function() { - // When attached we enter high visibility mode by default - assertTrue(isVisible('nearby-share-high-visibility-page')); - assertFalse(isVisible('nearby-share-confirm-page')); - // If a share target comes in, we show it. - await fakeReceiveManager.exitHighVisibility(); - Polymer.dom.flush(); - assertFalse(isVisible('cr-dialog')); - }); + confirmPage.$$('nearby-page-template').$$('#actionButton').click(); + const shareTargetId = await fakeReceiveManager.whenCalled('accept'); + assertEquals(target.id, shareTargetId); }); - suite('DisabledTests', function() { - setup(function() { - sharedSetup(false); - }); + test('show high visibility page, get a target, reject', async function() { + // When attached we enter high visibility mode by default + assertTrue(isVisible('nearby-share-high-visibility-page')); + assertFalse(isVisible('nearby-share-confirm-page')); + // If a share target comes in, we show it. + const target = + fakeReceiveManager.simulateShareTargetArrival('testName', '1234'); + const confirmPage = dialog.$$('nearby-share-confirm-page'); + Polymer.dom.flush(); - teardown(function() { - dialog.remove(); - }); + assertEquals( + target.name, confirmPage.$$('#shareTargetName').textContent.trim()); + assertEquals('1234', confirmPage.$$('#connectionToken').textContent.trim()); - test('when disabled, onboarding is shown first', async function() { - dialog.showHighVisibilityPage(); - await test_util.waitAfterNextRender(dialog); - - assertTrue(isVisible('nearby-onboarding-page')); - // Advance to the next page. - getButton('nearby-onboarding-page', '#actionButton').click(); - - await test_util.waitAfterNextRender(dialog); - - assertTrue(isVisible('nearby-visibility-page')); - // Advance to the next page. - getButton('nearby-visibility-page', '#actionButton').click(); - - await test_util.waitAfterNextRender(dialog); - - assertTrue(dialog.settings.enabled); - assertTrue(isVisible('nearby-share-high-visibility-page')); - }); - - test('when showing onboarding, close when complete.', async function() { - dialog.showOnboarding(); - await test_util.waitAfterNextRender(dialog); - - assertTrue(isVisible('nearby-onboarding-page')); - // Advance to the next page. - getButton('nearby-onboarding-page', '#actionButton').click(); - - await test_util.waitAfterNextRender(dialog); - - assertTrue(isVisible('nearby-visibility-page')); - // This should close the dialog. - getButton('nearby-visibility-page', '#actionButton').click(); - - assertTrue(dialog.closing_); - - await test_util.waitAfterNextRender(dialog); - - assertFalse(dialog.$$('#dialog').open); - }); + confirmPage.$$('nearby-page-template').$$('#cancelButton').click(); + const shareTargetId = await fakeReceiveManager.whenCalled('reject'); + assertEquals(target.id, shareTargetId); }); + + test( + 'show high visibility page, exitHighVisibility, closes dialog', + async function() { + // When attached we enter high visibility mode by default + assertTrue(isVisible('nearby-share-high-visibility-page')); + assertFalse(isVisible('nearby-share-confirm-page')); + // If a share target comes in, we show it. + await fakeReceiveManager.exitHighVisibility(); + Polymer.dom.flush(); + assertFalse(isVisible('cr-dialog')); + }); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index dc7fb57..a48be41d 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -1128,7 +1128,6 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../../nearby_share/shared/fake_nearby_contact_manager.js', '../../test_util.js', '../../test_browser_proxy.js', 'fake_receive_manager.js',
diff --git a/chrome/test/data/webui/settings/people_page_manage_profile_test.js b/chrome/test/data/webui/settings/people_page_manage_profile_test.js index 2cba144..88262333 100644 --- a/chrome/test/data/webui/settings/people_page_manage_profile_test.js +++ b/chrome/test/data/webui/settings/people_page_manage_profile_test.js
@@ -81,11 +81,7 @@ browserProxy = new TestManageProfileBrowserProxy(); ManageProfileBrowserProxyImpl.instance_ = browserProxy; PolymerTest.clearBody(); - manageProfile = document.createElement('settings-manage-profile'); - manageProfile.profileIconUrl = 'fake-icon-1.png'; - manageProfile.profileName = 'Initial Fake Name'; - manageProfile.syncStatus = {supervisedUser: false, childUser: false}; - document.body.appendChild(manageProfile); + manageProfile = createManageProfileElement(); Router.getInstance().navigateTo(routes.MANAGE_PROFILE); }); @@ -93,6 +89,16 @@ manageProfile.remove(); }); + function createManageProfileElement() { + const manageProfileElement = + document.createElement('settings-manage-profile'); + manageProfileElement.profileIconUrl = 'fake-icon-1.png'; + manageProfileElement.profileName = 'Initial Fake Name'; + manageProfileElement.syncStatus = {supervisedUser: false, childUser: false}; + document.body.appendChild(manageProfileElement); + return manageProfileElement; + } + // Tests that the manage profile subpage // - gets and receives all the available icons // - can select a new icon @@ -101,8 +107,9 @@ return browserProxy.whenCalled('getAvailableIcons') .then(function() { flush(); - items = manageProfile.$.selector.$['avatar-grid'].querySelectorAll( - '.avatar'); + items = + manageProfile.$.avatarSelector.$['avatar-grid'].querySelectorAll( + '.avatar'); assertFalse(!!manageProfile.profileAvatar); assertEquals(3, items.length); @@ -167,6 +174,27 @@ const hasShortcutToggle = manageProfile.$$('#hasShortcutToggle'); assertFalse(!!hasShortcutToggle); }); + + + // Tests that the theme selector is hidden if profile colors feature is + // disabled. + test('ProfileThemeSelectorHidden', function() { + assertFalse(!!manageProfile.$$('#themeSelector')); + }); + + // Tests that the theme selector is visible if profile colors feature is + // enabled. + test('ProfileThemeSelectorVisible', function() { + // Recreate a manage profile element with overridden loadTimeData. + PolymerTest.clearBody(); + loadTimeData.overrideValues({ + profileThemeSelectorEnabled: true, + }); + manageProfile = createManageProfileElement(); + flush(); + + assertTrue(!!manageProfile.$$('#themeSelector')); + }); }); suite('ManageProfileTestsProfileShortcutsEnabled', function() {
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn index a63739b1..d5e98c83 100644 --- a/chrome/updater/BUILD.gn +++ b/chrome/updater/BUILD.gn
@@ -86,8 +86,6 @@ "app/app.h", "app/app_install.cc", "app/app_install.h", - "app/app_register.cc", - "app/app_register.h", "app/app_server.cc", "app/app_server.h", "app/app_uninstall.cc", @@ -279,7 +277,7 @@ "//base/test:test_support", "//chrome/common:constants", "//chrome/updater/device_management:unittest", - "//chrome/updater/test/test_app", + "//chrome/updater/test/test_app:constants", "//chrome/updater/test/test_app:version_header", "//chrome/updater/tools:unittest", "//components/prefs:test_support", @@ -313,8 +311,6 @@ "mac/scoped_xpc_service_mock.mm", "mac/update_service_out_of_process_test.mm", "test/integration_tests_mac.mm", - "test/test_app/constants.cc", - "test/test_app/constants.h", ] deps += [ @@ -331,7 +327,7 @@ data_deps = [ "//chrome/updater/mac:updater_bundle", - "//chrome/updater/test/test_app:test_app", + "//chrome/updater/test/test_app", ] } }
diff --git a/chrome/updater/app/app_register.h b/chrome/updater/app/app_register.h deleted file mode 100644 index 866f109..0000000 --- a/chrome/updater/app/app_register.h +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2020 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_UPDATER_APP_APP_REGISTER_H_ -#define CHROME_UPDATER_APP_APP_REGISTER_H_ - -#include "base/memory/scoped_refptr.h" - -namespace updater { - -class App; - -scoped_refptr<App> MakeAppRegister(); - -} // namespace updater - -#endif // CHROME_UPDATER_APP_APP_REGISTER_H_
diff --git a/chrome/updater/constants.cc b/chrome/updater/constants.cc index f4acab8..7c1ed0f1f 100644 --- a/chrome/updater/constants.cc +++ b/chrome/updater/constants.cc
@@ -17,7 +17,6 @@ const char kCrashMeSwitch[] = "crash-me"; const char kCrashHandlerSwitch[] = "crash-handler"; const char kUpdateSwitch[] = "update"; -const char kRegisterSwitch[] = "register"; const char kInstallSwitch[] = "install"; const char kUninstallSwitch[] = "uninstall"; const char kSystemSwitch[] = "system";
diff --git a/chrome/updater/constants.h b/chrome/updater/constants.h index eb5530de..2d11a38 100644 --- a/chrome/updater/constants.h +++ b/chrome/updater/constants.h
@@ -63,9 +63,6 @@ // Updates the updater. extern const char kUpdateSwitch[]; -// Registers an app with the updater. Installs the bundled updater if needed. -extern const char kRegisterSwitch[]; - // Installs the updater. extern const char kInstallSwitch[];
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index 13c27a1..9c8c0fa2 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -5,8 +5,12 @@ #include "chrome/updater/test/integration_tests.h" #include "base/test/task_environment.h" +#include "base/version.h" #include "build/build_config.h" +#include "chrome/updater/persisted_data.h" #include "chrome/updater/prefs.h" +#include "chrome/updater/test/test_app/constants.h" +#include "chrome/updater/test/test_app/test_app_version.h" #include "chrome/updater/updater_version.h" #include "chrome/updater/util.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/updater/test/test_app/BUILD.gn b/chrome/updater/test/test_app/BUILD.gn index ad4a238..3689decf 100644 --- a/chrome/updater/test/test_app/BUILD.gn +++ b/chrome/updater/test/test_app/BUILD.gn
@@ -45,12 +45,17 @@ output = "$target_gen_dir/test_app_version.h" } +source_set("constants") { + sources = [ + "constants.cc", + "constants.h", + ] +} + source_set("app_sources") { sources = [ "//chrome/updater/app/app.cc", "//chrome/updater/app/app.h", - "constants.cc", - "constants.h", "test_app.cc", "test_app.h", "test_app_mac.mm", @@ -64,6 +69,7 @@ ] deps = [ + ":constants", ":version_header", "//base", "//chrome/updater:base",
diff --git a/chrome/updater/test/test_app/constants.cc b/chrome/updater/test/test_app/constants.cc index 0c60937..fed3392 100644 --- a/chrome/updater/test/test_app/constants.cc +++ b/chrome/updater/test/test_app/constants.cc
@@ -10,9 +10,6 @@ const char kRegisterUpdaterSwitch[] = "register-updater"; const char kRegisterToUpdaterSwitch[] = "ipc-register"; const char kForegroundUpdateSwitch[] = "ipc-update"; - -#if defined(OS_WIN) -const base::char16 kAppId[] = L"6f0f9a34-a0ab-4a75-a0eb-6eab78d0dc4b"; -#endif // defined(OS_WIN) +const char kTestAppId[] = "6f0f9a34-a0ab-4a75-a0eb-6eab78d0dc4b"; } // namespace updater
diff --git a/chrome/updater/test/test_app/constants.h b/chrome/updater/test/test_app/constants.h index 406b235..9f188f31 100644 --- a/chrome/updater/test/test_app/constants.h +++ b/chrome/updater/test/test_app/constants.h
@@ -5,7 +5,6 @@ #ifndef CHROME_UPDATER_TEST_TEST_APP_CONSTANTS_H_ #define CHROME_UPDATER_TEST_TEST_APP_CONSTANTS_H_ -#include "base/strings/string16.h" #include "build/build_config.h" namespace updater { @@ -22,10 +21,8 @@ // Initiates a foreground update through IPC. extern const char kForegroundUpdateSwitch[]; -#if defined(OS_WIN) -// Test app GUID. -extern const base::char16 kAppId[]; -#endif // defined(OS_WIN) +// The application ID of the test app. +extern const char kTestAppId[]; // Update process state machine. enum class UpdateStatus {
diff --git a/chrome/updater/test/test_app/test_app.cc b/chrome/updater/test/test_app/test_app.cc index 34f86f6..c27e9f7 100644 --- a/chrome/updater/test/test_app/test_app.cc +++ b/chrome/updater/test/test_app/test_app.cc
@@ -43,8 +43,6 @@ const std::string& version, int64_t size, const base::string16& message); - - scoped_refptr<UpdateClient> update_client; }; void TestApp::SetUpdateStatus(UpdateStatus status, @@ -83,19 +81,17 @@ } void TestApp::Register() { - update_client->Register(base::BindRepeating(&TestApp::Shutdown, this)); + UpdateClient::Create()->Register(base::BindOnce(&TestApp::Shutdown, this)); } void TestApp::DoForegroundUpdate() { - update_client->CheckForUpdate( + UpdateClient::Create()->CheckForUpdate( base::BindRepeating(&TestApp::SetUpdateStatus, this)); } void TestApp::ParseCommandLine() { const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - update_client = UpdateClient::Create(); - if (command_line->HasSwitch(kInstallUpdaterSwitch)) { base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock()}, base::BindOnce(&InstallUpdater), @@ -107,7 +103,17 @@ } else if (command_line->HasSwitch(kRegisterUpdaterSwitch)) { base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock()}, base::BindOnce(&InstallUpdater), - base::BindOnce(&TestApp::Shutdown, this)); + base::BindOnce( + [](base::OnceClosure register_func, + base::OnceCallback<void(int)> shutdown_func, int error) { + if (error) { + std::move(shutdown_func).Run(error); + return; + } + std::move(register_func).Run(); + }, + base::BindOnce(&TestApp::Register, this), + base::BindOnce(&TestApp::Shutdown, this))); } else { Shutdown(0); }
diff --git a/chrome/updater/test/test_app/test_app_mac.mm b/chrome/updater/test/test_app/test_app_mac.mm index b67ea5ff..3b95baa 100644 --- a/chrome/updater/test/test_app/test_app_mac.mm +++ b/chrome/updater/test/test_app/test_app_mac.mm
@@ -63,9 +63,7 @@ } base::CommandLine command(updater_executable_path); - command.AppendSwitch(kRegisterSwitch); - command.AppendSwitchASCII(kAppIdSwitch, TEST_APP_FULLNAME_STRING); - command.AppendSwitchASCII(kAppVersionSwitch, TEST_APP_VERSION_STRING); + command.AppendSwitch(kInstallSwitch); command.AppendSwitchASCII("--vmodule", "*/updater/*=2"); std::string output;
diff --git a/chrome/updater/test/test_app/update_client.cc b/chrome/updater/test/test_app/update_client.cc index 249f7a1..a3e653b 100644 --- a/chrome/updater/test/test_app/update_client.cc +++ b/chrome/updater/test/test_app/update_client.cc
@@ -29,11 +29,10 @@ return CanDialIPC(); } -void UpdateClient::Register(base::RepeatingCallback<void(int)> callback) { - registration_callback_ = std::move(callback); - +void UpdateClient::Register(base::OnceCallback<void(int)> callback) { BeginRegister({}, {}, TEST_APP_VERSION_STRING, - base::BindOnce(&UpdateClient::RegistrationCompleted, this)); + base::BindOnce(&UpdateClient::RegistrationCompleted, this, + std::move(callback))); } void UpdateClient::CheckForUpdate(StatusCallback callback) { @@ -84,15 +83,15 @@ base::string16())); } -void UpdateClient::RegistrationCompleted(UpdateService::Result result) { +void UpdateClient::RegistrationCompleted(base::OnceCallback<void(int)> callback, + UpdateService::Result result) { if (result != UpdateService::Result::kSuccess) { LOG(ERROR) << "Updater registration error: " << base::NumberToString(static_cast<int>(result)); } callback_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(registration_callback_, static_cast<int>(result))); + FROM_HERE, base::BindOnce(std::move(callback), static_cast<int>(result))); } void UpdateClient::UpdateCompleted(UpdateService::Result result) {
diff --git a/chrome/updater/test/test_app/update_client.h b/chrome/updater/test/test_app/update_client.h index 331507b..0efad23fa 100644 --- a/chrome/updater/test/test_app/update_client.h +++ b/chrome/updater/test/test_app/update_client.h
@@ -35,10 +35,11 @@ UpdateClient(); - void Register(base::RepeatingCallback<void(int)> callback); + void Register(base::OnceCallback<void(int)> callback); void CheckForUpdate(StatusCallback callback); void HandleStatusUpdate(UpdateService::UpdateState update_state); - void RegistrationCompleted(UpdateService::Result result); + void RegistrationCompleted(base::OnceCallback<void(int)> callback, + UpdateService::Result result); void UpdateCompleted(UpdateService::Result result); protected: @@ -60,7 +61,6 @@ virtual bool CanDialIPC() = 0; StatusCallback callback_; - base::RepeatingCallback<void(int)> registration_callback_; scoped_refptr<base::SequencedTaskRunner> callback_task_runner_; };
diff --git a/chrome/updater/test/test_app/update_client_mac.mm b/chrome/updater/test/test_app/update_client_mac.mm index c029b3c..f9617d3 100644 --- a/chrome/updater/test/test_app/update_client_mac.mm +++ b/chrome/updater/test/test_app/update_client_mac.mm
@@ -20,6 +20,7 @@ #import "chrome/updater/app/server/mac/service_protocol.h" #import "chrome/updater/app/server/mac/update_service_wrappers.h" #import "chrome/updater/mac/xpc_service_names.h" +#include "chrome/updater/test/test_app/constants.h" #include "chrome/updater/test/test_app/test_app_version.h" @interface CRUUpdateClientOnDemandImpl : NSObject <CRUUpdateChecking> { @@ -132,8 +133,7 @@ static_cast<UpdateService::Result>(error))); }; - [client_.get() registerForUpdatesWithAppId:base::SysUTF8ToNSString( - base::mac::BaseBundleID()) + [client_.get() registerForUpdatesWithAppId:base::SysUTF8ToNSString(kTestAppId) brandCode:base::SysUTF8ToNSString(brand_code) tag:base::SysUTF8ToNSString(tag) version:base::SysUTF8ToNSString(version)
diff --git a/chrome/updater/test/test_app/update_client_win.cc b/chrome/updater/test/test_app/update_client_win.cc index 1ee50d4c..a15f681e9 100644 --- a/chrome/updater/test/test_app/update_client_win.cc +++ b/chrome/updater/test/test_app/update_client_win.cc
@@ -184,7 +184,8 @@ auto observer = Microsoft::WRL::Make<UpdaterObserver>(updater_, std::move(callback)); - HRESULT hr = updater_->Update(kAppId, observer.Get()); + HRESULT hr = + updater_->Update(base::ASCIIToUTF16(kTestAppId).c_str(), observer.Get()); if (FAILED(hr)) { LOG(ERROR) << "Failed to call IUpdater::UpdateAll " << std::hex << hr; UpdateService::UpdateState state;
diff --git a/chrome/updater/updater.cc b/chrome/updater/updater.cc index 8d3c475e..305491b 100644 --- a/chrome/updater/updater.cc +++ b/chrome/updater/updater.cc
@@ -13,7 +13,6 @@ #include "build/build_config.h" #include "chrome/updater/app/app.h" #include "chrome/updater/app/app_install.h" -#include "chrome/updater/app/app_register.h" #include "chrome/updater/app/app_uninstall.h" #include "chrome/updater/app/app_update.h" #include "chrome/updater/app/app_wake.h" @@ -104,10 +103,6 @@ if (command_line->HasSwitch(kUpdateSwitch)) return MakeAppUpdate()->Run(); - if (command_line->HasSwitch(kRegisterSwitch) && - command_line->HasSwitch(kAppIdSwitch)) - return MakeAppRegister()->Run(); - #if defined(OS_WIN) if (command_line->HasSwitch(kComServiceSwitch)) return ServiceMain::RunComService(command_line);
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn index 652a8f3..349a141 100644 --- a/chromeos/BUILD.gn +++ b/chromeos/BUILD.gn
@@ -318,6 +318,14 @@ # crbug.com/1114752 "arc.ContainerMount", + + # crbug.com/1131496 + "apps.LaunchHelpApp.clamshell_oobe_stable", + "apps.LaunchHelpApp.tablet_oobe_stable", + + # crbug.com/1131304 + "printer.PinPrintLexmark.no_pin", + "printer.PinPrintLexmark.pin", ] }
diff --git a/chromeos/components/diagnostics_ui/resources/battery_status_card.html b/chromeos/components/diagnostics_ui/resources/battery_status_card.html index e24ab02..2dceffd9 100644 --- a/chromeos/components/diagnostics_ui/resources/battery_status_card.html +++ b/chromeos/components/diagnostics_ui/resources/battery_status_card.html
@@ -8,5 +8,10 @@ </div> <div slot="body"> <div id="manufacturer">[[batteryInfo_.manufacturer]]</div> + <div id="chargeFullDesign">[[batteryHealth_.charge_full_design_milliamp_hours]]</div> + <div id="chargeFullNow">[[batteryChargeStatus_.charge_full_now_milliamp_hours]]</div> + <div id="chargeNow">[[batteryChargeStatus_.charge_now_milliamp_hours]]</div> + <div id="powerTime">[[batteryChargeStatus_.power_time]]</div> + <div id="adapterStatus">[[batteryChargeStatus_.power_adapter_status]]</div> </div> </diagnostics-card>
diff --git a/chromeos/components/diagnostics_ui/resources/battery_status_card.js b/chromeos/components/diagnostics_ui/resources/battery_status_card.js index 7662344..5893cff9 100644 --- a/chromeos/components/diagnostics_ui/resources/battery_status_card.js +++ b/chromeos/components/diagnostics_ui/resources/battery_status_card.js
@@ -6,7 +6,7 @@ import './diagnostics_shared_css.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {BatteryInfo, SystemDataProviderInterface} from './diagnostics_types.js' +import {BatteryChargeStatus, BatteryHealth, BatteryInfo, SystemDataProviderInterface} from './diagnostics_types.js' import {getSystemDataProvider} from './mojo_interface_provider.js'; /** @@ -24,6 +24,16 @@ systemDataProvider_: null, properties: { + /** @private {!BatteryChargeStatus} */ + batteryChargeStatus_: { + type: Object, + }, + + /** @private {!BatteryHealth} */ + batteryHealth_: { + type: Object, + }, + /** @private {!BatteryInfo} */ batteryInfo_: { type: Object, @@ -34,6 +44,8 @@ created() { this.systemDataProvider_ = getSystemDataProvider(); this.fetchBatteryInfo_(); + this.observeBatteryChargeStatus_(); + this.observeBatteryHealth_(); }, /** @private */ @@ -50,4 +62,30 @@ this.batteryInfo_ = batteryInfo; }, + /** @private */ + observeBatteryChargeStatus_() { + this.systemDataProvider_.observeBatteryChargeStatus(this); + }, + + /** + * Implements BatteryChargeStatusObserver.onBatteryChargeStatusUpdated() + * @param {!BatteryChargeStatus} batteryChargeStatus + */ + onBatteryChargeStatusUpdated(batteryChargeStatus) { + this.batteryChargeStatus_ = batteryChargeStatus; + }, + + /** @private */ + observeBatteryHealth_() { + this.systemDataProvider_.observeBatteryHealth(this); + }, + + /** + * Implements BatteryHealthObserver.onBatteryHealthUpdated() + * @param {!BatteryHealth} batteryHealth + */ + onBatteryHealthUpdated(batteryHealth) { + this.batteryHealth_ = batteryHealth; + }, + });
diff --git a/chromeos/components/diagnostics_ui/resources/diagnostics_types.js b/chromeos/components/diagnostics_ui/resources/diagnostics_types.js index aee3554..75820e0 100644 --- a/chromeos/components/diagnostics_ui/resources/diagnostics_types.js +++ b/chromeos/components/diagnostics_ui/resources/diagnostics_types.js
@@ -11,18 +11,39 @@ */ /** + * Type of SystemDataProviderInterface.ObserveBatteryChargeStatus function. + * @typedef {!function(!BatteryChargeStatusObserver): !Promise} + */ +export let ObserveBatteryChargeStatusFunction; + +/** + * Type of SystemDataProviderInterface.ObserveBatteryHealth function. + * @typedef {!function(!BatteryHealthObserver): !Promise} + */ +export let ObserveBatteryHealthFunction; + +/** * Type of SystemDataProviderInterface.ObserveCpuUsage function. * @typedef {!function(!CpuUsageObserver): !Promise} */ export let ObserveCpuUsageFunction; /** + * Type of SystemDataProviderInterface.ObserveMemoryUsage function. + * @typedef {!function(!MemoryUsageObserver): !Promise} + */ +export let ObserveMemoryUsageFunction; + +/** * Type alias for the SystemDataProviderInterface. * TODO(zentaro): Replace with a real mojo type when implemented. * @typedef {{ * getBatteryInfo: !function(): !Promise<!BatteryInfo>, * getSystemInfo: !function(): !Promise<!SystemInfo>, + * observeBatteryChargeStatus: !ObserveBatteryChargeStatusFunction, + * observeBatteryHealth: !ObserveBatteryHealthFunction, * observeCpuUsage: !ObserveCpuUsageFunction, + * observeMemoryUsage: !ObserveMemoryUsageFunction, * }} */ export let SystemDataProviderInterface; @@ -82,3 +103,70 @@ * }} */ export let CpuUsage; + +/** + * Type alias for BatteryChargeStatusObserver. + * @typedef {{ + * onBatteryChargeStatusUpdated: !function(!BatteryChargeStatus) + * }} + */ +export let BatteryChargeStatusObserver; + +/** + * External power source enumeration. + * @enum {number} + */ +export let ExternalPowerSource = { + kAc: 0, + kUsb: 1, + kDisconnected: 2, +}; + +/** + * Type alias for BatteryChargeStatus. + * @typedef {{ + * charge_full_now_milliamp_hours: number, + * charge_now_milliamp_hours: number, + * current_now_milliamps: number, + * power_adapter_status: ExternalPowerSource, + * power_time: string, + * }} + */ +export let BatteryChargeStatus; + +/** + * Type alias for BatteryHealthObserver. + * @typedef {{ + * onBatteryHealthUpdated: !function(!BatteryHealth) + * }} + */ +export let BatteryHealthObserver; + +/** + * Type alias for BatteryHealth. + * @typedef {{ + * battery_wear_percentage: number, + * charge_full_design_milliamp_hours: number, + * charge_full_now_milliamp_hours: number, + * cycle_count: number, + * }} + */ +export let BatteryHealth; + +/** + * Type alias for MemoryUsageObserver. + * @typedef {{ + * onMemoryUsageUpdated: !function(!MemoryUsage) + * }} + */ +export let MemoryUsageObserver; + +/** + * Type alias for MemoryUsage. + * @typedef {{ + * available_memory_kib: number, + * free_memory_kib: number, + * total_memory_kib: number, + * }} + */ +export let MemoryUsage;
diff --git a/chromeos/components/diagnostics_ui/resources/fake_data.js b/chromeos/components/diagnostics_ui/resources/fake_data.js index 2bd96086..ceb300c 100644 --- a/chromeos/components/diagnostics_ui/resources/fake_data.js +++ b/chromeos/components/diagnostics_ui/resources/fake_data.js
@@ -2,7 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {CpuUsage, SystemInfo} from './diagnostics_types.js' +import {BatteryChargeStatus, BatteryHealth, CpuUsage, ExternalPowerSource, MemoryUsage, SystemInfo} from './diagnostics_types.js' + +/* @type {!Array<!BatteryChargeStatus>} */ +export const fakeBatteryChargeStatus = [{ + charge_full_now_milliamp_hours: 6000, + charge_now_milliamp_hours: 4200, + current_now_milliamps: 1123, + power_adapter_status: ExternalPowerSource.kAc, + power_time: '3h 15m', +}]; + +/* @type {!Array<!BatteryHealth>} */ +export const fakeBatteryHealth = [{ + battery_wear_percentage: 7, + charge_full_design_milliamp_hours: 6000, + charge_full_now_milliamp_hours: 5700, + cycle_count: 73, +}]; /* @type {!BatteryInfo} */ export const fakeBatteryInfo = { @@ -17,6 +34,13 @@ percent_usage_user: 20, }]; +/* @type {!Array<!MemoryUsage>} */ +export const fakeMemoryUsage = [{ + available_memory_kib: 57000, + free_memory_kib: 15000, + total_memory_kib: 128000, +}]; + /* @type {!SystemInfo} */ export const fakeSystemInfo = { board_name: 'CrOS Board',
diff --git a/chromeos/components/diagnostics_ui/resources/fake_observables.js b/chromeos/components/diagnostics_ui/resources/fake_observables.js index eff773b..3014160 100644 --- a/chromeos/components/diagnostics_ui/resources/fake_observables.js +++ b/chromeos/components/diagnostics_ui/resources/fake_observables.js
@@ -37,9 +37,6 @@ /** @param {!Array<!T>} observations */ setObservableData(observations) { - // TODO(zentaro): Fully support multiple observations. - assert(observations.length == 1); - this.observations_ = observations; this.index_ = 0; }
diff --git a/chromeos/components/diagnostics_ui/resources/fake_system_data_provider.js b/chromeos/components/diagnostics_ui/resources/fake_system_data_provider.js index 92e4fa90..5f37a3f 100644 --- a/chromeos/components/diagnostics_ui/resources/fake_system_data_provider.js +++ b/chromeos/components/diagnostics_ui/resources/fake_system_data_provider.js
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {BatteryInfo, CpuUsage, CpuUsageObserver, SystemInfo} from './diagnostics_types.js'; +import {BatteryChargeStatus, BatteryHealth, BatteryInfo, CpuUsage, CpuUsageObserver, ExternalPowerSource, MemoryUsage, MemoryUsageObserver, SystemInfo} from './diagnostics_types.js'; import {FakeMethodResolver} from './fake_method_resolver.js'; import {FakeObservables} from './fake_observables.js'; @@ -24,7 +24,11 @@ this.methods_.register('getBatteryInfo'); // Setup observables. + this.observables_.register( + 'BatteryChargeStatusObserver_onBatteryChargeStatusUpdated'); + this.observables_.register('BatteryHealthObserver_onBatteryHealthUpdated'); this.observables_.register('CpuUsageObserver_onCpuUsageUpdated'); + this.observables_.register('MemoryUsageObserver_onMemoryUsageUpdated'); } /** @@ -59,6 +63,63 @@ } /* + * Implements SystemDataProviderInterface.ObserveBatteryChargeStatus. + * @param {!BatteryChargeStatusObserver} remote + * @return {!Promise} + */ + observeBatteryChargeStatus(remote) { + return new Promise((resolve) => { + this.observables_.observe( + 'BatteryChargeStatusObserver_onBatteryChargeStatusUpdated', + (batteryChargeStatus) => { + remote.onBatteryChargeStatusUpdated( + /** @type {!BatteryChargeStatus} */ (batteryChargeStatus)); + }); + + this.observables_.trigger( + 'BatteryChargeStatusObserver_onBatteryChargeStatusUpdated'); + resolve(); + }); + } + + /** + * Sets the values that will observed from observeBatteryChargeStatus. + * @param {!Array<!BatteryChargeStatus>} batteryChargeStatusList + */ + setFakeBatteryChargeStatus(batteryChargeStatusList) { + this.observables_.setObservableData( + 'BatteryChargeStatusObserver_onBatteryChargeStatusUpdated', + batteryChargeStatusList); + } + + /* + * Implements SystemDataProviderInterface.ObserveBatteryHealth. + * @param {!BatteryHealthObserver} remote + * @return {!Promise} + */ + observeBatteryHealth(remote) { + return new Promise((resolve) => { + this.observables_.observe( + 'BatteryHealthObserver_onBatteryHealthUpdated', (batteryHealth) => { + remote.onBatteryHealthUpdated( + /** @type {!BatteryHealth} */ (batteryHealth)); + }); + + this.observables_.trigger('BatteryHealthObserver_onBatteryHealthUpdated'); + resolve(); + }); + } + + /** + * Sets the values that will observed from observeBatteryHealth. + * @param {!Array<!BatteryHealth>} batteryHealthList + */ + setFakeBatteryHealth(batteryHealthList) { + this.observables_.setObservableData( + 'BatteryHealthObserver_onBatteryHealthUpdated', batteryHealthList); + } + + /* * Implements SystemDataProviderInterface.ObserveCpuUsage. * @param {!CpuUsageObserver} remote * @return {!Promise} @@ -84,4 +145,31 @@ this.observables_.setObservableData( 'CpuUsageObserver_onCpuUsageUpdated', cpuUsageList); } + + /* + * Implements SystemDataProviderInterface.ObserveMemoryUsage. + * @param {!MemoryUsageObserver} remote + * @return {!Promise} + */ + observeMemoryUsage(remote) { + return new Promise((resolve) => { + this.observables_.observe( + 'MemoryUsageObserver_onMemoryUsageUpdated', (memoryUsage) => { + remote.onMemoryUsageUpdated( + /** @type {!MemoryUsage} */ (memoryUsage)); + }); + + this.observables_.trigger('MemoryUsageObserver_onMemoryUsageUpdated'); + resolve(); + }); + } + + /** + * Sets the values that will observed from ObserveCpuUsage. + * @param {!Array<!MemoryUsage>} memoryUsageList + */ + setFakeMemoryUsage(memoryUsageList) { + this.observables_.setObservableData( + 'MemoryUsageObserver_onMemoryUsageUpdated', memoryUsageList); + } }
diff --git a/chromeos/components/diagnostics_ui/resources/memory_card.html b/chromeos/components/diagnostics_ui/resources/memory_card.html index 8411d301..80ae8cbc 100644 --- a/chromeos/components/diagnostics_ui/resources/memory_card.html +++ b/chromeos/components/diagnostics_ui/resources/memory_card.html
@@ -7,5 +7,8 @@ <div id="cardTitle">Memory</div> </div> <div slot="body"> + <div id="memoryTotal">[[memoryUsage_.total_memory_kib]]</div> + <div id="memoryAvailable">[[memoryUsage_.available_memory_kib]]</div> + <div id="memoryFree">[[memoryUsage_.free_memory_kib]]</div> </div> </diagnostics-card>
diff --git a/chromeos/components/diagnostics_ui/resources/memory_card.js b/chromeos/components/diagnostics_ui/resources/memory_card.js index 1310f2eb..f863b27 100644 --- a/chromeos/components/diagnostics_ui/resources/memory_card.js +++ b/chromeos/components/diagnostics_ui/resources/memory_card.js
@@ -6,7 +6,7 @@ import './diagnostics_shared_css.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {SystemDataProviderInterface} from './diagnostics_types.js' +import {MemoryUsage, SystemDataProviderInterface} from './diagnostics_types.js' import {getSystemDataProvider} from './mojo_interface_provider.js'; /** @@ -23,9 +23,30 @@ */ systemDataProvider_: null, + properties: { + /** @private {!MemoryUsage} */ + memoryUsage_: { + type: Object, + }, + }, + /** @override */ created() { this.systemDataProvider_ = getSystemDataProvider(); + this.observeMemoryUsage_(); + }, + + /** @private */ + observeMemoryUsage_() { + this.systemDataProvider_.observeMemoryUsage(this); + }, + + /** + * Implements MemoryUsageObserver.onMemoryUsageUpdated() + * @param {!MemoryUsage} memoryUsage + */ + onMemoryUsageUpdated(memoryUsage) { + this.memoryUsage_ = memoryUsage; }, });
diff --git a/chromeos/components/diagnostics_ui/resources/mojo_interface_provider.js b/chromeos/components/diagnostics_ui/resources/mojo_interface_provider.js index ae404ca..edec27a 100644 --- a/chromeos/components/diagnostics_ui/resources/mojo_interface_provider.js +++ b/chromeos/components/diagnostics_ui/resources/mojo_interface_provider.js
@@ -4,7 +4,7 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {SystemDataProviderInterface, SystemInfo} from './diagnostics_types.js' -import {fakeBatteryInfo, fakeCpuUsage, fakeSystemInfo} from './fake_data.js' +import {fakeBatteryChargeStatus, fakeBatteryHealth, fakeBatteryInfo, fakeCpuUsage, fakeMemoryUsage, fakeSystemInfo} from './fake_data.js' import {FakeSystemDataProvider} from './fake_system_data_provider.js' /** @@ -22,8 +22,11 @@ let provider = new FakeSystemDataProvider(); // Setup fake method data. + provider.setFakeBatteryChargeStatus(fakeBatteryChargeStatus); + provider.setFakeBatteryHealth(fakeBatteryHealth); provider.setFakeBatteryInfo(fakeBatteryInfo); provider.setFakeCpuUsage(fakeCpuUsage); + provider.setFakeMemoryUsage(fakeMemoryUsage); provider.setFakeSystemInfo(fakeSystemInfo); // Set the fake provider.
diff --git a/chromeos/components/telemetry_extension_ui/resources/message_types.js b/chromeos/components/telemetry_extension_ui/resources/message_types.js index 9596410..9044c31a 100644 --- a/chromeos/components/telemetry_extension_ui/resources/message_types.js +++ b/chromeos/components/telemetry_extension_ui/resources/message_types.js
@@ -128,7 +128,7 @@ /** * Request message sent by the unprivileged context to the privileged - * context to run NVME wear level routine. + * context to run NVMe wear level routine. * @typedef {{ wearLevelThreshold: !number }} */ dpsl_internal.DiagnosticsRunNvmeWearLevelRoutineRequest;
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 2c5583f7..320c162a 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -366,12 +366,6 @@ // ChromeOS Media App. https://crbug.com/996088. const base::Feature kMediaApp{"MediaApp", base::FEATURE_ENABLED_BY_DEFAULT}; -// Controls whether to use screen priorities to decide if transition from one -// Oobe screen to another is allowed. -// TODO(https://crbug.com/1064271): Remove this flag once the feature is stable. -const base::Feature kOobeScreensPriority{"OobeScreensPriority", - base::FEATURE_ENABLED_BY_DEFAULT}; - // Enables a unique URL for each path in CrOS settings. // This allows deep linking to individual settings, i.e. in settings search. const base::Feature kOsSettingsDeepLinking{"OsSettingsDeepLinking", @@ -644,10 +638,6 @@ return base::FeatureList::IsEnabled(kClipboardHistory); } -bool IsOobeScreensPriorityEnabled() { - return base::FeatureList::IsEnabled(kOobeScreensPriority); -} - bool IsParentalControlsSettingsEnabled() { return base::FeatureList::IsEnabled(kParentalControlsSettings); }
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index 79815db1..968a2d8 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -162,8 +162,6 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kMinimumChromeVersion; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) -extern const base::Feature kOobeScreensPriority; -COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kOsSettingsDeepLinking; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kOsSettingsPolymer3;
diff --git a/components/BUILD.gn b/components/BUILD.gn index ebf7e34..cd01d8c 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -224,6 +224,7 @@ "//components/autofill/content/browser:unit_tests", "//components/autofill/content/renderer:unit_tests", "//components/autofill/core/common/mojom:unit_tests", + "//components/background_sync:unit_tests", "//components/blocked_content:unit_tests", "//components/browsing_data/content:unit_tests", "//components/captive_portal/content:unit_tests",
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index 2afc2399..a5bbd3b 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -186,11 +186,6 @@ const base::Feature kAutofillOffNoServerData{"AutofillOffNoServerData", base::FEATURE_DISABLED_BY_DEFAULT}; -// When enabled, autofill server will override field types with rater -// consensus data before returning to client. -const base::Feature kAutofillOverrideWithRaterConsensus{ - "AutofillOverrideWithRaterConsensus", base::FEATURE_DISABLED_BY_DEFAULT}; - // If feature is enabled, autofill will be disabled for mixed forms (forms on // HTTPS sites that submit over HTTP). const base::Feature kAutofillPreventMixedFormsFilling{ @@ -252,12 +247,6 @@ const base::Feature kAutofillServerCommunication{ "AutofillServerCommunication", base::FEATURE_ENABLED_BY_DEFAULT}; -// Controls whether autofill suggestions are filtered by field values previously -// filled by website. -const base::Feature kAutofillShowAllSuggestionsOnPrefilledForms{ - "AutofillShowAllSuggestionsOnPrefilledForms", - base::FEATURE_DISABLED_BY_DEFAULT}; - // Controls whether we show warnings in the Dev console for misused autocomplete // types. const base::Feature kAutofillShowAutocompleteConsoleWarnings{ @@ -289,6 +278,7 @@ const base::Feature kAutofillTouchToFill = {"TouchToFillAndroid", base::FEATURE_ENABLED_BY_DEFAULT}; +// Autofill upload throttling is used for testing. const base::Feature kAutofillUploadThrottling{"AutofillUploadThrottling", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h index 0e98b086..6337edb 100644 --- a/components/autofill/core/common/autofill_features.h +++ b/components/autofill/core/common/autofill_features.h
@@ -53,7 +53,6 @@ extern const base::Feature kAutofillPruneSuggestions; extern const base::Feature kAutofillMetadataUploads; extern const base::Feature kAutofillOffNoServerData; -extern const base::Feature kAutofillOverrideWithRaterConsensus; extern const base::Feature kAutofillPreventMixedFormsFilling; extern const base::Feature kAutofillProbableFormSubmissionInBrowser; extern const base::Feature kAutofillProfileClientValidation; @@ -65,7 +64,6 @@ extern const base::Feature kAutofillSaveAndFillVPA; extern const base::Feature kAutofillSectionUponRedundantNameInfo; extern const base::Feature kAutofillServerCommunication; -extern const base::Feature kAutofillShowAllSuggestionsOnPrefilledForms; extern const base::Feature kAutofillShowAutocompleteConsoleWarnings; extern const base::Feature kAutofillShowTypePredictions; extern const base::Feature kAutofillSkipComparingInferredLabels;
diff --git a/components/autofill/core/common/mojom/BUILD.gn b/components/autofill/core/common/mojom/BUILD.gn index a50148a..4c3ab8a 100644 --- a/components/autofill/core/common/mojom/BUILD.gn +++ b/components/autofill/core/common/mojom/BUILD.gn
@@ -57,10 +57,6 @@ cpp = "::autofill::PasswordAndMetadata" }, { - mojom = "autofill.mojom.PasswordForm" - cpp = "::autofill::PasswordForm" - }, - { mojom = "autofill.mojom.PasswordFormFieldPredictionMap" cpp = "::autofill::PasswordFormFieldPredictionMap" },
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc b/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc index 996e882..bc85d1d 100644 --- a/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc +++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc
@@ -239,13 +239,6 @@ std::move(closure).Run(); } -void ExpectPasswordForm(const PasswordForm& expected, - base::OnceClosure closure, - const PasswordForm& passed) { - EXPECT_EQ(expected, passed); - std::move(closure).Run(); -} - TEST_F(AutofillTypeTraitsTestImpl, PassFormFieldData) { FormFieldData input; test::CreateTestSelectField("TestLabel", "TestName", "TestValue", kOptions,
diff --git a/components/autofill/core/common/password_form.cc b/components/autofill/core/common/password_form.cc index 4957609..6585faa 100644 --- a/components/autofill/core/common/password_form.cc +++ b/components/autofill/core/common/password_form.cc
@@ -84,6 +84,16 @@ return ostream.str(); } +base::string16 ValueElementVectorToString( + const ValueElementVector& value_element_pairs) { + std::vector<base::string16> pairs(value_element_pairs.size()); + std::transform(value_element_pairs.begin(), value_element_pairs.end(), + pairs.begin(), [](const ValueElementPair& p) { + return p.first + base::ASCIIToUTF16("+") + p.second; + }); + return base::JoinString(pairs, base::ASCIIToUTF16(", ")); +} + // Serializes a PasswordForm to a JSON object. Used only for logging in tests. void PasswordFormToJSON(const PasswordForm& form, base::DictionaryValue* target) { @@ -256,16 +266,6 @@ left.password_element == right.password_element); } -base::string16 ValueElementVectorToString( - const ValueElementVector& value_element_pairs) { - std::vector<base::string16> pairs(value_element_pairs.size()); - std::transform(value_element_pairs.begin(), value_element_pairs.end(), - pairs.begin(), [](const ValueElementPair& p) { - return p.first + base::ASCIIToUTF16("+") + p.second; - }); - return base::JoinString(pairs, base::ASCIIToUTF16(", ")); -} - std::ostream& operator<<(std::ostream& os, PasswordForm::Scheme scheme) { return os << ToString(scheme); }
diff --git a/components/autofill/core/common/password_form.h b/components/autofill/core/common/password_form.h index 2ecbb50d..3d3e786 100644 --- a/components/autofill/core/common/password_form.h +++ b/components/autofill/core/common/password_form.h
@@ -48,7 +48,8 @@ // The field descriptions in the struct specification below are intended to // describe which fields are not strictly required when adding a saved password // entry to the database and how they can affect the matching process. - +// +// TODO(crbug.com/1067347): Move complete class to password_manager namespace. struct PasswordForm { // Enum to differentiate between HTML form based authentication, and dialogs // using basic or digest schemes. Default is kHtml. Only PasswordForms of the @@ -377,10 +378,6 @@ bool ArePasswordFormUniqueKeysEqual(const PasswordForm& left, const PasswordForm& right); -// Converts a vector of ValueElementPair to string. -base::string16 ValueElementVectorToString( - const ValueElementVector& value_element_pairs); - // For testing. std::ostream& operator<<(std::ostream& os, PasswordForm::Scheme scheme); std::ostream& operator<<(std::ostream& os, const PasswordForm& form);
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc index 0db873c..46fc274 100644 --- a/components/autofill_assistant/browser/controller.cc +++ b/components/autofill_assistant/browser/controller.cc
@@ -289,11 +289,8 @@ return false; } - SetProgressActiveStep( - std::distance( - step_progress_bar_configuration_->annotated_step_icons().cbegin(), - it) + - 1); + SetProgressActiveStep(std::distance( + step_progress_bar_configuration_->annotated_step_icons().cbegin(), it)); return true; }
diff --git a/components/autofill_assistant/browser/controller_unittest.cc b/components/autofill_assistant/browser/controller_unittest.cc index 0852c4bda..8a15459 100644 --- a/components/autofill_assistant/browser/controller_unittest.cc +++ b/components/autofill_assistant/browser/controller_unittest.cc
@@ -745,7 +745,7 @@ EXPECT_EQ(3, *controller_->GetProgressActiveStep()); } -TEST_F(ControllerTest, SetProgressStepFromIdentifierFails) { +TEST_F(ControllerTest, SetProgressStepFromIdentifier) { Start(); ShowProgressBarProto::StepProgressBarConfiguration config; @@ -754,9 +754,9 @@ config.add_annotated_step_icons()->set_identifier("icon2"); controller_->SetStepProgressBarConfiguration(config); - EXPECT_CALL(mock_observer_, OnProgressActiveStepChanged(2)).Times(1); + EXPECT_CALL(mock_observer_, OnProgressActiveStepChanged(1)).Times(1); EXPECT_TRUE(controller_->SetProgressActiveStepIdentifier("icon2")); - EXPECT_EQ(2, *controller_->GetProgressActiveStep()); + EXPECT_EQ(1, *controller_->GetProgressActiveStep()); } TEST_F(ControllerTest, SetProgressStepFromUnknownIdentifier) {
diff --git a/components/background_sync/BUILD.gn b/components/background_sync/BUILD.gn new file mode 100644 index 0000000..30728a5 --- /dev/null +++ b/components/background_sync/BUILD.gn
@@ -0,0 +1,34 @@ +# Copyright 2020 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. + +static_library("background_sync") { + sources = [ + "background_sync_permission_context.cc", + "background_sync_permission_context.h", + ] + + deps = [ + "//components/content_settings/core/browser", + "//components/content_settings/core/common", + "//components/permissions", + "//third_party/blink/public/common:headers", + ] +} + +source_set("unit_tests") { + testonly = true + sources = [ "background_sync_permission_context_unittest.cc" ] + + deps = [ + ":background_sync", + "//base", + "//components/content_settings/core/browser", + "//components/permissions", + "//components/permissions:test_support", + "//content/public/browser", + "//content/test:test_support", + "//testing/gtest", + "//url:url", + ] +}
diff --git a/components/background_sync/DEPS b/components/background_sync/DEPS new file mode 100644 index 0000000..d703f09 --- /dev/null +++ b/components/background_sync/DEPS
@@ -0,0 +1,7 @@ +include_rules = [ + "+components/content_settings/core", + "+components/permissions", + "+content/public/browser", + "+content/public/test", + "+third_party/blink/public/mojom", +]
diff --git a/components/background_sync/OWNERS b/components/background_sync/OWNERS new file mode 100644 index 0000000..ef947b20 --- /dev/null +++ b/components/background_sync/OWNERS
@@ -0,0 +1,10 @@ +iclelland@chromium.org +jkarlin@chromium.org +nator@chromium.org +peter@chromium.org +rayankans@chromium.org + +per-file *permission_context*=file://components/permissions/PERMISSIONS_OWNERS + +# COMPONENT: Blink>BackgroundSync +# TEAM: platform-capabilities@chromium.org
diff --git a/chrome/browser/background_sync/background_sync_permission_context.cc b/components/background_sync/background_sync_permission_context.cc similarity index 93% rename from chrome/browser/background_sync/background_sync_permission_context.cc rename to components/background_sync/background_sync_permission_context.cc index c412c40..722b94a 100644 --- a/chrome/browser/background_sync/background_sync_permission_context.cc +++ b/components/background_sync/background_sync_permission_context.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/background_sync/background_sync_permission_context.h" +#include "components/background_sync/background_sync_permission_context.h" #include "base/notreached.h" #include "components/content_settings/core/common/content_settings_types.h"
diff --git a/chrome/browser/background_sync/background_sync_permission_context.h b/components/background_sync/background_sync_permission_context.h similarity index 85% rename from chrome/browser/background_sync/background_sync_permission_context.h rename to components/background_sync/background_sync_permission_context.h index 9fad455..c3ea6d20 100644 --- a/chrome/browser/background_sync/background_sync_permission_context.h +++ b/components/background_sync/background_sync_permission_context.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_PERMISSION_CONTEXT_H_ -#define CHROME_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_PERMISSION_CONTEXT_H_ +#ifndef COMPONENTS_BACKGROUND_SYNC_BACKGROUND_SYNC_PERMISSION_CONTEXT_H_ +#define COMPONENTS_BACKGROUND_SYNC_BACKGROUND_SYNC_PERMISSION_CONTEXT_H_ #include "base/macros.h" #include "components/permissions/permission_context_base.h" @@ -36,4 +36,4 @@ DISALLOW_COPY_AND_ASSIGN(BackgroundSyncPermissionContext); }; -#endif // CHROME_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_PERMISSION_CONTEXT_H_ +#endif // COMPONENTS_BACKGROUND_SYNC_BACKGROUND_SYNC_PERMISSION_CONTEXT_H_
diff --git a/chrome/browser/background_sync/background_sync_permission_context_unittest.cc b/components/background_sync/background_sync_permission_context_unittest.cc similarity index 83% rename from chrome/browser/background_sync/background_sync_permission_context_unittest.cc rename to components/background_sync/background_sync_permission_context_unittest.cc index 50fc9bd..2fe06a1 100644 --- a/chrome/browser/background_sync/background_sync_permission_context_unittest.cc +++ b/components/background_sync/background_sync_permission_context_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/background_sync/background_sync_permission_context.h" +#include "components/background_sync/background_sync_permission_context.h" #include <string> @@ -10,25 +10,24 @@ #include "base/callback_helpers.h" #include "base/macros.h" #include "base/run_loop.h" -#include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "chrome/test/base/testing_profile.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/permissions/permission_request_id.h" +#include "components/permissions/permissions_client.h" +#include "components/permissions/test/test_permissions_client.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/test/mock_render_process_host.h" +#include "content/public/test/test_renderer_host.h" #include "content/public/test/web_contents_tester.h" #include "testing/gtest/include/gtest/gtest.h" class BackgroundSyncPermissionContextTest - : public ChromeRenderViewHostTestHarness { + : public content::RenderViewHostTestHarness { protected: BackgroundSyncPermissionContextTest() = default; - ~BackgroundSyncPermissionContextTest() override = default; void NavigateAndRequestPermission( @@ -58,6 +57,9 @@ bool permission_granted() const { return permission_granted_; } + protected: + permissions::TestPermissionsClient client_; + private: bool permission_granted_; @@ -67,7 +69,7 @@ // Background sync permission should be allowed by default for a secure origin. TEST_F(BackgroundSyncPermissionContextTest, TestSecureRequestingUrl) { GURL url("https://www.example.com"); - BackgroundSyncPermissionContext permission_context(profile()); + BackgroundSyncPermissionContext permission_context(browser_context()); NavigateAndRequestPermission(url, &permission_context); @@ -77,7 +79,7 @@ // Background sync permission should be denied for an insecure origin. TEST_F(BackgroundSyncPermissionContextTest, TestInsecureRequestingUrl) { GURL url("http://example.com"); - BackgroundSyncPermissionContext permission_context(profile()); + BackgroundSyncPermissionContext permission_context(browser_context()); NavigateAndRequestPermission(url, &permission_context); @@ -88,8 +90,9 @@ TEST_F(BackgroundSyncPermissionContextTest, TestBlockOrigin) { GURL url1("https://www.example1.com"); GURL url2("https://www.example2.com"); - BackgroundSyncPermissionContext permission_context(profile()); - HostContentSettingsMapFactory::GetForProfile(profile()) + BackgroundSyncPermissionContext permission_context(browser_context()); + permissions::PermissionsClient::Get() + ->GetSettingsMap(browser_context()) ->SetContentSettingDefaultScope(url1, GURL(), ContentSettingsType::BACKGROUND_SYNC, std::string(), CONTENT_SETTING_BLOCK);
diff --git a/components/browser_ui/contacts_picker/android/java/res/layout/contacts_list_item_view.xml b/components/browser_ui/contacts_picker/android/java/res/layout/contacts_list_item_view.xml index af91fe7..f537236 100644 --- a/components/browser_ui/contacts_picker/android/java/res/layout/contacts_list_item_view.xml +++ b/components/browser_ui/contacts_picker/android/java/res/layout/contacts_list_item_view.xml
@@ -4,7 +4,8 @@ found in the LICENSE file. --> <merge - xmlns:android="http://schemas.android.com/apk/res/android"> + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools"> <org.chromium.ui.widget.ChromeImageView android:id="@+id/icon_view" @@ -105,5 +106,6 @@ android:layout_height="32dp" android:layout_marginEnd="10dp" android:src="@drawable/btn_star_filled" - android:visibility="gone" /> + android:visibility="gone" + tools:ignore="ContentDescription"/> </merge>
diff --git a/components/browser_ui/photo_picker/android/java/res/layout/photo_picker_dialog.xml b/components/browser_ui/photo_picker/android/java/res/layout/photo_picker_dialog.xml index 4552c9c..4005f019 100644 --- a/components/browser_ui/photo_picker/android/java/res/layout/photo_picker_dialog.xml +++ b/components/browser_ui/photo_picker/android/java/res/layout/photo_picker_dialog.xml
@@ -6,6 +6,7 @@ <org.chromium.ui.widget.OptimizedFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/default_bg_color_elev_0" > @@ -26,7 +27,8 @@ android:layout_centerHorizontal="true" android:background="@drawable/navigation_bubble_shadow" app:srcCompat="@drawable/zoom_in" - android:visibility="gone" /> + android:visibility="gone" + tools:ignore="ContentDescription"/> <org.chromium.components.browser_ui.photo_picker.PickerVideoPlayer android:layout_width="match_parent" @@ -35,4 +37,4 @@ android:background="@android:color/black" android:clickable="true" android:visibility="gone" /> -</org.chromium.ui.widget.OptimizedFrameLayout> \ No newline at end of file +</org.chromium.ui.widget.OptimizedFrameLayout>
diff --git a/components/browser_ui/site_settings/android/java/res/xml/single_website_preferences.xml b/components/browser_ui/site_settings/android/java/res/xml/single_website_preferences.xml index 20c55d9..d7ef87f 100644 --- a/components/browser_ui/site_settings/android/java/res/xml/single_website_preferences.xml +++ b/components/browser_ui/site_settings/android/java/res/xml/single_website_preferences.xml
@@ -16,6 +16,7 @@ <org.chromium.components.browser_ui.settings.ChromeBasePreference android:key="os_permissions_warning_extra" /> <Preference + android:selectable="false" android:key="os_permissions_warning_divider" android:layout="@layout/divider_preference" /> <org.chromium.components.browser_ui.settings.TextMessagePreference @@ -24,6 +25,7 @@ android:icon="@drawable/btn_info" app:iconTint="@color/default_icon_color" /> <Preference + android:selectable="false" android:key="intrusive_ads_info_divider" android:layout="@layout/divider_preference" /> <PreferenceCategory
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java index 40aef11..3aa67ad0 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
@@ -8,7 +8,6 @@ import android.app.Activity; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Build; @@ -131,9 +130,8 @@ PREF_CLEAR_DATA, }; - // Determines if this page will refresh its permissions display after clear and reset is - // clicked. - private boolean mRefreshAfterReset; + // The callback to be run after this site is reset. + private Runnable mWebsiteResetCallback; private static final int REQUEST_CODE_NOTIFICATION_CHANNEL_SETTINGS = 1; @@ -262,8 +260,8 @@ mHideNonPermissionPreferences = hide; } - public void setRefreshAfterReset(boolean refresh) { - mRefreshAfterReset = refresh; + public void setWebsiteResetCallback(Runnable callback) { + mWebsiteResetCallback = callback; } /** @@ -277,7 +275,7 @@ * @param websites The websites to search in. * @return The merged website. */ - private static Website mergePermissionAndStorageInfoForTopLevelOrigin( + public static Website mergePermissionAndStorageInfoForTopLevelOrigin( WebsiteAddress address, Collection<Website> websites) { String origin = address.getOrigin(); String host = Uri.parse(origin).getHost(); @@ -989,8 +987,7 @@ } private void popBackIfNoSettings() { - if (!hasPermissionsPreferences() && !hasUsagePreferences() && getActivity() != null - && !mRefreshAfterReset) { + if (!hasPermissionsPreferences() && !hasUsagePreferences() && getActivity() != null) { getActivity().finish(); } } @@ -1022,11 +1019,16 @@ .setTitle(R.string.website_reset) .setMessage(R.string.website_reset_confirmation) .setPositiveButton(R.string.website_reset, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { + (dialog, which) -> { + if (mHideNonPermissionPreferences) { + mSiteDataCleaner.resetPermissions( + getSiteSettingsClient().getBrowserContextHandle(), mSite); + } else { resetSite(); } + if (mWebsiteResetCallback != null) { + mWebsiteResetCallback.run(); + } }) .setNegativeButton(R.string.cancel, null) .show(); @@ -1057,6 +1059,7 @@ boolean finishActivityImmediately = mSite.getTotalUsage() == 0 && mObjectPolicyPermissionCount == 0; + mSiteDataCleaner.resetPermissions(getSiteSettingsClient().getBrowserContextHandle(), mSite); mSiteDataCleaner.clearData( getSiteSettingsClient().getBrowserContextHandle(), mSite, mDataClearedCallback); @@ -1065,9 +1068,7 @@ RecordHistogram.recordEnumeratedHistogram("SingleWebsitePreferences.NavigatedFromToReset", navigationSource, SettingsNavigationSource.NUM_ENTRIES); - if (mRefreshAfterReset) { - init(); - } else if (finishActivityImmediately) { + if (finishActivityImmediately) { getActivity().finish(); } }
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteDataCleaner.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteDataCleaner.java index e92fc84..fabc112a 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteDataCleaner.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteDataCleaner.java
@@ -22,7 +22,13 @@ WebsitePreferenceBridgeJni.get().clearCookieData(browserContextHandle, origin); WebsitePreferenceBridgeJni.get().clearBannerData(browserContextHandle, origin); WebsitePreferenceBridgeJni.get().clearMediaLicenses(browserContextHandle, origin); + site.clearAllStoredData(browserContextHandle, finishCallback::run); + } + /** + * Resets the permissions of the specified site. + */ + public void resetPermissions(BrowserContextHandle browserContextHandle, Website site) { // Clear the permissions. for (ContentSettingException exception : site.getContentSettingExceptions()) { site.setContentSettingPermission(browserContextHandle, @@ -36,7 +42,5 @@ for (ChosenObjectInfo info : site.getChosenObjectInfo()) { info.revoke(browserContextHandle); } - - site.clearAllStoredData(browserContextHandle, finishCallback::run); } }
diff --git a/components/content_settings/renderer/content_settings_agent_impl.cc b/components/content_settings/renderer/content_settings_agent_impl.cc index 3702512..5bdb837 100644 --- a/components/content_settings/renderer/content_settings_agent_impl.cc +++ b/components/content_settings/renderer/content_settings_agent_impl.cc
@@ -263,21 +263,20 @@ mojom::ContentSettingsManager::StorageType ContentSettingsAgentImpl::ConvertToMojoStorageType(StorageType storage_type) { switch (storage_type) { - case StorageType::kDatabase: { + case StorageType::kDatabase: return mojom::ContentSettingsManager::StorageType::DATABASE; - } - case StorageType::kIndexedDB: { + case StorageType::kIndexedDB: return mojom::ContentSettingsManager::StorageType::INDEXED_DB; - } - case StorageType::kCacheStorage: { + case StorageType::kCacheStorage: return mojom::ContentSettingsManager::StorageType::CACHE; - } - case StorageType::kWebLocks: { + case StorageType::kWebLocks: return mojom::ContentSettingsManager::StorageType::WEB_LOCKS; - } - case StorageType::kFileSystem: { + case StorageType::kFileSystem: return mojom::ContentSettingsManager::StorageType::FILE_SYSTEM; - } + case StorageType::kLocalStorage: + return mojom::ContentSettingsManager::StorageType::LOCAL_STORAGE; + case StorageType::kSessionStorage: + return mojom::ContentSettingsManager::StorageType::SESSION_STORAGE; } } @@ -290,11 +289,30 @@ return; } + StoragePermissionsKey key(url::Origin(frame->GetSecurityOrigin()), + storage_type); + const auto permissions = cached_storage_permissions_.find(key); + if (permissions != cached_storage_permissions_.end()) { + std::move(callback).Run(permissions->second); + return; + } + + // Passing the |cache_storage_permissions_| ref to the callback is safe here + // as the mojo::Remote is owned by |this| and won't invoke the callback if + // |this| (and in turn |cache_storage_permissions_|) is destroyed. + base::OnceCallback<void(bool)> new_cb = base::BindOnce( + [](base::OnceCallback<void(bool)> original_cb, StoragePermissionsKey key, + base::flat_map<StoragePermissionsKey, bool>& cache_map, bool result) { + cache_map[key] = result; + std::move(original_cb).Run(result); + }, + std::move(callback), key, std::ref(cached_storage_permissions_)); + GetContentSettingsManager().AllowStorageAccess( routing_id(), ConvertToMojoStorageType(storage_type), frame->GetSecurityOrigin(), frame->GetDocument().SiteForCookies().RepresentativeUrl(), - frame->GetDocument().TopFrameOrigin(), std::move(callback)); + frame->GetDocument().TopFrameOrigin(), std::move(new_cb)); } bool ContentSettingsAgentImpl::AllowStorageAccessSync( @@ -303,12 +321,19 @@ if (IsFrameWithOpaqueOrigin(frame)) return false; + StoragePermissionsKey key(url::Origin(frame->GetSecurityOrigin()), + storage_type); + const auto permissions = cached_storage_permissions_.find(key); + if (permissions != cached_storage_permissions_.end()) + return permissions->second; + bool result = false; GetContentSettingsManager().AllowStorageAccess( routing_id(), ConvertToMojoStorageType(storage_type), frame->GetSecurityOrigin(), frame->GetDocument().SiteForCookies().RepresentativeUrl(), frame->GetDocument().TopFrameOrigin(), &result); + cached_storage_permissions_[key] = result; return result; } @@ -382,29 +407,6 @@ return allow || IsWhitelistedForContentSettings(); } -bool ContentSettingsAgentImpl::AllowStorage(bool local) { - WebLocalFrame* frame = render_frame()->GetWebFrame(); - if (IsFrameWithOpaqueOrigin(frame)) - return false; - - StoragePermissionsKey key( - url::Origin(frame->GetDocument().GetSecurityOrigin()).GetURL(), local); - const auto permissions = cached_storage_permissions_.find(key); - if (permissions != cached_storage_permissions_.end()) - return permissions->second; - - bool result = false; - GetContentSettingsManager().AllowStorageAccess( - routing_id(), - local ? mojom::ContentSettingsManager::StorageType::LOCAL_STORAGE - : mojom::ContentSettingsManager::StorageType::SESSION_STORAGE, - frame->GetSecurityOrigin(), - frame->GetDocument().SiteForCookies().RepresentativeUrl(), - frame->GetDocument().TopFrameOrigin(), &result); - cached_storage_permissions_[key] = result; - return result; -} - bool ContentSettingsAgentImpl::AllowReadFromClipboard(bool default_value) { return delegate_->AllowReadFromClipboard().value_or(default_value); }
diff --git a/components/content_settings/renderer/content_settings_agent_impl.h b/components/content_settings/renderer/content_settings_agent_impl.h index e6f97a1e..1d9075a 100644 --- a/components/content_settings/renderer/content_settings_agent_impl.h +++ b/components/content_settings/renderer/content_settings_agent_impl.h
@@ -24,6 +24,7 @@ #include "mojo/public/cpp/bindings/associated_remote.h" #include "third_party/blink/public/platform/web_content_settings_client.h" #include "url/gurl.h" +#include "url/origin.h" namespace blink { class WebFrame; @@ -91,7 +92,6 @@ bool AllowScript(bool enabled_per_settings) override; bool AllowScriptFromSource(bool enabled_per_settings, const blink::WebURL& script_url) override; - bool AllowStorage(bool local) override; bool AllowReadFromClipboard(bool default_value) override; bool AllowWriteToClipboard(bool default_value) override; bool AllowMutationEvents(bool default_value) override; @@ -166,8 +166,8 @@ // Stores if images, scripts, and plugins have actually been blocked. base::flat_set<ContentSettingsType> content_blocked_; - // Caches the result of AllowStorage. - using StoragePermissionsKey = std::pair<GURL, bool>; + // Caches the result of AllowStorageAccess. + using StoragePermissionsKey = std::pair<url::Origin, StorageType>; base::flat_map<StoragePermissionsKey, bool> cached_storage_permissions_; // Caches the result of AllowScript.
diff --git a/components/content_settings/renderer/content_settings_agent_impl_browsertest.cc b/components/content_settings/renderer/content_settings_agent_impl_browsertest.cc index c0e36cd9..217f968 100644 --- a/components/content_settings/renderer/content_settings_agent_impl_browsertest.cc +++ b/components/content_settings/renderer/content_settings_agent_impl_browsertest.cc
@@ -223,18 +223,41 @@ EXPECT_EQ(1, mock_agent.on_content_blocked_count()); } -// Tests that multiple invokations of AllowDOMStorage result in a single IPC. -TEST_F(ContentSettingsAgentImplBrowserTest, AllowDOMStorage) { +// Tests that multiple invocations of AllowStorageAccessSync result in a single +// IPC. +TEST_F(ContentSettingsAgentImplBrowserTest, AllowStorageAccessSync) { // Load some HTML, so we have a valid security origin. LoadHTMLWithUrlOverride("<html></html>", "https://example.com/"); MockContentSettingsAgentImpl mock_agent(view_->GetMainRenderFrame()); - mock_agent.AllowStorage(true); + mock_agent.AllowStorageAccessSync( + blink::WebContentSettingsClient::StorageType::kLocalStorage); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, mock_agent.allow_storage_access_count()); // Accessing localStorage from the same origin again shouldn't result in a // new IPC. - mock_agent.AllowStorage(true); + mock_agent.AllowStorageAccessSync( + blink::WebContentSettingsClient::StorageType::kLocalStorage); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, mock_agent.allow_storage_access_count()); +} + +// Tests that multiple invocations of AllowStorageAccess result in a single IPC. +TEST_F(ContentSettingsAgentImplBrowserTest, AllowStorageAccess) { + // Load some HTML, so we have a valid security origin. + LoadHTMLWithUrlOverride("<html></html>", "https://example.com/"); + MockContentSettingsAgentImpl mock_agent(view_->GetMainRenderFrame()); + mock_agent.AllowStorageAccess( + blink::WebContentSettingsClient::StorageType::kLocalStorage, + base::DoNothing()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, mock_agent.allow_storage_access_count()); + + // Accessing localStorage from the same origin again shouldn't result in a + // new IPC. + mock_agent.AllowStorageAccess( + blink::WebContentSettingsClient::StorageType::kLocalStorage, + base::DoNothing()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, mock_agent.allow_storage_access_count()); }
diff --git a/components/download/internal/background_service/scheduler/device_status_listener.cc b/components/download/internal/background_service/scheduler/device_status_listener.cc index 76f11e5d..becbb1f 100644 --- a/components/download/internal/background_service/scheduler/device_status_listener.cc +++ b/components/download/internal/background_service/scheduler/device_status_listener.cc
@@ -24,6 +24,9 @@ case network::mojom::ConnectionType::CONNECTION_2G: case network::mojom::ConnectionType::CONNECTION_3G: case network::mojom::ConnectionType::CONNECTION_4G: + case network::mojom::ConnectionType::CONNECTION_5G: + // TODO(crbug.com/1127134): 5G networks may be unmetered. Find a way to + // detect this and make DeviceStatusListener aware of it. return NetworkStatus::METERED; case network::mojom::ConnectionType::CONNECTION_UNKNOWN: case network::mojom::ConnectionType::CONNECTION_NONE:
diff --git a/components/metrics/net/network_metrics_provider.cc b/components/metrics/net/network_metrics_provider.cc index 1f4bfda..79ceddcf 100644 --- a/components/metrics/net/network_metrics_provider.cc +++ b/components/metrics/net/network_metrics_provider.cc
@@ -251,6 +251,8 @@ return SystemProfileProto::Network::CONNECTION_3G; case network::mojom::ConnectionType::CONNECTION_4G: return SystemProfileProto::Network::CONNECTION_4G; + case network::mojom::ConnectionType::CONNECTION_5G: + return SystemProfileProto::Network::CONNECTION_5G; case network::mojom::ConnectionType::CONNECTION_BLUETOOTH: return SystemProfileProto::Network::CONNECTION_BLUETOOTH; }
diff --git a/components/page_info/android/java/res/layout/page_info_row.xml b/components/page_info/android/java/res/layout/page_info_row.xml index 697a8ae..a1cf416 100644 --- a/components/page_info/android/java/res/layout/page_info_row.xml +++ b/components/page_info/android/java/res/layout/page_info_row.xml
@@ -5,44 +5,41 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<merge + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools"> - <RelativeLayout + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground" + android:paddingHorizontal="@dimen/page_info_popup_padding_sides" + android:paddingVertical="12dp"> + + <ImageView + android:id="@+id/page_info_row_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_centerVertical="true" + android:layout_marginEnd="32dp" + app:tint="@color/default_icon_color" + tools:ignore="ContentDescription" /> + + <org.chromium.ui.widget.TextViewWithLeading + android:id="@+id/page_info_row_title" android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingTop="12dp" - android:paddingBottom="12dp" - android:paddingEnd="@dimen/page_info_popup_padding_sides" - android:paddingStart="@dimen/page_info_popup_padding_sides" > + android:layout_height="wrap_content" + android:layout_marginBottom="4dp" + android:layout_toEndOf="@id/page_info_row_icon" + android:textAppearance="@style/TextAppearance.TextLarge.Primary" /> - <ImageView - android:id="@+id/page_info_row_icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - tools:ignore="ContentDescription" - android:layout_marginEnd="32dp" - android:layout_centerVertical="true" - android:layout_alignParentStart="true" - app:tint="@color/default_icon_color" /> - - <org.chromium.ui.widget.TextViewWithLeading - android:id="@+id/page_info_row_title" - android:textAppearance="@style/TextAppearance.TextLarge.Primary" - android:layout_toEndOf="@id/page_info_row_icon" - android:layout_marginBottom="4dp" - android:layout_height="wrap_content" - android:layout_width="match_parent" /> - - <org.chromium.ui.widget.TextViewWithLeading - android:id="@+id/page_info_row_subtitle" - android:textAppearance="@style/TextAppearance.TextMedium.Secondary" - android:layout_toEndOf="@id/page_info_row_icon" - android:layout_below="@id/page_info_row_title" - app:leading="@dimen/text_size_medium_leading" - android:layout_height="wrap_content" - android:layout_width="match_parent" /> - - </RelativeLayout> -</merge> \ No newline at end of file + <org.chromium.ui.widget.TextViewWithLeading + android:id="@+id/page_info_row_subtitle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/page_info_row_title" + android:layout_toEndOf="@id/page_info_row_icon" + android:textAppearance="@style/TextAppearance.TextMedium.Secondary" + app:leading="@dimen/text_size_medium_leading" /> +</RelativeLayout>
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesController.java index 2911758..9493878 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesController.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesController.java
@@ -9,15 +9,20 @@ import androidx.appcompat.app.AppCompatActivity; +import org.chromium.components.browser_ui.site_settings.SingleWebsiteSettings; import org.chromium.components.browser_ui.site_settings.SiteDataCleaner; +import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory; import org.chromium.components.browser_ui.site_settings.Website; import org.chromium.components.browser_ui.site_settings.WebsiteAddress; +import org.chromium.components.browser_ui.site_settings.WebsitePermissionsFetcher; import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge; import org.chromium.components.content_settings.CookieControlsBridge; import org.chromium.components.content_settings.CookieControlsEnforcement; import org.chromium.components.content_settings.CookieControlsObserver; import org.chromium.components.embedder_support.util.Origin; +import java.util.Collection; + /** * Class for controlling the page info cookies section. */ @@ -35,6 +40,7 @@ private int mBlockedCookies; private int mStatus; private boolean mIsEnforced; + private Website mWebsite; public PageInfoCookiesController(PageInfoMainController mainController, PageInfoRowView rowView, PageInfoControllerDelegate delegate, String fullUrl) { @@ -80,18 +86,31 @@ mSubPage.setCookiesCount(mAllowedCookies, mBlockedCookies); mSubPage.setCookieBlockingStatus(mStatus, mIsEnforced); + SiteSettingsCategory storageCategory = SiteSettingsCategory.createFromType( + mMainController.getBrowserContext(), SiteSettingsCategory.Type.USE_STORAGE); + new WebsitePermissionsFetcher(mMainController.getBrowserContext()) + .fetchPreferencesForCategory(storageCategory, this::onStorageFetched); + return mSubPage.requireView(); } + private void onStorageFetched(Collection<Website> result) { + String origin = Origin.createOrThrow(mFullUrl).toString(); + WebsiteAddress address = WebsiteAddress.create(origin); + + mWebsite = SingleWebsiteSettings.mergePermissionAndStorageInfoForTopLevelOrigin( + address, result); + mSubPage.setStorageUsage(mWebsite.getTotalUsage()); + } + private void onCheckedChangedCallback(boolean state) { mBridge.setThirdPartyCookieBlockingEnabledForSite(state); } private void clearData() { - String origin = Origin.createOrThrow(mFullUrl).toString(); - WebsiteAddress address = WebsiteAddress.create(origin); - new SiteDataCleaner().clearData(mMainController.getBrowserContext(), - new Website(address, address), mMainController::exitSubpage); + if (mWebsite == null) return; + new SiteDataCleaner().clearData( + mMainController.getBrowserContext(), mWebsite, mMainController::exitSubpage); } @Override
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java index 84d0310..7614d73 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java
@@ -4,6 +4,7 @@ package org.chromium.components.page_info; import android.os.Bundle; +import android.text.format.Formatter; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; @@ -94,4 +95,12 @@ mCookieInUse.setTitle(getContext().getResources().getQuantityString( R.plurals.page_info_cookies_in_use, allowedCookies, allowedCookies)); } + + public void setStorageUsage(long storageUsage) { + mCookieInUse.setSummary( + storageUsage > 0 ? String.format( + getContext().getString(R.string.origin_settings_storage_usage_brief), + Formatter.formatShortFileSize(getContext(), storageUsage)) + : null); + } }
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java index 790bbe4..a0657ba 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java
@@ -53,7 +53,7 @@ mRowView.getContext(), SingleWebsiteSettings.class.getName(), fragmentArgs); mSubpageFragment.setSiteSettingsClient(mDelegate.getSiteSettingsClient()); mSubpageFragment.setHideNonPermissionPreferences(true); - mSubpageFragment.setRefreshAfterReset(true); + mSubpageFragment.setWebsiteResetCallback(mMainController::exitSubpage); AppCompatActivity host = (AppCompatActivity) mRowView.getContext(); host.getSupportFragmentManager().beginTransaction().add(mSubpageFragment, null).commitNow(); return mSubpageFragment.requireView();
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoRowView.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoRowView.java index dfe98b5..5797a3a 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoRowView.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoRowView.java
@@ -7,10 +7,8 @@ import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; +import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.RelativeLayout; import android.widget.TextView; import androidx.annotation.DrawableRes; @@ -20,7 +18,7 @@ /** * View showing an icon, title and subtitle for a page info row. */ -public class PageInfoRowView extends RelativeLayout implements OnClickListener { +public class PageInfoRowView extends FrameLayout { /** Parameters to configure the row view. */ public static class ViewParams { public boolean visible; @@ -33,7 +31,6 @@ private final ImageView mIcon; private final TextView mTitle; private final TextView mSubtitle; - private Runnable mClickCallback; public PageInfoRowView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); @@ -44,24 +41,20 @@ } public void setParams(ViewParams params) { - setVisibility(params.visible ? View.VISIBLE : View.GONE); + setVisibility(params.visible ? VISIBLE : GONE); mIcon.setImageResource(params.iconResId); mTitle.setText(params.title); - mTitle.setVisibility(params.title != null ? View.VISIBLE : View.GONE); + mTitle.setVisibility(params.title != null ? VISIBLE : GONE); updateSubtitle(params.subtitle); - mClickCallback = params.clickCallback; - setOnClickListener(this); + if (params.clickCallback != null) { + setClickable(true); + setFocusable(true); + getChildAt(0).setOnClickListener((v) -> params.clickCallback.run()); + } } public void updateSubtitle(String subtitle) { mSubtitle.setText(subtitle); - mSubtitle.setVisibility(subtitle != null ? View.VISIBLE : View.GONE); - } - - @Override - public void onClick(View view) { - if (mClickCallback != null) { - mClickCallback.run(); - } + mSubtitle.setVisibility(subtitle != null ? VISIBLE : GONE); } }
diff --git a/components/paint_preview/player/android/javatests/src/org/chromium/components/paintpreview/player/PaintPreviewPlayerTest.java b/components/paint_preview/player/android/javatests/src/org/chromium/components/paintpreview/player/PaintPreviewPlayerTest.java index b4d2268..12df1a7 100644 --- a/components/paint_preview/player/android/javatests/src/org/chromium/components/paintpreview/player/PaintPreviewPlayerTest.java +++ b/components/paint_preview/player/android/javatests/src/org/chromium/components/paintpreview/player/PaintPreviewPlayerTest.java
@@ -27,7 +27,6 @@ import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.DisableIf; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.ScalableTimeout; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.test.util.Criteria; @@ -172,7 +171,6 @@ @Test @MediumTest - @DisabledTest(message = "crbug.com/1117264") public void overscrollRefreshTest() throws Exception { initPlayerManager(true); UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index bd64f49..8568cc6 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -148,6 +148,7 @@ "password_feature_manager.h", "password_feature_manager_impl.cc", "password_feature_manager_impl.h", + "password_form.h", "password_form_filling.cc", "password_form_filling.h", "password_form_manager.cc",
diff --git a/components/password_manager/core/browser/password_form.h b/components/password_manager/core/browser/password_form.h new file mode 100644 index 0000000..dee04bd --- /dev/null +++ b/components/password_manager/core/browser/password_form.h
@@ -0,0 +1,18 @@ +// Copyright 2020 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_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_FORM_H_ +#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_FORM_H_ + +#include "components/autofill/core/common/password_form.h" + +namespace password_manager { + +// TODO(crbug.com/1067347): Move complete class to password_manager, once all +// references to `autofill::PasswordForm` are dropped. +using PasswordForm = autofill::PasswordForm; + +} // namespace password_manager + +#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_FORM_H_
diff --git a/components/payments/content/installable_payment_app_crawler.cc b/components/payments/content/installable_payment_app_crawler.cc index 5c9f7a45..c3fa3a5 100644 --- a/components/payments/content/installable_payment_app_crawler.cc +++ b/components/payments/content/installable_payment_app_crawler.cc
@@ -18,7 +18,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/global_routing_id.h" #include "content/public/browser/manifest_icon_downloader.h" -#include "content/public/browser/payment_app_provider.h" +#include "content/public/browser/payment_app_provider_util.h" #include "content/public/browser/permission_controller.h" #include "content/public/browser/permission_type.h" #include "content/public/browser/render_frame_host.h" @@ -337,7 +337,7 @@ } std::string error_message; - if (!content::PaymentAppProvider::GetInstance()->IsValidInstallablePaymentApp( + if (!content::PaymentAppProviderUtil::IsValidInstallablePaymentApp( web_app_manifest_url, GURL(app_info->sw_js_url), GURL(app_info->sw_scope), &error_message)) { SetFirstError(error_message);
diff --git a/components/payments/content/service_worker_payment_app.cc b/components/payments/content/service_worker_payment_app.cc index 6d51dca..897b35f 100644 --- a/components/payments/content/service_worker_payment_app.cc +++ b/components/payments/content/service_worker_payment_app.cc
@@ -19,6 +19,7 @@ #include "components/payments/core/features.h" #include "components/payments/core/method_strings.h" #include "content/public/browser/payment_app_provider.h" +#include "content/public/browser/payment_app_provider_util.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h" #include "ui/gfx/image/image_skia.h" @@ -130,8 +131,12 @@ return; } - content::PaymentAppProvider::GetInstance()->CanMakePayment( - web_contents(), stored_payment_app_info_->registration_id, + auto* payment_app_provider = GetPaymentAppProvider(); + if (!payment_app_provider) + return; + + payment_app_provider->CanMakePayment( + stored_payment_app_info_->registration_id, url::Origin::Create(stored_payment_app_info_->scope), *spec_->details().id, std::move(event_data), base::BindOnce(&ServiceWorkerPaymentApp::OnCanMakePaymentEventResponded, @@ -206,11 +211,13 @@ void ServiceWorkerPaymentApp::InvokePaymentApp(Delegate* delegate) { delegate_ = delegate; + auto* payment_app_provider = GetPaymentAppProvider(); + if (!payment_app_provider) + return; if (needs_installation_) { - content::PaymentAppProvider::GetInstance()->InstallAndInvokePaymentApp( - web_contents(), CreatePaymentRequestEventData(), - installable_web_app_info_->name, + payment_app_provider->InstallAndInvokePaymentApp( + CreatePaymentRequestEventData(), installable_web_app_info_->name, installable_web_app_info_->icon == nullptr ? SkBitmap() : *(installable_web_app_info_->icon), @@ -228,8 +235,8 @@ url::Origin sw_origin = url::Origin::Create(stored_payment_app_info_->scope); OnPaymentAppIdentity(sw_origin, stored_payment_app_info_->registration_id); - content::PaymentAppProvider::GetInstance()->InvokePaymentApp( - web_contents(), stored_payment_app_info_->registration_id, sw_origin, + payment_app_provider->InvokePaymentApp( + stored_payment_app_info_->registration_id, sw_origin, CreatePaymentRequestEventData(), base::BindOnce(&ServiceWorkerPaymentApp::OnPaymentAppInvoked, weak_ptr_factory_.GetWeakPtr())); @@ -240,8 +247,10 @@ void ServiceWorkerPaymentApp::OnPaymentAppWindowClosed() { delegate_ = nullptr; - content::PaymentAppProvider::GetInstance()->OnClosingOpenedWindow( - web_contents(), + auto* payment_app_provider = GetPaymentAppProvider(); + if (!payment_app_provider) + return; + payment_app_provider->OnClosingOpenedWindow( mojom::PaymentEventResponseType::PAYMENT_HANDLER_WINDOW_CLOSING); } @@ -562,8 +571,8 @@ // app since this getter is called for the invoked app inside the // PaymentRequest::OnPaymentHandlerOpenWindowCalled function. ukm_source_id_ = - content::PaymentAppProvider::GetInstance() - ->GetSourceIdForPaymentAppFromScope(sw_scope.GetOrigin()); + content::PaymentAppProviderUtil::GetSourceIdForPaymentAppFromScope( + sw_scope.GetOrigin()); } return ukm_source_id_; } @@ -592,12 +601,23 @@ void ServiceWorkerPaymentApp::AbortPaymentApp( base::OnceCallback<void(bool)> abort_callback) { - content::PaymentAppProvider::GetInstance()->AbortPayment( - web_contents(), registration_id_, + auto* payment_app_provider = GetPaymentAppProvider(); + if (!payment_app_provider) + return; + + payment_app_provider->AbortPayment( + registration_id_, stored_payment_app_info_ ? url::Origin::Create(stored_payment_app_info_->scope) : url::Origin::Create(GURL(installable_web_app_info_->sw_scope)), *spec_->details().id, std::move(abort_callback)); } +content::PaymentAppProvider* ServiceWorkerPaymentApp::GetPaymentAppProvider() { + return (!web_contents()) + ? nullptr + : content::PaymentAppProvider::GetOrCreateForWebContents( + web_contents()); +} + } // namespace payments
diff --git a/components/payments/content/service_worker_payment_app.h b/components/payments/content/service_worker_payment_app.h index a7ab79d3..97f55e6 100644 --- a/components/payments/content/service_worker_payment_app.h +++ b/components/payments/content/service_worker_payment_app.h
@@ -20,6 +20,7 @@ #include "third_party/blink/public/mojom/payments/payment_request.mojom.h" namespace content { +class PaymentAppProvider; class WebContents; } // namespace content @@ -129,6 +130,8 @@ // invoked. void OnPaymentAppIdentity(const url::Origin& origin, int64_t registration_id); + content::PaymentAppProvider* GetPaymentAppProvider(); + GURL top_origin_; GURL frame_origin_; const PaymentRequestSpec* spec_;
diff --git a/components/payments/content/service_worker_payment_app_finder.cc b/components/payments/content/service_worker_payment_app_finder.cc index 5dc754e..2050275 100644 --- a/components/payments/content/service_worker_payment_app_finder.cc +++ b/components/payments/content/service_worker_payment_app_finder.cc
@@ -95,7 +95,7 @@ : public base::SupportsUserData::Data { public: static base::WeakPtr<SelfDeletingServiceWorkerPaymentAppFinder> - CreateAndSetOwnedBy(base::SupportsUserData* owner) { + CreateAndSetOwnedBy(content::WebContents* owner) { auto owned = std::make_unique<SelfDeletingServiceWorkerPaymentAppFinder>(owner); auto* pointer = owned.get(); @@ -104,7 +104,7 @@ } explicit SelfDeletingServiceWorkerPaymentAppFinder( - base::SupportsUserData* owner) + content::WebContents* owner) : owner_(owner) {} SelfDeletingServiceWorkerPaymentAppFinder( @@ -314,14 +314,13 @@ base::StringPiece(raw_data->front_as<char>(), raw_data->size()), &string_encoded_icon); - auto* browser_context = - static_cast<content::WebContents*>(owner_)->GetBrowserContext(); - content::PaymentAppProvider::GetInstance()->UpdatePaymentAppIcon( - browser_context, app->registration_id, app->scope.spec(), app->name, - string_encoded_icon, method_name, app->supported_delegations, - base::BindOnce( - &SelfDeletingServiceWorkerPaymentAppFinder::OnUpdatePaymentAppIcon, - weak_ptr_factory_.GetWeakPtr())); + content::PaymentAppProvider::GetOrCreateForWebContents(owner_) + ->UpdatePaymentAppIcon( + app->registration_id, app->scope.spec(), app->name, + string_encoded_icon, method_name, app->supported_delegations, + base::BindOnce(&SelfDeletingServiceWorkerPaymentAppFinder:: + OnUpdatePaymentAppIcon, + weak_ptr_factory_.GetWeakPtr())); } void OnUpdatePaymentAppIcon(payments::mojom::PaymentHandlerStatus status) { @@ -365,7 +364,7 @@ // |owner_| owns this SelfDeletingServiceWorkerPaymentAppFinder, so it is // always valid. - base::SupportsUserData* owner_; + content::WebContents* owner_; std::unique_ptr<PaymentManifestDownloader> downloader_; std::unique_ptr<PaymentManifestParser> parser_;
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 2ec18623..9aa258d5 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -1950,7 +1950,7 @@ 'owners': ['jamiewalch@chromium.org', 'rkjnsn@chromium.org'], 'type': 'main', 'schema': { 'type': 'boolean' }, - 'supported_on': ['chrome.*:23-', 'chrome_os:41-'], + 'supported_on': ['chrome.*:23-'], 'features': { 'dynamic_refresh': True, 'per_profile': False, @@ -1970,7 +1970,7 @@ 'owners': ['jamiewalch@chromium.org', 'rkjnsn@chromium.org'], 'type': 'main', 'schema': { 'type': 'boolean' }, - 'supported_on': ['chrome.*:30-', 'chrome_os:41-'], + 'supported_on': ['chrome.*:30-'], 'features': { 'dynamic_refresh': True, 'per_profile': False, @@ -1988,7 +1988,7 @@ 'owners': ['jamiewalch@chromium.org', 'rkjnsn@chromium.org'], 'type': 'main', 'schema': { 'type': 'boolean' }, - 'supported_on': ['chrome.*:35-', 'chrome_os:41-'], + 'supported_on': ['chrome.*:35-'], 'features': { 'dynamic_refresh': True, 'per_profile': False, @@ -2046,7 +2046,7 @@ 'owners': ['jamiewalch@chromium.org', 'rkjnsn@chromium.org'], 'type': 'main', 'schema': { 'type': 'boolean' }, - 'supported_on': ['chrome.linux:25-', 'chrome.mac:25-', 'chrome_os:42-'], + 'supported_on': ['chrome.linux:25-', 'chrome.mac:25-'], 'features': { 'dynamic_refresh': True, 'per_profile': False, @@ -2064,7 +2064,7 @@ 'owners': ['jamiewalch@chromium.org', 'rkjnsn@chromium.org'], 'type': 'string', 'schema': { 'type': 'string' }, - 'supported_on': ['chrome.*:28-','chrome_os:42-'], + 'supported_on': ['chrome.*:28-'], 'features': { 'dynamic_refresh': True, 'per_profile': False, @@ -2075,14 +2075,14 @@ 'tags': ['website-sharing'], 'desc': '''If this policy is set, the remote access host will require authenticating clients to obtain an authentication token from this URL in order to connect. Must be used in conjunction with RemoteAccessHostTokenValidationUrl. - This feature is currently disabled server-side.''', + This feature is disabled if empty or not set.''', }, { 'name': 'RemoteAccessHostTokenValidationUrl', 'owners': ['jamiewalch@chromium.org', 'rkjnsn@chromium.org'], 'type': 'string', 'schema': { 'type': 'string' }, - 'supported_on': ['chrome.*:28-','chrome_os:42-'], + 'supported_on': ['chrome.*:28-'], 'features': { 'dynamic_refresh': True, 'per_profile': False, @@ -2093,14 +2093,14 @@ 'tags': ['website-sharing'], 'desc': '''If this policy is set, the remote access host will use this URL to validate authentication tokens from remote access clients, in order to accept connections. Must be used in conjunction with RemoteAccessHostTokenUrl. - This feature is currently disabled server-side.''', + This feature is disabled if empty or not set.''', }, { 'name': 'RemoteAccessHostTokenValidationCertificateIssuer', 'owners': ['jamiewalch@chromium.org', 'rkjnsn@chromium.org'], 'type': 'string', 'schema': { 'type': 'string' }, - 'supported_on': ['chrome.*:28-','chrome_os:42-'], + 'supported_on': ['chrome.*:28-'], 'features': { 'dynamic_refresh': True, 'per_profile': False, @@ -2111,7 +2111,7 @@ 'tags': [], 'desc': '''If this policy is set, the host will use a client certificate with the given issuer CN to authenticate to RemoteAccessHostTokenValidationUrl. Set it to "*" to use any available client certificate. - This feature is currently disabled server-side.''', + This feature is disabled if empty or not set.''', }, { 'name': 'RemoteAccessHostDebugOverridePolicies', @@ -2815,7 +2815,7 @@ 'type': 'array', 'items': { 'type': 'string' }, }, - 'future_on': ['chrome_os'], + 'supported_on': ['chrome_os:87-'], 'features': { 'dynamic_refresh': True, 'per_profile': True @@ -7235,7 +7235,7 @@ }, { 'name': 'ChromeOsMultiProfileUserBehavior', - 'owners': ['xiyuan@chromium.org', 'sinhak@chromium.org'], + 'owners': ['xiyuan@chromium.org', 'sinhak@chromium.org', 'tellier@google.com', 'rsorokin@chromium.org', 'cros-oac@google.com'], 'type': 'string-enum', 'schema': { 'type': 'string', @@ -9239,13 +9239,17 @@ 'features': { 'dynamic_refresh': True, }, + 'deprecated': True, 'example_value': [ 'madmax@managedchrome.com' ], 'id': 122, 'caption': '''Login user white list''', 'tags': [], 'desc': '''Defines the list of users that are allowed to login to the device. Entries are of the form <ph name="USER_ALLOWLIST_ENTRY_FORMAT">user@domain</ph>, such as <ph name="USER_ALLOWLIST_ENTRY_EXAMPLE">madmax@managedchrome.com</ph>. To allow arbitrary users on a domain, use entries of the form <ph name="USER_ALLOWLIST_ENTRY_WILDCARD">*@domain</ph>. - If this policy is not configured, there are no restrictions on which users are allowed to sign in. Note that creating new users still requires the <ph name="DEVICE_ALLOW_NEW_USERS_POLICY_NAME">DeviceAllowNewUsers</ph> policy to be configured appropriately.''', + If this policy is not configured, there are no restrictions on which users are allowed to sign in. Note that creating new users still requires the <ph name="DEVICE_ALLOW_NEW_USERS_POLICY_NAME">DeviceAllowNewUsers</ph> policy to be configured appropriately. + + This policy is deprecated, please use <ph name="DEVICE_USER_ALLOWLIST_POLICY_NAME">DeviceUserAllowlist</ph> instead. + ''', 'arc_support': 'This policy controls who may start a <ph name="PRODUCT_OS_NAME">$2<ex>Chromium OS</ex></ph> session. It does not prevent users from signing in to additional Google accounts within Android. If you want to prevent this, configure the Android-specific <ph name="ACCOUNT_TYPES_WITH_MANAGEMENT_DISABLED_CLOUDDPC_POLICY_NAME">accountTypesWithManagementDisabled</ph> policy as part of <ph name="ARC_POLICY_POLICY_NAME">ArcPolicy</ph>.', }, @@ -9258,7 +9262,7 @@ 'items': { 'type': 'string' }, 'sensitiveValue': True, }, - 'future_on': ['chrome_os'], + 'supported_on': ['chrome_os:87-'], 'device_only': True, 'features': { 'dynamic_refresh': True, @@ -14303,6 +14307,7 @@ 'features': { 'dynamic_refresh': False, }, + 'deprecated': True, 'example_value': [ { 'vendor_id' : 1027, @@ -14318,7 +14323,10 @@ 'tags': ['system-security'], 'desc': '''Setting the policy defines the list of USB devices users can detach from their kernel driver to use through the chrome.usb API directly inside a web app. Entries are pairs of USB Vendor Identifier and Product Identifier to identify specific hardware. - If not set, the list of a detachable USB devices is empty.''', + If not set, the list of a detachable USB devices is empty. + + This policy is deprecated, please use <ph name="USB_DETACHABLE_ALLOWLIST_POLICY_NAME">UsbDetachableAllowlist</ph> instead. + ''', }, { 'name': 'UsbDetachableAllowlist', @@ -14335,7 +14343,7 @@ }, }, }, - 'future_on': ['chrome_os'], + 'supported_on': ['chrome_os:87-'], 'device_only': True, 'features': { 'dynamic_refresh': False, @@ -15453,6 +15461,7 @@ 'dynamic_refresh': True, 'per_profile': False, }, + 'deprecated': True, 'example_value': { "url": "https://example.com/printerpolicy", "hash": "deadbeefdeadbeefdeadbeefdeadbeefdeafdeadbeefdeadbeef" @@ -15468,13 +15477,15 @@ The file is downloaded and cached. It will be re-downloaded whenever the URL or the hash changes. - If this policy is set, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will download the file for printer configurations and make printers available in accordance with <ph name="DEVICE_NATIVE_PRINTERS_ACCESS_MODE">DeviceNativePrintersAccessMode</ph>, <ph name="DEVICE_NATIVE_PRINTERS_WHITELIST_POLICY_NAME">DeviceNativePrintersWhitelist</ph>, and <ph name="DEVICE_NATIVE_PRINTERS_BLACKLIST_POLICY_NAME">DeviceNativePrintersBlacklist</ph>. + If this policy is set, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will download the file for printer configurations and make printers available in accordance with <ph name="DEVICE_PRINTERS_ACCESS_MODE_POLICY_NAME">DevicePrintersAccessMode</ph>, <ph name="DEVICE_PRINTERS_ALLOWLIST_POLICY_NAME">DevicePrintersAllowlist</ph>, and <ph name="DEVICE_PRINTERS_BLOCKLIST_POLICY_NAME">DevicePrintersBlocklist</ph>. This policy has no effect on whether users can configure printers on individual devices. It is intended to be supplementary to the configuration of printers by individual users. This policy is additive to the <ph name="BULK_PRINTERS_POLICY_NAME">NativePrintersBulkConfiguration</ph>. If this policy is unset, there will be no device printers and the other <ph name="DEVICE_NATIVE_PRINTERS_POLICY_PATTERN">DeviceNativePrinter*</ph> policies will be ignored. + + This policy is deprecated, please use <ph name="DEVICE_PRINTERS_POLICY_NAME">DevicePrinters</ph> instead. ''', }, { @@ -15509,14 +15520,17 @@ 'dynamic_refresh': True, 'per_profile': False, }, + 'deprecated': True, 'example_value': 1, 'caption': '''Device printers configuration access policy.''', 'tags': [], - 'desc': '''Controls which printers from the <ph name="DEVICE_PRINTERS_POLICY">DeviceNativePrinters</ph> are available to users. + 'desc': '''Controls which printers from the <ph name="DEVICE_PRINTERS_POLICY_NAME">DevicePrinters</ph> are available to users. - Designates which access policy is used for bulk printer configuration. If <ph name="PRINTERS_ALLOW_ALL">AllowAll</ph> is selected, all printers are shown. If <ph name="PRINTERS_BLACKLIST">BlacklistRestriction</ph> is selected, <ph name="DEVICE_NATIVE_PRINTERS_BLACKLIST">DeviceNativePrintersBlacklist</ph> is used to restrict access to the specified printers. If <ph name="PRINTERS_WHITELIST">WhitelistPrintersOnly</ph> is selected, <ph name="DEVICE_NATIVE_PRINTERS_WHITELIST">DevicePrintersWhitelist</ph> designates only those printers which are selectable. + Designates which access policy is used for bulk printer configuration. If <ph name="PRINTERS_ALLOW_ALL">AllowAll</ph> is selected, all printers are shown. If <ph name="PRINTERS_BLACKLIST">BlacklistRestriction</ph> is selected, <ph name="DEVICE_PRINTERS_BLOCKLIST_POLICY_NAME">DevicePrintersBlocklist</ph> is used to restrict access to the specified printers. If <ph name="PRINTERS_WHITELIST">WhitelistPrintersOnly</ph> is selected, <ph name="DEVICE_PRINTERS_ALLOWLIST_POLCY_NAME">DevicePrintersAllowlist</ph> designates only those printers which are selectable. If this policy is not set, <ph name="PRINTERS_ALLOW_ALL">AllowAll</ph> is assumed. + + This policy is deprecated, please use <ph name="DEVICE_PRINTERS_ACCESS_MODE_POLICY_NAME">DevicePrintersAccessMode</ph> instead. ''', }, { @@ -15533,14 +15547,17 @@ 'features': { 'dynamic_refresh': True, }, + 'deprecated': True, 'example_value': ["id1", "id2", "id3"], 'caption': '''Disabled enterprise device printers''', 'tags': [], 'desc': '''Specifies the printers which a user cannot use. - This policy is only used if <ph name="PRINTERS_BLACKLIST">BlacklistRestriction</ph> is chosen for <ph name="DEVICE_NATIVE_PRINTERS_ACCESS_MODE">DeviceNativePrintersAccessMode</ph>. + This policy is only used if <ph name="PRINTERS_BLACKLIST">BlacklistRestriction</ph> is chosen for <ph name="DEVICE_PRINTERS_ACCESS_MODE_POLICY_NAME">DevicePrintersAccessMode</ph>. - If this policy is used, all printers are provided to the user except for the ids listed in this policy. The ids must correspond to the "id" or "guid" fields in the file specified in <ph name="DEVICE_PRINTERS_POLICY">DeviceNativePrinters</ph>. + If this policy is used, all printers are provided to the user except for the ids listed in this policy. The ids must correspond to the "id" or "guid" fields in the file specified in <ph name="DEVICE_PRINTERS_POLICY_NAME">DevicePrinters</ph>. + + This policy is deprecated, please use <ph name="DEVICE_PRINTERS_BLOCKLIST_POLICY_NAME">DevicePrintersBlocklist</ph> instead. ''', }, { @@ -15558,14 +15575,17 @@ 'dynamic_refresh': True, 'per_profile': False, }, + 'deprecated': True, 'example_value': ["id1", "id2", "id3"], 'caption': '''Enabled enterprise device printers''', 'tags': [], 'desc': '''Specifies the printers which a user can use. - This policy is only used if <ph name="PRINTERS_WHITELIST">WhitelistPrintersOnly</ph> is chosen for <ph name="DEVICE_NATIVE_PRINTERS_ACCESS_MODE">DeviceNativePrintersAccessMode</ph> + This policy is only used if <ph name="PRINTERS_WHITELIST">WhitelistPrintersOnly</ph> is chosen for <ph name="DEVICE_PRINTERS_ACCESS_MODE_POLICY_NAME">DevicePrintersAccessMode</ph> - If this policy is used, only the printers with ids matching the values in this policy are available to the user. The ids must correspond to the "id" or "guid" fields in the file specified in <ph name="DEVICE_PRINTERS_POLICY">DeviceNativePrinters</ph>. + If this policy is used, only the printers with ids matching the values in this policy are available to the user. The ids must correspond to the "id" or "guid" fields in the file specified in <ph name="DEVICE_PRINTERS_POLICY_NAME">DevicePrinters</ph>. + + This policy is deprecated, please use <ph name="DEVICE_PRINTERS_ALLOWLIST_POLICY_NAME">DevicePrintersAllowlist</ph> instead. ''', }, { @@ -15581,7 +15601,7 @@ 'hash': { 'type': 'string' } }, }, - 'future_on': ['chrome_os'], + 'supported_on': ['chrome_os:87-'], 'features': { 'dynamic_refresh': True, 'per_profile': False, @@ -15615,7 +15635,7 @@ 'owners': ['skau@chromium.org', 'nikitapodguzov@chromium.org'], 'id': 733, 'device_only': True, - 'future_on': ['chrome_os'], + 'supported_on': ['chrome_os:87-'], 'type': 'int-enum', 'schema': { 'type': 'integer', @@ -15655,7 +15675,7 @@ { 'name': 'DevicePrintersBlocklist', 'owners': ['skau@chromium.org', 'nikitapodguzov@chromium.org', 'bmalcolm@chromium.org'], - 'future_on': ['chrome_os'], + 'supported_on': ['chrome_os:87-'], 'device_only': True, 'id': 734, 'type': 'list', @@ -15679,7 +15699,7 @@ { 'name': 'DevicePrintersAllowlist', 'owners': ['skau@chromium.org', 'nikitapodguzov@chromium.org', 'bmalcolm@chromium.org'], - 'future_on': ['chrome_os'], + 'supported_on': ['chrome_os:87-'], 'device_only': True, 'id': 735, 'type': 'list', @@ -15943,6 +15963,7 @@ 'dynamic_refresh': True, 'per_profile': True, }, + 'deprecated': True, 'example_value': ['PIN'], 'default_for_enterprise_users': [], 'id': 352,
diff --git a/components/remote_cocoa/DEPS b/components/remote_cocoa/DEPS index 755476f..3666e05 100644 --- a/components/remote_cocoa/DEPS +++ b/components/remote_cocoa/DEPS
@@ -3,6 +3,8 @@ "+components/crash/core/common/crash_key.h", "+components/viz/common", "+mojo/public/cpp/bindings", + "+net/cert", + "+services/network/public/mojom/network_param.mojom", "+skia/ext", "+ui/accelerated_widget_mac", "+ui/base",
diff --git a/components/remote_cocoa/app_shim/BUILD.gn b/components/remote_cocoa/app_shim/BUILD.gn index 80269ea..a9bf35e 100644 --- a/components/remote_cocoa/app_shim/BUILD.gn +++ b/components/remote_cocoa/app_shim/BUILD.gn
@@ -26,6 +26,8 @@ "bridged_content_view_touch_bar.mm", "browser_native_widget_window_mac.h", "browser_native_widget_window_mac.mm", + "certificate_viewer.h", + "certificate_viewer.mm", "color_panel_bridge.h", "color_panel_bridge.mm", "drag_drop_client.h", @@ -59,6 +61,7 @@ "//components/crash/core/common", "//components/remote_cocoa/common:mojo", "//mojo/public/cpp/bindings", + "//net", "//ui/accelerated_widget_mac", "//ui/base", "//ui/base/ime:ime", @@ -69,5 +72,6 @@ frameworks = [ "Cocoa.framework", "QuartzCore.framework", + "SecurityInterface.framework", ] }
diff --git a/components/remote_cocoa/app_shim/certificate_viewer.h b/components/remote_cocoa/app_shim/certificate_viewer.h new file mode 100644 index 0000000..4602c1c4 --- /dev/null +++ b/components/remote_cocoa/app_shim/certificate_viewer.h
@@ -0,0 +1,23 @@ +// Copyright 2020 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_REMOTE_COCOA_APP_SHIM_CERTIFICATE_VIEWER_H_ +#define COMPONENTS_REMOTE_COCOA_APP_SHIM_CERTIFICATE_VIEWER_H_ + +#import <Cocoa/Cocoa.h> + +namespace net { +class X509Certificate; +} + +namespace remote_cocoa { + +// Shows the platform certificate viewer, displaying |certificate| and parented +// to |owning_window|. +void ShowCertificateViewerForWindow(NSWindow* owning_window, + net::X509Certificate* ceriticate); + +} // namespace remote_cocoa + +#endif // COMPONENTS_REMOTE_COCOA_APP_SHIM_CERTIFICATE_VIEWER_H_
diff --git a/components/remote_cocoa/app_shim/certificate_viewer.mm b/components/remote_cocoa/app_shim/certificate_viewer.mm new file mode 100644 index 0000000..0c12e8b --- /dev/null +++ b/components/remote_cocoa/app_shim/certificate_viewer.mm
@@ -0,0 +1,77 @@ +// Copyright 2020 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. + +#import "components/remote_cocoa/app_shim/certificate_viewer.h" + +#include <CoreFoundation/CFArray.h> +#include <Security/Security.h> +#import <SecurityInterface/SFCertificatePanel.h> + +#include "base/mac/foundation_util.h" +#include "base/mac/scoped_cftyperef.h" +#include "base/notreached.h" +#include "net/cert/x509_util_ios_and_mac.h" +#include "net/cert/x509_util_mac.h" + +namespace remote_cocoa { + +void ShowCertificateViewerForWindow(NSWindow* owning_window, + net::X509Certificate* certificate) { + base::ScopedCFTypeRef<CFArrayRef> cert_chain( + net::x509_util::CreateSecCertificateArrayForX509Certificate(certificate)); + if (!cert_chain) + return; + + // Explicitly disable revocation checking, regardless of user preferences + // or system settings. The behaviour of SFCertificatePanel is to call + // SecTrustEvaluate on the certificate(s) supplied, effectively + // duplicating the behaviour of net::X509Certificate::Verify(). However, + // this call stalls the UI if revocation checking is enabled in the + // Keychain preferences or if the cert may be an EV cert. By disabling + // revocation checking, the stall is limited to the time taken for path + // building and verification, which should be minimized due to the path + // being provided in |certificates|. This does not affect normal + // revocation checking from happening, which is controlled by + // net::X509Certificate::Verify() and user preferences, but will prevent + // the certificate viewer UI from displaying which certificate is revoked. + // This is acceptable, as certificate revocation will still be shown in + // the page info bubble if a certificate in the chain is actually revoked. + base::ScopedCFTypeRef<CFMutableArrayRef> policies( + CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); + if (!policies.get()) { + NOTREACHED(); + return; + } + // Add a basic X.509 policy, in order to match the behaviour of + // SFCertificatePanel when no policies are specified. + base::ScopedCFTypeRef<SecPolicyRef> basic_policy; + OSStatus status = + net::x509_util::CreateBasicX509Policy(basic_policy.InitializeInto()); + if (status != noErr) { + NOTREACHED(); + return; + } + CFArrayAppendValue(policies, basic_policy.get()); + + status = net::x509_util::CreateRevocationPolicies(false, policies); + if (status != noErr) { + NOTREACHED(); + return; + } + + SFCertificatePanel* panel = [[SFCertificatePanel alloc] init]; + [panel setPolicies:base::mac::CFToNSCast(policies.get())]; + [panel beginSheetForWindow:owning_window + modalDelegate:nil + didEndSelector:nil + contextInfo:nil + certificates:base::mac::CFToNSCast(cert_chain.get()) + showGroup:YES]; + // beginSheetForWindow: internally retains an extra reference to |panel| and + // releases it when the sheet closes. Release the original reference so the + // sheet is destroyed. + [panel autorelease]; +} + +} // namespace remote_cocoa
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h index 616544f..7068e5d 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h
@@ -201,6 +201,8 @@ void SetParent(uint64_t parent_id) override; void CreateSelectFileDialog( mojo::PendingReceiver<mojom::SelectFileDialog> receiver) override; + void ShowCertificateViewer( + const scoped_refptr<net::X509Certificate>& certificate) override; void StackAbove(uint64_t sibling_id) override; void StackAtTop() override; void ShowEmojiPanel() override;
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm index 2ee45cb..cad39d6 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
@@ -19,6 +19,7 @@ #include "base/strings/sys_string_conversions.h" #import "components/remote_cocoa/app_shim/bridged_content_view.h" #import "components/remote_cocoa/app_shim/browser_native_widget_window_mac.h" +#import "components/remote_cocoa/app_shim/certificate_viewer.h" #import "components/remote_cocoa/app_shim/mouse_capture.h" #import "components/remote_cocoa/app_shim/native_widget_mac_frameless_nswindow.h" #import "components/remote_cocoa/app_shim/native_widget_mac_nswindow.h" @@ -40,6 +41,7 @@ #include "ui/display/screen.h" #include "ui/events/cocoa/cocoa_event_utils.h" #include "ui/gfx/geometry/dip_util.h" +#include "ui/gfx/geometry/size_conversions.h" #import "ui/gfx/mac/coordinate_conversion.h" #import "ui/gfx/mac/nswindow_frame_controls.h" @@ -389,6 +391,11 @@ std::move(receiver)); } +void NativeWidgetNSWindowBridge::ShowCertificateViewer( + const scoped_refptr<net::X509Certificate>& certificate) { + ShowCertificateViewerForWindow(window_, certificate.get()); +} + void NativeWidgetNSWindowBridge::StackAbove(uint64_t sibling_id) { NativeWidgetNSWindowBridge* sibling_bridge = NativeWidgetNSWindowBridge::GetFromId(sibling_id); @@ -1226,8 +1233,9 @@ const gfx::CALayerParams& ca_layer_params) { // Ignore frames arriving "late" for an old size. A frame at the new size // should arrive soon. - gfx::Size frame_dip_size = gfx::ConvertSizeToDIP(ca_layer_params.scale_factor, - ca_layer_params.pixel_size); + // TODO(danakj): We should avoid lossy conversions to integer DIPs. + gfx::Size frame_dip_size = gfx::ToFlooredSize(gfx::ConvertSizeToDips( + ca_layer_params.pixel_size, ca_layer_params.scale_factor)); if (content_dip_size_ != frame_dip_size) return; compositor_frame_dip_size_ = frame_dip_size;
diff --git a/components/remote_cocoa/browser/window.h b/components/remote_cocoa/browser/window.h index 5c6099b..72926af6 100644 --- a/components/remote_cocoa/browser/window.h +++ b/components/remote_cocoa/browser/window.h
@@ -55,12 +55,6 @@ // being viewed in a remote process. bool REMOTE_COCOA_BROWSER_EXPORT IsWindowRemote(gfx::NativeWindow window); -// Create a transparent NSWindow that is in the same position as |window|, -// but is at the ModalPanel window level, so that it will appear over all -// other window. -NSWindow* REMOTE_COCOA_BROWSER_EXPORT -CreateInProcessTransparentClone(gfx::NativeWindow window); - } // namespace remote_cocoa #endif // COMPONENTS_REMOTE_COCOA_BROWSER_WINDOW_H_
diff --git a/components/remote_cocoa/browser/window.mm b/components/remote_cocoa/browser/window.mm index 11e4b8a..23afc17 100644 --- a/components/remote_cocoa/browser/window.mm +++ b/components/remote_cocoa/browser/window.mm
@@ -66,17 +66,4 @@ return nullptr; } -NSWindow* CreateInProcessTransparentClone(gfx::NativeWindow remote_window) { - DCHECK(IsWindowRemote(remote_window)); - NSWindow* window = [[NSWindow alloc] - initWithContentRect:[remote_window.GetNativeNSWindow() frame] - styleMask:NSWindowStyleMaskBorderless - backing:NSBackingStoreBuffered - defer:NO]; - [window setAlphaValue:0]; - [window makeKeyAndOrderFront:nil]; - [window setLevel:NSModalPanelWindowLevel]; - return window; -} - } // namespace remote_cocoa
diff --git a/components/remote_cocoa/common/BUILD.gn b/components/remote_cocoa/common/BUILD.gn index bce2462f..5005f8e 100644 --- a/components/remote_cocoa/common/BUILD.gn +++ b/components/remote_cocoa/common/BUILD.gn
@@ -19,6 +19,7 @@ public_deps = [ "//mojo/public/mojom/base", + "//services/network/public/mojom", "//ui/base/accelerators/mojom", "//ui/base/mojom", "//ui/display/mojom",
diff --git a/components/remote_cocoa/common/native_widget_ns_window.mojom b/components/remote_cocoa/common/native_widget_ns_window.mojom index 2a2bad4..b3dea656 100644 --- a/components/remote_cocoa/common/native_widget_ns_window.mojom +++ b/components/remote_cocoa/common/native_widget_ns_window.mojom
@@ -6,6 +6,7 @@ import "components/remote_cocoa/common/select_file_dialog.mojom"; import "mojo/public/mojom/base/string16.mojom"; +import "services/network/public/mojom/network_param.mojom"; import "ui/base/mojom/ui_base_types.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom"; import "ui/gfx/mojom/ca_layer_params.mojom"; @@ -91,6 +92,9 @@ // Open a panel for file selection or creation. CreateSelectFileDialog(pending_receiver<SelectFileDialog> dialog); + // Open a panel to display the specified certificate. + ShowCertificateViewer(network.mojom.X509Certificate certificate); + // Places this NativeWidgetNSWindow in front of the NativeWidgetNSWindow // indicated by |sibling_id| in z-order. StackAbove(uint64 sibling_id);
diff --git a/components/search_engines/android/java/src/org/chromium/components/search_engines/TemplateUrlService.java b/components/search_engines/android/java/src/org/chromium/components/search_engines/TemplateUrlService.java index 4f77ee7..9f6baa74a 100644 --- a/components/search_engines/android/java/src/org/chromium/components/search_engines/TemplateUrlService.java +++ b/components/search_engines/android/java/src/org/chromium/components/search_engines/TemplateUrlService.java
@@ -182,13 +182,6 @@ } /** - * Do not use. This is part of a 3-sided patch to avoid breaking downstream builds. - */ - public boolean isSearchResultsPageFromDefaultSearchProvider(String url) { - return isSearchResultsPageFromDefaultSearchProvider(new GURL(url)); - } - - /** * Checks whether a search result page is from a default search provider. * @param url The url for the search result page. * @return Whether the search result page with the given url from the default search provider.
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc index 6f6bf90..a616251 100644 --- a/components/signin/core/browser/account_reconcilor.cc +++ b/components/signin/core/browser/account_reconcilor.cc
@@ -533,16 +533,33 @@ identity_manager_->HasAccountWithRefreshTokenInPersistentErrorState( primary_account); - const signin::MultiloginParameters parameters_for_multilogin = - delegate_->CalculateParametersForMultilogin( + const signin::MultiloginParameters kLogoutParameters( + gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER, + std::vector<CoreAccountId>()); + + const bool should_revoke_tokens = + delegate_->ShouldRevokeTokensBeforeMultilogin( chrome_accounts, primary_account, gaia_accounts, first_execution_, primary_has_error); DCHECK(is_reconcile_started_); + signin::MultiloginParameters parameters_for_multilogin; + if (should_revoke_tokens) { + // Set parameters for logout for deleting cookies. + parameters_for_multilogin = kLogoutParameters; + RevokeAllSecondaryTokens( + identity_manager_, + AccountReconcilorDelegate::RevokeTokenOption::kRevoke, primary_account, + /*is_account_consistency_enforced=*/true, + signin_metrics::SourceForRefreshTokenOperation:: + kAccountReconcilor_Reconcile); + } else { + parameters_for_multilogin = delegate_->CalculateParametersForMultilogin( + chrome_accounts, primary_account, gaia_accounts, first_execution_, + primary_has_error); + } if (CookieNeedsUpdate(parameters_for_multilogin, gaia_accounts)) { - if (parameters_for_multilogin.mode == - gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER && - parameters_for_multilogin.accounts_to_send.empty()) { + if (parameters_for_multilogin == kLogoutParameters) { // UPDATE mode does not support empty list of accounts, call logout // instead. PerformLogoutAllAccountsAction();
diff --git a/components/signin/core/browser/account_reconcilor_delegate.cc b/components/signin/core/browser/account_reconcilor_delegate.cc index 2136f33..fd27447 100644 --- a/components/signin/core/browser/account_reconcilor_delegate.cc +++ b/components/signin/core/browser/account_reconcilor_delegate.cc
@@ -52,15 +52,27 @@ const std::vector<gaia::ListedAccount>& gaia_accounts, bool first_execution, bool primary_has_error) const { - const gaia::MultiloginMode mode = CalculateModeForReconcile( - gaia_accounts, primary_account, first_execution, primary_has_error); + const gaia::MultiloginMode mode = + CalculateModeForReconcile(chrome_accounts, gaia_accounts, primary_account, + first_execution, primary_has_error); const std::vector<CoreAccountId> accounts_to_send = GetChromeAccountsForReconcile(chrome_accounts, primary_account, - gaia_accounts, mode); + gaia_accounts, first_execution, + primary_has_error, mode); return {mode, accounts_to_send}; } +bool AccountReconcilorDelegate::ShouldRevokeTokensBeforeMultilogin( + const std::vector<CoreAccountId>& chrome_accounts, + const CoreAccountId& primary_account, + const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error) const { + return false; +} + gaia::MultiloginMode AccountReconcilorDelegate::CalculateModeForReconcile( + const std::vector<CoreAccountId>& chrome_accounts, const std::vector<gaia::ListedAccount>& gaia_accounts, const CoreAccountId& primary_account, bool first_execution, @@ -76,8 +88,8 @@ // Gaia only supports kMaxGaiaAccounts. Multilogin and MergeSession calls // which go above this count will fail. const int kMaxGaiaAccounts = 10; - DCHECK(!first_account.empty()); - DCHECK(base::Contains(chrome_accounts, first_account)); + DCHECK(first_account.empty() || + base::Contains(chrome_accounts, first_account)); // Ordered list of accounts, this is the result of this function. std::vector<CoreAccountId> ordered_accounts; @@ -104,22 +116,24 @@ // Put first_account in first position if needed, using swap to avoid changing // the order of existing cookies. - auto first_account_it = std::find(ordered_accounts.begin(), - ordered_accounts.end(), first_account); - if (first_account_it == ordered_accounts.end()) { - // The first account was not already in the cookies, add it in the first - // empty spot, or at the end if there is no available spot. - first_account_it = std::find(ordered_accounts.begin(), - ordered_accounts.end(), CoreAccountId()); + if (!first_account.empty()) { + auto first_account_it = std::find(ordered_accounts.begin(), + ordered_accounts.end(), first_account); if (first_account_it == ordered_accounts.end()) { - first_account_it = - ordered_accounts.insert(first_account_it, first_account); - } else { - *first_account_it = first_account; + // The first account was not already in the cookies, add it in the first + // empty spot, or at the end if there is no available spot. + first_account_it = std::find(ordered_accounts.begin(), + ordered_accounts.end(), CoreAccountId()); + if (first_account_it == ordered_accounts.end()) { + first_account_it = + ordered_accounts.insert(first_account_it, first_account); + } else { + *first_account_it = first_account; + } + chrome_accounts_set.erase(first_account); } - chrome_accounts_set.erase(first_account); + std::iter_swap(ordered_accounts.begin(), first_account_it); } - std::iter_swap(ordered_accounts.begin(), first_account_it); // Add the remaining chrome accounts. // First in empty spots. @@ -137,13 +151,12 @@ ordered_accounts.push_back(*remaining_accounts_it); ++remaining_accounts_it; } - // There may still be empty spots left. Compact the vector by moving accounts // from the end of the vector into the empty spots. auto compacting_it = ordered_accounts.begin(); while (compacting_it != ordered_accounts.end()) { // Remove all the empty accounts at the end. - while (ordered_accounts.back().empty()) + while (!ordered_accounts.empty() && ordered_accounts.back().empty()) ordered_accounts.pop_back(); // Find next empty slot. compacting_it = @@ -169,6 +182,8 @@ const std::vector<CoreAccountId>& chrome_accounts, const CoreAccountId& primary_account, const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error, const gaia::MultiloginMode mode) const { return std::vector<CoreAccountId>(); }
diff --git a/components/signin/core/browser/account_reconcilor_delegate.h b/components/signin/core/browser/account_reconcilor_delegate.h index 7477dec..3b3888c 100644 --- a/components/signin/core/browser/account_reconcilor_delegate.h +++ b/components/signin/core/browser/account_reconcilor_delegate.h
@@ -91,6 +91,15 @@ bool first_execution, bool primary_has_error) const; + // Returns whether secondary accounts should be revoked for doing full logout. + // Used only for the Multilogin codepath. + virtual bool ShouldRevokeTokensBeforeMultilogin( + const std::vector<CoreAccountId>& chrome_accounts, + const CoreAccountId& primary_account, + const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error) const; + // Returns whether secondary accounts should be revoked at the beginning of // the reconcile. virtual RevokeTokenOption ShouldRevokeSecondaryTokensBeforeReconcile( @@ -144,11 +153,11 @@ AccountReconcilor* reconcilor() { return reconcilor_; } protected: - // Computes a new ordering for chrome_accounts. |first_account| must be in - // |chrome_accounts|. The returned order has the following properties: - // - first_account will be first. + // Computes a new ordering for chrome_accounts. + // The returned order has the following properties: + // - first_account will be first if it's not empty. // - if a chrome account is also in gaia_accounts, the function tries to keep - // it at the same index. The function mimimizes account re-numbering. + // it at the same index. The function minimizes account re-numbering. // - if there are too many accounts, some accounts will be discarded. // |first_account| and accounts already in cookies will be kept in priority. // Aplhabetical order is used to break ties. @@ -166,11 +175,14 @@ const std::vector<CoreAccountId>& chrome_accounts, const CoreAccountId& primary_account, const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error, const gaia::MultiloginMode mode) const; // Returns Mode which shows if it is allowed to change the order of the gaia // accounts (e.g. on mobile or on stratup). Default is UPDATE. virtual gaia::MultiloginMode CalculateModeForReconcile( + const std::vector<CoreAccountId>& chrome_accounts, const std::vector<gaia::ListedAccount>& gaia_accounts, const CoreAccountId& primary_account, bool first_execution,
diff --git a/components/signin/core/browser/account_reconcilor_delegate_unittest.cc b/components/signin/core/browser/account_reconcilor_delegate_unittest.cc index a7c5d11..1196d93 100644 --- a/components/signin/core/browser/account_reconcilor_delegate_unittest.cc +++ b/components/signin/core/browser/account_reconcilor_delegate_unittest.cc
@@ -16,7 +16,7 @@ struct AccountReconcilorDelegateTestParam { const char* chrome_accounts; const char* gaia_accounts; - char first_account; + const char* first_account; const char* expected_order; }; @@ -25,64 +25,77 @@ // | Tokens | Cookies | First Acc. | Expected cookies | // |------------ Basic cases ----------------------------------------| // Nothing to do. - { "A", "A", 'A', "A" }, - { "ABCD", "ABCD", 'A', "ABCD" }, + { "A", "A", "A", "A" }, + { "ABCD", "ABCD", "A", "ABCD" }, // Token ordering does not matter. - { "DBCA", "ABCD", 'A', "ABCD" }, + { "DBCA", "ABCD", "A", "ABCD" }, // Simple reordering of cookies. - { "AB", "BA", 'A', "AB" }, + { "AB", "BA", "A", "AB" }, // |------------ Extra accounts in cookie ---------------------------| // Extra secondary account. - { "A", "AB", 'A', "A" }, + { "A", "AB", "A", "A" }, // Extra primary account. - { "A", "BA", 'A', "A" }, + { "A", "BA", "A", "A" }, // Multiple extra accounts. - { "AE", "ABCDEF", 'A', "AE" }, - { "AE", "GABCDEF", 'A', "AE" }, + { "AE", "ABCDEF", "A", "AE" }, + { "AE", "GABCDEF", "A", "AE" }, // C is kept in place. - { "ACF", "ABCDEF", 'A', "AFC" }, + { "ACF", "ABCDEF", "A", "AFC" }, // |------------ Missing accounts in cookie -------------------------| // Cookie was lost. - { "A", "", 'A', "A" }, - { "ABCD", "", 'A', "ABCD" }, + { "A", "", "A", "A" }, + { "ABCD", "", "A", "ABCD" }, // B kept in place. - { "ADB", "CB", 'A', "ABD" }, + { "ADB", "CB", "A", "ABD" }, // ACEG kept in place. - { "ABCDEFGH", "ACEG", 'A', "ACEGBDFH" }, + { "ABCDEFGH", "ACEG", "A", "ACEGBDFH" }, // C kept in place, but not B. - { "ABCD", "BC", 'A', "ACBD" }, + { "ABCD", "BC", "A", "ACBD" }, // D not kept in place. - { "AD", "ABCD", 'A', "AD" }, + { "AD", "ABCD", "A", "AD" }, // |------------ Both extra accounts and missing accounts -----------| // Simple account mismatch. - { "A", "B", 'A', "A" }, + { "A", "B", "A", "A" }, // ADE kept in place, BG removed. - { "ADEH", "ABDEG", 'A', "AHDE" }, + { "ADEH", "ABDEG", "A", "AHDE" }, // E kept in place, BG removed, AD swapped. - { "ADEH", "ABDEG", 'D', "DHAE" }, + { "ADEH", "ABDEG", "D", "DHAE" }, // Missing first account. - { "ADE", "BCDE", 'A', "AED" }, + { "ADE", "BCDE", "A", "AED" }, // Three-ways swap A-B-D. - { "ABCE", "BCDE", 'A', "ACBE" }, + { "ABCE", "BCDE", "A", "ACBE" }, // Extreme example. - { "ACJKL", "ABCDEFGHIJ", 'A', "AKCLJ" }, + { "ACJKL", "ABCDEFGHIJ", "A", "AKCLJ" }, // |------------ More than 10 accounts in chrome --------------------| // Trim extra accounts. - { "ABCDEFGHIJKLM", "ABCDEFGHIJ", 'A', "ABCDEFGHIJ" }, + { "ABCDEFGHIJKLM", "ABCDEFGHIJ", "A", "ABCDEFGHIJ" }, // D missing. - { "ABCEFGHIJKLMN", "ABCDEFGHIJ", 'A', "ABCKEFGHIJ" }, + { "ABCEFGHIJKLMN", "ABCDEFGHIJ", "A", "ABCKEFGHIJ" }, // DG missing. - { "ABCEFHIJKLMOP", "ABCDEFGHIJ", 'A', "ABCKEFLHIJ" }, + { "ABCEFHIJKLMOP", "ABCDEFGHIJ", "A", "ABCKEFLHIJ" }, // Primary swapped in. - { "ABCDEFGHIJKLM", "ABCDEFGHIJ", 'K', "KBCDEFGHIJ" }, + { "ABCDEFGHIJKLM", "ABCDEFGHIJ", "K", "KBCDEFGHIJ" }, // |------------ More than 10 accounts in cookie --------------------| // Trim extra account. - { "ABCDEFGHIJK", "ABCDEFGHIJK", 'A', "ABCDEFGHIJ" }, + { "ABCDEFGHIJK", "ABCDEFGHIJK", "A", "ABCDEFGHIJ" }, // Other edge cases. - { "BE", "ABCDEFGHIJK", 'B', "BE" }, - { "AE", "ABCDEFGHIJK", 'A', "AE" }, - { "AK", "ABCDEFGHIJK", 'A', "AK" }, - { "K", "ABCDEFGHIJK", 'K', "K" }, + { "BE", "ABCDEFGHIJK", "B", "BE" }, + { "AE", "ABCDEFGHIJK", "A", "AE" }, + { "AK", "ABCDEFGHIJK", "A", "AK" }, + { "K", "ABCDEFGHIJK", "K", "K" }, +// |------------ Missing first account ------------------------------| + // B kept in place. + { "AB", "B", "", "BA" }, + // BC kept in place, E removed, AD added. + { "ABCD", "BCE", "", "BCAD" }, + // C kept in place, first account D replaced. + { "ABC", "DC", "", "ACB" }, + // First accounts match + { "ABC", "AC", "", "ACB" }, + // Extreme example. + { "ACJKH", "JBCDEFGHIR", "", "JACKH" }, + // Empty chrome accounts. + { "", "ABC", "", "" }, }; // clang-format on @@ -117,13 +130,14 @@ TEST_P(AccountReconcilorDelegateTest, ReorderChromeAccountsForReconcile) { // Decode test parameters. CoreAccountId first_account = - CoreAccountId(std::string(1, GetParam().first_account)); + CoreAccountId(std::string(GetParam().first_account)); std::vector<CoreAccountId> chrome_accounts; for (int i = 0; GetParam().chrome_accounts[i] != '\0'; ++i) { chrome_accounts.push_back( CoreAccountId(std::string(1, GetParam().chrome_accounts[i]))); } - ASSERT_TRUE(base::Contains(chrome_accounts, first_account)) + ASSERT_TRUE(first_account.empty() || + base::Contains(chrome_accounts, first_account)) << "Invalid test parameter."; std::vector<gaia::ListedAccount> gaia_accounts = GaiaAccountsFromString(GetParam().gaia_accounts);
diff --git a/components/signin/core/browser/account_reconcilor_unittest.cc b/components/signin/core/browser/account_reconcilor_unittest.cc index 5474b4b..9cbc468 100644 --- a/components/signin/core/browser/account_reconcilor_unittest.cc +++ b/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -83,6 +83,8 @@ const std::vector<CoreAccountId>& chrome_accounts, const CoreAccountId& primary_account, const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error, const gaia::MultiloginMode mode) const override { return chrome_accounts; } @@ -835,19 +837,19 @@ cookies_after_reconcile.push_back({account.ToString(), true}); } } else { - std::set<CoreAccountId> accounts_set(parameters.accounts_to_send.begin(), - parameters.accounts_to_send.end()); + std::vector<CoreAccountId> accounts(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(CoreAccountId(param.gaia_id)) != - accounts_set.end()) { + CoreAccountId account = CoreAccountId(param.gaia_id); + if (base::Contains(accounts, account)) { param.is_valid = true; - accounts_set.erase(CoreAccountId(param.gaia_id)); + accounts.erase(std::find(accounts.begin(), accounts.end(), account)); } else { - param.is_valid = false; + DCHECK(!param.is_valid); } } - for (const CoreAccountId& account : accounts_set) { + for (const CoreAccountId& account : accounts) { cookies_after_reconcile.push_back({account.ToString(), true}); } } @@ -881,159 +883,156 @@ // First reconcile (Chrome restart): Rebuild the Gaia cookie to match the // tokens. Make the Sync account the default account in the Gaia cookie. // Sync enabled. - { "", "A", IsFirstReconcile::kBoth, "X", "", "", "P", "", "xA", 3}, - { "*AB", "AB", IsFirstReconcile::kBoth, "", "*AB", "AB", "", "*AB", "AB", 0}, - { "*A", "A", IsFirstReconcile::kBoth, "", "*A", "A", "", "*A" , "A", 0}, + { "", "A", IsFirstReconcile::kBoth, "X", "", "", "U", "", "", 3}, + { "*AB", "AB", IsFirstReconcile::kBoth, "", "*AB", "AB", "", "*AB", "AB", 0}, + { "*A", "A", IsFirstReconcile::kBoth, "", "*A", "A", "", "*A" , "A", 0}, + { "*A", "", IsFirstReconcile::kBoth, "A", "*A", "A", "PA", "*A" , "A", 1}, + { "*A", "B", IsFirstReconcile::kBoth, "XA", "*A", "A", "UA", "*A" , "A", 1}, + { "*A", "AB", IsFirstReconcile::kBoth, "XA", "*A", "A", "UA", "*A" , "A", 5}, + { "*AB", "BA", IsFirstReconcile::kFirst, "XAB", "*AB", "AB", "UAB", "*AB", "AB", 7}, + { "*AB", "BA", IsFirstReconcile::kNotFirst, "", "*AB", "BA", "", "*AB", "BA", 0}, - { "*A", "", IsFirstReconcile::kFirst, "A", "*A", "A", "UA", "*A" , "A", 1}, - { "*A", "", IsFirstReconcile::kNotFirst, "A", "*A", "A", "PA", "*A" , "A", 1}, + { "*AB", "A", IsFirstReconcile::kBoth, "B", "*AB", "AB", "PAB", "*AB", "AB", 4}, - { "*A", "B", IsFirstReconcile::kFirst, "XA", "*A", "A", "UA", "*A" , "A", 1}, - { "*A", "B", IsFirstReconcile::kNotFirst, "XA", "*A", "A", "PA", "*A" , "xBA", 1}, + { "*AB", "B", IsFirstReconcile::kFirst, "XAB", "*AB", "AB", "UAB", "*AB", "AB", 1}, + { "*AB", "B", IsFirstReconcile::kNotFirst, "A", "*AB", "BA", "PBA", "*AB", "BA", 1}, - { "*A", "AB", IsFirstReconcile::kBoth, "XA", "*A", "A", "PA", "*A" , "AxB", 5}, - - { "*AB", "BA", IsFirstReconcile::kFirst, "XAB", "*AB", "AB", "UAB", "*AB", "AB", 7}, - { "*AB", "BA", IsFirstReconcile::kNotFirst, "", "*AB", "BA", "", "*AB", "BA", 0}, - - { "*AB", "A", IsFirstReconcile::kBoth, "B", "*AB", "AB", "PAB", "*AB", "AB", 4}, - - { "*AB", "B", IsFirstReconcile::kFirst, "XAB", "*AB", "AB", "UAB", "*AB", "AB", 1}, - { "*AB", "B", IsFirstReconcile::kNotFirst, "A", "*AB", "BA", "PAB", "*AB", "BA", 1}, - - { "*AB", "", IsFirstReconcile::kFirst, "AB", "*AB", "AB", "UAB", "*AB", "AB", 1}, - { "*AB", "", IsFirstReconcile::kNotFirst, "AB", "*AB", "AB", "PAB", "*AB", "AB", 1}, + { "*AB", "", IsFirstReconcile::kBoth, "AB", "*AB", "AB", "PAB", "*AB", "AB", 1}, // Sync enabled, token error on primary. - { "*xAB", "AB", IsFirstReconcile::kBoth, "X", "*xA", "" , "PB", "*xAB", "xAB", 2}, - { "*xAB", "BA", IsFirstReconcile::kBoth, "XB", "*xAB", "B", "PB", "*xAB", "BxA", 2}, - { "*xAB", "A", IsFirstReconcile::kBoth, "X", "*xA", "" , "PB", "*xAB", "xAB", 2}, - { "*xAB", "B", IsFirstReconcile::kBoth, "", "*xAB", "B", "", "*xAB", "B" , 0}, - { "*xAB", "", IsFirstReconcile::kBoth, "B", "*xAB", "B", "PB", "*xAB", "B" , 0}, + + { "*xAB", "AB", IsFirstReconcile::kBoth, "X", "*xA", "" , "U", "*xA", "", 2}, + { "*xAB", "BA", IsFirstReconcile::kBoth, "XB", "*xAB", "B", "UB", "*xAB", "B", 2}, + { "*xAB", "A", IsFirstReconcile::kBoth, "X", "*xA", "" , "U", "*xA", "", 2}, + { "*xAB", "B", IsFirstReconcile::kBoth, "", "*xAB", "B", "", "*xAB", "B", 0}, + { "*xAB", "", IsFirstReconcile::kBoth, "B", "*xAB", "B", "PB", "*xAB", "B", 0}, // Sync enabled, token error on secondary. - { "*AxB", "AB", IsFirstReconcile::kBoth, "XA", "*A", "A", "PA", "*A", "AxB", 5}, - - { "*AxB", "BA", IsFirstReconcile::kFirst, "XA", "*A", "A", "UA", "*A", "A" , 5}, - { "*AxB", "BA", IsFirstReconcile::kNotFirst, "XA", "*A", "A", "PA", "*A", "xBA", 5}, - - { "*AxB", "A", IsFirstReconcile::kBoth, "", "*A", "A", "", "*A", "A" , 0 }, - - { "*AxB", "B", IsFirstReconcile::kFirst, "XA", "*A", "A", "UA", "*A", "A" , 1}, - { "*AxB", "B", IsFirstReconcile::kNotFirst, "XA", "*A", "A", "PA", "*A", "xBA", 1 }, - - { "*AxB", "", IsFirstReconcile::kFirst, "A", "*A", "A", "UA", "*A", "A", 1}, - { "*AxB", "", IsFirstReconcile::kNotFirst, "A", "*A", "A", "PA", "*A", "A", 1}, + { "*AxB", "AB", IsFirstReconcile::kBoth, "XA", "*A", "A", "UA", "*A", "A", 5}, + { "*AxB", "A", IsFirstReconcile::kBoth, "", "*A", "A", "", "*A", "A", 0}, + { "*AxB", "", IsFirstReconcile::kBoth, "A", "*A", "A", "PA", "*A", "A", 1}, + // The first account in cookies is swapped even when Chrome is running. + // The swap would happen at next startup anyway and doing it earlier avoids signing the user out. + { "*AxB", "BA", IsFirstReconcile::kBoth, "XA", "*A", "A", "UA", "*A", "A", 5}, + { "*AxB", "B", IsFirstReconcile::kBoth, "XA", "*A", "A", "UA", "*A", "A", 1}, // Sync enabled, token error on both accounts. - { "*xAxB", "AB", IsFirstReconcile::kBoth, "X", "*xA", "", "P", "*xA", "xAxB", 2}, - { "*xAxB", "BA", IsFirstReconcile::kBoth, "X", "*xA", "", "P", "*xA", "xBxA", 2}, - { "*xAxB", "A", IsFirstReconcile::kBoth, "X", "*xA", "", "P", "*xA", "xA", 2}, - { "*xAxB", "B", IsFirstReconcile::kBoth, "X", "*xA", "", "P", "*xA", "xB", 5}, - { "*xAxB", "", IsFirstReconcile::kBoth, "", "*xA", "", "", "*xA", "", 0}, + { "*xAxB", "AB", IsFirstReconcile::kBoth, "X", "*xA", "", "U", "*xA", "", 2}, + { "*xAxB", "BA", IsFirstReconcile::kBoth, "X", "*xA", "", "U", "*xA", "", 2}, + { "*xAxB", "A", IsFirstReconcile::kBoth, "X", "*xA", "", "U", "*xA", "", 2}, + { "*xAxB", "B", IsFirstReconcile::kBoth, "X", "*xA", "", "U", "*xA", "", 5}, + { "*xAxB", "", IsFirstReconcile::kBoth, "", "*xA", "", "", "*xA", "", 0}, // Sync disabled. - { "AB", "AB", IsFirstReconcile::kBoth, "", "AB", "AB", "", "AB", "AB", 0}, - { "AB", "BA", IsFirstReconcile::kBoth, "", "AB", "BA", "", "AB", "BA", 0}, - { "AB", "A", IsFirstReconcile::kBoth, "B", "AB", "AB", "PAB", "AB", "AB", 4}, - { "AB", "B", IsFirstReconcile::kBoth, "A", "AB", "BA", "PAB", "AB", "BA", 4}, - { "AB", "", IsFirstReconcile::kBoth, "AB", "AB", "AB", "PAB", "AB", "AB", 0}, + { "AB", "AB", IsFirstReconcile::kBoth, "", "AB", "AB", "", "AB", "AB", 0}, + { "AB", "BA", IsFirstReconcile::kBoth, "", "AB", "BA", "", "AB", "BA", 0}, + { "AB", "A", IsFirstReconcile::kBoth, "B", "AB", "AB", "PAB", "AB", "AB", 4}, + { "AB", "B", IsFirstReconcile::kBoth, "A", "AB", "BA", "PBA", "AB", "BA", 4}, + { "AB", "", IsFirstReconcile::kBoth, "AB", "AB", "AB", "PAB", "AB", "AB", 0}, // Sync disabled, token error on first account. - { "xAB", "AB", IsFirstReconcile::kFirst, "XB", "B", "B", "PB", "B", "xAB", 3}, - { "xAB", "AB", IsFirstReconcile::kNotFirst, "X", "", "" , "PB", "B", "xAB", 3}, + { "xAB", "AB", IsFirstReconcile::kFirst, "XB", "B", "B", "UB", "B", "B", 3}, + { "xAB", "AB", IsFirstReconcile::kNotFirst, "X", "", "" , "U", "", "", 3}, - { "xAB", "BA", IsFirstReconcile::kBoth, "XB", "B", "B", "PB", "B", "BxA", 5}, + { "xAB", "BA", IsFirstReconcile::kBoth, "XB", "B", "B", "UB", "B", "B", 5}, - { "xAB", "A", IsFirstReconcile::kFirst, "XB", "B", "B", "PB", "B", "xAB", 3}, - { "xAB", "A", IsFirstReconcile::kNotFirst, "X", "", "" , "PB", "B", "xAB", 3}, + { "xAB", "A", IsFirstReconcile::kFirst, "XB", "B", "B", "UB", "B", "B", 3}, + { "xAB", "A", IsFirstReconcile::kNotFirst, "X", "", "" , "U", "", "", 3}, - { "xAB", "B", IsFirstReconcile::kBoth, "", "B", "B", "", "B", "B", 0}, + { "xAB", "B", IsFirstReconcile::kBoth, "", "B", "B", "", "B", "B", 0}, - { "xAB", "", IsFirstReconcile::kBoth, "B", "B", "B", "PB", "B", "B", 0}, + { "xAB", "", IsFirstReconcile::kBoth, "B", "B", "B", "PB", "B", "B", 0}, // Sync disabled, token error on second account . - { "AxB", "AB", IsFirstReconcile::kBoth, "XA", "A", "A", "PA", "A", "AxB", 5}, + { "AxB", "AB", IsFirstReconcile::kBoth, "XA", "A", "A", "UA", "A", "A", 5}, - { "AxB", "BA", IsFirstReconcile::kFirst, "XA", "A", "A", "PA", "A", "xBA", 3}, - { "AxB", "BA", IsFirstReconcile::kNotFirst, "X", "", "" , "PA", "A", "xBA", 3}, + { "AxB", "BA", IsFirstReconcile::kFirst, "XA", "A", "A", "UA", "A", "A", 3}, + { "AxB", "BA", IsFirstReconcile::kNotFirst, "X", "", "" , "U", "", "", 3}, - { "AxB", "A", IsFirstReconcile::kBoth, "", "A", "A", "", "A", "A", 0}, + { "AxB", "A", IsFirstReconcile::kBoth, "", "A", "A", "", "A", "A", 0}, - { "AxB", "B", IsFirstReconcile::kFirst, "XA", "A", "A", "PA", "A", "xBA", 3}, - { "AxB", "B", IsFirstReconcile::kNotFirst, "X", "", "" , "PA", "A", "xBA", 3}, + { "AxB", "B", IsFirstReconcile::kFirst, "XA", "A", "A", "UA", "A", "A", 3}, + { "AxB", "B", IsFirstReconcile::kNotFirst, "X", "", "" , "U", "", "", 3}, - { "AxB", "", IsFirstReconcile::kBoth, "A", "A", "A", "PA", "A", "A", 0}, + { "AxB", "", IsFirstReconcile::kBoth, "A", "A", "A", "PA", "A", "A", 0}, // Sync disabled, token error on both accounts. - { "xAxB", "AB", IsFirstReconcile::kBoth, "X", "", "", "P", "", "xAxB", 3}, - { "xAxB", "BA", IsFirstReconcile::kBoth, "X", "", "", "P", "", "xBxA", 3}, - { "xAxB", "A", IsFirstReconcile::kBoth, "X", "", "", "P", "", "xA", 3}, - { "xAxB", "B", IsFirstReconcile::kBoth, "X", "", "", "P", "", "xB", 3}, - { "xAxB", "", IsFirstReconcile::kBoth, "", "", "", "", "", "", 0}, + { "xAxB", "AB", IsFirstReconcile::kBoth, "X", "", "", "U", "", "", 3}, + { "xAxB", "BA", IsFirstReconcile::kBoth, "X", "", "", "U", "", "", 3}, + { "xAxB", "A", IsFirstReconcile::kBoth, "X", "", "", "U", "", "", 3}, + { "xAxB", "B", IsFirstReconcile::kBoth, "X", "", "", "U", "", "", 3}, + { "xAxB", "", IsFirstReconcile::kBoth, "", "", "", "", "", "", 0}, // Account marked as invalid in cookies. // No difference between cookies and tokens, do not do do anything. // Do not logout. Regression tests for http://crbug.com/854799 - { "", "xA", IsFirstReconcile::kBoth, "", "", "xA", "", "", "xA", 0}, - { "", "xAxB", IsFirstReconcile::kBoth, "", "", "xAxB", "", "", "xAxB", 0}, - { "xA", "xA", IsFirstReconcile::kBoth, "", "", "xA", "", "", "xA", 0}, - { "xAB", "xAB", IsFirstReconcile::kBoth, "", "B", "xAB", "", "B", "xAB", 0}, - { "AxB", "AxC", IsFirstReconcile::kBoth, "", "A", "AxC", "", "A", "AxC", 0}, - { "B", "xAB", IsFirstReconcile::kBoth, "", "B", "xAB", "", "B", "xAB", 0}, - { "*xA", "xA", IsFirstReconcile::kBoth, "", "*xA", "xA", "", "*xA", "xA", 0}, - { "*xA", "xB", IsFirstReconcile::kBoth, "", "*xA", "xB", "", "*xA", "xB", 0}, - { "*xAB", "xAB", IsFirstReconcile::kBoth, "", "*xAB", "xAB", "", "*xAB", "xAB", 0}, - { "*AxB", "xBA", IsFirstReconcile::kNotFirst, "", "*A", "xBA", "", "*A", "xBA", 0}, + { "", "xA", IsFirstReconcile::kBoth, "", "", "xA", "", "", "xA", 0}, + { "", "xAxB", IsFirstReconcile::kBoth, "", "", "xAxB", "", "", "xAxB", 0}, + { "xA", "xA", IsFirstReconcile::kBoth, "", "", "xA", "", "", "xA", 0}, + { "xAB", "xAB", IsFirstReconcile::kBoth, "", "B", "xAB", "", "B", "xAB", 0}, + { "AxB", "AxC", IsFirstReconcile::kBoth, "", "A", "AxC", "", "A", "AxC", 0}, + { "B", "xAB", IsFirstReconcile::kBoth, "", "B", "xAB", "", "B", "xAB", 0}, + { "*xA", "xA", IsFirstReconcile::kBoth, "", "*xA", "xA", "", "*xA", "xA", 0}, + { "*xA", "xB", IsFirstReconcile::kBoth, "", "*xA", "xB", "", "*xA", "xB", 0}, + { "*xAB", "xAB", IsFirstReconcile::kBoth, "", "*xAB", "xAB", "", "*xAB", "xAB", 0}, + { "*AxB", "xBA", IsFirstReconcile::kNotFirst, "", "*A", "xBA", "", "*A", "xBA", 0}, // Appending a new cookie after the invalid one. - { "B", "xA", IsFirstReconcile::kBoth, "B", "B", "xAB", "PB", "B", "xAB", 4}, - { "xAB", "xA", IsFirstReconcile::kBoth, "B", "B", "xAB", "PB", "B", "xAB", 4}, + { "B", "xA", IsFirstReconcile::kBoth, "B", "B", "xAB", "PB", "B", "xAB", 4}, + { "xAB", "xA", IsFirstReconcile::kBoth, "B", "B", "xAB", "PB", "B", "xAB", 4}, // Refresh existing cookies. - { "AB", "xAB", IsFirstReconcile::kBoth, "A", "AB", "AB", "PAB","AB", "AB", 4}, - { "*AB", "xBxA", IsFirstReconcile::kNotFirst, "BA", "*AB", "BA", "PAB","*AB", "BA", 1}, + { "AB", "xAB", IsFirstReconcile::kBoth, "A", "AB", "AB", "PAB", "AB", "AB", 4}, + { "*AB", "xBxA", IsFirstReconcile::kNotFirst, "BA", "*AB", "BA", "PBA", "*AB", "BA", 1}, // Appending and invalidating cookies at the same time. - // Difference should disappear after migrating to Multilogin. - { "xAB", "xAC", IsFirstReconcile::kFirst, "XB", "B", "B", "PB", "B", "xAxCB", 6}, - { "xAB", "xAC", IsFirstReconcile::kNotFirst, "X", "", "", "PB", "B", "xAxCB", 6}, + { "xAB", "xAC", IsFirstReconcile::kFirst, "XB", "B", "B", "UB", "B", "B", 6}, + { "xAB", "xAC", IsFirstReconcile::kNotFirst, "X", "", "", "U", "", "", 6}, - { "xAB", "AxC", IsFirstReconcile::kFirst, "XB", "B", "B", "PB", "B", "xAxCB", 3}, - { "xAB", "AxC", IsFirstReconcile::kNotFirst, "X", "", "", "PB", "B", "xAxCB", 3}, + { "xAB", "AxC", IsFirstReconcile::kFirst, "XB", "B", "B", "UB", "B", "B", 3}, + { "xAB", "AxC", IsFirstReconcile::kNotFirst, "X", "", "", "U", "", "", 3}, - { "*xAB", "xABC", IsFirstReconcile::kFirst, "XB", "*xAB", "B", "PB", "*xAB", "xABxC", 5}, - { "*xAB", "xABC", IsFirstReconcile::kNotFirst, "X", "*xA", "", "PB", "*xAB", "xABxC", 5}, + { "*xAB", "xABC", IsFirstReconcile::kFirst, "XB", "*xAB", "B", "UB", "*xAB", "B", 5}, + { "*xAB", "xABC", IsFirstReconcile::kNotFirst, "X", "*xA", "", "U", "*xA", "", 5}, - { "xAB", "xABC", IsFirstReconcile::kFirst, "XB", "B", "B", "PB", "B", "xABxC", 5}, - { "xAB", "xABC", IsFirstReconcile::kNotFirst, "X", "", "", "PB", "B", "xABxC", 5}, - + { "xAB", "xABC", IsFirstReconcile::kFirst, "XB", "B", "B", "UB", "B", "B", 5}, + { "xAB", "xABC", IsFirstReconcile::kNotFirst, "X", "", "", "U", "", "", 5}, // Miscellaneous cases. // Check that unknown Gaia accounts are signed out. - { "*A", "AB", IsFirstReconcile::kBoth, "XA", "*A", "A", "PA", "*A", "AxB", 5}, + { "*A", "AB", IsFirstReconcile::kBoth, "XA", "*A", "A", "UA", "*A", "A", 5}, // Check that Gaia default account is kept in first position. - { "AB", "BC", IsFirstReconcile::kBoth, "XBA","AB", "BA", "PAB","AB", "BxCA", 6}, + { "AB", "BC", IsFirstReconcile::kBoth, "XBA", "AB", "BA", "UBA", "AB", "BA", 6}, // Check that Gaia cookie order is preserved for B. - { "*ABC", "CB", IsFirstReconcile::kFirst, "XABC","*ABC", "ABC", "UABC","*ABC","ABC", 1}, + { "*ABC", "CB", IsFirstReconcile::kFirst, "XABC", "*ABC", "ABC", "UABC", "*ABC", "ABC", 1}, + // TODO(https://crbug.com/1129931): Merge session should do XCB instead. + { "xABC", "ABC", IsFirstReconcile::kFirst, "XBC", "BC", "BC", "UCB", "BC", "CB", 1}, + // Check that order in the chrome_accounts is not important. + { "A*B", "", IsFirstReconcile::kBoth, "BA", "A*B", "BA", "PBA", "A*B", "BA", 7}, + { "*xBA", "BA", IsFirstReconcile::kFirst, "X", "*xB", "" , "U", "*xB", "", 2}, // Required for idempotency check. - { "", "", IsFirstReconcile::kNotFirst, "", "", "", "", "", "", 0}, - { "", "xA", IsFirstReconcile::kNotFirst, "", "", "xA", "", "", "xA", 0}, - { "", "xB", IsFirstReconcile::kNotFirst, "", "", "xB", "", "", "xB", 0}, - { "", "xAxB", IsFirstReconcile::kNotFirst, "", "", "xAxB", "", "", "xAxB", 0}, - { "", "xBxA", IsFirstReconcile::kNotFirst, "", "", "xBxA", "", "", "xBxA", 0}, - { "*A", "A", IsFirstReconcile::kNotFirst, "", "*A", "A", "", "*A", "A", 0}, - { "*A", "xBA", IsFirstReconcile::kNotFirst, "", "*A", "xBA", "", "*A", "xBA", 0}, - { "*A", "AxB", IsFirstReconcile::kNotFirst, "", "*A", "AxB", "", "*A", "AxB", 0}, - { "A", "A", IsFirstReconcile::kNotFirst, "", "A", "A", "", "A", "A", 0}, - { "A", "xBA", IsFirstReconcile::kNotFirst, "", "A", "xBA", "", "A", "xBA", 0}, - { "A", "AxB", IsFirstReconcile::kNotFirst, "", "A", "AxB", "", "A", "AxB", 0}, - { "B", "B", IsFirstReconcile::kNotFirst, "", "B", "B", "", "B", "B", 0}, - { "B", "xAB", IsFirstReconcile::kNotFirst, "", "B", "xAB", "", "B", "xAB", 0}, - { "B", "BxA", IsFirstReconcile::kNotFirst, "", "B", "BxA", "", "B", "BxA", 0}, - { "*xA", "", IsFirstReconcile::kNotFirst, "", "*xA", "", "", "*xA", "", 0}, - { "*xA", "xAxB", IsFirstReconcile::kNotFirst, "", "*xA", "xAxB", "", "*xA", "xAxB", 0}, - { "*xA", "xBxA", IsFirstReconcile::kNotFirst, "", "*xA", "xBxA", "", "*xA", "xBxA", 0}, - { "*xA", "xA", IsFirstReconcile::kNotFirst, "", "*xA", "xA", "", "*xA", "xA", 0}, - { "*xA", "xB", IsFirstReconcile::kNotFirst, "", "*xA", "xB", "", "*xA", "xB", 0}, - { "*xAB", "B", IsFirstReconcile::kNotFirst, "", "*xAB", "B", "", "*xAB", "B", 0}, - { "*xAB", "BxA", IsFirstReconcile::kNotFirst, "", "*xAB", "BxA", "", "*xAB", "BxA", 0}, - { "*xAB", "xAB", IsFirstReconcile::kNotFirst, "", "*xAB", "xAB", "", "*xAB", "xAB", 0}, - { "*xAB", "xABxC",IsFirstReconcile::kNotFirst, "", "*xAB", "xABxC","", "*xAB", "xABxC", 0}, - { "A", "AxC", IsFirstReconcile::kNotFirst, "", "A", "AxC", "", "A", "AxC", 0}, - { "AB", "BxCA", IsFirstReconcile::kNotFirst, "", "AB", "BxCA", "", "AB", "BxCA", 0}, - { "B", "xABxC",IsFirstReconcile::kNotFirst, "", "B", "xABxC","", "B", "xABxC", 0}, - { "B", "xAxCB",IsFirstReconcile::kNotFirst, "", "B", "xAxCB","", "B", "xAxCB", 0}, - { "*ABC", "ACB", IsFirstReconcile::kNotFirst, "", "*ABC", "ACB", "", "*ABC", "ACB", 0}, - { "*ABC", "ABC", IsFirstReconcile::kNotFirst, "", "*ABC", "ABC", "", "*ABC", "ABC", 0} + { "", "", IsFirstReconcile::kNotFirst, "", "", "", "", "", "", 0}, + { "", "xA", IsFirstReconcile::kNotFirst, "", "", "xA", "", "", "xA", 0}, + { "", "xB", IsFirstReconcile::kNotFirst, "", "", "xB", "", "", "xB", 0}, + { "", "xAxB", IsFirstReconcile::kNotFirst, "", "", "xAxB", "", "", "xAxB", 0}, + { "", "xBxA", IsFirstReconcile::kNotFirst, "", "", "xBxA", "", "", "xBxA", 0}, + { "*A", "A", IsFirstReconcile::kNotFirst, "", "*A", "A", "", "*A", "A", 0}, + { "*A", "xBA", IsFirstReconcile::kNotFirst, "", "*A", "xBA", "", "*A", "xBA", 0}, + { "*A", "AxB", IsFirstReconcile::kNotFirst, "", "*A", "AxB", "", "*A", "AxB", 0}, + { "A", "A", IsFirstReconcile::kNotFirst, "", "A", "A", "", "A", "A", 0}, + { "A", "xBA", IsFirstReconcile::kNotFirst, "", "A", "xBA", "", "A", "xBA", 0}, + { "A", "AxB", IsFirstReconcile::kNotFirst, "", "A", "AxB", "", "A", "AxB", 0}, + { "B", "B", IsFirstReconcile::kNotFirst, "", "B", "B", "", "B", "B", 0}, + { "B", "xAB", IsFirstReconcile::kNotFirst, "", "B", "xAB", "", "B", "xAB", 0}, + { "B", "BxA", IsFirstReconcile::kNotFirst, "", "B", "BxA", "", "B", "BxA", 0}, + { "*xA", "", IsFirstReconcile::kNotFirst, "", "*xA", "", "", "*xA", "", 0}, + { "*xA", "xAxB", IsFirstReconcile::kNotFirst, "", "*xA", "xAxB", "", "*xA", "xAxB", 0}, + { "*xA", "xBxA", IsFirstReconcile::kNotFirst, "", "*xA", "xBxA", "", "*xA", "xBxA", 0}, + { "*xA", "xA", IsFirstReconcile::kNotFirst, "", "*xA", "xA", "", "*xA", "xA", 0}, + { "*xA", "xB", IsFirstReconcile::kNotFirst, "", "*xA", "xB", "", "*xA", "xB", 0}, + { "*xAB", "B", IsFirstReconcile::kNotFirst, "", "*xAB", "B", "", "*xAB", "B", 0}, + { "*xAB", "BxA", IsFirstReconcile::kNotFirst, "", "*xAB", "BxA", "", "*xAB", "BxA", 0}, + { "*xAB", "xAB", IsFirstReconcile::kNotFirst, "", "*xAB", "xAB", "", "*xAB", "xAB", 0}, + { "*xAB", "xABxC",IsFirstReconcile::kNotFirst, "", "*xAB", "xABxC", "", "*xAB", "xABxC", 0}, + { "*xB", "", IsFirstReconcile::kNotFirst, "", "*xB", "", "", "*xB", "", 0}, + { "A*B", "BA", IsFirstReconcile::kNotFirst, "", "A*B", "BA", "", "A*B", "BA", 0}, + { "A*B", "AB", IsFirstReconcile::kNotFirst, "", "A*B", "AB", "", "A*B", "AB", 0}, + { "A", "AxC", IsFirstReconcile::kNotFirst, "", "A", "AxC", "", "A", "AxC", 0}, + { "AB", "BxCA", IsFirstReconcile::kNotFirst, "", "AB", "BxCA", "", "AB", "BxCA", 0}, + { "B", "xABxC",IsFirstReconcile::kNotFirst, "", "B", "xABxC", "", "B", "xABxC", 0}, + { "B", "xAxCB",IsFirstReconcile::kNotFirst, "", "B", "xAxCB", "", "B", "xAxCB", 0}, + { "*ABC", "ACB", IsFirstReconcile::kNotFirst, "", "*ABC", "ACB", "", "*ABC", "ACB", 0}, + { "*ABC", "ABC", IsFirstReconcile::kNotFirst, "", "*ABC", "ABC", "", "*ABC", "ABC", 0}, + { "BC", "BC", IsFirstReconcile::kNotFirst, "", "BC", "BC", "", "BC", "BC", 0}, + { "BC", "CB", IsFirstReconcile::kNotFirst, "", "BC", "CB", "", "BC", "CB", 0}, }; // clang-format on @@ -1199,7 +1198,15 @@ } const signin::MultiloginParameters params(mode, accounts_to_send); cookies_after_reconcile = FakeSetAccountsInCookie(params, cookies); - EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params)).Times(1); + if (accounts_to_send.empty() && + (mode == + gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER)) { + EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction()) + .Times(1); + } else { + EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params)) + .Times(1); + } } // Reconcile. AccountReconcilor* reconcilor = GetMockReconcilor(); @@ -1364,10 +1371,10 @@ EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id_1)); } else { std::vector<CoreAccountId> accounts_to_send = {account_id_2, account_id_1}; - // Send accounts to Gaia in any order, it will determine the order itself in - // PRESERVE order. + // Send accounts to Gaia in order of chrome accounts. Account 2 is added + // first. const signin::MultiloginParameters params( - gaia::MultiloginMode::MULTILOGIN_PRESERVE_COOKIE_ACCOUNTS_ORDER, + gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER, accounts_to_send); EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params)); } @@ -2797,10 +2804,13 @@ const std::vector<CoreAccountId>& chrome_accounts, const CoreAccountId& primary_account, const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error, const gaia::MultiloginMode mode) const override { return {}; } gaia::MultiloginMode CalculateModeForReconcile( + const std::vector<CoreAccountId>& chrome_accounts, const std::vector<gaia::ListedAccount>& gaia_accounts, const CoreAccountId& primary_account, bool first_execution,
diff --git a/components/signin/core/browser/active_directory_account_reconcilor_delegate.cc b/components/signin/core/browser/active_directory_account_reconcilor_delegate.cc index a848799..e045435 100644 --- a/components/signin/core/browser/active_directory_account_reconcilor_delegate.cc +++ b/components/signin/core/browser/active_directory_account_reconcilor_delegate.cc
@@ -46,6 +46,8 @@ const std::vector<CoreAccountId>& chrome_accounts, const CoreAccountId& primary_account, const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error, const gaia::MultiloginMode mode) const { DCHECK_EQ(mode, gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER);
diff --git a/components/signin/core/browser/active_directory_account_reconcilor_delegate.h b/components/signin/core/browser/active_directory_account_reconcilor_delegate.h index dd1d215f..4d4d74d 100644 --- a/components/signin/core/browser/active_directory_account_reconcilor_delegate.h +++ b/components/signin/core/browser/active_directory_account_reconcilor_delegate.h
@@ -34,6 +34,8 @@ const std::vector<CoreAccountId>& chrome_accounts, const CoreAccountId& primary_account, const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error, const gaia::MultiloginMode mode) const override; bool ShouldAbortReconcileIfPrimaryHasError() const override; bool ShouldRevokeTokensIfNoPrimaryAccount() const override;
diff --git a/components/signin/core/browser/dice_account_reconcilor_delegate.cc b/components/signin/core/browser/dice_account_reconcilor_delegate.cc index 8c2749be..b008cc3 100644 --- a/components/signin/core/browser/dice_account_reconcilor_delegate.cc +++ b/components/signin/core/browser/dice_account_reconcilor_delegate.cc
@@ -174,18 +174,95 @@ return CoreAccountId(); } -gaia::MultiloginMode DiceAccountReconcilorDelegate::CalculateModeForReconcile( +bool DiceAccountReconcilorDelegate::ShouldDeleteAccountsFromGaia( + const std::vector<CoreAccountId>& chrome_accounts, + const std::vector<gaia::ListedAccount>& gaia_accounts) const { + // A valid Gaia account should be deleted if it does not have a Chrome + // account. + for (const gaia::ListedAccount& gaia_account : gaia_accounts) { + if (gaia_account.valid && !base::Contains(chrome_accounts, gaia_account.id)) + return true; + } + return false; +} + +bool DiceAccountReconcilorDelegate::IsPreserveModePossible( + const std::vector<CoreAccountId>& chrome_accounts, const std::vector<gaia::ListedAccount>& gaia_accounts, + CoreAccountId first_account) const { + if (ShouldDeleteAccountsFromGaia(chrome_accounts, gaia_accounts)) { + // Preserve mode cannot remove accounts. + return false; + } + // Check if the required first account is equal to the first account in + // cookies as the preserve mode doesn't reorder cookies. + return first_account.empty() || gaia_accounts.empty() || + first_account == gaia_accounts[0].id; +} + +bool DiceAccountReconcilorDelegate::ShouldRevokeTokensBeforeMultilogin( + const std::vector<CoreAccountId>& chrome_accounts, const CoreAccountId& primary_account, + const std::vector<gaia::ListedAccount>& gaia_accounts, bool first_execution, bool primary_has_error) const { - const bool sync_enabled = !primary_account.empty(); - const bool first_gaia_is_primary = - !gaia_accounts.empty() && (gaia_accounts[0].id == primary_account); - return sync_enabled && first_execution && !primary_has_error && - !first_gaia_is_primary - ? gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER - : gaia::MultiloginMode::MULTILOGIN_PRESERVE_COOKIE_ACCOUNTS_ORDER; + // If Gaia accounts are empty, any combination of accounts can be set and + // logout is not needed. + if (gaia_accounts.empty()) + return false; + + // On first execution, it's generally OK to reorder accounts. Only logout if + // the Sync account needs to be removed from the first position in cookies (it + // would be unacceptable to swap another account there). + if (first_execution) { + return !primary_account.empty() && primary_has_error && + gaia_accounts[0].id == primary_account && gaia_accounts[0].valid; + } + // If there is a valid Sync account, then it's ok to reorder the accounts + // even though Chrome is running (the accounts would be reordered on the next + // startup, and this avoids a logout). + if (!primary_account.empty() && !primary_has_error) { + return false; + } + // If the first gaia account doesn't have token then logout. Exception: If the + // first gaia account is invalid, but it can be left in its place (this is + // possible only if there is no need to delete gaia accounts). Other accounts + // will be added after. + return !base::Contains(chrome_accounts, gaia_accounts[0].id) && + ShouldDeleteAccountsFromGaia(chrome_accounts, gaia_accounts); +} + +CoreAccountId DiceAccountReconcilorDelegate::GetFirstGaiaAccountForMultilogin( + const std::vector<CoreAccountId>& chrome_accounts, + const CoreAccountId& primary_account, + const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error) const { + bool valid_sync_account = !primary_account.empty() && !primary_has_error; + // On first execution if there is a valid sync account, then primary + // account should be set to the first position. + if (first_execution && valid_sync_account) { + return primary_account; + } + // In case accounts in cookies are accidentally lost we + // should try to put cached first account first since Gaia has no information + // about it. + if (gaia_accounts.empty() && !last_known_first_account_.empty() && + base::Contains(chrome_accounts, last_known_first_account_)) { + // last_known_account_ is always empty on first execution. + DCHECK(!first_execution); + return last_known_first_account_; + } + // If there are no cookies and a valid sync account, then we can + // set primary account to first position without reordering. + if (gaia_accounts.empty() && valid_sync_account) { + return primary_account; + } + // Empty account means that there is no special requirements for + // the first account. The first account will be selected in such a way as + // to minimize account re-numbering. ReorderChromeAccountsForReconcile + // function implements this logic. + return CoreAccountId(); } std::vector<CoreAccountId> @@ -193,20 +270,29 @@ const std::vector<CoreAccountId>& chrome_accounts, const CoreAccountId& primary_account, const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error, const gaia::MultiloginMode mode) const { - if (mode == gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER) { - return ReorderChromeAccountsForReconcile(chrome_accounts, primary_account, - gaia_accounts); - } - if (gaia_accounts.empty() && - base::Contains(chrome_accounts, last_known_first_account_)) { - // In PRESERVE mode in case accounts in cookies are accidentally lost we - // should put cached first account first since Gaia has no information about - // it. - return ReorderChromeAccountsForReconcile( - chrome_accounts, last_known_first_account_, gaia_accounts); - } - return chrome_accounts; + CoreAccountId first_account = GetFirstGaiaAccountForMultilogin( + chrome_accounts, primary_account, gaia_accounts, first_execution, + primary_has_error); + return ReorderChromeAccountsForReconcile(chrome_accounts, first_account, + gaia_accounts); +} + +// Minimize the use of Update, prefer using Preserve instead when possible. +gaia::MultiloginMode DiceAccountReconcilorDelegate::CalculateModeForReconcile( + const std::vector<CoreAccountId>& chrome_accounts, + const std::vector<gaia::ListedAccount>& gaia_accounts, + const CoreAccountId& primary_account, + bool first_execution, + bool primary_has_error) const { + CoreAccountId first_account = GetFirstGaiaAccountForMultilogin( + chrome_accounts, primary_account, gaia_accounts, first_execution, + primary_has_error); + return IsPreserveModePossible(chrome_accounts, gaia_accounts, first_account) + ? gaia::MultiloginMode::MULTILOGIN_PRESERVE_COOKIE_ACCOUNTS_ORDER + : gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER; } AccountReconcilorDelegate::RevokeTokenOption
diff --git a/components/signin/core/browser/dice_account_reconcilor_delegate.h b/components/signin/core/browser/dice_account_reconcilor_delegate.h index fa98b9f3..ad62529 100644 --- a/components/signin/core/browser/dice_account_reconcilor_delegate.h +++ b/components/signin/core/browser/dice_account_reconcilor_delegate.h
@@ -45,6 +45,12 @@ RevokeTokenAction revoke_token_action) override; void OnReconcileFinished(const CoreAccountId& first_account) override; bool ShouldRevokeTokensOnCookieDeleted() override; + bool ShouldRevokeTokensBeforeMultilogin( + const std::vector<CoreAccountId>& chrome_accounts, + const CoreAccountId& primary_account, + const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error) const override; private: // Possible inconsistency reasons between tokens and gaia cookies. @@ -71,18 +77,48 @@ const std::vector<gaia::ListedAccount>& gaia_accounts, bool first_execution) const; + // AccountReconcilorDelegate: std::vector<CoreAccountId> GetChromeAccountsForReconcile( const std::vector<CoreAccountId>& chrome_accounts, const CoreAccountId& primary_account, const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error, const gaia::MultiloginMode mode) const override; - gaia::MultiloginMode CalculateModeForReconcile( + const std::vector<CoreAccountId>& chrome_accounts, const std::vector<gaia::ListedAccount>& gaia_accounts, const CoreAccountId& primary_account, bool first_execution, bool primary_has_error) const override; + // Checks if Preserve mode is possible. Preserve mode fails if there is a + // valid cookie and no matching valid token. If first_account is not empty, + // then this account must be first in the cookie after the Preserve mode is + // performed. + bool IsPreserveModePossible( + const std::vector<CoreAccountId>& chrome_accounts, + const std::vector<gaia::ListedAccount>& gaia_accounts, + CoreAccountId first_account) const; + + // Checks if there are valid cookies that should be deleted. That's happening + // if there is a valid cookie that doesn't have a valid token. + bool ShouldDeleteAccountsFromGaia( + const std::vector<CoreAccountId>& chrome_accounts, + const std::vector<gaia::ListedAccount>& gaia_accounts) const; + + // Returns the first account to add in the Gaia cookie for multilogin. + // If this returns an empty account, it means any account can come first. + // The order for other accounts will be selected outside of this function + // using ReorderChromeAccountsForReconcile function to minimize account + // re-numbering. + CoreAccountId GetFirstGaiaAccountForMultilogin( + const std::vector<CoreAccountId>& chrome_accounts, + const CoreAccountId& primary_account, + const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error) const; + SigninClient* signin_client_; bool migration_completed_;
diff --git a/components/signin/core/browser/mirror_account_reconcilor_delegate.cc b/components/signin/core/browser/mirror_account_reconcilor_delegate.cc index d855b2d5..6178299 100644 --- a/components/signin/core/browser/mirror_account_reconcilor_delegate.cc +++ b/components/signin/core/browser/mirror_account_reconcilor_delegate.cc
@@ -68,6 +68,8 @@ const std::vector<CoreAccountId>& chrome_accounts, const CoreAccountId& primary_account, const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error, const gaia::MultiloginMode mode) const { DCHECK_EQ(mode, gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER);
diff --git a/components/signin/core/browser/mirror_account_reconcilor_delegate.h b/components/signin/core/browser/mirror_account_reconcilor_delegate.h index aa54f81..87db817 100644 --- a/components/signin/core/browser/mirror_account_reconcilor_delegate.h +++ b/components/signin/core/browser/mirror_account_reconcilor_delegate.h
@@ -45,6 +45,8 @@ const std::vector<CoreAccountId>& chrome_accounts, const CoreAccountId& primary_account, const std::vector<gaia::ListedAccount>& gaia_accounts, + bool first_execution, + bool primary_has_error, const gaia::MultiloginMode mode) const override; // IdentityManager::Observer:
diff --git a/components/signin/ios/browser/account_consistency_service.h b/components/signin/ios/browser/account_consistency_service.h index d537800..44faadf 100644 --- a/components/signin/ios/browser/account_consistency_service.h +++ b/components/signin/ios/browser/account_consistency_service.h
@@ -10,7 +10,6 @@ #include <string> #include "base/callback.h" -#include "base/feature_list.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/time/time.h" @@ -33,9 +32,6 @@ class AccountReconcilor; class PrefService; -// Feature flag controlling whether to restore GAIA cookies if they are deleted. -extern const base::Feature kRestoreGAIACookiesIfDeleted; - // Handles actions necessary for keeping the list of Google accounts available // on the web and those available on the iOS device from first-party Google apps // consistent. This includes setting the Account Consistency cookie,
diff --git a/components/signin/ios/browser/account_consistency_service.mm b/components/signin/ios/browser/account_consistency_service.mm index 2e8e005b..225f0f0 100644 --- a/components/signin/ios/browser/account_consistency_service.mm +++ b/components/signin/ios/browser/account_consistency_service.mm
@@ -19,6 +19,7 @@ #include "components/prefs/scoped_user_pref_update.h" #include "components/signin/core/browser/account_reconcilor.h" #include "components/signin/core/browser/signin_header_helper.h" +#include "components/signin/ios/browser/features.h" #include "components/signin/public/base/account_consistency_method.h" #include "components/signin/public/identity_manager/accounts_cookie_mutator.h" #include "google_apis/gaia/gaia_urls.h" @@ -78,9 +79,6 @@ }; } // namespace -const base::Feature kRestoreGAIACookiesIfDeleted{ - "RestoreGAIACookiesIfDeleted", base::FEATURE_DISABLED_BY_DEFAULT}; - AccountConsistencyHandler::AccountConsistencyHandler( web::WebState* web_state, AccountConsistencyService* service, @@ -222,10 +220,11 @@ void AccountConsistencyService::SetGaiaCookiesIfDeleted() { // We currently enforce a time threshold to update the Gaia cookie - // to prevent calling the expensive call to the cookie manager's - // |GetAllCookies|. + // for signed-in users to prevent calling the expensive method + // |GetAllCookies| in the cookie manager. if (base::Time::Now() - last_gaia_cookie_verification_time_ < - kDelayThresholdToUpdateGaiaCookie) { + kDelayThresholdToUpdateGaiaCookie || + !identity_manager_->HasPrimaryAccount()) { return; } network::mojom::CookieManager* cookie_manager = @@ -253,7 +252,7 @@ // ITP restrictions marking Google domains as potential trackers. LogIOSGaiaCookiesPresentOnNavigation(false); - if (!base::FeatureList::IsEnabled(kRestoreGAIACookiesIfDeleted)) { + if (!base::FeatureList::IsEnabled(signin::kRestoreGaiaCookiesIfDeleted)) { return; } // Re-generate cookie to ensure that the user is properly signed in.
diff --git a/components/signin/ios/browser/account_consistency_service_unittest.mm b/components/signin/ios/browser/account_consistency_service_unittest.mm index f69637de..44498608 100644 --- a/components/signin/ios/browser/account_consistency_service_unittest.mm +++ b/components/signin/ios/browser/account_consistency_service_unittest.mm
@@ -577,6 +577,7 @@ } TEST_F(AccountConsistencyServiceTest, SetGaiaCookieUpdateNotUpdateTime) { + SignIn(); SimulateUpdateGaiaCookie(); // Advance clock, but stay within the one-hour Gaia update time. @@ -588,6 +589,7 @@ } TEST_F(AccountConsistencyServiceTest, SetGaiaCookieUpdateAtUpdateTime) { + SignIn(); SimulateUpdateGaiaCookie(); // Advance clock past one-hour Gaia update time. @@ -602,12 +604,14 @@ // |kRestoreGAIACookiesIfDeleted| experiment is disabled. TEST_F(AccountConsistencyServiceTest, GAIACookieStatusLoggedProperly) { base::HistogramTester histogram_tester; - base::test::ScopedFeatureList feature_list; - feature_list.InitAndDisableFeature(kRestoreGAIACookiesIfDeleted); histogram_tester.ExpectTotalCount(kGAIACookiePresentHistogram, 0); SimulateUpdateGaiaCookie(); base::RunLoop().RunUntilIdle(); + histogram_tester.ExpectTotalCount(kGAIACookiePresentHistogram, 0); + SignIn(); + SimulateUpdateGaiaCookie(); + base::RunLoop().RunUntilIdle(); histogram_tester.ExpectTotalCount(kGAIACookiePresentHistogram, 1); }
diff --git a/components/signin/ios/browser/features.cc b/components/signin/ios/browser/features.cc index 9419512..0f56762f 100644 --- a/components/signin/ios/browser/features.cc +++ b/components/signin/ios/browser/features.cc
@@ -13,4 +13,7 @@ return base::FeatureList::IsEnabled(kForceStartupSigninPromo); } +const base::Feature kRestoreGaiaCookiesIfDeleted{ + "RestoreGAIACookiesIfDeleted", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace signin
diff --git a/components/signin/ios/browser/features.h b/components/signin/ios/browser/features.h index 5cdf203..9f93aeb 100644 --- a/components/signin/ios/browser/features.h +++ b/components/signin/ios/browser/features.h
@@ -15,6 +15,9 @@ // Returns true if the startup sign-in promo should be displayed at boot. bool ForceStartupSigninPromo(); +// Feature controlling whether to restore GAIA cookies if they are deleted. +extern const base::Feature kRestoreGaiaCookiesIfDeleted; + } // namespace signin #endif // COMPONENTS_SIGNIN_IOS_BROWSER_FEATURES_H_
diff --git a/components/signin/public/base/multilogin_parameters.cc b/components/signin/public/base/multilogin_parameters.cc index a517b31..ce5878cf 100644 --- a/components/signin/public/base/multilogin_parameters.cc +++ b/components/signin/public/base/multilogin_parameters.cc
@@ -6,6 +6,9 @@ namespace signin { +MultiloginParameters::MultiloginParameters() + : mode(gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER) {} + MultiloginParameters::MultiloginParameters( const gaia::MultiloginMode mode, const std::vector<CoreAccountId>& accounts_to_send)
diff --git a/components/signin/public/base/multilogin_parameters.h b/components/signin/public/base/multilogin_parameters.h index fce25969..efb672e 100644 --- a/components/signin/public/base/multilogin_parameters.h +++ b/components/signin/public/base/multilogin_parameters.h
@@ -14,13 +14,14 @@ namespace signin { struct MultiloginParameters { + // Parameters with UPDATE mode and empty accounts. + MultiloginParameters(); MultiloginParameters(gaia::MultiloginMode mode, const std::vector<CoreAccountId>& accounts_to_send); MultiloginParameters(const MultiloginParameters& other); MultiloginParameters& operator=(const MultiloginParameters& other); ~MultiloginParameters(); - // Needed for testing. bool operator==(const MultiloginParameters& other) const { return mode == other.mode && accounts_to_send == other.accounts_to_send; }
diff --git a/components/sync/trusted_vault/DEPS b/components/sync/trusted_vault/DEPS index c6d4c22..74ac98ea 100644 --- a/components/sync/trusted_vault/DEPS +++ b/components/sync/trusted_vault/DEPS
@@ -3,6 +3,7 @@ "+components/signin/public", "+components/sync/base", "+components/sync/driver", + "+components/sync/engine", "+components/sync/protocol", "+crypto", "+services/network/public",
diff --git a/components/sync/trusted_vault/standalone_trusted_vault_client.cc b/components/sync/trusted_vault/standalone_trusted_vault_client.cc index 6335e869..d0403cbb 100644 --- a/components/sync/trusted_vault/standalone_trusted_vault_client.cc +++ b/components/sync/trusted_vault/standalone_trusted_vault_client.cc
@@ -14,6 +14,7 @@ #include "base/task_runner_util.h" #include "components/signin/public/identity_manager/account_info.h" #include "components/sync/base/bind_to_task_runner.h" +#include "components/sync/engine/sync_engine_switches.h" #include "components/sync/trusted_vault/standalone_trusted_vault_backend.h" #include "components/sync/trusted_vault/trusted_vault_access_token_fetcher_impl.h" #include "components/sync/trusted_vault/trusted_vault_connection_impl.h" @@ -115,12 +116,28 @@ StandaloneTrustedVaultClient::StandaloneTrustedVaultClient( const base::FilePath& file_path, signin::IdentityManager* identity_manager) - : identity_manager_(identity_manager), - file_path_(file_path), - backend_task_runner_( + : backend_task_runner_( base::ThreadPool::CreateSequencedTaskRunner(kBackendTaskTraits)), access_token_fetcher_frontend_(identity_manager) { - DCHECK(identity_manager_); + if (!base::FeatureList::IsEnabled( + switches::kSyncSupportTrustedVaultPassphrase)) { + return; + } + // TODO(crbug.com/1113598): populate URLLoaderFactory into + // TrustedVaultConnectionImpl ctor. + // TODO(crbug.com/1102340): allow setting custom TrustedVaultConnection for + // testing. + backend_ = base::MakeRefCounted<StandaloneTrustedVaultBackend>( + file_path, std::make_unique<TrustedVaultConnectionImpl>( + /*url_loader_factory=*/nullptr, + std::make_unique<TrustedVaultAccessTokenFetcherImpl>( + access_token_fetcher_frontend_.GetWeakPtr()))); + backend_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&StandaloneTrustedVaultBackend::ReadDataFromDisk, + backend_)); + primary_account_observer_ = std::make_unique<PrimaryAccountObserver>( + backend_task_runner_, backend_, identity_manager); } StandaloneTrustedVaultClient::~StandaloneTrustedVaultClient() = default; @@ -134,7 +151,7 @@ void StandaloneTrustedVaultClient::FetchKeys( const CoreAccountInfo& account_info, base::OnceCallback<void(const std::vector<std::vector<uint8_t>>&)> cb) { - TriggerLazyInitializationIfNeeded(); + DCHECK(backend_); backend_task_runner_->PostTask( FROM_HERE, base::BindOnce(&StandaloneTrustedVaultBackend::FetchKeys, backend_, @@ -145,7 +162,7 @@ const std::string& gaia_id, const std::vector<std::vector<uint8_t>>& keys, int last_key_version) { - TriggerLazyInitializationIfNeeded(); + DCHECK(backend_); backend_task_runner_->PostTask( FROM_HERE, base::BindOnce(&StandaloneTrustedVaultBackend::StoreKeys, backend_, gaia_id, keys, last_key_version)); @@ -153,7 +170,7 @@ } void StandaloneTrustedVaultClient::RemoveAllStoredKeys() { - TriggerLazyInitializationIfNeeded(); + DCHECK(backend_); backend_task_runner_->PostTask( FROM_HERE, base::BindOnce(&StandaloneTrustedVaultBackend::RemoveAllStoredKeys, @@ -164,7 +181,7 @@ void StandaloneTrustedVaultClient::MarkKeysAsStale( const CoreAccountInfo& account_info, base::OnceCallback<void(bool)> cb) { - TriggerLazyInitializationIfNeeded(); + DCHECK(backend_); base::PostTaskAndReplyWithResult( backend_task_runner_.get(), FROM_HERE, base::BindOnce(&StandaloneTrustedVaultBackend::MarkKeysAsStale, backend_, @@ -188,6 +205,7 @@ void StandaloneTrustedVaultClient::FetchBackendPrimaryAccountForTesting( base::OnceCallback<void(const base::Optional<CoreAccountInfo>&)> cb) const { + DCHECK(backend_); base::PostTaskAndReplyWithResult( backend_task_runner_.get(), FROM_HERE, base::BindOnce( @@ -196,36 +214,6 @@ std::move(cb)); } -void StandaloneTrustedVaultClient::TriggerLazyInitializationIfNeeded() { - if (backend_) { - return; - } - - // TODO(crbug.com/1113598): populate URLLoaderFactory into - // TrustedVaultConnectionImpl ctor. - // TODO(crbug.com/1102340): allow setting custom TrustedVaultConnection for - // testing. - backend_ = base::MakeRefCounted<StandaloneTrustedVaultBackend>( - file_path_, std::make_unique<TrustedVaultConnectionImpl>( - /*url_loader_factory=*/nullptr, - std::make_unique<TrustedVaultAccessTokenFetcherImpl>( - access_token_fetcher_frontend_.GetWeakPtr()))); - backend_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&StandaloneTrustedVaultBackend::ReadDataFromDisk, - backend_)); - - // |primary_account_observer_| will populate primary account to |backend_| - // whenever it changes and upon construction, if there is a primary account - // already. - primary_account_observer_ = std::make_unique<PrimaryAccountObserver>( - backend_task_runner_, backend_, identity_manager_); -} - -bool StandaloneTrustedVaultClient::IsInitializationTriggeredForTesting() const { - return backend_ != nullptr; -} - void StandaloneTrustedVaultClient::SetRecoverabilityDegradedForTesting() { is_recoverability_degraded_for_testing_ = true; }
diff --git a/components/sync/trusted_vault/standalone_trusted_vault_client.h b/components/sync/trusted_vault/standalone_trusted_vault_client.h index d27a323d..fa9f0141 100644 --- a/components/sync/trusted_vault/standalone_trusted_vault_client.h +++ b/components/sync/trusted_vault/standalone_trusted_vault_client.h
@@ -60,33 +60,25 @@ void FetchBackendPrimaryAccountForTesting( base::OnceCallback<void(const base::Optional<CoreAccountInfo>&)> callback) const; - bool IsInitializationTriggeredForTesting() const; void SetRecoverabilityDegradedForTesting(); private: - void TriggerLazyInitializationIfNeeded(); - - // Never null and must outlive this object. - signin::IdentityManager* identity_manager_; - - const base::FilePath file_path_; const scoped_refptr<base::SequencedTaskRunner> backend_task_runner_; CallbackList observer_list_; - // |backend_| constructed lazily in the UI thread, used in - // |backend_task_runner_| and destroyed (refcounted) on any thread. - scoped_refptr<StandaloneTrustedVaultBackend> backend_; - - // Observes changes of primary account and populates them into |backend_|. - // Created lazily together with |backend_| and holds reference to it and - // |backend_task_runner_|. - std::unique_ptr<signin::IdentityManager::Observer> primary_account_observer_; - // Allows access token fetching for primary account on the ui thread. Passed // as WeakPtr to TrustedVaultAccessTokenFetcherImpl. TrustedVaultAccessTokenFetcherFrontend access_token_fetcher_frontend_; + // |backend_| constructed in the UI thread, used in |backend_task_runner_| + // and destroyed (refcounted) on any thread. + scoped_refptr<StandaloneTrustedVaultBackend> backend_; + + // Observes changes of primary account and populates them into |backend_|. + // Holds references to |backend_| and |backend_task_runner_|. + std::unique_ptr<signin::IdentityManager::Observer> primary_account_observer_; + bool is_recoverability_degraded_for_testing_ = false; };
diff --git a/components/sync/trusted_vault/standalone_trusted_vault_client_unittest.cc b/components/sync/trusted_vault/standalone_trusted_vault_client_unittest.cc index 50cd48c..7186581 100644 --- a/components/sync/trusted_vault/standalone_trusted_vault_client_unittest.cc +++ b/components/sync/trusted_vault/standalone_trusted_vault_client_unittest.cc
@@ -9,11 +9,13 @@ #include "base/files/scoped_temp_dir.h" #include "base/run_loop.h" #include "base/test/bind_test_util.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "components/os_crypt/os_crypt.h" #include "components/os_crypt/os_crypt_mocker.h" #include "components/signin/public/identity_manager/account_info.h" #include "components/signin/public/identity_manager/identity_test_environment.h" +#include "components/sync/engine/sync_engine_switches.h" #include "components/sync/protocol/local_trusted_vault.pb.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -66,7 +68,10 @@ StandaloneTrustedVaultClientTest() : file_path_(CreateUniqueTempDir(&temp_dir_) .Append(base::FilePath(FILE_PATH_LITERAL("some_file")))), - client_(file_path_, identity_env_.identity_manager()) {} + client_(file_path_, identity_env_.identity_manager()) { + override_features_.InitAndEnableFeature( + switches::kSyncSupportTrustedVaultPassphrase); + } ~StandaloneTrustedVaultClientTest() override = default; @@ -97,6 +102,7 @@ return fetched_primary_account; } + base::test::ScopedFeatureList override_features_; base::test::TaskEnvironment task_environment_; base::ScopedTempDir temp_dir_; const base::FilePath file_path_; @@ -105,16 +111,9 @@ StandaloneTrustedVaultClient client_; }; -TEST_F(StandaloneTrustedVaultClientTest, ShouldNotAutoTriggerInitialization) { - EXPECT_FALSE(client_.IsInitializationTriggeredForTesting()); -} - TEST_F(StandaloneTrustedVaultClientTest, ShouldFetchEmptyKeys) { const std::string kGaiaId = "user1"; - - ASSERT_FALSE(client_.IsInitializationTriggeredForTesting()); EXPECT_THAT(FetchKeysAndWait(kGaiaId), IsEmpty()); - EXPECT_TRUE(client_.IsInitializationTriggeredForTesting()); } TEST_F(StandaloneTrustedVaultClientTest, ShouldFetchNonEmptyKeys) { @@ -139,9 +138,12 @@ ASSERT_NE(-1, base::WriteFile(file_path_, encrypted_data.c_str(), encrypted_data.size())); - ASSERT_FALSE(client_.IsInitializationTriggeredForTesting()); - EXPECT_THAT(FetchKeysAndWait(kGaiaId1), ElementsAre(kKey1)); - EXPECT_THAT(FetchKeysAndWait(kGaiaId2), ElementsAre(kKey2, kKey3)); + // Initialize new client to read the data from the file. + StandaloneTrustedVaultClient client(file_path_, + identity_env_.identity_manager()); + EXPECT_THAT(FetchKeysAndWaitForClient(kGaiaId1, &client), ElementsAre(kKey1)); + EXPECT_THAT(FetchKeysAndWaitForClient(kGaiaId2, &client), + ElementsAre(kKey2, kKey3)); } TEST_F(StandaloneTrustedVaultClientTest, ShouldStoreKeys) { @@ -224,16 +226,10 @@ // ChromeOS doesn't support sign-out. #if !defined(OS_CHROMEOS) TEST_F(StandaloneTrustedVaultClientTest, ShouldPopulatePrimaryAccountChanges) { - ASSERT_FALSE(client_.IsInitializationTriggeredForTesting()); - // Set initial primary account before backend initialization. const std::string email1 = "user1@gmail.com"; identity_env_.SetPrimaryAccount(email1); - // Trigger backend initialization. - ASSERT_THAT(FetchKeysAndWait("user1"), IsEmpty()); - ASSERT_TRUE(client_.IsInitializationTriggeredForTesting()); - // Verify that current primary account corresponds to |email1|. base::Optional<CoreAccountInfo> current_primary_account = FetchBackendPrimaryAccountAndWait();
diff --git a/components/variations/BUILD.gn b/components/variations/BUILD.gn index 0baea092..31d4615c 100644 --- a/components/variations/BUILD.gn +++ b/components/variations/BUILD.gn
@@ -4,8 +4,13 @@ import("//build/buildflag_header.gni") import("//build/config/chromecast_build.gni") +import("//mojo/public/tools/bindings/mojom.gni") import("//testing/test.gni") +mojom("variations_mojom") { + sources = [ "variations.mojom" ] +} + if (is_android) { import("//build/config/android/rules.gni") } @@ -103,6 +108,7 @@ deps = [ ":buildflags", + ":variations_mojom", "proto", "//base", "//components/crash/core/common:crash_key", @@ -145,7 +151,10 @@ "variations_params_manager.h", ] - public_deps = [ ":variations" ] + public_deps = [ + ":variations", + ":variations_mojom", + ] deps = [ "field_trial_config:field_trial_config", @@ -183,6 +192,7 @@ deps = [ ":variations", + ":variations_mojom", "net", "proto", "//base/test:test_support",
diff --git a/components/variations/OWNERS b/components/variations/OWNERS index 0b08a582..7a5eb7b 100644 --- a/components/variations/OWNERS +++ b/components/variations/OWNERS
@@ -1,4 +1,7 @@ file://base/metrics/OWNERS +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS + # COMPONENT: Internals>Metrics>Variations # TEAM: chromium-dev@chromium.org
diff --git a/components/variations/net/BUILD.gn b/components/variations/net/BUILD.gn index a85ff53..e872d22 100644 --- a/components/variations/net/BUILD.gn +++ b/components/variations/net/BUILD.gn
@@ -23,6 +23,7 @@ "//base", "//components/google/core/common", "//components/metrics", + "//components/variations:variations_mojom", "//components/variations/field_trial_config", "//components/variations/proto", ] @@ -33,7 +34,10 @@ "variations_url_loader_throttle.cc", "variations_url_loader_throttle.h", ] - deps += [ "//third_party/blink/public/common" ] + deps += [ + "//components/variations:variations_mojom", + "//third_party/blink/public/common", + ] } }
diff --git a/components/variations/net/variations_http_headers.cc b/components/variations/net/variations_http_headers.cc index d80c6ea..e71505f9 100644 --- a/components/variations/net/variations_http_headers.cc +++ b/components/variations/net/variations_http_headers.cc
@@ -5,7 +5,6 @@ #include "components/variations/net/variations_http_headers.h" #include <utility> -#include <vector> #include "base/bind.h" #include "base/feature_list.h" @@ -16,7 +15,7 @@ #include "base/strings/string_util.h" #include "components/google/core/common/google_util.h" #include "components/variations/net/omnibox_http_headers.h" -#include "components/variations/proto/study.pb.h" +#include "components/variations/variations_features.h" #include "components/variations/variations_ids_provider.h" #include "net/base/isolation_info.h" #include "net/traffic_annotation/network_traffic_annotation.h" @@ -111,11 +110,11 @@ // Returns true if the request is sent from a Google web property, i.e. from a // first-party context. // -// The context is determined using |resource_request| and |owner|. The latter is +// The context is determined using |owner| and |resource_request|. |owner| is // used for subframe-initiated subresource requests from the renderer. Note that // for these kinds of requests, ResourceRequest::TrustedParams is not populated. -bool IsFirstPartyContext(const network::ResourceRequest& resource_request, - Owner owner) { +bool IsFirstPartyContext(Owner owner, + const network::ResourceRequest& resource_request) { if (!resource_request.request_initiator) { // The absence of |request_initiator| means that the request was initiated // by the browser, e.g. a request from the browser to Autofill upon form @@ -189,23 +188,54 @@ return false; } +// Returns GoogleWebVisibility::FIRST_PARTY if kRestrictGoogleWebVisibility is +// enabled and the request is from a first-party context; otherwise, returns +// GoogleWebVisibility::ANY. +variations::mojom::GoogleWebVisibility GetVisibilityKey( + Owner owner, + const network::ResourceRequest& resource_request) { + bool use_first_party_visibility = + IsFirstPartyContext(owner, resource_request) && + base::FeatureList::IsEnabled(internal::kRestrictGoogleWebVisibility); + + return use_first_party_visibility + ? variations::mojom::GoogleWebVisibility::FIRST_PARTY + : variations::mojom::GoogleWebVisibility::ANY; +} + +// Returns a variations header from |variations_headers|. When +// kRestrictGoogleWebVisibility is enabled, the request context is considered +// and may be used to select a header with a more limited set of IDs. +std::string SelectVariationsHeader( + variations::mojom::VariationsHeadersPtr variations_headers, + Owner owner, + const network::ResourceRequest& resource_request) { + return variations_headers->headers_map.at( + GetVisibilityKey(owner, resource_request)); +} + class VariationsHeaderHelper { public: - // Note: It's OK to pass SignedIn::kNo if it's unknown, as it does not affect - // transmission of experiments coming from the variations server. - VariationsHeaderHelper(network::ResourceRequest* request, - SignedIn signed_in = SignedIn::kNo) - : VariationsHeaderHelper(request, CreateVariationsHeader(signed_in)) {} - VariationsHeaderHelper(network::ResourceRequest* resource_request, - std::string variations_header) + // Constructor for browser-initiated requests. + // + // If the signed-in status is unknown, SignedIn::kNo can be passed as it does + // not affect transmission of experiments from the variations server. + VariationsHeaderHelper(SignedIn signed_in, + network::ResourceRequest* resource_request) + : VariationsHeaderHelper(CreateVariationsHeader(signed_in, + Owner::kUnknown, + *resource_request), + resource_request) {} + + // Constructor for when the appropriate header has been determined. + VariationsHeaderHelper(std::string variations_header, + network::ResourceRequest* resource_request) : resource_request_(resource_request) { DCHECK(resource_request_); variations_header_ = std::move(variations_header); } - bool AppendHeaderIfNeeded(const GURL& url, - InIncognito incognito, - Owner owner) { + bool AppendHeaderIfNeeded(const GURL& url, InIncognito incognito) { AppendOmniboxOnDeviceSuggestionsHeaderIfNeeded(url, resource_request_); // Note the criteria for attaching client experiment headers: @@ -221,9 +251,6 @@ !ShouldAppendVariationsHeader(url, "Append")) return false; - // TODO(crbug/1094303): Use the result to determine which IDs to include. - IsFirstPartyContext(*resource_request_, owner); - if (variations_header_.empty()) return false; @@ -235,12 +262,25 @@ } private: - // TODO(crbug/1094303): Update the signature to accept a - // Study_GoogleWebVisibility and pass the given value to - // GetClientDataHeader(). - static std::string CreateVariationsHeader(SignedIn signed_in) { - return VariationsIdsProvider::GetInstance()->GetClientDataHeader( - signed_in == SignedIn::kYes, Study_GoogleWebVisibility_ANY); + // Returns a variations header containing IDs appropriate for |signed_in|. + // When kRestrictGoogleWebVisibility is enabled, the request context is + // considered and may be used to select a header with a more limited set of + // IDs. + // + // Can be used only by code running in the browser process, which is where + // the populated VariationsIdsProvider exists. + static std::string CreateVariationsHeader( + SignedIn signed_in, + Owner owner, + const network::ResourceRequest& resource_request) { + variations::mojom::VariationsHeadersPtr variations_headers = + VariationsIdsProvider::GetInstance()->GetClientDataHeaders( + signed_in == SignedIn::kYes); + + if (variations_headers.is_null()) + return ""; + return variations_headers->headers_map.at( + GetVisibilityKey(owner, resource_request)); } network::ResourceRequest* resource_request_; @@ -258,17 +298,20 @@ // TODO(crbug.com/1094303): Consider passing the Owner if we can get it. // However, we really only care about having the owner for requests initiated // on the renderer side. - return VariationsHeaderHelper(request, signed_in) - .AppendHeaderIfNeeded(url, incognito, Owner::kUnknown); + return VariationsHeaderHelper(signed_in, request) + .AppendHeaderIfNeeded(url, incognito); } -bool AppendVariationsHeaderWithCustomValue(const GURL& url, - InIncognito incognito, - const std::string& variations_header, - Owner owner, - network::ResourceRequest* request) { - return VariationsHeaderHelper(request, variations_header) - .AppendHeaderIfNeeded(url, incognito, owner); +bool AppendVariationsHeaderWithCustomValue( + const GURL& url, + InIncognito incognito, + variations::mojom::VariationsHeadersPtr variations_headers, + Owner owner, + network::ResourceRequest* request) { + const std::string& header = + SelectVariationsHeader(std::move(variations_headers), owner, *request); + return VariationsHeaderHelper(header, request) + .AppendHeaderIfNeeded(url, incognito); } bool AppendVariationsHeaderUnknownSignedIn(const GURL& url, @@ -277,8 +320,8 @@ // TODO(crbug.com/1094303): Consider passing the Owner if we can get it. // However, we really only care about having the owner for requests initiated // on the renderer side. - return VariationsHeaderHelper(request).AppendHeaderIfNeeded(url, incognito, - Owner::kUnknown); + return VariationsHeaderHelper(SignedIn::kNo, request) + .AppendHeaderIfNeeded(url, incognito); } void RemoveVariationsHeaderIfNeeded( @@ -295,11 +338,11 @@ InIncognito incognito, SignedIn signed_in, const net::NetworkTrafficAnnotationTag& annotation_tag) { - bool variation_headers_added = + bool variations_headers_added = AppendVariationsHeader(request->url, incognito, signed_in, request.get()); std::unique_ptr<network::SimpleURLLoader> simple_url_loader = network::SimpleURLLoader::Create(std::move(request), annotation_tag); - if (variation_headers_added) { + if (variations_headers_added) { simple_url_loader->SetOnRedirectCallback( base::BindRepeating(&RemoveVariationsHeaderIfNeeded)); }
diff --git a/components/variations/net/variations_http_headers.h b/components/variations/net/variations_http_headers.h index 7640510..9b526a8e 100644 --- a/components/variations/net/variations_http_headers.h +++ b/components/variations/net/variations_http_headers.h
@@ -6,10 +6,10 @@ #define COMPONENTS_VARIATIONS_NET_VARIATIONS_HTTP_HEADERS_H_ #include <memory> -#include <set> #include <string> #include <vector> +#include "components/variations/variations.mojom.h" #include "services/network/public/mojom/network_context.mojom.h" #include "services/network/public/mojom/url_response_head.mojom-forward.h" @@ -66,16 +66,17 @@ SignedIn signed_in, network::ResourceRequest* request); -// Similar to AppendVariationsHeader, but uses specified |variations_header| as -// the custom header value. It also uses |owner|, which indicates whether +// Similar to AppendVariationsHeader, but takes multiple appropriate headers, +// one of which may be appended. It also uses |owner|, which indicates whether // the request-initiating frame's top frame is a Google-owned web property. // // You should not generally need to use this. -bool AppendVariationsHeaderWithCustomValue(const GURL& url, - InIncognito incognito, - const std::string& variations_header, - Owner owner, - network::ResourceRequest* request); +bool AppendVariationsHeaderWithCustomValue( + const GURL& url, + InIncognito incognito, + variations::mojom::VariationsHeadersPtr variations_headers, + Owner owner, + network::ResourceRequest* request); // Adds Chrome experiment and metrics state as a custom header to |request| // when the signed-in state is not known to the caller; See above for details.
diff --git a/components/variations/net/variations_http_headers_unittest.cc b/components/variations/net/variations_http_headers_unittest.cc index 560e67d..fd3f1d39f4 100644 --- a/components/variations/net/variations_http_headers_unittest.cc +++ b/components/variations/net/variations_http_headers_unittest.cc
@@ -6,10 +6,12 @@ #include <string> +#include "base/containers/flat_map.h" #include "base/macros.h" #include "base/stl_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" +#include "components/variations/variations.mojom.h" #include "net/base/isolation_info.h" #include "net/cookies/site_for_cookies.h" #include "services/network/public/cpp/resource_request.h" @@ -53,8 +55,13 @@ void AppendVariationsHeader(const GURL& destination, Owner owner, network::ResourceRequest* request) { - AppendVariationsHeaderWithCustomValue(destination, InIncognito::kNo, - "Header contents.", owner, request); + base::flat_map<variations::mojom::GoogleWebVisibility, std::string> headers = + {{variations::mojom::GoogleWebVisibility::FIRST_PARTY, "abc123"}, + {variations::mojom::GoogleWebVisibility::ANY, "xyz456"}}; + + AppendVariationsHeaderWithCustomValue( + destination, InIncognito::kNo, + variations::mojom::VariationsHeaders::New(headers), owner, request); } } // namespace @@ -327,9 +334,8 @@ data.isolation_info_frame_origin_url); base::HistogramTester tester; - AppendVariationsHeaderWithCustomValue( - GURL("https://foo.google.com"), variations::InIncognito::kNo, - "Header contents.", + AppendVariationsHeader( + GURL("https://foo.google.com"), data.is_top_level_google_owned ? Owner::kGoogle : Owner::kNotGoogle, &request);
diff --git a/components/variations/net/variations_url_loader_throttle.cc b/components/variations/net/variations_url_loader_throttle.cc index 4a7d25c1a..0d87362 100644 --- a/components/variations/net/variations_url_loader_throttle.cc +++ b/components/variations/net/variations_url_loader_throttle.cc
@@ -29,13 +29,14 @@ } // namespace VariationsURLLoaderThrottle::VariationsURLLoaderThrottle( - const std::string& variation_ids_header) - : variation_ids_header_(variation_ids_header), owner_(Owner::kUnknown) {} + variations::mojom::VariationsHeadersPtr variations_headers) + : variations_headers_(std::move(variations_headers)), + owner_(Owner::kUnknown) {} VariationsURLLoaderThrottle::VariationsURLLoaderThrottle( - const std::string& variation_ids_header, + variations::mojom::VariationsHeadersPtr variations_headers, const url::Origin& top_frame_origin) - : variation_ids_header_(variation_ids_header), + : variations_headers_(std::move(variations_headers)), owner_(GetOwner(top_frame_origin)) {} VariationsURLLoaderThrottle::~VariationsURLLoaderThrottle() = default; @@ -47,10 +48,8 @@ if (!variations_client || variations_client->IsOffTheRecord()) return; - // TODO(crbug/1094303): Consider both variations::Study_GoogleWebVisibility - // values. throttles->push_back(std::make_unique<VariationsURLLoaderThrottle>( - variations_client->GetVariationsHeader())); + variations_client->GetVariationsHeaders())); } void VariationsURLLoaderThrottle::DetachFromCurrentSequence() {} @@ -58,10 +57,17 @@ void VariationsURLLoaderThrottle::WillStartRequest( network::ResourceRequest* request, bool* defer) { - // This throttle is never created when incognito so we pass in - // variations::InIncognito::kNo. + if (variations_headers_.is_null()) + return; + + // InIncognito::kNo is passed because this throttle is never created in + // incognito mode. + // + // |variations_headers_| is moved rather than cloned because a + // VariationsURLLoaderThrottle is created for each request and + // WillStartRequest() is called only once—from ThrottlingURLLoader::Start(). variations::AppendVariationsHeaderWithCustomValue( - request->url, variations::InIncognito::kNo, variation_ids_header_, owner_, + request->url, InIncognito::kNo, std::move(variations_headers_), owner_, request); }
diff --git a/components/variations/net/variations_url_loader_throttle.h b/components/variations/net/variations_url_loader_throttle.h index fdfd5c27..b280e3e 100644 --- a/components/variations/net/variations_url_loader_throttle.h +++ b/components/variations/net/variations_url_loader_throttle.h
@@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "components/variations/variations.mojom.h" #include "third_party/blink/public/common/loader/url_loader_throttle.h" #include "url/origin.h" @@ -32,11 +33,13 @@ // // TODO(crbug.com/1094303): Consider removing this once we've confirmed that // non-render-thread-initiated requests have TrustedParams when needed. - explicit VariationsURLLoaderThrottle(const std::string& variation_ids_header); + explicit VariationsURLLoaderThrottle( + variations::mojom::VariationsHeadersPtr variations_headers); // Constructor for throttles created in the render thread, i.e. via // VariationsRenderThreadObserver. - VariationsURLLoaderThrottle(const std::string& variation_ids_header, - const url::Origin& top_frame_origin); + VariationsURLLoaderThrottle( + variations::mojom::VariationsHeadersPtr variations_headers, + const url::Origin& top_frame_origin); ~VariationsURLLoaderThrottle() override; VariationsURLLoaderThrottle(VariationsURLLoaderThrottle&&) = delete; @@ -66,7 +69,9 @@ net::HttpRequestHeaders* modified_headers, net::HttpRequestHeaders* modified_cors_exempt_headers) override; - const std::string variation_ids_header_; + // Stores multiple appropriate variations headers. See GetClientDataHeaders() + // in variations_ids_provider.h for more details. + variations::mojom::VariationsHeadersPtr variations_headers_; // Denotes whether the top frame of the request-initiating frame is a Google- // owned web property, e.g. YouTube.
diff --git a/components/variations/variations.mojom b/components/variations/variations.mojom new file mode 100644 index 0000000..d80dcc4 --- /dev/null +++ b/components/variations/variations.mojom
@@ -0,0 +1,21 @@ +// Copyright 2020 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. + +module variations.mojom; + +// Corresponds to GoogleWebVisibility in a variations study. See +// components/variations/proto/study.proto for details. +// TODO(crbug.com/1094303): Make the key an int and use the proto's enum to +// index. This will let us reuse the types from the proto so that we don't have +// to maintain two separate definitions that need to stay in sync. +enum GoogleWebVisibility { + ANY = 0, + FIRST_PARTY = 1, +}; + +// Stores multiple header values because the renderer does not know in advance +// which header might be needed for different requests. +struct VariationsHeaders { + map<GoogleWebVisibility, string> headers_map; +}; \ No newline at end of file
diff --git a/components/variations/variations_client.h b/components/variations/variations_client.h index f1f870f..bdfa3bd1 100644 --- a/components/variations/variations_client.h +++ b/components/variations/variations_client.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_VARIATIONS_VARIATIONS_CLIENT_H_ #define COMPONENTS_VARIATIONS_VARIATIONS_CLIENT_H_ +#include "components/variations/variations.mojom.h" + namespace variations { // Used by VariationsURLLoaderThrottle to insulate the content layer from @@ -19,10 +21,11 @@ // directly or we'd end up with a circular dependency. virtual bool IsOffTheRecord() const = 0; - // Returns the variations header that should be appended for google requests. - // TODO(crbug/1094303): Update the signature to take a - // variations::Study_GoogleWebVisibility. - virtual std::string GetVariationsHeader() const = 0; + // Returns the variations headers that may be appended to eligible requests + // to Google web properties. For more details, see GetClientDataHeaders() in + // variations_ids_provider.h. + virtual variations::mojom::VariationsHeadersPtr GetVariationsHeaders() + const = 0; }; } // namespace variations
diff --git a/components/variations/variations_ids_provider.cc b/components/variations/variations_ids_provider.cc index 5516cd91..9752559 100644 --- a/components/variations/variations_ids_provider.cc +++ b/components/variations/variations_ids_provider.cc
@@ -42,22 +42,31 @@ return base::Singleton<VariationsIdsProvider>::get(); } -std::string VariationsIdsProvider::GetClientDataHeader( - bool is_signed_in, - Study_GoogleWebVisibility web_visibility) { +variations::mojom::VariationsHeadersPtr +VariationsIdsProvider::GetClientDataHeaders(bool is_signed_in) { // Lazily initialize the header, if not already done, before attempting to // transmit it. InitVariationIDsCacheIfNeeded(); - std::string variation_ids_header_copy; + std::string first_party_header_copy; + std::string any_context_header_copy; { - auto it = variations_headers_map_.find( - VariationsHeaderKey{is_signed_in, web_visibility}); - if (it == variations_headers_map_.end()) - return ""; - variation_ids_header_copy = it->second; + base::AutoLock lock(lock_); + first_party_header_copy = GetClientDataHeaderWhileLocked( + is_signed_in, Study_GoogleWebVisibility_FIRST_PARTY); + any_context_header_copy = GetClientDataHeaderWhileLocked( + is_signed_in, Study_GoogleWebVisibility_ANY); } - return variation_ids_header_copy; + + if (first_party_header_copy.empty() && any_context_header_copy.empty()) + return nullptr; + + base::flat_map<variations::mojom::GoogleWebVisibility, std::string> headers = + {{variations::mojom::GoogleWebVisibility::FIRST_PARTY, + first_party_header_copy}, + {variations::mojom::GoogleWebVisibility::ANY, any_context_header_copy}}; + + return variations::mojom::VariationsHeaders::New(headers); } std::string VariationsIdsProvider::GetVariationsString( @@ -379,6 +388,20 @@ return AddVariationIdsToSet(variation_ids_from_command_line, target_set); } +std::string VariationsIdsProvider::GetClientDataHeaderWhileLocked( + bool is_signed_in, + Study_GoogleWebVisibility web_visibility) { + lock_.AssertAcquired(); + + auto it = variations_headers_map_.find( + VariationsHeaderKey{is_signed_in, web_visibility}); + + if (it == variations_headers_map_.end()) + return ""; + // Deliberately return a copy. + return it->second; +} + std::set<VariationsIdsProvider::VariationIDEntry> VariationsIdsProvider::GetAllVariationIds() { lock_.AssertAcquired();
diff --git a/components/variations/variations_ids_provider.h b/components/variations/variations_ids_provider.h index e21b749..0dbfc80 100644 --- a/components/variations/variations_ids_provider.h +++ b/components/variations/variations_ids_provider.h
@@ -18,6 +18,7 @@ #include "base/synchronization/lock.h" #include "components/variations/proto/study.pb.h" #include "components/variations/synthetic_trials.h" +#include "components/variations/variations.mojom.h" #include "components/variations/variations_associated_data.h" namespace base { @@ -60,15 +61,16 @@ static VariationsIdsProvider* GetInstance(); - // Returns the value of the X-Client-Data header corresponding to - // |is_signed_in| and |web_visibility|, computing and caching the header if - // necessary. If |is_signed_in| is false, VariationIDs that should be sent for - // only signed in users (i.e. GOOGLE_WEB_PROPERTIES_SIGNED_IN entries) are not - // included. Considering |web_visibility| allows fewer VariationIDs to be sent - // in third-party contexts. See IsFirstPartyContext() in - // variations_http_headers.cc for more details. - std::string GetClientDataHeader(bool is_signed_in, - Study_GoogleWebVisibility web_visibility); + // Returns the X-Client-Data headers corresponding to |is_signed_in|: a header + // that may be sent in first-party requests and a header that may be sent in + // third-party requests. For more details, see IsFirstPartyContext() in + // variations_http_headers.cc. + // + // If |is_signed_in| is false, VariationIDs that should be sent for only + // signed in users (i.e. GOOGLE_WEB_PROPERTIES_SIGNED_IN entries) are not + // included. Also, computes and caches the header if necessary. + variations::mojom::VariationsHeadersPtr GetClientDataHeaders( + bool is_signed_in); // Returns a space-separated string containing the list of current active // variations (as would be reported in the |variation_id| repeated field of @@ -197,6 +199,13 @@ const std::string& command_line_variation_ids, std::set<VariationIDEntry>* target_set); + // Returns the value of the X-Client-Data header corresponding to + // |is_signed_in| and |web_visibility|. Considering |web_visibility| may allow + // fewer VariationIDs to be sent in third-party contexts. + std::string GetClientDataHeaderWhileLocked( + bool is_signed_in, + Study_GoogleWebVisibility web_visibility); + // Returns the currently active set of variation ids, which includes any // default values, synthetic variations and actual field trial variations. std::set<VariationIDEntry> GetAllVariationIds(); @@ -232,7 +241,8 @@ // // The key for each header describes the VariationIDs included in its // associated header. See VariationsHeaderKey's comments for more information. - std::map<VariationsHeaderKey, std::string> variations_headers_map_; + std::map<VariationsHeaderKey, std::string> variations_headers_map_ + GUARDED_BY(lock_); // List of observers to notify on variation ids header update. // NOTE this should really check observers are unregistered but due to
diff --git a/components/variations/variations_ids_provider_unittest.cc b/components/variations/variations_ids_provider_unittest.cc index d559cc8..d92b08d 100644 --- a/components/variations/variations_ids_provider_unittest.cc +++ b/components/variations/variations_ids_provider_unittest.cc
@@ -13,6 +13,7 @@ #include "components/variations/entropy_provider.h" #include "components/variations/proto/client_variations.pb.h" #include "components/variations/proto/study.pb.h" +#include "components/variations/variations.mojom.h" #include "components/variations/variations_associated_data.h" #include "testing/gtest/include/gtest/gtest.h" @@ -76,9 +77,12 @@ EXPECT_EQ(VariationsIdsProvider::ForceIdsResult::SUCCESS, provider.ForceVariationIds({"12", "456", "t789"}, "")); provider.InitVariationIDsCacheIfNeeded(); - std::string variations = provider.GetClientDataHeader( - /*is_signed_in=*/false, Study_GoogleWebVisibility_ANY); - EXPECT_FALSE(variations.empty()); + variations::mojom::VariationsHeadersPtr headers = + provider.GetClientDataHeaders(/*is_signed_in=*/false); + EXPECT_FALSE(headers->headers_map.empty()); + const std::string variations = + headers->headers_map.at(variations::mojom::GoogleWebVisibility::ANY); + std::set<VariationID> variation_ids; std::set<VariationID> trigger_ids; ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids)); @@ -95,9 +99,12 @@ EXPECT_EQ(VariationsIdsProvider::ForceIdsResult::SUCCESS, provider.ForceVariationIds({"12"}, "456,t789")); provider.InitVariationIDsCacheIfNeeded(); - std::string variations = provider.GetClientDataHeader( - /*is_signed_in=*/false, Study_GoogleWebVisibility_ANY); - EXPECT_FALSE(variations.empty()); + variations::mojom::VariationsHeadersPtr headers = + provider.GetClientDataHeaders(/*is_signed_in=*/false); + EXPECT_FALSE(headers->headers_map.empty()); + const std::string variations = + headers->headers_map.at(variations::mojom::GoogleWebVisibility::ANY); + std::set<VariationID> variation_ids; std::set<VariationID> trigger_ids; ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids)); @@ -114,28 +121,19 @@ EXPECT_EQ(VariationsIdsProvider::ForceIdsResult::INVALID_VECTOR_ENTRY, provider.ForceVariationIds({"abcd12", "456"}, "")); provider.InitVariationIDsCacheIfNeeded(); - EXPECT_TRUE(provider - .GetClientDataHeader(/*is_signed_in=*/false, - Study_GoogleWebVisibility_ANY) - .empty()); + EXPECT_TRUE(provider.GetClientDataHeaders(/*is_signed_in=*/false).is_null()); // Invalid trigger experiment id EXPECT_EQ(VariationsIdsProvider::ForceIdsResult::INVALID_VECTOR_ENTRY, provider.ForceVariationIds({"12", "tabc456"}, "")); provider.InitVariationIDsCacheIfNeeded(); - EXPECT_TRUE(provider - .GetClientDataHeader(/*is_signed_in=*/false, - Study_GoogleWebVisibility_ANY) - .empty()); + EXPECT_TRUE(provider.GetClientDataHeaders(/*is_signed_in=*/false).is_null()); // Invalid command-line ids. EXPECT_EQ(VariationsIdsProvider::ForceIdsResult::INVALID_SWITCH_ENTRY, provider.ForceVariationIds({"12", "50"}, "tabc456")); provider.InitVariationIDsCacheIfNeeded(); - EXPECT_TRUE(provider - .GetClientDataHeader(/*is_signed_in=*/false, - Study_GoogleWebVisibility_ANY) - .empty()); + EXPECT_TRUE(provider.GetClientDataHeaders(/*is_signed_in=*/false).is_null()); } TEST_F(VariationsIdsProviderTest, ForceDisableVariationIds_ValidCommandLine) { @@ -146,9 +144,12 @@ provider.ForceVariationIds({"1", "2", "t3", "t4"}, "5,6,t7,t8")); EXPECT_TRUE(provider.ForceDisableVariationIds("2,t4,6,t8")); provider.InitVariationIDsCacheIfNeeded(); - std::string variations = provider.GetClientDataHeader( - /*is_signed_in=*/false, Study_GoogleWebVisibility_ANY); - EXPECT_FALSE(variations.empty()); + variations::mojom::VariationsHeadersPtr headers = + provider.GetClientDataHeaders(/*is_signed_in=*/false); + EXPECT_FALSE(headers->headers_map.empty()); + const std::string variations = + headers->headers_map.at(variations::mojom::GoogleWebVisibility::ANY); + std::set<VariationID> variation_ids; std::set<VariationID> trigger_ids; ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids)); @@ -169,10 +170,7 @@ EXPECT_FALSE(provider.ForceDisableVariationIds("abc")); EXPECT_FALSE(provider.ForceDisableVariationIds("tabc456")); provider.InitVariationIDsCacheIfNeeded(); - EXPECT_TRUE(provider - .GetClientDataHeader(/*is_signed_in=*/false, - Study_GoogleWebVisibility_ANY) - .empty()); + EXPECT_TRUE(provider.GetClientDataHeaders(/*is_signed_in=*/false).is_null()); } TEST_F(VariationsIdsProviderTest, OnFieldTrialGroupFinalized) { @@ -206,8 +204,11 @@ // Get non-signed in ids. { - std::string variations = provider.GetClientDataHeader( - /*is_signed_in=*/false, Study_GoogleWebVisibility_ANY); + variations::mojom::VariationsHeadersPtr headers = + provider.GetClientDataHeaders(/*is_signed_in=*/false); + const std::string variations = + headers->headers_map.at(variations::mojom::GoogleWebVisibility::ANY); + std::set<VariationID> variation_ids; std::set<VariationID> trigger_ids; ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids)); @@ -221,8 +222,11 @@ // Now, get signed-in ids. { - std::string variations = provider.GetClientDataHeader( - /*is_signed_in=*/true, Study_GoogleWebVisibility_ANY); + variations::mojom::VariationsHeadersPtr headers = + provider.GetClientDataHeaders(/*is_signed_in=*/true); + const std::string variations = + headers->headers_map.at(variations::mojom::GoogleWebVisibility::ANY); + std::set<VariationID> variation_ids; std::set<VariationID> trigger_ids; ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids));
diff --git a/components/viz/service/display_embedder/output_presenter_gl.cc b/components/viz/service/display_embedder/output_presenter_gl.cc index 593f5f0..d587bf4 100644 --- a/components/viz/service/display_embedder/output_presenter_gl.cc +++ b/components/viz/service/display_embedder/output_presenter_gl.cc
@@ -134,8 +134,11 @@ gl::GLImage* PresenterImageGL::GetGLImage( std::unique_ptr<gfx::GpuFence>* fence) { - if (scoped_overlay_read_access_) + if (scoped_overlay_read_access_) { + if (fence) + *fence = scoped_overlay_read_access_->TakeFence(); return scoped_overlay_read_access_->gl_image(); + } DCHECK(scoped_gl_read_access_); @@ -314,7 +317,8 @@ std::unique_ptr<gfx::GpuFence> fence; // If the submitted_image() is being scheduled, we don't new a new fence. auto* gl_image = reinterpret_cast<PresenterImageGL*>(image)->GetGLImage( - is_submitted ? nullptr : &fence); + (is_submitted || !gl_surface_->SupportsPlaneGpuFences()) ? nullptr + : &fence); // Output surface is also z-order 0. constexpr int kPlaneZOrder = 0; @@ -356,7 +360,7 @@ gl_surface_->ScheduleOverlayPlane( overlay.plane_z_order, overlay.transform, gl_image, ToNearestRect(overlay.display_rect), overlay.uv_rect, - !overlay.is_opaque, nullptr /* gpu_fence */); + !overlay.is_opaque, accesses[i]->TakeFence()); } #elif defined(OS_APPLE) gl_surface_->ScheduleCALayer(ui::CARendererLayerParams(
diff --git a/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/WebApkValidator.java b/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/WebApkValidator.java index d73e493..ae8dd11 100644 --- a/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/WebApkValidator.java +++ b/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/WebApkValidator.java
@@ -194,15 +194,15 @@ } return false; } - if (isNotWebApkQuick(packageInfo)) { - return false; - } if (sOverrideValidationForTesting) { if (DEBUG) { - Log.d(TAG, "Ok! Looks like a WebApk (has start url) and validation is disabled."); + Log.d(TAG, "WebApk validation is disabled for testing."); } return true; } + if (isNotWebApkQuick(packageInfo)) { + return false; + } if (verifyV1WebApk(packageInfo, webappPackageName)) { return true; }
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 7090c78..f8b30e4 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1281,6 +1281,7 @@ "payments/payment_app_installer.h", "payments/payment_app_provider_impl.cc", "payments/payment_app_provider_impl.h", + "payments/payment_app_provider_util.cc", "payments/payment_instrument_icon_fetcher.cc", "payments/payment_instrument_icon_fetcher.h", "payments/payment_manager.cc",
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 6fba6e66..e3c9f484 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -90,6 +90,9 @@ // If the position is outside the anchor of the base position, then return // the first or last position in the same direction. switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return position->text_offset(); case ax::mojom::MoveDirection::kBackward: return base->CreatePositionAtStartOfAnchor()->text_offset(); case ax::mojom::MoveDirection::kForward: @@ -1328,6 +1331,7 @@ // On Windows and Linux ATK, it is standard text navigation behavior to stop // if we are searching in the backwards direction and the current position is // already at the required text boundary. + DCHECK_NE(direction, ax::mojom::MoveDirection::kNone); if (direction == ax::mojom::MoveDirection::kBackward) boundary_behavior = ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary;
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc index ce8253a..d844523 100644 --- a/content/browser/accessibility/browser_accessibility_com_win.cc +++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -1602,6 +1602,9 @@ DCHECK_LE(start_offset, text_length); switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return start_offset; case ax::mojom::MoveDirection::kBackward: { if (offset_to_text_attributes().empty()) return 0;
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc index 597d9687..9ddf4a33 100644 --- a/content/browser/accessibility/web_contents_accessibility_android.cc +++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -346,6 +346,7 @@ old_rwhva->SetWebContentsAccessibility(nullptr); if (new_rwhva) new_rwhva->SetWebContentsAccessibility(accessibility_.get()); + accessibility_->UpdateBrowserAccessibilityManager(); } WebContentsAccessibilityAndroid::WebContentsAccessibilityAndroid( @@ -355,8 +356,12 @@ : java_ref_(env, obj), web_contents_(static_cast<WebContentsImpl*>(web_contents)), frame_info_initialized_(false), - use_zoom_for_dsf_enabled_(IsUseZoomForDSFEnabled()), - connector_(new Connector(web_contents, this)) { + use_zoom_for_dsf_enabled_(IsUseZoomForDSFEnabled()) { + // We must initialize this after weak_ptr_factory_ because it can result in + // calling UpdateBrowserAccessibilityManager() which accesses + // weak_ptr_factory_. + connector_ = new Connector(web_contents, this); + CollectStats(); } @@ -372,6 +377,12 @@ Java_WebContentsAccessibilityImpl_onNativeObjectDestroyed(env, obj); } +void WebContentsAccessibilityAndroid::UpdateBrowserAccessibilityManager() { + auto* manager = GetRootBrowserAccessibilityManager(); + if (manager) + manager->set_web_contents_accessibility(GetWeakPtr()); +} + void WebContentsAccessibilityAndroid::DeleteEarly(JNIEnv* env) { connector_->DeleteEarly(); }
diff --git a/content/browser/accessibility/web_contents_accessibility_android.h b/content/browser/accessibility/web_contents_accessibility_android.h index 10f36ee..0d3f69cb 100644 --- a/content/browser/accessibility/web_contents_accessibility_android.h +++ b/content/browser/accessibility/web_contents_accessibility_android.h
@@ -39,6 +39,10 @@ WebContents* web_contents); ~WebContentsAccessibilityAndroid() override; + // Notify the root BrowserAccessibilityManager that this is the + // WebContentsAccessibilityAndroid it should talk to. + void UpdateBrowserAccessibilityManager(); + // -------------------------------------------------------------------------- // Methods called from Java via JNI // -------------------------------------------------------------------------- @@ -297,7 +301,7 @@ // receives accessibility events. // Owns itself, and destroyed upon WebContentsObserver::WebContentsDestroyed. class Connector; - Connector* connector_; + Connector* connector_ = nullptr; base::WeakPtrFactory<WebContentsAccessibilityAndroid> weak_ptr_factory_{this};
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 6a54d0c..7e3fd308 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -65,6 +65,8 @@ #include "media/mojo/services/video_decode_perf_history.h" #include "services/device/public/mojom/sensor_provider.mojom.h" #include "services/device/public/mojom/vibration_manager.mojom.h" +#include "services/metrics/public/mojom/ukm_interface.mojom.h" +#include "services/metrics/ukm_recorder_interface.h" #include "services/network/public/cpp/cross_origin_embedder_policy.h" #include "services/network/public/mojom/restricted_cookie_manager.mojom.h" #include "services/shape_detection/public/mojom/barcodedetection_provider.mojom.h" @@ -203,6 +205,12 @@ } #endif +void BindUkmRecorderInterface( + mojo::PendingReceiver<ukm::mojom::UkmRecorderInterface> receiver) { + metrics::UkmRecorderInterface::Create(ukm::UkmRecorder::Get(), + std::move(receiver)); +} + void BindBadgeServiceForServiceWorkerOnUI( int service_worker_process_id, const GURL& service_worker_scope, @@ -846,6 +854,8 @@ base::BindRepeating(&BindFaceDetectionProvider)); map->Add<shape_detection::mojom::TextDetection>( base::BindRepeating(&BindTextDetection)); + map->Add<ukm::mojom::UkmRecorderInterface>( + base::BindRepeating(&BindUkmRecorderInterface)); // worker host binders // base::Unretained(host) is safe because the map is owned by @@ -939,6 +949,8 @@ base::BindRepeating(&BindFaceDetectionProvider)); map->Add<shape_detection::mojom::TextDetection>( base::BindRepeating(&BindTextDetection)); + map->Add<ukm::mojom::UkmRecorderInterface>( + base::BindRepeating(&BindUkmRecorderInterface)); // worker host binders // base::Unretained(host) is safe because the map is owned by @@ -1019,6 +1031,8 @@ base::BindRepeating(&BindFaceDetectionProvider)); map->Add<shape_detection::mojom::TextDetection>( base::BindRepeating(&BindTextDetection)); + map->Add<ukm::mojom::UkmRecorderInterface>( + base::BindRepeating(&BindUkmRecorderInterface)); // worker host binders map->Add<blink::mojom::QuicTransportConnector>(
diff --git a/content/browser/contacts/contacts_manager_impl.cc b/content/browser/contacts/contacts_manager_impl.cc index fd419c1e..6289914 100644 --- a/content/browser/contacts/contacts_manager_impl.cc +++ b/content/browser/contacts/contacts_manager_impl.cc
@@ -12,7 +12,6 @@ #include "build/build_config.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/public/browser/contacts_picker_properties_requested.h" -#include "content/public/browser/web_contents.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "services/metrics/public/cpp/metrics_utils.h" #include "services/metrics/public/cpp/ukm_builders.h" @@ -65,14 +64,8 @@ } ContactsManagerImpl::ContactsManagerImpl(RenderFrameHostImpl* render_frame_host) - : contacts_provider_(CreateProvider(render_frame_host)) { - WebContents* web_contents = - WebContents::FromRenderFrameHost(render_frame_host); - if (!web_contents || !web_contents->GetTopLevelNativeWindow()) - return; - - source_id_ = render_frame_host->GetPageUkmSourceId(); -} + : contacts_provider_(CreateProvider(render_frame_host)), + source_id_(render_frame_host->GetPageUkmSourceId()) {} ContactsManagerImpl::~ContactsManagerImpl() = default;
diff --git a/content/browser/devtools/devtools_agent_host_impl.cc b/content/browser/devtools/devtools_agent_host_impl.cc index 61f2d69..f3d3dbb 100644 --- a/content/browser/devtools/devtools_agent_host_impl.cc +++ b/content/browser/devtools/devtools_agent_host_impl.cc
@@ -101,7 +101,7 @@ } // static -scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForId( +scoped_refptr<DevToolsAgentHostImpl> DevToolsAgentHostImpl::GetForId( const std::string& id) { if (!g_devtools_instances.IsCreated()) return nullptr; @@ -112,6 +112,12 @@ } // static +scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForId( + const std::string& id) { + return DevToolsAgentHostImpl::GetForId(id); +} + +// static scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::Forward( const std::string& id, std::unique_ptr<DevToolsExternalAgentProxyDelegate> delegate) {
diff --git a/content/browser/devtools/devtools_agent_host_impl.h b/content/browser/devtools/devtools_agent_host_impl.h index dfdf9bf7..73176bf4 100644 --- a/content/browser/devtools/devtools_agent_host_impl.h +++ b/content/browser/devtools/devtools_agent_host_impl.h
@@ -28,6 +28,9 @@ // Describes interface for managing devtools agents from the browser process. class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost { public: + // Returns DevToolsAgentHost with a given |id| or nullptr of it doesn't exist. + static scoped_refptr<DevToolsAgentHostImpl> GetForId(const std::string& id); + // DevToolsAgentHost implementation. bool AttachClient(DevToolsAgentHostClient* client) override; bool AttachClientWithoutWakeLock(DevToolsAgentHostClient* client) override;
diff --git a/content/browser/field_trial_synchronizer.cc b/content/browser/field_trial_synchronizer.cc index ee5d1d6..6cc715b 100644 --- a/content/browser/field_trial_synchronizer.cc +++ b/content/browser/field_trial_synchronizer.cc
@@ -116,11 +116,8 @@ mojo::AssociatedRemote<mojom::RendererVariationsConfiguration> renderer_variations_configuration; channel->GetRemoteAssociatedInterface(&renderer_variations_configuration); - - // TODO(crbug/1094303): Consider both variations::Study_GoogleWebVisibility - // values. - renderer_variations_configuration->SetVariationsHeader( - client->GetVariationsHeader()); + renderer_variations_configuration->SetVariationsHeaders( + client->GetVariationsHeaders()); } void FieldTrialSynchronizer::VariationIdsHeaderUpdated() {
diff --git a/content/browser/font_access/font_access_manager_impl.cc b/content/browser/font_access/font_access_manager_impl.cc index c1976a7..e47e74a 100644 --- a/content/browser/font_access/font_access_manager_impl.cc +++ b/content/browser/font_access/font_access_manager_impl.cc
@@ -5,6 +5,7 @@ #include "content/browser/font_access/font_access_manager_impl.h" #include "base/bind.h" +#include "base/memory/read_only_shared_memory_region.h" #include "base/task/post_task.h" #include "content/browser/font_access/font_enumeration_cache.h" #include "content/browser/permissions/permission_controller_impl.h" @@ -43,7 +44,13 @@ #if defined(PLATFORM_HAS_LOCAL_FONT_ENUMERATION_IMPL) const BindingContext& context = receivers_.current_context(); + RenderFrameHostImpl* rfh = RenderFrameHostImpl::FromID(context.frame_id); + if (rfh == nullptr) { + std::move(callback).Run( + blink::mojom::FontEnumerationStatus::kUnexpectedError, + base::ReadOnlySharedMemoryRegion()); + } // Sticky User Activation is required for the API to function at all. if (!rfh->frame_tree_node()->HasStickyUserActivation()) {
diff --git a/content/browser/media/capture/web_contents_video_capture_device.cc b/content/browser/media/capture/web_contents_video_capture_device.cc index 3224837a..0093df22 100644 --- a/content/browser/media/capture/web_contents_video_capture_device.cc +++ b/content/browser/media/capture/web_contents_video_capture_device.cc
@@ -23,6 +23,7 @@ #include "ui/base/layout.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/size.h" +#include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/native_widget_types.h" namespace content { @@ -84,8 +85,9 @@ // that has a different device scale factor while being captured. gfx::Size preferred_size; if (auto* view = GetCurrentView()) { - preferred_size = - gfx::ConvertSizeToDIP(view->GetDeviceScaleFactor(), capture_size); + // TODO(danakj): Should this be rounded? + preferred_size = gfx::ToFlooredSize( + gfx::ConvertSizeToDips(capture_size, view->GetDeviceScaleFactor())); } if (preferred_size.IsEmpty()) { preferred_size = capture_size;
diff --git a/content/browser/network_context_client_base_impl.cc b/content/browser/network_context_client_base_impl.cc index 921b222..7c3239f 100644 --- a/content/browser/network_context_client_base_impl.cc +++ b/content/browser/network_context_client_base_impl.cc
@@ -167,6 +167,4 @@ void NetworkContextClientBase::OnTrustAnchorUsed() {} #endif -void NetworkContextClientBase::OnSCTReportReady(const std::string& cache_key) {} - } // namespace content
diff --git a/content/browser/payments/payment_app_browsertest.cc b/content/browser/payments/payment_app_browsertest.cc index 08e6dae..be77ad0 100644 --- a/content/browser/payments/payment_app_browsertest.cc +++ b/content/browser/payments/payment_app_browsertest.cc
@@ -132,10 +132,11 @@ const std::string& payment_request_id) { base::RunLoop run_loop; bool payment_aborted = false; - PaymentAppProvider::GetInstance()->AbortPayment( - shell()->web_contents(), registration_id, sw_origin, payment_request_id, - base::BindOnce(&CaptureAbortResult, run_loop.QuitClosure(), - &payment_aborted)); + PaymentAppProvider::GetOrCreateForWebContents(shell()->web_contents()) + ->AbortPayment( + registration_id, sw_origin, payment_request_id, + base::BindOnce(&CaptureAbortResult, run_loop.QuitClosure(), + &payment_aborted)); run_loop.Run(); return payment_aborted; @@ -150,11 +151,12 @@ base::RunLoop run_loop; bool can_make_payment = false; - PaymentAppProvider::GetInstance()->CanMakePayment( - shell()->web_contents(), registration_id, sw_origin, payment_request_id, - std::move(event_data), - base::BindOnce(&CaptureCanMakePaymentResult, run_loop.QuitClosure(), - &can_make_payment)); + PaymentAppProvider::GetOrCreateForWebContents(shell()->web_contents()) + ->CanMakePayment( + registration_id, sw_origin, payment_request_id, + std::move(event_data), + base::BindOnce(&CaptureCanMakePaymentResult, run_loop.QuitClosure(), + &can_make_payment)); run_loop.Run(); return can_make_payment; @@ -167,11 +169,12 @@ const std::string& instrument_key) { base::RunLoop run_loop; PaymentHandlerResponsePtr response; - PaymentAppProvider::GetInstance()->InvokePaymentApp( - shell()->web_contents(), registration_id, sw_origin, - CreatePaymentRequestEventData(supported_method, instrument_key), - base::BindOnce(&InvokePaymentAppCallback, run_loop.QuitClosure(), - &response)); + PaymentAppProvider::GetOrCreateForWebContents(shell()->web_contents()) + ->InvokePaymentApp( + registration_id, sw_origin, + CreatePaymentRequestEventData(supported_method, instrument_key), + base::BindOnce(&InvokePaymentAppCallback, run_loop.QuitClosure(), + &response)); run_loop.Run(); return response;
diff --git a/content/browser/payments/payment_app_installer.cc b/content/browser/payments/payment_app_installer.cc index ccb8c03..98eaff51 100644 --- a/content/browser/payments/payment_app_installer.cc +++ b/content/browser/payments/payment_app_installer.cc
@@ -207,10 +207,10 @@ if (callback_.is_null()) return; - if (success && web_contents() != nullptr) { - std::move(callback_).Run(web_contents(), registration_id_); + if (success) { + std::move(callback_).Run(registration_id_); } else { - std::move(callback_).Run(nullptr, -1); + std::move(callback_).Run(-1); } service_worker_context_->RemoveObserver(this);
diff --git a/content/browser/payments/payment_app_installer.h b/content/browser/payments/payment_app_installer.h index 9f6dbd0..30a3910 100644 --- a/content/browser/payments/payment_app_installer.h +++ b/content/browser/payments/payment_app_installer.h
@@ -23,8 +23,7 @@ class PaymentAppInstaller { public: using InstallPaymentAppCallback = - base::OnceCallback<void(WebContents* web_contents, - int64_t registration_id)>; + base::OnceCallback<void(int64_t registration_id)>; // Installs the payment app. // |app_name| is the name of the payment app.
diff --git a/content/browser/payments/payment_app_provider_impl.cc b/content/browser/payments/payment_app_provider_impl.cc index 7b10ed2..f8dae10 100644 --- a/content/browser/payments/payment_app_provider_impl.cc +++ b/content/browser/payments/payment_app_provider_impl.cc
@@ -26,7 +26,6 @@ #include "content/browser/service_worker/service_worker_metrics.h" #include "content/browser/service_worker/service_worker_version.h" #include "content/browser/storage_partition_impl.h" -#include "content/common/service_worker/service_worker_utils.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -54,11 +53,6 @@ using payments::mojom::PaymentHandlerResponseCallback; using payments::mojom::PaymentHandlerResponsePtr; using payments::mojom::PaymentMethodDataPtr; -using payments::mojom::PaymentRequestEventDataPtr; - -using ServiceWorkerStartCallback = - base::OnceCallback<void(scoped_refptr<ServiceWorkerVersion>, - blink::ServiceWorkerStatusCode)>; CanMakePaymentResponsePtr CreateBlankCanMakePaymentResponse( CanMakePaymentEventResponseType response_type) { @@ -128,7 +122,8 @@ // Abstract base class for event callbacks that are invoked when the payment // handler resolves the promise passed in to TheEvent.respondWith() method. -class RespondWithCallback : public PaymentHandlerResponseCallback { +class RespondWithCallback : public PaymentHandlerResponseCallback, + public WebContentsObserver { public: // Disallow copy and assign. RespondWithCallback(const RespondWithCallback& other) = delete; @@ -141,10 +136,10 @@ protected: RespondWithCallback( - BrowserContext* browser_context, + WebContents* web_contents, ServiceWorkerMetrics::EventType event_type, scoped_refptr<ServiceWorkerVersion> service_worker_version) - : browser_context_(browser_context), + : WebContentsObserver(web_contents), service_worker_version_(service_worker_version) { request_id_ = service_worker_version->StartRequest( event_type, base::BindOnce(&RespondWithCallback::OnServiceWorkerError, @@ -180,22 +175,15 @@ void ClearCallbackRepositoryAndCloseWindow() { DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); + if (!web_contents()) + return; InvokePaymentAppCallbackRepository::GetInstance()->RemoveCallback( - browser_context_); - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&CloseClientWindowOnUIThread)); + web_contents()->GetBrowserContext()); } private: - static void CloseClientWindowOnUIThread() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - PaymentAppProvider::GetInstance()->CloseOpenedWindow(); - } - int request_id_; - BrowserContext* browser_context_; scoped_refptr<ServiceWorkerVersion> service_worker_version_; mojo::Receiver<PaymentHandlerResponseCallback> receiver_{this}; @@ -208,10 +196,10 @@ class CanMakePaymentRespondWithCallback : public RespondWithCallback { public: CanMakePaymentRespondWithCallback( - BrowserContext* browser_context, + WebContents* web_contents, scoped_refptr<ServiceWorkerVersion> service_worker_version, PaymentAppProvider::CanMakePaymentCallback callback) - : RespondWithCallback(browser_context, + : RespondWithCallback(web_contents, ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT, service_worker_version), callback_(std::move(callback)) {} @@ -269,15 +257,15 @@ class InvokeRespondWithCallback : public RespondWithCallback { public: InvokeRespondWithCallback( - BrowserContext* browser_context, + WebContents* web_contents, scoped_refptr<ServiceWorkerVersion> service_worker_version, PaymentAppProvider::InvokePaymentAppCallback callback) - : RespondWithCallback(browser_context, + : RespondWithCallback(web_contents, ServiceWorkerMetrics::EventType::PAYMENT_REQUEST, service_worker_version), callback_(std::move(callback)) { InvokePaymentAppCallbackRepository::GetInstance()->SetCallback( - browser_context, this); + web_contents->GetBrowserContext(), this); } // Disallow copy and assign. @@ -304,7 +292,6 @@ RunOrPostTaskOnThread( FROM_HERE, BrowserThread::UI, base::BindOnce(std::move(callback_), std::move(response))); - ClearCallbackRepositoryAndCloseWindow(); delete this; } @@ -348,10 +335,10 @@ class AbortRespondWithCallback : public RespondWithCallback { public: AbortRespondWithCallback( - BrowserContext* browser_context, + WebContents* web_contents, scoped_refptr<ServiceWorkerVersion> service_worker_version, PaymentAppProvider::AbortCallback callback) - : RespondWithCallback(browser_context, + : RespondWithCallback(web_contents, ServiceWorkerMetrics::EventType::ABORT_PAYMENT, service_worker_version), callback_(std::move(callback)) {} @@ -423,7 +410,7 @@ } void DispatchAbortPaymentEvent( - BrowserContext* browser_context, + WebContents* web_contents, PaymentAppProvider::AbortCallback callback, scoped_refptr<ServiceWorkerVersion> active_version, blink::ServiceWorkerStatusCode service_worker_status) { @@ -443,7 +430,7 @@ // This object self-deletes after either success or error callback is // invoked. RespondWithCallback* respond_with_callback = new AbortRespondWithCallback( - browser_context, active_version, std::move(callback)); + web_contents, active_version, std::move(callback)); active_version->endpoint()->DispatchAbortPaymentEvent( respond_with_callback->BindNewPipeAndPassRemote(), @@ -451,7 +438,7 @@ } void DispatchCanMakePaymentEvent( - BrowserContext* browser_context, + WebContents* web_contents, CanMakePaymentEventDataPtr event_data, PaymentAppProvider::CanMakePaymentCallback callback, scoped_refptr<ServiceWorkerVersion> active_version, @@ -475,7 +462,7 @@ // This object self-deletes after either success or error callback is // invoked. RespondWithCallback* respond_with_callback = - new CanMakePaymentRespondWithCallback(browser_context, active_version, + new CanMakePaymentRespondWithCallback(web_contents, active_version, std::move(callback)); active_version->endpoint()->DispatchCanMakePaymentEvent( @@ -484,7 +471,7 @@ } void DispatchPaymentRequestEvent( - BrowserContext* browser_context, + WebContents* web_contents, PaymentRequestEventDataPtr event_data, PaymentAppProvider::InvokePaymentAppCallback callback, scoped_refptr<ServiceWorkerVersion> active_version, @@ -509,7 +496,7 @@ // This object self-deletes after either success or error callback is // invoked. RespondWithCallback* respond_with_callback = new InvokeRespondWithCallback( - browser_context, active_version, std::move(callback)); + web_contents, active_version, std::move(callback)); active_version->endpoint()->DispatchPaymentRequestEvent( std::move(event_data), respond_with_callback->BindNewPipeAndPassRemote(), @@ -547,51 +534,15 @@ base::BindOnce(&DidFindRegistrationOnCoreThread, std::move(callback))); } -void StartServiceWorkerForDispatch(BrowserContext* browser_context, - int64_t registration_id, - ServiceWorkerStartCallback callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( - BrowserContext::GetDefaultStoragePartition(browser_context)); - scoped_refptr<ServiceWorkerContextWrapper> service_worker_context = - partition->GetServiceWorkerContext(); - - RunOrPostTaskOnThread(FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), - base::BindOnce(&FindRegistrationOnCoreThread, - std::move(service_worker_context), - registration_id, std::move(callback))); -} - -void OnInstallPaymentApp( - const url::Origin& sw_origin, - PaymentRequestEventDataPtr event_data, - PaymentAppProvider::RegistrationIdCallback registration_id_callback, - PaymentAppProvider::InvokePaymentAppCallback callback, - WebContents* web_contents, - int64_t registration_id) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - if (registration_id >= 0 && web_contents != nullptr) { - std::move(registration_id_callback).Run(registration_id); - PaymentAppProvider::GetInstance()->InvokePaymentApp( - web_contents, registration_id, sw_origin, std::move(event_data), - std::move(callback)); - } else { - std::move(callback).Run(CreateBlankPaymentHandlerResponse( - PaymentEventResponseType::PAYMENT_EVENT_BROWSER_ERROR)); - } -} - -void AbortInvokePaymentApp(BrowserContext* browser_context, +void AbortInvokePaymentApp(WebContents* web_contents, PaymentEventResponseType reason) { DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); - if (!browser_context) + if (!web_contents) return; InvokeRespondWithCallback* callback = InvokePaymentAppCallbackRepository::GetInstance()->GetCallback( - browser_context); + web_contents->GetBrowserContext()); if (callback) callback->AbortPaymentSinceOpennedWindowClosing(reason); } @@ -624,25 +575,6 @@ } } -scoped_refptr<DevToolsBackgroundServicesContextImpl> GetDevTools( - BrowserContext* browser_context, - const url::Origin& sw_origin) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(browser_context); - auto* storage_partition = BrowserContext::GetStoragePartitionForSite( - browser_context, sw_origin.GetURL(), /*can_create=*/true); - if (!storage_partition) - return nullptr; - - scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools = - static_cast<DevToolsBackgroundServicesContextImpl*>( - storage_partition->GetDevToolsBackgroundServicesContext()); - return dev_tools && dev_tools->IsRecording( - DevToolsBackgroundService::kPaymentHandler) - ? dev_tools - : nullptr; -} - void OnResponseForCanMakePaymentOnUiThread( scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools, int64_t registration_id, @@ -724,28 +656,32 @@ } // namespace // static -PaymentAppProvider* PaymentAppProvider::GetInstance() { - return PaymentAppProviderImpl::GetInstance(); +PaymentAppProvider* PaymentAppProvider::GetOrCreateForWebContents( + WebContents* web_contents) { + return PaymentAppProviderImpl::GetOrCreateForWebContents(web_contents); } // static -PaymentAppProviderImpl* PaymentAppProviderImpl::GetInstance() { +PaymentAppProviderImpl* PaymentAppProviderImpl::GetOrCreateForWebContents( + WebContents* web_contents) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - return base::Singleton<PaymentAppProviderImpl>::get(); + auto* data = PaymentAppProviderImpl::FromWebContents(web_contents); + if (!data) + PaymentAppProviderImpl::CreateForWebContents(web_contents); + + return PaymentAppProviderImpl::FromWebContents(web_contents); } void PaymentAppProviderImpl::InvokePaymentApp( - WebContents* web_contents, int64_t registration_id, const url::Origin& sw_origin, PaymentRequestEventDataPtr event_data, InvokePaymentAppCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!web_contents) - return; + DCHECK(web_contents_); scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools = - GetDevTools(web_contents->GetBrowserContext(), sw_origin); + GetDevTools(sw_origin); if (dev_tools) { std::map<std::string, std::string> data = { {"Merchant Top Origin", event_data->top_origin.spec()}, @@ -764,17 +700,15 @@ } StartServiceWorkerForDispatch( - web_contents->GetBrowserContext(), registration_id, + registration_id, base::BindOnce( - &DispatchPaymentRequestEvent, web_contents->GetBrowserContext(), - std::move(event_data), + &DispatchPaymentRequestEvent, web_contents_, std::move(event_data), base::BindOnce(&OnResponseForPaymentRequestOnUiThread, dev_tools, registration_id, sw_origin, event_data->payment_request_id, std::move(callback)))); } void PaymentAppProviderImpl::InstallAndInvokePaymentApp( - WebContents* web_contents, PaymentRequestEventDataPtr event_data, const std::string& app_name, const SkBitmap& app_icon, @@ -786,8 +720,7 @@ RegistrationIdCallback registration_id_callback, InvokePaymentAppCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!web_contents) - return; + DCHECK(web_contents_); if (!sw_js_url.is_valid() || !sw_scope.is_valid() || method.empty()) { GetUIThreadTaskRunner({})->PostTask( @@ -810,15 +743,15 @@ } PaymentAppInstaller::Install( - web_contents, app_name, string_encoded_icon, sw_js_url, sw_scope, + web_contents_, app_name, string_encoded_icon, sw_js_url, sw_scope, sw_use_cache, method, supported_delegations, - base::BindOnce(&OnInstallPaymentApp, url::Origin::Create(sw_scope), - std::move(event_data), std::move(registration_id_callback), - std::move(callback))); + base::BindOnce(&PaymentAppProviderImpl::OnInstallPaymentApp, + weak_ptr_factory_.GetWeakPtr(), + url::Origin::Create(sw_scope), std::move(event_data), + std::move(registration_id_callback), std::move(callback))); } void PaymentAppProviderImpl::UpdatePaymentAppIcon( - BrowserContext* browser_context, int64_t registration_id, const std::string& instrument_key, const std::string& name, @@ -827,7 +760,8 @@ const SupportedDelegations& supported_delegations, PaymentAppProvider::UpdatePaymentAppIconCallback callback) { StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( - BrowserContext::GetDefaultStoragePartition(browser_context)); + BrowserContext::GetDefaultStoragePartition( + web_contents_->GetBrowserContext())); scoped_refptr<PaymentAppContextImpl> payment_app_context = partition->GetPaymentAppContext(); @@ -839,18 +773,16 @@ } void PaymentAppProviderImpl::CanMakePayment( - WebContents* web_contents, int64_t registration_id, const url::Origin& sw_origin, const std::string& payment_request_id, CanMakePaymentEventDataPtr event_data, CanMakePaymentCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!web_contents) - return; + DCHECK(web_contents_); scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools = - GetDevTools(web_contents->GetBrowserContext(), sw_origin); + GetDevTools(sw_origin); if (dev_tools) { std::map<std::string, std::string> data = { {"Merchant Top Origin", event_data->top_origin.spec()}, @@ -869,25 +801,23 @@ } StartServiceWorkerForDispatch( - web_contents->GetBrowserContext(), registration_id, - base::BindOnce(&DispatchCanMakePaymentEvent, - web_contents->GetBrowserContext(), std::move(event_data), + registration_id, + base::BindOnce(&DispatchCanMakePaymentEvent, web_contents_, + std::move(event_data), base::BindOnce(&OnResponseForCanMakePaymentOnUiThread, dev_tools, registration_id, sw_origin, payment_request_id, std::move(callback)))); } -void PaymentAppProviderImpl::AbortPayment(WebContents* web_contents, - int64_t registration_id, +void PaymentAppProviderImpl::AbortPayment(int64_t registration_id, const url::Origin& sw_origin, const std::string& payment_request_id, AbortCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!web_contents) - return; + DCHECK(web_contents_); scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools = - GetDevTools(web_contents->GetBrowserContext(), sw_origin); + GetDevTools(sw_origin); if (dev_tools) { dev_tools->LogBackgroundServiceEvent( registration_id, sw_origin, DevToolsBackgroundService::kPaymentHandler, @@ -896,24 +826,22 @@ } StartServiceWorkerForDispatch( - web_contents->GetBrowserContext(), registration_id, - base::BindOnce(&DispatchAbortPaymentEvent, - web_contents->GetBrowserContext(), + registration_id, + base::BindOnce(&DispatchAbortPaymentEvent, web_contents_, base::BindOnce(&OnResponseForAbortPaymentOnUiThread, dev_tools, registration_id, sw_origin, payment_request_id, std::move(callback)))); } -void PaymentAppProviderImpl::SetOpenedWindow(WebContents* web_contents) { +void PaymentAppProviderImpl::SetOpenedWindow() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!web_contents) - return; + DCHECK(web_contents_); CloseOpenedWindow(); DCHECK(!payment_handler_window_); payment_handler_window_ = - std::make_unique<PaymentHandlerWindowObserver>(web_contents); + std::make_unique<PaymentHandlerWindowObserver>(web_contents_); } void PaymentAppProviderImpl::CloseOpenedWindow() { @@ -930,56 +858,72 @@ } void PaymentAppProviderImpl::OnClosingOpenedWindow( - WebContents* web_contents, PaymentEventResponseType reason) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!web_contents) - return; + DCHECK(web_contents_); RunOrPostTaskOnThread( FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), - base::BindOnce(&AbortInvokePaymentApp, web_contents->GetBrowserContext(), - reason)); + base::BindOnce(&AbortInvokePaymentApp, web_contents_, reason)); } -bool PaymentAppProviderImpl::IsValidInstallablePaymentApp( - const GURL& manifest_url, - const GURL& sw_js_url, - const GURL& sw_scope, - std::string* error_message) { - DCHECK(manifest_url.is_valid() && sw_js_url.is_valid() && - sw_scope.is_valid()); +scoped_refptr<DevToolsBackgroundServicesContextImpl> +PaymentAppProviderImpl::GetDevTools(const url::Origin& sw_origin) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(web_contents_); + auto* storage_partition = BrowserContext::GetStoragePartitionForSite( + web_contents_->GetBrowserContext(), sw_origin.GetURL(), + /*can_create=*/true); + if (!storage_partition) + return nullptr; - // Scope will be checked against service worker js url when registering, but - // we check it here earlier to avoid presenting unusable payment handlers. - if (!ServiceWorkerUtils::IsPathRestrictionSatisfiedWithoutHeader( - sw_scope, sw_js_url, error_message)) { - return false; + scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools = + static_cast<DevToolsBackgroundServicesContextImpl*>( + storage_partition->GetDevToolsBackgroundServicesContext()); + return dev_tools && dev_tools->IsRecording( + DevToolsBackgroundService::kPaymentHandler) + ? dev_tools + : nullptr; +} + +void PaymentAppProviderImpl::StartServiceWorkerForDispatch( + int64_t registration_id, + ServiceWorkerStartCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( + BrowserContext::GetDefaultStoragePartition( + web_contents_->GetBrowserContext())); + scoped_refptr<ServiceWorkerContextWrapper> service_worker_context = + partition->GetServiceWorkerContext(); + + RunOrPostTaskOnThread(FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), + base::BindOnce(&FindRegistrationOnCoreThread, + std::move(service_worker_context), + registration_id, std::move(callback))); +} + +void PaymentAppProviderImpl::OnInstallPaymentApp( + const url::Origin& sw_origin, + PaymentRequestEventDataPtr event_data, + RegistrationIdCallback registration_id_callback, + InvokePaymentAppCallback callback, + int64_t registration_id) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(web_contents_); + + if (registration_id >= 0) { + std::move(registration_id_callback).Run(registration_id); + InvokePaymentApp(registration_id, sw_origin, std::move(event_data), + std::move(callback)); + } else { + std::move(callback).Run(CreateBlankPaymentHandlerResponse( + PaymentEventResponseType::PAYMENT_EVENT_BROWSER_ERROR)); } - - // TODO(crbug.com/855312): Unify duplicated code between here and - // ServiceWorkerProviderHost::IsValidRegisterMessage. - std::vector<GURL> urls = {manifest_url, sw_js_url, sw_scope}; - if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) { - *error_message = - "Origins are not matching, or some origins cannot access service " - "worker " - "(manifest:" + - manifest_url.spec() + " scope:" + sw_scope.spec() + - " sw:" + sw_js_url.spec() + ")"; - return false; - } - - return true; } -ukm::SourceId PaymentAppProviderImpl::GetSourceIdForPaymentAppFromScope( - const GURL& sw_scope) { - return ukm::UkmRecorder::GetSourceIdForPaymentAppFromScope( - sw_scope.GetOrigin()); -} - -PaymentAppProviderImpl::PaymentAppProviderImpl() = default; +PaymentAppProviderImpl::PaymentAppProviderImpl(WebContents* web_contents) + : web_contents_(web_contents) {} PaymentAppProviderImpl::~PaymentAppProviderImpl() = default; @@ -989,4 +933,5 @@ PaymentAppProviderImpl::PaymentHandlerWindowObserver:: ~PaymentHandlerWindowObserver() = default; +WEB_CONTENTS_USER_DATA_KEY_IMPL(PaymentAppProviderImpl) } // namespace content
diff --git a/content/browser/payments/payment_app_provider_impl.h b/content/browser/payments/payment_app_provider_impl.h index 8cc0491..3939fa3 100644 --- a/content/browser/payments/payment_app_provider_impl.h +++ b/content/browser/payments/payment_app_provider_impl.h
@@ -5,16 +5,27 @@ #ifndef CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_PROVIDER_IMPL_H_ #define CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_PROVIDER_IMPL_H_ -#include "base/memory/singleton.h" +#include "content/browser/devtools/devtools_background_services_context_impl.h" +#include "content/browser/payments/payment_app_context_impl.h" #include "content/common/content_export.h" #include "content/public/browser/payment_app_provider.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" namespace content { -class CONTENT_EXPORT PaymentAppProviderImpl : public PaymentAppProvider { +using payments::mojom::PaymentRequestEventDataPtr; +using ServiceWorkerStartCallback = + base::OnceCallback<void(scoped_refptr<ServiceWorkerVersion>, + blink::ServiceWorkerStatusCode)>; + +class CONTENT_EXPORT PaymentAppProviderImpl + : public PaymentAppProvider, + public WebContentsUserData<PaymentAppProviderImpl> { public: - static PaymentAppProviderImpl* GetInstance(); + ~PaymentAppProviderImpl() override; + static PaymentAppProviderImpl* GetOrCreateForWebContents( + WebContents* web_contents); // Disallow copy and assign. PaymentAppProviderImpl(const PaymentAppProviderImpl& other) = delete; @@ -23,13 +34,11 @@ // PaymentAppProvider implementation: // Should be accessed only on the UI thread. - void InvokePaymentApp(WebContents* web_contents, - int64_t registration_id, + void InvokePaymentApp(int64_t registration_id, const url::Origin& sw_origin, payments::mojom::PaymentRequestEventDataPtr event_data, InvokePaymentAppCallback callback) override; void InstallAndInvokePaymentApp( - WebContents* web_contents, payments::mojom::PaymentRequestEventDataPtr event_data, const std::string& app_name, const SkBitmap& app_icon, @@ -40,42 +49,41 @@ const SupportedDelegations& supported_delegations, RegistrationIdCallback registration_id_callback, InvokePaymentAppCallback callback) override; - void UpdatePaymentAppIcon(BrowserContext* browser_context, - int64_t registration_id, + void UpdatePaymentAppIcon(int64_t registration_id, const std::string& instrument_key, const std::string& name, const std::string& string_encoded_icon, const std::string& method_name, const SupportedDelegations& supported_delegations, UpdatePaymentAppIconCallback callback) override; - void CanMakePayment(WebContents* web_contents, - int64_t registration_id, + void CanMakePayment(int64_t registration_id, const url::Origin& sw_origin, const std::string& payment_request_id, payments::mojom::CanMakePaymentEventDataPtr event_data, CanMakePaymentCallback callback) override; - void AbortPayment(WebContents* web_contents, - int64_t registration_id, + void AbortPayment(int64_t registration_id, const url::Origin& sw_origin, const std::string& payment_request_id, AbortCallback callback) override; - void SetOpenedWindow(WebContents* web_contents) override; + void SetOpenedWindow() override; void CloseOpenedWindow() override; void OnClosingOpenedWindow( - WebContents* web_contents, payments::mojom::PaymentEventResponseType reason) override; - bool IsValidInstallablePaymentApp(const GURL& manifest_url, - const GURL& sw_js_url, - const GURL& sw_scope, - std::string* error_message) override; - ukm::SourceId GetSourceIdForPaymentAppFromScope( - const GURL& sw_scope) override; private: - PaymentAppProviderImpl(); - ~PaymentAppProviderImpl() override; + explicit PaymentAppProviderImpl(WebContents* web_contents); + friend class WebContentsUserData<PaymentAppProviderImpl>; + WEB_CONTENTS_USER_DATA_KEY_DECL(); - friend struct base::DefaultSingletonTraits<PaymentAppProviderImpl>; + scoped_refptr<DevToolsBackgroundServicesContextImpl> GetDevTools( + const url::Origin& sw_origin); + void StartServiceWorkerForDispatch(int64_t registration_id, + ServiceWorkerStartCallback callback); + void OnInstallPaymentApp(const url::Origin& sw_origin, + PaymentRequestEventDataPtr event_data, + RegistrationIdCallback registration_id_callback, + InvokePaymentAppCallback callback, + int64_t registration_id); // Note that constructor of WebContentsObserver is protected. class PaymentHandlerWindowObserver : public WebContentsObserver { @@ -85,6 +93,11 @@ }; std::unique_ptr<PaymentHandlerWindowObserver> payment_handler_window_; + + // Owns this object. + WebContents* web_contents_; + + base::WeakPtrFactory<PaymentAppProviderImpl> weak_ptr_factory_{this}; }; } // namespace content
diff --git a/content/browser/payments/payment_app_provider_impl_unittest.cc b/content/browser/payments/payment_app_provider_impl_unittest.cc index 802427b..51767c3 100644 --- a/content/browser/payments/payment_app_provider_impl_unittest.cc +++ b/content/browser/payments/payment_app_provider_impl_unittest.cc
@@ -11,7 +11,7 @@ #include "base/run_loop.h" #include "content/browser/payments/installed_payment_apps_finder_impl.h" #include "content/browser/payments/payment_app_content_unittest_base.h" -#include "content/browser/payments/payment_app_provider_impl.h" +#include "content/public/browser/payment_app_provider.h" #include "content/public/browser/permission_type.h" #include "content/public/browser/web_contents.h" #include "content/public/test/mock_permission_manager.h" @@ -107,9 +107,9 @@ const url::Origin& sw_origin, payments::mojom::PaymentRequestEventDataPtr event_data, PaymentAppProvider::InvokePaymentAppCallback callback) { - PaymentAppProviderImpl::GetInstance()->InvokePaymentApp( - web_contents_, registration_id, sw_origin, std::move(event_data), - std::move(callback)); + PaymentAppProvider::GetOrCreateForWebContents(web_contents_) + ->InvokePaymentApp(registration_id, sw_origin, std::move(event_data), + std::move(callback)); base::RunLoop().RunUntilIdle(); } @@ -118,24 +118,24 @@ const std::string& payment_request_id, payments::mojom::CanMakePaymentEventDataPtr event_data, PaymentAppProvider::CanMakePaymentCallback callback) { - PaymentAppProviderImpl::GetInstance()->CanMakePayment( - web_contents_, registration_id, sw_origin, payment_request_id, - std::move(event_data), std::move(callback)); + PaymentAppProvider::GetOrCreateForWebContents(web_contents_) + ->CanMakePayment(registration_id, sw_origin, payment_request_id, + std::move(event_data), std::move(callback)); } void AbortPayment(int64_t registration_id, const url::Origin& sw_origin, const std::string& payment_request_id, PaymentAppProvider::AbortCallback callback) { - PaymentAppProviderImpl::GetInstance()->AbortPayment( - web_contents_, registration_id, sw_origin, payment_request_id, - std::move(callback)); + PaymentAppProvider::GetOrCreateForWebContents(web_contents_) + ->AbortPayment(registration_id, sw_origin, payment_request_id, + std::move(callback)); } void OnClosingOpenedWindow() { - PaymentAppProviderImpl::GetInstance()->OnClosingOpenedWindow( - web_contents_, payments::mojom::PaymentEventResponseType:: - PAYMENT_HANDLER_WINDOW_CLOSING); + PaymentAppProvider::GetOrCreateForWebContents(web_contents_) + ->OnClosingOpenedWindow(payments::mojom::PaymentEventResponseType:: + PAYMENT_HANDLER_WINDOW_CLOSING); base::RunLoop().RunUntilIdle(); }
diff --git a/content/browser/payments/payment_app_provider_util.cc b/content/browser/payments/payment_app_provider_util.cc new file mode 100644 index 0000000..945ad9f --- /dev/null +++ b/content/browser/payments/payment_app_provider_util.cc
@@ -0,0 +1,50 @@ +// Copyright 2020 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/public/browser/payment_app_provider_util.h" + +#include "content/common/service_worker/service_worker_utils.h" +#include "content/public/browser/browser_thread.h" + +namespace content { + +// static +ukm::SourceId PaymentAppProviderUtil::GetSourceIdForPaymentAppFromScope( + const GURL& sw_scope) { + return ukm::UkmRecorder::GetSourceIdForPaymentAppFromScope( + sw_scope.GetOrigin()); +} + +// static +bool PaymentAppProviderUtil::IsValidInstallablePaymentApp( + const GURL& manifest_url, + const GURL& sw_js_url, + const GURL& sw_scope, + std::string* error_message) { + DCHECK(manifest_url.is_valid() && sw_js_url.is_valid() && + sw_scope.is_valid()); + + // Scope will be checked against service worker js url when registering, but + // we check it here earlier to avoid presenting unusable payment handlers. + if (!ServiceWorkerUtils::IsPathRestrictionSatisfiedWithoutHeader( + sw_scope, sw_js_url, error_message)) { + return false; + } + + // TODO(crbug.com/855312): Unify duplicated code between here and + // ServiceWorkerProviderHost::IsValidRegisterMessage. + std::vector<GURL> urls = {manifest_url, sw_js_url, sw_scope}; + if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) { + *error_message = + "Origins are not matching, or some origins cannot access service " + "worker (manifest:" + + manifest_url.spec() + " scope:" + sw_scope.spec() + + " sw:" + sw_js_url.spec() + ")"; + return false; + } + + return true; +} + +} // namespace content
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/content/browser/renderer_host/browser_compositor_view_mac.mm index f973fe0..ddefee8 100644 --- a/content/browser/renderer_host/browser_compositor_view_mac.mm +++ b/content/browser/renderer_host/browser_compositor_view_mac.mm
@@ -25,6 +25,7 @@ #include "ui/compositor/recyclable_compositor_mac.h" #include "ui/display/screen.h" #include "ui/gfx/geometry/dip_util.h" +#include "ui/gfx/geometry/size_conversions.h" namespace content { @@ -158,8 +159,9 @@ child_local_surface_id_allocation)) { if (auto_resize_enabled) { dfh_display_.set_device_scale_factor(new_device_scale_factor); - dfh_size_dip_ = gfx::ConvertSizeToDIP(dfh_display_.device_scale_factor(), - new_size_in_pixels); + // TODO(danakj): We should avoid lossy conversions to integer DIPs. + dfh_size_dip_ = gfx::ToFlooredSize(gfx::ConvertSizeToDips( + new_size_in_pixels, dfh_display_.device_scale_factor())); dfh_size_pixels_ = new_size_in_pixels; root_layer_->SetBounds(gfx::Rect(dfh_size_dip_)); if (recyclable_compositor_) {
diff --git a/content/browser/renderer_host/cross_process_frame_connector.cc b/content/browser/renderer_host/cross_process_frame_connector.cc index bc950a2..fc48683 100644 --- a/content/browser/renderer_host/cross_process_frame_connector.cc +++ b/content/browser/renderer_host/cross_process_frame_connector.cc
@@ -290,7 +290,6 @@ } void CrossProcessFrameConnector::OnSynchronizeVisualProperties( - const viz::FrameSinkId& frame_sink_id, const blink::FrameVisualProperties& visual_properties) { TRACE_EVENT_WITH_FLOW2( TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"), @@ -319,7 +318,7 @@ last_received_zoom_level_ = visual_properties.zoom_level; last_received_local_frame_size_ = visual_properties.local_frame_size; - SynchronizeVisualProperties(frame_sink_id, visual_properties); + SynchronizeVisualProperties(visual_properties); } void CrossProcessFrameConnector::OnUpdateViewportIntersection(
diff --git a/content/browser/renderer_host/cross_process_frame_connector.h b/content/browser/renderer_host/cross_process_frame_connector.h index e5e9e60..e4425fc8 100644 --- a/content/browser/renderer_host/cross_process_frame_connector.h +++ b/content/browser/renderer_host/cross_process_frame_connector.h
@@ -189,7 +189,6 @@ // Handlers for messages received from the parent frame. void OnSynchronizeVisualProperties( - const viz::FrameSinkId& frame_sink_id, const blink::FrameVisualProperties& visual_properties); void OnUpdateViewportIntersection( const blink::ViewportIntersectionState& viewport_intersection);
diff --git a/content/browser/renderer_host/frame_connector_delegate.cc b/content/browser/renderer_host/frame_connector_delegate.cc index d8363fa..beadcb8 100644 --- a/content/browser/renderer_host/frame_connector_delegate.cc +++ b/content/browser/renderer_host/frame_connector_delegate.cc
@@ -30,7 +30,6 @@ blink::mojom::IntrinsicSizingInfoPtr) {} void FrameConnectorDelegate::SynchronizeVisualProperties( - const viz::FrameSinkId& frame_sink_id, const blink::FrameVisualProperties& visual_properties) { screen_info_ = visual_properties.screen_info; local_surface_id_allocation_ = visual_properties.local_surface_id_allocation;
diff --git a/content/browser/renderer_host/frame_connector_delegate.h b/content/browser/renderer_host/frame_connector_delegate.h index cf9c3ae..d15f613 100644 --- a/content/browser/renderer_host/frame_connector_delegate.h +++ b/content/browser/renderer_host/frame_connector_delegate.h
@@ -80,7 +80,6 @@ // Sends new resize parameters to the sub-frame's renderer. void SynchronizeVisualProperties( - const viz::FrameSinkId& frame_sink_id, const blink::FrameVisualProperties& visual_properties); // Return the size of the CompositorFrame to use in the child renderer.
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc index 8c02673..5741a72 100644 --- a/content/browser/renderer_host/input/input_router_impl.cc +++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -201,7 +201,6 @@ touch_scroll_started_sent_ = true; touch_event_queue_.PrependTouchScrollNotification(); } - touch_event_queue_.OnGestureScrollEvent(gesture_event); } if (gesture_event.event.IsTouchpadZoomEvent() &&
diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc index 552f2e8..0ba305c 100644 --- a/content/browser/renderer_host/input/input_router_impl_unittest.cc +++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -1676,6 +1676,9 @@ dispatched_messages[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); + EXPECT_EQ(WebInputEvent::Type::kTouchStart, + disposition_handler_->ack_event_type()); + SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin, blink::WebGestureDevice::kTouchscreen); dispatched_messages = GetAndResetDispatchedMessages(); @@ -1684,14 +1687,55 @@ dispatched_messages[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollBegin, + disposition_handler_->ack_event_type()); + SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate, blink::WebGestureDevice::kTouchscreen); EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount()); - EXPECT_EQ(2U, GetAndResetDispatchedMessages().size()); + dispatched_messages = GetAndResetDispatchedMessages(); + EXPECT_EQ(2U, dispatched_messages.size()); + EXPECT_EQ(WebInputEvent::Type::kTouchScrollStarted, + dispatched_messages[0]->ToEvent()->Event()->Event().GetType()); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, + dispatched_messages[1]->ToEvent()->Event()->Event().GetType()); + // Ack the GestureScrollUpdate. + dispatched_messages[1]->ToEvent()->CallCallback( + blink::mojom::InputEventResultState::kConsumed); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, + disposition_handler_->ack_event_type()); + EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); - // Now send an async move. + // Now since we're scrolling send an async move. MoveTouchPoint(0, 5, 5); SendTouchEvent(); + EXPECT_EQ(WebInputEvent::Type::kTouchMove, + disposition_handler_->ack_event_type()); + EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); + EXPECT_EQ(1U, GetAndResetDispatchedMessages().size()); + + // To catch crbug/1072364 send another scroll which returns kNoConsumerExists + // and ensure we're still async scrolling since we've already started the + // scroll. + SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate, + blink::WebGestureDevice::kTouchscreen); + EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount()); + dispatched_messages = GetAndResetDispatchedMessages(); + EXPECT_EQ(1U, dispatched_messages.size()); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, + dispatched_messages[0]->ToEvent()->Event()->Event().GetType()); + // Ack the GestureScrollUpdate. + dispatched_messages[0]->ToEvent()->CallCallback( + blink::mojom::InputEventResultState::kNoConsumerExists); + EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, + disposition_handler_->ack_event_type()); + EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); + + // Now since we're scrolling (even with NoConsumerExists) send an async move. + MoveTouchPoint(0, 10, 5); + SendTouchEvent(); + EXPECT_EQ(WebInputEvent::Type::kTouchMove, + disposition_handler_->ack_event_type()); EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); EXPECT_EQ(1U, GetAndResetDispatchedMessages().size()); }
diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue.cc b/content/browser/renderer_host/input/passthrough_touch_event_queue.cc index bcdb5e91..37411ac 100644 --- a/content/browser/renderer_host/input/passthrough_touch_event_queue.cc +++ b/content/browser/renderer_host/input/passthrough_touch_event_queue.cc
@@ -143,22 +143,16 @@ AckCompletedEvents(); } -void PassthroughTouchEventQueue::OnGestureScrollEvent( - const GestureEventWithLatencyInfo& gesture_event) { - if (gesture_event.event.GetType() == - blink::WebInputEvent::Type::kGestureScrollUpdate) { - send_touch_events_async_ = true; - } -} - void PassthroughTouchEventQueue::OnGestureEventAck( const GestureEventWithLatencyInfo& event, blink::mojom::InputEventResultState ack_result) { - // Turn events sent during gesture scrolls to be async. - if (event.event.GetType() == - blink::WebInputEvent::Type::kGestureScrollUpdate) { - send_touch_events_async_ = - (ack_result == blink::mojom::InputEventResultState::kConsumed); + // When the scroll finishes allow TouchEvents to be blocking again. + if (event.event.GetType() == blink::WebInputEvent::Type::kGestureScrollEnd) { + send_touch_events_async_ = false; + } else if (event.event.GetType() == + blink::WebInputEvent::Type::kGestureScrollUpdate && + ack_result == blink::mojom::InputEventResultState::kConsumed) { + send_touch_events_async_ = true; } }
diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue.h b/content/browser/renderer_host/input/passthrough_touch_event_queue.h index 75d1726..caa3b58 100644 --- a/content/browser/renderer_host/input/passthrough_touch_event_queue.h +++ b/content/browser/renderer_host/input/passthrough_touch_event_queue.h
@@ -102,7 +102,6 @@ const ui::LatencyInfo& latency_info, const uint32_t unique_touch_event_id, bool should_stop_timeout_monitor); - void OnGestureScrollEvent(const GestureEventWithLatencyInfo& gesture_event); void OnGestureEventAck(const GestureEventWithLatencyInfo& event, blink::mojom::InputEventResultState ack_result);
diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc b/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc index 7f67166e..a3457be 100644 --- a/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc +++ b/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
@@ -86,12 +86,6 @@ std::move(followup_touch_event_); SendTouchEvent(*followup_touch_event); } - if (followup_gesture_event_) { - std::unique_ptr<WebGestureEvent> followup_gesture_event = - std::move(followup_gesture_event_); - queue_->OnGestureScrollEvent(GestureEventWithLatencyInfo( - *followup_gesture_event, ui::LatencyInfo())); - } last_acked_event_ = event.event; last_acked_event_state_ = ack_result; } @@ -146,13 +140,6 @@ queue_->QueueEvent(TouchEventWithLatencyInfo(event, ui::LatencyInfo())); } - void SendGestureEvent(WebInputEvent::Type type) { - WebGestureEvent event(type, WebInputEvent::kNoModifiers, - ui::EventTimeForNow()); - queue_->OnGestureScrollEvent( - GestureEventWithLatencyInfo(event, ui::LatencyInfo())); - } - void SendTouchEventAck(blink::mojom::InputEventResultState ack_result) { DCHECK(!sent_events_ids_.empty()); queue_->ProcessTouchAck( @@ -188,10 +175,6 @@ followup_touch_event_.reset(new WebTouchEvent(event)); } - void SetFollowupEvent(const WebGestureEvent& event) { - followup_gesture_event_.reset(new WebGestureEvent(event)); - } - void SetSyncAckResult(blink::mojom::InputEventResultState sync_ack_result) { sync_ack_result_.reset( new blink::mojom::InputEventResultState(sync_ack_result)); @@ -355,7 +338,6 @@ blink::mojom::InputEventResultState last_acked_event_state_; SyntheticWebTouchEvent touch_event_; std::unique_ptr<WebTouchEvent> followup_touch_event_; - std::unique_ptr<WebGestureEvent> followup_gesture_event_; std::unique_ptr<blink::mojom::InputEventResultState> sync_ack_result_; double slop_length_dips_; gfx::PointF anchor_; @@ -1161,11 +1143,8 @@ EXPECT_TRUE(IsTimeoutRunning()); EXPECT_EQ(1U, GetAndResetSentEventCount()); - // The cancelled sequence may turn into a scroll gesture. - WebGestureEvent followup_scroll(WebInputEvent::Type::kGestureScrollBegin, - WebInputEvent::kNoModifiers, - ui::EventTimeForNow()); - SetFollowupEvent(followup_scroll); + // The cancelled sequence may turn into a scroll gesture, but this code but + // these GestureScrollBegin events are generated elsewhere. // Delay the ack. RunTasksAndWait(DefaultTouchTimeoutDelay() * 2); @@ -1198,8 +1177,7 @@ EXPECT_EQ(1U, GetAndResetSentEventCount()); EXPECT_EQ(1U, GetAndResetAckedEventCount()); - // Now end the scroll sequence. - SendGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd); + // Now end the scroll sequence (A GestureScrollEnd). PressTouchPoint(0, 1); EXPECT_TRUE(IsTimeoutRunning()); EXPECT_EQ(1U, GetAndResetSentEventCount()); @@ -1218,11 +1196,8 @@ EXPECT_TRUE(IsTimeoutRunning()); EXPECT_EQ(1U, GetAndResetSentEventCount()); - // The cancelled sequence may turn into a scroll gesture. - WebGestureEvent followup_scroll(WebInputEvent::Type::kGestureScrollBegin, - WebInputEvent::kNoModifiers, - ui::EventTimeForNow()); - SetFollowupEvent(followup_scroll); + // The cancelled sequence may turn into a scroll gesture, but this code but + // these GestureScrollBegin events are generated elsewhere. // Delay the ack. RunTasksAndWait(DefaultTouchTimeoutDelay() * 2); @@ -1243,7 +1218,6 @@ // Now end the scroll sequence. Events will not be forwarded until the two // outstanding touch acks are received. - SendGestureEvent(blink::WebInputEvent::Type::kGestureScrollEnd); MoveTouchPoint(0, 2, 2); ReleaseTouchPoint(0); EXPECT_FALSE(IsTimeoutRunning()); @@ -1425,10 +1399,6 @@ ASSERT_EQ(1U, GetAndResetSentEventCount()); ASSERT_EQ(1U, GetAndResetAckedEventCount()); - WebGestureEvent followup_scroll(WebInputEvent::Type::kGestureScrollBegin, - WebInputEvent::kNoModifiers, - WebInputEvent::GetStaticTimeStampForTests()); - SetFollowupEvent(followup_scroll); MoveTouchPoint(0, 20, 5); EXPECT_EQ(0U, GetAndResetSentEventCount()); EXPECT_EQ(1U, GetAndResetAckedEventCount()); @@ -1457,7 +1427,6 @@ EXPECT_EQ(1U, GetAndResetAckedEventCount()); MoveTouchPoint(0, 20, 5); - SendGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin); SendTouchEventAck(blink::mojom::InputEventResultState::kConsumed); EXPECT_EQ(0U, queued_event_count()); EXPECT_EQ(2U, GetAndResetSentEventCount()); @@ -1471,10 +1440,8 @@ EXPECT_EQ(1U, GetAndResetSentEventCount()); MoveTouchPoint(0, 20, 5); - WebGestureEvent followup_scroll(WebInputEvent::Type::kGestureScrollUpdate, - WebInputEvent::kNoModifiers, - WebInputEvent::GetStaticTimeStampForTests()); - SetFollowupEvent(followup_scroll); + // A GestureScrollUpdate would be sent here so simulate the ACK of the + // TouchMove AND the GestureScrollUpdate SendTouchEventAck(blink::mojom::InputEventResultState::kNotConsumed); SendGestureEventAck(WebInputEvent::Type::kGestureScrollUpdate, blink::mojom::InputEventResultState::kConsumed); @@ -1498,9 +1465,10 @@ MoveTouchPoint(0, 20, 5); EXPECT_EQ(WebInputEvent::DispatchType::kBlocking, sent_event().dispatch_type); - SendGestureEvent(blink::WebInputEvent::Type::kGestureScrollBegin); - SendGestureEvent(blink::WebInputEvent::Type::kGestureScrollUpdate); SendTouchEventAck(blink::mojom::InputEventResultState::kNotConsumed); + // Consume the GestureScrollUpdate to move TouchMoves to async behaviour. + SendGestureEventAck(WebInputEvent::Type::kGestureScrollUpdate, + blink::mojom::InputEventResultState::kConsumed); EXPECT_EQ(WebInputEvent::DispatchType::kBlocking, sent_event().dispatch_type); ASSERT_EQ(1U, GetAndResetSentEventCount()); @@ -1529,15 +1497,19 @@ ASSERT_EQ(1U, GetAndResetSentEventCount()); // If subsequent touchmoves aren't consumed, the generated scroll events - // will restore async touch dispatch. + // will restore async touch dispatch if the GestureScrollUpdate's are + // consumed. MoveTouchPoint(0, 25, 5); SendTouchEventAck(blink::mojom::InputEventResultState::kNotConsumed); - SendGestureEvent(blink::WebInputEvent::Type::kGestureScrollUpdate); + SendGestureEventAck(WebInputEvent::Type::kGestureScrollUpdate, + blink::mojom::InputEventResultState::kConsumed); EXPECT_EQ(WebInputEvent::DispatchType::kBlocking, sent_event().dispatch_type); ASSERT_EQ(1U, GetAndResetSentEventCount()); AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1); MoveTouchPoint(0, 30, 5); SendTouchEventAck(blink::mojom::InputEventResultState::kNotConsumed); + SendGestureEventAck(WebInputEvent::Type::kGestureScrollUpdate, + blink::mojom::InputEventResultState::kConsumed); EXPECT_NE(WebInputEvent::DispatchType::kBlocking, sent_event().dispatch_type); ASSERT_EQ(1U, GetAndResetSentEventCount());
diff --git a/content/browser/renderer_host/render_widget_host_browsertest.cc b/content/browser/renderer_host/render_widget_host_browsertest.cc index 0939d06..f80a4ee 100644 --- a/content/browser/renderer_host/render_widget_host_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_browsertest.cc
@@ -267,14 +267,14 @@ // Simulate a mouse move without any pressed buttons. This should not // generate any touch events. - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 10, 0, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 120, 0, false); TestInputEventObserver::EventTypeVector dispatched_events = observer.GetAndResetDispatchedEventTypes(); EXPECT_EQ(0u, dispatched_events.size()); // Mouse press becomes touch start which in turn becomes tap. - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseDown, 10, 10, 0, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseDown, 10, 120, 0, true); WaitForAckWith(blink::WebInputEvent::Type::kTouchStart); EXPECT_EQ(blink::WebInputEvent::Type::kTouchStart, @@ -285,7 +285,7 @@ EXPECT_EQ(blink::WebInputEvent::Type::kGestureTapDown, dispatched_events[1]); // Mouse drag generates touch move, cancels tap and starts scroll. - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 30, 0, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 100, 0, true); dispatched_events = observer.GetAndResetDispatchedEventTypes(); ASSERT_EQ(4u, dispatched_events.size()); @@ -301,7 +301,7 @@ EXPECT_EQ(0u, observer.GetAndResetDispatchedEventTypes().size()); // Mouse drag with shift becomes pinch. - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 35, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 95, blink::WebInputEvent::kShiftKey, true); EXPECT_EQ(blink::WebInputEvent::Type::kTouchMove, observer.acked_touch_event_type()); @@ -312,7 +312,7 @@ EXPECT_EQ(blink::WebInputEvent::Type::kGesturePinchBegin, dispatched_events[1]); - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 50, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 80, blink::WebInputEvent::kShiftKey, true); EXPECT_EQ(blink::WebInputEvent::Type::kTouchMove, observer.acked_touch_event_type()); @@ -324,7 +324,7 @@ dispatched_events[1]); // Mouse drag without shift becomes scroll again. - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 60, 0, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 70, 0, true); EXPECT_EQ(blink::WebInputEvent::Type::kTouchMove, observer.acked_touch_event_type()); @@ -336,7 +336,7 @@ EXPECT_EQ(blink::WebInputEvent::Type::kGestureScrollUpdate, dispatched_events[2]); - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 70, 0, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 60, 0, true); EXPECT_EQ(blink::WebInputEvent::Type::kTouchMove, observer.acked_touch_event_type()); @@ -346,8 +346,9 @@ EXPECT_EQ(blink::WebInputEvent::Type::kGestureScrollUpdate, dispatched_events[1]); - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseUp, 10, 70, 0, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseUp, 10, 60, 0, true); + WaitForAckWith(blink::WebInputEvent::Type::kTouchEnd); EXPECT_EQ(blink::WebInputEvent::Type::kTouchEnd, observer.acked_touch_event_type()); dispatched_events = observer.GetAndResetDispatchedEventTypes(); @@ -357,13 +358,13 @@ dispatched_events[1]); // Mouse move does nothing. - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 80, 0, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 50, 0, false); dispatched_events = observer.GetAndResetDispatchedEventTypes(); EXPECT_EQ(0u, dispatched_events.size()); // Another mouse down continues scroll. - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseDown, 10, 80, 0, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseDown, 10, 50, 0, true); WaitForAckWith(blink::WebInputEvent::Type::kTouchStart); EXPECT_EQ(blink::WebInputEvent::Type::kTouchStart, @@ -372,7 +373,7 @@ ASSERT_EQ(2u, dispatched_events.size()); EXPECT_EQ(blink::WebInputEvent::Type::kTouchStart, dispatched_events[0]); EXPECT_EQ(blink::WebInputEvent::Type::kGestureTapDown, dispatched_events[1]); - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 100, 0, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 30, 0, true); EXPECT_EQ(blink::WebInputEvent::Type::kTouchMove, observer.acked_touch_event_type()); @@ -388,7 +389,7 @@ EXPECT_EQ(0u, observer.GetAndResetDispatchedEventTypes().size()); // Another pinch. - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 110, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 20, blink::WebInputEvent::kShiftKey, true); EXPECT_EQ(blink::WebInputEvent::Type::kTouchMove, observer.acked_touch_event_type()); @@ -397,7 +398,7 @@ EXPECT_EQ(blink::WebInputEvent::Type::kTouchMove, dispatched_events[0]); EXPECT_EQ(blink::WebInputEvent::Type::kGesturePinchBegin, dispatched_events[1]); - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 120, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 10, blink::WebInputEvent::kShiftKey, true); EXPECT_EQ(blink::WebInputEvent::Type::kTouchMove, observer.acked_touch_event_type()); @@ -419,7 +420,7 @@ dispatched_events[2]); // Mouse event should pass untouched. - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 10, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 120, blink::WebInputEvent::kShiftKey, true); dispatched_events = observer.GetAndResetDispatchedEventTypes(); ASSERT_EQ(1u, dispatched_events.size()); @@ -431,7 +432,7 @@ ui::GestureProviderConfigType::GENERIC_MOBILE); // Another touch. - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseDown, 10, 10, 0, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseDown, 10, 120, 0, true); WaitForAckWith(blink::WebInputEvent::Type::kTouchStart); EXPECT_EQ(blink::WebInputEvent::Type::kTouchStart, @@ -442,7 +443,7 @@ EXPECT_EQ(blink::WebInputEvent::Type::kGestureTapDown, dispatched_events[1]); // Scroll. - SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 30, 0, + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 100, 0, true); EXPECT_EQ(blink::WebInputEvent::Type::kTouchMove, observer.acked_touch_event_type());
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 f45da60..0f6b2327 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
@@ -556,13 +556,13 @@ float device_scale_factor = root_view->GetDeviceScaleFactor(); DCHECK_GT(device_scale_factor, 0.0f); gfx::PointF point_in_pixels = - gfx::ConvertPointToPixel(device_scale_factor, point); + gfx::ConvertPointToPixels(point, device_scale_factor); viz::Target target = query->FindTargetForLocationStartingFrom( source, point_in_pixels, root_view->GetFrameSinkId()); frame_sink_id = target.frame_sink_id; if (frame_sink_id.is_valid()) { *transformed_point = - gfx::ConvertPointToDIP(device_scale_factor, target.location_in_target); + gfx::ConvertPointToDips(target.location_in_target, device_scale_factor); } else { *transformed_point = point; }
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index 44f2c6f..b2139c2 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -793,8 +793,8 @@ float device_scale_factor = original_view->GetDeviceScaleFactor(); DCHECK_GT(device_scale_factor, 0.0f); - gfx::Point3F point_in_pixels( - gfx::ConvertPointToPixel(device_scale_factor, point)); + gfx::Point3F point_in_pixels = + gfx::Point3F(gfx::ConvertPointToPixels(point, device_scale_factor)); // TODO(crbug.com/966995): Optimize so that |point_in_pixels| doesn't need to // be in the coordinate space of the root surface in HitTestQuery. gfx::Transform transform_root_to_original; @@ -802,12 +802,14 @@ &transform_root_to_original); if (!transform_root_to_original.TransformPointReverse(&point_in_pixels)) return false; + gfx::PointF transformed_point_in_physical_pixels; if (!query->TransformLocationForTarget( - target_ancestors, point_in_pixels.AsPointF(), transformed_point)) { + target_ancestors, point_in_pixels.AsPointF(), + &transformed_point_in_physical_pixels)) { return false; } - *transformed_point = - gfx::ConvertPointToDIP(device_scale_factor, *transformed_point); + *transformed_point = gfx::ConvertPointToDips( + transformed_point_in_physical_pixels, device_scale_factor); return true; }
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc index e51fa31..800f341 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc
@@ -293,7 +293,6 @@ allocator.GenerateId(); viz::LocalSurfaceIdAllocation local_surface_id_allocation = allocator.GetCurrentLocalSurfaceIdAllocation(); - constexpr viz::FrameSinkId frame_sink_id(1, 1); blink::FrameVisualProperties visual_properties; visual_properties.screen_space_rect = screen_space_rect; @@ -305,8 +304,7 @@ base::RunLoop().RunUntilIdle(); widget_.ClearVisualProperties(); - test_frame_connector_->SynchronizeVisualProperties(frame_sink_id, - visual_properties); + test_frame_connector_->SynchronizeVisualProperties(visual_properties); // Update to the renderer. base::RunLoop().RunUntilIdle();
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm index 9955638..3d059f30 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -1147,7 +1147,7 @@ [rwhv_mac_->GetInProcessNSView() mouseEvent:event]; base::RunLoop().RunUntilIdle(); events = host_->GetAndResetDispatchedMessages(); - ASSERT_EQ("TouchEnd GestureScrollEnd", GetMessageNames(events)); + ASSERT_EQ("TouchEnd", GetMessageNames(events)); EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen, static_cast<const blink::WebTouchEvent&>( events[0]->ToEvent()->Event()->Event()) @@ -1157,6 +1157,7 @@ events.clear(); base::RunLoop().RunUntilIdle(); events = host_->GetAndResetDispatchedMessages(); + ASSERT_EQ("GestureScrollEnd", GetMessageNames(events)); event = MockMouseEventWithParams(kCGEventLeftMouseDown, {6, 9},
diff --git a/content/browser/service_worker/service_worker_client_utils.cc b/content/browser/service_worker/service_worker_client_utils.cc index 4afde322..41c31fd 100644 --- a/content/browser/service_worker/service_worker_client_utils.cc +++ b/content/browser/service_worker/service_worker_client_utils.cc
@@ -213,7 +213,8 @@ if (type == WindowType::PAYMENT_HANDLER_WINDOW) { // Set the opened web_contents to payment app provider to manage its life // cycle. - PaymentAppProvider::GetInstance()->SetOpenedWindow(web_contents); + PaymentAppProvider::GetOrCreateForWebContents(web_contents) + ->SetOpenedWindow(); } }
diff --git a/content/browser/service_worker/service_worker_main_resource_loader.cc b/content/browser/service_worker/service_worker_main_resource_loader.cc index d9a6ce9..c9e61002f 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader.cc +++ b/content/browser/service_worker/service_worker_main_resource_loader.cc
@@ -246,13 +246,6 @@ "initial_worker_status", EmbeddedWorkerInstance::StatusToString(initial_worker_status)); - // At this point a service worker is running and the fetch event is about - // to dispatch. Record some load timings. - base::TimeTicks now = base::TimeTicks::Now(); - response_head_->load_timing.service_worker_ready_time = now; - response_head_->load_timing.send_start = now; - response_head_->load_timing.send_end = now; - devtools_attached_ = version->embedded_worker()->devtools_attached(); } @@ -296,6 +289,21 @@ return; } + // Record the timing of when the fetch event is dispatched on the worker + // thread. This is used for PerformanceResourceTiming#fetchStart and + // PerformanceResourceTiming#requestStart, but it's still under spec + // discussion. + // See https://github.com/w3c/resource-timing/issues/119 for more details. + // Exposed as PerformanceResourceTiming#fetchStart. + response_head_->load_timing.service_worker_ready_time = + fetch_event_timing_->dispatch_event_time; + // Exposed as PerformanceResourceTiming#requestStart. + response_head_->load_timing.send_start = + fetch_event_timing_->dispatch_event_time; + // Recorded for the DevTools. + response_head_->load_timing.send_end = + fetch_event_timing_->dispatch_event_time; + if (fetch_result == ServiceWorkerFetchDispatcher::FetchEventResult::kShouldFallback) { TransitionToStatus(Status::kCompleted);
diff --git a/content/browser/service_worker/service_worker_main_resource_loader_unittest.cc b/content/browser/service_worker/service_worker_main_resource_loader_unittest.cc index 7d774f39..28aa8ed 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader_unittest.cc +++ b/content/browser/service_worker/service_worker_main_resource_loader_unittest.cc
@@ -105,11 +105,19 @@ public: FetchEventServiceWorker( EmbeddedWorkerTestHelper* helper, - FakeEmbeddedWorkerInstanceClient* embedded_worker_instance_client) + FakeEmbeddedWorkerInstanceClient* embedded_worker_instance_client, + BrowserTaskEnvironment* task_environment) : FakeServiceWorker(helper), + task_environment_(task_environment), embedded_worker_instance_client_(embedded_worker_instance_client) {} ~FetchEventServiceWorker() override = default; + // Tells this worker to dispatch a fetch event 1s after the fetch event is + // received. + void DispatchAfter1sDelay() { + response_mode_ = ResponseMode::kDispatchAfter1sDelay; + } + // Tells this worker to respond to fetch events with the specified blob. void RespondWithBlob(blink::mojom::SerializedBlobPtr blob) { response_mode_ = ResponseMode::kBlob; @@ -243,6 +251,12 @@ std::move(params), response_callback.Unbind(), std::move(finish_callback)); break; + case ResponseMode::kDispatchAfter1sDelay: + task_environment_->AdvanceClock(base::TimeDelta::FromSeconds(1)); + FakeServiceWorker::DispatchFetchEventForMainResource( + std::move(params), response_callback.Unbind(), + std::move(finish_callback)); + break; case ResponseMode::kBlob: response_callback->OnResponse( OkResponse(std::move(blob_body_), response_source_, response_time_, @@ -320,6 +334,7 @@ private: enum class ResponseMode { kDefault, + kDispatchAfter1sDelay, kBlob, kStream, kFallbackResponse, @@ -331,6 +346,8 @@ kHeaders }; + BrowserTaskEnvironment* const task_environment_; + ResponseMode response_mode_ = ResponseMode::kDefault; scoped_refptr<network::ResourceRequestBody> request_body_; @@ -391,7 +408,8 @@ class ServiceWorkerMainResourceLoaderTest : public testing::Test { public: ServiceWorkerMainResourceLoaderTest() - : task_environment_(BrowserTaskEnvironment::IO_MAINLOOP) {} + : task_environment_(BrowserTaskEnvironment::IO_MAINLOOP, + base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} ~ServiceWorkerMainResourceLoaderTest() override = default; void SetUp() override { @@ -433,7 +451,7 @@ helper_.get()); service_worker_ = helper_->AddNewPendingServiceWorker<FetchEventServiceWorker>( - helper_.get(), client); + helper_.get(), client, &task_environment_); // Wait for main script response is set to |version| because // ServiceWorkerMainResourceLoader needs the main script response to @@ -1057,5 +1075,27 @@ EXPECT_EQ(net::ERR_ABORTED, client_.completion_status().error_code); } +TEST_F(ServiceWorkerMainResourceLoaderTest, TimingInfo) { + service_worker_->DispatchAfter1sDelay(); + + // Perform the request. + StartRequest(CreateRequest()); + client_.RunUntilComplete(); + + // The response header's timing is recorded appropriately. + auto& info = client_.response_head(); + EXPECT_EQ(200, info->headers->response_code()); + ExpectResponseInfo(*info, *CreateResponseInfoFromServiceWorker()); + EXPECT_EQ(base::TimeDelta::FromSeconds(1), + info->load_timing.service_worker_ready_time - + info->load_timing.service_worker_start_time); + EXPECT_EQ(base::TimeDelta::FromSeconds(1), + info->load_timing.service_worker_fetch_start - + info->load_timing.service_worker_start_time); + EXPECT_EQ(base::TimeDelta::FromSeconds(1), + info->load_timing.service_worker_respond_with_settled - + info->load_timing.service_worker_start_time); +} + } // namespace service_worker_main_resource_loader_unittest } // namespace content
diff --git a/content/browser/speech/speech_recognition_manager_impl.cc b/content/browser/speech/speech_recognition_manager_impl.cc index 4220ef86e..e9f186dc 100644 --- a/content/browser/speech/speech_recognition_manager_impl.cc +++ b/content/browser/speech/speech_recognition_manager_impl.cc
@@ -449,6 +449,17 @@ if (iter == sessions_.end()) return; + // The deletion observer is owned by this class, so it's safe to use + // Unretained. + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(&SpeechRecognitionManagerImpl::FrameDeletionObserver:: + RemoveObserverForSession, + base::Unretained(frame_deletion_observer_.get()), + iter->second->config.initial_context.render_process_id, + iter->second->config.initial_context.render_frame_id, + session_id)); + iter->second->ui.reset(); base::ThreadTaskRunnerHandle::Get()->PostTask(
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index f157038..46ae3a5 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -1873,10 +1873,6 @@ } #endif -void StoragePartitionImpl::OnSCTReportReady(const std::string& cache_key) { - GetContentClient()->browser()->OnSCTReportReady(browser_context_, cache_key); -} - void StoragePartitionImpl::ClearDataImpl( uint32_t remove_mask, uint32_t quota_storage_remove_mask,
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h index 28fb6bb6..df679ca 100644 --- a/content/browser/storage_partition_impl.h +++ b/content/browser/storage_partition_impl.h
@@ -271,7 +271,6 @@ #if defined(OS_CHROMEOS) void OnTrustAnchorUsed() override; #endif - void OnSCTReportReady(const std::string& cache_key) override; scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter() { return url_loader_factory_getter_;
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc index cf6efee..94f7c7f 100644 --- a/content/browser/tracing/tracing_controller_impl.cc +++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -93,6 +93,8 @@ return "3G"; case net::NetworkChangeNotifier::CONNECTION_4G: return "4G"; + case net::NetworkChangeNotifier::CONNECTION_5G: + return "5G"; case net::NetworkChangeNotifier::CONNECTION_NONE: return "None"; case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH:
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 9307077..1fc8bdbc 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -663,6 +663,7 @@ public_deps = [ "//cc/mojom", + "//components/variations:variations_mojom", "//content/public/common:interfaces", "//content/public/common:web_preferences_mojom", "//ipc:mojom",
diff --git a/content/common/android/cpu_time_metrics.cc b/content/common/android/cpu_time_metrics.cc index 476107e..839a967 100644 --- a/content/common/android/cpu_time_metrics.cc +++ b/content/common/android/cpu_time_metrics.cc
@@ -399,10 +399,11 @@ if (time_delta > base::TimeDelta()) { // Scale the process's cpu time by each cluster/frequency pair's - // relative proportion of execution time. - uint64_t delta_us = (process_cpu_time_delta.InMicroseconds() * - time_delta.InMicroseconds()) / - total_delta.InMicroseconds(); + // relative proportion of execution time. We scale by a double value + // to avoid integer overflow in the presence of large time_delta values. + uint64_t delta_us = process_cpu_time_delta.InMicroseconds() * + (time_delta.InMicroseconds() / + static_cast<double>(total_delta.InMicroseconds())); reporter->AddMicroseconds(frequency_mhz, delta_us); } }
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index b718e46a..eb065bc 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -604,8 +604,7 @@ IPC_MESSAGE_ROUTED0(FrameHostMsg_Unload_ACK) // Tells the browser that a child's visual properties have changed. -IPC_MESSAGE_ROUTED2(FrameHostMsg_SynchronizeVisualProperties, - viz::FrameSinkId /* frame_sink_id */, +IPC_MESSAGE_ROUTED1(FrameHostMsg_SynchronizeVisualProperties, blink::FrameVisualProperties) // Sent by a parent frame to notify its child about the state of the child's
diff --git a/content/common/renderer_variations_configuration.mojom b/content/common/renderer_variations_configuration.mojom index 7a5d1d66..261e33a 100644 --- a/content/common/renderer_variations_configuration.mojom +++ b/content/common/renderer_variations_configuration.mojom
@@ -4,11 +4,16 @@ module content.mojom; +import "components/variations/variations.mojom"; + // Configures the renderer. interface RendererVariationsConfiguration { - // Instructs the renderer to append a variations header for google requests. - // Only sent for non-incognito sessions. - SetVariationsHeader(string variation_ids_header); + // Makes variations headers available to the renderer. Multiple header values + // are sent because the renderer does not know in advance which header might + // be needed for different requests. + // + // Only sent for non-incognito, non-guest sessions. + SetVariationsHeaders(variations.mojom.VariationsHeaders? variations_headers); // Tells the renderer to create a FieldTrial, and by using a 100% probability // for the FieldTrial, forces the FieldTrial to have assigned group name.
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java index 671d9d3c..1fa334d 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
@@ -1710,7 +1710,11 @@ node.setDismissable(dismissable); node.setMultiLine(multiLine); node.setInputType(inputType); - node.setLiveRegion(liveRegion); + + // Deliberately don't call setLiveRegion because TalkBack speaks + // the entire region anytime it changes. Instead Chrome will + // call announceLiveRegionText() only on the nodes that change. + // node.setLiveRegion(liveRegion); // We only apply the |errorMessage| if {@link setAccessibilityNodeInfoBooleanAttributes} // set |contentInvalid| to true based on throttle delay.
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index e9202703..f3bb859 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -270,6 +270,7 @@ "page_navigator.cc", "page_navigator.h", "payment_app_provider.h", + "payment_app_provider_util.h", "peak_gpu_memory_tracker.h", "pepper_flash_settings_helper.h", "pepper_vpn_provider_resource_host_proxy.h",
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 601e19be..b227a0e2 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -746,11 +746,6 @@ virtual void OnTrustAnchorUsed(BrowserContext* browser_context) {} #endif - // Notification that a signed certificate timestamp (SCT) report was enqueued. - // Allows an embedder to implement their own behavior for auditing SCTs. - virtual void OnSCTReportReady(BrowserContext* browser_context, - const std::string& cache_key) {} - // Allows the embedder to override the LocationProvider implementation. // Return nullptr to indicate the default one for the platform should be // created. This is used by Qt, see
diff --git a/content/public/browser/network_context_client_base.h b/content/public/browser/network_context_client_base.h index fd39485d..6b972d0 100644 --- a/content/public/browser/network_context_client_base.h +++ b/content/public/browser/network_context_client_base.h
@@ -75,7 +75,6 @@ #if defined(OS_CHROMEOS) void OnTrustAnchorUsed() override; #endif - void OnSCTReportReady(const std::string& cache_key) override; }; } // namespace content
diff --git a/content/public/browser/payment_app_provider.h b/content/public/browser/payment_app_provider.h index e8c4cd0a..730311d 100644 --- a/content/public/browser/payment_app_provider.h +++ b/content/public/browser/payment_app_provider.h
@@ -7,7 +7,6 @@ #include "base/callback_forward.h" #include "content/common/content_export.h" -#include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/public/mojom/payments/payment_app.mojom.h" class SkBitmap; @@ -18,7 +17,6 @@ namespace content { -class BrowserContext; class WebContents; struct SupportedDelegations; @@ -33,7 +31,8 @@ public: // This static function is actually implemented in PaymentAppProviderImpl.cc. // Please see: content/browser/payments/payment_app_provider_impl.cc - static PaymentAppProvider* GetInstance(); + static PaymentAppProvider* GetOrCreateForWebContents( + WebContents* web_contents); using RegistrationIdCallback = base::OnceCallback<void(int64_t registration_id)>; @@ -47,13 +46,11 @@ // Should be accessed only on the UI thread. virtual void InvokePaymentApp( - WebContents* web_contents, int64_t registration_id, const url::Origin& sw_origin, payments::mojom::PaymentRequestEventDataPtr event_data, InvokePaymentAppCallback callback) = 0; virtual void InstallAndInvokePaymentApp( - WebContents* web_contents, payments::mojom::PaymentRequestEventDataPtr event_data, const std::string& app_name, const SkBitmap& app_icon, @@ -65,7 +62,6 @@ RegistrationIdCallback registration_id_callback, InvokePaymentAppCallback callback) = 0; virtual void UpdatePaymentAppIcon( - BrowserContext* browser_context, int64_t registration_id, const std::string& instrument_key, const std::string& name, @@ -74,14 +70,12 @@ const SupportedDelegations& supported_delegations, UpdatePaymentAppIconCallback callback) = 0; virtual void CanMakePayment( - WebContents* web_contents, int64_t registration_id, const url::Origin& sw_origin, const std::string& payment_request_id, payments::mojom::CanMakePaymentEventDataPtr event_data, CanMakePaymentCallback callback) = 0; - virtual void AbortPayment(WebContents* web_contents, - int64_t registration_id, + virtual void AbortPayment(int64_t registration_id, const url::Origin& sw_origin, const std::string& payment_request_id, AbortCallback callback) = 0; @@ -90,27 +84,14 @@ // opened window for payment handler at any moment in a browser context. The // previously opened window in the same browser context will be closed after // calling this interface. - virtual void SetOpenedWindow(WebContents* web_contents) = 0; + virtual void SetOpenedWindow() = 0; virtual void CloseOpenedWindow() = 0; // Notify the opened payment handler window is closing or closed by user so as // to abort payment request. virtual void OnClosingOpenedWindow( - WebContents* web_contents, payments::mojom::PaymentEventResponseType reason) = 0; - // Check whether given |sw_js_url| from |manifest_url| is allowed to register - // with |sw_scope|. - virtual bool IsValidInstallablePaymentApp(const GURL& manifest_url, - const GURL& sw_js_url, - const GURL& sw_scope, - std::string* error_message) = 0; - - // Gets the ukm source id for a payment app with |sw_scope|. - // This must ONLY be called when payment app window has been opened. - virtual ukm::SourceId GetSourceIdForPaymentAppFromScope( - const GURL& sw_scope) = 0; - protected: virtual ~PaymentAppProvider() = default; };
diff --git a/content/public/browser/payment_app_provider_util.h b/content/public/browser/payment_app_provider_util.h new file mode 100644 index 0000000..44231b1 --- /dev/null +++ b/content/public/browser/payment_app_provider_util.h
@@ -0,0 +1,30 @@ +// Copyright 2020 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_PUBLIC_BROWSER_PAYMENT_APP_PROVIDER_UTIL_H_ +#define CONTENT_PUBLIC_BROWSER_PAYMENT_APP_PROVIDER_UTIL_H_ + +#include "content/common/content_export.h" +#include "services/metrics/public/cpp/ukm_recorder.h" +#include "third_party/blink/public/mojom/payments/payment_app.mojom.h" + +namespace content { + +class CONTENT_EXPORT PaymentAppProviderUtil { + public: + // Gets the ukm source id for a payment app with |sw_scope|. + // This must ONLY be called when payment app window has been opened. + static ukm::SourceId GetSourceIdForPaymentAppFromScope(const GURL& sw_scope); + + // Check whether given |sw_js_url| from |manifest_url| is allowed to register + // with |sw_scope|. + static bool IsValidInstallablePaymentApp(const GURL& manifest_url, + const GURL& sw_js_url, + const GURL& sw_scope, + std::string* error_message); +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_PAYMENT_APP_PROVIDER_UTIL_H_
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index efd409b..03139e2 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -3443,12 +3443,6 @@ screen_space_rect_received_ = false; } -viz::FrameSinkId SynchronizeVisualPropertiesMessageFilter::GetOrWaitForId() { - // No-op if already quit. - frame_sink_id_run_loop_.Run(); - return frame_sink_id_; -} - viz::LocalSurfaceId SynchronizeVisualPropertiesMessageFilter::WaitForSurfaceId() { surface_id_run_loop_ = std::make_unique<base::RunLoop>(); @@ -3461,13 +3455,11 @@ void SynchronizeVisualPropertiesMessageFilter:: OnSynchronizeFrameHostVisualProperties( - const viz::FrameSinkId& frame_sink_id, const blink::FrameVisualProperties& visual_properties) { - OnSynchronizeVisualProperties(frame_sink_id, visual_properties); + OnSynchronizeVisualProperties(visual_properties); } void SynchronizeVisualPropertiesMessageFilter::OnSynchronizeVisualProperties( - const viz::FrameSinkId& frame_sink_id, const blink::FrameVisualProperties& visual_properties) { // Monitor |is_pinch_gesture_active| to determine when pinch gestures begin // and end. @@ -3508,16 +3500,6 @@ this, visual_properties.local_surface_id_allocation.local_surface_id())); - // Record the received value. We cannot check the current state of the child - // frame, as it can only be processed on the UI thread, and we cannot block - // here. - frame_sink_id_ = frame_sink_id; - - // There can be several updates before a valid viz::FrameSinkId is ready. Do - // not quit |run_loop_| until after we receive a valid one. - if (!frame_sink_id_.is_valid()) - return; - // We can't nest on the IO thread. So tests will wait on the UI thread, so // post there to exit the nesting. GetUIThreadTaskRunner({})->PostTask( @@ -3539,7 +3521,7 @@ } void SynchronizeVisualPropertiesMessageFilter::OnUpdatedFrameSinkIdOnUI() { - frame_sink_id_run_loop_.Quit(); + run_loop_.Quit(); } void SynchronizeVisualPropertiesMessageFilter::OnUpdatedSurfaceIdOnUI(
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 8bae6b28..2079d24 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -1773,11 +1773,6 @@ void WaitForRect(); void ResetRectRunLoop(); - // Returns the new viz::FrameSinkId immediately if the IPC has been received. - // Otherwise this will block the UI thread until it has been received, then it - // will return the new viz::FrameSinkId. - viz::FrameSinkId GetOrWaitForId(); - // Waits for the next viz::LocalSurfaceId be received and returns it. viz::LocalSurfaceId WaitForSurfaceId(); @@ -1791,10 +1786,8 @@ private: void OnSynchronizeFrameHostVisualProperties( - const viz::FrameSinkId& frame_sink_id, const blink::FrameVisualProperties& visual_properties); void OnSynchronizeVisualProperties( - const viz::FrameSinkId& frame_sink_id, const blink::FrameVisualProperties& visual_properties); // |rect| is in DIPs. void OnUpdatedFrameRectOnUI(const gfx::Rect& rect); @@ -1803,8 +1796,7 @@ bool OnMessageReceived(const IPC::Message& message) override; - viz::FrameSinkId frame_sink_id_; - base::RunLoop frame_sink_id_run_loop_; + base::RunLoop run_loop_; std::unique_ptr<base::RunLoop> screen_space_rect_run_loop_; bool screen_space_rect_received_;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 44a3b3a..ba05139 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -295,6 +295,7 @@ "//components/metrics", "//components/metrics:single_sample_metrics", "//components/url_formatter", + "//components/variations:variations_mojom", "//components/variations/net", "//components/viz/client", "//components/viz/common",
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc index 9fd6d11ac..cf4e0aa 100644 --- a/content/renderer/accessibility/render_accessibility_impl.cc +++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -137,9 +137,12 @@ void AXTreeSnapshotterImpl::SnapshotContentTree(ui::AXMode ax_mode, size_t max_node_count, ui::AXTreeUpdate* response) { - WebAXObject root = context_->Root(); - if (!root.MaybeUpdateLayoutAndCheckValidity()) + if (!render_frame_->GetWebFrame()) return; + if (!WebAXObject::MaybeUpdateLayoutAndCheckValidity( + render_frame_->GetWebFrame()->GetDocument())) + return; + WebAXObject root = context_->Root(); BlinkAXTreeSource tree_source(render_frame_, ax_mode); tree_source.SetRoot(root);
diff --git a/content/renderer/net_info_helper.cc b/content/renderer/net_info_helper.cc index 0fb3d94d..c6714af 100644 --- a/content/renderer/net_info_helper.cc +++ b/content/renderer/net_info_helper.cc
@@ -23,6 +23,8 @@ case net::NetworkChangeNotifier::CONNECTION_3G: return blink::kWebConnectionTypeCellular3G; case net::NetworkChangeNotifier::CONNECTION_4G: + // TODO(crbug.com/1127134): Introduce a new WebConnectionType for 5G. + case net::NetworkChangeNotifier::CONNECTION_5G: return blink::kWebConnectionTypeCellular4G; case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH: return blink::kWebConnectionTypeBluetooth;
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 5dd9abf..0827af0 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -571,7 +571,7 @@ // Let the browser know about the updated view rect. Send(new FrameHostMsg_SynchronizeVisualProperties( - routing_id_, frame_sink_id_, pending_visual_properties_)); + routing_id_, pending_visual_properties_)); sent_visual_properties_ = pending_visual_properties_; TRACE_EVENT_WITH_FLOW2(
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 62abc570..316316d 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -714,17 +714,6 @@ return viz::FrameSinkId(RenderThread::Get()->GetClientId(), routing_id()); } -gfx::PointF RenderWidget::ConvertWindowPointToViewport( - const gfx::PointF& point) { - blink::WebFloatRect point_in_viewport(point.x(), point.y(), 0, 0); - ConvertWindowToViewport(&point_in_viewport); - return gfx::PointF(point_in_viewport.x, point_in_viewport.y); -} - -gfx::Point RenderWidget::ConvertWindowPointToViewport(const gfx::Point& point) { - return gfx::ToRoundedPoint(ConvertWindowPointToViewport(gfx::PointF(point))); -} - bool RenderWidget::RequestPointerLock( WebLocalFrame* requester_frame, blink::WebWidgetClient::PointerLockCallback callback,
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 404617d..f0912b1 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -216,8 +216,6 @@ void ConvertViewportToWindow(blink::WebRect* rect) override; void ConvertViewportToWindow(blink::WebFloatRect* rect) override; void ConvertWindowToViewport(blink::WebFloatRect* rect) override; - gfx::Point ConvertWindowPointToViewport(const gfx::Point& point) override; - gfx::PointF ConvertWindowPointToViewport(const gfx::PointF& point) override; bool RequestPointerLock(blink::WebLocalFrame* requester_frame, blink::WebWidgetClient::PointerLockCallback callback, bool request_unadjusted_movement) override;
diff --git a/content/renderer/variations_render_thread_observer.cc b/content/renderer/variations_render_thread_observer.cc index 96c3259b..0163b7c 100644 --- a/content/renderer/variations_render_thread_observer.cc +++ b/content/renderer/variations_render_thread_observer.cc
@@ -19,20 +19,25 @@ // workers) necessitating locking. class VariationsData { public: - void SetVariationsHeader(const std::string& variation_ids_header) { + void SetVariationsHeaders( + variations::mojom::VariationsHeadersPtr variations_headers) { base::AutoLock lock(lock_); - variations_header_ = variation_ids_header; + variations_headers_ = std::move(variations_headers); } // Deliberately returns a copy. - std::string GetVariationsHeader() const { + variations::mojom::VariationsHeadersPtr GetVariationsHeaders() const { base::AutoLock lock(lock_); - return variations_header_; + return variations_headers_.Clone(); } private: mutable base::Lock lock_; - std::string variations_header_ GUARDED_BY(lock_); + + // Stores variations headers that may be appended to eligible requests to + // Google web properties. For more details, see GetClientDataHeaders() in + // variations_ids_provider.h. + variations::mojom::VariationsHeadersPtr variations_headers_ GUARDED_BY(lock_); }; VariationsData* GetVariationsData() { @@ -52,11 +57,13 @@ std::vector<std::unique_ptr<blink::URLLoaderThrottle>>* throttles) { variations::OmniboxURLLoaderThrottle::AppendThrottleIfNeeded(throttles); - std::string variations_header = GetVariationsData()->GetVariationsHeader(); - if (!variations_header.empty()) { + variations::mojom::VariationsHeadersPtr variations_headers = + GetVariationsData()->GetVariationsHeaders(); + + if (!variations_headers.is_null()) { throttles->push_back( std::make_unique<variations::VariationsURLLoaderThrottle>( - std::move(variations_header), top_frame_origin)); + std::move(variations_headers), top_frame_origin)); } } @@ -73,9 +80,9 @@ mojom::RendererVariationsConfiguration::Name_); } -void VariationsRenderThreadObserver::SetVariationsHeader( - const std::string& variation_ids_header) { - GetVariationsData()->SetVariationsHeader(variation_ids_header); +void VariationsRenderThreadObserver::SetVariationsHeaders( + variations::mojom::VariationsHeadersPtr variations_headers) { + GetVariationsData()->SetVariationsHeaders(std::move(variations_headers)); } void VariationsRenderThreadObserver::SetFieldTrialGroup(
diff --git a/content/renderer/variations_render_thread_observer.h b/content/renderer/variations_render_thread_observer.h index c5470b7..fd3e3e4 100644 --- a/content/renderer/variations_render_thread_observer.h +++ b/content/renderer/variations_render_thread_observer.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/macros.h" +#include "components/variations/variations.mojom.h" #include "content/common/renderer_variations_configuration.mojom.h" #include "content/public/renderer/render_thread_observer.h" #include "mojo/public/cpp/bindings/associated_receiver.h" @@ -43,7 +44,8 @@ blink::AssociatedInterfaceRegistry* associated_interfaces) override; // content::mojom::RendererConfiguration: - void SetVariationsHeader(const std::string& variation_ids_header) override; + void SetVariationsHeaders( + variations::mojom::VariationsHeadersPtr variations_headers) override; void SetFieldTrialGroup(const std::string& trial_name, const std::string& group_name) override;
diff --git a/content/web_test/renderer/web_test_content_settings_client.cc b/content/web_test/renderer/web_test_content_settings_client.cc index ede63e66..5d47699b 100644 --- a/content/web_test/renderer/web_test_content_settings_client.cc +++ b/content/web_test/renderer/web_test_content_settings_client.cc
@@ -53,7 +53,8 @@ return allowed; } -bool WebTestContentSettingsClient::AllowStorage(bool enabled_per_settings) { +bool WebTestContentSettingsClient::AllowStorageAccessSync( + StorageType storage_type) { return flags_->storage_allowed(); }
diff --git a/content/web_test/renderer/web_test_content_settings_client.h b/content/web_test/renderer/web_test_content_settings_client.h index 506dc7c1..88e03473 100644 --- a/content/web_test/renderer/web_test_content_settings_client.h +++ b/content/web_test/renderer/web_test_content_settings_client.h
@@ -36,7 +36,7 @@ bool AllowScript(bool enabled_per_settings) override; bool AllowScriptFromSource(bool enabled_per_settings, const blink::WebURL& script_url) override; - bool AllowStorage(bool local) override; + bool AllowStorageAccessSync(StorageType storage_type) override; bool AllowRunningInsecureContent(bool enabled_per_settings, const blink::WebURL& url) override;
diff --git a/docs/chromedriver_status.md b/docs/chromedriver_status.md index c2d5a2ec..4c4a647 100644 --- a/docs/chromedriver_status.md +++ b/docs/chromedriver_status.md
@@ -41,6 +41,7 @@ | GET | /session/{session id}/element/{element id}/rect | Get Element Rect | Complete | | GET | /session/{session id}/element/{element id}/enabled | Is Element Enabled | Complete | | GET | /session/{session id}/element/{element id}/computedlabel | Get Computed Label | Complete | +| GET | /session/{session id}/element/{element id}/computedrole | Get Computed Role | Complete | | POST | /session/{session id}/element/{element id}/click | Element Click | Partially Complete | [1996](https://bugs.chromium.org/p/chromedriver/issues/detail?id=1996) | POST | /session/{session id}/element/{element id}/clear | Element Clear | Complete | | POST | /session/{session id}/element/{element id}/value | Element Send Keys | Partially Complete | [1999](https://bugs.chromium.org/p/chromedriver/issues/detail?id=1999)
diff --git a/docs/privacy_budget_instrumentation.md b/docs/privacy_budget_instrumentation.md index 666dc4e..f098c033 100644 --- a/docs/privacy_budget_instrumentation.md +++ b/docs/privacy_budget_instrumentation.md
@@ -326,6 +326,12 @@ There's no hard rule about this, but the `UseCounter` name is an implementation detail that doesn't belong in the IDL. It also adds unnecessary noise. +*** note +**IMPORTANT** Make sure that each API has its own `UseCounter` name. Otherwise +multiple APIs will have their samples accumulate within the same bucket. This +alters the observed characteristics of the API from what it really is. +*** + <!-- Sort (case insensitive), but don't line-wrap --> [`blink::Document`]: ../third_party/blink/renderer/core/dom/document.h [`blink::ExecutionContext`]: ../third_party/blink/renderer/core/execution_context/execution_context.h
diff --git a/extensions/common/api/automation.idl b/extensions/common/api/automation.idl index 938092ad..e1648057 100644 --- a/extensions/common/api/automation.idl +++ b/extensions/common/api/automation.idl
@@ -341,7 +341,6 @@ // to the tree, each node that's added, removed, or changed, will appear // in exactly one TreeChange, with one of these types. // - // // nodeCreated means that this node was added to the tree and its parent is // new as well, so it's just one node in a new subtree that was added. enum TreeChangeType { @@ -437,27 +436,71 @@ suggestion }; -// The following three enums are associated with an AutomationEvent. +// The following three enums are associated with an $(ref:automation.AutomationIntent). -// A command associated with an AutomationEvent. -enum EventCommandType { +// A command associated with an $(ref:automation.AutomationIntent). +enum IntentCommandType { clearSelection, - cut, delete, dictate, extendSelection, format, + history, insert, marker, moveSelection, - paste, - replace, - setSelection, - type + setSelection }; -// A text boundary associated with an AutomationEvent. -enum EventTextBoundaryType { +// The type of an input event associated with an $(ref:automation.AutomationIntent). It describes an edit +// command, e.g. IntentCommandType.insert, in more detail. +enum IntentInputEventType { + // Insertion. + insertText, + insertLineBreak, + insertParagraph, + insertOrderedList, + insertUnorderedList, + insertHorizontalRule, + insertFromPaste, + insertFromDrop, + insertFromYank, + insertTranspose, + insertReplacementText, + insertCompositionText, + // Deletion. + deleteWordBackward, + deleteWordForward, + deleteSoftLineBackward, + deleteSoftLineForward, + deleteHardLineBackward, + deleteHardLineForward, + deleteContentBackward, + deleteContentForward, + deleteByCut, + deleteByDrag, + // History. + historyUndo, + historyRedo, + // Formatting. + formatBold, + formatItalic, + formatUnderline, + formatStrikeThrough, + formatSuperscript, + formatSubscript, + formatJustifyCenter, + formatJustifyFull, + formatJustifyRight, + formatJustifyLeft, + formatIndent, + formatOutdent, + formatRemove, + formatSetBlockTextDirection +}; + +// A text boundary associated with an $(ref:automation.AutomationIntent). +enum IntentTextBoundaryType { character, format, lineEnd, @@ -479,10 +522,10 @@ wordStartOrEnd }; -// A move direction associated with an AutomationEvent. -enum EventMoveDirectionType { - forward, - backward +// A move direction associated with an $(ref:automation.AutomationIntent). +enum IntentMoveDirectionType { + backward, + forward }; // A sort applied to a table row or column header. @@ -599,14 +642,14 @@ callback QueryCallback = void(AutomationNode node); [nocompile, noinline_doc] dictionary AutomationIntent { - // A command associated with this AutomationEvent. - EventCommandType command; + // A command associated with this AutomationIntent. + IntentCommandType command; - // A text boundary associated with this AutomationEvent. - EventTextBoundaryType textBoundary; + // A text boundary associated with this AutomationIntent. + IntentTextBoundaryType textBoundary; - // A move direction associated with this AutomationEvent. - EventMoveDirectionType moveDirection; + // A move direction associated with this AutomationIntent. + IntentMoveDirectionType moveDirection; }; // An event in the Automation tree. @@ -623,14 +666,15 @@ // The source of this event. DOMString eventFrom; + // Any mouse coordinates associated with this event. long mouseX; long mouseY; - // Intents associated with this event. + // A list of $(ref:automation.AutomationIntent)s associated with this event. AutomationIntent[] intents; // Stops this event from further processing except for any remaining - // listeners on $(ref:AutomationEvent.target). + // listeners on $(ref:automation.AutomationEvent.target). static void stopPropagation(); };
diff --git a/extensions/renderer/api/automation/automation_internal_custom_bindings.cc b/extensions/renderer/api/automation/automation_internal_custom_bindings.cc index 3f6c1897..237620a 100644 --- a/extensions/renderer/api/automation/automation_internal_custom_bindings.cc +++ b/extensions/renderer/api/automation/automation_internal_custom_bindings.cc
@@ -2394,6 +2394,8 @@ for (const auto& intent : event.event_intents) { base::Value dict(base::Value::Type::DICTIONARY); dict.SetKey("command", base::Value(ui::ToString(intent.command))); + dict.SetKey("inputEventType", + base::Value(ui::ToString(intent.input_event_type))); dict.SetKey("textBoundary", base::Value(ui::ToString(intent.text_boundary))); dict.SetKey("moveDirection",
diff --git a/extensions/renderer/resources/automation/automation_event.js b/extensions/renderer/resources/automation/automation_event.js index 88c94d15..22e341d 100644 --- a/extensions/renderer/resources/automation/automation_event.js +++ b/extensions/renderer/resources/automation/automation_event.js
@@ -4,12 +4,15 @@ var utils = require('utils'); -function AutomationEventImpl(type, target, eventFrom) { +function AutomationEventImpl(type, target, eventFrom, mouseX, mouseY, intents) { this.propagationStopped = false; this.type = type; this.target = target; this.eventPhase = Event.NONE; this.eventFrom = eventFrom; + this.mouseX = mouseX; + this.mouseY = mouseY; + this.intents = intents; } AutomationEventImpl.prototype = { @@ -26,11 +29,17 @@ functions: [ 'stopPropagation', ], + properties: [ + 'generatedType', + ], readonly: [ 'type', 'target', 'eventPhase', 'eventFrom', + 'mouseX', + 'mouseY', + 'intents', ], });
diff --git a/extensions/renderer/resources/automation/automation_node.js b/extensions/renderer/resources/automation/automation_node.js index 588e6ca7..2d6f32a 100644 --- a/extensions/renderer/resources/automation/automation_node.js +++ b/extensions/renderer/resources/automation/automation_node.js
@@ -1087,11 +1087,9 @@ $Array.push(path, parent); parent = parent.parent; } - var event = new AutomationEvent(eventType, this.wrapper, eventFrom); + var event = new AutomationEvent(eventType, this.wrapper, eventFrom, mouseX, + mouseY, intents); event.generatedType = generatedEventType; - event.mouseX = mouseX; - event.mouseY = mouseY; - event.intents = intents; // Dispatch the event through the propagation path in three phases: // - capturing: starting from the root and going down to the target's parent
diff --git a/fuchsia/runners/BUILD.gn b/fuchsia/runners/BUILD.gn index 80103aa..9cc7578f 100644 --- a/fuchsia/runners/BUILD.gn +++ b/fuchsia/runners/BUILD.gn
@@ -76,13 +76,17 @@ "//base", "//components/cast/named_message_port_connector:named_message_port_connector", "//fuchsia/base", - "//fuchsia/base:message_port", "//fuchsia/base:modular", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.modular", "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp", "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", "//url", ] + + # TODO(crbug.com/1131102): Remove dep when MessagePortProxy lands, and add assertions to ensure + # that Blink indirect deps don't creep back in. + deps += [ "//fuchsia/base:message_port" ] + public_deps = [ ":common", "//fuchsia:cast_fidl", @@ -100,8 +104,10 @@ ":common", "//base", "//fuchsia/base", - "//mojo/core/embedder", # TODO(crbug.com/1126571): Remove when MPP lands. + "//mojo/core/embedder", # TODO(crbug.com/1126571): Remove when + # MessagePortProxy lands. ] + data_deps = [ ":cast_runner_core" ] visibility = [ ":*" ] } @@ -110,6 +116,18 @@ binary = ":cast_runner_exe" package_name_override = "cast_runner" manifest = "cast/cast_runner.cmx" + + # TODO(crbug.com/1131102): Remove these exclusions when MessagePortProxy lands. + excluded_files = [ + "lib/libEGL.so", + "lib/libfuchsia_egl.so", + "lib/libGLESv2.so", + "lib/libswiftshader_libEGL.so", + "lib/libswiftshader_libGLESv2.so", + "lib/libtrace-engine.so", + "lib/libvulkan.so", + "lib/VkLayer_image_pipe_swapchain.so", + ] } fuchsia_package_runner("cast_runner") { @@ -166,7 +184,8 @@ "//base/test:run_all_unittests", "//base/test:test_support", "//fuchsia/base:test_support", - "//mojo/core/embedder", # TODO(crbug.com/1126571): Remove when MPP lands. + "//mojo/core/embedder", # TODO(crbug.com/1126571): Remove when + # MessagePortProxy lands. "//net:test_support", "//testing/gtest", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.camera3",
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc index 44800465..45558ea 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
@@ -240,6 +240,7 @@ } gl::GLImage* GetGLImage() override { return gl_image_; } + std::unique_ptr<gfx::GpuFence> GetReadFence() override { return nullptr; } gl::GLImage* gl_image_ = nullptr; };
diff --git a/gpu/command_buffer/service/shared_image_backing_gl_image.cc b/gpu/command_buffer/service/shared_image_backing_gl_image.cc index 6f8ff6e..0318fd9 100644 --- a/gpu/command_buffer/service/shared_image_backing_gl_image.cc +++ b/gpu/command_buffer/service/shared_image_backing_gl_image.cc
@@ -73,14 +73,20 @@ } bool SharedImageRepresentationGLTextureImpl::BeginAccess(GLenum mode) { + DCHECK(mode_ == 0); + mode_ = mode; if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM) return client_->SharedImageRepresentationGLTextureBeginAccess(); return true; } void SharedImageRepresentationGLTextureImpl::EndAccess() { + DCHECK(mode_ != 0); + GLenum current_mode = mode_; + mode_ = 0; if (client_) - return client_->SharedImageRepresentationGLTextureEndAccess(); + return client_->SharedImageRepresentationGLTextureEndAccess( + current_mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); } /////////////////////////////////////////////////////////////////////////////// @@ -111,14 +117,20 @@ bool SharedImageRepresentationGLTexturePassthroughImpl::BeginAccess( GLenum mode) { + DCHECK(mode_ == 0); + mode_ = mode; if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM) return client_->SharedImageRepresentationGLTextureBeginAccess(); return true; } void SharedImageRepresentationGLTexturePassthroughImpl::EndAccess() { + DCHECK(mode_ != 0); + GLenum current_mode = mode_; + mode_ = 0; if (client_) - return client_->SharedImageRepresentationGLTextureEndAccess(); + return client_->SharedImageRepresentationGLTextureEndAccess( + current_mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); } /////////////////////////////////////////////////////////////////////////////// @@ -191,7 +203,7 @@ write_surface_ = nullptr; if (client_) - client_->SharedImageRepresentationGLTextureEndAccess(); + client_->SharedImageRepresentationGLTextureEndAccess(false /* readonly */); } sk_sp<SkPromiseImageTexture> SharedImageRepresentationSkiaImpl::BeginReadAccess( @@ -208,7 +220,7 @@ void SharedImageRepresentationSkiaImpl::EndReadAccess() { if (client_) - client_->SharedImageRepresentationGLTextureEndAccess(); + client_->SharedImageRepresentationGLTextureEndAccess(true /* readonly */); } bool SharedImageRepresentationSkiaImpl::SupportsMultipleConcurrentReadAccess() { @@ -246,6 +258,12 @@ return gl_image_.get(); } +std::unique_ptr<gfx::GpuFence> +SharedImageRepresentationOverlayImpl::GetReadFence() { + auto* gl_backing = static_cast<SharedImageBackingGLImage*>(backing()); + return gl_backing->GetLastWriteGpuFence(); +} + /////////////////////////////////////////////////////////////////////////////// // SharedImageBackingGLImage @@ -359,6 +377,11 @@ return 0; } +std::unique_ptr<gfx::GpuFence> +SharedImageBackingGLImage::GetLastWriteGpuFence() { + return last_write_gl_fence_ ? last_write_gl_fence_->GetGpuFence() : nullptr; +} + scoped_refptr<gfx::NativePixmap> SharedImageBackingGLImage::GetNativePixmap() { return image_->GetNativePixmap(); } @@ -563,7 +586,8 @@ return BindOrCopyImageIfNeeded(); } -void SharedImageBackingGLImage::SharedImageRepresentationGLTextureEndAccess() { +void SharedImageBackingGLImage::SharedImageRepresentationGLTextureEndAccess( + bool readonly) { #if defined(OS_MAC) // If this image could potentially be shared with Metal via WebGPU, then flush // the GL context to ensure Metal will see it. @@ -587,6 +611,14 @@ image_bind_or_copy_needed_ = true; } } +#else + // If the image will be used for an overlay, we insert a fence that can be + // used by OutputPresenter to synchronize image writes with presentation. + if (!readonly && usage() & SHARED_IMAGE_USAGE_SCANOUT && + gl::GLFence::IsGpuFenceSupported()) { + last_write_gl_fence_ = gl::GLFence::CreateForGpuFence(); + DCHECK(last_write_gl_fence_); + } #endif }
diff --git a/gpu/command_buffer/service/shared_image_backing_gl_image.h b/gpu/command_buffer/service/shared_image_backing_gl_image.h index 0100964..39a7b45 100644 --- a/gpu/command_buffer/service/shared_image_backing_gl_image.h +++ b/gpu/command_buffer/service/shared_image_backing_gl_image.h
@@ -8,6 +8,7 @@ #include "gpu/command_buffer/service/shared_image_backing.h" #include "gpu/command_buffer/service/shared_image_backing_gl_common.h" #include "gpu/gpu_gles2_export.h" +#include "ui/gl/gl_fence.h" namespace gpu { @@ -16,7 +17,7 @@ class SharedImageRepresentationGLTextureClient { public: virtual bool SharedImageRepresentationGLTextureBeginAccess() = 0; - virtual void SharedImageRepresentationGLTextureEndAccess() = 0; + virtual void SharedImageRepresentationGLTextureEndAccess(bool readonly) = 0; virtual void SharedImageRepresentationGLTextureRelease(bool have_context) = 0; }; @@ -41,6 +42,7 @@ SharedImageRepresentationGLTextureClient* const client_ = nullptr; gles2::Texture* texture_; + GLenum mode_ = 0; }; // Representation of a SharedImageBackingGLTexture or @@ -69,6 +71,7 @@ SharedImageRepresentationGLTextureClient* const client_ = nullptr; scoped_refptr<gles2::TexturePassthrough> texture_passthrough_; + GLenum mode_ = 0; }; // Skia representation for both SharedImageBackingGLCommon. @@ -131,6 +134,7 @@ bool BeginReadAccess() override; void EndReadAccess() override; gl::GLImage* GetGLImage() override; + std::unique_ptr<gfx::GpuFence> GetReadFence() override; scoped_refptr<gl::GLImage> gl_image_; }; @@ -163,6 +167,7 @@ GLenum GetGLTarget() const; GLuint GetGLServiceId() const; + std::unique_ptr<gfx::GpuFence> GetLastWriteGpuFence(); private: // SharedImageBacking: @@ -198,7 +203,7 @@ // SharedImageRepresentationGLTextureClient: bool SharedImageRepresentationGLTextureBeginAccess() override; - void SharedImageRepresentationGLTextureEndAccess() override; + void SharedImageRepresentationGLTextureEndAccess(bool readonly) override; void SharedImageRepresentationGLTextureRelease(bool have_context) override; bool IsPassthrough() const { return is_passthrough_; } @@ -228,6 +233,7 @@ scoped_refptr<gles2::TexturePassthrough> passthrough_texture_; sk_sp<SkPromiseImageTexture> cached_promise_texture_; + std::unique_ptr<gl::GLFence> last_write_gl_fence_; base::WeakPtrFactory<SharedImageBackingGLImage> weak_factory_; };
diff --git a/gpu/command_buffer/service/shared_image_backing_gl_texture.cc b/gpu/command_buffer/service/shared_image_backing_gl_texture.cc index bb72877..308d6d7 100644 --- a/gpu/command_buffer/service/shared_image_backing_gl_texture.cc +++ b/gpu/command_buffer/service/shared_image_backing_gl_texture.cc
@@ -424,7 +424,9 @@ const bool use_buffer = usage & SHARED_IMAGE_USAGE_SCANOUT; #endif if (use_buffer && !format_info.allow_scanout) { - LOG(ERROR) << "CreateSharedImage: SCANOUT shared images unavailable"; + LOG(ERROR) << "CreateSharedImage: SCANOUT shared images unavailable. " + "Buffer format= " + << gfx::BufferFormatToString(format_info.buffer_format); return nullptr; }
diff --git a/gpu/command_buffer/service/shared_image_representation.cc b/gpu/command_buffer/service/shared_image_representation.cc index 55d76297..e5ddefc 100644 --- a/gpu/command_buffer/service/shared_image_representation.cc +++ b/gpu/command_buffer/service/shared_image_representation.cc
@@ -8,6 +8,7 @@ #include "gpu/command_buffer/service/texture_manager.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" #include "third_party/skia/include/gpu/GrDirectContext.h" +#include "ui/gl/gl_fence.h" #if defined(OS_ANDROID) #include "base/android/scoped_hardware_buffer_fence_sync.h" @@ -227,8 +228,15 @@ SharedImageRepresentationOverlay::ScopedReadAccess::ScopedReadAccess( util::PassKey<SharedImageRepresentationOverlay> pass_key, SharedImageRepresentationOverlay* representation, - gl::GLImage* gl_image) - : ScopedAccessBase(representation), gl_image_(gl_image) {} + gl::GLImage* gl_image, + std::unique_ptr<gfx::GpuFence> fence) + : ScopedAccessBase(representation), + gl_image_(gl_image), + fence_(std::move(fence)) {} + +SharedImageRepresentationOverlay::ScopedReadAccess::~ScopedReadAccess() { + representation()->EndReadAccess(); +} std::unique_ptr<SharedImageRepresentationOverlay::ScopedReadAccess> SharedImageRepresentationOverlay::BeginScopedReadAccess(bool needs_gl_image) { @@ -244,7 +252,7 @@ return std::make_unique<ScopedReadAccess>( util::PassKey<SharedImageRepresentationOverlay>(), this, - needs_gl_image ? GetGLImage() : nullptr); + needs_gl_image ? GetGLImage() : nullptr, GetReadFence()); } SharedImageRepresentationDawn::ScopedAccess::ScopedAccess(
diff --git a/gpu/command_buffer/service/shared_image_representation.h b/gpu/command_buffer/service/shared_image_representation.h index 626f610a..2ca5a05 100644 --- a/gpu/command_buffer/service/shared_image_representation.h +++ b/gpu/command_buffer/service/shared_image_representation.h
@@ -392,20 +392,22 @@ MemoryTypeTracker* tracker) : SharedImageRepresentation(manager, backing, tracker) {} - class ScopedReadAccess + class GPU_GLES2_EXPORT ScopedReadAccess : public ScopedAccessBase<SharedImageRepresentationOverlay> { public: ScopedReadAccess(util::PassKey<SharedImageRepresentationOverlay> pass_key, SharedImageRepresentationOverlay* representation, - gl::GLImage* gl_image); - ~ScopedReadAccess() { representation()->EndReadAccess(); } + gl::GLImage* gl_image, + std::unique_ptr<gfx::GpuFence> fence); + ~ScopedReadAccess(); - gl::GLImage* gl_image() const { - return gl_image_; - } + gl::GLImage* gl_image() const { return gl_image_; } + + std::unique_ptr<gfx::GpuFence> TakeFence() { return std::move(fence_); } private: gl::GLImage* gl_image_; + std::unique_ptr<gfx::GpuFence> fence_; }; #if defined(OS_ANDROID) @@ -426,6 +428,9 @@ // TODO(penghuang): Refactor it to not depend on GL. // Get the backing as GLImage for GLSurface::ScheduleOverlayPlane. virtual gl::GLImage* GetGLImage() = 0; + // Optionally returns a fence to synchronize writes on the SharedImage with + // overlay presentation. + virtual std::unique_ptr<gfx::GpuFence> GetReadFence() = 0; }; // An interface that allows a SharedImageBacking to hold a reference to VA-API
diff --git a/gpu/command_buffer/service/shared_image_representation_d3d.cc b/gpu/command_buffer/service/shared_image_representation_d3d.cc index 4afcd6c1..afde8952 100644 --- a/gpu/command_buffer/service/shared_image_representation_d3d.cc +++ b/gpu/command_buffer/service/shared_image_representation_d3d.cc
@@ -150,4 +150,9 @@ return static_cast<SharedImageBackingD3D*>(backing())->GetGLImage(); } +std::unique_ptr<gfx::GpuFence> +SharedImageRepresentationOverlayD3D::GetReadFence() { + return nullptr; +} + } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_representation_d3d.h b/gpu/command_buffer/service/shared_image_representation_d3d.h index c73d4c7f..164b974 100644 --- a/gpu/command_buffer/service/shared_image_representation_d3d.h +++ b/gpu/command_buffer/service/shared_image_representation_d3d.h
@@ -81,6 +81,7 @@ void EndReadAccess() override; gl::GLImage* GetGLImage() override; + std::unique_ptr<gfx::GpuFence> GetReadFence() override; }; } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_video.cc b/gpu/command_buffer/service/shared_image_video.cc index 6b7ebfe..9cb70be 100644 --- a/gpu/command_buffer/service/shared_image_video.cc +++ b/gpu/command_buffer/service/shared_image_video.cc
@@ -433,6 +433,8 @@ return stream_image_.get(); } + std::unique_ptr<gfx::GpuFence> GetReadFence() override { return nullptr; } + void NotifyOverlayPromotion(bool promotion, const gfx::Rect& bounds) override { stream_image_->NotifyOverlayPromotion(promotion, bounds);
diff --git a/gpu/command_buffer/service/test_shared_image_backing.cc b/gpu/command_buffer/service/test_shared_image_backing.cc index ab09c2f9..d51e7bd7 100644 --- a/gpu/command_buffer/service/test_shared_image_backing.cc +++ b/gpu/command_buffer/service/test_shared_image_backing.cc
@@ -118,6 +118,7 @@ bool BeginReadAccess() override { return true; } void EndReadAccess() override {} gl::GLImage* GetGLImage() override { return nullptr; } + std::unique_ptr<gfx::GpuFence> GetReadFence() override { return nullptr; } #if defined(OS_ANDROID) void NotifyOverlayPromotion(bool promotion,
diff --git a/gpu/vulkan/x/vulkan_implementation_x11.cc b/gpu/vulkan/x/vulkan_implementation_x11.cc index 2965a1d..7f45842 100644 --- a/gpu/vulkan/x/vulkan_implementation_x11.cc +++ b/gpu/vulkan/x/vulkan_implementation_x11.cc
@@ -16,6 +16,7 @@ #include "gpu/vulkan/vulkan_surface.h" #include "gpu/vulkan/vulkan_util.h" #include "gpu/vulkan/x/vulkan_surface_x11.h" +#include "ui/base/x/x11_util.h" #include "ui/gfx/gpu_fence.h" #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/x/x11.h" @@ -25,43 +26,6 @@ namespace { -bool IsVulkanSurfaceSupported() { - static const char* extensions[] = { - "DRI3", // open source driver. - "ATIFGLRXDRI", // AMD proprietary driver. - "NV-CONTROL", // NVidia proprietary driver. - }; - auto* display = gfx::GetXDisplay(); - int ext_code, first_event, first_error; - for (const auto* extension : extensions) { - if (XQueryExtension(display, extension, &ext_code, &first_event, - &first_error)) { - return true; - } - } - return false; -} - -class ScopedUnsetDisplay { - public: - ScopedUnsetDisplay() { - const char* display = getenv("DISPLAY"); - if (display) { - display_.emplace(display); - unsetenv("DISPLAY"); - } - } - ~ScopedUnsetDisplay() { - if (display_) { - setenv("DISPLAY", display_->c_str(), 1); - } - } - - private: - base::Optional<std::string> display_; - DISALLOW_COPY_AND_ASSIGN(ScopedUnsetDisplay); -}; - bool InitializeVulkanFunctionPointers( const base::FilePath& path, VulkanFunctionPointers* vulkan_function_pointers) { @@ -81,12 +45,12 @@ VulkanImplementationX11::~VulkanImplementationX11() = default; bool VulkanImplementationX11::InitializeVulkanInstance(bool using_surface) { - if (using_surface && !use_swiftshader() && !IsVulkanSurfaceSupported()) + if (using_surface && !use_swiftshader() && !ui::IsVulkanSurfaceSupported()) using_surface = false; using_surface_ = using_surface; // Unset DISPLAY env, so the vulkan can be initialized successfully, if the X // server doesn't support Vulkan surface. - base::Optional<ScopedUnsetDisplay> unset_display; + base::Optional<ui::ScopedUnsetDisplay> unset_display; if (!using_surface_) unset_display.emplace();
diff --git a/infra/config/generated/commit-queue.cfg b/infra/config/generated/commit-queue.cfg index 9ee7da1..9a5a792 100644 --- a/infra/config/generated/commit-queue.cfg +++ b/infra/config/generated/commit-queue.cfg
@@ -1121,6 +1121,10 @@ includable_only: true } builders { + name: "chromium/try/linux-wpt-payments-fyi-rel" + includable_only: true + } + builders { name: "chromium/try/linux_android_dbg_ng" includable_only: true }
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 0ac3dcc..6c1b28c 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -11341,6 +11341,36 @@ } } builders { + name: "linux-wpt-payments-fyi-rel" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + cmd: "recipes" + } + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" + execution_timeout_secs: 36000 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experimental: YES + resultdb { + enable: true + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + } + } + builders { name: "mac-archive-dbg" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -24160,6 +24190,43 @@ } } builders { + name: "linux-wpt-payments-fyi-rel" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + cmd: "recipes" + } + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" + execution_timeout_secs: 14400 + expiration_secs: 7200 + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + resultdb { + enable: true + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + } + } + builders { name: "linux_android_dbg_ng" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper"
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg index aaa06cf1..673421e 100644 --- a/infra/config/generated/luci-milo.cfg +++ b/infra/config/generated/luci-milo.cfg
@@ -6686,6 +6686,10 @@ category: "linux" } builders { + name: "buildbucket/luci.chromium.ci/linux-wpt-payments-fyi-rel" + category: "linux" + } + builders { name: "buildbucket/luci.chromium.ci/Leak Detection Linux" category: "linux" short_name: "lk" @@ -12691,6 +12695,9 @@ name: "buildbucket/luci.chromium.try/linux-wpt-identity-fyi-rel" } builders { + name: "buildbucket/luci.chromium.try/linux-wpt-payments-fyi-rel" + } + builders { name: "buildbucket/luci.chromium.try/linux_android_dbg_ng" } builders { @@ -13482,6 +13489,9 @@ name: "buildbucket/luci.chromium.try/linux-wpt-identity-fyi-rel" } builders { + name: "buildbucket/luci.chromium.try/linux-wpt-payments-fyi-rel" + } + builders { name: "buildbucket/luci.chromium.try/linux_chromium_analysis" } builders {
diff --git a/infra/config/generated/luci-scheduler.cfg b/infra/config/generated/luci-scheduler.cfg index 1c3dd02..f13228a 100644 --- a/infra/config/generated/luci-scheduler.cfg +++ b/infra/config/generated/luci-scheduler.cfg
@@ -9174,6 +9174,16 @@ } } job { + id: "ci-linux-wpt-payments-fyi-rel" + realm: "ci" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "linux-wpt-payments-fyi-rel" + } +} +job { id: "ci-m85-Android Release (Nexus 5X)" realm: "ci-m85" acl_sets: "ci-m85" @@ -11410,6 +11420,16 @@ } } job { + id: "linux-wpt-payments-fyi-rel" + realm: "ci" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "linux-wpt-payments-fyi-rel" + } +} +job { id: "linux_chromium_bot_db_exporter" realm: "findit" schedule: "0 0,6,12,18 * * *" @@ -12383,6 +12403,7 @@ triggers: "linux-win_cross-rel" triggers: "linux-wpt-fyi-rel" triggers: "linux-wpt-identity-fyi-rel" + triggers: "linux-wpt-payments-fyi-rel" triggers: "mac-archive-dbg" triggers: "mac-archive-rel" triggers: "mac-arm64-rel"
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index 7a093db2..f94b8be 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -2538,6 +2538,15 @@ goma_backend = goma.backend.RBE_PROD, ) +ci.fyi_builder( + name = "linux-wpt-payments-fyi-rel", + console_view_entry = ci.console_view_entry( + category = "linux", + ), + experimental = True, + goma_backend = goma.backend.RBE_PROD, +) + # This is launching & collecting entirely isolated tests. # OS shouldn't matter. ci.fyi_builder(
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index 976de16..262f7c3 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -939,6 +939,10 @@ ) try_.chromium_linux_builder( + name = "linux-wpt-payments-fyi-rel", +) + +try_.chromium_linux_builder( name = "linux_chromium_analysis", )
diff --git a/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm b/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm index 92a014f4..121fcd3d 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm +++ b/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm
@@ -86,6 +86,8 @@ return net::NetworkChangeNotifier::CONNECTION_NONE; case 7: return net::NetworkChangeNotifier::CONNECTION_BLUETOOTH; + case 8: + return net::NetworkChangeNotifier::CONNECTION_5G; default: return net::NetworkChangeNotifier::CONNECTION_UNKNOWN; } @@ -93,9 +95,16 @@ // Gives the differents expected value based on scenario number. int getExpectedValue(int number) { - if (number > 2 && number < 6) - return 0; - return 1; + // Cellular network types are expected to return 0. + switch (getConnectionType(number)) { + case net::NetworkChangeNotifier::CONNECTION_2G: + case net::NetworkChangeNotifier::CONNECTION_3G: + case net::NetworkChangeNotifier::CONNECTION_4G: + case net::NetworkChangeNotifier::CONNECTION_5G: + return 0; + default: + return 1; + } } using MetricsMediatorTest = PlatformTest; @@ -107,7 +116,7 @@ MetricsMediatorMock* mock_metrics_helper = [[MetricsMediatorMock alloc] init]; // Checks all different scenarios. - for (int i = 0; i < 8; ++i) { + for (int i = 0; i < 9; ++i) { [mock_metrics_helper reset]; [mock_metrics_helper connectionTypeChanged:getConnectionType(i)]; EXPECT_EQ(getExpectedValue(i), [mock_metrics_helper reportingValue]); @@ -115,7 +124,7 @@ } // Checks that no new ConnectionType has been added. - EXPECT_EQ(net::NetworkChangeNotifier::CONNECTION_BLUETOOTH, + EXPECT_EQ(net::NetworkChangeNotifier::CONNECTION_5G, net::NetworkChangeNotifier::CONNECTION_LAST); }
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index 1249e62..35df37c 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn
@@ -106,7 +106,6 @@ "//ios/chrome/browser/ui/coordinators:chrome_coordinators", "//ios/chrome/browser/ui/fullscreen:feature_flags", "//ios/chrome/browser/ui/omnibox", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/toolbar_container:feature_flags", "//ios/chrome/browser/web:feature_flags", "//ios/chrome/common",
diff --git a/ios/chrome/browser/crash_report/synthetic_crash_report_util.mm b/ios/chrome/browser/crash_report/synthetic_crash_report_util.mm index 36b54a6b..f618c15 100644 --- a/ios/chrome/browser/crash_report/synthetic_crash_report_util.mm +++ b/ios/chrome/browser/crash_report/synthetic_crash_report_util.mm
@@ -8,7 +8,6 @@ #include "base/files/memory_mapped_file.h" #include "base/ios/device_util.h" -#include "base/metrics/histogram_macros.h" #include "base/notreached.h" #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" @@ -100,7 +99,4 @@ std::strcpy(reinterpret_cast<char*>(mapped_config_file.data()), config_string.data()); } - - UMA_STABILITY_HISTOGRAM_BOOLEAN( - "Stability.iOS.UTE.CreatedSyntheticCrashReportConfig", created_config); }
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn index c3d7346e..db054b3a 100644 --- a/ios/chrome/browser/flags/BUILD.gn +++ b/ios/chrome/browser/flags/BUILD.gn
@@ -59,7 +59,6 @@ "//ios/chrome/browser/ui/settings/autofill:feature_flags", "//ios/chrome/browser/ui/tab_grid:features", "//ios/chrome/browser/ui/table_view:feature_flags", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/toolbar_container:feature_flags", "//ios/chrome/browser/web:feature_flags", "//ios/public/provider/chrome/browser",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 13c06f2..602f080f 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -72,7 +72,6 @@ #include "ios/chrome/browser/ui/settings/autofill/features.h" #import "ios/chrome/browser/ui/tab_grid/features.h" #import "ios/chrome/browser/ui/table_view/feature_flags.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/toolbar_container/toolbar_container_features.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/web/features.h" @@ -317,12 +316,6 @@ flag_descriptions::kAutofillIOSDelayBetweenFieldsName, flag_descriptions::kAutofillIOSDelayBetweenFieldsDescription, flags_ui::kOsIos, MULTI_VALUE_TYPE(kAutofillIOSDelayBetweenFieldsChoices)}, - {"autofill-show-all-profiles-on-prefilled-forms", - flag_descriptions::kAutofillShowAllSuggestionsOnPrefilledFormsName, - flag_descriptions::kAutofillShowAllSuggestionsOnPrefilledFormsDescription, - flags_ui::kOsIos, - FEATURE_VALUE_TYPE( - autofill::features::kAutofillShowAllSuggestionsOnPrefilledForms)}, {"autofill-restrict-formless-form-extraction", flag_descriptions::kAutofillRestrictUnownedFieldsToFormlessCheckoutName, flag_descriptions:: @@ -527,10 +520,6 @@ flag_descriptions::kSSLCommittedInterstitialsName, flag_descriptions::kSSLCommittedInterstitialsDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(web::features::kSSLCommittedInterstitials)}, - {"change-tab-switcher-position", - flag_descriptions::kChangeTabSwitcherPositionName, - flag_descriptions::kChangeTabSwitcherPositionDescription, flags_ui::kOsIos, - FEATURE_VALUE_TYPE(kChangeTabSwitcherPosition)}, {"fullscreen-controller-browser-scoped", flag_descriptions::kFullscreenControllerBrowserScopedName, flag_descriptions::kFullscreenControllerBrowserScopedDescription, @@ -694,6 +683,11 @@ flag_descriptions::kAutofillUseRendererIDsDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE( autofill::features::kAutofillUseUniqueRendererIDsOnIOS)}, + {"restore-gaia-cookies-if-deleted", + flag_descriptions::kRestoreGaiaCookiesIfDeletedName, + flag_descriptions::kRestoreGaiaCookiesIfDeletedDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE(signin::kRestoreGaiaCookiesIfDeleted)}, }; bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index a17a7397..3616ae7f 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -103,12 +103,6 @@ "When enabled and saving a credit card to Google Payments, a dialog is " "displayed that allows editing the card info before confirming save."; -const char kAutofillShowAllSuggestionsOnPrefilledFormsName[] = - "Enable showing all suggestions when focusing prefilled field"; -const char kAutofillShowAllSuggestionsOnPrefilledFormsDescription[] = - "When enabled: show all suggestions when the focused field value has not " - "been entered by the user. When disabled: use the field value as a filter."; - const char kAutofillRestrictUnownedFieldsToFormlessCheckoutName[] = "Restrict formless form extraction"; const char kAutofillRestrictUnownedFieldsToFormlessCheckoutDescription[] = @@ -155,12 +149,6 @@ "disabled, initial upload is delayed until deferred initialization. This " "does not affect recovery mode."; -extern const char kChangeTabSwitcherPositionName[] = - "Change tab switcher button position"; -extern const char kChangeTabSwitcherPositionDescription[] = - "When enable, the tab switcher button position changes from tab strip to " - "toolbar and bookmark button is removed."; - const char kCollectionsCardPresentationStyleName[] = "Card style presentation for Collections."; const char kCollectionsCardPresentationStyleDescription[] = @@ -424,6 +412,12 @@ "When enabled, the first time the renderer crashes, the page is reloaded " "instead of showing the SadTab"; +const char kRestoreGaiaCookiesIfDeletedName[] = + "Restore GAIA cookies if deleted"; +const char kRestoreGaiaCookiesIfDeletedDescription[] = + "When enabled, will restore GAIA cookies for signed-in Chrome users if " + "they are deleted."; + const char kSafeBrowsingAvailableName[] = "Make Safe Browsing available"; const char kSafeBrowsingAvailableDescription[] = "When enabled, navigation URLs are compared to Safe Browsing blocklists, "
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index d08fcac4..5248564 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -76,11 +76,6 @@ extern const char kAutofillSaveCardInfobarEditSupportName[]; extern const char kAutofillSaveCardInfobarEditSupportDescription[]; -// Title and description for the flag to control if prefilled value filter -// profiles. -extern const char kAutofillShowAllSuggestionsOnPrefilledFormsName[]; -extern const char kAutofillShowAllSuggestionsOnPrefilledFormsDescription[]; - // Title and description for the flag to restrict extraction of formless forms // to checkout flows. extern const char kAutofillRestrictUnownedFieldsToFormlessCheckoutName[]; @@ -122,10 +117,6 @@ extern const char kBreakpadNoDelayInitialUploadName[]; extern const char kBreakpadNoDelayInitialUploadDescription[]; -// Title and description for the flag that controls the tab switcher position. -extern const char kChangeTabSwitcherPositionName[]; -extern const char kChangeTabSwitcherPositionDescription[]; - // Title and description for the flag that controls whether Collections are // presented using the new iOS13 Card style or the custom legacy one. extern const char kCollectionsCardPresentationStyleName[]; @@ -473,6 +464,9 @@ extern const char kWellKnownChangePasswordName[]; extern const char kWellKnownChangePasswordDescription[]; +extern const char kRestoreGaiaCookiesIfDeletedName[]; +extern const char kRestoreGaiaCookiesIfDeletedDescription[]; + // Please add names and descriptions above in alphabetical order. } // namespace flag_descriptions
diff --git a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc index a946ea7..d965040 100644 --- a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc +++ b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc
@@ -44,7 +44,6 @@ #include "ios/chrome/browser/json_parser/in_process_json_parser.h" #include "ios/chrome/browser/pref_names.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" -#include "ios/chrome/browser/ui/util/ui_util.h" #include "ios/chrome/common/channel_info.h" #include "ios/web/public/browser_state.h" #include "net/url_request/url_request_context_getter.h"
diff --git a/ios/chrome/browser/signin/gaia_auth_fetcher_ios.h b/ios/chrome/browser/signin/gaia_auth_fetcher_ios.h index 64da9f2..19094839 100644 --- a/ios/chrome/browser/signin/gaia_auth_fetcher_ios.h +++ b/ios/chrome/browser/signin/gaia_auth_fetcher_ios.h
@@ -34,17 +34,6 @@ : public GaiaAuthFetcher, public GaiaAuthFetcherIOSBridge::GaiaAuthFetcherIOSBridgeDelegate { public: - // Sets whether the iOS specialization of the GaiaAuthFetcher should be used. - // Mainly used for testing. - // Note that if |should_use| is true, it might still not be used if it is - // unnecessary or WKWebView isn't enabled. - static void SetShouldUseGaiaAuthFetcherIOSForTesting( - bool use_gaia_fetcher_ios); - - // Returns whether the iOS specialization of the GaiaAuthFetcher should be - // used. - static bool ShouldUseGaiaAuthFetcherIOS(); - GaiaAuthFetcherIOS( GaiaAuthConsumer* consumer, gaia::GaiaSource source,
diff --git a/ios/chrome/browser/signin/gaia_auth_fetcher_ios.mm b/ios/chrome/browser/signin/gaia_auth_fetcher_ios.mm index 93b7cd48..41256e08 100644 --- a/ios/chrome/browser/signin/gaia_auth_fetcher_ios.mm +++ b/ios/chrome/browser/signin/gaia_auth_fetcher_ios.mm
@@ -16,13 +16,6 @@ #error "This file requires ARC support." #endif -namespace { - -// Whether the iOS specialization of the GaiaAuthFetcher should be used. -bool g_should_use_gaia_auth_fetcher_ios = true; - -} // namespace - GaiaAuthFetcherIOS::GaiaAuthFetcherIOS( GaiaAuthConsumer* consumer, gaia::GaiaSource source, @@ -45,7 +38,7 @@ bool cookies_required = credentials_mode != network::mojom::CredentialsMode::kOmit; - if (!ShouldUseGaiaAuthFetcherIOS() || !cookies_required) { + if (!cookies_required) { GaiaAuthFetcher::CreateAndStartGaiaFetcher(body, body_content_type, headers, gaia_gurl, credentials_mode, traffic_annotation); @@ -81,12 +74,3 @@ SetPendingFetch(false); DispatchFetchedRequest(url, data, net_error, response_code); } - -void GaiaAuthFetcherIOS::SetShouldUseGaiaAuthFetcherIOSForTesting( - bool use_gaia_fetcher_ios) { - g_should_use_gaia_auth_fetcher_ios = use_gaia_fetcher_ios; -} - -bool GaiaAuthFetcherIOS::ShouldUseGaiaAuthFetcherIOS() { - return g_should_use_gaia_auth_fetcher_ios; -}
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm index 3e6c737e..55ee860 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm
@@ -80,34 +80,16 @@ // Verify the bookmark is set. [BookmarkEarlGrey verifyBookmarksWithTitle:bookmarkTitle expectedCount:1]; - // Verify the star is lit. - if (![ChromeEarlGrey isCompactWidth] && - ![ChromeEarlGrey isChangeTabSwitcherPositionEnabled]) { - [[EarlGrey - selectElementWithMatcher:grey_accessibilityLabel( - l10n_util::GetNSString(IDS_TOOLTIP_STAR))] - assertWithMatcher:grey_notNil()]; - } - // Open the BookmarkEditor. - if ([ChromeEarlGrey isCompactWidth] || - [ChromeEarlGrey isChangeTabSwitcherPositionEnabled]) { - [ChromeEarlGreyUI openToolsMenu]; - [[[EarlGrey - selectElementWithMatcher:grey_allOf(grey_accessibilityID( - kToolsMenuEditBookmark), - grey_sufficientlyVisible(), nil)] - usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 200) - onElementWithMatcher:grey_accessibilityID( - kPopupMenuToolsMenuTableViewId)] - performAction:grey_tap()]; - } else { - [[EarlGrey - selectElementWithMatcher:grey_accessibilityLabel( - l10n_util::GetNSString(IDS_TOOLTIP_STAR))] - performAction:grey_tap()]; - } + [ChromeEarlGreyUI openToolsMenu]; + [[[EarlGrey + selectElementWithMatcher:grey_allOf( + grey_accessibilityID(kToolsMenuEditBookmark), + grey_sufficientlyVisible(), nil)] + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 200) + onElementWithMatcher:grey_accessibilityID(kPopupMenuToolsMenuTableViewId)] + performAction:grey_tap()]; // Delete the Bookmark. [[EarlGrey selectElementWithMatcher:grey_accessibilityID( @@ -119,25 +101,17 @@ // Verify the the page is no longer bookmarked. - if ([ChromeEarlGrey isCompactWidth] || - [ChromeEarlGrey isChangeTabSwitcherPositionEnabled]) { - [ChromeEarlGreyUI openToolsMenu]; - [[[EarlGrey - selectElementWithMatcher:grey_allOf(grey_accessibilityID( - kToolsMenuAddToBookmarks), - grey_sufficientlyVisible(), nil)] - usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 200) - onElementWithMatcher:grey_accessibilityID( - kPopupMenuToolsMenuTableViewId)] - assertWithMatcher:grey_notNil()]; - // After veryfing, close the ToolsMenu by tapping on its button. - [ChromeEarlGreyUI openToolsMenu]; - } else { - [[EarlGrey - selectElementWithMatcher:grey_accessibilityLabel( - l10n_util::GetNSString(IDS_TOOLTIP_STAR))] - assertWithMatcher:grey_notNil()]; - } + [ChromeEarlGreyUI openToolsMenu]; + [[[EarlGrey + selectElementWithMatcher:grey_allOf(grey_accessibilityID( + kToolsMenuAddToBookmarks), + grey_sufficientlyVisible(), nil)] + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 200) + onElementWithMatcher:grey_accessibilityID(kPopupMenuToolsMenuTableViewId)] + assertWithMatcher:grey_notNil()]; + // After veryfing, close the ToolsMenu by tapping on its button. + [ChromeEarlGreyUI openToolsMenu]; + // Close the opened tab. [ChromeEarlGrey closeCurrentTab]; } @@ -228,21 +202,15 @@ selectElementWithMatcher:TappableBookmarkNodeWithLabel(@"Second URL")] performAction:grey_tap()]; - // Edit the bookmark. - if (![ChromeEarlGrey isCompactWidth] && - ![ChromeEarlGrey isChangeTabSwitcherPositionEnabled]) { - [[EarlGrey selectElementWithMatcher:StarButton()] performAction:grey_tap()]; - } else { - [ChromeEarlGreyUI openToolsMenu]; - [[[EarlGrey - selectElementWithMatcher:grey_allOf(grey_accessibilityID( - kToolsMenuEditBookmark), - grey_sufficientlyVisible(), nil)] - usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 200) - onElementWithMatcher:grey_accessibilityID( - kPopupMenuToolsMenuTableViewId)] - performAction:grey_tap()]; - } + [ChromeEarlGreyUI openToolsMenu]; + [[[EarlGrey + selectElementWithMatcher:grey_allOf( + grey_accessibilityID(kToolsMenuEditBookmark), + grey_sufficientlyVisible(), nil)] + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 200) + onElementWithMatcher:grey_accessibilityID(kPopupMenuToolsMenuTableViewId)] + performAction:grey_tap()]; + GREYAssertTrue([ChromeEarlGrey registeredKeyCommandCount] == 0, @"No keyboard commands are registered."); }
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn index bdf728ef..9be8841 100644 --- a/ios/chrome/browser/ui/browser_view/BUILD.gn +++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -151,7 +151,6 @@ "//ios/chrome/browser/ui/toolbar/fullscreen", "//ios/chrome/browser/ui/toolbar/fullscreen:fullscreen_broadcasting_util", "//ios/chrome/browser/ui/toolbar/public", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/toolbar_container", "//ios/chrome/browser/ui/toolbar_container:feature_flags", "//ios/chrome/browser/ui/translate:legacy_translate",
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm index 6336872..6e59bfbf 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -1969,9 +1969,6 @@ self.legacyTabStripCoordinator.longPressDelegate = self.popupMenuCoordinator; - UILayoutGuide* guide = - [[NamedGuide alloc] initWithName:kTabStripTabSwitcherGuide]; - [self.view addLayoutGuide:guide]; [self.legacyTabStripCoordinator start]; } }
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_dependency_factory.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_dependency_factory.mm index 60ec128..e4c5735 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller_dependency_factory.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_dependency_factory.mm
@@ -10,7 +10,6 @@ #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" #import "ios/chrome/browser/ui/browser_view/browser_view_controller_helper.h" #import "ios/chrome/browser/ui/browser_view/key_commands_provider.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #include "ui/base/l10n/l10n_util_mac.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/bubble/BUILD.gn b/ios/chrome/browser/ui/bubble/BUILD.gn index 7b235347..122f8a26b 100644 --- a/ios/chrome/browser/ui/bubble/BUILD.gn +++ b/ios/chrome/browser/ui/bubble/BUILD.gn
@@ -27,7 +27,6 @@ "//ios/chrome/browser/feature_engagement", "//ios/chrome/browser/ui/colors", "//ios/chrome/browser/ui/commands", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/util", "//ios/chrome/common", "//ios/chrome/common/ui/colors",
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.mm b/ios/chrome/browser/ui/bubble/bubble_presenter.mm index 86935b3..b3acdf3f 100644 --- a/ios/chrome/browser/ui/bubble/bubble_presenter.mm +++ b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
@@ -18,7 +18,6 @@ #import "ios/chrome/browser/ui/bubble/bubble_util.h" #import "ios/chrome/browser/ui/bubble/bubble_view_controller_presenter.h" #import "ios/chrome/browser/ui/commands/toolbar_commands.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/util/named_guide.h" #import "ios/chrome/browser/ui/util/named_guide_util.h" #include "ios/chrome/browser/ui/util/ui_util.h" @@ -178,13 +177,8 @@ IsSplitToolbarMode() ? BubbleArrowDirectionDown : BubbleArrowDirectionUp; NSString* text = l10n_util::GetNSString(IDS_IOS_LONG_PRESS_TOOLBAR_IPH_PROMOTION_TEXT); - CGPoint tabGridButtonAnchor = - IsRegularXRegularSizeClass() && - !base::FeatureList::IsEnabled(kChangeTabSwitcherPosition) - ? [self anchorPointToGuide:kTabStripTabSwitcherGuide - direction:arrowDirection] - : [self anchorPointToGuide:kTabSwitcherGuide - direction:arrowDirection]; + CGPoint tabGridButtonAnchor = [self anchorPointToGuide:kTabSwitcherGuide + direction:arrowDirection]; // If the feature engagement tracker does not consider it valid to display // the tip, then end early to prevent the potential reassignment of the @@ -316,15 +310,8 @@ IsSplitToolbarMode() ? BubbleArrowDirectionDown : BubbleArrowDirectionUp; NSString* text = l10n_util::GetNSStringWithFixup(IDS_IOS_NEW_TAB_IPH_PROMOTION_TEXT); - CGPoint tabSwitcherAnchor; - if (IsRegularXRegularSizeClass() && - !base::FeatureList::IsEnabled(kChangeTabSwitcherPosition)) { - tabSwitcherAnchor = [self anchorPointToGuide:kTabStripTabSwitcherGuide - direction:arrowDirection]; - } else { - tabSwitcherAnchor = - [self anchorPointToGuide:kTabSwitcherGuide direction:arrowDirection]; - } + CGPoint tabSwitcherAnchor = [self anchorPointToGuide:kTabSwitcherGuide + direction:arrowDirection]; // If the feature engagement tracker does not consider it valid to display // the new tab tip, then end early to prevent the potential reassignment
diff --git a/ios/chrome/browser/ui/commands/popup_menu_commands.h b/ios/chrome/browser/ui/commands/popup_menu_commands.h index 0c49aa9..f6bdd20 100644 --- a/ios/chrome/browser/ui/commands/popup_menu_commands.h +++ b/ios/chrome/browser/ui/commands/popup_menu_commands.h
@@ -24,8 +24,6 @@ - (void)showToolsMenuPopup; // Shows the popup for the tab grid button. - (void)showTabGridButtonPopup; -// Shows the popup for the tab grid button in the tab strip. -- (void)showTabStripTabGridButtonPopup; // Shows the popup for the new tab button. - (void)showNewTabButtonPopup; // Dismisses the currently presented popup.
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_discover_header_item.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_discover_header_item.mm index eb6b840..20e0835 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_discover_header_item.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_discover_header_item.mm
@@ -134,7 +134,7 @@ // TODO(b/167703449): Once the card width and padding is exposed we should // stop hardcoding this for some iPhones (the ones with a portrait width of // kFeedCardIPhoneWidth) and use those values instead. - BOOL shouldFixWidth = IsPortrait() + BOOL shouldFixWidth = IsPortrait(self.window) ? (CurrentScreenWidth() == kFeedCardIPhoneWidth) : (CurrentScreenHeight() == kFeedCardIPhoneWidth); if (shouldFixWidth) {
diff --git a/ios/chrome/browser/ui/infobars/coordinators/BUILD.gn b/ios/chrome/browser/ui/infobars/coordinators/BUILD.gn index f9257b98..cff09e8 100644 --- a/ios/chrome/browser/ui/infobars/coordinators/BUILD.gn +++ b/ios/chrome/browser/ui/infobars/coordinators/BUILD.gn
@@ -40,7 +40,6 @@ "//ios/chrome/browser/ui/infobars/modals", "//ios/chrome/browser/ui/infobars/modals:public", "//ios/chrome/browser/ui/infobars/presentation", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/util", "//ui/base", ]
diff --git a/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.mm b/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.mm index 722d6a94..edc3405 100644 --- a/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.mm +++ b/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.mm
@@ -23,7 +23,6 @@ #import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.h" #import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_positioner.h" #import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_transition_driver.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/util/named_guide.h" #import "ios/chrome/browser/ui/util/ui_util.h"
diff --git a/ios/chrome/browser/ui/keyboard/keyboard_commands_egtest.mm b/ios/chrome/browser/ui/keyboard/keyboard_commands_egtest.mm index 520d343..ed078bf0 100644 --- a/ios/chrome/browser/ui/keyboard/keyboard_commands_egtest.mm +++ b/ios/chrome/browser/ui/keyboard/keyboard_commands_egtest.mm
@@ -113,13 +113,6 @@ [ChromeEarlGrey loadURL:self.testServer->GetURL("/pony.html")]; // Bookmark page - if ([ChromeEarlGrey isIPadIdiom] && - ![ChromeEarlGrey isChangeTabSwitcherPositionEnabled]) { - id<GREYMatcher> bookmarkMatcher = - chrome_test_util::ButtonWithAccessibilityLabelId(IDS_TOOLTIP_STAR); - [[EarlGrey selectElementWithMatcher:bookmarkMatcher] - performAction:grey_tap()]; - } else { [ChromeEarlGreyUI openToolsMenu]; [[[EarlGrey selectElementWithMatcher:grey_allOf(grey_accessibilityID( @@ -129,19 +122,18 @@ onElementWithMatcher:grey_accessibilityID( kPopupMenuToolsMenuTableViewId)] performAction:grey_tap()]; - } - // Tap on the HUD. - id<GREYMatcher> edit = chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_NAVIGATION_BAR_EDIT_BUTTON); - [[EarlGrey selectElementWithMatcher:edit] performAction:grey_tap()]; + // Tap on the HUD. + id<GREYMatcher> edit = chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_NAVIGATION_BAR_EDIT_BUTTON); + [[EarlGrey selectElementWithMatcher:edit] performAction:grey_tap()]; - [self waitForSingleBookmarkEditorToDisplay]; + [self waitForSingleBookmarkEditorToDisplay]; - [self verifyNoKeyboardCommandsAreRegistered]; + [self verifyNoKeyboardCommandsAreRegistered]; - id<GREYMatcher> cancel = grey_accessibilityID(@"Cancel"); - [[EarlGrey selectElementWithMatcher:cancel] performAction:grey_tap()]; + id<GREYMatcher> cancel = grey_accessibilityID(@"Cancel"); + [[EarlGrey selectElementWithMatcher:cancel] performAction:grey_tap()]; } // Tests that keyboard commands are not registered when the Bookmarks UI is
diff --git a/ios/chrome/browser/ui/location_bar/BUILD.gn b/ios/chrome/browser/ui/location_bar/BUILD.gn index 7bd46cd..da7bd0b 100644 --- a/ios/chrome/browser/ui/location_bar/BUILD.gn +++ b/ios/chrome/browser/ui/location_bar/BUILD.gn
@@ -67,7 +67,6 @@ "//ios/chrome/browser/ui/orchestrator:orchestrator", "//ios/chrome/browser/ui/toolbar/buttons", "//ios/chrome/browser/ui/toolbar/public", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/voice", "//ios/chrome/browser/ui/whats_new:utils",
diff --git a/ios/chrome/browser/ui/omnibox/BUILD.gn b/ios/chrome/browser/ui/omnibox/BUILD.gn index 57ed3f6..ca1f9c3 100644 --- a/ios/chrome/browser/ui/omnibox/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/BUILD.gn
@@ -158,7 +158,6 @@ "//ios/chrome/browser/ui/omnibox/popup", "//ios/chrome/browser/ui/orchestrator:orchestrator", "//ios/chrome/browser/ui/toolbar/public", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/util:multiwindow_util", "//ios/chrome/browser/ui/whats_new:utils",
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm index feedb0a..56bd333 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
@@ -19,7 +19,6 @@ #include "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h" #include "ios/chrome/browser/system_flags.h" #import "ios/chrome/browser/ui/omnibox/omnibox_util.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/animation_util.h"
diff --git a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn index 58997ea3..973f9ea 100644 --- a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
@@ -36,7 +36,6 @@ "//ios/chrome/browser/ui/omnibox:omnibox_util", "//ios/chrome/browser/ui/toolbar/buttons", "//ios/chrome/browser/ui/toolbar/public", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/whats_new:utils", "//ios/chrome/browser/web_state_list:web_state_list",
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm index 111b0fa..855ed3d 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
@@ -5,7 +5,6 @@ #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #import "ios/chrome/browser/ui/util/named_guide.h" #include "ios/chrome/browser/ui/util/ui_util.h"
diff --git a/ios/chrome/browser/ui/popup_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/BUILD.gn index f8c47b1..c0ad3c2 100644 --- a/ios/chrome/browser/ui/popup_menu/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/BUILD.gn
@@ -80,7 +80,6 @@ "//ios/chrome/browser/ui/popup_menu/public/cells", "//ios/chrome/browser/ui/presenters", "//ios/chrome/browser/ui/reading_list", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/util:multiwindow_util", "//ios/chrome/browser/web",
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm index 7181592..a7b5909 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -29,7 +29,6 @@ #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_presenter_delegate.h" #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.h" #import "ios/chrome/browser/ui/presenters/contained_presenter_delegate.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/util/layout_guide_names.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -130,13 +129,6 @@ fromNamedGuide:kNewTabButtonGuide]; } -- (void)showTabStripTabGridButtonPopup { - DCHECK(!base::FeatureList::IsEnabled(kChangeTabSwitcherPosition)); - base::RecordAction(base::UserMetricsAction("MobileTabStripShowTabGridMenu")); - [self presentPopupOfType:PopupMenuTypeTabStripTabGrid - fromNamedGuide:kTabStripTabSwitcherGuide]; -} - - (void)dismissPopupMenuAnimated:(BOOL)animated { [self.UIUpdater updateUIForMenuDismissed]; [self.presenter dismissAnimated:animated];
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm index f552841f..196aea5 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
@@ -44,7 +44,6 @@ #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_consumer.h" #import "ios/chrome/browser/ui/reading_list/reading_list_menu_notification_delegate.h" #import "ios/chrome/browser/ui/reading_list/reading_list_menu_notifier.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/multi_window_support.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
diff --git a/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm b/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm index 6b7273d..262a2176 100644 --- a/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm +++ b/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm
@@ -448,7 +448,7 @@ - (void)layoutActionButton { CGRect containerBounds = self.containerBounds; BOOL isIPadIdiom = IsIPadIdiom(); - BOOL isPortrait = IsPortrait(); + BOOL isPortrait = IsPortrait(self.window); BOOL shouldAddActionButtonToContainer = isIPadIdiom || !isPortrait; LayoutRect actionButtonLayout = LayoutRectZero; actionButtonLayout.size = @@ -491,7 +491,7 @@ // Center the containerView on iPads. containerOriginY = (CGRectGetHeight(self.bounds) - containerSize.height) / 2.0f; - } else if (IsPortrait()) { + } else if (IsPortrait(self.window)) { // Align containerView to a quarter of the view height on portrait iPhones. containerOriginY = (CGRectGetHeight(self.bounds) - containerSize.height) / 4.0f;
diff --git a/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller.mm b/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller.mm index a65b875..3c031f6 100644 --- a/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller.mm +++ b/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller.mm
@@ -149,7 +149,7 @@ // bounds will still be landscape at this point. Swap the height and width // here so that the dimensions will be correct once the app rotates to // portrait. - if (IsLandscape()) { + if (IsLandscape(self.view.window)) { mainBounds.size = CGSizeMake(mainBounds.size.height, mainBounds.size.width); } UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:mainBounds];
diff --git a/ios/chrome/browser/ui/tabs/BUILD.gn b/ios/chrome/browser/ui/tabs/BUILD.gn index fde9b1c..2bc2206 100644 --- a/ios/chrome/browser/ui/tabs/BUILD.gn +++ b/ios/chrome/browser/ui/tabs/BUILD.gn
@@ -60,7 +60,6 @@ "//ios/chrome/browser/ui/popup_menu/public", "//ios/chrome/browser/ui/tab_grid/grid/resources:grid_cell_close_button", "//ios/chrome/browser/ui/tabs/requirements", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/url_loading", "//ios/chrome/browser/web_state_list",
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm index cb96ee17..5bd63e5a 100644 --- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm +++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -44,7 +44,6 @@ #import "ios/chrome/browser/ui/tabs/tab_strip_view.h" #import "ios/chrome/browser/ui/tabs/tab_view.h" #include "ios/chrome/browser/ui/tabs/target_frame_cache.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/named_guide.h" #include "ios/chrome/browser/ui/util/rtl_geometry.h" @@ -89,10 +88,6 @@ const CGFloat kMaxTabWidthStacked = 265.0; const CGFloat kMaxTabWidthUnstacked = 225.0; -// Tab Switcher button dimensions. -const CGFloat kTabSwitcherButtonWidth = 46.0; -const CGFloat kTabSwitcherButtonBackgroundWidth = 62.0; - const CGFloat kMinTabWidthStacked = 200.0; const CGFloat kMinTabWidthUnstacked = 160.0; @@ -186,11 +181,6 @@ TabStripContainerView* _view; TabStripView* _tabStripView; UIButton* _buttonNewTab; - UIButton* _tabSwitcherButton; - - // Background view of the tab switcher button. Only visible while in unstacked - // layout. - UIImageView* _tabSwitcherButtonBackgroundView; TabStripStyle _style; @@ -412,9 +402,6 @@ // toggle buttons states depending on the current layout mode. - (void)updateScrollViewFrameForTabSwitcherButton; -// Updates the tab switcher button with the current tab count. -- (void)updateTabCount; - // Returns the existing tab view for |webState| or nil if there is no TabView // for it. - (TabView*)tabViewForWebState:(web::WebState*)webState; @@ -519,9 +506,6 @@ [_tabStripView addSubview:_buttonNewTab]; - if (!base::FeatureList::IsEnabled(kChangeTabSwitcherPosition)) - [self installTabSwitcherButton]; - // Add tab buttons to tab strip. [self initializeTabArray]; @@ -573,7 +557,6 @@ - (void)hideTabStrip:(BOOL)hidden { self.view.hidden = hidden; - [self updateTabSwitcherGuide]; } - (void)tabStripSizeDidChange { @@ -710,8 +693,6 @@ - (void)recordUserMetrics:(id)sender { if (sender == _buttonNewTab) base::RecordAction(UserMetricsAction("MobileTabStripNewTab")); - else if (sender == _tabSwitcherButton) - base::RecordAction(UserMetricsAction("MobileTabSwitcherOpen")); else LOG(WARNING) << "Trying to record metrics for unknown sender " << base::SysNSStringToUTF8([sender description]); @@ -792,24 +773,6 @@ return [self webStateListIndexForIndex:[_tabArray indexOfObject:view]]; } -// The |tabSwitcherGuide| cannot use constrainedView in the tab strip because -// here views use CGAffineTransformMakeScale to support RTL, and NamedGuide -// doesn't honor transforms. Instead we set the tabSwitcherGuide as necessary. -- (void)updateTabSwitcherGuide { - if (base::FeatureList::IsEnabled(kChangeTabSwitcherPosition)) - return; - - NamedGuide* tabSwitcherGuide = - [NamedGuide guideWithName:kTabStripTabSwitcherGuide view:self.view]; - if (self.view.hidden) { - tabSwitcherGuide.constrainedFrame = CGRectZero; - } else { - tabSwitcherGuide.constrainedFrame = - [_tabSwitcherButton.superview convertRect:_tabSwitcherButton.frame - toView:tabSwitcherGuide.owningView]; - } -} - // Updates the title and the favicon of the |view| with data from |webState|. - (void)updateTabView:(TabView*)view withWebState:(web::WebState*)webState { [[view titleLabel] setText:tab_util::GetTabTitle(webState)]; @@ -1210,8 +1173,6 @@ }]; [self setNeedsLayoutWithAnimation]; - - [self updateTabCount]; } // Observer method. |webState| inserted on |webStateList|. @@ -1227,8 +1188,6 @@ [self updateContentSizeAndRepositionViews]; [self setNeedsLayoutWithAnimation]; [self updateContentOffsetForWebStateIndex:index isNewWebState:YES]; - - [self updateTabCount]; } // Observer method, WebState replaced in |webStateList|. @@ -1285,82 +1244,6 @@ return availableSpace; } -- (void)installTabSwitcherButton { - DCHECK(!base::FeatureList::IsEnabled(kChangeTabSwitcherPosition)); - DCHECK(!_tabSwitcherButton); - UIImage* tabSwitcherButtonIcon; - UIImage* tabSwitcherButtonIconPressed; - tabSwitcherButtonIcon = - [UIImage imageNamed:@"tabstrip_tab_switcher_count_button"]; - tabSwitcherButtonIconPressed = - [UIImage imageNamed:@"tabstrip_tab_switcher_count_button_pressed"]; - - int tabSwitcherButtonIdsAccessibilityLabel = - IDS_IOS_TAB_STRIP_ENTER_TAB_SWITCHER; - NSString* tabSwitcherButtonEnglishUiAutomationName = @"Enter Tab Switcher"; - const CGFloat tabStripHeight = _view.frame.size.height; - CGRect buttonFrame = - CGRectMake(CGRectGetMaxX(_view.frame) - kTabSwitcherButtonWidth, 0, - kTabSwitcherButtonWidth, tabStripHeight); - _tabSwitcherButton = - [TabStripCenteredButton buttonWithType:UIButtonTypeCustom]; - if (UseRTLLayout()) - [_tabSwitcherButton setTransform:CGAffineTransformMakeScale(-1, 1)]; - [self addTabSwitcherLongPressGesture]; - - [_tabSwitcherButton setTintColor:[UIColor whiteColor]]; - [_tabSwitcherButton setFrame:buttonFrame]; - [_tabSwitcherButton setContentMode:UIViewContentModeCenter]; - [_tabSwitcherButton setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; - [_tabSwitcherButton setBackgroundColor:[UIColor clearColor]]; - [_tabSwitcherButton setExclusiveTouch:YES]; - [_tabSwitcherButton setImage:tabSwitcherButtonIcon - forState:UIControlStateNormal]; - [_tabSwitcherButton setImage:tabSwitcherButtonIconPressed - forState:UIControlStateHighlighted]; - [_tabSwitcherButton addTarget:[self applicationCommandsHandler] - action:@selector(prepareTabSwitcher) - forControlEvents:UIControlEventTouchDown]; - [_tabSwitcherButton addTarget:[self applicationCommandsHandler] - action:@selector(displayTabSwitcher) - forControlEvents:UIControlEventTouchUpInside]; - [_tabSwitcherButton addTarget:self - action:@selector(recordUserMetrics:) - forControlEvents:UIControlEventTouchUpInside]; - [self updateTabCount]; - - SetA11yLabelAndUiAutomationName(_tabSwitcherButton, - tabSwitcherButtonIdsAccessibilityLabel, - tabSwitcherButtonEnglishUiAutomationName); - [_view addSubview:_tabSwitcherButton]; - // Shrink the scroll view. - [self updateScrollViewFrameForTabSwitcherButton]; -} - -// Adds a LongPressGesture to the |_tabSwitcherButton|, with target on -// -|handleTabSwitcherLongPress:|. -- (void)addTabSwitcherLongPressGesture { - UILongPressGestureRecognizer* longPress = - [[UILongPressGestureRecognizer alloc] - initWithTarget:self - action:@selector(handleTabSwitcherLongPress:)]; - [_tabSwitcherButton addGestureRecognizer:longPress]; -} - -// Handles the long press on the |_tabSwitcherButton|. -- (void)handleTabSwitcherLongPress:(UILongPressGestureRecognizer*)gesture { - if (gesture.state == UIGestureRecognizerStateBegan) { - [[self popupMenuCommandsHandler] showTabStripTabGridButtonPopup]; - TriggerHapticFeedbackForImpact(UIImpactFeedbackStyleMedium); - } else if (gesture.state == UIGestureRecognizerStateEnded) { - [self.longPressDelegate - longPressEndedAtPoint:[gesture locationOfTouch:0 inView:nil]]; - } else if (gesture.state == UIGestureRecognizerStateChanged) { - [self.longPressDelegate - longPressFocusPointChangedTo:[gesture locationOfTouch:0 inView:nil]]; - } -} - - (void)shiftTabStripSubviews:(CGPoint)oldContentOffset { CGFloat dx = [_tabStripView contentOffset].x - oldContentOffset.x; for (UIView* view in [_tabStripView subviews]) { @@ -1529,49 +1412,14 @@ - (void)updateScrollViewFrameForTabSwitcherButton { CGRect tabFrame = _tabStripView.frame; tabFrame.size.width = _view.bounds.size.width; - if (!base::FeatureList::IsEnabled(kChangeTabSwitcherPosition)) { - if (self.useTabStacking) { - tabFrame.size.width -= kTabSwitcherButtonWidth; - _tabStripView.contentInset = UIEdgeInsetsZero; - [_tabSwitcherButtonBackgroundView setHidden:YES]; - } else { - if (!_tabSwitcherButtonBackgroundView) { - _tabSwitcherButtonBackgroundView = [[UIImageView alloc] init]; - const CGFloat tabStripHeight = _view.frame.size.height; - const CGRect backgroundViewFrame = CGRectMake( - CGRectGetMaxX(_view.frame) - kTabSwitcherButtonBackgroundWidth, 0.0, - kTabSwitcherButtonBackgroundWidth, tabStripHeight); - [_tabSwitcherButtonBackgroundView setFrame:backgroundViewFrame]; - [_tabSwitcherButtonBackgroundView - setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; - UIImage* backgroundTabSwitcherImage = - [UIImage imageNamed:@"tabstrip_toggle_button_gradient"]; - [_tabSwitcherButtonBackgroundView setImage:backgroundTabSwitcherImage]; - [_view addSubview:_tabSwitcherButtonBackgroundView]; - } - [_tabSwitcherButtonBackgroundView setHidden:NO]; - _tabStripView.contentInset = - UIEdgeInsetsMake(0, 0, 0, kTabSwitcherButtonWidth); - [_view bringSubviewToFront:_tabSwitcherButton]; - } - } [_tabStripView setFrame:tabFrame]; } -- (void)updateTabCount { - [_tabSwitcherButton setTitle:TextForTabCount(_webStateList->count()) - forState:UIControlStateNormal]; - [_tabSwitcherButton - setAccessibilityValue:[NSString stringWithFormat:@"%d", - _webStateList->count()]]; -} - #pragma mark - TabStripViewLayoutDelegate // Creates TabViews for each Tab in the WebStateList and positions them in the // correct location onscreen. - (void)layoutTabStripSubviews { - [self updateTabSwitcherGuide]; const int tabCount = static_cast<int>([_tabArray count] - [_closingTabs count]); if (!tabCount)
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn index e942d816..e57f6d0 100644 --- a/ios/chrome/browser/ui/toolbar/BUILD.gn +++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -102,7 +102,6 @@ "//ios/chrome/browser/ui/thumb_strip:feature_flags", "//ios/chrome/browser/ui/toolbar/buttons", "//ios/chrome/browser/ui/toolbar/public", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/toolbar_container:toolbar_collapsing", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/util",
diff --git a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_egtest.mm b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_egtest.mm index e3bf79e..f5b4265c 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_egtest.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_egtest.mm
@@ -161,21 +161,6 @@ assertWithMatcher:assertionMatcher]; } -// Returns a matcher for a UIControl object being spotlighted. -id<GREYMatcher> Spotlighted() { - GREYMatchesBlock matches = ^BOOL(UIControl* control) { - return control.state & kControlStateSpotlighted; - }; - GREYDescribeToBlock describe = ^void(id<GREYDescription> description) { - [description appendText:@"is spotlighted"]; - }; - return grey_allOf( - grey_kindOfClass([UIControl class]), - [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches - descriptionBlock:describe], - nil); -} - // Rotate the device if it is an iPhone or change the trait collection to // compact width if it is an iPad. Returns the new trait collection. UITraitCollection* RotateOrChangeTraitCollection( @@ -292,13 +277,8 @@ CheckVisibilityInToolbar(ShareButton(), ButtonVisibilityPrimary); CheckVisibilityInToolbar(ReloadButton(), ButtonVisibilityPrimary); - if ([ChromeEarlGrey isChangeTabSwitcherPositionEnabled]) { - CheckVisibilityInToolbar(BookmarkButton(), ButtonVisibilityNone); - CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilityPrimary); - } else { - CheckVisibilityInToolbar(BookmarkButton(), ButtonVisibilityPrimary); - CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilityNone); - } + CheckVisibilityInToolbar(BookmarkButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilityPrimary); CheckVisibilityInToolbar(BackButton(), ButtonVisibilityPrimary); CheckVisibilityInToolbar(ForwardButton(), ButtonVisibilityPrimary); @@ -394,51 +374,6 @@ @implementation AdaptiveToolbarTestCase -// Tests that bookmarks button is spotlighted for the bookmarked pages. -- (void)testBookmarkButton { - if (![ChromeEarlGrey isRegularXRegularSizeClass] || - [ChromeEarlGrey isChangeTabSwitcherPositionEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"The bookmark button is only visible on Regular x Regular size " - @"classes."); - } - - // Setup the bookmarks. - [ChromeEarlGrey waitForBookmarksToFinishLoading]; - [ChromeEarlGrey clearBookmarks]; - - // Setup the server. - self.testServer->RegisterRequestHandler( - base::BindRepeating(&StandardResponse)); - GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); - - // Navigate to a page and check the bookmark button is not spotlighted. - [ChromeEarlGrey loadURL:self.testServer->GetURL(kPageURL)]; - [[EarlGrey selectElementWithMatcher:BookmarkButton()] - assertWithMatcher:grey_allOf(grey_kindOfClass([UIControl class]), - grey_not(Spotlighted()), nil)]; - - // Bookmark the page. - [[EarlGrey selectElementWithMatcher:BookmarkButton()] - performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:BookmarkButton()] - assertWithMatcher:Spotlighted()]; - - // Navigate to a different page and check the button is not selected. - [ChromeEarlGrey loadURL:self.testServer->GetURL(kPageURL2)]; - [[EarlGrey selectElementWithMatcher:BookmarkButton()] - assertWithMatcher:grey_allOf(grey_kindOfClass([UIControl class]), - grey_not(Spotlighted()), nil)]; - - // Navigate back to the bookmarked page and check the button. - [ChromeEarlGrey loadURL:self.testServer->GetURL(kPageURL)]; - [[EarlGrey selectElementWithMatcher:BookmarkButton()] - assertWithMatcher:Spotlighted()]; - - // Clean the bookmarks - [ChromeEarlGrey clearBookmarks]; -} - // Tests that tapping a button cancels the focus on the omnibox. - (void)testCancelOmniboxEdit { if ([ChromeEarlGrey isCompactWidth]) {
diff --git a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm index 56d510b..f4d85d6b 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm
@@ -17,7 +17,6 @@ #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_tab_grid_button.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_tools_menu_button.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/util/animation_util.h"
diff --git a/ios/chrome/browser/ui/toolbar/buttons/BUILD.gn b/ios/chrome/browser/ui/toolbar/buttons/BUILD.gn index bfea18e..520c206 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/BUILD.gn +++ b/ios/chrome/browser/ui/toolbar/buttons/BUILD.gn
@@ -49,7 +49,6 @@ "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant", "//ios/chrome/browser/ui/toolbar/public", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web_state_list", "//ios/chrome/common/ui/colors",
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_actions_handler.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_actions_handler.mm index 332fdf86..a1f2962 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_actions_handler.mm +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_actions_handler.mm
@@ -13,7 +13,6 @@ #import "ios/chrome/browser/ui/commands/find_in_page_commands.h" #import "ios/chrome/browser/ui/commands/omnibox_commands.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #include "url/gurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm index cf303ea..59ddac16 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm
@@ -13,7 +13,6 @@ #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_new_tab_button.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_tab_grid_button.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_tools_menu_button.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/rtl_geometry.h"
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.mm index ea4d472d..e1b671b 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.mm +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.mm
@@ -4,7 +4,6 @@ #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -45,13 +44,8 @@ - (ToolbarComponentVisibility)tabGridButtonVisibility { switch (self.type) { case PRIMARY: - if (base::FeatureList::IsEnabled(kChangeTabSwitcherPosition)) { - return ToolbarComponentVisibilityAlways & - ~ToolbarComponentVisibilitySplit; - } else { - return ToolbarComponentVisibilityCompactWidthCompactHeight | - ToolbarComponentVisibilityRegularWidthCompactHeight; - } + return ToolbarComponentVisibilityAlways & + ~ToolbarComponentVisibilitySplit; case SECONDARY: return ToolbarComponentVisibilitySplit; }
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_new_tab_button.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_new_tab_button.mm index dd6a607..ca5a5396 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_new_tab_button.mm +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_new_tab_button.mm
@@ -6,7 +6,6 @@ #include "base/feature_list.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h"
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_tab_grid_button.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_tab_grid_button.mm index 251e72cb..6a56787 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_tab_grid_button.mm +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_tab_grid_button.mm
@@ -5,7 +5,6 @@ #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_tab_grid_button.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #include "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
diff --git a/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm index 2852aab..aec0ac7 100644 --- a/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm +++ b/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm
@@ -12,7 +12,6 @@ #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_tab_grid_button.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_tools_menu_button.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_utils.h" #import "ios/chrome/browser/ui/toolbar/toolbar_progress_bar.h" @@ -259,15 +258,8 @@ self.tabGridButton = [self.buttonFactory tabGridButton]; self.toolsMenuButton = [self.buttonFactory toolsMenuButton]; - if (base::FeatureList::IsEnabled(kChangeTabSwitcherPosition)) { - self.trailingStackViewButtons = - @[ self.shareButton, self.tabGridButton, self.toolsMenuButton ]; - } else { - self.trailingStackViewButtons = @[ - self.bookmarkButton, self.shareButton, self.tabGridButton, - self.toolsMenuButton - ]; - } + self.trailingStackViewButtons = + @[ self.shareButton, self.tabGridButton, self.toolsMenuButton ]; self.trailingStackView = [[UIStackView alloc] initWithArrangedSubviews:self.trailingStackViewButtons];
diff --git a/ios/chrome/browser/ui/toolbar/public/BUILD.gn b/ios/chrome/browser/ui/toolbar/public/BUILD.gn index 773a1395..f6c0764 100644 --- a/ios/chrome/browser/ui/toolbar/public/BUILD.gn +++ b/ios/chrome/browser/ui/toolbar/public/BUILD.gn
@@ -13,7 +13,6 @@ "toolbar_utils.mm", ] deps = [ - ":feature_flags", "//base", "//ios/chrome/browser/ui/activity_services/requirements", "//ios/chrome/browser/ui/bubble", @@ -33,12 +32,3 @@ "toolbar_constants.mm", ] } - -source_set("feature_flags") { - sources = [ - "features.h", - "features.mm", - ] - deps = [ "//base" ] - configs += [ "//build/config/compiler:enable_arc" ] -}
diff --git a/ios/chrome/browser/ui/toolbar/public/features.h b/ios/chrome/browser/ui/toolbar/public/features.h index 5a649a9..2e8a9fb 100644 --- a/ios/chrome/browser/ui/toolbar/public/features.h +++ b/ios/chrome/browser/ui/toolbar/public/features.h
@@ -9,7 +9,4 @@ #include "base/feature_list.h" -// Feature to change tab switcher position and remove bookmark button. -extern const base::Feature kChangeTabSwitcherPosition; - #endif // IOS_CHROME_BROWSER_UI_TOOLBAR_PUBLIC_FEATURES_H_
diff --git a/ios/chrome/browser/ui/toolbar/public/features.mm b/ios/chrome/browser/ui/toolbar/public/features.mm index e29bd35..c76cca4 100644 --- a/ios/chrome/browser/ui/toolbar/public/features.mm +++ b/ios/chrome/browser/ui/toolbar/public/features.mm
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/toolbar/public/features.h" #include "base/command_line.h" #include "base/metrics/field_trial_params.h" @@ -10,6 +9,3 @@ #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif - -const base::Feature kChangeTabSwitcherPosition{ - "ChangeTabSwitcherPosition", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm index 3ac5b9e..2b2af0a03 100644 --- a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm +++ b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm
@@ -10,7 +10,6 @@ #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_tab_grid_button.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_tools_menu_button.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/toolbar_container/toolbar_collapsing.h" #import "ios/chrome/browser/ui/util/named_guide.h" #include "ios/chrome/browser/ui/util/rtl_geometry.h"
diff --git a/ios/chrome/browser/ui/util/BUILD.gn b/ios/chrome/browser/ui/util/BUILD.gn index 9b6b8db4..ebc4b54f 100644 --- a/ios/chrome/browser/ui/util/BUILD.gn +++ b/ios/chrome/browser/ui/util/BUILD.gn
@@ -96,7 +96,6 @@ "//ios/chrome/browser:utils", "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui:feature_flags", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/common:timing", "//ios/chrome/common/ui/util", "//ios/chrome/common/ui/util:dynamic_type_util",
diff --git a/ios/chrome/browser/ui/util/layout_guide_names.h b/ios/chrome/browser/ui/util/layout_guide_names.h index 2d88e42..50e2e44 100644 --- a/ios/chrome/browser/ui/util/layout_guide_names.h +++ b/ios/chrome/browser/ui/util/layout_guide_names.h
@@ -44,9 +44,6 @@ // A guide that is constrained to match the frame of the TabSwitcher button's // image. extern GuideName* const kTabSwitcherGuide; -// A guide that is constrained to match the frame of the TabStrip's TabSwitcher -// button's image. -extern GuideName* const kTabStripTabSwitcherGuide; // A guide that is constrained to match the frame of the ToolsMenu button. extern GuideName* const kToolsMenuGuide; // A guide that is constrained to match the frame of the translate infobar
diff --git a/ios/chrome/browser/ui/util/layout_guide_names.mm b/ios/chrome/browser/ui/util/layout_guide_names.mm index 5ff6066..876ecaa 100644 --- a/ios/chrome/browser/ui/util/layout_guide_names.mm +++ b/ios/chrome/browser/ui/util/layout_guide_names.mm
@@ -21,7 +21,6 @@ GuideName* const kForwardButtonGuide = @"kForwardButtonGuide"; GuideName* const kNewTabButtonGuide = @"kNewTabButtonGuide"; GuideName* const kTabSwitcherGuide = @"kTabSwitcherGuide"; -GuideName* const kTabStripTabSwitcherGuide = @"kTabStripTabSwitcherGuide"; GuideName* const kToolsMenuGuide = @"kToolsMenuGuide"; GuideName* const kTranslateInfobarOptionsGuide = @"kTranslateInfobarOptionsGuide";
diff --git a/ios/chrome/browser/ui/util/named_guide.mm b/ios/chrome/browser/ui/util/named_guide.mm index 9fa4dffe..a7ec114 100644 --- a/ios/chrome/browser/ui/util/named_guide.mm +++ b/ios/chrome/browser/ui/util/named_guide.mm
@@ -6,7 +6,6 @@ #include "base/check.h" #import "base/mac/foundation_util.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -144,8 +143,6 @@ #pragma mark - Public + (instancetype)guideWithName:(GuideName*)name view:(UIView*)view { - DCHECK(name != kTabStripTabSwitcherGuide || - !base::FeatureList::IsEnabled(kChangeTabSwitcherPosition)); while (view) { for (UILayoutGuide* guide in view.layoutGuides) { NamedGuide* namedGuide = base::mac::ObjCCast<NamedGuide>(guide);
diff --git a/ios/chrome/browser/ui/util/ui_util.h b/ios/chrome/browser/ui/util/ui_util.h index 8e096274f..1b788446 100644 --- a/ios/chrome/browser/ui/util/ui_util.h +++ b/ios/chrome/browser/ui/util/ui_util.h
@@ -20,13 +20,6 @@ // Array of widths for device idioms in portrait orientation. extern const CGFloat kPortraitWidth[INTERFACE_IDIOM_COUNT]; -// Returns true if the device is in portrait orientation or if interface -// orientation is unknown. -bool IsPortrait(); - -// Returns true if the device is in landscape orientation. -bool IsLandscape(); - // Returns the height of the screen in the current orientation. CGFloat CurrentScreenHeight();
diff --git a/ios/chrome/browser/ui/util/ui_util.mm b/ios/chrome/browser/ui/util/ui_util.mm index 302e275..4031119 100644 --- a/ios/chrome/browser/ui/util/ui_util.mm +++ b/ios/chrome/browser/ui/util/ui_util.mm
@@ -10,7 +10,6 @@ #include "base/feature_list.h" #include "base/ios/ios_util.h" #include "ios/chrome/app/tests_hook.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #include "ui/base/device_form_factor.h" @@ -29,16 +28,6 @@ 768 // IPAD_IDIOM }; -bool IsPortrait() { - UIInterfaceOrientation orient = GetInterfaceOrientation(); - return UIInterfaceOrientationIsPortrait(orient) || - orient == UIInterfaceOrientationUnknown; -} - -bool IsLandscape() { - return UIInterfaceOrientationIsLandscape(GetInterfaceOrientation()); -} - CGFloat CurrentScreenHeight() { return [UIScreen mainScreen].bounds.size.height; }
diff --git a/ios/chrome/browser/ui/util/uikit_ui_util.h b/ios/chrome/browser/ui/util/uikit_ui_util.h index 1be6b7c..e7dd076 100644 --- a/ios/chrome/browser/ui/util/uikit_ui_util.h +++ b/ios/chrome/browser/ui/util/uikit_ui_util.h
@@ -179,8 +179,8 @@ // Returns a cropped image using |cropRect| on |image|. UIImage* CropImage(UIImage* image, const CGRect& cropRect); -// Returns the interface orientation of the app. -UIInterfaceOrientation GetInterfaceOrientation(); +// Returns the interface orientation of the given window in the app. +UIInterfaceOrientation GetInterfaceOrientation(UIWindow* window); // Returns the height of the keyboard in the current orientation. CGFloat CurrentKeyboardHeight(NSValue* keyboardFrameValue); @@ -199,6 +199,13 @@ UIColor* secondColor, CGFloat fraction); +// Returns true if the window is in portrait orientation or if orientation is +// unknown. +bool IsPortrait(UIWindow* window); + +// Returns true if the window is in landscape orientation. +bool IsLandscape(UIWindow* window); + // Whether the |environment| has a compact horizontal size class. bool IsCompactWidth(id<UITraitEnvironment> environment);
diff --git a/ios/chrome/browser/ui/util/uikit_ui_util.mm b/ios/chrome/browser/ui/util/uikit_ui_util.mm index 57215a4b..3f7fd3a 100644 --- a/ios/chrome/browser/ui/util/uikit_ui_util.mm +++ b/ios/chrome/browser/ui/util/uikit_ui_util.mm
@@ -513,8 +513,12 @@ return result; } -UIInterfaceOrientation GetInterfaceOrientation() { +UIInterfaceOrientation GetInterfaceOrientation(UIWindow* window) { +#if !defined(__IPHONE_13_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_13_0 return [[UIApplication sharedApplication] statusBarOrientation]; +#else + return window.windowScene.interfaceOrientation; +#endif } CGFloat CurrentKeyboardHeight(NSValue* keyboardFrameValue) { @@ -571,6 +575,16 @@ alpha:Lerp(a1, a2, fraction)]; } +bool IsPortrait(UIWindow* window) { + UIInterfaceOrientation orient = GetInterfaceOrientation(window); + return UIInterfaceOrientationIsPortrait(orient) || + orient == UIInterfaceOrientationUnknown; +} + +bool IsLandscape(UIWindow* window) { + return UIInterfaceOrientationIsLandscape(GetInterfaceOrientation(window)); +} + bool IsCompactWidth(id<UITraitEnvironment> environment) { return IsCompactWidth(environment.traitCollection); }
diff --git a/ios/chrome/test/app/signin_test_util.h b/ios/chrome/test/app/signin_test_util.h index 64b16ad..8dfceb9f 100644 --- a/ios/chrome/test/app/signin_test_util.h +++ b/ios/chrome/test/app/signin_test_util.h
@@ -14,13 +14,6 @@ // Tears down the fake ChromeIdentityService and restores the real one. void TearDownMockAuthentication(); -// Sets up a mock AccountReconcilor that will always succeed and won't use the -// network. -void SetUpMockAccountReconcilor(); - -// Tears down the mock AccountReconcilor if it was previously set up. -void TearDownMockAccountReconcilor(); - // Signs the user out and starts clearing all identities from the // ChromeIdentityService. void SignOutAndClearIdentities();
diff --git a/ios/chrome/test/app/signin_test_util.mm b/ios/chrome/test/app/signin_test_util.mm index d85392a..279c33e 100644 --- a/ios/chrome/test/app/signin_test_util.mm +++ b/ios/chrome/test/app/signin_test_util.mm
@@ -67,14 +67,6 @@ ->ResetChromeIdentityServiceObserverForTesting(); } -void SetUpMockAccountReconcilor() { - GaiaAuthFetcherIOS::SetShouldUseGaiaAuthFetcherIOSForTesting(false); -} - -void TearDownMockAccountReconcilor() { - GaiaAuthFetcherIOS::SetShouldUseGaiaAuthFetcherIOSForTesting(true); -} - void SignOutAndClearIdentities() { // EarlGrey monitors network requests by swizzling internal iOS network // objects and expects them to be dealloced before the tear down. It is
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index 68bde08..34dc0fe 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -146,7 +146,6 @@ "//ios/chrome/browser/ui/toolbar:eg_app_support+eg2", "//ios/chrome/browser/ui/toolbar:toolbar_ui", "//ios/chrome/browser/ui/toolbar/public", - "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/util:eg_app_support+eg2", "//ios/chrome/browser/unified_consent",
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.h b/ios/chrome/test/earl_grey/chrome_earl_grey.h index fe0090a..b97b628 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.h
@@ -506,9 +506,6 @@ // Returns YES if AutofillEnableCompanyName feature is enabled. - (BOOL)isAutofillCompanyNameEnabled WARN_UNUSED_RESULT; -// Returns YES if kChangeTabSwitcherPosition feature is enabled. -- (BOOL)isChangeTabSwitcherPositionEnabled WARN_UNUSED_RESULT; - // Returns YES if DemographicMetricsReporting feature is enabled. - (BOOL)isDemographicMetricsReportingEnabled WARN_UNUSED_RESULT;
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm index c29f86a..3ff8eeb 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -924,10 +924,6 @@ return [ChromeEarlGreyAppInterface isAutofillCompanyNameEnabled]; } -- (BOOL)isChangeTabSwitcherPositionEnabled { - return [ChromeEarlGreyAppInterface isChangeTabSwitcherPositionEnabled]; -} - - (BOOL)isDemographicMetricsReportingEnabled { return [ChromeEarlGreyAppInterface isDemographicMetricsReportingEnabled]; }
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h index 67dbe10..7333e92 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h
@@ -413,9 +413,6 @@ // Returns YES if AutofillEnableCompanyName feature is enabled. + (BOOL)isAutofillCompanyNameEnabled WARN_UNUSED_RESULT; -// Returns YES if kChangeTabSwitcherPosition feature is enabled. -+ (BOOL)isChangeTabSwitcherPositionEnabled WARN_UNUSED_RESULT; - // Returns YES if DemographicMetricsReporting feature is enabled. + (BOOL)isDemographicMetricsReportingEnabled WARN_UNUSED_RESULT;
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm index 4932d4cb..78b4ad8 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
@@ -28,7 +28,6 @@ #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/settings/autofill/features.h" #import "ios/chrome/browser/ui/table_view/feature_flags.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/menu_util.h" #import "ios/chrome/browser/ui/util/named_guide.h" @@ -738,10 +737,6 @@ autofill::features::kAutofillEnableCompanyName); } -+ (BOOL)isChangeTabSwitcherPositionEnabled { - return base::FeatureList::IsEnabled(kChangeTabSwitcherPosition); -} - + (BOOL)isDemographicMetricsReportingEnabled { return base::FeatureList::IsEnabled( metrics::DemographicMetricsProvider::kDemographicMetricsReporting);
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm index b703289..87da69ae 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
@@ -52,7 +52,6 @@ #import "ios/chrome/browser/ui/tab_grid/tab_grid_constants.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_url_item.h" #import "ios/chrome/browser/ui/toolbar/primary_toolbar_view.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #import "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" @@ -356,10 +355,6 @@ } + (id<GREYMatcher>)showTabsButton { - if (IsIPadIdiom() && - !base::FeatureList::IsEnabled(kChangeTabSwitcherPosition)) { - return grey_accessibilityID(@"Enter Tab Switcher"); - } return grey_allOf(grey_accessibilityID(kToolbarStackButtonIdentifier), grey_sufficientlyVisible(), nil); }
diff --git a/ios/chrome/test/earl_grey/chrome_test_case_app_interface.mm b/ios/chrome/test/earl_grey/chrome_test_case_app_interface.mm index c89d432..7e34a86 100644 --- a/ios/chrome/test/earl_grey/chrome_test_case_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_test_case_app_interface.mm
@@ -15,11 +15,9 @@ + (void)setUpMockAuthentication { chrome_test_util::SetUpMockAuthentication(); - chrome_test_util::SetUpMockAccountReconcilor(); } + (void)tearDownMockAuthentication { - chrome_test_util::TearDownMockAccountReconcilor(); chrome_test_util::TearDownMockAuthentication(); }
diff --git a/media/gpu/v4l2/v4l2_vp9_accelerator.cc b/media/gpu/v4l2/v4l2_vp9_accelerator.cc index 57999a4..e49675a2 100644 --- a/media/gpu/v4l2/v4l2_vp9_accelerator.cc +++ b/media/gpu/v4l2/v4l2_vp9_accelerator.cc
@@ -265,7 +265,7 @@ memset(&ctrl, 0, sizeof(ctrl)); ctrl.id = V4L2_CID_MPEG_VIDEO_VP9_FRAME_HDR; ctrl.size = sizeof(v4l2_frame_hdr); - ctrl.p_vp9_frame_hdr = &v4l2_frame_hdr; + ctrl.ptr = &v4l2_frame_hdr; ctrls.push_back(ctrl); struct v4l2_ctrl_vp9_decode_param v4l2_decode_param; @@ -318,7 +318,7 @@ memset(&ctrl, 0, sizeof(ctrl)); ctrl.id = V4L2_CID_MPEG_VIDEO_VP9_DECODE_PARAM; ctrl.size = sizeof(v4l2_decode_param); - ctrl.p_vp9_decode_param = &v4l2_decode_param; + ctrl.ptr = &v4l2_decode_param; ctrls.push_back(ctrl); // Defined outside of the if() clause below as it must remain valid until @@ -336,7 +336,7 @@ memset(&ctrl, 0, sizeof(ctrl)); ctrl.id = V4L2_CID_MPEG_VIDEO_VP9_ENTROPY; ctrl.size = sizeof(v4l2_entropy); - ctrl.p_vp9_entropy = &v4l2_entropy; + ctrl.ptr = &v4l2_entropy; ctrls.push_back(ctrl); } @@ -382,7 +382,7 @@ memset(&ctrl, 0, sizeof(ctrl)); ctrl.id = V4L2_CID_MPEG_VIDEO_VP9_ENTROPY; ctrl.size = sizeof(v4l2_entropy); - ctrl.p_vp9_entropy = &v4l2_entropy; + ctrl.ptr = &v4l2_entropy; scoped_refptr<V4L2DecodeSurface> dec_surface = VP9PictureToV4L2DecodeSurface(pic.get());
diff --git a/net/android/network_change_notifier_delegate_android.cc b/net/android/network_change_notifier_delegate_android.cc index e6e0dac..7f054cc 100644 --- a/net/android/network_change_notifier_delegate_android.cc +++ b/net/android/network_change_notifier_delegate_android.cc
@@ -29,6 +29,7 @@ case NetworkChangeNotifier::CONNECTION_2G: case NetworkChangeNotifier::CONNECTION_3G: case NetworkChangeNotifier::CONNECTION_4G: + case NetworkChangeNotifier::CONNECTION_5G: case NetworkChangeNotifier::CONNECTION_NONE: case NetworkChangeNotifier::CONNECTION_BLUETOOTH: break;
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc index d900804..e84683d 100644 --- a/net/base/network_change_notifier.cc +++ b/net/base/network_change_notifier.cc
@@ -405,14 +405,9 @@ const char* NetworkChangeNotifier::ConnectionTypeToString( ConnectionType type) { static const char* const kConnectionTypeNames[] = { - "CONNECTION_UNKNOWN", - "CONNECTION_ETHERNET", - "CONNECTION_WIFI", - "CONNECTION_2G", - "CONNECTION_3G", - "CONNECTION_4G", - "CONNECTION_NONE", - "CONNECTION_BLUETOOTH" + "CONNECTION_UNKNOWN", "CONNECTION_ETHERNET", "CONNECTION_WIFI", + "CONNECTION_2G", "CONNECTION_3G", "CONNECTION_4G", + "CONNECTION_NONE", "CONNECTION_BLUETOOTH", "CONNECTION_5G", }; static_assert(base::size(kConnectionTypeNames) == NetworkChangeNotifier::CONNECTION_LAST + 1, @@ -445,6 +440,7 @@ case CONNECTION_2G: case CONNECTION_3G: case CONNECTION_4G: + case CONNECTION_5G: is_cellular = true; break; case CONNECTION_UNKNOWN:
diff --git a/net/base/network_change_notifier.h b/net/base/network_change_notifier.h index f04b540a..db390707 100644 --- a/net/base/network_change_notifier.h +++ b/net/base/network_change_notifier.h
@@ -52,9 +52,10 @@ CONNECTION_2G = 3, CONNECTION_3G = 4, CONNECTION_4G = 5, - CONNECTION_NONE = 6, // No connection. + CONNECTION_NONE = 6, // No connection. CONNECTION_BLUETOOTH = 7, - CONNECTION_LAST = CONNECTION_BLUETOOTH + CONNECTION_5G = 8, + CONNECTION_LAST = CONNECTION_5G }; // This is the NetInfo v3 set of connection technologies as seen in @@ -65,6 +66,9 @@ // // A Java counterpart will be generated for this enum. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net + // + // TODO(crbug.com/1127134): Introduce subtypes for 5G networks once they can + // be detected. enum ConnectionSubtype { SUBTYPE_UNKNOWN = 0, SUBTYPE_NONE,
diff --git a/net/base/network_change_notifier_unittest.cc b/net/base/network_change_notifier_unittest.cc index 289fba0..b5c2d86 100644 --- a/net/base/network_change_notifier_unittest.cc +++ b/net/base/network_change_notifier_unittest.cc
@@ -54,6 +54,11 @@ EXPECT_GE(100.0, max_bandwidth); EXPECT_LE(100.0, max_bandwidth); break; + case NetworkChangeNotifier::CONNECTION_5G: + // TODO(crbug.com/1127134): Expect proper bounds once we have introduced + // subtypes for 5G connections. + EXPECT_EQ(std::numeric_limits<double>::infinity(), max_bandwidth); + break; case NetworkChangeNotifier::CONNECTION_NONE: EXPECT_EQ(0.0, max_bandwidth); break;
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc index 79303c8..e319a35 100644 --- a/net/nqe/network_quality_estimator.cc +++ b/net/nqe/network_quality_estimator.cc
@@ -116,6 +116,7 @@ case NetworkChangeNotifier::ConnectionType::CONNECTION_2G: case NetworkChangeNotifier::ConnectionType::CONNECTION_3G: case NetworkChangeNotifier::ConnectionType::CONNECTION_4G: + case NetworkChangeNotifier::ConnectionType::CONNECTION_5G: #if defined(OS_ANDROID) network_id.id = android::GetTelephonyNetworkOperator(); #endif @@ -975,6 +976,7 @@ return std::min(effective_connection_type_, EFFECTIVE_CONNECTION_TYPE_SLOW_2G); case NetworkChangeNotifier::CONNECTION_4G: + case NetworkChangeNotifier::CONNECTION_5G: case NetworkChangeNotifier::CONNECTION_WIFI: return std::min(effective_connection_type_, EFFECTIVE_CONNECTION_TYPE_2G); @@ -993,6 +995,7 @@ return std::min(effective_connection_type_, EFFECTIVE_CONNECTION_TYPE_2G); case NetworkChangeNotifier::CONNECTION_4G: + case NetworkChangeNotifier::CONNECTION_5G: case NetworkChangeNotifier::CONNECTION_WIFI: return std::min(effective_connection_type_, EFFECTIVE_CONNECTION_TYPE_3G); @@ -1011,6 +1014,7 @@ return std::min(effective_connection_type_, EFFECTIVE_CONNECTION_TYPE_3G); case NetworkChangeNotifier::CONNECTION_4G: + case NetworkChangeNotifier::CONNECTION_5G: case NetworkChangeNotifier::CONNECTION_WIFI: return std::min(effective_connection_type_, EFFECTIVE_CONNECTION_TYPE_4G);
diff --git a/net/nqe/network_quality_estimator_params.cc b/net/nqe/network_quality_estimator_params.cc index 7fe22912..ff2289a 100644 --- a/net/nqe/network_quality_estimator_params.cc +++ b/net/nqe/network_quality_estimator_params.cc
@@ -124,6 +124,8 @@ return "3G"; case NetworkChangeNotifier::CONNECTION_4G: return "4G"; + case NetworkChangeNotifier::CONNECTION_5G: + return "5G"; case NetworkChangeNotifier::CONNECTION_NONE: return "None"; case NetworkChangeNotifier::CONNECTION_BLUETOOTH:
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc index 6f9435b..f643b7db 100644 --- a/net/quic/quic_network_transaction_unittest.cc +++ b/net/quic/quic_network_transaction_unittest.cc
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/stl_util.h" +#include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" @@ -214,6 +215,17 @@ return params; } +std::string ConstructDataFrameForVersion(base::StringPiece body, + quic::ParsedQuicVersion version) { + if (!version.HasIetfQuicFrames()) { + return body.as_string(); + } + std::unique_ptr<char[]> buffer; + auto header_length = + quic::HttpEncoder::SerializeDataFrameHeader(body.size(), &buffer); + return base::StrCat({base::StringPiece(buffer.get(), header_length), body}); +} + } // namespace class TestSocketPerformanceWatcher : public SocketPerformanceWatcher { @@ -613,14 +625,8 @@ std::move(headers), nullptr); } - std::string ConstructDataHeader(size_t body_len) { - if (!version_.HasIetfQuicFrames()) { - return ""; - } - std::unique_ptr<char[]> buffer; - auto header_length = - quic::HttpEncoder::SerializeDataFrameHeader(body_len, &buffer); - return std::string(buffer.get(), header_length); + std::string ConstructDataFrame(base::StringPiece body) { + return ConstructDataFrameForVersion(body, version_); } void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) { @@ -887,11 +893,10 @@ ASYNC, server_maker.MakeResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, server_maker.GetResponseHeaders("200 OK"), nullptr)); - std::string header = ConstructDataHeader(9); quic_data.AddRead( ASYNC, server_maker.MakeDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, - true, header + "quic used")); + true, ConstructDataFrame("quic used"))); // Don't care about the final ack. quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read. @@ -1098,11 +1103,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -1138,11 +1142,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -1178,11 +1181,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -1333,11 +1335,10 @@ absl::string_view(response_data.data() + offset, len))); } - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( packet_number, GetNthClientInitiatedBidirectionalStreamId(0), - false, true, header + "hello!")); + false, true, ConstructDataFrame("hello!"))); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddWrite( @@ -1408,12 +1409,10 @@ absl::string_view(response_data.data() + offset, len))); } - std::string header = ConstructDataHeader(6); - mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( packet_number, GetNthClientInitiatedBidirectionalStreamId(0), - false, true, header + "hello!")); + false, true, ConstructDataFrame("hello!"))); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddWrite( @@ -1452,11 +1451,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -1491,11 +1489,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("408 Request Timeout"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -1528,11 +1525,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -1581,11 +1577,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -1646,11 +1641,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -1738,11 +1732,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -1957,11 +1950,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -2005,11 +1997,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -2083,11 +2074,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -2168,11 +2158,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -2265,17 +2254,10 @@ ASYNC, server_maker.MakeResponseHeadersPacket( 1, client_stream_0, false, false, server_maker.GetResponseHeaders("200 OK"), nullptr)); - std::string header(""); - if (VersionUsesHttp3(picked_version.transport_version)) { - std::unique_ptr<char[]> buffer; - auto header_length = - quic::HttpEncoder::SerializeDataFrameHeader(6, &buffer); - header = std::string(buffer.get(), header_length); - } - mock_quic_data.AddRead( - ASYNC, server_maker.MakeDataPacket(2, client_stream_0, false, true, - header + "hello!")); + ASYNC, server_maker.MakeDataPacket( + 2, client_stream_0, false, true, + ConstructDataFrameForVersion("hello!", picked_version))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -2320,11 +2302,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -2448,11 +2429,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -2532,11 +2512,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -2579,11 +2558,10 @@ "connection migration with port change only")); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( SYNCHRONOUS, ConstructServerDataPacket( 3, GetNthClientInitiatedBidirectionalStreamId(0), false, - true, header + "hello!")); + true, ConstructDataFrame("hello!"))); mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckAndRstPacket( @@ -3059,7 +3037,6 @@ client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO const std::string body = "hello!"; - std::string header = ConstructDataHeader(body.length()); client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE); if (VersionUsesHttp3(version_.transport_version)) { @@ -3078,7 +3055,7 @@ quic_data2.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + body)); + ConstructDataFrame(body))); quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -3843,11 +3820,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -3978,11 +3954,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); @@ -4143,11 +4118,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK", alt_svc_list))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); @@ -4167,7 +4141,7 @@ mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -4209,11 +4183,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); @@ -4231,7 +4204,7 @@ mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -4298,11 +4271,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); @@ -4329,7 +4301,7 @@ mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -4442,11 +4414,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(21); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello from mail QUIC!")); + ConstructDataFrame("hello from mail QUIC!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); // Second QUIC request data. @@ -4463,7 +4434,7 @@ mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true, - header + "hello from mail QUIC!")); + ConstructDataFrame("hello from mail QUIC!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -4551,11 +4522,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -4629,11 +4599,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -4698,11 +4667,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF @@ -4787,11 +4755,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -4834,11 +4801,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_number++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -4908,11 +4874,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -4997,11 +4962,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_number++, 3, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -5583,11 +5547,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_number++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -5650,11 +5613,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -5982,11 +5944,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data. @@ -6114,11 +6075,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); socket_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -6155,11 +6115,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); socket_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -6341,20 +6300,18 @@ mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1)); } - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); if (!should_send_priority_packet) { mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3)); } - std::string header2 = ConstructDataHeader(10); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true, - header2 + "and hello!")); + ConstructDataFrame("and hello!"))); if (should_send_priority_packet) { mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3)); @@ -6454,20 +6411,18 @@ mock_quic_data1.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 3, 1)); } - std::string header = ConstructDataHeader(6); mock_quic_data1.AddRead( ASYNC, ConstructServerDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello1")); + ConstructDataFrame("hello1"))); if (!should_send_priority_packet) { mock_quic_data1.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 4, 3)); } - std::string header2 = ConstructDataHeader(10); mock_quic_data1.AddRead( ASYNC, ConstructServerDataPacket( 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true, - header2 + "and hello1")); + ConstructDataFrame("and hello1"))); if (should_send_priority_packet) { mock_quic_data1.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 5, 3)); @@ -6544,20 +6499,18 @@ mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket( client_packet_number2++, 3, 1)); } - std::string header3 = ConstructDataHeader(6); mock_quic_data2.AddRead( ASYNC, server_maker2.MakeDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header3 + "hello2")); + ConstructDataFrame("hello2"))); if (!should_send_priority_packet) { mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket( client_packet_number2++, 4, 3)); } - std::string header4 = ConstructDataHeader(10); mock_quic_data2.AddRead( ASYNC, server_maker2.MakeDataPacket( 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true, - header4 + "and hello2")); + ConstructDataFrame("and hello2"))); if (should_send_priority_packet) { mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket( client_packet_number2++, 5, 3)); @@ -6675,11 +6628,10 @@ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1)); } // Response body for first request. - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); if (should_send_priority_packet) { // Client ACKs the response headers. mock_quic_data.AddWrite( @@ -6739,34 +6691,22 @@ SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++)); } - std::string header = ConstructDataHeader(1); - if (!version_.HasIetfQuicFrames()) { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientRequestHeadersAndDataFramesPacket( - write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), - true, true, DEFAULT_PRIORITY, - GetRequestHeaders("POST", "https", "/"), 0, nullptr, {"1"})); - } else { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientRequestHeadersAndDataFramesPacket( - write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), - true, true, DEFAULT_PRIORITY, - GetRequestHeaders("POST", "https", "/"), 0, nullptr, - {header, "1"})); - } + mock_quic_data.AddWrite( + SYNCHRONOUS, + ConstructClientRequestHeadersAndDataFramesPacket( + write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), + true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"), + 0, nullptr, {ConstructDataFrame("1")})); mock_quic_data.AddRead( ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header2 = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header2 + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1)); @@ -6853,7 +6793,6 @@ : quic::QuicUtils::GetHeadersStreamId( version_.transport_version)); - std::string header = ConstructDataHeader(18); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, @@ -6971,21 +6910,19 @@ mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1)); } - std::string header = ConstructDataHeader(20); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true, - header + "Pushed Resource Data")); + ConstructDataFrame("Pushed Resource Data"))); if (!should_send_priority_packet) { mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3)); } - std::string header2 = ConstructDataHeader(18); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header2 + "Main Resource Data")); + ConstructDataFrame("Main Resource Data"))); if (should_send_priority_packet) { mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3)); @@ -7055,11 +6992,10 @@ ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read @@ -7225,15 +7161,9 @@ uint64_t packet_number, quic::QuicStreamId stream_id, QuicTestPacketMaker* maker) { - std::string header = ""; - if (version_.HasIetfQuicFrames()) { - std::unique_ptr<char[]> buffer; - auto header_length = - quic::HttpEncoder::SerializeDataFrameHeader(5, &buffer); - header = std::string(buffer.get(), header_length); - } - return maker->MakeDataPacket(packet_number, stream_id, false, true, - header + "hello"); + return maker->MakeDataPacket( + packet_number, stream_id, false, true, + ConstructDataFrameForVersion("hello", version_)); } std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket( @@ -7650,21 +7580,19 @@ mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1)); } - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); if (!should_send_priority_packet) { mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3)); } - std::string header2 = ConstructDataHeader(10); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true, - header2 + "and hello!")); + ConstructDataFrame("and hello!"))); if (should_send_priority_packet) { mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3)); @@ -7686,26 +7614,14 @@ GetNthServerInitiatedUnidirectionalStreamId(0), quic::QUIC_STREAM_CANCELLED, 5, 5)); } - const char kBody[] = "1"; - std::string header3 = ConstructDataHeader(1); - if (!version_.HasIetfQuicFrames()) { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientRequestHeadersAndDataFramesPacket( - client_packet_number++, - GetNthClientInitiatedBidirectionalStreamId(1), false, true, - DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"), - GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, {kBody})); - } else { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientRequestHeadersAndDataFramesPacket( - client_packet_number++, - GetNthClientInitiatedBidirectionalStreamId(1), false, true, - DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"), - GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, - {header3, kBody})); - } + mock_quic_data.AddWrite( + SYNCHRONOUS, + ConstructClientRequestHeadersAndDataFramesPacket( + client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), + false, true, DEFAULT_PRIORITY, + GetRequestHeaders("GET", "https", "/pushed.jpg"), + GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, + {ConstructDataFrame("1")})); // We see the same response as for the earlier pushed and cancelled // stream. @@ -7716,7 +7632,7 @@ mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true, - header2 + "and hello!")); + ConstructDataFrame("and hello!"))); mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6)); @@ -7791,11 +7707,10 @@ false, GetResponseHeaders("200 OK"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 3, 1)); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddRead(ASYNC, 0); mock_quic_data.AddSocketDataToFactory(&socket_factory_); @@ -7851,34 +7766,23 @@ "GET / HTTP/1.1\r\n" "Host: mail.example.org\r\n" "Connection: keep-alive\r\n\r\n"; - std::string header = ConstructDataHeader(strlen(get_request)); - if (!version_.HasIetfQuicFrames()) { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientAckAndDataPacket( - packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), - 1, 1, false, quiche::QuicheStringPiece(get_request))); - } else { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientAckAndDataPacket( - packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), - 1, 1, false, {header + std::string(get_request)})); - } + mock_quic_data.AddWrite( + SYNCHRONOUS, + ConstructClientAckAndDataPacket( + packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, + 1, false, ConstructDataFrame(get_request))); const char get_response[] = "HTTP/1.1 200 OK\r\n" "Content-Length: 10\r\n\r\n"; - std::string header2 = ConstructDataHeader(strlen(get_response)); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, - header2 + std::string(get_response))); - std::string header3 = ConstructDataHeader(10); + ConstructDataFrame(get_response))); mock_quic_data.AddRead( SYNCHRONOUS, ConstructServerDataPacket( 3, GetNthClientInitiatedBidirectionalStreamId(0), false, - false, header3 + std::string("0123456789"))); + false, ConstructDataFrame("0123456789"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 3, 2)); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -7958,38 +7862,25 @@ spdy::SpdySerializedFrame get_frame = spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST); - std::string header = ConstructDataHeader(get_frame.size()); - if (!version_.HasIetfQuicFrames()) { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientAckAndDataPacket( - packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), - 1, 1, false, - quiche::QuicheStringPiece(get_frame.data(), get_frame.size()))); - } else { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientAckAndDataPacket( - packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), - 1, 1, false, - {header + std::string(get_frame.data(), get_frame.size())})); - } + mock_quic_data.AddWrite( + SYNCHRONOUS, + ConstructClientAckAndDataPacket( + packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, + 1, false, ConstructDataFrame({get_frame.data(), get_frame.size()}))); spdy::SpdySerializedFrame resp_frame = spdy_util.ConstructSpdyGetReply(nullptr, 0, 1); - std::string header2 = ConstructDataHeader(resp_frame.size()); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, - header2 + std::string(resp_frame.data(), resp_frame.size()))); + ConstructDataFrame({resp_frame.data(), resp_frame.size()}))); spdy::SpdySerializedFrame data_frame = spdy_util.ConstructSpdyDataFrame(1, "0123456789", true); - std::string header3 = ConstructDataHeader(resp_frame.size()); mock_quic_data.AddRead( SYNCHRONOUS, ConstructServerDataPacket( 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false, - header3 + std::string(data_frame.data(), data_frame.size()))); + ConstructDataFrame({data_frame.data(), data_frame.size()}))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 3, 2)); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -8067,42 +7958,28 @@ 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - quic::QuicStreamOffset server_data_offset = 0; const char get_request_1[] = "GET / HTTP/1.1\r\n" "Host: mail.example.org\r\n" "Connection: keep-alive\r\n\r\n"; - std::string header = ConstructDataHeader(strlen(get_request_1)); - if (!version_.HasIetfQuicFrames()) { - mock_quic_data.AddWrite( - SYNCHRONOUS, ConstructClientAckAndDataPacket( - write_packet_index++, false, - GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, - false, quiche::QuicheStringPiece(get_request_1))); - } else { - mock_quic_data.AddWrite( - SYNCHRONOUS, ConstructClientAckAndDataPacket( - write_packet_index++, false, - GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, - false, {header + std::string(get_request_1)})); - } + mock_quic_data.AddWrite( + SYNCHRONOUS, ConstructClientAckAndDataPacket( + write_packet_index++, false, + GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, + false, ConstructDataFrame(get_request_1))); const char get_response_1[] = "HTTP/1.1 200 OK\r\n" "Content-Length: 10\r\n\r\n"; - std::string header2 = ConstructDataHeader(strlen(get_response_1)); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, - header2 + std::string(get_response_1))); - server_data_offset += strlen(get_response_1) + header2.length(); + ConstructDataFrame(get_response_1))); - std::string header3 = ConstructDataHeader(10); mock_quic_data.AddRead( SYNCHRONOUS, ConstructServerDataPacket( 3, GetNthClientInitiatedBidirectionalStreamId(0), false, - false, header3 + std::string("0123456789"))); - server_data_offset += 10 + header3.length(); + false, ConstructDataFrame("0123456789"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2)); @@ -8111,37 +7988,24 @@ "GET /2 HTTP/1.1\r\n" "Host: mail.example.org\r\n" "Connection: keep-alive\r\n\r\n"; - std::string header4 = ConstructDataHeader(strlen(get_request_2)); - if (version_.HasIetfQuicFrames()) { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientDataPacket( - write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), - false, false, {header4 + std::string(get_request_2)})); - } else { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientDataPacket( - write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), - false, false, quiche::QuicheStringPiece(get_request_2))); - } + mock_quic_data.AddWrite( + SYNCHRONOUS, + ConstructClientDataPacket( + write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), + false, false, ConstructDataFrame(get_request_2))); const char get_response_2[] = "HTTP/1.1 200 OK\r\n" "Content-Length: 7\r\n\r\n"; - std::string header5 = ConstructDataHeader(strlen(get_response_2)); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false, - header5 + std::string(get_response_2))); - server_data_offset += strlen(get_response_2) + header5.length(); + ConstructDataFrame(get_response_2))); - std::string header6 = ConstructDataHeader(7); mock_quic_data.AddRead( SYNCHRONOUS, ConstructServerDataPacket( 5, GetNthClientInitiatedBidirectionalStreamId(0), false, - false, header6 + std::string("0123456"))); - server_data_offset += 7 + header6.length(); + false, ConstructDataFrame("0123456"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4)); @@ -8234,34 +8098,23 @@ "GET / HTTP/1.1\r\n" "Host: mail.example.org\r\n" "Connection: keep-alive\r\n\r\n"; - std::string header = ConstructDataHeader(strlen(get_request)); - if (!version_.HasIetfQuicFrames()) { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientAckAndDataPacket( - packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), - 1, 1, false, quiche::QuicheStringPiece(get_request))); - } else { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientAckAndDataPacket( - packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), - 1, 1, false, {header + std::string(get_request)})); - } + mock_quic_data.AddWrite( + SYNCHRONOUS, + ConstructClientAckAndDataPacket( + packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, + 1, false, ConstructDataFrame(get_request))); const char get_response[] = "HTTP/1.1 200 OK\r\n" "Content-Length: 10\r\n\r\n"; - std::string header2 = ConstructDataHeader(strlen(get_response)); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, - header2 + std::string(get_response))); - std::string header3 = ConstructDataHeader(10); + ConstructDataFrame(get_response))); mock_quic_data.AddRead( SYNCHRONOUS, ConstructServerDataPacket( 3, GetNthClientInitiatedBidirectionalStreamId(0), false, - false, header3 + std::string("0123456789"))); + false, ConstructDataFrame("0123456789"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 3, 2)); @@ -8293,38 +8146,25 @@ SpdyTestUtil spdy_util; spdy::SpdySerializedFrame get_frame = spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST); - std::string header4 = ConstructDataHeader(get_frame.size()); - if (!version_.HasIetfQuicFrames()) { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientAckAndDataPacket( - packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), - 4, 4, false, - quiche::QuicheStringPiece(get_frame.data(), get_frame.size()))); - } else { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientAckAndDataPacket( - packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), - 4, 4, false, - {header4 + std::string(get_frame.data(), get_frame.size())})); - } + mock_quic_data.AddWrite( + SYNCHRONOUS, + ConstructClientAckAndDataPacket( + packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, + 4, false, ConstructDataFrame({get_frame.data(), get_frame.size()}))); spdy::SpdySerializedFrame resp_frame = spdy_util.ConstructSpdyGetReply(nullptr, 0, 1); - std::string header5 = ConstructDataHeader(resp_frame.size()); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, - header5 + std::string(resp_frame.data(), resp_frame.size()))); + ConstructDataFrame({resp_frame.data(), resp_frame.size()}))); spdy::SpdySerializedFrame data_frame = spdy_util.ConstructSpdyDataFrame(1, "0123456", true); - std::string header6 = ConstructDataHeader(data_frame.size()); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false, - header6 + std::string(data_frame.data(), data_frame.size()))); + ConstructDataFrame({data_frame.data(), data_frame.size()}))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 6, 5)); @@ -8574,34 +8414,23 @@ "GET / HTTP/1.1\r\n" "Host: mail.example.org\r\n" "Connection: keep-alive\r\n\r\n"; - std::string header = ConstructDataHeader(strlen(get_request)); - if (!version_.HasIetfQuicFrames()) { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientAckAndDataPacket( - packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), - 2, 2, false, quiche::QuicheStringPiece(get_request))); - } else { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientAckAndDataPacket( - packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), - 2, 2, false, {header + std::string(get_request)})); - } + mock_quic_data.AddWrite( + SYNCHRONOUS, + ConstructClientAckAndDataPacket( + packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, + 2, false, ConstructDataFrame(get_request))); const char get_response[] = "HTTP/1.1 200 OK\r\n" "Content-Length: 10\r\n\r\n"; - std::string header2 = ConstructDataHeader(strlen(get_response)); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false, - header2 + std::string(get_response))); + ConstructDataFrame(get_response))); - std::string header3 = ConstructDataHeader(10); mock_quic_data.AddRead( SYNCHRONOUS, ConstructServerDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(1), false, - false, header3 + std::string("0123456789"))); + false, ConstructDataFrame("0123456789"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3)); mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read @@ -8864,7 +8693,6 @@ "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS); MockQuicData mock_quic_data(version_); - quic::QuicStreamOffset server_data_offset = 0; int packet_num = 1; if (VersionUsesHttp3(version_.transport_version)) { @@ -8910,7 +8738,6 @@ 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, "0123456789")); } - server_data_offset += 10; mock_quic_data.AddWrite(SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 2, 1)); @@ -9147,37 +8974,35 @@ // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s // priority updates to match the request's priority. Client sends PRIORITY // frames to inform server of new HTTP/2 stream dependencies. - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientPriorityFramesPacket( - packet_num++, false, - {{push_stream_1, client_stream_2, - ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}, - {push_stream_0, client_stream_0, - ConvertRequestPriorityToQuicPriority(HIGHEST)}})); + mock_quic_data.AddWrite( + SYNCHRONOUS, + ConstructClientPriorityFramesPacket( + packet_num++, false, + {{push_stream_1, client_stream_2, + ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}, + {push_stream_0, client_stream_0, + ConvertRequestPriorityToQuicPriority(HIGHEST)}})); // Server sends data for the three requests and the two push promises. - std::string header = ConstructDataHeader(8); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, - header + "hello 0!")); + ConstructDataFrame("hello 0!"))); mock_quic_data.AddRead( SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, - header + "hello 1!")); + ConstructDataFrame("hello 1!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 9, 8)); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, - header + "hello 2!")); - std::string header2 = ConstructDataHeader(12); - mock_quic_data.AddRead( - SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, - header2 + "and hello 0!")); + ConstructDataFrame("hello 2!"))); + mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket( + 11, push_stream_0, false, true, + ConstructDataFrame("and hello 0!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 11, 10)); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, - header2 + "and hello 1!")); + ConstructDataFrame("and hello 1!"))); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read mock_quic_data.AddRead(ASYNC, 0); // EOF @@ -9328,7 +9153,7 @@ unpartitioned_mock_quic_data.AddRead( ASYNC, server_maker1.MakeDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, - true, ConstructDataHeader(1) + "1")); + true, ConstructDataFrame("1"))); unpartitioned_mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1)); @@ -9346,7 +9171,7 @@ unpartitioned_mock_quic_data.AddRead( ASYNC, server_maker1.MakeDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(1), false, - true, ConstructDataHeader(1) + "2")); + true, ConstructDataFrame("2"))); unpartitioned_mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3)); @@ -9364,7 +9189,7 @@ unpartitioned_mock_quic_data.AddRead( ASYNC, server_maker1.MakeDataPacket( 6, GetNthClientInitiatedBidirectionalStreamId(2), false, - true, ConstructDataHeader(1) + "3")); + true, ConstructDataFrame("3"))); unpartitioned_mock_quic_data.AddWrite( SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 6, 5)); @@ -9408,7 +9233,7 @@ partitioned_mock_quic_data1.AddRead( ASYNC, server_maker2.MakeDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, - true, ConstructDataHeader(1) + "1")); + true, ConstructDataFrame("1"))); partitioned_mock_quic_data1.AddWrite( SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 2, 1)); @@ -9426,7 +9251,7 @@ partitioned_mock_quic_data1.AddRead( ASYNC, server_maker2.MakeDataPacket( 4, GetNthClientInitiatedBidirectionalStreamId(1), false, - true, ConstructDataHeader(1) + "3")); + true, ConstructDataFrame("3"))); partitioned_mock_quic_data1.AddWrite( SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 4, 3)); @@ -9468,7 +9293,7 @@ partitioned_mock_quic_data2.AddRead( ASYNC, server_maker3.MakeDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, - true, ConstructDataHeader(1) + "2")); + true, ConstructDataFrame("2"))); partitioned_mock_quic_data2.AddWrite( SYNCHRONOUS, client_maker3.MakeAckPacket(packet_num3++, 2, 1)); @@ -9601,31 +9426,20 @@ 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"), nullptr)); - std::string header = ConstructDataHeader(strlen(kGetRequest)); - if (!version_.HasIetfQuicFrames()) { - mock_quic_data[index]->AddWrite( - SYNCHRONOUS, client_maker.MakeAckAndDataPacket( - packet_num++, false, - GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, - false, quiche::QuicheStringPiece(kGetRequest))); - } else { - mock_quic_data[index]->AddWrite( - SYNCHRONOUS, client_maker.MakeAckAndDataPacket( - packet_num++, false, - GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, - false, {header + std::string(kGetRequest)})); - } + mock_quic_data[index]->AddWrite( + SYNCHRONOUS, + client_maker.MakeAckAndDataPacket( + packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), + 1, 1, false, ConstructDataFrame(kGetRequest))); - std::string header2 = ConstructDataHeader(strlen(kGetResponse)); mock_quic_data[index]->AddRead( ASYNC, server_maker.MakeDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, - false, header2 + std::string(kGetResponse))); + false, ConstructDataFrame(kGetResponse))); mock_quic_data[index]->AddRead( - SYNCHRONOUS, - server_maker.MakeDataPacket( - 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false, - ConstructDataHeader(10) + std::string("0123456789"))); + SYNCHRONOUS, server_maker.MakeDataPacket( + 3, GetNthClientInitiatedBidirectionalStreamId(0), + false, false, ConstructDataFrame("0123456789"))); mock_quic_data[index]->AddWrite( SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2)); mock_quic_data[index]->AddRead(SYNCHRONOUS, @@ -9693,33 +9507,21 @@ SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++)); } const std::string upload_content = "foo"; - if (!version_.HasIetfQuicFrames()) { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientRequestHeadersAndDataFramesPacket( - write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), - true, true, DEFAULT_PRIORITY, - GetRequestHeaders("POST", "https", "/"), 0, nullptr, - {upload_content})); - } else { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientRequestHeadersAndDataFramesPacket( - write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), - true, true, DEFAULT_PRIORITY, - GetRequestHeaders("POST", "https", "/"), 0, nullptr, - {ConstructDataHeader(upload_content.length()), upload_content})); - } + mock_quic_data.AddWrite( + SYNCHRONOUS, + ConstructClientRequestHeadersAndDataFramesPacket( + write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), + true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"), + 0, nullptr, {ConstructDataFrame(upload_content)})); mock_quic_data.AddRead( ASYNC, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header2 = ConstructDataHeader(6); mock_quic_data.AddRead( ASYNC, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true, - header2 + "hello!")); + ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1)); @@ -9755,32 +9557,20 @@ SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++)); } const std::string upload_content = "foo"; - if (!version_.HasIetfQuicFrames()) { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientRequestHeadersAndDataFramesPacket( - write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), - true, true, DEFAULT_PRIORITY, - GetRequestHeaders("POST", "https", "/"), 0, nullptr, - {upload_content})); - } else { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientRequestHeadersAndDataFramesPacket( - write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), - true, true, DEFAULT_PRIORITY, - GetRequestHeaders("POST", "https", "/"), 0, nullptr, - {ConstructDataHeader(upload_content.length()), upload_content})); - } + mock_quic_data.AddWrite( + SYNCHRONOUS, + ConstructClientRequestHeadersAndDataFramesPacket( + write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), + true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"), + 0, nullptr, {ConstructDataFrame(upload_content)})); mock_quic_data.AddRead( SYNCHRONOUS, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header2 = ConstructDataHeader(6); mock_quic_data.AddRead( SYNCHRONOUS, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, - true, header2 + "hello!")); + true, ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1)); @@ -9836,32 +9626,20 @@ SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++)); } const std::string upload_content = "foo"; - if (!version_.HasIetfQuicFrames()) { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientRequestHeadersAndDataFramesPacket( - write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), - true, true, DEFAULT_PRIORITY, - GetRequestHeaders("POST", "https", "/"), 0, nullptr, - {upload_content})); - } else { - mock_quic_data.AddWrite( - SYNCHRONOUS, - ConstructClientRequestHeadersAndDataFramesPacket( - write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), - true, true, DEFAULT_PRIORITY, - GetRequestHeaders("POST", "https", "/"), 0, nullptr, - {ConstructDataHeader(upload_content.length()), upload_content})); - } + mock_quic_data.AddWrite( + SYNCHRONOUS, + ConstructClientRequestHeadersAndDataFramesPacket( + write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0), + true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"), + 0, nullptr, {ConstructDataFrame(upload_content)})); mock_quic_data.AddRead( SYNCHRONOUS, ConstructServerResponseHeadersPacket( 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false, GetResponseHeaders("200 OK"))); - std::string header = ConstructDataHeader(6); mock_quic_data.AddRead( SYNCHRONOUS, ConstructServerDataPacket( 2, GetNthClientInitiatedBidirectionalStreamId(0), false, - true, header + "hello!")); + true, ConstructDataFrame("hello!"))); mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1)); mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
diff --git a/net/tools/net_watcher/net_watcher.cc b/net/tools/net_watcher/net_watcher.cc index 717b595..3cb1f05f 100644 --- a/net/tools/net_watcher/net_watcher.cc +++ b/net/tools/net_watcher/net_watcher.cc
@@ -65,6 +65,8 @@ return "CONNECTION_3G"; case net::NetworkChangeNotifier::CONNECTION_4G: return "CONNECTION_4G"; + case net::NetworkChangeNotifier::CONNECTION_5G: + return "CONNECTION_5G"; case net::NetworkChangeNotifier::CONNECTION_NONE: return "CONNECTION_NONE"; case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH:
diff --git a/printing/page_range.h b/printing/page_range.h index 0d262a6..20e84fa 100644 --- a/printing/page_range.h +++ b/printing/page_range.h
@@ -5,6 +5,8 @@ #ifndef PRINTING_PAGE_RANGE_H_ #define PRINTING_PAGE_RANGE_H_ +#include <stdint.h> + #include <vector> #include "printing/printing_export.h"
diff --git a/remoting/host/policy_watcher_unittest.cc b/remoting/host/policy_watcher_unittest.cc index 18eb74b..8fb2d69 100644 --- a/remoting/host/policy_watcher_unittest.cc +++ b/remoting/host/policy_watcher_unittest.cc
@@ -530,6 +530,7 @@ "RemoteAccessHostdomain", "RemoteAccessHostPolicyForFutureVersion")); +#if !defined(OS_CHROMEOS) TEST_F(PolicyWatcherTest, PairingFalseThenTrue) { testing::InSequence sequence; EXPECT_CALL(mock_policy_callback_, @@ -559,6 +560,7 @@ SetPolicies(gnubby_auth_false_); SetPolicies(gnubby_auth_true_); } +#endif // !defined(OS_CHROMEOS) TEST_F(PolicyWatcherTest, RemoteAssistanceUiAccess) { testing::InSequence sequence; @@ -595,6 +597,7 @@ SetPolicies(relay_true_); } +#if !defined(OS_CHROMEOS) TEST_F(PolicyWatcherTest, Curtain) { testing::InSequence sequence; EXPECT_CALL(mock_policy_callback_, @@ -661,6 +664,7 @@ SetPolicies(third_party_auth_partial_); SetPolicies(third_party_auth_full_); } +#endif // !defined(OS_CHROMEOS) TEST_F(PolicyWatcherTest, UdpPortRange) { testing::InSequence sequence; @@ -693,6 +697,16 @@ // RemoteAccessHostMatchUsername is marked in policy_templates.json as not // supported on Windows and therefore is (by design) excluded from the schema. expected_schema.erase(key::kRemoteAccessHostMatchUsername); +#elif defined(OS_CHROMEOS) + // Me2Me Policies are not supported on ChromeOS. + expected_schema.erase(key::kRemoteAccessHostAllowGnubbyAuth); + expected_schema.erase(key::kRemoteAccessHostAllowClientPairing); + expected_schema.erase(key::kRemoteAccessHostMatchUsername); + expected_schema.erase(key::kRemoteAccessHostRequireCurtain); + expected_schema.erase(key::kRemoteAccessHostTokenUrl); + expected_schema.erase(key::kRemoteAccessHostTokenValidationUrl); + expected_schema.erase(key::kRemoteAccessHostTokenValidationCertificateIssuer); + expected_schema.erase(key::kRemoteAccessHostAllowUiAccessForRemoteAssistance); #else // !defined(OS_WIN) // RemoteAssistanceHostAllowUiAccess does not exist on non-Windows platforms. expected_schema.erase(key::kRemoteAccessHostAllowUiAccessForRemoteAssistance); @@ -726,14 +740,14 @@ // Check one, random "string" policy to see if the type propagated correctly // from policy_templates.json file. const policy::Schema string_schema = - schema->GetKnownProperty("RemoteAccessHostDomain"); + schema->GetKnownProperty("RemoteAccessHostUdpPortRange"); EXPECT_TRUE(string_schema.valid()); EXPECT_EQ(string_schema.type(), base::Value::Type::STRING); // And check one, random "boolean" policy to see if the type propagated // correctly from policy_templates.json file. const policy::Schema boolean_schema = - schema->GetKnownProperty("RemoteAccessHostRequireCurtain"); + schema->GetKnownProperty("RemoteAccessHostAllowRelayedConnection"); EXPECT_TRUE(boolean_schema.valid()); EXPECT_EQ(boolean_schema.type(), base::Value::Type::BOOLEAN); } @@ -784,4 +798,4 @@ ASSERT_EQ(0u, current_policies->size()); } -} // namespace remoting +} // namespace remoting \ No newline at end of file
diff --git a/services/metrics/public/cpp/ukm_recorder.h b/services/metrics/public/cpp/ukm_recorder.h index 2516a66..23309b4 100644 --- a/services/metrics/public/cpp/ukm_recorder.h +++ b/services/metrics/public/cpp/ukm_recorder.h
@@ -29,7 +29,7 @@ } // namespace metrics namespace content { -class PaymentAppProviderImpl; +class PaymentAppProviderUtil; } // namespace content namespace web_app { @@ -94,7 +94,7 @@ // Gets new source Id for PAYMENT_APP_ID type and updates the source url to // the scope of the app. This method should only be called by - // PaymentAppProviderImpl class when the payment app window is opened. + // PaymentAppProviderUtil class when the payment app window is opened. static SourceId GetSourceIdForPaymentAppFromScope( const GURL& service_worker_scope); @@ -105,7 +105,7 @@ friend blink::Document; friend metrics::UkmRecorderInterface; friend PermissionUmaUtil; - friend content::PaymentAppProviderImpl; + friend content::PaymentAppProviderUtil; // WebApkUkmRecorder and DesktopWebAppUkmRecorder record metrics about // installed web apps. Instead of using
diff --git a/services/network/network_change_manager_unittest.cc b/services/network/network_change_manager_unittest.cc index 249c0d9..052b859 100644 --- a/services/network/network_change_manager_unittest.cc +++ b/services/network/network_change_manager_unittest.cc
@@ -207,6 +207,9 @@ break; case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH: EXPECT_EQ(mojom::ConnectionType::CONNECTION_BLUETOOTH, mojoType); + break; + case net::NetworkChangeNotifier::CONNECTION_5G: + EXPECT_EQ(mojom::ConnectionType::CONNECTION_5G, mojoType); EXPECT_EQ(mojom::ConnectionType::CONNECTION_LAST, mojoType); break; }
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 591c018..4de2f631 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -433,6 +433,7 @@ #if BUILDFLAG(IS_CT_SUPPORTED) if (params_->ct_policy) SetCTPolicy(std::move(params_->ct_policy)); + SetSCTAuditingEnabled(params_->enable_sct_auditing); #endif #if defined(OS_ANDROID)
diff --git a/services/network/network_service.cc b/services/network/network_service.cc index dd365ae..3475441 100644 --- a/services/network/network_service.cc +++ b/services/network/network_service.cc
@@ -760,6 +760,19 @@ void NetworkService::ClearSCTAuditingCache() { sct_auditing_cache_->ClearCache(); } + +void NetworkService::ConfigureSCTAuditing( + bool enabled, + double sampling_rate, + const GURL& reporting_uri, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + mojo::PendingRemote<mojom::URLLoaderFactory> factory) { + sct_auditing_cache_->set_enabled(enabled); + sct_auditing_cache_->set_sampling_rate(sampling_rate); + sct_auditing_cache_->set_report_uri(reporting_uri); + sct_auditing_cache_->set_traffic_annotation(traffic_annotation); + sct_auditing_cache_->set_url_loader_factory(std::move(factory)); +} #endif #if defined(OS_ANDROID)
diff --git a/services/network/network_service.h b/services/network/network_service.h index 85dcae89..a17a843b 100644 --- a/services/network/network_service.h +++ b/services/network/network_service.h
@@ -30,6 +30,7 @@ #include "net/dns/dns_config.h" #include "net/log/net_log.h" #include "net/log/trace_net_log_observer.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "services/network/keepalive_statistics_recorder.h" #include "services/network/network_change_manager.h" #include "services/network/network_quality_estimator_manager.h" @@ -40,6 +41,7 @@ #include "services/network/public/mojom/network_quality_estimator_manager.mojom.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/mojom/trust_tokens.mojom.h" +#include "services/network/public/mojom/url_loader.mojom.h" #include "services/network/trust_tokens/trust_token_key_commitments.h" #include "services/service_manager/public/cpp/binder_registry.h" @@ -216,6 +218,12 @@ base::OnceClosure done) override; #if BUILDFLAG(IS_CT_SUPPORTED) void ClearSCTAuditingCache() override; + void ConfigureSCTAuditing( + bool enabled, + double sampling_rate, + const GURL& reporting_uri, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + mojo::PendingRemote<mojom::URLLoaderFactory> factory) override; #endif #if defined(OS_ANDROID)
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc index 257a1da..9e2b5d89 100644 --- a/services/network/public/cpp/features.cc +++ b/services/network/public/cpp/features.cc
@@ -232,13 +232,6 @@ const base::Feature kWebSocketReassembleShortMessages{ "WebSocketReassembleShortMessages", base::FEATURE_ENABLED_BY_DEFAULT}; -// Controls whether SCT audit reports are queued and the rate at which they -// should be sampled. -const base::Feature kSCTAuditing{"SCTAuditing", - base::FEATURE_DISABLED_BY_DEFAULT}; -constexpr base::FeatureParam<double> kSCTAuditingSamplingRate{ - &kSCTAuditing, "sampling_rate", 0.0}; - // Enables usage of First Party Sets to determine cookie availability. constexpr base::Feature kFirstPartySets{"FirstPartySets", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h index 069dac9..6f117fa 100644 --- a/services/network/public/cpp/features.h +++ b/services/network/public/cpp/features.h
@@ -94,11 +94,6 @@ extern const base::Feature kWebSocketReassembleShortMessages; COMPONENT_EXPORT(NETWORK_CPP) -extern const base::Feature kSCTAuditing; -COMPONENT_EXPORT(NETWORK_CPP) -extern const base::FeatureParam<double> kSCTAuditingSamplingRate; - -COMPONENT_EXPORT(NETWORK_CPP) extern const base::Feature kFirstPartySets; } // namespace features
diff --git a/services/network/public/cpp/network_connection_tracker.cc b/services/network/public/cpp/network_connection_tracker.cc index b45315c..d0d319b 100644 --- a/services/network/public/cpp/network_connection_tracker.cc +++ b/services/network/public/cpp/network_connection_tracker.cc
@@ -103,6 +103,7 @@ case network::mojom::ConnectionType::CONNECTION_2G: case network::mojom::ConnectionType::CONNECTION_3G: case network::mojom::ConnectionType::CONNECTION_4G: + case network::mojom::ConnectionType::CONNECTION_5G: is_cellular = true; break; case network::mojom::ConnectionType::CONNECTION_UNKNOWN:
diff --git a/services/network/public/cpp/network_interface_mojom_traits.cc b/services/network/public/cpp/network_interface_mojom_traits.cc index c08f595..fbcd7d4 100644 --- a/services/network/public/cpp/network_interface_mojom_traits.cc +++ b/services/network/public/cpp/network_interface_mojom_traits.cc
@@ -43,6 +43,8 @@ return network::mojom::ConnectionType::CONNECTION_3G; case net::NetworkChangeNotifier::ConnectionType::CONNECTION_4G: return network::mojom::ConnectionType::CONNECTION_4G; + case net::NetworkChangeNotifier::ConnectionType::CONNECTION_5G: + return network::mojom::ConnectionType::CONNECTION_5G; case net::NetworkChangeNotifier::ConnectionType::CONNECTION_NONE: return network::mojom::ConnectionType::CONNECTION_NONE; case net::NetworkChangeNotifier::ConnectionType::CONNECTION_BLUETOOTH: @@ -75,6 +77,9 @@ case network::mojom::ConnectionType::CONNECTION_4G: *output = net::NetworkChangeNotifier::ConnectionType::CONNECTION_4G; return true; + case network::mojom::ConnectionType::CONNECTION_5G: + *output = net::NetworkChangeNotifier::ConnectionType::CONNECTION_5G; + return true; case network::mojom::ConnectionType::CONNECTION_NONE: *output = net::NetworkChangeNotifier::ConnectionType::CONNECTION_NONE; return true;
diff --git a/services/network/public/mojom/network_change_manager.mojom b/services/network/public/mojom/network_change_manager.mojom index 07c9089..5ebd2c2 100644 --- a/services/network/public/mojom/network_change_manager.mojom +++ b/services/network/public/mojom/network_change_manager.mojom
@@ -15,7 +15,8 @@ CONNECTION_4G = 5, CONNECTION_NONE = 6, // No connection. CONNECTION_BLUETOOTH = 7, - CONNECTION_LAST = CONNECTION_BLUETOOTH + CONNECTION_5G = 8, + CONNECTION_LAST = CONNECTION_5G }; // This needs to match the definition of net::ConnectionSubtype.
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 4e4731b..6d4d6419 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -371,6 +371,14 @@ [EnableIf=is_ct_supported] bool enable_expect_ct_reporting = false; + // Enables SCT auditing, which sends reports for SCTs found in connections + // made by this network context. Can also be dynamically configured via + // NetworkContext::SetSCTAuditingEnabled(). This must be set to true and + // auditing must be enabled and configured globally via + // NetworkService::ConfigureSCTAuditing(). + [EnableIf=is_ct_supported] + bool enable_sct_auditing = false; + // The Certificate Transparency logs that are known to the client. SCTs from // these logs will be extracted and verified; other SCTs will be treated as // unrecognized. @@ -860,10 +868,6 @@ // Notification that a trust anchor was used for the given user. [EnableIf=is_chromeos] OnTrustAnchorUsed(); - - // Notification that a report was enqueued in the SCT auditing cache. - [EnableIf=is_ct_supported] - OnSCTReportReady(string cache_key); }; // Represents a distinct context for making network requests, with its own
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom index e2fecb2..9e7a148 100644 --- a/services/network/public/mojom/network_service.mojom +++ b/services/network/public/mojom/network_service.mojom
@@ -15,6 +15,7 @@ import "services/network/public/mojom/cookie_manager.mojom"; import "services/network/public/mojom/host_resolver.mojom"; import "services/network/public/mojom/http_raw_headers.mojom"; +import "services/network/public/mojom/mutable_network_traffic_annotation_tag.mojom"; import "services/network/public/mojom/net_log.mojom"; import "services/network/public/mojom/network_change_manager.mojom"; import "services/network/public/mojom/network_context.mojom"; @@ -392,6 +393,18 @@ [EnableIf=is_ct_supported] ClearSCTAuditingCache(); + // Configures SCT auditing. + // This allows the embedder to specify whether SCT auditing should be enabled, + // what sampling rate to use on reports, and which URLLoaderFactory to use for + // sending reports. + // TODO(cthomp): Document what happens if the URLLoaderFactory is destroyed. + [EnableIf=is_ct_supported] + ConfigureSCTAuditing(bool enabled, + double sampling_rate, + url.mojom.Url report_uri, + MutableNetworkTrafficAnnotationTag traffic_annotation, + pending_remote<network.mojom.URLLoaderFactory> factory); + // Calls base::debug::DumpWithoutCrashing for the network process. // TODO(http://crbug.com/934317): Remove this once done debugging renderer // hangs.
diff --git a/services/network/sct_auditing_cache.cc b/services/network/sct_auditing_cache.cc index df60a69..f14295b 100644 --- a/services/network/sct_auditing_cache.cc +++ b/services/network/sct_auditing_cache.cc
@@ -4,20 +4,33 @@ #include "services/network/sct_auditing_cache.h" +#include "base/callback.h" #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" #include "base/rand_util.h" #include "crypto/secure_hash.h" #include "crypto/sha2.h" +#include "net/base/elements_upload_data_stream.h" #include "net/base/hash_value.h" #include "net/base/host_port_pair.h" +#include "net/base/load_flags.h" +#include "net/base/net_errors.h" +#include "net/base/request_priority.h" +#include "net/base/upload_bytes_element_reader.h" #include "net/cert/ct_serialization.h" #include "net/cert/signed_certificate_timestamp.h" #include "net/cert/signed_certificate_timestamp_and_status.h" #include "net/cert/x509_certificate.h" +#include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" #include "services/network/network_context.h" #include "services/network/network_service.h" #include "services/network/public/cpp/features.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "services/network/public/mojom/network_context.mojom.h" +#include "services/network/public/mojom/url_response_head.mojom.h" #include "services/network/public/proto/sct_audit_report.pb.h" #include "third_party/boringssl/src/include/openssl/pool.h" #include "third_party/boringssl/src/include/openssl/sha.h" @@ -26,6 +39,8 @@ namespace { +constexpr int kSendSCTReportTimeoutSeconds = 30; + sct_auditing::SCTWithSourceAndVerifyStatus::SctVerifyStatus MapSCTVerifyStatusToProtoStatus(net::ct::SCTVerifyStatus status) { switch (status) { @@ -65,6 +80,48 @@ } } +// Owns the SimpleURLLoader and runs the callback and then deletes itself when +// the response arrives. +class SimpleURLLoaderOwner { + public: + using LoaderDoneCallback = + base::OnceCallback<void(int /* net_error */, + int /* http_response_code */)>; + + SimpleURLLoaderOwner(mojom::URLLoaderFactory* url_loader_factory, + std::unique_ptr<SimpleURLLoader> loader, + LoaderDoneCallback done_callback) + : loader_(std::move(loader)), done_callback_(std::move(done_callback)) { + // We only care about whether the report was successfully received, so we + // download the headers only. + // If the loader is destroyed, the callback will be canceled, so using + // base::Unretained here is safe. + loader_->DownloadHeadersOnly( + url_loader_factory, + base::BindOnce(&SimpleURLLoaderOwner::OnURLLoaderComplete, + base::Unretained(this))); + } + + SimpleURLLoaderOwner(const SimpleURLLoaderOwner&) = delete; + SimpleURLLoaderOwner& operator=(const SimpleURLLoaderOwner&) = delete; + + private: + ~SimpleURLLoaderOwner() = default; + + void OnURLLoaderComplete(scoped_refptr<net::HttpResponseHeaders> headers) { + if (done_callback_) { + int response_code = 0; + if (loader_->ResponseInfo() && loader_->ResponseInfo()->headers) + response_code = loader_->ResponseInfo()->headers->response_code(); + std::move(done_callback_).Run(loader_->NetError(), response_code); + } + delete this; + } + + std::unique_ptr<SimpleURLLoader> loader_; + LoaderDoneCallback done_callback_; +}; + } // namespace SCTAuditingCache::SCTAuditingCache(size_t cache_size) : cache_(cache_size) {} @@ -76,14 +133,12 @@ const net::X509Certificate* validated_certificate_chain, const net::SignedCertificateTimestampAndStatusList& signed_certificate_timestamps) { - if (!base::FeatureList::IsEnabled(features::kSCTAuditing) || - !context->is_sct_auditing_enabled()) { + if (!enabled_ || !context->is_sct_auditing_enabled()) return; - } // Generate the cache key for this report. In order to have the cache // deduplicate reports for the same SCTs, we compute the cache key as the - // hash of the SCTs. The digest is converted to a string for use over Mojo. + // hash of the SCTs. SHA256_CTX ctx; SHA256_Init(&ctx); for (const auto& sct : signed_certificate_timestamps) { @@ -100,6 +155,15 @@ if (it != cache_.end()) return; + // Set the `cache_key` with an null report. If we don't choose to sample these + // SCTs, then we don't need to store a report as we won't reference it again + // (and can save on memory usage). If we do choose to sample these SCTs, we + // then construct the report and move it into the cache entry for `cache_key`. + cache_.Put(cache_key, nullptr); + + if (base::RandDouble() > sampling_rate_) + return; + // Insert SCTs into cache. auto report = std::make_unique<sct_auditing::TLSConnectionReport>(); auto* connection_context = report->mutable_context(); @@ -132,20 +196,73 @@ } cache_.Put(cache_key, std::move(report)); - - // TODO(1082860): We should optimize memory usage by only storing an empty - // report for items we don't sample. - double sampling_rate = features::kSCTAuditingSamplingRate.Get(); - if (base::RandDouble() > sampling_rate) - return; - - context->client()->OnSCTReportReady(net::HashValue(cache_key).ToString()); + SendReport(cache_key); } sct_auditing::TLSConnectionReport* SCTAuditingCache::GetPendingReport( const net::SHA256HashValue& cache_key) { - NOTIMPLEMENTED(); - return nullptr; + auto it = cache_.Get(cache_key); + if (it == cache_.end()) + return nullptr; + return it->second.get(); +} + +void SCTAuditingCache::SendReport(const net::SHA256HashValue& cache_key) { + // Ensure that the URLLoaderFactory is still connected. + if (!url_loader_factory_ || !url_loader_factory_.is_connected()) { + // TODO(cthomp): Should this signal to embedder that something has failed? + return; + } + + // (1) Get the report from the cache, if it exists. + auto* report = GetPendingReport(cache_key); + if (!report) { + // TODO(crbug.com/1082860): This generally means that the report has been + // evicted from the cache. We should handle this more gracefully once we + // implement retrying reports as that will increase the likelihood. + return; + } + + // (2) Create a SimpleURLLoader for the request. + auto report_request = std::make_unique<ResourceRequest>(); + report_request->url = report_uri_; + report_request->method = "POST"; + report_request->load_flags = net::LOAD_DISABLE_CACHE; + report_request->credentials_mode = network::mojom::CredentialsMode::kOmit; + + auto url_loader = SimpleURLLoader::Create( + std::move(report_request), + static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation_)); + url_loader->SetTimeoutDuration( + base::TimeDelta::FromSeconds(kSendSCTReportTimeoutSeconds)); + + // (3) Serialize the report and attach it to the loader. + std::string report_data; + bool ok = report->SerializeToString(&report_data); + DCHECK(ok); + url_loader->AttachStringForUpload(report_data, "application/octet-stream"); + + // (4) Pass the loader to an owner for its lifetime. This initiates the + // request and will handle calling `callback` when the request completes + // (on success or error) or times out. + // The callback takes a WeakPtr as the SCTAuditingCache or Network Service + // could be destroyed before the callback triggers. + auto done_callback = base::BindOnce(&SCTAuditingCache::OnReportComplete, + weak_factory_.GetWeakPtr(), cache_key); + new SimpleURLLoaderOwner(url_loader_factory_.get(), std::move(url_loader), + std::move(done_callback)); +} + +void SCTAuditingCache::OnReportComplete(const net::SHA256HashValue& cache_key, + int net_error, + int http_response_code) { + // TODO(crbug.com/1082860): Mark report as complete on success, handle retries + // on failures. For now we empty the cache entry to save space once it has + // been successfully sent. + if (net_error == net::OK && http_response_code == net::HTTP_OK) { + if (GetPendingReport(cache_key)) + cache_.Put(cache_key, nullptr); + } } void SCTAuditingCache::ClearCache() {
diff --git a/services/network/sct_auditing_cache.h b/services/network/sct_auditing_cache.h index ef6f5a947..2aefe21 100644 --- a/services/network/sct_auditing_cache.h +++ b/services/network/sct_auditing_cache.h
@@ -5,6 +5,7 @@ #ifndef SERVICES_NETWORK_SCT_AUDITING_CACHE_H_ #define SERVICES_NETWORK_SCT_AUDITING_CACHE_H_ +#include <map> #include <string> #include <vector> @@ -15,6 +16,9 @@ #include "net/base/host_port_pair.h" #include "net/cert/sct_auditing_delegate.h" #include "net/cert/signed_certificate_timestamp_and_status.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "net/url_request/url_request.h" +#include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/proto/sct_audit_report.pb.h" namespace net { @@ -29,6 +33,10 @@ // than once. The cache evicts least-recently-used entries after it reaches its // capacity. // +// The SCTAuditingCache also handles sending reports to a specified report URL +// using a specific NetworkContext. These are configured by the embedder via the +// network service's ConfigureSCTAuditing() API. +// // A single SCTAuditingCache should be shared among all contexts that want to // deduplicate reports and use a single sampling mechanism. Currently, one // SCTAuditingCache is created and owned by the NetworkService and shared @@ -44,10 +52,8 @@ // Creates a report containing the details about the connection context and // SCTs and adds it to the cache if the SCTs are not already in the // cache. If the SCTs were not already in the cache, a random sample is drawn - // to determine whether to notify the NetworkContextClient (and thus send a - // report). This means we sample a subset of *certificates* rather than a - // subset of *connections*. If a new entry is sampled, the associated - // NetworkContextClient is notified. + // to determine whether to send a report. This means we sample a subset of + // *certificates* rather than a subset of *connections*. void MaybeEnqueueReport( NetworkContext* context, const net::HostPortPair& host_port_pair, @@ -58,8 +64,25 @@ sct_auditing::TLSConnectionReport* GetPendingReport( const net::SHA256HashValue& cache_key); + // Sends the report associated with `cache_key` to `report_uri` (which is + // specified by the embedder). When the request completes (on success or + // failure), `callback` will be called with the response details. + void SendReport(const net::SHA256HashValue& cache_key); + void ClearCache(); + void set_enabled(bool enabled) { enabled_ = enabled; } + void set_sampling_rate(double rate) { sampling_rate_ = rate; } + void set_report_uri(const GURL& report_uri) { report_uri_ = report_uri; } + void set_traffic_annotation( + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { + traffic_annotation_ = traffic_annotation; + } + void set_url_loader_factory( + mojo::PendingRemote<mojom::URLLoaderFactory> factory) { + url_loader_factory_.Bind(std::move(factory)); + } + base::MRUCache<net::SHA256HashValue, std::unique_ptr<sct_auditing::TLSConnectionReport>>* GetCacheForTesting() { @@ -67,9 +90,21 @@ } private: + void OnReportComplete(const net::SHA256HashValue& cache_key, + int net_error, + int http_response_code); + base::MRUCache<net::SHA256HashValue, std::unique_ptr<sct_auditing::TLSConnectionReport>> cache_; + + bool enabled_ = false; + double sampling_rate_ = 0; + GURL report_uri_; + net::MutableNetworkTrafficAnnotationTag traffic_annotation_; + mojo::Remote<mojom::URLLoaderFactory> url_loader_factory_; + + base::WeakPtrFactory<SCTAuditingCache> weak_factory_{this}; }; } // namespace network
diff --git a/services/network/sct_auditing_cache_unittest.cc b/services/network/sct_auditing_cache_unittest.cc index 82df969..45758a3 100644 --- a/services/network/sct_auditing_cache_unittest.cc +++ b/services/network/sct_auditing_cache_unittest.cc
@@ -15,25 +15,21 @@ #include "net/cert/signed_certificate_timestamp_and_status.h" #include "net/test/cert_test_util.h" #include "net/test/test_data_directory.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "services/network/network_context.h" #include "services/network/network_service.h" #include "services/network/public/cpp/features.h" #include "services/network/public/proto/sct_audit_report.pb.h" #include "services/network/test/test_network_context_client.h" +#include "services/network/test/test_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" namespace network { namespace { -base::test::ScopedFeatureList::FeatureAndParams probability_zero{ - network::features::kSCTAuditing, - {{network::features::kSCTAuditingSamplingRate.name, "0.0"}}}; -base::test::ScopedFeatureList::FeatureAndParams probability_one{ - network::features::kSCTAuditing, - {{network::features::kSCTAuditingSamplingRate.name, "1.0"}}}; - class SCTAuditingCacheTest : public testing::Test { public: SCTAuditingCacheTest() @@ -67,11 +63,33 @@ network_context_->SetClient(std::move(network_context_client_remote)); } + // Initializes the configuration for the SCTAuditingCache to defaults and + // sets up the URLLoaderFactory. Individual tests can directly call the set_* + // methods to tweak the configuration. + void InitSCTAuditing(SCTAuditingCache* cache) { + cache->set_enabled(true); + cache->set_sampling_rate(1.0); + cache->set_report_uri(GURL("https://example.test")); + cache->set_traffic_annotation( + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); + + url_loader_factory_ = std::make_unique<TestURLLoaderFactory>(); + mojo::PendingRemote<network::mojom::URLLoaderFactory> factory_client; + url_loader_factory_->Clone(factory_client.InitWithNewPipeAndPassReceiver()); + cache->set_url_loader_factory(std::move(factory_client)); + } + + // Getter for TestURLLoaderFactory to allow tests to specify responses. + TestURLLoaderFactory* url_loader_factory() { + return url_loader_factory_.get(); + } + base::test::TaskEnvironment task_environment_{ base::test::TaskEnvironment::MainThreadType::IO}; std::unique_ptr<NetworkService> network_service_; std::unique_ptr<NetworkContext> network_context_; std::unique_ptr<network::mojom::NetworkContextClient> network_context_client_; + std::unique_ptr<TestURLLoaderFactory> url_loader_factory_; scoped_refptr<net::X509Certificate> chain_; @@ -115,9 +133,8 @@ // Test that if auditing is disabled on the NetworkContext, no reports are // cached. TEST_F(SCTAuditingCacheTest, NoReportsCachedWhenAuditingDisabled) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeaturesAndParameters({probability_one}, {}); SCTAuditingCache cache(10); + InitSCTAuditing(&cache); network_context_->SetIsSCTAuditingEnabledForTesting(false); @@ -134,9 +151,8 @@ // Test that inserting and retrieving a report works. TEST_F(SCTAuditingCacheTest, InsertAndRetrieveReport) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeaturesAndParameters({probability_one}, {}); SCTAuditingCache cache(10); + InitSCTAuditing(&cache); const net::HostPortPair host_port_pair("example.com", 443); net::SignedCertificateTimestampAndStatusList sct_list; @@ -151,9 +167,8 @@ // Tests that old entries are evicted when the cache is full. TEST_F(SCTAuditingCacheTest, EvictLRUAfterCacheFull) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeaturesAndParameters({probability_one}, {}); SCTAuditingCache cache(2); + InitSCTAuditing(&cache); const net::HostPortPair host_port_pair1("example1.com", 443); const net::HostPortPair host_port_pair2("example2.com", 443); @@ -198,9 +213,8 @@ // Tests that a new report gets dropped if the same SCTs are already in the // cache. TEST_F(SCTAuditingCacheTest, ReportWithSameSCTsDeduplicated) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeaturesAndParameters({probability_one}, {}); SCTAuditingCache cache(10); + InitSCTAuditing(&cache); const net::HostPortPair host_port_pair1("example.com", 443); const net::HostPortPair host_port_pair2("example.org", 443); @@ -224,9 +238,8 @@ // When a report gets deduplicated, the existing entry should have its last-seen // time bumped up. TEST_F(SCTAuditingCacheTest, DeduplicationUpdatesLastSeenTime) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeaturesAndParameters({probability_one}, {}); SCTAuditingCache cache(2); + InitSCTAuditing(&cache); const net::HostPortPair host_port_pair1("example1.com", 443); const net::HostPortPair host_port_pair2("example2.com", 443); @@ -270,4 +283,110 @@ } } +TEST_F(SCTAuditingCacheTest, NoReportsCachedWhenCacheDisabled) { + SCTAuditingCache cache(2); + InitSCTAuditing(&cache); + cache.set_enabled(false); + + // Try to enqueue a report. + const net::HostPortPair host_port_pair("example.com", 443); + net::SignedCertificateTimestampAndStatusList sct_list; + MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, + "extensions", "signature", base::Time::Now(), + net::ct::SCT_STATUS_LOG_UNKNOWN, &sct_list); + cache.MaybeEnqueueReport(network_context_.get(), host_port_pair, chain_.get(), + sct_list); + + // Check that there are no entries in the cache. + EXPECT_EQ(0u, cache.GetCacheForTesting()->size()); +} + +TEST_F(SCTAuditingCacheTest, ReportsCachedButNotSentWhenSamplingIsZero) { + SCTAuditingCache cache(2); + InitSCTAuditing(&cache); + cache.set_sampling_rate(0); + + // Enqueue a report. + const net::HostPortPair host_port_pair("example.com", 443); + net::SignedCertificateTimestampAndStatusList sct_list; + MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, + "extensions", "signature", base::Time::Now(), + net::ct::SCT_STATUS_LOG_UNKNOWN, &sct_list); + cache.MaybeEnqueueReport(network_context_.get(), host_port_pair, chain_.get(), + sct_list); + + // Check that there is one entry in the cache. + EXPECT_EQ(1u, cache.GetCacheForTesting()->size()); + + // Check that there are no pending reports. + EXPECT_EQ(0, url_loader_factory()->NumPending()); +} + +// Tests that when a new report is sampled, it will be sent to the server. +// TODO(cthomp): Allow tracking success/failure of the report being sent. One +// way would be to have OnSuccess/OnError handlers be defined by an +// SCTAuditingReportingDelegate installed on the cache. +TEST_F(SCTAuditingCacheTest, ReportsSentWithServerOK) { + SCTAuditingCache cache(2); + InitSCTAuditing(&cache); + + // Enqueue a report which will trigger a send. + const net::HostPortPair host_port_pair("example.com", 443); + net::SignedCertificateTimestampAndStatusList sct_list; + MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, + "extensions", "signature", base::Time::Now(), + net::ct::SCT_STATUS_LOG_UNKNOWN, &sct_list); + cache.MaybeEnqueueReport(network_context_.get(), host_port_pair, chain_.get(), + sct_list); + + // Check that there is one pending report. + EXPECT_EQ(1, url_loader_factory()->NumPending()); + + // Simulate the server returning 200 OK to the report request. + url_loader_factory()->AddResponse("https://example.test", + /*content=*/"", + /*status=*/net::HTTP_OK); + task_environment_.RunUntilIdle(); + + EXPECT_EQ(0, url_loader_factory()->NumPending()); + + // Check that the report has been cleared in the cache as it has been + // successfully sent. + for (const auto& entry : *cache.GetCacheForTesting()) { + EXPECT_FALSE(entry.second); + } +} + +// Tests when the report server returns an HTTP error code. +// TODO(cthomp): Check that the cache treats the send as a failure. +TEST_F(SCTAuditingCacheTest, ReportSentWithServerError) { + SCTAuditingCache cache(2); + InitSCTAuditing(&cache); + + // Enqueue a report which will trigger a send. + const net::HostPortPair host_port_pair("example.com", 443); + net::SignedCertificateTimestampAndStatusList sct_list; + MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, + "extensions", "signature", base::Time::Now(), + net::ct::SCT_STATUS_LOG_UNKNOWN, &sct_list); + cache.MaybeEnqueueReport(network_context_.get(), host_port_pair, chain_.get(), + sct_list); + + // Check that there is one pending report. + EXPECT_EQ(1, url_loader_factory()->NumPending()); + + // Simulate the server returning 429 TOO MANY REQUEST to the report request. + url_loader_factory()->AddResponse("https://example.test", + /*content=*/"", + /*status=*/net::HTTP_TOO_MANY_REQUESTS); + task_environment_.RunUntilIdle(); + + EXPECT_EQ(0, url_loader_factory()->NumPending()); + + // Check that the report is still stored in the cache as it has not succeeded. + for (const auto& entry : *cache.GetCacheForTesting()) { + EXPECT_TRUE(entry.second); + } +} + } // namespace network
diff --git a/services/network/test/test_network_context_client.h b/services/network/test/test_network_context_client.h index 0e7d940f..8b2f8598 100644 --- a/services/network/test/test_network_context_client.h +++ b/services/network/test/test_network_context_client.h
@@ -82,7 +82,6 @@ void OnTrustAnchorUsed() override {} #endif #if BUILDFLAG(IS_CT_SUPPORTED) - void OnSCTReportReady(const std::string& cache_key) override {} #endif private:
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_linux.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_linux.cc index f0aa537a..c3af87b 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_linux.cc +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_linux.cc
@@ -5,8 +5,6 @@ #include <dlfcn.h> #include <fcntl.h> #include <stdint.h> -#include <sys/prctl.h> - #include <memory> #include "base/android/library_loader/anchor_functions.h" @@ -230,44 +228,6 @@ return num_valid_regions; } -// RAII class making the current process dumpable via prctl(PR_SET_DUMPABLE, 1), -// in case it is not currently dumpable as described in proc(5) and prctl(2). -// Noop if the original dumpable state could not be determined. -class ScopedProcessSetDumpable { - public: - ScopedProcessSetDumpable() { - int result = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0); - if (result < 0) { - PLOG(ERROR) << "prctl"; - AvoidPrctlOnDestruction(); - return; - } - was_dumpable_ = result > 0; - - if (!was_dumpable_) { - if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) != 0) { - PLOG(ERROR) << "prctl"; - // PR_SET_DUMPABLE is often disallowed, avoid crashing in this case. - AvoidPrctlOnDestruction(); - } - } - } - - ScopedProcessSetDumpable(const ScopedProcessSetDumpable&) = delete; - ScopedProcessSetDumpable& operator=(const ScopedProcessSetDumpable&) = delete; - - ~ScopedProcessSetDumpable() { - if (!was_dumpable_) { - PCHECK(prctl(PR_SET_DUMPABLE, 0, 0, 0, 0)); - } - } - - private: - void AvoidPrctlOnDestruction() { was_dumpable_ = true; } - - bool was_dumpable_; -}; - } // namespace FILE* g_proc_smaps_for_testing = nullptr; @@ -368,14 +328,8 @@ base::ScopedFILE pagemap_file(fopen(kPagemap, "r")); if (!pagemap_file.get()) { - { - ScopedProcessSetDumpable set_dumpable; - pagemap_file.reset(fopen(kPagemap, "r")); - } - if (!pagemap_file.get()) { - DLOG(WARNING) << "Could not open " << kPagemap; - return OSMetrics::MappedAndResidentPagesDumpState::kAccessPagemapDenied; - } + DLOG(WARNING) << "Could not open " << kPagemap; + return OSMetrics::MappedAndResidentPagesDumpState::kAccessPagemapDenied; } const size_t kPageSize = base::GetPageSize();
diff --git a/testing/buildbot/chromium.ci.json b/testing/buildbot/chromium.ci.json index 0ef037cd..b4654cf 100644 --- a/testing/buildbot/chromium.ci.json +++ b/testing/buildbot/chromium.ci.json
@@ -252421,6 +252421,37 @@ } ] }, + "linux-wpt-payments-fyi-rel": { + "isolated_scripts": [ + { + "args": [ + "payment-handler/", + "payment-method-basic-card/", + "payment-method-id/", + "payment-request/" + ], + "isolate_name": "wpt_tests_isolate", + "merge": { + "args": [ + "--verbose" + ], + "script": "//third_party/blink/tools/merge_web_test_results.py" + }, + "name": "wpt_tests_suite", + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://:wpt_tests_isolate/" + } + ] + }, "mac-archive-dbg": { "additional_compile_targets": [ "all"
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 25d858f0..80176d36 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -48403,6 +48403,37 @@ } ] }, + "linux-wpt-payments-fyi-rel": { + "isolated_scripts": [ + { + "args": [ + "payment-handler/", + "payment-method-basic-card/", + "payment-method-id/", + "payment-request/" + ], + "isolate_name": "wpt_tests_isolate", + "merge": { + "args": [ + "--verbose" + ], + "script": "//third_party/blink/tools/merge_web_test_results.py" + }, + "name": "wpt_tests_suite", + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://:wpt_tests_isolate/" + } + ] + }, "mac-arm64-rel-tests": { "gtest_tests": [ {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index dce585d6..18aa126 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -4536,6 +4536,28 @@ }, }, }, + + 'wpt_web_tests_payments': { + 'wpt_tests_suite': { + 'args': [ + 'payment-handler/', + 'payment-method-basic-card/', + 'payment-method-id/', + 'payment-request/', + ], + 'merge': { + 'args': [ + '--verbose', + ], + 'script': '//third_party/blink/tools/merge_web_test_results.py', + }, + 'isolate_name': 'wpt_tests_isolate', + 'results_handler': 'layout tests', + 'swarming': { + 'shards': 1, + }, + }, + }, }, ##############################################################################
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 5f90a1e..dbdec65 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -2391,6 +2391,14 @@ 'isolated_scripts': 'wpt_web_tests_identity', }, }, + 'linux-wpt-payments-fyi-rel': { + 'mixins': [ + 'linux-xenial', + ], + 'test_suites': { + 'isolated_scripts': 'wpt_web_tests_payments', + }, + }, 'mac-arm64-rel-tests': { 'mixins': [ 'mac_arm64_apple_dtk_experimental',
diff --git a/testing/scripts/OWNERS b/testing/scripts/OWNERS index 7ecff41..a9d2e406 100644 --- a/testing/scripts/OWNERS +++ b/testing/scripts/OWNERS
@@ -10,9 +10,9 @@ per-file run_wpt_tests.py=lpz@chromium.org per-file run_wpt_tests.py=robertma@chromium.org -per-file wpt_common.py=lpz@chromium.org -per-file wpt_common.py=robertma@chromium.org -per-file wpt_common.py=rmhasan@chromium.org +per-file wpt_common*.py=lpz@chromium.org +per-file wpt_common*.py=robertma@chromium.org +per-file wpt_common*.py=rmhasan@chromium.org per-file run_performance_tests.py=johnchen@chromium.org per-file run_performance_tests.py=wenbinzhang@google.com
diff --git a/testing/scripts/PRESUBMIT.py b/testing/scripts/PRESUBMIT.py new file mode 100644 index 0000000..914728fc --- /dev/null +++ b/testing/scripts/PRESUBMIT.py
@@ -0,0 +1,19 @@ +# Copyright 2020 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. + +"""Top-level presubmit script for testing/trigger_scripts. + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts +for more details about the presubmit API built into depot_tools. +""" + +def CommonChecks(input_api, output_api): + return input_api.canned_checks.RunUnitTestsInDirectory( + input_api, output_api, '.', whitelist=[r'^.+_unittest\.py$']) + +def CheckChangeOnUpload(input_api, output_api): + return CommonChecks(input_api, output_api) + +def CheckChangeOnCommit(input_api, output_api): + return CommonChecks(input_api, output_api)
diff --git a/testing/scripts/get_compile_targets.py b/testing/scripts/get_compile_targets.py index 1e5fcf0..9aadc7c 100755 --- a/testing/scripts/get_compile_targets.py +++ b/testing/scripts/get_compile_targets.py
@@ -30,8 +30,10 @@ if filename in ('common.py', 'get_compile_targets.py', 'gpu_integration_test_adapter.py', + 'PRESUBMIT.py', 'sizes_common.py', - 'wpt_common.py'): + 'wpt_common.py', + 'wpt_common_unittest.py'): continue with common.temporary_file() as tempfile_path:
diff --git a/testing/scripts/wpt_common.py b/testing/scripts/wpt_common.py index 5d0efa7..be08a3c 100644 --- a/testing/scripts/wpt_common.py +++ b/testing/scripts/wpt_common.py
@@ -26,12 +26,16 @@ as integrating output with the results viewer. Subclasses contain other (usually platform-specific) logic.""" - def __init__(self): + def __init__(self, host=None): super(BaseWptScriptAdapter, self).__init__() - self.fs = FileSystem() - host = Host() + if not host: + host = Host() + self.fs = host.filesystem self.port = host.port_factory.get() self.wpt_manifest = self.port.wpt_manifest("external/wpt") + # Path to the output of the test run. Comes from the args passed to the + # run, parsed after this constructor. Can be overwritten by tests. + self.wpt_output = None def generate_test_output_args(self, output): return ['--log-chromium', output] @@ -47,24 +51,27 @@ '--chunk-type=hash'] def do_post_test_run_tasks(self): + if not self.wpt_output and self.options: + self.wpt_output = self.options.isolated_script_test_output + # Move json results into layout-test-results directory - results_dir = os.path.dirname(self.options.isolated_script_test_output) + results_dir = os.path.dirname(self.wpt_output) layout_test_results = os.path.join(results_dir, 'layout-test-results') - if os.path.exists(layout_test_results): + if self.fs.exists(layout_test_results): self.fs.rmtree(layout_test_results) self.fs.maybe_make_directory(layout_test_results) # Perform post-processing of wptrunner output self.process_wptrunner_output() - self.fs.copyfile(self.options.isolated_script_test_output, + self.fs.copyfile(self.wpt_output, os.path.join(layout_test_results, 'full_results.json')) # create full_results_jsonp.js file which is used to # load results into the results viewer self.fs.write_text_file( os.path.join(layout_test_results, 'full_results_jsonp.js'), 'ADD_FULL_RESULTS(%s);' % self.fs.read_text_file( - self.options.isolated_script_test_output)) + self.wpt_output)) # copy layout test results viewer to layout-test-results directory self.fs.copyfile( @@ -78,13 +85,13 @@ or artifacts which need to be extracted into their own files and removed from the json file (to avoid duplication).""" output_json = json.loads( - self.fs.read_text_file(self.options.isolated_script_test_output)) + self.fs.read_text_file(self.wpt_output)) test_json = output_json["tests"] - results_dir = os.path.dirname(self.options.isolated_script_test_output) + results_dir = os.path.dirname(self.wpt_output) self._process_test_leaves(results_dir, output_json["path_delimiter"], test_json, "") # Write output_json back to the same file after modifying it in memory - self.fs.write_text_file(self.options.isolated_script_test_output, + self.fs.write_text_file(self.wpt_output, json.dumps(output_json)) def _process_test_leaves(self, results_dir, delim, root_node, path_so_far): @@ -131,6 +138,8 @@ artifact_subpath = self._write_log_artifact( test_failures.FILENAME_SUFFIX_CRASH_LOG, results_dir, path_so_far, crashlog_artifact) + if artifact_subpath: + root_node["artifacts"]["crash_log"] = [artifact_subpath] return @@ -169,7 +178,7 @@ test_file_path = os.path.join(EXTERNAL_WPT_TESTS_DIR, test_file_subpath) expected_ini_path = test_file_path + ".ini" - if not os.path.exists(expected_ini_path): + if not self.fs.exists(expected_ini_path): return None # This test has checked-in expected output. It needs to be copied to the @@ -206,7 +215,7 @@ ) log_artifact_full_path = os.path.join(results_dir, log_artifact_sub_path) - if not os.path.exists(os.path.dirname(log_artifact_full_path)): + if not self.fs.exists(os.path.dirname(log_artifact_full_path)): self.fs.maybe_make_directory( os.path.dirname(log_artifact_full_path)) self.fs.write_text_file(log_artifact_full_path, @@ -257,7 +266,7 @@ result[screenshot_key] = screenshot_sub_path screenshot_full_path = os.path.join(results_dir,screenshot_sub_path) - if not os.path.exists(os.path.dirname(screenshot_full_path)): + if not self.fs.exists(os.path.dirname(screenshot_full_path)): self.fs.maybe_make_directory( os.path.dirname(screenshot_full_path)) # Note: we are writing raw bytes to this file
diff --git a/testing/scripts/wpt_common_unittest.py b/testing/scripts/wpt_common_unittest.py new file mode 100755 index 0000000..33ba1d96 --- /dev/null +++ b/testing/scripts/wpt_common_unittest.py
@@ -0,0 +1,333 @@ +#!/usr/bin/env vpython +# Copyright (c) 2020 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. + +"""Unit tests for common functionality of wpt testing scripts.""" + +import base64 +import json +import os +import unittest + +from wpt_common import ( + BaseWptScriptAdapter, EXTERNAL_WPT_TESTS_DIR, WEB_TESTS_DIR +) + +from blinkpy.common.host_mock import MockHost +from blinkpy.web_tests.port.factory_mock import MockPortFactory +from blinkpy.w3c.wpt_manifest import BASE_MANIFEST_NAME + +# The path where the output of a wpt run was written. This is the file that +# gets processed by BaseWptScriptAdapter. +OUTPUT_JSON_FILENAME = "/out.json" + + +class BaseWptScriptAdapterTest(unittest.TestCase): + def setUp(self): + self.host = MockHost() + self.host.port_factory = MockPortFactory(self.host) + self.port = self.host.port_factory.get() + + # Create a testing manifest containing any test files that we + # might interact with. + self.host.filesystem.write_text_file( + self.port.web_tests_dir() + '/external/' + BASE_MANIFEST_NAME, + json.dumps({ + 'items': { + 'reftest': { + 'reftest.html': [ + 'c3f2fb6f436da59d43aeda0a7e8a018084557033', + [None, [['reftest-ref.html', '==']], {}], + ] + }, + 'testharness': { + 'test.html': [ + 'd933fd981d4a33ba82fb2b000234859bdda1494e', + [None, {}] + ], + 'crash.html': [ + 'd933fd981d4a33ba82fb2b000234859bdda1494e', + [None, {}] + ], + 'variant.html': [ + 'b8db5972284d1ac6bbda0da81621d9bca5d04ee7', + ['variant.html?foo=bar/abc', {}], + ['variant.html?foo=baz', {}], + ], + 'dir': { + 'multiglob.https.any.js': [ + 'd6498c3e388e0c637830fa080cca78b0ab0e5305', + ['dir/multiglob.https.any.window.html', {}], + ['dir/multiglob.https.any.worker.html', {}], + ], + }, + }, + }, + })) + self.host.filesystem.write_text_file( + os.path.join(WEB_TESTS_DIR, "fast", "harness", "results.html"), + "results-viewer-body") + self.wpt_adapter = BaseWptScriptAdapter(self.host) + self.wpt_adapter.wpt_output = OUTPUT_JSON_FILENAME + + def _create_json_output(self, json_dict): + """Writing some json output for processing.""" + self.host.filesystem.write_text_file(OUTPUT_JSON_FILENAME, + json.dumps(json_dict)) + + def _load_json_output(self): + """Loads the json output after post-processing.""" + return json.loads(self.host.filesystem.read_text_file( + OUTPUT_JSON_FILENAME)) + + def test_write_log_artifact(self): + # Ensure that log artifacts are written to the correct location. + json_dict = { + 'tests': { + 'test.html': { + 'expected': 'PASS', + 'actual': 'PASS', + 'artifacts': { + 'wpt_actual_status': ['OK'], + 'log': ['test.html actual text'], + }, + }, + }, + 'path_delimiter': '/', + } + self._create_json_output(json_dict) + self.wpt_adapter.do_post_test_run_tasks() + written_files = self.wpt_adapter.fs.written_files + self.assertEqual( + "test.html actual text", + written_files["/layout-test-results/test-actual.txt"]) + # Ensure the artifact in the json was replaced with the location of + # the newly-created file. + updated_json = self._load_json_output() + self.assertFalse( + "log" in updated_json["tests"]["test.html"]["artifacts"]) + self.assertEqual( + ["layout-test-results/test-actual.txt"], + updated_json["tests"]["test.html"]["artifacts"]["actual_text"]) + + def test_write_crashlog_artifact(self): + # Ensure that crash log artifacts are written to the correct location. + json_dict = { + 'tests': { + 'test.html': { + 'expected': 'PASS', + 'actual': 'CRASH', + 'artifacts': { + 'wpt_actual_status': ['CRASH'], + 'wpt_crash_log': ['test.html crashed!'], + }, + }, + }, + 'path_delimiter': '/', + } + self._create_json_output(json_dict) + self.wpt_adapter.do_post_test_run_tasks() + written_files = self.wpt_adapter.fs.written_files + self.assertEqual( + "test.html crashed!", + written_files["/layout-test-results/test-crash-log.txt"]) + # Ensure the artifact in the json was replaced with the location of + # the newly-created file. + updated_json = self._load_json_output() + self.assertFalse( + "wpt_crash_log" in updated_json["tests"]["test.html"]["artifacts"]) + self.assertEqual( + ["layout-test-results/test-crash-log.txt"], + updated_json["tests"]["test.html"]["artifacts"]["crash_log"]) + + def test_write_screenshot_artifacts(self): + # Ensure that screenshots are written to the correct filenames and + # their bytes are base64 decoded. + json_dict = { + 'tests': { + 'reftest.html': { + 'expected': 'PASS', + 'actual': 'PASS', + 'artifacts': { + 'wpt_actual_status': ['PASS'], + 'screenshots': [ + 'reftest.html:abcd', + 'reftest-ref.html:bcde', + ], + }, + }, + }, + 'path_delimiter': '/', + } + self._create_json_output(json_dict) + self.wpt_adapter.do_post_test_run_tasks() + written_files = self.wpt_adapter.fs.written_files + self.assertEqual( + base64.b64decode('abcd'), + written_files["/layout-test-results/reftest-actual.png"]) + self.assertEqual( + base64.b64decode('bcde'), + written_files["/layout-test-results/reftest-expected.png"]) + # Ensure the artifacts in the json were replaced with the location of + # the newly-created files. + updated_json = self._load_json_output() + self.assertFalse( + "screenshots" in updated_json["tests"]["reftest.html"]["artifacts"]) + self.assertEqual( + ["layout-test-results/reftest-actual.png"], + updated_json["tests"]["reftest.html"]["artifacts"]["actual_image"]) + self.assertEqual( + ["layout-test-results/reftest-expected.png"], + updated_json["tests"]["reftest.html"]["artifacts"] + ["expected_image"]) + + def test_copy_expected_output(self): + # Check that an -expected.txt file is created from a checked-in metadata + # ini file if it exists for a test + json_dict = { + 'tests': { + 'test.html': { + 'expected': 'PASS', + 'actual': 'PASS', + 'artifacts': { + 'wpt_actual_status': ['OK'], + 'log': ['test.html actual text'], + }, + }, + }, + 'path_delimiter': '/', + } + self._create_json_output(json_dict) + # Also create a checked-in metadata file for this test + self.host.filesystem.write_text_file( + os.path.join(EXTERNAL_WPT_TESTS_DIR, "test.html.ini"), + "test.html checked-in metadata") + self.wpt_adapter.do_post_test_run_tasks() + written_files = self.wpt_adapter.fs.written_files + self.assertEqual( + "test.html actual text", + written_files["/layout-test-results/test-actual.txt"]) + # The checked-in metadata file gets renamed from .ini to -expected.txt + self.assertEqual( + "test.html checked-in metadata", + written_files["/layout-test-results/test-expected.txt"]) + # Ensure the artifacts in the json were replaced with the locations of + # the newly-created files. + updated_json = self._load_json_output() + self.assertFalse( + "log" in updated_json["tests"]["test.html"]["artifacts"]) + self.assertEqual( + ["layout-test-results/test-actual.txt"], + updated_json["tests"]["test.html"]["artifacts"]["actual_text"]) + self.assertEqual( + ["layout-test-results/test-expected.txt"], + updated_json["tests"]["test.html"]["artifacts"]["expected_text"]) + + def test_expected_output_for_variant(self): + # Check that an -expected.txt file is created from a checked-in metadata + # ini file for a variant test. Variants are a little different because + # we have to use the manifest to map a test name to the test file, and + # determine the associated metadata from the test file. + # Check that an -expected.txt file is created from a checked-in metadata + # ini file if it exists for a test + json_dict = { + 'tests': { + 'variant.html?foo=bar/abc': { + 'expected': 'PASS', + 'actual': 'PASS', + 'artifacts': { + 'wpt_actual_status': ['OK'], + 'log': ['variant bar/abc actual text'], + }, + }, + }, + 'path_delimiter': '/', + } + self._create_json_output(json_dict) + # Also create a checked-in metadata file for this test. This filename + # matches the test *file* name, not the test name (which includes the + # variant). + self.host.filesystem.write_text_file( + os.path.join(EXTERNAL_WPT_TESTS_DIR, "variant.html.ini"), + "variant.html checked-in metadata") + self.wpt_adapter.do_post_test_run_tasks() + written_files = self.wpt_adapter.fs.written_files + self.assertEqual( + "variant bar/abc actual text", + written_files[ + "/layout-test-results/variant_foo=bar_abc-actual.txt"]) + # The checked-in metadata file gets renamed from .ini to -expected.txt + self.assertEqual( + "variant.html checked-in metadata", + written_files[ + "/layout-test-results/variant_foo=bar_abc-expected.txt"]) + # Ensure the artifacts in the json were replaced with the locations of + # the newly-created files. + updated_json = self._load_json_output() + self.assertFalse("log" in updated_json["tests"] + ["variant.html?foo=bar/abc"]["artifacts"]) + self.assertEqual( + ["layout-test-results/variant_foo=bar_abc-actual.txt"], + updated_json["tests"]["variant.html?foo=bar/abc"]["artifacts"] + ["actual_text"]) + self.assertEqual( + ["layout-test-results/variant_foo=bar_abc-expected.txt"], + updated_json["tests"]["variant.html?foo=bar/abc"]["artifacts"] + ["expected_text"]) + + def test_expected_output_for_multiglob(self): + # Check that an -expected.txt file is created from a checked-in metadata + # ini file for a multiglobal test. Multi-globals are a little different + # because we have to use the manifest to map a test name to the test + # file, and determine the associated metadata from the test file. + json_dict = { + 'tests': { + 'dir/multiglob.https.any.worker.html': { + 'expected': 'PASS', + 'actual': 'PASS', + 'artifacts': { + 'wpt_actual_status': ['OK'], + 'log': ['dir/multiglob worker actual text'], + }, + }, + }, + 'path_delimiter': '/', + } + self._create_json_output(json_dict) + # Also create a checked-in metadata file for this test. This filename + # matches the test *file* name, not the test name (which includes test + # scope). + self.host.filesystem.write_text_file( + os.path.join(EXTERNAL_WPT_TESTS_DIR, + "dir/multiglob.https.any.js.ini"), + "dir/multiglob checked-in metadata") + self.wpt_adapter.do_post_test_run_tasks() + written_files = self.wpt_adapter.fs.written_files + self.assertEqual( + "dir/multiglob worker actual text", + written_files[ + "/layout-test-results/dir/" + "multiglob.https.any.worker-actual.txt"]) + # The checked-in metadata file gets renamed from .ini to -expected.txt + self.assertEqual( + "dir/multiglob checked-in metadata", + written_files[ + "/layout-test-results/dir/" + "multiglob.https.any.worker-expected.txt"]) + # Ensure the artifacts in the json were replaced with the locations of + # the newly-created files. + updated_json = self._load_json_output() + self.assertFalse("log" in updated_json["tests"] + ["dir/multiglob.https.any.worker.html"]["artifacts"]) + self.assertEqual( + ["layout-test-results/dir/multiglob.https.any.worker-actual.txt"], + updated_json["tests"]["dir/multiglob.https.any.worker.html"] + ["artifacts"]["actual_text"]) + self.assertEqual( + ["layout-test-results/dir/multiglob.https.any.worker-expected.txt"], + updated_json["tests"]["dir/multiglob.https.any.worker.html"] + ["artifacts"]["expected_text"]) + +if __name__ == '__main__': + unittest.main()
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 621abd4..a7df57f 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -3345,21 +3345,6 @@ ] } ], - "IOSChangeTabSwitcherPosition": [ - { - "platforms": [ - "ios" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "ChangeTabSwitcherPosition" - ] - } - ] - } - ], "IOSCrashReportBreadcrumbs": [ { "platforms": [
diff --git a/third_party/abseil-cpp/BUILD.gn b/third_party/abseil-cpp/BUILD.gn index ededd30..5537c5c 100644 --- a/third_party/abseil-cpp/BUILD.gn +++ b/third_party/abseil-cpp/BUILD.gn
@@ -25,7 +25,7 @@ if (is_component_build) { public_configs = [ ":absl_component_build" ] - if (is_win) { + if (is_win && is_clang) { if (current_cpu == "x64") { if (is_debug) { sources = [ "symbols_x64_dbg.def" ]
diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium index ddd09b3..cb24fce 100644 --- a/third_party/abseil-cpp/README.chromium +++ b/third_party/abseil-cpp/README.chromium
@@ -4,7 +4,7 @@ License: Apache 2.0 License File: LICENSE Version: 0 -Revision: 6af91b35109cb35ae53cfe908e31a0c31c4a47f3 +Revision: d3614de6178018178723ac3b8b4baaf3f1dc7fcb Security Critical: yes Description:
diff --git a/third_party/abseil-cpp/absl/container/btree_map.h b/third_party/abseil-cpp/absl/container/btree_map.h index 448ac48..abc09b0 100644 --- a/third_party/abseil-cpp/absl/container/btree_map.h +++ b/third_party/abseil-cpp/absl/container/btree_map.h
@@ -185,7 +185,7 @@ // template <typename K> size_type erase(const K& key): // // Erases the element with the matching key, if it exists, returning the - // number of elements erased. + // number of elements erased (0 or 1). using Base::erase; // btree_map::insert()
diff --git a/third_party/abseil-cpp/absl/container/btree_set.h b/third_party/abseil-cpp/absl/container/btree_set.h index d3e78866..21ef0a0 100644 --- a/third_party/abseil-cpp/absl/container/btree_set.h +++ b/third_party/abseil-cpp/absl/container/btree_set.h
@@ -183,7 +183,7 @@ // template <typename K> size_type erase(const K& key): // // Erases the element with the matching key, if it exists, returning the - // number of elements erased. + // number of elements erased (0 or 1). using Base::erase; // btree_set::insert()
diff --git a/third_party/abseil-cpp/absl/container/flat_hash_map.h b/third_party/abseil-cpp/absl/container/flat_hash_map.h index dbd37d3c..74def0d 100644 --- a/third_party/abseil-cpp/absl/container/flat_hash_map.h +++ b/third_party/abseil-cpp/absl/container/flat_hash_map.h
@@ -234,7 +234,8 @@ // // size_type erase(const key_type& key): // - // Erases the element with the matching key, if it exists. + // Erases the element with the matching key, if it exists, returning the + // number of elements erased (0 or 1). using Base::erase; // flat_hash_map::insert()
diff --git a/third_party/abseil-cpp/absl/container/flat_hash_set.h b/third_party/abseil-cpp/absl/container/flat_hash_set.h index 94be6e3..81e145a 100644 --- a/third_party/abseil-cpp/absl/container/flat_hash_set.h +++ b/third_party/abseil-cpp/absl/container/flat_hash_set.h
@@ -227,7 +227,8 @@ // // size_type erase(const key_type& key): // - // Erases the element with the matching key, if it exists. + // Erases the element with the matching key, if it exists, returning the + // number of elements erased (0 or 1). using Base::erase; // flat_hash_set::insert()
diff --git a/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.cc b/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.cc index 75c4db6c..59cc5aa 100644 --- a/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.cc +++ b/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.cc
@@ -41,8 +41,10 @@ } // namespace std::mt19937_64* GetSharedRng() { - RandomDeviceSeedSeq seed_seq; - static auto* rng = new std::mt19937_64(seed_seq); + static auto* rng = [] { + RandomDeviceSeedSeq seed_seq; + return new std::mt19937_64(seed_seq); + }(); return rng; }
diff --git a/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h b/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h index 130da13..ec13a2f 100644 --- a/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +++ b/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h
@@ -1327,6 +1327,7 @@ } if (ABSL_PREDICT_TRUE(g.MatchEmpty())) return end(); seq.next(); + assert(seq.index() < capacity_ && "full table!"); } } template <class K = key_type> @@ -1678,8 +1679,8 @@ #endif return {seq.offset(mask.LowestBitSet()), seq.index()}; } - assert(seq.index() < capacity_ && "full table!"); seq.next(); + assert(seq.index() < capacity_ && "full table!"); } } @@ -1710,6 +1711,7 @@ } if (ABSL_PREDICT_TRUE(g.MatchEmpty())) break; seq.next(); + assert(seq.index() < capacity_ && "full table!"); } return {prepare_insert(hash), true}; }
diff --git a/third_party/abseil-cpp/absl/container/node_hash_map.h b/third_party/abseil-cpp/absl/container/node_hash_map.h index 9852ff7f..7a39f62 100644 --- a/third_party/abseil-cpp/absl/container/node_hash_map.h +++ b/third_party/abseil-cpp/absl/container/node_hash_map.h
@@ -225,7 +225,8 @@ // // size_type erase(const key_type& key): // - // Erases the element with the matching key, if it exists. + // Erases the element with the matching key, if it exists, returning the + // number of elements erased (0 or 1). using Base::erase; // node_hash_map::insert()
diff --git a/third_party/abseil-cpp/absl/container/node_hash_set.h b/third_party/abseil-cpp/absl/container/node_hash_set.h index 56bab5c2..56ce3b6 100644 --- a/third_party/abseil-cpp/absl/container/node_hash_set.h +++ b/third_party/abseil-cpp/absl/container/node_hash_set.h
@@ -217,7 +217,8 @@ // // size_type erase(const key_type& key): // - // Erases the element with the matching key, if it exists. + // Erases the element with the matching key, if it exists, returning the + // number of elements erased (0 or 1). using Base::erase; // node_hash_set::insert()
diff --git a/third_party/abseil-cpp/absl/debugging/internal/demangle.cc b/third_party/abseil-cpp/absl/debugging/internal/demangle.cc index b980d1b..46cdb67 100644 --- a/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +++ b/third_party/abseil-cpp/absl/debugging/internal/demangle.cc
@@ -1936,7 +1936,8 @@ bool Demangle(const char *mangled, char *out, int out_size) { State state; InitState(&state, mangled, out, out_size); - return ParseTopLevelMangledName(&state) && !Overflowed(&state); + return ParseTopLevelMangledName(&state) && !Overflowed(&state) && + state.parse_state.out_cur_idx > 0; } } // namespace debugging_internal
diff --git a/third_party/abseil-cpp/absl/status/status.h b/third_party/abseil-cpp/absl/status/status.h index de10996f..42f634e 100644 --- a/third_party/abseil-cpp/absl/status/status.h +++ b/third_party/abseil-cpp/absl/status/status.h
@@ -365,8 +365,8 @@ // Constructors // This default constructor creates an OK status with no message or payload. - // Avoid this constructor and pefer explicit construction of an OK status with - // `absl::OkStatus()`. + // Avoid this constructor and prefer explicit construction of an OK status + // with `absl::OkStatus()`. Status(); // Creates a status in the canonical error space with the specified
diff --git a/third_party/abseil-cpp/absl/synchronization/mutex_test.cc b/third_party/abseil-cpp/absl/synchronization/mutex_test.cc index 307d0e3..16fc9058 100644 --- a/third_party/abseil-cpp/absl/synchronization/mutex_test.cc +++ b/third_party/abseil-cpp/absl/synchronization/mutex_test.cc
@@ -1102,7 +1102,7 @@ // annotation-based static thread-safety analysis is not currently // predicate-aware and cannot tell if the two for-loops that acquire and // release the locks have the same predicates. -TEST(Mutex, DeadlockDetectorStessTest) ABSL_NO_THREAD_SAFETY_ANALYSIS { +TEST(Mutex, DeadlockDetectorStressTest) ABSL_NO_THREAD_SAFETY_ANALYSIS { // Stress test: Here we create a large number of locks and use all of them. // If a deadlock detector keeps a full graph of lock acquisition order, // it will likely be too slow for this test to pass.
diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel b/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel index 7379dec9..45a9529 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel +++ b/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel
@@ -92,6 +92,11 @@ ### tests +test_suite( + name = "all_tests", + visibility = ["//visibility:public"], +) + cc_test( name = "civil_time_test", size = "small",
diff --git a/third_party/abseil-cpp/ci/linux_gcc-latest_libstdcxx_bazel.sh b/third_party/abseil-cpp/ci/linux_gcc-latest_libstdcxx_bazel.sh index cd15f710..b327405 100755 --- a/third_party/abseil-cpp/ci/linux_gcc-latest_libstdcxx_bazel.sh +++ b/third_party/abseil-cpp/ci/linux_gcc-latest_libstdcxx_bazel.sh
@@ -75,7 +75,7 @@ ${DOCKER_CONTAINER} \ /bin/sh -c " cp -r /abseil-cpp-ro/* /abseil-cpp/ - if [[ -n \"${ALTERNATE_OPTIONS:-}\" ]]; then + if [ -n \"${ALTERNATE_OPTIONS:-}\" ]; then cp ${ALTERNATE_OPTIONS:-} absl/base/options.h || exit 1 fi /usr/local/bin/bazel test ... \
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 21fcca0..7151833 100644 --- a/third_party/blink/public/common/loader/url_loader_throttle.h +++ b/third_party/blink/public/common/loader/url_loader_throttle.h
@@ -140,7 +140,8 @@ // Will* methods below and may only be called once. virtual void DetachFromCurrentSequence(); - // Called before the resource request is started. + // Called exactly once before the resource request is started. + // // |request| needs to be modified before the callback returns (i.e. // asynchronously touching the pointer in defer case is not valid) // When |request->url| is modified it will make an internal redirect, which
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 0ab8167..3bc83f5b 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2805,10 +2805,10 @@ kWebkitPrerenderLoadEventFired = 3475, kWebkitPrerenderDOMContentLoadedEventFired = 3476, kIdleDetectionPermissionRequested = 3477, - kIdentifiabilityStudyReserved3478 = 3478, - kIdentifiabilityStudyReserved3479 = 3479, - kIdentifiabilityStudyReserved3480 = 3480, - kIdentifiabilityStudyReserved3481 = 3481, + kV8MediaDeviceInfo_Kind_AttributeGetter = 3478, + kV8MediaDeviceInfo_GroupId_AttributeGetter = 3479, + kV8MediaDeviceInfo_Label_AttributeGetter = 3480, + kV8Navigator_JavaEnabled_Method = 3481, kIdentifiabilityStudyReserved3482 = 3482, kIdentifiabilityStudyReserved3483 = 3483, kIdentifiabilityStudyReserved3484 = 3484, @@ -2860,39 +2860,39 @@ kIdentifiabilityStudyReserved3530 = 3530, kIdentifiabilityStudyReserved3531 = 3531, kIdentifiabilityStudyReserved3532 = 3532, - kIdentifiabilityStudyReserved3533 = 3533, - kIdentifiabilityStudyReserved3534 = 3534, - kIdentifiabilityStudyReserved3535 = 3535, - kIdentifiabilityStudyReserved3536 = 3536, - kIdentifiabilityStudyReserved3537 = 3537, + kV8SpeechSynthesisVoice_Default_AttributeGetter = 3533, + kV8SpeechSynthesisVoice_Lang_AttributeGetter = 3534, + kV8SpeechSynthesisVoice_LocalService_AttributeGetter = 3535, + kV8SpeechSynthesisVoice_Name_AttributeGetter = 3536, + kV8SpeechSynthesisVoice_VoiceURI_AttributeGetter = 3537, kIdentifiabilityStudyReserved3538 = 3538, kIdentifiabilityStudyReserved3539 = 3539, kIdentifiabilityStudyReserved3540 = 3540, kV8WheelEvent_DeltaMode_AttributeGetter = 3541, kIdentifiabilityStudyReserved3542 = 3542, - kIdentifiabilityStudyReserved3543 = 3543, - kIdentifiabilityStudyReserved3544 = 3544, - kIdentifiabilityStudyReserved3545 = 3545, + kV8HIDDevice_ProductId_AttributeGetter = 3543, + kV8HIDDevice_ProductName_AttributeGetter = 3544, + kV8HIDDevice_VendorId_AttributeGetter = 3545, kIdentifiabilityStudyReserved3546 = 3546, - kIdentifiabilityStudyReserved3547 = 3547, - kIdentifiabilityStudyReserved3548 = 3548, - kIdentifiabilityStudyReserved3549 = 3549, - kIdentifiabilityStudyReserved3550 = 3550, - kIdentifiabilityStudyReserved3551 = 3551, - kIdentifiabilityStudyReserved3552 = 3552, - kIdentifiabilityStudyReserved3553 = 3553, - kIdentifiabilityStudyReserved3554 = 3554, - kIdentifiabilityStudyReserved3555 = 3555, - kIdentifiabilityStudyReserved3556 = 3556, - kIdentifiabilityStudyReserved3557 = 3557, - kIdentifiabilityStudyReserved3558 = 3558, - kIdentifiabilityStudyReserved3559 = 3559, - kIdentifiabilityStudyReserved3560 = 3560, - kIdentifiabilityStudyReserved3561 = 3561, - kIdentifiabilityStudyReserved3562 = 3562, - kIdentifiabilityStudyReserved3563 = 3563, - kIdentifiabilityStudyReserved3564 = 3564, - kIdentifiabilityStudyReserved3565 = 3565, + kV8HIDReportItem_HasNull_AttributeGetter = 3547, + kV8HIDReportItem_IsAbsolute_AttributeGetter = 3548, + kV8HIDReportItem_IsArray_AttributeGetter = 3549, + kV8HIDReportItem_IsRange_AttributeGetter = 3550, + kV8HIDReportItem_LogicalMaximum_AttributeGetter = 3551, + kV8HIDReportItem_LogicalMinimum_AttributeGetter = 3552, + kV8HIDReportItem_PhysicalMaximum_AttributeGetter = 3553, + kV8HIDReportItem_PhysicalMinimum_AttributeGetter = 3554, + kV8HIDReportItem_ReportCount_AttributeGetter = 3555, + kV8HIDReportItem_ReportSize_AttributeGetter = 3556, + kV8HIDReportItem_UnitExponent_AttributeGetter = 3557, + kV8HIDReportItem_UnitFactorCurrentExponent_AttributeGetter = 3558, + kV8HIDReportItem_UnitFactorLengthExponent_AttributeGetter = 3559, + kV8HIDReportItem_UnitFactorLuminousIntensityExponent_AttributeGetter = 3560, + kV8HIDReportItem_UnitFactorMassExponent_AttributeGetter = 3561, + kV8HIDReportItem_UnitFactorTemperatureExponent_AttributeGetter = 3562, + kV8HIDReportItem_UnitFactorTimeExponent_AttributeGetter = 3563, + kV8HIDReportItem_UsageMaximum_AttributeGetter = 3564, + kV8HIDReportItem_UsageMinimum_AttributeGetter = 3565, kIdentifiabilityStudyReserved3566 = 3566, kIdentifiabilityStudyReserved3567 = 3567, kIdentifiabilityStudyReserved3568 = 3568, @@ -2909,6 +2909,106 @@ kForcedDarkMode = 3579, kPreferredColorSchemeDark = 3580, kPreferredColorSchemeDarkSetting = 3581, + kIdentifiabilityStudyReserved3582 = 3582, + kIdentifiabilityStudyReserved3583 = 3583, + kIdentifiabilityStudyReserved3584 = 3584, + kIdentifiabilityStudyReserved3585 = 3585, + kIdentifiabilityStudyReserved3586 = 3586, + kIdentifiabilityStudyReserved3587 = 3587, + kIdentifiabilityStudyReserved3588 = 3588, + kIdentifiabilityStudyReserved3589 = 3589, + kIdentifiabilityStudyReserved3590 = 3590, + kIdentifiabilityStudyReserved3591 = 3591, + kIdentifiabilityStudyReserved3592 = 3592, + kIdentifiabilityStudyReserved3593 = 3593, + kIdentifiabilityStudyReserved3594 = 3594, + kIdentifiabilityStudyReserved3595 = 3595, + kIdentifiabilityStudyReserved3596 = 3596, + kIdentifiabilityStudyReserved3597 = 3597, + kIdentifiabilityStudyReserved3598 = 3598, + kIdentifiabilityStudyReserved3599 = 3599, + kIdentifiabilityStudyReserved3600 = 3600, + kIdentifiabilityStudyReserved3601 = 3601, + kIdentifiabilityStudyReserved3602 = 3602, + kIdentifiabilityStudyReserved3603 = 3603, + kIdentifiabilityStudyReserved3604 = 3604, + kIdentifiabilityStudyReserved3605 = 3605, + kIdentifiabilityStudyReserved3606 = 3606, + kIdentifiabilityStudyReserved3607 = 3607, + kIdentifiabilityStudyReserved3608 = 3608, + kIdentifiabilityStudyReserved3609 = 3609, + kIdentifiabilityStudyReserved3610 = 3610, + kIdentifiabilityStudyReserved3611 = 3611, + kIdentifiabilityStudyReserved3612 = 3612, + kIdentifiabilityStudyReserved3613 = 3613, + kIdentifiabilityStudyReserved3614 = 3614, + kIdentifiabilityStudyReserved3615 = 3615, + kIdentifiabilityStudyReserved3616 = 3616, + kIdentifiabilityStudyReserved3617 = 3617, + kIdentifiabilityStudyReserved3618 = 3618, + kIdentifiabilityStudyReserved3619 = 3619, + kIdentifiabilityStudyReserved3620 = 3620, + kIdentifiabilityStudyReserved3621 = 3621, + kIdentifiabilityStudyReserved3622 = 3622, + kIdentifiabilityStudyReserved3623 = 3623, + kIdentifiabilityStudyReserved3624 = 3624, + kIdentifiabilityStudyReserved3625 = 3625, + kIdentifiabilityStudyReserved3626 = 3626, + kIdentifiabilityStudyReserved3627 = 3627, + kIdentifiabilityStudyReserved3628 = 3628, + kIdentifiabilityStudyReserved3629 = 3629, + kIdentifiabilityStudyReserved3630 = 3630, + kIdentifiabilityStudyReserved3631 = 3631, + kIdentifiabilityStudyReserved3632 = 3632, + kIdentifiabilityStudyReserved3633 = 3633, + kIdentifiabilityStudyReserved3634 = 3634, + kIdentifiabilityStudyReserved3635 = 3635, + kIdentifiabilityStudyReserved3636 = 3636, + kIdentifiabilityStudyReserved3637 = 3637, + kIdentifiabilityStudyReserved3638 = 3638, + kIdentifiabilityStudyReserved3639 = 3639, + kIdentifiabilityStudyReserved3640 = 3640, + kIdentifiabilityStudyReserved3641 = 3641, + kIdentifiabilityStudyReserved3642 = 3642, + kIdentifiabilityStudyReserved3643 = 3643, + kIdentifiabilityStudyReserved3644 = 3644, + kIdentifiabilityStudyReserved3645 = 3645, + kIdentifiabilityStudyReserved3646 = 3646, + kIdentifiabilityStudyReserved3647 = 3647, + kIdentifiabilityStudyReserved3648 = 3648, + kIdentifiabilityStudyReserved3649 = 3649, + kIdentifiabilityStudyReserved3650 = 3650, + kIdentifiabilityStudyReserved3651 = 3651, + kIdentifiabilityStudyReserved3652 = 3652, + kIdentifiabilityStudyReserved3653 = 3653, + kIdentifiabilityStudyReserved3654 = 3654, + kIdentifiabilityStudyReserved3655 = 3655, + kIdentifiabilityStudyReserved3656 = 3656, + kIdentifiabilityStudyReserved3657 = 3657, + kIdentifiabilityStudyReserved3658 = 3658, + kIdentifiabilityStudyReserved3659 = 3659, + kIdentifiabilityStudyReserved3660 = 3660, + kIdentifiabilityStudyReserved3661 = 3661, + kIdentifiabilityStudyReserved3662 = 3662, + kIdentifiabilityStudyReserved3663 = 3663, + kIdentifiabilityStudyReserved3664 = 3664, + kIdentifiabilityStudyReserved3665 = 3665, + kIdentifiabilityStudyReserved3666 = 3666, + kIdentifiabilityStudyReserved3667 = 3667, + kIdentifiabilityStudyReserved3668 = 3668, + kIdentifiabilityStudyReserved3669 = 3669, + kIdentifiabilityStudyReserved3670 = 3670, + kIdentifiabilityStudyReserved3671 = 3671, + kIdentifiabilityStudyReserved3672 = 3672, + kIdentifiabilityStudyReserved3673 = 3673, + kIdentifiabilityStudyReserved3674 = 3674, + kIdentifiabilityStudyReserved3675 = 3675, + kIdentifiabilityStudyReserved3676 = 3676, + kIdentifiabilityStudyReserved3677 = 3677, + kIdentifiabilityStudyReserved3678 = 3678, + kIdentifiabilityStudyReserved3679 = 3679, + kIdentifiabilityStudyReserved3680 = 3680, + kIdentifiabilityStudyReserved3681 = 3681, // 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/platform/TaskTypes.md b/third_party/blink/public/platform/TaskTypes.md index 3a3d28c4..316b68d 100644 --- a/third_party/blink/public/platform/TaskTypes.md +++ b/third_party/blink/public/platform/TaskTypes.md
@@ -7,54 +7,55 @@ frozen or deferred. All specified (in W3C, HTML, DOM, etc) task types are pausable. Some internal task queues are not. -| Queue Type | Throttlable | Deferrable | Freezable | Pausable | Virtual time | -|------------------------------|-------------|------------|-----------|----------|--------------| -| DOMManipulation | No | Yes | Yes | Yes | Yes | -| UserInteraction | No | No | Yes | Yes | Yes | -| Networking | No | Yes | Yes | Yes | No | -| NetworkingWithURLLoaderAnnot | No | Yes | Yes | Yes | No | -| NetworkingControl | No | Yes | Yes | Yes | No | -| HistoryTraversal | No | Yes | Yes | Yes | Yes | -| Embed | No | Yes | Yes | Yes | Yes | -| MediaElementEvent | No | No | Yes | Yes | Yes | -| CanvasBlobSerialization | No | Yes | Yes | Yes | Yes | -| Microtask | No | Yes | Yes | Yes | Yes | -| JavascriptTimerDelayed | Yes | Yes | Yes | Yes | Yes | -| JavascriptTimerImmediate [1] | No | Yes | Yes | Yes | Yes | -| RemoteEvent | No | Yes | Yes | Yes | Yes | -| WebSocket | No | Yes | Yes | Yes | Yes | -| PostedMessage | No | No | Yes | Yes | Yes | -| UnshippedPortMessage | No | Yes | Yes | Yes | Yes | -| FileReading | No | Yes | Yes | Yes | Yes | -| DatabaseAccess | No | No | Yes | Yes | Yes | -| Presentation | No | Yes | Yes | Yes | Yes | -| Sensor | No | Yes | Yes | Yes | Yes | -| PerformanceTimeline | No | Yes | Yes | Yes | Yes | -| WebGL | No | Yes | Yes | Yes | Yes | -| IdleTask | No | Yes | Yes | Yes | Yes | -| MiscPlatformAPI | No | Yes | Yes | Yes | Yes | -| WorkerAnimation | No | No | Yes | Yes | Yes | -| FontLoading | No | Yes | Yes | Yes | Yes | -| ApplicationLifeCycle | No | Yes | Yes | Yes | Yes | -| BackgroundFetch | No | Yes | Yes | Yes | Yes | -| Permission | No | Yes | Yes | Yes | Yes | -| ServiceWorkerClientMessage | No | No | Yes | Yes | Yes | -| WebLocks | No | No | No | No | Yes | -| InternalDefault | No | Yes | Yes | Yes | Yes | -| InternalLoading | No | Yes | Yes | Yes | No | -| InternalTest | No | No | No | No | Yes | -| InternalWebCrypto | No | No | Yes | Yes | Yes | -| InternalMedia | No | No | Yes | Yes | Yes | -| InternalMediaRealTime | No | No | Yes | Yes | Yes | -| InternalIPC | No | No | No | No | Yes | -| InternalUserInteraction | No | No | Yes | Yes | Yes | -| InternalInspector | No | No | No | No | No | -| InternalTranslation | Yes | Yes | Yes | Yes | Yes | -| InternalIntersectionObserver | No | No | Yes | Yes | Yes | -| InternalContentCapture | Yes | Yes | Yes | Yes | Yes | -| InternalNavigationAssociated | No | No | No | No | No | -| InternalFreezableIPC | No | No | Yes | No | No | -| InternalContinueScriptLoadin | No | No | Yes | Yes | Yes | +| Queue Type | Throttlable | Deferrable | Freezable | Pausable | Virtual time | +|-----------------------------------|-------------|------------|-----------|----------|--------------| +| DOMManipulation | No | Yes | Yes | Yes | Yes | +| UserInteraction | No | No | Yes | Yes | Yes | +| Networking | No | Yes | Yes | Yes | No | +| NetworkingWithURLLoaderAnnotation | No | Yes | Yes | Yes | No | +| NetworkingControl | No | Yes | Yes | Yes | No | +| HistoryTraversal | No | Yes | Yes | Yes | Yes | +| Embed | No | Yes | Yes | Yes | Yes | +| MediaElementEvent | No | No | Yes | Yes | Yes | +| CanvasBlobSerialization | No | Yes | Yes | Yes | Yes | +| Microtask | No | Yes | Yes | Yes | Yes | +| JavascriptTimerDelayedLowNesting | Yes | Yes | Yes | Yes | Yes | +| JavascriptTimerDelayedHighNesting | Yes | Yes | Yes | Yes | Yes | +| JavascriptTimerImmediate [1] | No | Yes | Yes | Yes | Yes | +| RemoteEvent | No | Yes | Yes | Yes | Yes | +| WebSocket | No | Yes | Yes | Yes | Yes | +| PostedMessage | No | No | Yes | Yes | Yes | +| UnshippedPortMessage | No | Yes | Yes | Yes | Yes | +| FileReading | No | Yes | Yes | Yes | Yes | +| DatabaseAccess | No | No | Yes | Yes | Yes | +| Presentation | No | Yes | Yes | Yes | Yes | +| Sensor | No | Yes | Yes | Yes | Yes | +| PerformanceTimeline | No | Yes | Yes | Yes | Yes | +| WebGL | No | Yes | Yes | Yes | Yes | +| IdleTask | No | Yes | Yes | Yes | Yes | +| MiscPlatformAPI | No | Yes | Yes | Yes | Yes | +| WorkerAnimation | No | No | Yes | Yes | Yes | +| FontLoading | No | Yes | Yes | Yes | Yes | +| ApplicationLifeCycle | No | Yes | Yes | Yes | Yes | +| BackgroundFetch | No | Yes | Yes | Yes | Yes | +| Permission | No | Yes | Yes | Yes | Yes | +| ServiceWorkerClientMessage | No | No | Yes | Yes | Yes | +| WebLocks | No | No | No | No | Yes | +| InternalDefault | No | Yes | Yes | Yes | Yes | +| InternalLoading | No | Yes | Yes | Yes | No | +| InternalTest | No | No | No | No | Yes | +| InternalWebCrypto | No | No | Yes | Yes | Yes | +| InternalMedia | No | No | Yes | Yes | Yes | +| InternalMediaRealTime | No | No | Yes | Yes | Yes | +| InternalIPC | No | No | No | No | Yes | +| InternalUserInteraction | No | No | Yes | Yes | Yes | +| InternalInspector | No | No | No | No | No | +| InternalTranslation | Yes | Yes | Yes | Yes | Yes | +| InternalIntersectionObserver | No | No | Yes | Yes | Yes | +| InternalContentCapture | Yes | Yes | Yes | Yes | Yes | +| InternalNavigationAssociated | No | No | No | No | No | +| InternalFreezableIPC | No | No | Yes | No | No | +| InternalContinueScriptLoading | No | No | Yes | Yes | Yes | Internal Translation queue supports concept of it running only in the foreground. It is disabled if the page that owns it goes in background.
diff --git a/third_party/blink/public/platform/task_type.h b/third_party/blink/public/platform/task_type.h index d97c40c..e2e4cbb 100644 --- a/third_party/blink/public/platform/task_type.h +++ b/third_party/blink/public/platform/task_type.h
@@ -73,14 +73,17 @@ kMicrotask = 9, // https://html.spec.whatwg.org/multipage/webappapis.html#timers - // For tasks queued by setInterval() and similar APIs. A different type is - // used depending on whether the timeout is zero or non-zero. Tasks with - // a zero timeout and a nesting level <= 5 will be associated with task - // queues that are not throttlable. This complies with the spec since it - // does not reduce the timeout to less than zero or bypass the timeout - // extension triggered on nesting level >= 5. - kJavascriptTimerDelayed = 10, + // For tasks queued by setTimeout() or setInterval(). + // + // Task nesting level is < 5 and timeout is zero. kJavascriptTimerImmediate = 72, + // Task nesting level is < 5 and timeout is > 0. + kJavascriptTimerDelayedLowNesting = 73, + // Task nesting level is >= 5. + kJavascriptTimerDelayedHighNesting = 10, + // Note: The timeout is increased to be at least 4ms when the task nesting + // level is >= 5. Therefore, the timeout is necessarily > 0 for + // kJavascriptTimerDelayedHighNesting. // https://html.spec.whatwg.org/multipage/comms.html#sse-processing-model // This task source is used for any tasks that are queued by EventSource @@ -271,7 +274,7 @@ kWorkerThreadTaskQueueV8 = 47, kWorkerThreadTaskQueueCompositor = 48, - kCount = 73, + kCount = 74, }; } // namespace blink
diff --git a/third_party/blink/public/platform/web_content_settings_client.h b/third_party/blink/public/platform/web_content_settings_client.h index 19ec36fb..f6eb370 100644 --- a/third_party/blink/public/platform/web_content_settings_client.h +++ b/third_party/blink/public/platform/web_content_settings_client.h
@@ -29,7 +29,9 @@ kCacheStorage, kIndexedDB, kFileSystem, - kWebLocks + kWebLocks, + kLocalStorage, + kSessionStorage }; // Controls whether access to the given StorageType is allowed for this frame. @@ -66,11 +68,6 @@ return enabled_per_settings; } - // Controls whether HTML5 Web Storage is allowed for this frame. - // If local is true, then this is for local storage, otherwise it's for - // session storage. - virtual bool AllowStorage(bool local) { return true; } - // Controls whether access to read the clipboard is allowed for this frame. virtual bool AllowReadFromClipboard(bool default_value) { return default_value;
diff --git a/third_party/blink/public/web/web_widget_client.h b/third_party/blink/public/web/web_widget_client.h index 9ddedfa6..721efc2 100644 --- a/third_party/blink/public/web/web_widget_client.h +++ b/third_party/blink/public/web/web_widget_client.h
@@ -59,7 +59,6 @@ namespace gfx { class Point; -class PointF; } namespace ui { @@ -156,12 +155,6 @@ // is eanbled. TODO(oshima): Update the comment when the // migration is completed. virtual void ConvertWindowToViewport(WebFloatRect* rect) {} - virtual gfx::Point ConvertWindowPointToViewport(const gfx::Point& point) { - return point; - } - virtual gfx::PointF ConvertWindowPointToViewport(const gfx::PointF& point) { - return point; - } // Called when a drag-and-drop operation should begin. Returns whether the // call has been handled.
diff --git a/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc b/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc index cf9faf82..31c912e 100644 --- a/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc +++ b/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc
@@ -16,131 +16,195 @@ BlinkAXEventIntent BlinkAXEventIntent::FromEditCommand( const EditCommand& edit_command) { ax::mojom::blink::Command command; - // Set default values for move direction and text boundary. - ax::mojom::blink::TextBoundary text_boundary = - ax::mojom::blink::TextBoundary::kCharacter; - ax::mojom::blink::MoveDirection move_direction = - ax::mojom::blink::MoveDirection::kForward; - + ax::mojom::blink::InputEventType input_event_type; switch (edit_command.GetInputType()) { case InputEvent::InputType::kNone: return BlinkAXEventIntent(); // An empty intent. // Insertion. case InputEvent::InputType::kInsertText: - command = ax::mojom::blink::Command::kType; + command = ax::mojom::blink::Command::kInsert; + input_event_type = ax::mojom::blink::InputEventType::kInsertText; break; case InputEvent::InputType::kInsertLineBreak: - command = ax::mojom::blink::Command::kType; - text_boundary = ax::mojom::blink::TextBoundary::kLineEnd; + command = ax::mojom::blink::Command::kInsert; + input_event_type = ax::mojom::blink::InputEventType::kInsertLineBreak; break; case InputEvent::InputType::kInsertParagraph: - command = ax::mojom::blink::Command::kType; - text_boundary = ax::mojom::blink::TextBoundary::kParagraphEnd; + command = ax::mojom::blink::Command::kInsert; + input_event_type = ax::mojom::blink::InputEventType::kInsertParagraph; break; case InputEvent::InputType::kInsertOrderedList: + command = ax::mojom::blink::Command::kInsert; + input_event_type = ax::mojom::blink::InputEventType::kInsertOrderedList; + break; case InputEvent::InputType::kInsertUnorderedList: - command = ax::mojom::blink::Command::kFormat; + command = ax::mojom::blink::Command::kInsert; + input_event_type = ax::mojom::blink::InputEventType::kInsertUnorderedList; break; case InputEvent::InputType::kInsertHorizontalRule: - command = ax::mojom::blink::Command::kType; + command = ax::mojom::blink::Command::kInsert; + input_event_type = + ax::mojom::blink::InputEventType::kInsertHorizontalRule; break; case InputEvent::InputType::kInsertFromPaste: + command = ax::mojom::blink::Command::kInsert; + input_event_type = ax::mojom::blink::InputEventType::kInsertFromPaste; + break; case InputEvent::InputType::kInsertFromDrop: + command = ax::mojom::blink::Command::kInsert; + input_event_type = ax::mojom::blink::InputEventType::kInsertFromDrop; + break; case InputEvent::InputType::kInsertFromYank: - command = ax::mojom::blink::Command::kPaste; + command = ax::mojom::blink::Command::kInsert; + input_event_type = ax::mojom::blink::InputEventType::kInsertFromYank; break; case InputEvent::InputType::kInsertTranspose: + command = ax::mojom::blink::Command::kInsert; + input_event_type = ax::mojom::blink::InputEventType::kInsertTranspose; + break; case InputEvent::InputType::kInsertReplacementText: - command = ax::mojom::blink::Command::kReplace; + command = ax::mojom::blink::Command::kInsert; + input_event_type = + ax::mojom::blink::InputEventType::kInsertReplacementText; break; case InputEvent::InputType::kInsertCompositionText: - command = ax::mojom::blink::Command::kType; + command = ax::mojom::blink::Command::kInsert; + input_event_type = + ax::mojom::blink::InputEventType::kInsertCompositionText; break; // Deletion. - // - // Text boundary indicates up to which point the deletion is applied. For - // example, if a soft line break is deleted in the forward direction, then - // it means that we are deleting until the next line start. case InputEvent::InputType::kDeleteWordBackward: command = ax::mojom::blink::Command::kDelete; - text_boundary = ax::mojom::blink::TextBoundary::kWordStart; - move_direction = ax::mojom::blink::MoveDirection::kBackward; + input_event_type = ax::mojom::blink::InputEventType::kDeleteWordBackward; break; case InputEvent::InputType::kDeleteWordForward: command = ax::mojom::blink::Command::kDelete; - text_boundary = ax::mojom::blink::TextBoundary::kWordEnd; + input_event_type = ax::mojom::blink::InputEventType::kDeleteWordForward; break; case InputEvent::InputType::kDeleteSoftLineBackward: command = ax::mojom::blink::Command::kDelete; - text_boundary = ax::mojom::blink::TextBoundary::kLineEnd; - move_direction = ax::mojom::blink::MoveDirection::kBackward; + input_event_type = + ax::mojom::blink::InputEventType::kDeleteSoftLineBackward; break; case InputEvent::InputType::kDeleteSoftLineForward: command = ax::mojom::blink::Command::kDelete; - text_boundary = ax::mojom::blink::TextBoundary::kLineStart; + input_event_type = + ax::mojom::blink::InputEventType::kDeleteSoftLineForward; break; case InputEvent::InputType::kDeleteHardLineBackward: command = ax::mojom::blink::Command::kDelete; - text_boundary = ax::mojom::blink::TextBoundary::kParagraphEnd; - move_direction = ax::mojom::blink::MoveDirection::kBackward; + input_event_type = + ax::mojom::blink::InputEventType::kDeleteHardLineBackward; break; case InputEvent::InputType::kDeleteHardLineForward: command = ax::mojom::blink::Command::kDelete; - text_boundary = ax::mojom::blink::TextBoundary::kParagraphStart; + input_event_type = + ax::mojom::blink::InputEventType::kDeleteHardLineForward; break; case InputEvent::InputType::kDeleteContentBackward: command = ax::mojom::blink::Command::kDelete; - move_direction = ax::mojom::blink::MoveDirection::kBackward; + input_event_type = + ax::mojom::blink::InputEventType::kDeleteContentBackward; break; case InputEvent::InputType::kDeleteContentForward: command = ax::mojom::blink::Command::kDelete; + input_event_type = + ax::mojom::blink::InputEventType::kDeleteContentForward; break; case InputEvent::InputType::kDeleteByCut: + command = ax::mojom::blink::Command::kDelete; + input_event_type = ax::mojom::blink::InputEventType::kDeleteByCut; + break; case InputEvent::InputType::kDeleteByDrag: - command = ax::mojom::blink::Command::kCut; + command = ax::mojom::blink::Command::kDelete; + input_event_type = ax::mojom::blink::InputEventType::kDeleteByDrag; break; // History. case InputEvent::InputType::kHistoryUndo: + command = ax::mojom::blink::Command::kHistory; + input_event_type = ax::mojom::blink::InputEventType::kHistoryUndo; + break; case InputEvent::InputType::kHistoryRedo: - return BlinkAXEventIntent(); // No accessibility sideeffects for now. + command = ax::mojom::blink::Command::kHistory; + input_event_type = ax::mojom::blink::InputEventType::kHistoryRedo; + break; // Formatting. case InputEvent::InputType::kFormatBold: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatBold; + break; case InputEvent::InputType::kFormatItalic: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatItalic; + break; case InputEvent::InputType::kFormatUnderline: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatUnderline; + break; case InputEvent::InputType::kFormatStrikeThrough: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatStrikeThrough; + break; case InputEvent::InputType::kFormatSuperscript: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatSuperscript; + break; case InputEvent::InputType::kFormatSubscript: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatSubscript; + break; case InputEvent::InputType::kFormatJustifyCenter: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatJustifyCenter; + break; case InputEvent::InputType::kFormatJustifyFull: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatJustifyFull; + break; case InputEvent::InputType::kFormatJustifyRight: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatJustifyRight; + break; case InputEvent::InputType::kFormatJustifyLeft: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatJustifyLeft; + break; case InputEvent::InputType::kFormatIndent: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatIndent; + break; case InputEvent::InputType::kFormatOutdent: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatOutdent; + break; case InputEvent::InputType::kFormatRemove: + command = ax::mojom::blink::Command::kFormat; + input_event_type = ax::mojom::blink::InputEventType::kFormatRemove; + break; case InputEvent::InputType::kFormatSetBlockTextDirection: command = ax::mojom::blink::Command::kFormat; + input_event_type = + ax::mojom::blink::InputEventType::kFormatSetBlockTextDirection; break; case InputEvent::InputType::kNumberOfInputTypes: - NOTREACHED() << "Should never be assigned as an input type."; - command = ax::mojom::blink::Command::kType; - break; + NOTREACHED() + << "Should never be assigned as an input type to |edit_command|."; + return BlinkAXEventIntent(); } - return BlinkAXEventIntent(command, text_boundary, move_direction); + return BlinkAXEventIntent(command, input_event_type); } // static BlinkAXEventIntent BlinkAXEventIntent::FromClearedSelection( const SetSelectionBy set_selection_by) { - // |text_boundary| and |move_direction| are not used in this case. - return BlinkAXEventIntent(ax::mojom::blink::Command::kClearSelection, - ax::mojom::blink::TextBoundary::kCharacter, - ax::mojom::blink::MoveDirection::kForward); + // text boundary and move direction are not needed in this case. + return BlinkAXEventIntent(ax::mojom::blink::Command::kClearSelection); } // static @@ -191,6 +255,9 @@ break; case TextGranularity::kWord: switch (move_direction) { + case ax::mojom::blink::MoveDirection::kNone: + NOTREACHED(); + return BlinkAXEventIntent(); case ax::mojom::blink::MoveDirection::kBackward: // All platforms behave the same when moving backward by word. text_boundary = ax::mojom::blink::TextBoundary::kWordStart; @@ -230,6 +297,9 @@ // This granularity moves either to the start or the end of the current // sentence, depending on the direction. switch (move_direction) { + case ax::mojom::blink::MoveDirection::kNone: + NOTREACHED(); + return BlinkAXEventIntent(); case ax::mojom::blink::MoveDirection::kBackward: text_boundary = ax::mojom::blink::TextBoundary::kSentenceStart; break; @@ -242,6 +312,9 @@ // This granularity moves either to the start or the end of the current // line, depending on the direction. switch (move_direction) { + case ax::mojom::blink::MoveDirection::kNone: + NOTREACHED(); + return BlinkAXEventIntent(); case ax::mojom::blink::MoveDirection::kBackward: text_boundary = ax::mojom::blink::TextBoundary::kLineStart; break; @@ -254,6 +327,9 @@ // This granularity moves either to the start or the end of the current // paragraph, depending on the direction. switch (move_direction) { + case ax::mojom::blink::MoveDirection::kNone: + NOTREACHED(); + return BlinkAXEventIntent(); case ax::mojom::blink::MoveDirection::kBackward: text_boundary = ax::mojom::blink::TextBoundary::kParagraphStart; break; @@ -310,9 +386,16 @@ : ax::mojom::blink::MoveDirection::kBackward); } -// Creates an empty (uninitialized) instance. BlinkAXEventIntent::BlinkAXEventIntent() = default; +BlinkAXEventIntent::BlinkAXEventIntent(ax::mojom::blink::Command command) + : intent_(command), is_initialized_(true) {} + +BlinkAXEventIntent::BlinkAXEventIntent( + ax::mojom::blink::Command command, + ax::mojom::blink::InputEventType input_event_type) + : intent_(command, input_event_type), is_initialized_(true) {} + BlinkAXEventIntent::BlinkAXEventIntent( ax::mojom::blink::Command command, ax::mojom::blink::TextBoundary text_boundary, @@ -365,6 +448,8 @@ unsigned hash = 1u; WTF::AddIntToHash(hash, static_cast<const unsigned>(key.intent().command)); WTF::AddIntToHash(hash, + static_cast<const unsigned>(key.intent().input_event_type)); + WTF::AddIntToHash(hash, static_cast<const unsigned>(key.intent().text_boundary)); WTF::AddIntToHash(hash, static_cast<const unsigned>(key.intent().move_direction));
diff --git a/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h b/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h index 547d5122..8d93361 100644 --- a/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h +++ b/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h
@@ -45,7 +45,21 @@ bool is_base_first, const SetSelectionBy set_selection_by); + // Creates an empty (uninitialized) instance. BlinkAXEventIntent(); + + // Constructs an event intent which contains only a command without any other + // arguments. This is used e.g. by the selection changed event when the + // current selection is cleared. + explicit BlinkAXEventIntent(ax::mojom::blink::Command command); + + // Constructs an editing event intent; which is primarily attached to a text + // changed or a text attributes changed event. + BlinkAXEventIntent(ax::mojom::blink::Command command, + ax::mojom::blink::InputEventType input_event_type); + + // Constructs a selection event intent; which is attached to a selection + // changed event. BlinkAXEventIntent(ax::mojom::blink::Command command, ax::mojom::blink::TextBoundary text_boundary, ax::mojom::blink::MoveDirection move_direction);
diff --git a/third_party/blink/renderer/core/accessibility/blink_ax_event_intent_test.cc b/third_party/blink/renderer/core/accessibility/blink_ax_event_intent_test.cc index 4d2a3de..fdeaedea 100644 --- a/third_party/blink/renderer/core/accessibility/blink_ax_event_intent_test.cc +++ b/third_party/blink/renderer/core/accessibility/blink_ax_event_intent_test.cc
@@ -12,9 +12,8 @@ namespace test { TEST(BlinkAXEventIntentTest, Equality) { - BlinkAXEventIntent intent1(ax::mojom::blink::Command::kCut, - ax::mojom::blink::TextBoundary::kWordEnd, - ax::mojom::blink::MoveDirection::kForward); + BlinkAXEventIntent intent1(ax::mojom::blink::Command::kInsert, + ax::mojom::blink::InputEventType::kInsertText); BlinkAXEventIntent intent2(ax::mojom::blink::Command::kSetSelection, ax::mojom::blink::TextBoundary::kWordEnd, ax::mojom::blink::MoveDirection::kForward); @@ -35,9 +34,8 @@ } TEST(BlinkAXEventIntentTest, EqualityWithEmptyValue) { - BlinkAXEventIntent intent1(ax::mojom::blink::Command::kCut, - ax::mojom::blink::TextBoundary::kWordEnd, - ax::mojom::blink::MoveDirection::kForward); + BlinkAXEventIntent intent1(ax::mojom::blink::Command::kInsert, + ax::mojom::blink::InputEventType::kInsertText); // Empty values. BlinkAXEventIntent intent2; BlinkAXEventIntent intent3; @@ -52,9 +50,8 @@ } TEST(BlinkAXEventIntentTest, EqualityWithDeletedValue) { - BlinkAXEventIntent intent1(ax::mojom::blink::Command::kCut, - ax::mojom::blink::TextBoundary::kWordEnd, - ax::mojom::blink::MoveDirection::kForward); + BlinkAXEventIntent intent1(ax::mojom::blink::Command::kInsert, + ax::mojom::blink::InputEventType::kInsertText); BlinkAXEventIntent intent2(WTF::kHashTableDeletedValue); BlinkAXEventIntent intent3(WTF::kHashTableDeletedValue);
diff --git a/third_party/blink/renderer/core/accessibility/scoped_blink_ax_event_intent_test.cc b/third_party/blink/renderer/core/accessibility/scoped_blink_ax_event_intent_test.cc index 21d7531..77f2ab94 100644 --- a/third_party/blink/renderer/core/accessibility/scoped_blink_ax_event_intent_test.cc +++ b/third_party/blink/renderer/core/accessibility/scoped_blink_ax_event_intent_test.cc
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" #include "ui/accessibility/ax_enums.mojom-blink.h" namespace blink { @@ -23,7 +24,7 @@ { ScopedBlinkAXEventIntent scoped_intent( - {ax::mojom::blink::Command::kCut, + {ax::mojom::blink::Command::kExtendSelection, ax::mojom::blink::TextBoundary::kWordEnd, ax::mojom::blink::MoveDirection::kForward}, &GetDocument()); @@ -43,10 +44,10 @@ { ScopedBlinkAXEventIntent scoped_intent( - {{ax::mojom::blink::Command::kCut, + {{ax::mojom::blink::Command::kExtendSelection, ax::mojom::blink::TextBoundary::kWordEnd, ax::mojom::blink::MoveDirection::kForward}, - {ax::mojom::blink::Command::kCut, + {ax::mojom::blink::Command::kExtendSelection, ax::mojom::blink::TextBoundary::kWordEnd, ax::mojom::blink::MoveDirection::kForward}}, &GetDocument()); @@ -68,16 +69,14 @@ { ScopedBlinkAXEventIntent scoped_intent1( - {ax::mojom::blink::Command::kType, - ax::mojom::blink::TextBoundary::kCharacter, - ax::mojom::blink::MoveDirection::kForward}, + {ax::mojom::blink::Command::kInsert, + ax::mojom::blink::InputEventType::kInsertText}, &GetDocument()); { ScopedBlinkAXEventIntent scoped_intent2( - {ax::mojom::blink::Command::kCut, - ax::mojom::blink::TextBoundary::kWordEnd, - ax::mojom::blink::MoveDirection::kForward}, + {ax::mojom::blink::Command::kDelete, + ax::mojom::blink::InputEventType::kDeleteWordBackward}, &GetDocument()); EXPECT_TRUE( @@ -108,9 +107,8 @@ { ScopedBlinkAXEventIntent scoped_intent1( - {{ax::mojom::blink::Command::kType, - ax::mojom::blink::TextBoundary::kCharacter, - ax::mojom::blink::MoveDirection::kForward}, + {{ax::mojom::blink::Command::kInsert, + ax::mojom::blink::InputEventType::kInsertText}, {ax::mojom::blink::Command::kSetSelection, ax::mojom::blink::TextBoundary::kWordEnd, ax::mojom::blink::MoveDirection::kForward}}, @@ -118,12 +116,9 @@ { ScopedBlinkAXEventIntent scoped_intent2( - {{ax::mojom::blink::Command::kCut, - ax::mojom::blink::TextBoundary::kWordEnd, - ax::mojom::blink::MoveDirection::kForward}, - {ax::mojom::blink::Command::kClearSelection, - ax::mojom::blink::TextBoundary::kWordEnd, - ax::mojom::blink::MoveDirection::kForward}}, + {{ax::mojom::blink::Command::kDelete, + ax::mojom::blink::InputEventType::kDeleteWordForward}, + BlinkAXEventIntent{ax::mojom::blink::Command::kClearSelection}}, &GetDocument()); EXPECT_TRUE( @@ -166,17 +161,15 @@ { ScopedBlinkAXEventIntent scoped_intent1( - {ax::mojom::blink::Command::kType, - ax::mojom::blink::TextBoundary::kCharacter, - ax::mojom::blink::MoveDirection::kForward}, + {ax::mojom::blink::Command::kInsert, + ax::mojom::blink::InputEventType::kInsertText}, &GetDocument()); { // Create a second, identical intent. ScopedBlinkAXEventIntent scoped_intent2( - {ax::mojom::blink::Command::kType, - ax::mojom::blink::TextBoundary::kCharacter, - ax::mojom::blink::MoveDirection::kForward}, + {ax::mojom::blink::Command::kInsert, + ax::mojom::blink::InputEventType::kInsertText}, &GetDocument()); EXPECT_TRUE(
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index ec38bdb..4fd15a8 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -622,7 +622,6 @@ : public GarbageCollected<Document::NetworkStateObserver>, public NetworkStateNotifier::NetworkStateObserver, public ExecutionContextLifecycleObserver { - public: explicit NetworkStateObserver(ExecutionContext* context) : ExecutionContextLifecycleObserver(context) { @@ -5919,6 +5918,16 @@ return; } + if (RuntimeEnabledFeatures::OriginIsolationHeaderEnabled(dom_window_) && + dom_window_->GetAgent()->IsOriginIsolated()) { + AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kSecurity, + mojom::blink::ConsoleMessageLevel::kWarning, + "document.domain mutation is ignored because the surrounding agent " + "cluster is origin-isolated.")); + return; + } + if (GetFrame()) { UseCounter::Count(*this, dom_window_->GetSecurityOrigin()->Port() == 0
diff --git a/third_party/blink/renderer/core/feature_policy/policy_test.cc b/third_party/blink/renderer/core/feature_policy/policy_test.cc index 790a799..093ba90 100644 --- a/third_party/blink/renderer/core/feature_policy/policy_test.cc +++ b/third_party/blink/renderer/core/feature_policy/policy_test.cc
@@ -157,17 +157,40 @@ UnorderedElementsAre("*")); } -TEST_F(IFramePolicyTest, TestAllowedFeatures) { +TEST_F(IFramePolicyTest, TestSameOriginAllowedFeatures) { Vector<String> allowed_features = GetPolicy()->allowedFeatures(nullptr); + // These features are allowed in a same origin context, and not restricted by + // the parent document's policy. EXPECT_TRUE(allowed_features.Contains("fullscreen")); EXPECT_TRUE(allowed_features.Contains("payment")); EXPECT_TRUE(allowed_features.Contains("camera")); - // "geolocation" has default policy as allowed on self origin. EXPECT_TRUE(allowed_features.Contains("geolocation")); - EXPECT_FALSE(allowed_features.Contains("badfeature")); + // "midi" is restricted by the parent document's policy. EXPECT_FALSE(allowed_features.Contains("midi")); - // "sync-xhr" is allowed on all origins + // "sync-xhr" is allowed on all origins. EXPECT_TRUE(allowed_features.Contains("sync-xhr")); + // This feature does not exist, so should not be advertised as allowed. + EXPECT_FALSE(allowed_features.Contains("badfeature")); +} + +TEST_F(IFramePolicyTest, TestCrossOriginAllowedFeatures) { + // Update the iframe's policy, given a new origin. + GetPolicy()->UpdateContainerPolicy( + ParsedFeaturePolicy(), SecurityOrigin::CreateFromString(kOriginA)); + Vector<String> allowed_features = GetPolicy()->allowedFeatures(nullptr); + // These features are allowed in the cross-origin frame by the Feature-Policy + // header. + EXPECT_TRUE(allowed_features.Contains("fullscreen")); + EXPECT_TRUE(allowed_features.Contains("camera")); + // These features are not allowed by the header, and so should not be allowed + // in a cross-origin context. + EXPECT_FALSE(allowed_features.Contains("payment")); + EXPECT_FALSE(allowed_features.Contains("geolocation")); + EXPECT_FALSE(allowed_features.Contains("midi")); + // "sync-xhr" is allowed on all origins. + EXPECT_TRUE(allowed_features.Contains("sync-xhr")); + // This feature does not exist, so should not be advertised as allowed. + EXPECT_FALSE(allowed_features.Contains("badfeature")); } TEST_F(IFramePolicyTest, TestCombinedPolicy) { @@ -178,15 +201,20 @@ GetPolicy()->UpdateContainerPolicy( container_policy, SecurityOrigin::CreateFromString(kOriginA)); Vector<String> allowed_features = GetPolicy()->allowedFeatures(nullptr); - EXPECT_TRUE(allowed_features.Contains("fullscreen")); + // These features are not allowed by either the header or attribute. EXPECT_FALSE(allowed_features.Contains("payment")); + // These features are allowed by the header. + EXPECT_TRUE(allowed_features.Contains("fullscreen")); + // These features are explicitly allowed by the attribute. EXPECT_TRUE(allowed_features.Contains("geolocation")); - EXPECT_FALSE(allowed_features.Contains("midi")); EXPECT_TRUE(allowed_features.Contains("camera")); - // "geolocation" has default policy as allowed on self origin. - EXPECT_FALSE(allowed_features.Contains("badfeature")); - // "sync-xhr" is still implicitly allowed on all origins + // "midi" is allowed by the attribute, but still blocked by the parent + // document's policy. + EXPECT_FALSE(allowed_features.Contains("midi")); + // "sync-xhr" is still implicitly allowed on all origins. EXPECT_TRUE(allowed_features.Contains("sync-xhr")); + // This feature does not exist, so should not be advertised as allowed. + EXPECT_FALSE(allowed_features.Contains("badfeature")); } } // namespace blink
diff --git a/third_party/blink/renderer/core/fetch/fetch_data_loader.cc b/third_party/blink/renderer/core/fetch/fetch_data_loader.cc index 70c83354..b9d1fcb 100644 --- a/third_party/blink/renderer/core/fetch/fetch_data_loader.cc +++ b/third_party/blink/renderer/core/fetch/fetch_data_loader.cc
@@ -104,8 +104,12 @@ private: void FinishedCreatingFromDataPipe( const scoped_refptr<BlobDataHandle>& blob_handle) { + if (!blob_handle) { + DidFetchDataLoadFailed(); + return; + } if (!load_complete_) { - blob_handle_ = std::move(blob_handle); + blob_handle_ = blob_handle; return; } client_->DidFetchDataLoadedBlobHandle(blob_handle);
diff --git a/third_party/blink/renderer/core/frame/dom_timer.cc b/third_party/blink/renderer/core/frame/dom_timer.cc index a287ba4..4330003 100644 --- a/third_party/blink/renderer/core/frame/dom_timer.cc +++ b/third_party/blink/renderer/core/frame/dom_timer.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/frame/dom_timer.h" +#include "base/numerics/clamped_math.h" #include "base/single_thread_task_runner.h" #include "base/time/time.h" #include "third_party/blink/public/platform/task_type.h" @@ -47,20 +48,6 @@ constexpr base::TimeDelta kMinimumInterval = base::TimeDelta::FromMilliseconds(4); -// Computes the timeout of a timer according to the algorithm at -// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html. -base::TimeDelta ComputeTimeout(base::TimeDelta timeout, int nesting_level) { - // Step 10: - if (timeout < base::TimeDelta()) - timeout = base::TimeDelta(); - - // Step 11 (the implementation is not spec-compliant crbug.com/1108877): - if (nesting_level + 1 >= kMaxTimerNestingLevel && timeout < kMinimumInterval) - timeout = kMinimumInterval; - - return timeout; -} - } // namespace int DOMTimer::Install(ExecutionContext* context, @@ -87,23 +74,42 @@ bool single_shot, int timeout_id) : ExecutionContextLifecycleObserver(context), - TimerBase(context->GetTaskRunner( - ComputeTimeout(timeout, context->Timers()->TimerNestingLevel()) - .is_zero() - ? TaskType::kJavascriptTimerImmediate - : TaskType::kJavascriptTimerDelayed)), + TimerBase(nullptr), timeout_id_(timeout_id), + // Step 9: nesting_level_(context->Timers()->TimerNestingLevel()), action_(action) { DCHECK_GT(timeout_id, 0); - // Steps 10 and 11, and rounding up to 1 ms for historical reasons - // crbug.com/402694. - timeout = std::max(base::TimeDelta::FromMilliseconds(1), - ComputeTimeout(timeout, nesting_level_)); + // Step 10: + if (timeout < base::TimeDelta()) + timeout = base::TimeDelta(); - // Step 12 and 13: - ++nesting_level_; + // Steps 12 and 13: + // Note: The implementation increments the nesting level before using it to + // adjust timeout, contrary to what the spec requires crbug.com/1108877. + IncrementNestingLevel(); + + // Step 11: + // Note: The implementation uses >= instead of >, contrary to what the spec + // requires crbug.com/1108877. + if (nesting_level_ >= kMaxTimerNestingLevel && timeout < kMinimumInterval) + timeout = kMinimumInterval; + + // Select TaskType based on nesting level. + TaskType task_type; + if (timeout.is_zero()) { + task_type = TaskType::kJavascriptTimerImmediate; + DCHECK_LT(nesting_level_, kMaxTimerNestingLevel); + } else if (nesting_level_ >= kMaxTimerNestingLevel) { + task_type = TaskType::kJavascriptTimerDelayedHighNesting; + } else { + task_type = TaskType::kJavascriptTimerDelayedLowNesting; + } + MoveToNewTaskRunner(context->GetTaskRunner(task_type)); + + // Clamping up to 1ms for historical reasons crbug.com/402694. + timeout = std::max(timeout, base::TimeDelta::FromMilliseconds(1)); if (single_shot) StartOneShot(timeout, FROM_HERE); @@ -164,15 +170,29 @@ // Simple case for non-one-shot timers. if (IsActive()) { - if (is_interval && RepeatInterval() < kMinimumInterval) { - nesting_level_++; - if (nesting_level_ >= kMaxTimerNestingLevel) { - MoveToNewTaskRunner( - context->GetTaskRunner(TaskType::kJavascriptTimerDelayed)); + DCHECK(is_interval); + + // Steps 12 and 13: + // Note: The implementation increments the nesting level before using it to + // adjust timeout, contrary to what the spec requires crbug.com/1108877. + IncrementNestingLevel(); + + // Make adjustments when the nesting level becomes >= |kMaxNestingLevel|. + // Note: The implementation uses >= instead of >, contrary to what the spec + // requires crbug.com/1108877. + if (nesting_level_ == kMaxTimerNestingLevel) { + // Move to the TaskType that corresponds to nesting level >= + // |kMaxNestingLevel|. + MoveToNewTaskRunner( + context->GetTaskRunner(TaskType::kJavascriptTimerDelayedHighNesting)); + // Step 11: + if (RepeatInterval() < kMinimumInterval) AugmentRepeatInterval(kMinimumInterval - RepeatInterval()); - } } + DCHECK(nesting_level_ < kMaxTimerNestingLevel || + RepeatInterval() >= kMinimumInterval); + // No access to member variables after this point, it can delete the timer. action_->Execute(context); @@ -206,4 +226,8 @@ ExecutionContextLifecycleObserver::Trace(visitor); } +void DOMTimer::IncrementNestingLevel() { + nesting_level_ = base::ClampAdd(nesting_level_, 1); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/dom_timer.h b/third_party/blink/renderer/core/frame/dom_timer.h index 460577a..8750c50 100644 --- a/third_party/blink/renderer/core/frame/dom_timer.h +++ b/third_party/blink/renderer/core/frame/dom_timer.h
@@ -79,6 +79,11 @@ private: void Fired() override; + // Increments the nesting level, clamping at the maximum value that can be + // represented by |int|. Since the value is only used to compare with + // |kMaxTimerNestingLevel|, the clamping doesn't affect behavior. + void IncrementNestingLevel(); + int timeout_id_; int nesting_level_; probe::AsyncTaskId async_task_id_;
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_base.cc b/third_party/blink/renderer/core/frame/web_frame_widget_base.cc index 9353cf8..fef6b30 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_base.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
@@ -489,11 +489,10 @@ return; } - WebRect offset_in_window(drag_image_offset.x(), drag_image_offset.y(), 0, 0); - Client()->ConvertViewportToWindow(&offset_in_window); + gfx::Point offset_in_dips = widget_base_->BlinkSpaceToDIPs(drag_image_offset); GetAssociatedFrameWidgetHost()->StartDragging( drag_data, operations_allowed, drag_image, - gfx::Vector2d(offset_in_window.x, offset_in_window.y), + gfx::Vector2d(offset_in_dips.x(), offset_in_dips.y()), possible_drag_event_info_.Clone()); } @@ -1560,11 +1559,11 @@ WebRect control_bounds; WebRect selection_bounds; controller->GetLayoutBounds(&control_bounds, &selection_bounds); - client_->ConvertViewportToWindow(&control_bounds); - edit_context_control_bounds->emplace(control_bounds); + *edit_context_control_bounds = + widget_base_->BlinkSpaceToDIPs(gfx::Rect(control_bounds)); if (controller->IsEditContextActive()) { - client_->ConvertViewportToWindow(&selection_bounds); - edit_context_selection_bounds->emplace(selection_bounds); + *edit_context_selection_bounds = + widget_base_->BlinkSpaceToDIPs(gfx::Rect(selection_bounds)); } } @@ -1605,15 +1604,16 @@ WebRect focus_webrect; WebRect anchor_webrect; SelectionBounds(focus_webrect, anchor_webrect); - client_->ConvertViewportToWindow(&focus_webrect); - client_->ConvertViewportToWindow(&anchor_webrect); + gfx::Rect focus_rect_in_dips = + widget_base_->BlinkSpaceToDIPs(gfx::Rect(focus_webrect)); + gfx::Rect anchor_rect_in_dips = + widget_base_->BlinkSpaceToDIPs(gfx::Rect(anchor_webrect)); // if the bounds are the same return false. - if (gfx::Rect(focus_webrect) == *focus && - gfx::Rect(anchor_webrect) == *anchor) + if (focus_rect_in_dips == *focus && anchor_rect_in_dips == *anchor) return false; - *focus = gfx::Rect(focus_webrect); - *anchor = gfx::Rect(anchor_webrect); + *focus = focus_rect_in_dips; + *anchor = anchor_rect_in_dips; WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget(); if (!focused_frame) @@ -1759,9 +1759,9 @@ } uint64_t WebFrameWidgetBase::GetScrollableContainerIdAt( - const gfx::PointF& point) { - gfx::PointF point_in_pixel = Client()->ConvertWindowPointToViewport(point); - return HitTestResultAt(point_in_pixel).GetScrollableContainerId(); + const gfx::PointF& point_in_dips) { + gfx::PointF point = widget_base_->DIPsToBlinkSpace(point_in_dips); + return HitTestResultAt(point).GetScrollableContainerId(); } void WebFrameWidgetBase::SetEditCommandsForNextKeyEvent( @@ -1860,7 +1860,7 @@ } void WebFrameWidgetBase::GetCompositionCharacterBoundsInWindow( - Vector<gfx::Rect>* bounds) { + Vector<gfx::Rect>* bounds_in_dips) { WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget(); if (!focused_frame) return; @@ -1870,13 +1870,11 @@ if (!controller->GetCompositionCharacterBounds(bounds_from_blink)) return; - for (size_t i = 0; i < bounds_from_blink.size(); ++i) { - Client()->ConvertViewportToWindow(&bounds_from_blink[i]); - bounds->push_back(bounds_from_blink[i]); + for (auto& rect : bounds_from_blink) { + bounds_in_dips->push_back(widget_base_->BlinkSpaceToDIPs(gfx::Rect(rect))); } } - void WebFrameWidgetBase::AddImeTextSpansToExistingText( uint32_t start, uint32_t end, @@ -1901,10 +1899,9 @@ unsigned length = ime_text_span.end_offset - ime_text_span.start_offset; focused_frame->FirstRectForCharacterRange(ime_text_span.start_offset, length, webrect); - Client()->ConvertViewportToWindow(&webrect); ime_text_spans_info.push_back(ui::mojom::blink::ImeTextSpanInfo::New( - ime_text_span, gfx::Rect(webrect))); + ime_text_span, widget_base_->BlinkSpaceToDIPs(gfx::Rect(webrect)))); } return ime_text_spans_info; } @@ -2063,13 +2060,13 @@ focused_frame->ReplaceMisspelledRange(word); } -void WebFrameWidgetBase::SelectRange(const gfx::Point& base, - const gfx::Point& extent) { +void WebFrameWidgetBase::SelectRange(const gfx::Point& base_in_dips, + const gfx::Point& extent_in_dips) { WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget(); if (!focused_frame) return; - focused_frame->SelectRange(Client()->ConvertWindowPointToViewport(base), - Client()->ConvertWindowPointToViewport(extent)); + focused_frame->SelectRange(widget_base_->DIPsToBlinkSpace(base_in_dips), + widget_base_->DIPsToBlinkSpace(extent_in_dips)); } void WebFrameWidgetBase::AdjustSelectionByCharacterOffset( @@ -2097,16 +2094,17 @@ selection_menu_behavior); } -void WebFrameWidgetBase::MoveRangeSelectionExtent(const gfx::Point& extent) { +void WebFrameWidgetBase::MoveRangeSelectionExtent( + const gfx::Point& extent_in_dips) { WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget(); if (!focused_frame) return; focused_frame->MoveRangeSelectionExtent( - Client()->ConvertWindowPointToViewport(extent)); + widget_base_->DIPsToBlinkSpace(extent_in_dips)); } void WebFrameWidgetBase::ScrollFocusedEditableNodeIntoRect( - const gfx::Rect& rect) { + const gfx::Rect& rect_in_dips) { WebLocalFrame* local_frame = FocusedWebLocalFrameInWidget(); if (!local_frame) return; @@ -2116,15 +2114,15 @@ // DidChangeVisibleViewport to ensure that we don't assume the element // is already in view and ignore the scroll. local_frame->Client()->ResetHasScrolledFocusedEditableIntoView(); - local_frame->Client()->ScrollFocusedEditableElementIntoRect(rect); + local_frame->Client()->ScrollFocusedEditableElementIntoRect(rect_in_dips); } -void WebFrameWidgetBase::MoveCaret(const gfx::Point& point) { +void WebFrameWidgetBase::MoveCaret(const gfx::Point& point_in_dips) { WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget(); if (!focused_frame) return; focused_frame->MoveCaretSelection( - Client()->ConvertWindowPointToViewport(point)); + widget_base_->DIPsToBlinkSpace(point_in_dips)); } #if defined(OS_ANDROID)
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_base.h b/third_party/blink/renderer/core/frame/web_frame_widget_base.h index 0d81f1d..2b60193 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_base.h +++ b/third_party/blink/renderer/core/frame/web_frame_widget_base.h
@@ -150,7 +150,7 @@ WebInputEvent::Type injected_type) override; void DidChangeCursor(const ui::Cursor&) override; void GetCompositionCharacterBoundsInWindow( - Vector<gfx::Rect>* bounds) override; + Vector<gfx::Rect>* bounds_in_dips) override; gfx::Range CompositionRange() override; WebTextInputInfo TextInputInfo() override; ui::mojom::VirtualKeyboardVisibilityRequest @@ -179,7 +179,8 @@ int relative_cursor_pos) override; void FinishComposingText(bool keep_selection) override; bool IsProvisional() override; - uint64_t GetScrollableContainerIdAt(const gfx::PointF& point) override; + uint64_t GetScrollableContainerIdAt( + const gfx::PointF& point_in_dips) override; void SetEditCommandsForNextKeyEvent( Vector<mojom::blink::EditCommandPtr> edit_commands) override; @@ -214,14 +215,16 @@ void CollapseSelection() override; void Replace(const String& word) override; void ReplaceMisspelling(const String& word) override; - void SelectRange(const gfx::Point& base, const gfx::Point& extent) override; + void SelectRange(const gfx::Point& base_in_dips, + const gfx::Point& extent_in_dips) override; void AdjustSelectionByCharacterOffset( int32_t start, int32_t end, mojom::blink::SelectionMenuBehavior behavior) override; - void MoveRangeSelectionExtent(const gfx::Point& extent) override; - void ScrollFocusedEditableNodeIntoRect(const gfx::Rect& rect) override; - void MoveCaret(const gfx::Point& point) override; + void MoveRangeSelectionExtent(const gfx::Point& extent_in_dips) override; + void ScrollFocusedEditableNodeIntoRect( + const gfx::Rect& rect_in_dips) override; + void MoveCaret(const gfx::Point& point_in_dips) override; #if defined(OS_ANDROID) void SelectWordAroundCaret(SelectWordAroundCaretCallback callback) override; #endif
diff --git a/third_party/blink/renderer/core/html/forms/range_input_type.cc b/third_party/blink/renderer/core/html/forms/range_input_type.cc index 27b6d62..251f273 100644 --- a/third_party/blink/renderer/core/html/forms/range_input_type.cc +++ b/third_party/blink/renderer/core/html/forms/range_input_type.cc
@@ -263,7 +263,7 @@ LegacyLayout legacy) const { UseCounter::Count(GetElement().GetDocument(), WebFeature::kLegacyLayoutBySlider); - // TODO(crbug.com/1040826): input[type=range] should not use + // TODO(crbug.com/1131352): input[type=range] should not use // LayoutFlexibleBox. return LayoutObjectFactory::CreateFlexibleBox(GetElement(), style, legacy); }
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.cc b/third_party/blink/renderer/core/layout/layout_flexible_box.cc index cd0739dc..0c892801 100644 --- a/third_party/blink/renderer/core/layout/layout_flexible_box.cc +++ b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
@@ -219,7 +219,7 @@ LinePositionMode mode) const { CheckIsNotDestroyed(); DCHECK_EQ(mode, kPositionOnContainingLine); - // TODO(crbug.com/1040826): input[type=range] should not use + // TODO(crbug.com/1131352): input[type=range] should not use // LayoutFlexibleBox. We should move out this code. if (const auto* input = DynamicTo<HTMLInputElement>(GetNode())) { if (input->type() == input_type_names::kRange) {
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc index f1d9f265..f42e560 100644 --- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
@@ -1205,8 +1205,13 @@ if (!container_builder_.Baseline() && fallback_baseline) container_builder_.SetBaseline(*fallback_baseline); - if (Node().IsButton()) + // TODO(crbug.com/1131352): Avoid control-specific handling. + if (Node().IsButton()) { AdjustButtonBaseline(final_content_cross_size); + } else if (Node().IsSlider()) { + container_builder_.SetBaseline(BorderScrollbarPadding().BlockSum() + + final_content_cross_size); + } // Signal if we need to relayout with new child scrollbar information. return success;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc index ddca145..403ab97 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -677,11 +677,11 @@ unsigned start_offset) const { DCHECK_LE(item.start_offset_, start_offset); DCHECK_LT(start_offset, item.end_offset_); + const unsigned end_offset = item.end_offset_; + if (!item.shape_result_ || item.shape_result_->IsAppliedSpacing()) + return NGInlineItem(item, start_offset, end_offset, nullptr); if (item.start_offset_ == start_offset) return item; - const unsigned end_offset = item.end_offset_; - if (!item.shape_result_) - return NGInlineItem(item, start_offset, end_offset, nullptr); // TODO(yosin): We should handle |shape_result| doesn't have safe-to-break // at start and end, because of |ShapeText()| splits |ShapeResult| ignoring // safe-to-break offset. @@ -701,11 +701,11 @@ DCHECK_LT(item.start_offset_, end_offset); DCHECK_LE(end_offset, item.end_offset_); DCHECK_EQ(item.layout_object_, layout_text_); + const unsigned start_offset = item.start_offset_; + if (!item.shape_result_ || item.shape_result_->IsAppliedSpacing()) + return NGInlineItem(item, start_offset, end_offset, nullptr); if (item.end_offset_ == end_offset) return item; - const unsigned start_offset = item.start_offset_; - if (!item.shape_result_) - return NGInlineItem(item, start_offset, end_offset, nullptr); // TODO(yosin): We should handle |shape_result| doesn't have safe-to-break // at start and end, because of |ShapeText()| splits |ShapeResult| ignoring // safe-to-break offset.
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 cd1eb5a..7226d502 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
@@ -247,6 +247,9 @@ LayoutUnit static_width_right = LayoutUnit(0); if (initial_index_right + 1 < line.size()) { const NGLogicalLineItem& item = line[initial_index_right + 1]; + // |line_width| and/or InlineOffset() might be saturated. + if (line_width <= item.InlineOffset()) + return line_width; static_width_right = line_width - item.InlineOffset() + item.margin_line_left; } @@ -266,8 +269,13 @@ if (IsLtr(line_direction_)) { // Find truncation point at the left, truncate, and add an ellipsis. - while (available_width_left >= line[index_left].inline_size) + while (available_width_left >= line[index_left].inline_size) { available_width_left -= line[index_left++].inline_size; + if (index_left >= line.size()) { + // We have a logic bug. Do nothing. + return line_width; + } + } DCHECK_LE(index_left, index_right); DCHECK(!line[index_left].IsPlaceholder()); wtf_size_t new_index = AddTruncatedChild( @@ -288,8 +296,15 @@ } // Find truncation point at the right. - while (available_width_right >= line[index_right].inline_size) - available_width_right -= line[index_right--].inline_size; + while (available_width_right >= line[index_right].inline_size) { + available_width_right -= line[index_right].inline_size; + if (index_right == 0) { + // We have a logic bug. We proceed anyway because |line| was already + // modified. + break; + } + --index_right; + } LayoutUnit new_modified_right_offset = line[line.size() - 1].InlineOffset() + ellipsis_width_; DCHECK_LE(index_left, index_right); @@ -316,8 +331,14 @@ } else { // Find truncation point at the right, truncate, and add an ellipsis. - while (available_width_right >= line[index_right].inline_size) - available_width_right -= line[index_right--].inline_size; + while (available_width_right >= line[index_right].inline_size) { + available_width_right -= line[index_right].inline_size; + if (index_right == 0) { + // We have a logic bug. Do nothing. + return line_width; + } + --index_right; + } DCHECK_LE(index_left, index_right); DCHECK(!line[index_right].IsPlaceholder()); wtf_size_t new_index = @@ -341,8 +362,14 @@ LayoutUnit ellipsis_offset = line[line.size() - 1].InlineOffset(); // Find truncation point at the left. - while (available_width_left >= line[index_left].inline_size) + while (available_width_left >= line[index_left].inline_size) { available_width_left -= line[index_left++].inline_size; + if (index_left >= line.size()) { + // We have a logic bug. We proceed anyway because |line| was already + // modified. + break; + } + } DCHECK_LE(index_left, index_right); DCHECK(!line[index_left].IsPlaceholder()); if (available_width_left > 0) {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc index 91f2af90..f47df01 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
@@ -38,7 +38,10 @@ offset = child.Offset().left; size = child->Size().width; } - if (child->IsContainer()) { + // TODO(mstensho): Need to detect whether we're actually clipping in the + // block direction. The combination of overflow-x:clip and + // overflow-y:visible should enter children here. + if (child->IsContainer() && !child->HasNonVisibleOverflow()) { LayoutUnit children_size = CalculateColumnContentBlockSize( To<NGPhysicalContainerFragment>(*child), multicol_is_horizontal_writing_mode);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc index b5d5d87..8db199bd 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h" +#include "third_party/blink/renderer/core/html/forms/html_input_element.h" +#include "third_party/blink/renderer/core/input_type_names.h" #include "third_party/blink/renderer/core/layout/geometry/logical_size.h" #include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.h" #include "third_party/blink/renderer/core/layout/layout_replaced.h" @@ -63,6 +65,12 @@ } // namespace +bool NGLayoutInputNode::IsSlider() const { + if (const auto* input = DynamicTo<HTMLInputElement>(box_->GetNode())) + return input->type() == input_type_names::kRange; + return false; +} + bool NGLayoutInputNode::IsEmptyTableSection() const { return box_->IsTableSection() && To<LayoutNGTableSection>(box_)->IsEmpty(); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h index 6659c42..23cca89 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
@@ -135,6 +135,8 @@ bool IsRenderedLegend() const { return IsBlock() && box_->IsRenderedLegend(); } + // Return true if this node is for <input type=range>. + bool IsSlider() const; bool IsTable() const { return IsBlock() && box_->IsTable(); } bool IsTableCaption() const { return IsBlock() && box_->IsTableCaption(); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc index 7fc4ce3..f615081 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc
@@ -246,6 +246,11 @@ height_type, &child_scroll_overflow); child_box->AdjustScrollableOverflowForPropagation( container, height_type, &child_scroll_overflow); + if (UNLIKELY(has_hanging)) { + AdjustScrollableOverflowForHanging(line.RectInContainerBlock(), + container_writing_mode, + &child_scroll_overflow); + } } else { child_scroll_overflow = child_box->ScrollableOverflowForPropagation(container, height_type);
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 129b1da..21f397d 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -1280,12 +1280,16 @@ } static bool IsClipPathDescendant(const LayoutObject& object) { + // If the object itself is a resource container (root of a resource subtree) + // it is not considered a clipPath descendant since it is independent of its + // ancestors. + if (object.IsSVGResourceContainer()) + return false; const LayoutObject* parent = object.Parent(); while (parent) { if (parent->IsSVGResourceContainer()) { auto* container = ToLayoutSVGResourceContainer(parent); - if (container->ResourceType() == kClipperResourceType) - return true; + return container->ResourceType() == kClipperResourceType; } parent = parent->Parent(); }
diff --git a/third_party/blink/renderer/core/svg/svg_length_context.cc b/third_party/blink/renderer/core/svg/svg_length_context.cc index c84405593..d8c9732 100644 --- a/third_party/blink/renderer/core/svg/svg_length_context.cc +++ b/third_party/blink/renderer/core/svg/svg_length_context.cc
@@ -202,9 +202,16 @@ const Length& y_length, const ComputedStyle& style) const { FloatSize viewport_size; - if (x_length.IsPercentOrCalc() || y_length.IsPercentOrCalc()) + if (x_length.IsPercentOrCalc() || y_length.IsPercentOrCalc()) { DetermineViewport(viewport_size); - + // If either |x_length| or |y_length| is 'auto', set that viewport dimension + // to zero so that the corresponding Length resolves to zero. This matches + // the behavior of ValueForLength() below. + if (x_length.IsAuto()) + viewport_size.SetWidth(0); + else if (y_length.IsAuto()) + viewport_size.SetHeight(0); + } float zoom = style.EffectiveZoom(); return FloatPoint(ValueForLength(x_length, zoom, viewport_size.Width()), ValueForLength(y_length, zoom, viewport_size.Height()));
diff --git a/third_party/blink/renderer/core/workers/shared_worker_content_settings_proxy.cc b/third_party/blink/renderer/core/workers/shared_worker_content_settings_proxy.cc index 6dfe6ea1..1b5febcf 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_content_settings_proxy.cc +++ b/third_party/blink/renderer/core/workers/shared_worker_content_settings_proxy.cc
@@ -35,7 +35,7 @@ GetService()->RequestFileSystemAccessSync(&result); break; } - case StorageType::kDatabase: { + default: { // TODO(shuagga@microsoft.com): Revisit this default in the future. return true; }
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc index cada3fb9..f2ecee88 100644 --- a/third_party/blink/renderer/core/workers/worker_thread.cc +++ b/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -559,34 +559,36 @@ // worker thread. See also comments on GetTaskRunner(). // We only capture task types that are actually used. When you want to use a // new task type, add it here. - Vector<TaskType> available_task_types = {TaskType::kBackgroundFetch, - TaskType::kCanvasBlobSerialization, - TaskType::kDatabaseAccess, - TaskType::kDOMManipulation, - TaskType::kFileReading, - TaskType::kFontLoading, - TaskType::kInternalDefault, - TaskType::kInternalInspector, - TaskType::kInternalLoading, - TaskType::kInternalMedia, - TaskType::kInternalMediaRealTime, - TaskType::kInternalTest, - TaskType::kInternalWebCrypto, - TaskType::kJavascriptTimerDelayed, - TaskType::kJavascriptTimerImmediate, - TaskType::kMediaElementEvent, - TaskType::kMicrotask, - TaskType::kMiscPlatformAPI, - TaskType::kNetworking, - TaskType::kPerformanceTimeline, - TaskType::kPermission, - TaskType::kPostedMessage, - TaskType::kRemoteEvent, - TaskType::kUserInteraction, - TaskType::kWebGL, - TaskType::kWebLocks, - TaskType::kWebSocket, - TaskType::kWorkerAnimation}; + Vector<TaskType> available_task_types = { + TaskType::kBackgroundFetch, + TaskType::kCanvasBlobSerialization, + TaskType::kDatabaseAccess, + TaskType::kDOMManipulation, + TaskType::kFileReading, + TaskType::kFontLoading, + TaskType::kInternalDefault, + TaskType::kInternalInspector, + TaskType::kInternalLoading, + TaskType::kInternalMedia, + TaskType::kInternalMediaRealTime, + TaskType::kInternalTest, + TaskType::kInternalWebCrypto, + TaskType::kJavascriptTimerImmediate, + TaskType::kJavascriptTimerDelayedLowNesting, + TaskType::kJavascriptTimerDelayedHighNesting, + TaskType::kMediaElementEvent, + TaskType::kMicrotask, + TaskType::kMiscPlatformAPI, + TaskType::kNetworking, + TaskType::kPerformanceTimeline, + TaskType::kPermission, + TaskType::kPostedMessage, + TaskType::kRemoteEvent, + TaskType::kUserInteraction, + TaskType::kWebGL, + TaskType::kWebLocks, + TaskType::kWebSocket, + TaskType::kWorkerAnimation}; for (auto type : available_task_types) { auto task_runner = worker_scheduler_->GetTaskRunner(type); auto result = worker_task_runners_.insert(type, std::move(task_runner));
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 17125e02..2ed9a79 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -1868,7 +1868,7 @@ return false; const AXObject* focused_object = AXObjectCache().GetOrCreate(focused_element); - if (!focused_object->IsTextControl()) + if (!focused_object || !focused_object->IsTextControl()) return false; if (!focused_object->GetAOMPropertyOrARIAAttribute(
diff --git a/third_party/blink/renderer/modules/hid/hid_device.idl b/third_party/blink/renderer/modules/hid/hid_device.idl index 9a5e09e0..c2c7acd 100644 --- a/third_party/blink/renderer/modules/hid/hid_device.idl +++ b/third_party/blink/renderer/modules/hid/hid_device.idl
@@ -17,11 +17,11 @@ readonly attribute boolean opened; // The 16-bit vendor and product IDs reported by the device. - readonly attribute unsigned short vendorId; - readonly attribute unsigned short productId; + [HighEntropy=Direct, Measure] readonly attribute unsigned short vendorId; + [HighEntropy=Direct, Measure] readonly attribute unsigned short productId; // The device name, as reported by the device and shown in the chooser. - readonly attribute DOMString productName; + [HighEntropy=Direct, Measure] readonly attribute DOMString productName; // An array of the top-level collections within the HID report descriptor, // in the order they were encountered within the descriptor. The collections
diff --git a/third_party/blink/renderer/modules/hid/hid_report_item.idl b/third_party/blink/renderer/modules/hid/hid_report_item.idl index eed37327..f091fad 100644 --- a/third_party/blink/renderer/modules/hid/hid_report_item.idl +++ b/third_party/blink/renderer/modules/hid/hid_report_item.idl
@@ -34,21 +34,21 @@ ] interface HIDReportItem { // True if the item represents an absolute measurement (e.g. joystick tilt) // or false if it represents a relative measurement (e.g. mouse movement). - readonly attribute boolean isAbsolute; + [HighEntropy=Direct, Measure] readonly attribute boolean isAbsolute; // True if the item is an Array or false if it is a Variable. Array items // are typically used when a device needs to represent a large number of // button-type inputs, but only a few inputs need to be active at once. // Variable items require space in the report for each input, but can report // all inputs simultaneously. - readonly attribute boolean isArray; + [HighEntropy=Direct, Measure] readonly attribute boolean isArray; // True if the usages for this item are defined by |usageMinimum| and // |usageMaximum| or false if the usages are defined by |usages|. - readonly attribute boolean isRange; + [HighEntropy=Direct, Measure] readonly attribute boolean isRange; // True if the item uses an out-of-bounds value when there is no input. - readonly attribute boolean hasNull; + [HighEntropy=Direct, Measure] readonly attribute boolean hasNull; // An ordered list of 32-bit usage values associated with this item. Unused // if |isRange| is true. If |reportCount| is two or more, usages are @@ -58,19 +58,19 @@ // The minimum and maximum usage values associated with this item. Unused if // |isRange| is false. If |reportCount| is two or more, usages are assigned // starting from |usageMinimum| and increment by one. - readonly attribute unsigned long usageMinimum; - readonly attribute unsigned long usageMaximum; + [HighEntropy=Direct, Measure] readonly attribute unsigned long usageMinimum; + [HighEntropy=Direct, Measure] readonly attribute unsigned long usageMaximum; // The size of a single field described by this item, in bits. - readonly attribute unsigned short reportSize; + [HighEntropy=Direct, Measure] readonly attribute unsigned short reportSize; // The number of similar fields described by this item. The total size of // the item described by this report is |reportSize| * |reportCount| bits. - readonly attribute unsigned short reportCount; + [HighEntropy=Direct, Measure] readonly attribute unsigned short reportCount; // The base 10 exponent of the units for this report item. For instance, for // kilograms |unitExponent| would be 3 and for micrograms it would be -6. - readonly attribute byte unitExponent; + [HighEntropy=Direct, Measure] readonly attribute byte unitExponent; // The unit system determines which units are used for length, mass, time, // temperature, current, and luminous intensity. May be "none" if the values @@ -81,23 +81,23 @@ // unit definition. For instance, for acceleration all factors would have // an exponent of 0 except |unitFactorLengthExponent| which would be 1 and // |unitFactorTimeExponent| which would be -2. - readonly attribute byte unitFactorLengthExponent; - readonly attribute byte unitFactorMassExponent; - readonly attribute byte unitFactorTimeExponent; - readonly attribute byte unitFactorTemperatureExponent; - readonly attribute byte unitFactorCurrentExponent; - readonly attribute byte unitFactorLuminousIntensityExponent; + [HighEntropy=Direct, Measure] readonly attribute byte unitFactorLengthExponent; + [HighEntropy=Direct, Measure] readonly attribute byte unitFactorMassExponent; + [HighEntropy=Direct, Measure] readonly attribute byte unitFactorTimeExponent; + [HighEntropy=Direct, Measure] readonly attribute byte unitFactorTemperatureExponent; + [HighEntropy=Direct, Measure] readonly attribute byte unitFactorCurrentExponent; + [HighEntropy=Direct, Measure] readonly attribute byte unitFactorLuminousIntensityExponent; // The minimum and maximum values that may be represented by this input. A // device with |hasNull| may report a value outside this range to indicate // no input. - readonly attribute long logicalMinimum; - readonly attribute long logicalMaximum; + [HighEntropy=Direct, Measure] readonly attribute long logicalMinimum; + [HighEntropy=Direct, Measure] readonly attribute long logicalMaximum; // The minimum and maximum values, scaled to the units described by |unit| // and |unitExponent|. - readonly attribute long physicalMinimum; - readonly attribute long physicalMaximum; + [HighEntropy=Direct, Measure] readonly attribute long physicalMinimum; + [HighEntropy=Direct, Measure] readonly attribute long physicalMaximum; // The strings associated with this item. readonly attribute FrozenArray<DOMString> strings;
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_factory.cc b/third_party/blink/renderer/modules/indexeddb/idb_factory.cc index e02853f..4294805 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_factory.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
@@ -268,7 +268,7 @@ return resolver->Promise(); } - if (!CachedAllowIndexedDB(script_state)) { + if (!AllowIndexedDB(script_state)) { exception_state.ThrowDOMException(DOMExceptionCode::kUnknownError, kPermissionDeniedErrorMessage); resolver->Reject(); @@ -304,7 +304,7 @@ WebFeature::kFileAccessedDatabase); } - if (!CachedAllowIndexedDB(script_state)) { + if (!AllowIndexedDB(script_state)) { request->HandleResponse(MakeGarbageCollected<DOMException>( DOMExceptionCode::kUnknownError, kPermissionDeniedErrorMessage)); return request; @@ -365,7 +365,7 @@ script_state, database_callbacks, std::move(transaction_backend), transaction_id, version, std::move(metrics), GetObservedFeature()); - if (!CachedAllowIndexedDB(script_state)) { + if (!AllowIndexedDB(script_state)) { request->HandleResponse(MakeGarbageCollected<DOMException>( DOMExceptionCode::kUnknownError, kPermissionDeniedErrorMessage)); return request; @@ -436,7 +436,7 @@ IDBDatabaseMetadata::kDefaultVersion, std::move(metrics), GetObservedFeature()); - if (!CachedAllowIndexedDB(script_state)) { + if (!AllowIndexedDB(script_state)) { request->HandleResponse(MakeGarbageCollected<DOMException>( DOMExceptionCode::kUnknownError, kPermissionDeniedErrorMessage)); return request; @@ -506,14 +506,6 @@ WebContentSettingsClient::StorageType::kIndexedDB); } -bool IDBFactory::CachedAllowIndexedDB(ScriptState* script_state) { - if (!cached_allowed_.has_value()) { - // Cache the AllowIndexedDB() call because it triggers a sync IPC. - cached_allowed_.emplace(AllowIndexedDB(script_state)); - } - return cached_allowed_.value(); -} - mojo::PendingAssociatedRemote<mojom::blink::IDBCallbacks> IDBFactory::GetCallbacksProxy(std::unique_ptr<WebIDBCallbacks> callbacks_impl) { mojo::PendingAssociatedRemote<mojom::blink::IDBCallbacks> pending_callbacks;
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_factory.h b/third_party/blink/renderer/modules/indexeddb/idb_factory.h index f38a013..0299fa6 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_factory.h +++ b/third_party/blink/renderer/modules/indexeddb/idb_factory.h
@@ -95,7 +95,6 @@ bool); bool AllowIndexedDB(ScriptState* script_state); - bool CachedAllowIndexedDB(ScriptState* script_state); mojo::PendingAssociatedRemote<mojom::blink::IDBCallbacks> GetCallbacksProxy( std::unique_ptr<WebIDBCallbacks> callbacks); @@ -107,8 +106,6 @@ mojo::Remote<mojom::blink::IDBFactory> factory_; mojo::Remote<mojom::blink::FeatureObserver> feature_observer_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - - base::Optional<bool> cached_allowed_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/media_device_info.idl b/third_party/blink/renderer/modules/mediastream/media_device_info.idl index a67cde9..2788dc8 100644 --- a/third_party/blink/renderer/modules/mediastream/media_device_info.idl +++ b/third_party/blink/renderer/modules/mediastream/media_device_info.idl
@@ -36,8 +36,8 @@ SecureContext ] interface MediaDeviceInfo { readonly attribute DOMString deviceId; - readonly attribute MediaDeviceKind kind; - readonly attribute DOMString label; - readonly attribute DOMString groupId; + [HighEntropy=Direct, Measure] readonly attribute MediaDeviceKind kind; + [HighEntropy=Direct, Measure] readonly attribute DOMString label; + [HighEntropy=Direct, Measure] readonly attribute DOMString groupId; [CallWith=ScriptState, ImplementedAs=toJSONForBinding] object toJSON(); };
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc index 2764b87..82a155cd 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc
@@ -94,7 +94,8 @@ } void RTCDtlsTransport::ChangeState(webrtc::DtlsTransportInformation info) { - DCHECK(current_state_.state() != webrtc::DtlsTransportState::kClosed); + DCHECK(info.state() == webrtc::DtlsTransportState::kClosed || + current_state_.state() != webrtc::DtlsTransportState::kClosed); current_state_ = info; }
diff --git a/third_party/blink/renderer/modules/plugins/navigator_plugins.idl b/third_party/blink/renderer/modules/plugins/navigator_plugins.idl index 8f7653c1..8c83f5e 100644 --- a/third_party/blink/renderer/modules/plugins/navigator_plugins.idl +++ b/third_party/blink/renderer/modules/plugins/navigator_plugins.idl
@@ -8,5 +8,5 @@ ] partial interface Navigator { [HighEntropy, MeasureAs=NavigatorPlugins] readonly attribute PluginArray plugins; [HighEntropy, MeasureAs=NavigatorMimeTypes] readonly attribute MimeTypeArray mimeTypes; - boolean javaEnabled(); + [HighEntropy=Direct, Measure] boolean javaEnabled(); };
diff --git a/third_party/blink/renderer/modules/speech/speech_synthesis_voice.idl b/third_party/blink/renderer/modules/speech/speech_synthesis_voice.idl index 6f4bde6..6d52323 100644 --- a/third_party/blink/renderer/modules/speech/speech_synthesis_voice.idl +++ b/third_party/blink/renderer/modules/speech/speech_synthesis_voice.idl
@@ -28,9 +28,9 @@ [ LegacyNoInterfaceObject ] interface SpeechSynthesisVoice { - readonly attribute DOMString voiceURI; - readonly attribute DOMString name; - readonly attribute DOMString lang; - readonly attribute boolean localService; - [ImplementedAs=isDefault] readonly attribute boolean default; + [HighEntropy=Direct, Measure] readonly attribute DOMString voiceURI; + [HighEntropy=Direct, Measure] readonly attribute DOMString name; + [HighEntropy=Direct, Measure] readonly attribute DOMString lang; + [HighEntropy=Direct, Measure] readonly attribute boolean localService; + [HighEntropy=Direct, Measure, ImplementedAs=isDefault] readonly attribute boolean default; };
diff --git a/third_party/blink/renderer/modules/storage/storage_controller.cc b/third_party/blink/renderer/modules/storage/storage_controller.cc index 6c1590b..5c5c9209 100644 --- a/third_party/blink/renderer/modules/storage/storage_controller.cc +++ b/third_party/blink/renderer/modules/storage/storage_controller.cc
@@ -56,8 +56,14 @@ bool StorageController::CanAccessStorageArea(LocalFrame* frame, StorageArea::StorageType type) { if (auto* settings_client = frame->GetContentSettingsClient()) { - return settings_client->AllowStorage( - type == StorageArea::StorageType::kLocalStorage); + switch (type) { + case StorageArea::StorageType::kLocalStorage: + return settings_client->AllowStorageAccessSync( + WebContentSettingsClient::StorageType::kLocalStorage); + case StorageArea::StorageType::kSessionStorage: + return settings_client->AllowStorageAccessSync( + WebContentSettingsClient::StorageType::kSessionStorage); + } } return true; }
diff --git a/third_party/blink/renderer/modules/xr/xr_system.cc b/third_party/blink/renderer/modules/xr/xr_system.cc index 7956f21..753b53a 100644 --- a/third_party/blink/renderer/modules/xr/xr_system.cc +++ b/third_party/blink/renderer/modules/xr/xr_system.cc
@@ -138,7 +138,7 @@ feature_string == "plane-detection") { return device::mojom::XRSessionFeature::PLANE_DETECTION; } else if (RuntimeEnabledFeatures::WebXRDepthEnabled(context) && - feature_string == "depth") { + feature_string == "depth-sensing") { return device::mojom::XRSessionFeature::DEPTH; }
diff --git a/third_party/blink/renderer/platform/instrumentation/partition_alloc_memory_dump_provider.cc b/third_party/blink/renderer/platform/instrumentation/partition_alloc_memory_dump_provider.cc index b700370b..a0b2a4e 100644 --- a/third_party/blink/renderer/platform/instrumentation/partition_alloc_memory_dump_provider.cc +++ b/third_party/blink/renderer/platform/instrumentation/partition_alloc_memory_dump_provider.cc
@@ -23,6 +23,33 @@ kPartitionsDumpName, partition_name); } +void ThreadCacheDump(base::trace_event::MemoryAllocatorDump* thread_cache_dump, + const base::internal::ThreadCacheStats& stats) { + thread_cache_dump->AddScalar("alloc_count", "scalar", stats.alloc_count); + thread_cache_dump->AddScalar("alloc_hits", "scalar", stats.alloc_hits); + thread_cache_dump->AddScalar("alloc_misses", "scalar", stats.alloc_misses); + + thread_cache_dump->AddScalar("alloc_miss_empty", "scalar", + stats.alloc_miss_empty); + thread_cache_dump->AddScalar("alloc_miss_too_large", "scalar", + stats.alloc_miss_too_large); + + thread_cache_dump->AddScalar("cache_fill_count", "scalar", + stats.cache_fill_count); + thread_cache_dump->AddScalar("cache_fill_hits", "scalar", + stats.cache_fill_hits); + thread_cache_dump->AddScalar("cache_fill_misses", "scalar", + stats.cache_fill_misses); + thread_cache_dump->AddScalar("cache_fill_bucket_full", "scalar", + stats.cache_fill_bucket_full); + thread_cache_dump->AddScalar("cache_fill_too_large", "scalar", + stats.cache_fill_too_large); + + thread_cache_dump->AddScalar("size", "bytes", stats.bucket_total_memory); + thread_cache_dump->AddScalar("metadata_overhead", "bytes", + stats.metadata_overhead); +} + // This class is used to invert the dependency of PartitionAlloc on the // PartitionAllocMemoryDumpProvider. This implements an interface that will // be called with memory statistics for each bucket in the allocator. @@ -71,6 +98,17 @@ memory_stats->total_decommittable_bytes); allocator_dump->AddScalar("discardable_size", "bytes", memory_stats->total_discardable_bytes); + if (memory_stats->has_thread_cache) { + const auto& thread_cache_stats = memory_stats->current_thread_cache_stats; + auto* thread_cache_dump = memory_dump_->CreateAllocatorDump( + dump_name + "/thread_cache/main_thread"); + ThreadCacheDump(thread_cache_dump, thread_cache_stats); + + const auto& all_thread_caches_stats = memory_stats->all_thread_caches_stats; + auto* all_thread_caches_dump = memory_dump_->CreateAllocatorDump( + dump_name + "/thread_cache/all_threads"); + ThreadCacheDump(all_thread_caches_dump, all_thread_caches_stats); + } } void PartitionStatsDumperImpl::PartitionsDumpBucketStats( @@ -79,10 +117,10 @@ DCHECK(memory_stats->is_valid); std::string dump_name = GetPartitionDumpName(partition_name); if (memory_stats->is_direct_map) { - dump_name.append(base::StringPrintf("/directMap_%" PRIu64, ++uid_)); + dump_name.append(base::StringPrintf("/buckets/directMap_%" PRIu64, ++uid_)); } else { - dump_name.append( - base::StringPrintf("/bucket_%" PRIu32, memory_stats->bucket_slot_size)); + dump_name.append(base::StringPrintf("/buckets/bucket_%" PRIu32, + memory_stats->bucket_slot_size)); } base::trace_event::MemoryAllocatorDump* allocator_dump =
diff --git a/third_party/blink/renderer/platform/p2p/ipc_network_manager.cc b/third_party/blink/renderer/platform/p2p/ipc_network_manager.cc index 8a125da..bd0c9bc 100644 --- a/third_party/blink/renderer/platform/p2p/ipc_network_manager.cc +++ b/third_party/blink/renderer/platform/p2p/ipc_network_manager.cc
@@ -37,6 +37,7 @@ case net::NetworkChangeNotifier::CONNECTION_2G: case net::NetworkChangeNotifier::CONNECTION_3G: case net::NetworkChangeNotifier::CONNECTION_4G: + case net::NetworkChangeNotifier::CONNECTION_5G: return rtc::ADAPTER_TYPE_CELLULAR; default: return rtc::ADAPTER_TYPE_UNKNOWN;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc index f924537d..de85190 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -375,7 +375,8 @@ case TaskType::kInternalContentCapture: return ThrottleableTaskQueueTraits().SetPrioritisationType( QueueTraits::PrioritisationType::kBestEffort); - case TaskType::kJavascriptTimerDelayed: + case TaskType::kJavascriptTimerDelayedLowNesting: + case TaskType::kJavascriptTimerDelayedHighNesting: return ThrottleableTaskQueueTraits().SetPrioritisationType( QueueTraits::PrioritisationType::kJavaScriptTimer); case TaskType::kJavascriptTimerImmediate: {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc index 60b78aa3..1730345b9 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" +#include <map> #include <memory> #include <string> #include <vector> @@ -91,8 +92,9 @@ // FrameSchedulerImpl::CreateQueueTraitsForTaskType(). constexpr TaskType kAllFrameTaskTypes[] = { TaskType::kInternalContentCapture, - TaskType::kJavascriptTimerDelayed, TaskType::kJavascriptTimerImmediate, + TaskType::kJavascriptTimerDelayedLowNesting, + TaskType::kJavascriptTimerDelayedHighNesting, TaskType::kInternalLoading, TaskType::kNetworking, TaskType::kNetworkingWithURLLoaderAnnotation, @@ -140,7 +142,7 @@ TaskType::kInternalHighPriorityLocalFrame}; static_assert( - static_cast<int>(TaskType::kCount) == 73, + static_cast<int>(TaskType::kCount) == 74, "When adding a TaskType, make sure that kAllFrameTaskTypes is updated."); void AppendToVectorTestTask(Vector<String>* vector, String value) { @@ -430,7 +432,8 @@ }; class FrameSchedulerImplStopInBackgroundDisabledTest - : public FrameSchedulerImplTest { + : public FrameSchedulerImplTest, + public ::testing::WithParamInterface<TaskType> { public: FrameSchedulerImplStopInBackgroundDisabledTest() : FrameSchedulerImplTest({}, {blink::features::kStopInBackground}) {} @@ -498,12 +501,12 @@ task_environment->FastForwardBy(length); } -class FrameSchedulerImplTestWithIntensiveWakeUpThrottling +class FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase : public FrameSchedulerImplTest { public: using Super = FrameSchedulerImplTest; - FrameSchedulerImplTestWithIntensiveWakeUpThrottling() + FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase() : FrameSchedulerImplTest({features::kIntensiveWakeUpThrottling}, {features::kStopInBackground}) {} @@ -524,8 +527,12 @@ GetIntensiveWakeUpThrottlingDurationBetweenWakeUps(); }; +class FrameSchedulerImplTestWithIntensiveWakeUpThrottling + : public FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase, + public ::testing::WithParamInterface<TaskType> {}; + class FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride - : public FrameSchedulerImplTestWithIntensiveWakeUpThrottling { + : public FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase { public: // This should only be called once per test, and prior to the // PageSchedulerImpl logic actually parsing the policy switch. @@ -733,7 +740,7 @@ // Verify that tasks in a throttled task queue cause 1 wake up per second, when // intensive wake up throttling is disabled. Disable the kStopInBackground // feature because it hides the effect of intensive wake up throttling. -TEST_F(FrameSchedulerImplStopInBackgroundDisabledTest, ThrottledTaskExecution) { +TEST_P(FrameSchedulerImplStopInBackgroundDisabledTest, ThrottledTaskExecution) { constexpr auto kTaskPeriod = base::TimeDelta::FromSeconds(1); // This test posts enough tasks to run past the default intensive wake up @@ -745,7 +752,7 @@ .IntDiv(kTaskPeriod); // This TaskRunner is throttled. const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed); + frame_scheduler_->GetTaskRunner(GetParam()); // Hide the page. This enables wake up throttling. EXPECT_TRUE(page_scheduler_->IsPageVisible()); @@ -769,18 +776,18 @@ // Verify that tasks in a throttled task queue are not throttled when there is // an active opt-out. -TEST_F(FrameSchedulerImplStopInBackgroundDisabledTest, NoThrottlingWithOptOut) { +TEST_P(FrameSchedulerImplStopInBackgroundDisabledTest, NoThrottlingWithOptOut) { constexpr int kNumTasks = 3; // |task_runner| is throttled. const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed); + frame_scheduler_->GetTaskRunner(GetParam()); // |other_task_runner| is throttled. It belongs to a different frame on the // same page. const auto other_frame_scheduler = CreateFrameScheduler( page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr, FrameScheduler::FrameType::kSubframe); const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner = - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed); + frame_scheduler_->GetTaskRunner(GetParam()); // Fast-forward the time to a multiple of |kDefaultThrottledWakeUpInterval|. // Otherwise, the time at which tasks run will vary. @@ -864,6 +871,16 @@ } } +INSTANTIATE_TEST_SUITE_P( + AllTimerTaskTypes, + FrameSchedulerImplStopInBackgroundDisabledTest, + testing::Values(TaskType::kJavascriptTimerImmediate, + TaskType::kJavascriptTimerDelayedLowNesting, + TaskType::kJavascriptTimerDelayedHighNesting), + [](const testing::TestParamInfo<TaskType>& info) { + return TaskTypeNames::TaskTypeToString(info.param); + }); + TEST_F(FrameSchedulerImplTest, FreezeForegroundOnlyTasks) { int counter = 0; ForegroundOnlyTaskQueue()->task_runner()->PostTask( @@ -2327,7 +2344,9 @@ // Make sure the queue lookup and task type to queue traits map works as // expected. This test will fail if these task types are moved to different // default queues. - EXPECT_EQ(GetTaskQueue(TaskType::kJavascriptTimerDelayed), + EXPECT_EQ(GetTaskQueue(TaskType::kJavascriptTimerDelayedLowNesting), + JavaScriptTimerTaskQueue()); + EXPECT_EQ(GetTaskQueue(TaskType::kJavascriptTimerDelayedHighNesting), JavaScriptTimerTaskQueue()); EXPECT_EQ(GetTaskQueue(TaskType::kJavascriptTimerImmediate), JavaScriptTimerTaskQueue()); @@ -2350,10 +2369,9 @@ ForegroundOnlyTaskQueue()); } -// Verify that kJavascriptTimerDelayed is the only non-internal TaskType that -// can be throttled. This ensures that the Javascript timer throttling -// experiment only affects wake ups from Javascript timers -// https://crbug.com/1075553 +// Verify that kJavascriptTimer* are the only non-internal TaskType that can be +// throttled. This ensures that the Javascript timer throttling experiment only +// affects wake ups from Javascript timers https://crbug.com/1075553 TEST_F(FrameSchedulerImplTest, ThrottledTaskTypes) { page_scheduler_->SetPageVisible(false); @@ -2363,8 +2381,9 @@ << TaskTypeNames::TaskTypeToString(task_type)); switch (task_type) { case TaskType::kInternalContentCapture: - case TaskType::kJavascriptTimerDelayed: case TaskType::kJavascriptTimerImmediate: + case TaskType::kJavascriptTimerDelayedLowNesting: + case TaskType::kJavascriptTimerDelayedHighNesting: case TaskType::kInternalTranslation: EXPECT_TRUE(IsTaskTypeThrottled(task_type)); break; @@ -2433,7 +2452,7 @@ } TEST_F(FrameSchedulerImplTest, ComputePriorityForDetachedFrame) { - auto task_queue = GetTaskQueue(TaskType::kJavascriptTimerDelayed); + auto task_queue = GetTaskQueue(TaskType::kJavascriptTimerDelayedLowNesting); // Just check that it does not crash. page_scheduler_.reset(); frame_scheduler_->ComputePriority(task_queue.get()); @@ -2573,7 +2592,7 @@ TEST_F(FrameSchedulerImplTest, FeatureUpload) { ResetFrameScheduler(FrameScheduler::FrameType::kMainFrame); - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed) + frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerImmediate) ->PostTask( FROM_HERE, base::BindOnce( @@ -2612,7 +2631,7 @@ FeatureHandle feature_handle; - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed) + frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerImmediate) ->PostTask( FROM_HERE, base::BindOnce( @@ -2632,7 +2651,7 @@ }, frame_scheduler_.get(), frame_scheduler_delegate_.get(), &feature_handle)); - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed) + frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerImmediate) ->PostTask(FROM_HERE, base::BindOnce( [](FrameSchedulerImpl* frame_scheduler, @@ -2742,9 +2761,14 @@ testing::ElementsAre("V1", "V2", "B1", "B2", "U1", "U2")); } -// Verify that tasks posted with TaskType::kJavascriptTimerDelayed run at the +// Verify that tasks posted with TaskType::kJavascriptTimerDelayed* run at the // expected time when throttled. TEST_F(FrameSchedulerImplTest, ThrottledJSTimerTasksRunTime) { + constexpr TaskType kJavaScriptTimerTaskTypes[] = { + TaskType::kJavascriptTimerImmediate, + TaskType::kJavascriptTimerDelayedLowNesting, + TaskType::kJavascriptTimerDelayedHighNesting}; + // Snap the time to a multiple of 1 second. Otherwise, the exact run time // of throttled tasks after hiding the page will vary. FastForwardToAlignedTime(base::TimeDelta::FromSeconds(1)); @@ -2753,27 +2777,34 @@ // Hide the page to start throttling JS Timers. page_scheduler_->SetPageVisible(false); - const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed); - std::vector<base::TimeTicks> run_times; + std::map<TaskType, std::vector<base::TimeTicks>> run_times; - // Post tasks. - task_runner->PostTask(FROM_HERE, base::BindOnce(&RecordRunTime, &run_times)); - task_runner->PostDelayedTask(FROM_HERE, - base::BindOnce(&RecordRunTime, &run_times), - base::TimeDelta::FromMilliseconds(1000)); - task_runner->PostDelayedTask(FROM_HERE, - base::BindOnce(&RecordRunTime, &run_times), - base::TimeDelta::FromMilliseconds(1002)); - task_runner->PostDelayedTask(FROM_HERE, - base::BindOnce(&RecordRunTime, &run_times), - base::TimeDelta::FromMilliseconds(1004)); - task_runner->PostDelayedTask(FROM_HERE, - base::BindOnce(&RecordRunTime, &run_times), - base::TimeDelta::FromMilliseconds(2500)); - task_runner->PostDelayedTask(FROM_HERE, - base::BindOnce(&RecordRunTime, &run_times), - base::TimeDelta::FromMilliseconds(6000)); + // Post tasks with each Javascript Timer Task Type. + for (TaskType task_type : kJavaScriptTimerTaskTypes) { + const scoped_refptr<base::SingleThreadTaskRunner> task_runner = + frame_scheduler_->GetTaskRunner(task_type); + + // Note: Taking the address of an element in |run_times| is safe because + // inserting elements in a map does not invalidate references. + + task_runner->PostTask( + FROM_HERE, base::BindOnce(&RecordRunTime, &run_times[task_type])); + task_runner->PostDelayedTask( + FROM_HERE, base::BindOnce(&RecordRunTime, &run_times[task_type]), + base::TimeDelta::FromMilliseconds(1000)); + task_runner->PostDelayedTask( + FROM_HERE, base::BindOnce(&RecordRunTime, &run_times[task_type]), + base::TimeDelta::FromMilliseconds(1002)); + task_runner->PostDelayedTask( + FROM_HERE, base::BindOnce(&RecordRunTime, &run_times[task_type]), + base::TimeDelta::FromMilliseconds(1004)); + task_runner->PostDelayedTask( + FROM_HERE, base::BindOnce(&RecordRunTime, &run_times[task_type]), + base::TimeDelta::FromMilliseconds(2500)); + task_runner->PostDelayedTask( + FROM_HERE, base::BindOnce(&RecordRunTime, &run_times[task_type]), + base::TimeDelta::FromMilliseconds(6000)); + } // Make posted tasks run. task_environment_.FastForwardBy(base::TimeDelta::FromHours(1)); @@ -2781,13 +2812,16 @@ // The effective delay of a throttled task is >= the requested delay, and is // within [N * 1000, N * 1000 + 3] ms, where N is an integer. This is because // the wake up rate is 1 per second, and the duration of each wake up is 3 ms. - EXPECT_THAT(run_times, testing::ElementsAre( - start + base::TimeDelta::FromMilliseconds(0), + for (TaskType task_type : kJavaScriptTimerTaskTypes) { + EXPECT_THAT( + run_times[task_type], + testing::ElementsAre(start + base::TimeDelta::FromMilliseconds(0), start + base::TimeDelta::FromMilliseconds(1000), start + base::TimeDelta::FromMilliseconds(1002), start + base::TimeDelta::FromMilliseconds(2000), start + base::TimeDelta::FromMilliseconds(3000), start + base::TimeDelta::FromMilliseconds(6000))); + } } namespace { @@ -2846,13 +2880,13 @@ // Verify that tasks run at the expected time in frame that is same-origin with // the main frame with intensive wake up throttling. -TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, +TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, TaskExecutionSameOriginFrame) { ASSERT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame()); // Throttled TaskRunner to which tasks are posted in this test. const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed); + frame_scheduler_->GetTaskRunner(GetParam()); // Snap the time to a multiple of // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, the time at which @@ -3002,13 +3036,13 @@ // Verify that tasks run at the expected time in a frame that is cross-origin // with the main frame with intensive wake up throttling. -TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, +TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, TaskExecutionCrossOriginFrame) { frame_scheduler_->SetCrossOriginToMainFrame(true); // Throttled TaskRunner to which tasks are posted in this test. const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed); + frame_scheduler_->GetTaskRunner(GetParam()); // Snap the time to a multiple of // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, the time at which @@ -3154,11 +3188,11 @@ // Verify that tasks from different frames that are same-origin with the main // frame run at the expected time. -TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, +TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, ManySameFrameOriginFrames) { ASSERT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame()); const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed); + frame_scheduler_->GetTaskRunner(GetParam()); // Create a FrameScheduler that is same-origin with the main frame, and an // associated throttled TaskRunner. @@ -3168,7 +3202,7 @@ FrameScheduler::FrameType::kSubframe); ASSERT_FALSE(other_frame_scheduler->IsCrossOriginToMainFrame()); const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner = - other_frame_scheduler->GetTaskRunner(TaskType::kJavascriptTimerDelayed); + other_frame_scheduler->GetTaskRunner(GetParam()); // Snap the time to a multiple of // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, the time at which @@ -3213,18 +3247,18 @@ // Verify that intensive throttling is disabled when there is an opt-out for all // throttling. -TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, ThrottlingOptOut) { +TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, ThrottlingOptOut) { constexpr int kNumTasks = 3; // |task_runner| is throttled. const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed); + frame_scheduler_->GetTaskRunner(GetParam()); // |other_task_runner| is throttled. It belongs to a different frame on the // same page. const auto other_frame_scheduler = CreateFrameScheduler( page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr, FrameScheduler::FrameType::kSubframe); const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner = - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed); + frame_scheduler_->GetTaskRunner(GetParam()); // Fast-forward the time to a multiple of // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, @@ -3336,19 +3370,19 @@ // Verify that intensive throttling is disabled when there is an opt-out for // aggressive throttling. -TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, +TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, AggressiveThrottlingOptOut) { constexpr int kNumTasks = 3; // |task_runner| is throttled. const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed); + frame_scheduler_->GetTaskRunner(GetParam()); // |other_task_runner| is throttled. It belongs to a different frame on the // same page. const auto other_frame_scheduler = CreateFrameScheduler( page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr, FrameScheduler::FrameType::kSubframe); const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner = - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed); + frame_scheduler_->GetTaskRunner(GetParam()); // Fast-forward the time to a multiple of // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, @@ -3466,11 +3500,11 @@ // Verify that tasks run at the same time when a frame switches between being // same-origin and cross-origin with the main frame. -TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, +TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, FrameChangesOriginType) { EXPECT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame()); const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerDelayed); + frame_scheduler_->GetTaskRunner(GetParam()); // Create a new FrameScheduler that remains cross-origin with the main frame // throughout the test. @@ -3480,8 +3514,7 @@ FrameScheduler::FrameType::kSubframe); cross_origin_frame_scheduler->SetCrossOriginToMainFrame(true); const scoped_refptr<base::SingleThreadTaskRunner> cross_origin_task_runner = - cross_origin_frame_scheduler->GetTaskRunner( - TaskType::kJavascriptTimerDelayed); + cross_origin_frame_scheduler->GetTaskRunner(GetParam()); // Snap the time to a multiple of // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, the time at which @@ -3554,6 +3587,16 @@ } } +INSTANTIATE_TEST_SUITE_P( + AllTimerTaskTypes, + FrameSchedulerImplTestWithIntensiveWakeUpThrottling, + testing::Values(TaskType::kJavascriptTimerImmediate, + TaskType::kJavascriptTimerDelayedLowNesting, + TaskType::kJavascriptTimerDelayedHighNesting), + [](const testing::TestParamInfo<TaskType>& info) { + return TaskTypeNames::TaskTypeToString(info.param); + }); + TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride, PolicyForceEnable) { SetPolicyOverride(/* enabled = */ true);
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc index 2f59dcd..06f70a3 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
@@ -3917,7 +3917,7 @@ FrameScheduler::FrameType::kSubframe); scoped_refptr<TaskQueue> throttleable_tq = QueueForTaskType( - frame_scheduler.get(), TaskType::kJavascriptTimerDelayed); + frame_scheduler.get(), TaskType::kJavascriptTimerDelayedLowNesting); ForceUpdatePolicyAndGetCurrentUseCase(); EXPECT_FALSE(throttleable_tq->IsQueueEnabled()); @@ -3940,7 +3940,7 @@ FrameScheduler::FrameType::kSubframe); scoped_refptr<TaskQueue> timer_tq = QueueForTaskType( - frame_scheduler.get(), TaskType::kJavascriptTimerDelayed); + frame_scheduler.get(), TaskType::kJavascriptTimerDelayedLowNesting); FakeInputEvent mouse_move_event{WebInputEvent::Type::kMouseMove, blink::WebInputEvent::kLeftButtonDown};
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc b/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc index 869d5f5..31b77ef3 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
@@ -35,10 +35,12 @@ return "CanvasBlobSerialization"; case TaskType::kMicrotask: return "Microtask"; - case TaskType::kJavascriptTimerDelayed: - return "JavascriptTimerDelayed"; case TaskType::kJavascriptTimerImmediate: return "JavascriptTimerImmediate"; + case TaskType::kJavascriptTimerDelayedLowNesting: + return "JavascriptTimerDelayedLowNesting"; + case TaskType::kJavascriptTimerDelayedHighNesting: + return "JavascriptTimerDelayedHighNesting"; case TaskType::kRemoteEvent: return "RemoteEvent"; case TaskType::kWebSocket:
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc index b1bcad38..54ed831 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
@@ -133,8 +133,9 @@ scoped_refptr<base::SingleThreadTaskRunner> WorkerScheduler::GetTaskRunner( TaskType type) const { switch (type) { - case TaskType::kJavascriptTimerDelayed: case TaskType::kJavascriptTimerImmediate: + case TaskType::kJavascriptTimerDelayedLowNesting: + case TaskType::kJavascriptTimerDelayedHighNesting: case TaskType::kPostedMessage: case TaskType::kWorkerAnimation: return throttleable_task_queue_->CreateTaskRunner(type);
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_unittest.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_unittest.cc index a6552d0..6e59cb0 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_unittest.cc
@@ -286,7 +286,7 @@ // Tests interlacing pausable, throttable and unpausable tasks and // ensures that the pausable & throttable tasks don't run when paused. // Throttable - PostTestTask(&run_order, "T1", TaskType::kJavascriptTimerDelayed); + PostTestTask(&run_order, "T1", TaskType::kJavascriptTimerDelayedLowNesting); // Pausable PostTestTask(&run_order, "T2", TaskType::kNetworking); // Unpausable @@ -304,7 +304,7 @@ auto pause_handle = worker_scheduler_->Pause(); { auto pause_handle2 = worker_scheduler_->Pause(); - PostTestTask(&run_order, "T1", TaskType::kJavascriptTimerDelayed); + PostTestTask(&run_order, "T1", TaskType::kJavascriptTimerDelayedLowNesting); PostTestTask(&run_order, "T2", TaskType::kNetworking); } RunUntilIdle();
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc index 4ddb680..3b941bd 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc
@@ -539,7 +539,7 @@ scheduler_->SetUkmRecorderForTest(std::move(owned_ukm_recorder)); base::sequence_manager::FakeTask task( - static_cast<int>(TaskType::kJavascriptTimerDelayed)); + static_cast<int>(TaskType::kJavascriptTimerDelayedLowNesting)); base::sequence_manager::FakeTaskTiming task_timing( base::TimeTicks() + base::TimeDelta::FromMilliseconds(200), base::TimeTicks() + base::TimeDelta::FromMilliseconds(700), @@ -558,7 +558,7 @@ true); ukm::TestUkmRecorder::ExpectEntryMetric( entries[0], "TaskType", - static_cast<int>(TaskType::kJavascriptTimerDelayed)); + static_cast<int>(TaskType::kJavascriptTimerDelayedLowNesting)); ukm::TestUkmRecorder::ExpectEntryMetric( entries[0], "FrameStatus", static_cast<int>(FrameStatus::kCrossOriginBackground));
diff --git a/third_party/blink/renderer/platform/widget/frame_widget.h b/third_party/blink/renderer/platform/widget/frame_widget.h index 45573eee..36c3e8e 100644 --- a/third_party/blink/renderer/platform/widget/frame_widget.h +++ b/third_party/blink/renderer/platform/widget/frame_widget.h
@@ -121,7 +121,7 @@ // Return the composition character in window coordinates. virtual void GetCompositionCharacterBoundsInWindow( - Vector<gfx::Rect>* bounds) = 0; + Vector<gfx::Rect>* bounds_in_dips) = 0; virtual gfx::Range CompositionRange() = 0; // Returns ime_text_spans and corresponding window coordinates for the list @@ -170,7 +170,8 @@ virtual void FinishComposingText(bool keep_selection) = 0; virtual bool IsProvisional() = 0; - virtual uint64_t GetScrollableContainerIdAt(const gfx::PointF& point) = 0; + virtual uint64_t GetScrollableContainerIdAt( + const gfx::PointF& point_in_dips) = 0; virtual bool ShouldHandleImeEvents() { return false; }
diff --git a/third_party/blink/renderer/platform/widget/widget_base.cc b/third_party/blink/renderer/platform/widget/widget_base.cc index b1798aa..9cfa1f4 100644 --- a/third_party/blink/renderer/platform/widget/widget_base.cc +++ b/third_party/blink/renderer/platform/widget/widget_base.cc
@@ -1255,15 +1255,34 @@ gfx::PointF WidgetBase::DIPsToBlinkSpace(const gfx::PointF& point) { if (!use_zoom_for_dsf_) return point; - return gfx::ConvertPointToPixel( - client_->GetOriginalScreenInfo().device_scale_factor, point); + // TODO(danakj): Should this be GetScreenInfo() so it changes under emulation? + return gfx::ScalePoint(point, + client_->GetOriginalScreenInfo().device_scale_factor); +} + +gfx::Point WidgetBase::DIPsToBlinkSpace(const gfx::Point& point) { + if (!use_zoom_for_dsf_) + return point; + // TODO(danakj): Should this be GetScreenInfo() so it changes under emulation? + return gfx::ScaleToRoundedPoint( + point, client_->GetOriginalScreenInfo().device_scale_factor); } gfx::PointF WidgetBase::BlinkSpaceToDIPs(const gfx::PointF& point) { if (!use_zoom_for_dsf_) return point; - return gfx::ConvertPointToDIP( - client_->GetOriginalScreenInfo().device_scale_factor, point); + // TODO(danakj): Should this be GetScreenInfo() so it changes under emulation? + return gfx::ScalePoint( + point, 1.f / client_->GetOriginalScreenInfo().device_scale_factor); +} + +gfx::Point WidgetBase::BlinkSpaceToDIPs(const gfx::Point& point) { + if (!use_zoom_for_dsf_) + return point; + // TODO(danakj): Should this be GetScreenInfo() so it changes under emulation? + // TODO(dtapuska): Determine if this should be a floor vs rounded. + return gfx::ScaleToFlooredPoint( + point, client_->GetOriginalScreenInfo().device_scale_factor); } gfx::Size WidgetBase::DIPsToBlinkSpace(const gfx::Size& size) { @@ -1280,4 +1299,11 @@ return gfx::ScaleToCeiledSize(size, reverse); } +gfx::Rect WidgetBase::BlinkSpaceToDIPs(const gfx::Rect& rect) { + if (!use_zoom_for_dsf_) + return rect; + float reverse = 1 / client_->GetOriginalScreenInfo().device_scale_factor; + return gfx::ScaleToEnclosedRect(rect, reverse); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/widget/widget_base.h b/third_party/blink/renderer/platform/widget/widget_base.h index 64510c7..bf794c7 100644 --- a/third_party/blink/renderer/platform/widget/widget_base.h +++ b/third_party/blink/renderer/platform/widget/widget_base.h
@@ -270,18 +270,15 @@ // Converts from DIPs to Blink coordinate space (ie. Viewport/Physical // pixels). gfx::PointF DIPsToBlinkSpace(const gfx::PointF& point); - - // Converts from Blink coordinate space (ie. Viewport/Physical pixels) to - // DIPS. - gfx::PointF BlinkSpaceToDIPs(const gfx::PointF& point); - - // Converts from DIPs to Blink coordinate space (ie. Viewport/Physical - // pixels). + gfx::Point DIPsToBlinkSpace(const gfx::Point& point); gfx::Size DIPsToBlinkSpace(const gfx::Size& size); - // Converts from Blink coordinate space (ie. Viewport/Physical pixels) to + // Converts from Blink coordinate (ie. Viewport/Physical pixels) space to // DIPs. + gfx::PointF BlinkSpaceToDIPs(const gfx::PointF& point); + gfx::Point BlinkSpaceToDIPs(const gfx::Point& point); gfx::Size BlinkSpaceToDIPs(const gfx::Size& size); + gfx::Rect BlinkSpaceToDIPs(const gfx::Rect& rect); // Returns whether Zoom for DSF is enabled for the widget. bool UseZoomForDsf() { return use_zoom_for_dsf_; }
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index c72d2d8..4478183e 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -276,6 +276,9 @@ crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/abspos-013.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-013.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-014.tentative.html [ Failure ] +crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-024.tentative.html [ Failure ] +crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/replaced-element-016.tentative.html [ Failure ] +crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/replaced-element-021.tentative.html [ Failure ] crbug.com/936084 external/wpt/css/css-sizing/max-content-input-001.html [ Failure ] @@ -799,6 +802,8 @@ crbug.com/470421 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002b.html [ Failure ] crbug.com/470421 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-003a.html [ Failure ] crbug.com/470421 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-004a.html [ Failure ] +crbug.com/470421 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-021.tentative.html [ Failure ] +crbug.com/470421 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-022.tentative.html [ Failure ] # Untriaged flex failures crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001.xhtml [ Failure ] @@ -1176,7 +1181,6 @@ crbug.com/829028 virtual/layout_ng_block_frag/fragmentation/overflow-crossing-boundary.html [ Failure ] crbug.com/1079031 virtual/layout_ng_block_frag/fragmentation/relayout-abspos.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fragmentation/remove-unbreakable-block-in-line-float.html [ Failure ] -crbug.com/829028 virtual/layout_ng_block_frag/fragmentation/scrolling-contents-scroll.html [ Failure ] ### With LayoutNGFragmentTraversal (and LayoutNGFragmentItem) enabled: @@ -2674,9 +2678,6 @@ crbug.com/958381 [ Mac ] external/wpt/css/CSS2/tables/table-anonymous-objects-206.xht [ Failure ] # ====== New tests from wpt-importer added here ====== -crbug.com/626703 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-024.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-021.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-022.tentative.html [ Failure ] crbug.com/626703 [ Fuchsia ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-pause-immediately.https.html [ Failure ] crbug.com/626703 [ Mac11.0 ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-pause-immediately.https.html [ Failure ] crbug.com/626703 [ Mac ] external/wpt/web-locks/query-ordering.tentative.https.html [ Pass Failure ] @@ -2690,8 +2691,6 @@ crbug.com/626703 external/wpt/web-share/share-url-invalid.https.html [ Crash ] crbug.com/626703 external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/pageshow-event.window.html [ Timeout ] crbug.com/626703 [ Win7 ] external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Failure Timeout ] -crbug.com/626703 external/wpt/css/css-sizing/aspect-ratio/replaced-element-016.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-sizing/aspect-ratio/replaced-element-021.tentative.html [ Failure ] crbug.com/626703 external/wpt/content-security-policy/frame-src/frame-src-same-document.sub.html [ Timeout ] crbug.com/626703 external/wpt/input-events/input-events-get-target-ranges-backspace.tentative.html [ Timeout ] crbug.com/626703 external/wpt/input-events/input-events-get-target-ranges-forwarddelete.tentative.html [ Timeout ] @@ -2998,6 +2997,8 @@ # Tests pass under virtual/webrtc-wpt-plan-b virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-operations.https.html [ Pass ] +crbug.com/1131471 external/wpt/web-locks/clientids.tentative.https.html [ Failure ] + # See also crbug.com/920100 (sheriff 2019-01-09). crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout Failure ] crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout Failure ] @@ -5582,7 +5583,6 @@ # Tests using testRunner.useUnfortunateSynchronousResizeMode occasionally timeout, # but the test coverage is still good. crbug.com/919789 css3/viewport-percentage-lengths/viewport-percentage-lengths-resize.html [ Pass Timeout ] -crbug.com/919789 compositing/transitions/transform-on-large-layer.html [ Pass Timeout ] crbug.com/919789 compositing/transitions/transform-on-large-layer-expected.html [ Pass Timeout ] crbug.com/919789 fast/autoresize/turn-off-autoresize.html [ Pass Timeout ] crbug.com/919789 fast/autoresize/basic.html [ Pass Timeout ] @@ -6734,7 +6734,6 @@ # Sheriff 2020-09-17 crbug.com/1129347 [ Mac10.13 Debug ] http/tests/devtools/persistence/persistence-external-change-breakpoints.js [ Pass Failure ] ### virtual/scroll-unification/fast/scrolling/scrollbars/ -virtual/scroll-unification/fast/scrolling/scrollbars/mouse-autoscrolling-on-scrollbar.html [ Failure ] virtual/scroll-unification/fast/scrolling/scrollbars/mouse-scrolling-on-div-scrollbar.html [ Failure ] virtual/scroll-unification/fast/scrolling/scrollbars/scrollbar-occluded-by-div.html [ Failure ] virtual/scroll-unification/fast/scrolling/scrollbars/scrollbar-rtl-manipulation.html [ Failure ] @@ -6748,3 +6747,9 @@ # Sheriff 2020-09-22 crbug.com/1130533 [ Mac ] external/wpt/xhr/xhr-timeout-longtask.any.worker.html [ Pass Failure ] + +# Sheriff 2020-09-23 +crbug.com/1131551 compositing/transitions/transform-on-large-layer.html [ Pass Failure Timeout ] +crbug.com/1057060 virtual/compositor-threaded-percent-based-scrolling/fast/scrolling/scrollbars/mouse-autoscrolling-on-scrollbar.html [ Pass Failure Timeout ] +crbug.com/1057060 virtual/threaded-prefer-compositing/fast/scrolling/scrollbars/mouse-autoscrolling-on-scrollbar.html [ Pass Failure Timeout ] +crbug.com/1057060 virtual/scroll-unification/fast/scrolling/scrollbars/mouse-autoscrolling-on-scrollbar.html [ Pass Failure Timeout ]
diff --git a/third_party/blink/web_tests/accessibility/contenteditable-notifications.html b/third_party/blink/web_tests/accessibility/contenteditable-notifications.html index b6c0ee8..c88c99a 100644 --- a/third_party/blink/web_tests/accessibility/contenteditable-notifications.html +++ b/third_party/blink/web_tests/accessibility/contenteditable-notifications.html
@@ -19,82 +19,119 @@ const expectedSelectedTextChangedIntents = []; axTextBox.setNotificationListener(t.step_func((notification, intents) => { - if (notification == "ValueChanged") { + if (notification == 'ValueChanged') { assert_array_equals(intents, - expectedValueChangedIntents[valueChangedCount]); + expectedValueChangedIntents[valueChangedCount], + 'ValueChanged at ' + valueChangedCount); ++valueChangedCount; - } else if (notification == "SelectedTextChanged") { + } else if (notification == 'SelectedTextChanged') { assert_array_equals(intents, - expectedSelectedTextChangedIntents[selectedTextChangedCount]); + expectedSelectedTextChangedIntents[selectedTextChangedCount], + 'SelectedTextChanged at ' + selectedTextChangedCount); ++selectedTextChangedCount; } - if (valueChangedCount >= 4 && selectedTextChangedCount >= 9) { + if (valueChangedCount >= 6 && selectedTextChangedCount >= 11) { t.done(); } })); - // Initial setting of the selection. + // SelectedTextChanged at 0. expectedSelectedTextChangedIntents.push([ - 'AXEventIntent(setSelection,character,forward)' + 'AXEventIntent(setSelection,none,character,forward)' ]); textbox.focus(); + // SelectedTextChanged at 1. expectedSelectedTextChangedIntents.push([ - 'AXEventIntent(moveSelection,lineStart,forward)' + 'AXEventIntent(moveSelection,none,lineStart,forward)' ]); - eventSender.keyDown("ArrowDown", []); + eventSender.keyDown('ArrowDown', []); + // ValueChanged at 0. expectedValueChangedIntents.push([ - 'AXEventIntent(type,character,forward)' + 'AXEventIntent(insert,insertText,none,none)' ]); + // SelectedTextChanged at 2. expectedSelectedTextChangedIntents.push([ - 'AXEventIntent(setSelection,character,forward)', - 'AXEventIntent(type,character,forward)' + 'AXEventIntent(insert,insertText,none,none)', + 'AXEventIntent(setSelection,none,character,forward)' ]); - eventSender.keyDown("w", []); + eventSender.keyDown('w', []); + // SelectedTextChanged at 3. expectedSelectedTextChangedIntents.push([ - 'AXEventIntent(moveSelection,lineStart,forward)' + 'AXEventIntent(moveSelection,none,lineStart,forward)' ]); - eventSender.keyDown("ArrowDown", []); + eventSender.keyDown('ArrowDown', []); + // ValueChanged at 1. expectedValueChangedIntents.push([ - 'AXEventIntent(type,character,forward)' + 'AXEventIntent(insert,insertText,none,none)' ]); + // SelectedTextChanged at 4. expectedSelectedTextChangedIntents.push([ - 'AXEventIntent(type,character,forward)', - 'AXEventIntent(setSelection,character,forward)' + 'AXEventIntent(setSelection,none,character,forward)', + 'AXEventIntent(insert,insertText,none,none)' ]); - eventSender.keyDown("x", []); + eventSender.keyDown('x', []); + // SelectedTextChanged at 5. expectedSelectedTextChangedIntents.push([ - 'AXEventIntent(moveSelection,character,backward)' + 'AXEventIntent(moveSelection,none,character,backward)' ]); - eventSender.keyDown("ArrowLeft", []); + eventSender.keyDown('ArrowLeft', []); + // ValueChanged at 2. expectedValueChangedIntents.push([ - 'AXEventIntent(type,character,forward)' + 'AXEventIntent(delete,deleteContentForward,none,none)' ]); - expectedSelectedTextChangedIntents.push([ - 'AXEventIntent(setSelection,character,forward)', - 'AXEventIntent(type,character,forward)' - ]); - eventSender.keyDown("y", []); + eventSender.keyDown('Delete', []); + // SelectedTextChanged at 6. expectedSelectedTextChangedIntents.push([ - 'AXEventIntent(moveSelection,character,backward)' + 'AXEventIntent(moveSelection,none,character,backward)' ]); - eventSender.keyDown("ArrowLeft", []); + eventSender.keyDown('ArrowLeft', []); + // ValueChanged at 3. expectedValueChangedIntents.push([ - 'AXEventIntent(type,character,forward)' + 'AXEventIntent(insert,insertText,none,none)' ]); + // SelectedTextChanged at 7. expectedSelectedTextChangedIntents.push([ - 'AXEventIntent(setSelection,character,forward)', - 'AXEventIntent(type,character,forward)' + 'AXEventIntent(setSelection,none,character,forward)', + 'AXEventIntent(insert,insertText,none,none)' ]); - eventSender.keyDown("z", []); -}, 'This test ensures that moving the cursor in a contentEditable sends a selected text change notification, and typing in a contentEditable sends both a value changed and selected text changed notification.'); + eventSender.keyDown('y', []); + + // SelectedTextChanged at 8. + expectedSelectedTextChangedIntents.push([ + 'AXEventIntent(moveSelection,none,lineStart,backward)' + ]); + eventSender.keyDown('ArrowUp', []); + + // ValueChanged at 4. + expectedValueChangedIntents.push([ + 'AXEventIntent(insert,insertParagraph,none,none)' + ]); + // SelectedTextChanged at 9. + expectedSelectedTextChangedIntents.push([ + 'AXEventIntent(insert,insertParagraph,none,none)', + 'AXEventIntent(setSelection,none,character,forward)' + ]); + eventSender.keyDown('Enter', []); + + // ValueChanged at 5. + expectedValueChangedIntents.push([ + 'AXEventIntent(delete,deleteContentBackward,none,none)', + ]); + // SelectedTextChanged at 10. + expectedSelectedTextChangedIntents.push([ + 'AXEventIntent(setSelection,none,character,forward)', + 'AXEventIntent(delete,deleteContentBackward,none,none)', + ]); + eventSender.keyDown('Backspace', []); +}, 'Ensures that moving the cursor in a contentEditable sends a selected text change notification, and typing in a contentEditable sends both a value changed and selected text changed notification.'); </script>
diff --git a/third_party/blink/web_tests/accessibility/contenteditable-selection-with-ignored-nodes.html b/third_party/blink/web_tests/accessibility/contenteditable-selection-with-ignored-nodes.html index f2d3b1c8..8d1b3c1 100644 --- a/third_party/blink/web_tests/accessibility/contenteditable-selection-with-ignored-nodes.html +++ b/third_party/blink/web_tests/accessibility/contenteditable-selection-with-ignored-nodes.html
@@ -81,7 +81,7 @@ focusObject: axTextBox, focusOffset: 0, selectedText: ''}); - expectedIntents.push('AXEventIntent(setSelection,character,forward)'); + expectedIntents.push('AXEventIntent(setSelection,none,character,forward)'); const textBox = document.getElementById('textbox'); textBox.focus(); @@ -94,7 +94,7 @@ focusObject: axLine2, focusOffset: 0, selectedText: '\xA0\n'}); // '\xA0' == - expectedIntents.push('AXEventIntent(extendSelection,lineStart,forward)'); + expectedIntents.push('AXEventIntent(extendSelection,none,lineStart,forward)'); eventSender.keyDown('ArrowDown', ['shiftKey']); }); @@ -106,7 +106,7 @@ focusObject: axLine3, focusOffset: 0, selectedText: '\xA0\nApple\n\n'}); - expectedIntents.push('AXEventIntent(extendSelection,lineStart,forward)'); + expectedIntents.push('AXEventIntent(extendSelection,none,lineStart,forward)'); eventSender.keyDown('ArrowDown', ['shiftKey']); }); @@ -118,7 +118,7 @@ focusObject: axLine3Text, focusOffset: 6, selectedText: '\xA0\nApple\n\nBanana'}); - expectedIntents.push('AXEventIntent(extendSelection,lineStart,forward)'); + expectedIntents.push('AXEventIntent(extendSelection,none,lineStart,forward)'); eventSender.keyDown('ArrowDown', ['shiftKey']); });
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-aria-textbox.html b/third_party/blink/web_tests/accessibility/selection-change-notification-aria-textbox.html index 10a1f49..04ae4f2 100644 --- a/third_party/blink/web_tests/accessibility/selection-change-notification-aria-textbox.html +++ b/third_party/blink/web_tests/accessibility/selection-change-notification-aria-textbox.html
@@ -1,6 +1,7 @@ <!DOCTYPE html> <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script> +<script src="../resources/run-after-layout-and-paint.js"></script> <div id="ariaTextbox" role="textbox" tabIndex="0"> <p>Before</p> @@ -11,23 +12,16 @@ <script> 'use strict'; -async_test((t) => { - // This forces building the accessibility tree, because selection change - // events only fire on elements that already exist. - accessibilityController.accessibleElementById('dummy'); - - const element = document.getElementById('ariaTextbox'); - element.focus(); - +async_test_after_layout_and_paint((t) => { const axElement = accessibilityController.accessibleElementById('ariaTextbox'); axElement.setNotificationListener(t.step_func((notification, intents) => { - // Focus notification will come asynchronously after layout + // Focus notification will come asynchronously. if (notification == 'Focus') return; if (notification == 'SelectedTextChanged') { assert_array_equals(intents, - ['AXEventIntent(setSelection,character,forward)']); + ['AXEventIntent(setSelection,none,character,forward)']); axElement.unsetNotificationListener(); t.done(); return; @@ -36,6 +30,8 @@ assert_unreached('Unexpected notification: ' + notification); })); + const element = document.getElementById('ariaTextbox'); + element.focus(); const p = document.getElementById('p'); const range = document.createRange(); range.setStart(p.firstChild, 0);
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-contenteditable.html b/third_party/blink/web_tests/accessibility/selection-change-notification-contenteditable.html index 28aae43e..46c883b 100644 --- a/third_party/blink/web_tests/accessibility/selection-change-notification-contenteditable.html +++ b/third_party/blink/web_tests/accessibility/selection-change-notification-contenteditable.html
@@ -14,18 +14,15 @@ // Wait until layout has settled to avoid notification spam. async_test_after_layout_and_paint((t) => { - const element = document.getElementById('contentEditable'); - element.focus(); - const axElement = accessibilityController.accessibleElementById('contentEditable'); axElement.setNotificationListener(t.step_func((notification, intents) => { - // Focus notification will come asynchronously after layout + // Focus notification will come asynchronously. if (notification == 'Focus') return; if (notification == 'SelectedTextChanged') { assert_array_equals(intents, - ['AXEventIntent(setSelection,character,forward)']); + ['AXEventIntent(setSelection,none,character,forward)']); axElement.unsetNotificationListener(); t.done(); return; @@ -34,6 +31,8 @@ assert_unreached('Unexpected notification: ' + notification); })); + const element = document.getElementById('contentEditable'); + element.focus(); const p = document.getElementById('p'); const range = document.createRange(); range.setStart(p.firstChild, 0);
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-input.html b/third_party/blink/web_tests/accessibility/selection-change-notification-input.html index 7a72ccd..6be0d9b2 100644 --- a/third_party/blink/web_tests/accessibility/selection-change-notification-input.html +++ b/third_party/blink/web_tests/accessibility/selection-change-notification-input.html
@@ -1,17 +1,14 @@ <!DOCTYPE html> <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script> +<script src="../resources/run-after-layout-and-paint.js"></script> <input autofocus id="input" value="input"> <script> 'use strict'; -async_test((t) => { - // This forces building the accessibility tree, because selection change - // events only fire on elements that already exist. - accessibilityController.accessibleElementById('dummy'); - +async_test_after_layout_and_paint((t) => { const inputElement = document.getElementById('input'); const axRootElement = accessibilityController.rootElement; const axInputElement = accessibilityController.accessibleElementById('input'); @@ -26,7 +23,7 @@ axRootElement.setNotificationListener(function(notification, intents) { if (notification == 'DocumentSelectionChanged') { assert_array_equals(intents, - ['AXEventIntent(setSelection,character,forward)']); + ['AXEventIntent(setSelection,none,character,forward)']); gotDocumentSelectionChanged = true; axRootElement.unsetNotificationListener(); succeedIfDone(); @@ -36,7 +33,7 @@ axInputElement.setNotificationListener(function(notification, intents) { if (notification == 'SelectedTextChanged') { assert_array_equals(intents, - ['AXEventIntent(setSelection,character,forward)']); + ['AXEventIntent(setSelection,none,character,forward)']); gotSelectedTextChanged = true; axInputElement.unsetNotificationListener(); succeedIfDone();
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-on-selection-removed.html b/third_party/blink/web_tests/accessibility/selection-change-notification-on-selection-removed.html index ad2b042..360ee77 100644 --- a/third_party/blink/web_tests/accessibility/selection-change-notification-on-selection-removed.html +++ b/third_party/blink/web_tests/accessibility/selection-change-notification-on-selection-removed.html
@@ -27,7 +27,7 @@ axRoot.setNotificationListener(t.step_func((notification, intents) => { if (notification == 'DocumentSelectionChanged') { assert_array_equals(intents, - ['AXEventIntent(clearSelection,character,forward)']); + ['AXEventIntent(clearSelection,none,none,none)']); axRoot.unsetNotificationListener(); assert_equals(axRoot.selectionAnchorObject, null, 'selectionAnchorObject'); assert_equals(axRoot.selectionAnchorOffset, -1, 'selectionAnchorOffset');
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-statictext.html b/third_party/blink/web_tests/accessibility/selection-change-notification-statictext.html index 9036cda9..ca4a7d2 100644 --- a/third_party/blink/web_tests/accessibility/selection-change-notification-statictext.html +++ b/third_party/blink/web_tests/accessibility/selection-change-notification-statictext.html
@@ -12,7 +12,7 @@ axElement.setNotificationListener(t.step_func(function(notification, intents) { if (notification == 'SelectedTextChanged') { assert_array_equals(intents, - ['AXEventIntent(setSelection,character,forward)']); + ['AXEventIntent(setSelection,none,character,forward)']); axElement.unsetNotificationListener(); t.done(); }
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-textarea.html b/third_party/blink/web_tests/accessibility/selection-change-notification-textarea.html index 4b929ef8..acbe2c8 100644 --- a/third_party/blink/web_tests/accessibility/selection-change-notification-textarea.html +++ b/third_party/blink/web_tests/accessibility/selection-change-notification-textarea.html
@@ -1,29 +1,25 @@ <!DOCTYPE html> <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script> +<script src="../resources/run-after-layout-and-paint.js"></script> <textarea autofocus id="textarea">textarea</textarea> <script> 'use strict'; -async_test((t) => { - // This forces building the accessibility tree, because selection change - // events only fire on elements that already exist. - accessibilityController.accessibleElementById('dummy'); - - const element = document.getElementById('textarea'); +async_test_after_layout_and_paint((t) => { const axElement = accessibilityController.accessibleElementById('textarea'); - axElement.setNotificationListener(t.step_func((notification, intents) => { if (notification == 'SelectedTextChanged') { assert_array_equals(intents, - ['AXEventIntent(setSelection,character,forward)']); + ['AXEventIntent(setSelection,none,character,forward)']); axElement.unsetNotificationListener(); t.done(); } })); + const element = document.getElementById('textarea'); element.setSelectionRange(0, 1); });
diff --git a/third_party/blink/web_tests/editing/inserting/typing_letter_spacing2-expected.html b/third_party/blink/web_tests/editing/inserting/typing_letter_spacing2-expected.html new file mode 100644 index 0000000..b8cc739 --- /dev/null +++ b/third_party/blink/web_tests/editing/inserting/typing_letter_spacing2-expected.html
@@ -0,0 +1,10 @@ +<!doctype html> +<script src="../../resources/ahem.js"></script> +<style> +.sample { + font: 10px/15px Ahem; + letter-spacing: 20px; +} +</style> +<div class="sample" id="target">abcdefg</div> +<div class="sample" id="expected">abcdefg</div>
diff --git a/third_party/blink/web_tests/editing/inserting/typing_letter_spacing2.html b/third_party/blink/web_tests/editing/inserting/typing_letter_spacing2.html new file mode 100644 index 0000000..9d9b83e --- /dev/null +++ b/third_party/blink/web_tests/editing/inserting/typing_letter_spacing2.html
@@ -0,0 +1,15 @@ +<!doctype html> +<script src="../../resources/ahem.js"></script> +<style> +.sample { + font: 10px/15px Ahem; + letter-spacing: 20px; +} +</style> +<div class="sample" id="target">abcDEfg</div> +<div class="sample" id="expected">abcdefg</div> +<script> +document.body.offsetHeight; +const text = target.firstChild; +text.replaceData(3, 2, 'de'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-aspect-ratio-img-row-008.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-aspect-ratio-img-row-008.html index 59ec6fc6..58dee775 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-aspect-ratio-img-row-008.html +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-aspect-ratio-img-row-008.html
@@ -8,5 +8,5 @@ <p>Test passes if there is a filled green square.</p> <div style="display: flex; width: 100px;"> - <img src="data:image/svg+xml,%3Csvg viewBox='0 0 200 400' width='50px' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' fill='green' /%3E%3C/svg%3E" style="border-left: 50px solid green; min-width: 0px;"> + <img src="data:image/svg+xml,%3Csvg viewBox='0 0 200 400' width='50px' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' fill='green' /%3E%3C/svg%3E" style="border-left: 50px solid green; min-width: 0px;"> </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-aspect-ratio-img-row-009.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-aspect-ratio-img-row-009.html index fab5f0bf..e7dc55d2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-aspect-ratio-img-row-009.html +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-aspect-ratio-img-row-009.html
@@ -22,5 +22,5 @@ <div id=reference-overlapped-red></div> <div style="display: flex; width: 50px;"> - <img src="data:image/svg+xml,%3Csvg viewBox='0 0 200 400' width='50px' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' fill='green' /%3E%3C/svg%3E" style="border-left: 50px solid green;"> + <img src="data:image/svg+xml,%3Csvg viewBox='0 0 200 400' width='50px' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' fill='green' /%3E%3C/svg%3E" style="border-left: 50px solid green;"> </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-space-in-inline-box.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-space-in-inline-box.html new file mode 100644 index 0000000..fee51018 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-space-in-inline-box.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<title>Preserved trailing spaces in inline boxes should hang</title> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#propdef-white-space"> +<link rel="help" href="http://crbug.com/1130310"> +<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +.target { + font-family: Consolas, 'Courier New', Courier, monospace; + font-size: 20px; + width: 5ch; + white-space: pre-wrap; + overflow: auto visible; + border: 1px solid blue; +} +.not-culled span { + background: orange; +} +</style> +<body> + <div class="target">12345 678</div> + <div class="target"><span>12345 678</span></div> + <div class="target not-culled"><span>12345 678</span></div> +<script> +for (let target of document.getElementsByClassName('target')) { + test(() => { + let width = target.offsetWidth; + let scroll_width = target.scrollWidth; + assert_less_than_equal(scroll_width, width); + }); +} +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-feature-policy-test.sub.js b/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-feature-policy-test.sub.js index da1af41..9bc46ae 100644 --- a/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-feature-policy-test.sub.js +++ b/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-feature-policy-test.sub.js
@@ -72,13 +72,16 @@ ); }, `${sensorName}: ${header} allows same-origin iframes.`); + // Set allow="feature;feature;..." on iframe element to delegate features + // under test to cross origin subframe. async_test(t => { assert_implements(sensorName in self, `${sensorName} is not supported.`); test_feature_availability( desc, t, cross_origin_src + sensorName, - expect_feature_available_default + expect_feature_available_default, + feature_policies[sensorName].join(";") ); }, `${sensorName}: ${header} allows cross-origin iframes.`); }
diff --git a/third_party/blink/web_tests/external/wpt/origin-isolation/document-domain.sub.https.html b/third_party/blink/web_tests/external/wpt/origin-isolation/document-domain.sub.https.html new file mode 100644 index 0000000..6910b02 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/origin-isolation/document-domain.sub.https.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Setting document.domain does not change same-originness</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<!-- + Other tests check that using document.domain doesn't allow cross-origin + access. This test ensures a different, more subtle property: that origin + isolation makes document.domain into a no-op in other ways. +--> + +<iframe src="resources/frame.html"></iframe> + +<script type="module"> +setup({ explicit_done: true }); + +window.onload = () => { + test(() => { + // Normally, setting document.domain to itself would change the domain + // component of the origin. Since the iframe does *not* set document.domain, + // the two would then be considered cross-origin. + document.domain = document.domain; + + // However, because we're using origin isolation, this shouldn't have any + // impact. The test fails if this throws, and passes if it succeeds. + frames[0].document; + }, "Setting document.domain must not change same-originness"); + + test(() => { + assert_throws_dom("SecurityError", () => { + document.domain = "{{hosts[][nonexistent]}}"; + }); + }, "The registrable domain suffix check must happen before the bail-out"); + + done(); +}; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/origin-isolation/document-domain.sub.https.html.headers b/third_party/blink/web_tests/external/wpt/origin-isolation/document-domain.sub.https.html.headers new file mode 100644 index 0000000..ea3f6b33 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/origin-isolation/document-domain.sub.https.html.headers
@@ -0,0 +1 @@ +Origin-Isolation: ?1
diff --git a/third_party/blink/web_tests/external/wpt/origin-isolation/popups-crash.https.html b/third_party/blink/web_tests/external/wpt/origin-isolation/popups-crash.https.html new file mode 100644 index 0000000..dcfb5eb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/origin-isolation/popups-crash.https.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Crash test for https://crbug.com/1099718</title> + +<div id="log"></div> + +<script> +window.open("resources/crashy-popup.sub.html", "windowName1", "noopener"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/origin-isolation/resources/crashy-popup.sub.html b/third_party/blink/web_tests/external/wpt/origin-isolation/resources/crashy-popup.sub.html new file mode 100644 index 0000000..f8d077c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/origin-isolation/resources/crashy-popup.sub.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>This page helps exhibit a crash bug when window.open()ed</title> + +<iframe src="https://{{hosts[][www]}}:{{ports[https][0]}}/origin-isolation/resources/send-origin-isolation-header.py"></iframe> +<iframe src="https://{{hosts[][www]}}:{{ports[https][0]}}/origin-isolation/resources/send-origin-isolation-header.py?header=?1"></iframe>
diff --git a/third_party/blink/web_tests/external/wpt/origin-isolation/resources/crashy-popup.sub.html.headers b/third_party/blink/web_tests/external/wpt/origin-isolation/resources/crashy-popup.sub.html.headers new file mode 100644 index 0000000..ea3f6b33 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/origin-isolation/resources/crashy-popup.sub.html.headers
@@ -0,0 +1 @@ +Origin-Isolation: ?1
diff --git a/third_party/blink/web_tests/external/wpt/origin-isolation/resources/frame.html b/third_party/blink/web_tests/external/wpt/origin-isolation/resources/frame.html new file mode 100644 index 0000000..8f35d270 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/origin-isolation/resources/frame.html
@@ -0,0 +1,3 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A frame included by a test page</title>
diff --git a/third_party/blink/web_tests/external/wpt/origin-isolation/resources/frame.html.headers b/third_party/blink/web_tests/external/wpt/origin-isolation/resources/frame.html.headers new file mode 100644 index 0000000..ea3f6b33 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/origin-isolation/resources/frame.html.headers
@@ -0,0 +1 @@ +Origin-Isolation: ?1
diff --git a/third_party/blink/web_tests/external/wpt/origin-policy/features/non-object.https.html b/third_party/blink/web_tests/external/wpt/origin-policy/features/non-object.https.html index 2bd4b67e..d1be8e8 100644 --- a/third_party/blink/web_tests/external/wpt/origin-policy/features/non-object.https.html +++ b/third_party/blink/web_tests/external/wpt/origin-policy/features/non-object.https.html
@@ -11,6 +11,6 @@ "use strict"; runTestsInSubframe({ hostname: "op5", - testJS: "resources/no-camera-no-geolocation.mjs" + testJS: "resources/yes-camera-yes-geolocation.mjs" }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/origin-policy/features/non-string.https.html b/third_party/blink/web_tests/external/wpt/origin-policy/features/non-string.https.html index 190d224a..99645fc 100644 --- a/third_party/blink/web_tests/external/wpt/origin-policy/features/non-string.https.html +++ b/third_party/blink/web_tests/external/wpt/origin-policy/features/non-string.https.html
@@ -11,6 +11,6 @@ "use strict"; runTestsInSubframe({ hostname: "op6", - testJS: "resources/no-camera-no-geolocation.mjs" + testJS: "resources/yes-camera-yes-geolocation.mjs" }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/origin-policy/features/resources/helper.mjs b/third_party/blink/web_tests/external/wpt/origin-policy/features/resources/helper.mjs index 7ced355..0ea3b01 100644 --- a/third_party/blink/web_tests/external/wpt/origin-policy/features/resources/helper.mjs +++ b/third_party/blink/web_tests/external/wpt/origin-policy/features/resources/helper.mjs
@@ -2,7 +2,7 @@ export function runFPTest({ camera, geolocation }) { test(() => { - assert_equals(document.featurePolicy.allowsFeature('camera', 'https://example.com/'), camera, 'camera'); - assert_equals(document.featurePolicy.allowsFeature('geolocation', 'https://example.com/'), geolocation, 'geolocation'); + assert_equals(document.featurePolicy.allowsFeature('camera'), camera, 'camera'); + assert_equals(document.featurePolicy.allowsFeature('geolocation'), geolocation, 'geolocation'); }); }
diff --git a/third_party/blink/web_tests/external/wpt/origin-policy/features/valid-with-semicolon.https.html b/third_party/blink/web_tests/external/wpt/origin-policy/features/valid-with-semicolon.https.html index 8d2d0f4..53ea7a9 100644 --- a/third_party/blink/web_tests/external/wpt/origin-policy/features/valid-with-semicolon.https.html +++ b/third_party/blink/web_tests/external/wpt/origin-policy/features/valid-with-semicolon.https.html
@@ -11,6 +11,6 @@ "use strict"; runTestsInSubframe({ hostname: "op10", - testJS: "resources/yes-camera-yes-geolocation.mjs" + testJS: "resources/no-camera-yes-geolocation.mjs" }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/origin-policy/policies/op10 cspfp-valid.json b/third_party/blink/web_tests/external/wpt/origin-policy/policies/op10 cspfp-valid.json index 0fc1d163..c3bea5c7 100644 --- a/third_party/blink/web_tests/external/wpt/origin-policy/policies/op10 cspfp-valid.json +++ b/third_party/blink/web_tests/external/wpt/origin-policy/policies/op10 cspfp-valid.json
@@ -8,6 +8,6 @@ ] }, "features": { - "policy": "camera 'self' https://example.com/; geolocation 'self' https://example.com/" + "policy": "camera 'none'; geolocation 'self' https://example.com/" } }
diff --git a/third_party/blink/web_tests/external/wpt/origin-policy/policies/op2 cspfp-double-top-level.json b/third_party/blink/web_tests/external/wpt/origin-policy/policies/op2 cspfp-double-top-level.json index 26d798b..59c3419 100644 --- a/third_party/blink/web_tests/external/wpt/origin-policy/policies/op2 cspfp-double-top-level.json +++ b/third_party/blink/web_tests/external/wpt/origin-policy/policies/op2 cspfp-double-top-level.json
@@ -13,9 +13,9 @@ ] }, "features": { - "policy": "camera 'self' https://example.com/" + "policy": "geolocation 'none'" }, "features": { - "policy": "geolocation 'self' https://example.com/" + "policy": "camera 'none'" } }
diff --git a/third_party/blink/web_tests/external/wpt/origin-policy/policies/op5 cspfp-non-object.json b/third_party/blink/web_tests/external/wpt/origin-policy/policies/op5 cspfp-non-object.json index 7488f9b..1e40460 100644 --- a/third_party/blink/web_tests/external/wpt/origin-policy/policies/op5 cspfp-non-object.json +++ b/third_party/blink/web_tests/external/wpt/origin-policy/policies/op5 cspfp-non-object.json
@@ -5,5 +5,5 @@ "content_security": [ "script-src 'self' 'unsafe-inline'" ], - "features": "camera 'self' https://example.com/" + "features": "camera 'none'" }
diff --git a/third_party/blink/web_tests/external/wpt/origin-policy/policies/op6 cspfp-non-string.json b/third_party/blink/web_tests/external/wpt/origin-policy/policies/op6 cspfp-non-string.json index 5c6941b..231e7d4 100644 --- a/third_party/blink/web_tests/external/wpt/origin-policy/policies/op6 cspfp-non-string.json +++ b/third_party/blink/web_tests/external/wpt/origin-policy/policies/op6 cspfp-non-string.json
@@ -11,7 +11,7 @@ }, "features": { "policy": [ - "camera 'self' https://example.com/" + "camera 'none'" ] } }
diff --git a/third_party/blink/web_tests/external/wpt/screen-wake-lock/wakelock-enabled-by-feature-policy.https.sub.html b/third_party/blink/web_tests/external/wpt/screen-wake-lock/wakelock-enabled-by-feature-policy.https.sub.html index f908717..53e92f5 100644 --- a/third_party/blink/web_tests/external/wpt/screen-wake-lock/wakelock-enabled-by-feature-policy.https.sub.html +++ b/third_party/blink/web_tests/external/wpt/screen-wake-lock/wakelock-enabled-by-feature-policy.https.sub.html
@@ -28,12 +28,15 @@ ); }, 'Feature-Policy header {"screen-wake-lock" : ["*"]} allows same-origin iframes.'); + // Set allow="screen-wake-lock" on iframe element to delegate + // 'screen-wake-lock' to cross origin subframe. async_test(t => { test_feature_availability( 'navigator.wakeLock.request("screen")', t, cross_origin_src, - expect_feature_available_default + expect_feature_available_default, + 'screen-wake-lock' ); }, 'Feature-Policy header {"screen-wake-lock" : ["*"]} allows cross-origin iframes.');
diff --git a/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy.https.sub.html b/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy.https.sub.html index 316256b..0a2b296a 100644 --- a/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy.https.sub.html +++ b/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy.https.sub.html
@@ -27,15 +27,19 @@ expect_feature_available_default); }, header + ' allows workers in same-origin iframes.'); +// Set allow="serial" on iframe element to delegate 'serial' to cross origin +// subframe. async_test(t => { test_feature_availability('serial.getPorts()', t, cross_origin_src, - expect_feature_available_default); + expect_feature_available_default, 'serial'); }, header + ' allows cross-origin iframes.'); +// Set allow="serial" on iframe element to delegate 'serial' to cross origin +// subframe. async_test(t => { test_feature_availability('serial.getPorts()', t, cross_origin_worker_frame_src, - expect_feature_available_default); + expect_feature_available_default, 'serial'); }, header + ' allows workers in cross-origin iframes.'); fetch_tests_from_worker(new Worker(
diff --git a/third_party/blink/web_tests/external/wpt/svg/shapes/reftests/disabled-shapes-01.svg b/third_party/blink/web_tests/external/wpt/svg/shapes/reftests/disabled-shapes-01.svg index 65364dc..49572fe 100644 --- a/third_party/blink/web_tests/external/wpt/svg/shapes/reftests/disabled-shapes-01.svg +++ b/third_party/blink/web_tests/external/wpt/svg/shapes/reftests/disabled-shapes-01.svg
@@ -9,15 +9,25 @@ <g stroke="red" stroke-width="100"> <g transform="translate(50, 50)"> <rect/> + <rect width="10"/> + <rect height="10"/> + <rect width="10%"/> + <rect height="10%"/> <rect width="0" height="10"/> <rect width="-10" height="10"/> <rect height="0" width="10"/> <rect height="-10" width="10"/> <rect style="width: 0"/> + <rect style="width: 10px"/> + <rect style="width: 10%"/> + <rect style="width: calc(10%+10px)"/> <rect style="width: 0" height="10"/> <rect style="width: -10px"/> <rect style="width: -10px" height="10"/> <rect style="height: 0"/> + <rect style="height: 10px"/> + <rect style="height: 10%"/> + <rect style="height: calc(10%+10px)"/> <rect style="height: 0" width="10"/> <rect style="height: -10px"/> <rect style="height: -10px" width="10"/>
diff --git a/third_party/blink/web_tests/external/wpt/svg/shapes/reftests/polygon-with-filtered-marker.html b/third_party/blink/web_tests/external/wpt/svg/shapes/reftests/polygon-with-filtered-marker.html new file mode 100644 index 0000000..def8adc6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/shapes/reftests/polygon-with-filtered-marker.html
@@ -0,0 +1,10 @@ +<!doctype html> +<title>Filtered <marker> with <clipPath> ancestor on <polygon></title> +<link rel="match" href="../../struct/reftests/reference/green-100x100.html"> +<svg> + <clipPath> + <marker id="m" filter="url(#f)"/> + <filter id="f"/> + </clipPath> + <polygon points="0,0 100,0 100,100 0,100" fill="green" marker-start="url(#m)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/web-locks/clientids.tentative.https-expected.txt b/third_party/blink/web_tests/external/wpt/web-locks/clientids.tentative.https-expected.txt deleted file mode 100644 index 15e58a6..0000000 --- a/third_party/blink/web_tests/external/wpt/web-locks/clientids.tentative.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Client IDs match between Locks API and Service Workers assert_true: clientIds should match, but are different expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/webusb/usb-allowed-by-feature-policy.https.sub.html b/third_party/blink/web_tests/external/wpt/webusb/usb-allowed-by-feature-policy.https.sub.html index 9ec25ea..831cb42 100644 --- a/third_party/blink/web_tests/external/wpt/webusb/usb-allowed-by-feature-policy.https.sub.html +++ b/third_party/blink/web_tests/external/wpt/webusb/usb-allowed-by-feature-policy.https.sub.html
@@ -27,15 +27,17 @@ expect_feature_available_default); }, header + ' allows workers in same-origin iframes.'); +// Set allow="usb" on iframe element to delegate 'usb' to cross origin subframe. async_test(t => { test_feature_availability('usb.getDevices()', t, cross_origin_src, - expect_feature_available_default); + expect_feature_available_default, 'usb'); }, header + ' allows cross-origin iframes.'); +// Set allow="usb" on iframe element to delegate 'usb' to cross origin subframe. async_test(t => { test_feature_availability('usb.getDevices()', t, cross_origin_worker_frame_src, - expect_feature_available_default); + expect_feature_available_default, 'usb'); }, header + ' allows workers in cross-origin iframes.'); fetch_tests_from_worker(new Worker(
diff --git a/third_party/blink/web_tests/fast/forms/file/file-crash-by-pseudo-after-with-padding.html b/third_party/blink/web_tests/fast/forms/file/file-crash-by-pseudo-after-with-padding.html index 3a51e100..302d2a4 100644 --- a/third_party/blink/web_tests/fast/forms/file/file-crash-by-pseudo-after-with-padding.html +++ b/third_party/blink/web_tests/fast/forms/file/file-crash-by-pseudo-after-with-padding.html
@@ -10,6 +10,15 @@ width: 100%; padding-right: 100%; } + +.c19 { + width: 400px; +} + +.c19:after { + content: 'a'; + margin-left: 2000000000%; +} </style> <input type="file"> <script> @@ -19,4 +28,11 @@ fileInput.offsetWidth; // Ok if no crash. }, ':after with large padding should not cause a crash.'); + +test(() => { + const fileInput = document.querySelector('input'); + fileInput.classList.add('c19'); + fileInput.offsetWidth; + // Ok if no crash. +}, ':after with huge margin should not cause a crash.'); </script>
diff --git a/third_party/closure_compiler/externs/automation.js b/third_party/closure_compiler/externs/automation.js index 866f7733..93d45012 100644 --- a/third_party/closure_compiler/externs/automation.js +++ b/third_party/closure_compiler/externs/automation.js
@@ -435,29 +435,71 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/automation#type-EventCommandType + * @see https://developer.chrome.com/extensions/automation#type-IntentCommandType */ -chrome.automation.EventCommandType = { +chrome.automation.IntentCommandType = { CLEAR_SELECTION: 'clearSelection', - CUT: 'cut', DELETE: 'delete', DICTATE: 'dictate', EXTEND_SELECTION: 'extendSelection', FORMAT: 'format', + HISTORY: 'history', INSERT: 'insert', MARKER: 'marker', MOVE_SELECTION: 'moveSelection', - PASTE: 'paste', - REPLACE: 'replace', SET_SELECTION: 'setSelection', - TYPE: 'type', }; /** * @enum {string} - * @see https://developer.chrome.com/extensions/automation#type-EventTextBoundaryType + * @see https://developer.chrome.com/extensions/automation#type-IntentInputEventType */ -chrome.automation.EventTextBoundaryType = { +chrome.automation.IntentInputEventType = { + INSERT_TEXT: 'insertText', + INSERT_LINE_BREAK: 'insertLineBreak', + INSERT_PARAGRAPH: 'insertParagraph', + INSERT_ORDERED_LIST: 'insertOrderedList', + INSERT_UNORDERED_LIST: 'insertUnorderedList', + INSERT_HORIZONTAL_RULE: 'insertHorizontalRule', + INSERT_FROM_PASTE: 'insertFromPaste', + INSERT_FROM_DROP: 'insertFromDrop', + INSERT_FROM_YANK: 'insertFromYank', + INSERT_TRANSPOSE: 'insertTranspose', + INSERT_REPLACEMENT_TEXT: 'insertReplacementText', + INSERT_COMPOSITION_TEXT: 'insertCompositionText', + DELETE_WORD_BACKWARD: 'deleteWordBackward', + DELETE_WORD_FORWARD: 'deleteWordForward', + DELETE_SOFT_LINE_BACKWARD: 'deleteSoftLineBackward', + DELETE_SOFT_LINE_FORWARD: 'deleteSoftLineForward', + DELETE_HARD_LINE_BACKWARD: 'deleteHardLineBackward', + DELETE_HARD_LINE_FORWARD: 'deleteHardLineForward', + DELETE_CONTENT_BACKWARD: 'deleteContentBackward', + DELETE_CONTENT_FORWARD: 'deleteContentForward', + DELETE_BY_CUT: 'deleteByCut', + DELETE_BY_DRAG: 'deleteByDrag', + HISTORY_UNDO: 'historyUndo', + HISTORY_REDO: 'historyRedo', + FORMAT_BOLD: 'formatBold', + FORMAT_ITALIC: 'formatItalic', + FORMAT_UNDERLINE: 'formatUnderline', + FORMAT_STRIKE_THROUGH: 'formatStrikeThrough', + FORMAT_SUPERSCRIPT: 'formatSuperscript', + FORMAT_SUBSCRIPT: 'formatSubscript', + FORMAT_JUSTIFY_CENTER: 'formatJustifyCenter', + FORMAT_JUSTIFY_FULL: 'formatJustifyFull', + FORMAT_JUSTIFY_RIGHT: 'formatJustifyRight', + FORMAT_JUSTIFY_LEFT: 'formatJustifyLeft', + FORMAT_INDENT: 'formatIndent', + FORMAT_OUTDENT: 'formatOutdent', + FORMAT_REMOVE: 'formatRemove', + FORMAT_SET_BLOCK_TEXT_DIRECTION: 'formatSetBlockTextDirection', +}; + +/** + * @enum {string} + * @see https://developer.chrome.com/extensions/automation#type-IntentTextBoundaryType + */ +chrome.automation.IntentTextBoundaryType = { CHARACTER: 'character', FORMAT: 'format', LINE_END: 'lineEnd', @@ -481,11 +523,11 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/automation#type-EventMoveDirectionType + * @see https://developer.chrome.com/extensions/automation#type-IntentMoveDirectionType */ -chrome.automation.EventMoveDirectionType = { - FORWARD: 'forward', +chrome.automation.IntentMoveDirectionType = { BACKWARD: 'backward', + FORWARD: 'forward', }; /** @@ -589,9 +631,9 @@ /** * @typedef {{ - * command: !chrome.automation.EventCommandType, - * textBoundary: !chrome.automation.EventTextBoundaryType, - * moveDirection: !chrome.automation.EventMoveDirectionType + * command: !chrome.automation.IntentCommandType, + * textBoundary: !chrome.automation.IntentTextBoundaryType, + * moveDirection: !chrome.automation.IntentMoveDirectionType * }} * @see https://developer.chrome.com/extensions/automation#type-AutomationIntent */ @@ -645,7 +687,7 @@ chrome.automation.AutomationEvent.prototype.mouseY; /** - * Intents associated with this event. + * A list of $(ref:automation.AutomationIntent)s associated with this event. * @type {!Array<!chrome.automation.AutomationIntent>} * @see https://developer.chrome.com/extensions/automation#type-intents */ @@ -653,7 +695,7 @@ /** * Stops this event from further processing except for any remaining listeners - * on $(ref:AutomationEvent.target). + * on $(ref:automation.AutomationEvent.target). * @see https://developer.chrome.com/extensions/automation#method-stopPropagation */ chrome.automation.AutomationEvent.prototype.stopPropagation = function() {};
diff --git a/third_party/webxr_test_pages/webxr-samples/proposals/phone-ar-depth-gpu.html b/third_party/webxr_test_pages/webxr-samples/proposals/phone-ar-depth-gpu.html index 41ed77b..bf5d1ffe 100644 --- a/third_party/webxr_test_pages/webxr-samples/proposals/phone-ar-depth-gpu.html +++ b/third_party/webxr_test_pages/webxr-samples/proposals/phone-ar-depth-gpu.html
@@ -98,7 +98,7 @@ // Requests an immersive session with environment integration. let options = { - requiredFeatures: ['depth'], + requiredFeatures: ['depth-sensing'], }; navigator.xr.requestSession('immersive-ar', options).then((session) => {
diff --git a/third_party/webxr_test_pages/webxr-samples/proposals/phone-ar-depth.html b/third_party/webxr_test_pages/webxr-samples/proposals/phone-ar-depth.html index 4482fc5..70af8352 100644 --- a/third_party/webxr_test_pages/webxr-samples/proposals/phone-ar-depth.html +++ b/third_party/webxr_test_pages/webxr-samples/proposals/phone-ar-depth.html
@@ -99,7 +99,7 @@ // Requests an immersive session with environment integration. let options = { - requiredFeatures: ['depth'], + requiredFeatures: ['depth-sensing'], }; navigator.xr.requestSession('immersive-ar', options).then((session) => {
diff --git a/tools/binary_size/libsupersize/static/tree-ui.js b/tools/binary_size/libsupersize/static/tree-ui.js index 9158b32..8af09d5 100644 --- a/tools/binary_size/libsupersize/static/tree-ui.js +++ b/tools/binary_size/libsupersize/static/tree-ui.js
@@ -445,7 +445,9 @@ dom.replace(_symbolTree, rootElement); if (!_doneLoad && percent === 1) { _doneLoad = true; - console.log('Pro Tip: await worker.openNode("$FILE_PATH")') + console.log( + '%cPro Tip: %cawait supersize.worker.openNode("$FILE_PATH")', + 'font-weight:bold; color: red;', '') } }) );
diff --git a/tools/determinism/deterministic_build_ignorelist.pyl b/tools/determinism/deterministic_build_ignorelist.pyl index 0d9de1f..1e6fa2ba 100644 --- a/tools/determinism/deterministic_build_ignorelist.pyl +++ b/tools/determinism/deterministic_build_ignorelist.pyl
@@ -51,6 +51,7 @@ 'nacl_test_data/newlib/sysconf_nprocessors_onln_test_newlib_x86_64.nexe', 'nacl_test_data/pnacl/pnacl_debug_url_newlib_pnacl.pexe.debug', 'nacl_test_data/pnacl/pnacl_errors_newlib_pnacl.pexe', + 'ppapi_nacl_tests_pnacl_newlib_x32_nonsfi.nexe', 'ppapi_nacl_tests_newlib_x86_64.nexe', 'test_data/ppapi/tests/extensions/background_keepalive/newlib/ppapi_tests_extensions_background_keepalive_newlib_x86_64.nexe', 'test_data/ppapi/tests/extensions/load_unload/newlib/ppapi_tests_extensions_load_unload_newlib_x86_64.nexe', @@ -96,6 +97,7 @@ 'nacl_test_data/newlib/sysconf_nprocessors_onln_test_newlib_x86_64.nexe', 'nacl_test_data/pnacl/pnacl_debug_url_newlib_pnacl.pexe.debug', 'nacl_test_data/pnacl/pnacl_errors_newlib_pnacl.pexe', + 'ppapi_nacl_tests_pnacl_newlib_x32_nonsfi.nexe', 'ppapi_nacl_tests_newlib_x86_64.nexe', 'test_data/ppapi/tests/extensions/background_keepalive/newlib/ppapi_tests_extensions_background_keepalive_newlib_x86_64.nexe', 'test_data/ppapi/tests/extensions/load_unload/newlib/ppapi_tests_extensions_load_unload_newlib_x86_64.nexe',
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index f4730937..7e84805 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -306,6 +306,7 @@ 'linux-upload-perfetto': 'release_bot', 'linux-wpt-fyi-rel': 'release_bot_minimal_symbols', 'linux-wpt-identity-fyi-rel': 'release_bot_minimal_symbols', + 'linux-wpt-payments-fyi-rel': 'release_bot_minimal_symbols', 'mac-code-coverage': 'clang_code_coverage', 'mac-hermetic-upgrade-rel': 'release_bot', 'mac-mojo-rel': 'release_trybot',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index fed5580..6e3c4dd 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -9568,6 +9568,9 @@ <int value="8" label="Data collection failure"> Failure while collecting data. </int> + <int value="9" label="Session has zero samples"> + The profile session has zero samples. + </int> </enum> <enum name="ChromeOSRecoveryReason"> @@ -29242,10 +29245,10 @@ <int value="3475" label="WebkitPrerenderLoadEventFired"/> <int value="3476" label="WebkitPrerenderDOMContentLoadedEventFired"/> <int value="3477" label="IdleDetectionPermissionRequested"/> - <int value="3478" label="IdentifiabilityStudyReserved3478"/> - <int value="3479" label="IdentifiabilityStudyReserved3479"/> - <int value="3480" label="IdentifiabilityStudyReserved3480"/> - <int value="3481" label="IdentifiabilityStudyReserved3481"/> + <int value="3478" label="V8MediaDeviceInfo_Kind_AttributeGetter"/> + <int value="3479" label="V8MediaDeviceInfo_GroupId_AttributeGetter"/> + <int value="3480" label="V8MediaDeviceInfo_Label_AttributeGetter"/> + <int value="3481" label="V8Navigator_JavaEnabled_Method"/> <int value="3482" label="IdentifiabilityStudyReserved3482"/> <int value="3483" label="IdentifiabilityStudyReserved3483"/> <int value="3484" label="IdentifiabilityStudyReserved3484"/> @@ -29297,39 +29300,46 @@ <int value="3530" label="IdentifiabilityStudyReserved3530"/> <int value="3531" label="IdentifiabilityStudyReserved3531"/> <int value="3532" label="IdentifiabilityStudyReserved3532"/> - <int value="3533" label="IdentifiabilityStudyReserved3533"/> - <int value="3534" label="IdentifiabilityStudyReserved3534"/> - <int value="3535" label="IdentifiabilityStudyReserved3535"/> - <int value="3536" label="IdentifiabilityStudyReserved3536"/> - <int value="3537" label="IdentifiabilityStudyReserved3537"/> + <int value="3533" label="V8SpeechSynthesisVoice_Default_AttributeGetter"/> + <int value="3534" label="V8SpeechSynthesisVoice_Lang_AttributeGetter"/> + <int value="3535" + label="V8SpeechSynthesisVoice_LocalService_AttributeGetter"/> + <int value="3536" label="V8SpeechSynthesisVoice_Name_AttributeGetter"/> + <int value="3537" label="V8SpeechSynthesisVoice_VoiceURI_AttributeGetter"/> <int value="3538" label="IdentifiabilityStudyReserved3538"/> <int value="3539" label="IdentifiabilityStudyReserved3539"/> <int value="3540" label="IdentifiabilityStudyReserved3540"/> <int value="3541" label="V8WheelEvent_DeltaMode_AttributeGetter"/> <int value="3542" label="IdentifiabilityStudyReserved3542"/> - <int value="3543" label="IdentifiabilityStudyReserved3543"/> - <int value="3544" label="IdentifiabilityStudyReserved3544"/> - <int value="3545" label="IdentifiabilityStudyReserved3545"/> + <int value="3543" label="V8HIDDevice_ProductId_AttributeGetter"/> + <int value="3544" label="V8HIDDevice_ProductName_AttributeGetter"/> + <int value="3545" label="V8HIDDevice_VendorId_AttributeGetter"/> <int value="3546" label="IdentifiabilityStudyReserved3546"/> - <int value="3547" label="IdentifiabilityStudyReserved3547"/> - <int value="3548" label="IdentifiabilityStudyReserved3548"/> - <int value="3549" label="IdentifiabilityStudyReserved3549"/> - <int value="3550" label="IdentifiabilityStudyReserved3550"/> - <int value="3551" label="IdentifiabilityStudyReserved3551"/> - <int value="3552" label="IdentifiabilityStudyReserved3552"/> - <int value="3553" label="IdentifiabilityStudyReserved3553"/> - <int value="3554" label="IdentifiabilityStudyReserved3554"/> - <int value="3555" label="IdentifiabilityStudyReserved3555"/> - <int value="3556" label="IdentifiabilityStudyReserved3556"/> - <int value="3557" label="IdentifiabilityStudyReserved3557"/> - <int value="3558" label="IdentifiabilityStudyReserved3558"/> - <int value="3559" label="IdentifiabilityStudyReserved3559"/> - <int value="3560" label="IdentifiabilityStudyReserved3560"/> - <int value="3561" label="IdentifiabilityStudyReserved3561"/> - <int value="3562" label="IdentifiabilityStudyReserved3562"/> - <int value="3563" label="IdentifiabilityStudyReserved3563"/> - <int value="3564" label="IdentifiabilityStudyReserved3564"/> - <int value="3565" label="IdentifiabilityStudyReserved3565"/> + <int value="3547" label="V8HIDReportItem_HasNull_AttributeGetter"/> + <int value="3548" label="V8HIDReportItem_IsAbsolute_AttributeGetter"/> + <int value="3549" label="V8HIDReportItem_IsArray_AttributeGetter"/> + <int value="3550" label="V8HIDReportItem_IsRange_AttributeGetter"/> + <int value="3551" label="V8HIDReportItem_LogicalMaximum_AttributeGetter"/> + <int value="3552" label="V8HIDReportItem_LogicalMinimum_AttributeGetter"/> + <int value="3553" label="V8HIDReportItem_PhysicalMaximum_AttributeGetter"/> + <int value="3554" label="V8HIDReportItem_PhysicalMinimum_AttributeGetter"/> + <int value="3555" label="V8HIDReportItem_ReportCount_AttributeGetter"/> + <int value="3556" label="V8HIDReportItem_ReportSize_AttributeGetter"/> + <int value="3557" label="V8HIDReportItem_UnitExponent_AttributeGetter"/> + <int value="3558" + label="V8HIDReportItem_UnitFactorCurrentExponent_AttributeGetter"/> + <int value="3559" + label="V8HIDReportItem_UnitFactorLengthExponent_AttributeGetter"/> + <int value="3560" + label="V8HIDReportItem_UnitFactorLuminousIntensityExponent_AttributeGetter"/> + <int value="3561" + label="V8HIDReportItem_UnitFactorMassExponent_AttributeGetter"/> + <int value="3562" + label="V8HIDReportItem_UnitFactorTemperatureExponent_AttributeGetter"/> + <int value="3563" + label="V8HIDReportItem_UnitFactorTimeExponent_AttributeGetter"/> + <int value="3564" label="V8HIDReportItem_UsageMaximum_AttributeGetter"/> + <int value="3565" label="V8HIDReportItem_UsageMinimum_AttributeGetter"/> <int value="3566" label="IdentifiabilityStudyReserved3566"/> <int value="3567" label="IdentifiabilityStudyReserved3567"/> <int value="3568" label="IdentifiabilityStudyReserved3568"/> @@ -29346,6 +29356,106 @@ <int value="3579" label="ForcedDarkMode"/> <int value="3580" label="PreferredColorSchemeDark"/> <int value="3581" label="PreferredColorSchemeDarkSetting"/> + <int value="3582" label="IdentifiabilityStudyReserved3582"/> + <int value="3583" label="IdentifiabilityStudyReserved3583"/> + <int value="3584" label="IdentifiabilityStudyReserved3584"/> + <int value="3585" label="IdentifiabilityStudyReserved3585"/> + <int value="3586" label="IdentifiabilityStudyReserved3586"/> + <int value="3587" label="IdentifiabilityStudyReserved3587"/> + <int value="3588" label="IdentifiabilityStudyReserved3588"/> + <int value="3589" label="IdentifiabilityStudyReserved3589"/> + <int value="3590" label="IdentifiabilityStudyReserved3590"/> + <int value="3591" label="IdentifiabilityStudyReserved3591"/> + <int value="3592" label="IdentifiabilityStudyReserved3592"/> + <int value="3593" label="IdentifiabilityStudyReserved3593"/> + <int value="3594" label="IdentifiabilityStudyReserved3594"/> + <int value="3595" label="IdentifiabilityStudyReserved3595"/> + <int value="3596" label="IdentifiabilityStudyReserved3596"/> + <int value="3597" label="IdentifiabilityStudyReserved3597"/> + <int value="3598" label="IdentifiabilityStudyReserved3598"/> + <int value="3599" label="IdentifiabilityStudyReserved3599"/> + <int value="3600" label="IdentifiabilityStudyReserved3600"/> + <int value="3601" label="IdentifiabilityStudyReserved3601"/> + <int value="3602" label="IdentifiabilityStudyReserved3602"/> + <int value="3603" label="IdentifiabilityStudyReserved3603"/> + <int value="3604" label="IdentifiabilityStudyReserved3604"/> + <int value="3605" label="IdentifiabilityStudyReserved3605"/> + <int value="3606" label="IdentifiabilityStudyReserved3606"/> + <int value="3607" label="IdentifiabilityStudyReserved3607"/> + <int value="3608" label="IdentifiabilityStudyReserved3608"/> + <int value="3609" label="IdentifiabilityStudyReserved3609"/> + <int value="3610" label="IdentifiabilityStudyReserved3610"/> + <int value="3611" label="IdentifiabilityStudyReserved3611"/> + <int value="3612" label="IdentifiabilityStudyReserved3612"/> + <int value="3613" label="IdentifiabilityStudyReserved3613"/> + <int value="3614" label="IdentifiabilityStudyReserved3614"/> + <int value="3615" label="IdentifiabilityStudyReserved3615"/> + <int value="3616" label="IdentifiabilityStudyReserved3616"/> + <int value="3617" label="IdentifiabilityStudyReserved3617"/> + <int value="3618" label="IdentifiabilityStudyReserved3618"/> + <int value="3619" label="IdentifiabilityStudyReserved3619"/> + <int value="3620" label="IdentifiabilityStudyReserved3620"/> + <int value="3621" label="IdentifiabilityStudyReserved3621"/> + <int value="3622" label="IdentifiabilityStudyReserved3622"/> + <int value="3623" label="IdentifiabilityStudyReserved3623"/> + <int value="3624" label="IdentifiabilityStudyReserved3624"/> + <int value="3625" label="IdentifiabilityStudyReserved3625"/> + <int value="3626" label="IdentifiabilityStudyReserved3626"/> + <int value="3627" label="IdentifiabilityStudyReserved3627"/> + <int value="3628" label="IdentifiabilityStudyReserved3628"/> + <int value="3629" label="IdentifiabilityStudyReserved3629"/> + <int value="3630" label="IdentifiabilityStudyReserved3630"/> + <int value="3631" label="IdentifiabilityStudyReserved3631"/> + <int value="3632" label="IdentifiabilityStudyReserved3632"/> + <int value="3633" label="IdentifiabilityStudyReserved3633"/> + <int value="3634" label="IdentifiabilityStudyReserved3634"/> + <int value="3635" label="IdentifiabilityStudyReserved3635"/> + <int value="3636" label="IdentifiabilityStudyReserved3636"/> + <int value="3637" label="IdentifiabilityStudyReserved3637"/> + <int value="3638" label="IdentifiabilityStudyReserved3638"/> + <int value="3639" label="IdentifiabilityStudyReserved3639"/> + <int value="3640" label="IdentifiabilityStudyReserved3640"/> + <int value="3641" label="IdentifiabilityStudyReserved3641"/> + <int value="3642" label="IdentifiabilityStudyReserved3642"/> + <int value="3643" label="IdentifiabilityStudyReserved3643"/> + <int value="3644" label="IdentifiabilityStudyReserved3644"/> + <int value="3645" label="IdentifiabilityStudyReserved3645"/> + <int value="3646" label="IdentifiabilityStudyReserved3646"/> + <int value="3647" label="IdentifiabilityStudyReserved3647"/> + <int value="3648" label="IdentifiabilityStudyReserved3648"/> + <int value="3649" label="IdentifiabilityStudyReserved3649"/> + <int value="3650" label="IdentifiabilityStudyReserved3650"/> + <int value="3651" label="IdentifiabilityStudyReserved3651"/> + <int value="3652" label="IdentifiabilityStudyReserved3652"/> + <int value="3653" label="IdentifiabilityStudyReserved3653"/> + <int value="3654" label="IdentifiabilityStudyReserved3654"/> + <int value="3655" label="IdentifiabilityStudyReserved3655"/> + <int value="3656" label="IdentifiabilityStudyReserved3656"/> + <int value="3657" label="IdentifiabilityStudyReserved3657"/> + <int value="3658" label="IdentifiabilityStudyReserved3658"/> + <int value="3659" label="IdentifiabilityStudyReserved3659"/> + <int value="3660" label="IdentifiabilityStudyReserved3660"/> + <int value="3661" label="IdentifiabilityStudyReserved3661"/> + <int value="3662" label="IdentifiabilityStudyReserved3662"/> + <int value="3663" label="IdentifiabilityStudyReserved3663"/> + <int value="3664" label="IdentifiabilityStudyReserved3664"/> + <int value="3665" label="IdentifiabilityStudyReserved3665"/> + <int value="3666" label="IdentifiabilityStudyReserved3666"/> + <int value="3667" label="IdentifiabilityStudyReserved3667"/> + <int value="3668" label="IdentifiabilityStudyReserved3668"/> + <int value="3669" label="IdentifiabilityStudyReserved3669"/> + <int value="3670" label="IdentifiabilityStudyReserved3670"/> + <int value="3671" label="IdentifiabilityStudyReserved3671"/> + <int value="3672" label="IdentifiabilityStudyReserved3672"/> + <int value="3673" label="IdentifiabilityStudyReserved3673"/> + <int value="3674" label="IdentifiabilityStudyReserved3674"/> + <int value="3675" label="IdentifiabilityStudyReserved3675"/> + <int value="3676" label="IdentifiabilityStudyReserved3676"/> + <int value="3677" label="IdentifiabilityStudyReserved3677"/> + <int value="3678" label="IdentifiabilityStudyReserved3678"/> + <int value="3679" label="IdentifiabilityStudyReserved3679"/> + <int value="3680" label="IdentifiabilityStudyReserved3680"/> + <int value="3681" label="IdentifiabilityStudyReserved3681"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -61594,7 +61704,7 @@ <int value="7" label="MediaElementEvent"/> <int value="8" label="CanvasBlobSerialization"/> <int value="9" label="Microtask"/> - <int value="10" label="JavascriptTimerDelayed"/> + <int value="10" label="JavascriptTimerDelayedHighNesting"/> <int value="11" label="RemoteEvent"/> <int value="12" label="WebSocket"/> <int value="13" label="PostedMessage"/> @@ -61657,6 +61767,7 @@ <int value="70" label="InternalFindInPage"/> <int value="71" label="InternalHighPriorityLocalFrame"/> <int value="72" label="JavascriptTimerImmediate"/> + <int value="73" label="JavascriptTimerDelayedLowNesting"/> </enum> <enum name="RendererSchedulerTaskUseCase"> @@ -62309,6 +62420,7 @@ <int value="5" label="CONNECTION_4G"/> <int value="6" label="CONNECTION_NONE"/> <int value="7" label="CONNECTION_BLUETOOTH"/> + <int value="8" label="CONNECTION_5G"/> </enum> <enum name="ResourcePrefetchPredictorRedirectStatus">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 99274dbf..4a7d9c8 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -53761,7 +53761,7 @@ </histogram> <histogram name="Extensions.CorruptExtensionDisabledReason" - enum="CorruptExtensionDisabledReason" expires_after="M85"> + enum="CorruptExtensionDisabledReason" expires_after="2021-09-21"> <owner>lazyboy@chromium.org</owner> <owner>rockot@chromium.org</owner> <owner>extensions-core@chromium.org</owner> @@ -67942,7 +67942,7 @@ </histogram> <histogram name="InertialSensor.AccelerometerAndroidAvailable" - enum="BooleanAvailable" expires_after="M85"> + enum="BooleanAvailable" expires_after="M95"> <owner>timvolodine@chromium.org</owner> <summary> Whether the Sensor.TYPE_LINEAR_ACCELERATION was available at the start of @@ -67951,7 +67951,7 @@ </histogram> <histogram name="InertialSensor.AccelerometerIncGravityAndroidAvailable" - enum="BooleanAvailable" expires_after="M85"> + enum="BooleanAvailable" expires_after="M95"> <owner>timvolodine@chromium.org</owner> <summary> Whether the Sensor.TYPE_ACCELEROMETER was available at the start of Device @@ -67960,7 +67960,7 @@ </histogram> <histogram name="InertialSensor.AccelerometerWindowsAvailable" - enum="BooleanAvailable" expires_after="M85"> + enum="BooleanAvailable" expires_after="M95"> <owner>timvolodine@chromium.org</owner> <summary> Whether the SENSOR_TYPE_ACCELEROMETER_3D was available at the start of @@ -67969,7 +67969,7 @@ </histogram> <histogram name="InertialSensor.DeviceOrientationSensorAndroid" - enum="DeviceOrientationSensorTypeAndroid" expires_after="M85"> + enum="DeviceOrientationSensorTypeAndroid" expires_after="M95"> <owner>timvolodine@chromium.org</owner> <summary> Provides a histogram of the base sensors (if any) that are used at the start @@ -67981,7 +67981,7 @@ </histogram> <histogram name="InertialSensor.GyrometerWindowsAvailable" - enum="BooleanAvailable" expires_after="M85"> + enum="BooleanAvailable" expires_after="M95"> <owner>timvolodine@chromium.org</owner> <summary> Whether the SENSOR_TYPE_GYROMETER_3D was available at the start of Device @@ -67990,7 +67990,7 @@ </histogram> <histogram name="InertialSensor.GyroscopeAndroidAvailable" - enum="BooleanAvailable" expires_after="M85"> + enum="BooleanAvailable" expires_after="M95"> <owner>timvolodine@chromium.org</owner> <summary> Whether the Sensor.TYPE_GYROSCOPE was available at the start of Device @@ -67999,7 +67999,7 @@ </histogram> <histogram name="InertialSensor.InclinometerWindowsAvailable" - enum="BooleanAvailable" expires_after="M85"> + enum="BooleanAvailable" expires_after="M95"> <owner>timvolodine@chromium.org</owner> <summary> Whether the SENSOR_TYPE_INCLINOMETER_3D was available at the start of Device @@ -68008,7 +68008,7 @@ </histogram> <histogram name="InertialSensor.MotionDefaultAvailable" enum="BooleanAvailable" - expires_after="M85"> + expires_after="M95"> <owner>timvolodine@chromium.org</owner> <summary> This histogram counts the number of Device Motion API invocations in the @@ -68018,7 +68018,7 @@ </histogram> <histogram name="InertialSensor.MotionMacAvailable" enum="BooleanAvailable" - expires_after="M85"> + expires_after="M95"> <owner>timvolodine@chromium.org</owner> <summary> Whether the sudden motion sensor was available at the start of Device Motion @@ -68027,7 +68027,7 @@ </histogram> <histogram name="InertialSensor.OrientationDefaultAvailable" - enum="BooleanAvailable" expires_after="M85"> + enum="BooleanAvailable" expires_after="M95"> <owner>timvolodine@chromium.org</owner> <summary> This histogram counts the number of Device Orientation API invocations in @@ -68037,7 +68037,7 @@ </histogram> <histogram name="InertialSensor.OrientationMacAvailable" - enum="BooleanAvailable" expires_after="M85"> + enum="BooleanAvailable" expires_after="M95"> <owner>timvolodine@chromium.org</owner> <summary> Whether the sudden motion sensor was available at the start of Device @@ -169656,6 +169656,9 @@ <histogram name="Stability.iOS.UTE.CreatedSyntheticCrashReportConfig" enum="BooleanSuccess" expires_after="2020-09-30"> + <obsolete> + Removed 09/2019 after having collected enough data. + </obsolete> <owner>eugenebut@chromium.org</owner> <owner>olivierrobin@chromium.org</owner> <summary>
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index ba6641a..e851325 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -200,6 +200,7 @@ # Benchmark: media.desktop crbug.com/1114681 [ win-laptop ] media.desktop/video.html?src=smpte_3840x2160_60fps_vp9.webm&seek [ Skip ] +crbug.com/1095610 [ win-laptop ] media.desktop/video.html?src=garden2_10s.mp4&seek [ Skip ] # Benchmark: power.desktop crbug.com/1036360 [ win7 ] power.desktop/abcnews [ Skip ] @@ -402,6 +403,7 @@ crbug.com/1100138 [ desktop ] v8.browsing_desktop/browse:tools:gmail-openconversation:2020 [ skip ] crbug.com/1100138 [ desktop ] v8.browsing_desktop/browse:tools:gmail-search:2020 [ skip ] crbug.com/1104211 [ win ] v8.browsing_desktop/browse:news:cnn:2020 [ skip ] +crbug.com/1104211 [ linux ] v8.browsing_desktop/browse:news:cnn:2020 [ skip ] crbug.com/1105592 [ desktop ] v8.browsing_desktop/browse:news:nytimes:2020 [ skip ] # Benchmark v8.browsing_desktop-future @@ -419,6 +421,7 @@ crbug.com/1100138 [ desktop ] v8.browsing_desktop-future/browse:tools:gmail-openconversation:2020 [ skip ] crbug.com/1100138 [ desktop ] v8.browsing_desktop-future/browse:tools:gmail-search:2020 [ skip ] crbug.com/1104211 [ win ] v8.browsing_desktop-future/browse:news:cnn:2020 [ skip ] +crbug.com/1104211 [ desktop ] v8.browsing_desktop-future/browse:news:cnn:2020 [ skip ] crbug.com/1105592 [ desktop ] v8.browsing_desktop-future/browse:news:nytimes:2020 [ skip ] # Benchmark: v8.browsing_mobile @@ -445,6 +448,7 @@ # Benchmark: webrtc crbug.com/1051644 [ win ] webrtc/pause_play_peerconnections [ Skip ] +crbug.com/1129497 [ win-laptop ] webrtc/multiple_peerconnections [ Skip ] ##### Perf FYI benchmarks go after here ##### # Benchmark: loading.desktop_layout_ng
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 51dbe07f..dcd30ea 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -235,7 +235,7 @@ <item id="popular_sites_fetch" added_in_milestone="62" hash_code="50755044" type="0" content_hash_code="6910083" os_list="linux,windows" file_path="components/ntp_tiles/popular_sites_impl.cc"/> <item id="port_forwarding_controller_socket" added_in_milestone="65" hash_code="95075845" type="0" content_hash_code="122163428" os_list="linux,windows" file_path="chrome/browser/devtools/device/port_forwarding_controller.cc"/> <item id="ppapi_download_request" added_in_milestone="62" hash_code="135967426" type="0" content_hash_code="110461402" os_list="linux,windows" file_path="chrome/browser/safe_browsing/download_protection/ppapi_download_request.cc"/> - <item id="predictive_prefetch" added_in_milestone="85" hash_code="72157052" type="0" content_hash_code="69511160" os_list="linux,windows" file_path="chrome/browser/predictors/prefetch_manager.cc"/> + <item id="predictive_prefetch" added_in_milestone="85" hash_code="72157052" type="0" content_hash_code="28097398" os_list="linux,windows" file_path="chrome/browser/predictors/prefetch_manager.cc"/> <item id="prefetch_download" added_in_milestone="62" hash_code="44583172" type="0" content_hash_code="21424542" os_list="linux,windows" file_path="components/offline_pages/core/prefetch/prefetch_downloader_impl.cc"/> <item id="prefetch_visuals" added_in_milestone="75" hash_code="91068704" type="0" content_hash_code="90439946" os_list="linux,windows" file_path="components/offline_pages/core/prefetch/visuals_fetch_by_url.cc"/> <item id="previews_litepage_origin_prober" added_in_milestone="78" hash_code="33703614" type="0" deprecated="2020-04-23" content_hash_code="116235355" file_path="chrome/browser/previews/previews_lite_page_redirect_url_loader.cc"/> @@ -298,6 +298,7 @@ <item id="safety_check_update_connectivity" added_in_milestone="84" hash_code="137724067" type="0" content_hash_code="30977369" os_list="linux,windows" file_path="components/safety_check/update_check_helper.cc"/> <item id="sanitized_image_source" added_in_milestone="86" hash_code="36944304" type="0" content_hash_code="39770427" os_list="linux,windows" file_path="chrome/browser/ui/webui/sanitized_image_source.cc"/> <item id="save_file_manager" added_in_milestone="62" hash_code="56275203" type="0" content_hash_code="56692339" os_list="linux,windows" file_path="content/browser/download/save_file_manager.cc"/> + <item id="sct_auditing" added_in_milestone="87" hash_code="48603483" type="0" content_hash_code="43567503" os_list="linux,windows" file_path="chrome/browser/ssl/sct_reporting_service.cc"/> <item id="sdch_dictionary_fetch" added_in_milestone="62" hash_code="47152935" type="0" deprecated="2017-09-16" content_hash_code="16764294" file_path=""/> <item id="search_suggest_service" added_in_milestone="73" hash_code="57785193" type="0" content_hash_code="132247652" os_list="linux,windows" file_path="chrome/browser/search/search_suggest/search_suggest_loader_impl.cc"/> <item id="security_key_socket" added_in_milestone="66" hash_code="31074955" type="0" content_hash_code="13741232" os_list="linux,windows" file_path="remoting/host/security_key/security_key_socket.cc"/>
diff --git a/tools/traffic_annotation/summary/grouping.xml b/tools/traffic_annotation/summary/grouping.xml index 3a35f43c..4019de3 100644 --- a/tools/traffic_annotation/summary/grouping.xml +++ b/tools/traffic_annotation/summary/grouping.xml
@@ -212,6 +212,7 @@ <traffic_annotation unique_id="safe_browsing_binary_upload_app"/> <traffic_annotation unique_id="safe_browsing_binary_upload_connector"/> <traffic_annotation unique_id="safe_browsing_realtime_url_lookup"/> + <traffic_annotation unique_id="sct_auditing"/> <traffic_annotation unique_id="unwanted_software_report"/> <traffic_annotation unique_id="ppapi_download_request"/> </sender>
diff --git a/ui/accelerated_widget_mac/accelerated_widget_mac.mm b/ui/accelerated_widget_mac/accelerated_widget_mac.mm index 7bd2567..6a50953 100644 --- a/ui/accelerated_widget_mac/accelerated_widget_mac.mm +++ b/ui/accelerated_widget_mac/accelerated_widget_mac.mm
@@ -9,6 +9,7 @@ #include "base/lazy_instance.h" #include "base/mac/mac_util.h" #include "ui/gfx/geometry/dip_util.h" +#include "ui/gfx/geometry/size_conversions.h" namespace ui { namespace { @@ -56,8 +57,9 @@ const gfx::Size& dip_size) const { if (!last_ca_layer_params_valid_) return false; - gfx::Size last_swap_size_dip = gfx::ConvertSizeToDIP( - last_ca_layer_params_.scale_factor, last_ca_layer_params_.pixel_size); + // TODO(danakj): We should avoid lossy conversions to integer DIPs. + gfx::Size last_swap_size_dip = gfx::ToFlooredSize(gfx::ConvertSizeToDips( + last_ca_layer_params_.pixel_size, last_ca_layer_params_.scale_factor)); return last_swap_size_dip == dip_size; }
diff --git a/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm b/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm index b2ca09f8..382b23ab 100644 --- a/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm +++ b/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm
@@ -11,6 +11,7 @@ #include "third_party/skia/include/core/SkColor.h" #include "ui/accelerated_widget_mac/ca_renderer_layer_tree.h" #include "ui/gfx/geometry/dip_util.h" +#include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/mac/io_surface.h" #include "ui/gl/ca_renderer_layer_params.h" #include "ui/gl/gl_image_io_surface.h" @@ -459,8 +460,8 @@ EXPECT_EQ(gfx::ConvertRectToDIP(properties.scale_factor, gfx::Rect(properties.clip_rect.size())), gfx::Rect([clip_and_sorting_layer bounds])); - EXPECT_EQ(gfx::ConvertPointToDIP(properties.scale_factor, - properties.clip_rect.origin()), + EXPECT_EQ(gfx::ToFlooredPoint(gfx::ConvertPointToDips( + properties.clip_rect.origin(), properties.scale_factor)), gfx::Point([clip_and_sorting_layer position])); EXPECT_EQ(-properties.clip_rect.origin().x() / properties.scale_factor, [clip_and_sorting_layer sublayerTransform].m41); @@ -480,8 +481,8 @@ [content_layer contents]); EXPECT_EQ(properties.contents_rect, gfx::RectF([content_layer contentsRect])); - EXPECT_EQ(gfx::ConvertPointToDIP(properties.scale_factor, - properties.rect.origin()), + EXPECT_EQ(gfx::ToFlooredPoint(gfx::ConvertPointToDips( + properties.rect.origin(), properties.scale_factor)), gfx::Point([content_layer position])); EXPECT_EQ(gfx::ConvertRectToDIP(properties.scale_factor, gfx::Rect(properties.rect.size())),
diff --git a/ui/accelerated_widget_mac/display_ca_layer_tree.mm b/ui/accelerated_widget_mac/display_ca_layer_tree.mm index 0db8f3e..a5593432 100644 --- a/ui/accelerated_widget_mac/display_ca_layer_tree.mm +++ b/ui/accelerated_widget_mac/display_ca_layer_tree.mm
@@ -15,6 +15,7 @@ #include "ui/base/cocoa/animation_utils.h" #include "ui/base/cocoa/remote_layer_api.h" #include "ui/gfx/geometry/dip_util.h" +#include "ui/gfx/geometry/size_conversions.h" @interface CALayer (PrivateAPI) - (void)setContentsChanged; @@ -144,7 +145,10 @@ [io_surface_layer_ setContentsChanged]; else [io_surface_layer_ setContents:new_contents]; - gfx::Size bounds_dip = gfx::ConvertSizeToDIP(scale_factor, pixel_size); + // TODO(danakj): We should avoid lossy conversions to integer DIPs. The OS + // wants a floating point value. + gfx::Size bounds_dip = + gfx::ToFlooredSize(gfx::ConvertSizeToDips(pixel_size, scale_factor)); [io_surface_layer_ setBounds:CGRectMake(0, 0, bounds_dip.width(), bounds_dip.height())]; if ([io_surface_layer_ contentsScale] != scale_factor)
diff --git a/ui/accessibility/PRESUBMIT.py b/ui/accessibility/PRESUBMIT.py index d71a8f9..3d104cc9 100644 --- a/ui/accessibility/PRESUBMIT.py +++ b/ui/accessibility/PRESUBMIT.py
@@ -150,11 +150,13 @@ CheckMatchingEnum(ax_enums, 'MarkerType', automation_enums, 'MarkerType', errs, output_api) CheckMatchingEnum(ax_enums, 'Command', automation_enums, - 'EventCommandType', errs, output_api) + 'IntentCommandType', errs, output_api) + CheckMatchingEnum(ax_enums, 'InputEventType', automation_enums, + 'IntentInputEventType', errs, output_api) CheckMatchingEnum(ax_enums, 'TextBoundary', automation_enums, - 'EventTextBoundaryType', errs, output_api) + 'IntentTextBoundaryType', errs, output_api) CheckMatchingEnum(ax_enums, 'MoveDirection', automation_enums, - 'EventMoveDirectionType', errs, output_api) + 'IntentMoveDirectionType', errs, output_api) CheckMatchingEnum(ax_enums, 'SortDirection', automation_enums, 'SortDirectionType', errs, output_api) return errs
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc index f61025e91..5e3e186 100644 --- a/ui/accessibility/ax_enum_util.cc +++ b/ui/accessibility/ax_enum_util.cc
@@ -1100,10 +1100,12 @@ const char* ToString(ax::mojom::MoveDirection move_direction) { switch (move_direction) { - case ax::mojom::MoveDirection::kForward: - return "forward"; + case ax::mojom::MoveDirection::kNone: + return "none"; case ax::mojom::MoveDirection::kBackward: return "backward"; + case ax::mojom::MoveDirection::kForward: + return "forward"; } return ""; @@ -1111,10 +1113,10 @@ const char* ToString(ax::mojom::Command command) { switch (command) { + case ax::mojom::Command::kNone: + return "none"; case ax::mojom::Command::kClearSelection: return "clearSelection"; - case ax::mojom::Command::kCut: - return "cut"; case ax::mojom::Command::kDelete: return "delete"; case ax::mojom::Command::kDictate: @@ -1123,20 +1125,101 @@ return "extendSelection"; case ax::mojom::Command::kFormat: return "format"; + case ax::mojom::Command::kHistory: + return "history"; case ax::mojom::Command::kInsert: return "insert"; case ax::mojom::Command::kMarker: return "marker"; case ax::mojom::Command::kMoveSelection: return "moveSelection"; - case ax::mojom::Command::kPaste: - return "paste"; - case ax::mojom::Command::kReplace: - return "replace"; case ax::mojom::Command::kSetSelection: return "setSelection"; - case ax::mojom::Command::kType: - return "type"; + } + + return ""; +} + +const char* ToString(ax::mojom::InputEventType input_event_type) { + switch (input_event_type) { + case ax::mojom::InputEventType::kNone: + return "none"; + case ax::mojom::InputEventType::kInsertText: + return "insertText"; + case ax::mojom::InputEventType::kInsertLineBreak: + return "insertLineBreak"; + case ax::mojom::InputEventType::kInsertParagraph: + return "insertParagraph"; + case ax::mojom::InputEventType::kInsertOrderedList: + return "insertOrderedList"; + case ax::mojom::InputEventType::kInsertUnorderedList: + return "insertUnorderedList"; + case ax::mojom::InputEventType::kInsertHorizontalRule: + return "insertHorizontalRule"; + case ax::mojom::InputEventType::kInsertFromPaste: + return "insertFromPaste"; + case ax::mojom::InputEventType::kInsertFromDrop: + return "insertFromDrop"; + case ax::mojom::InputEventType::kInsertFromYank: + return "insertFromYank"; + case ax::mojom::InputEventType::kInsertTranspose: + return "insertTranspose"; + case ax::mojom::InputEventType::kInsertReplacementText: + return "insertReplacementText"; + case ax::mojom::InputEventType::kInsertCompositionText: + return "insertCompositionText"; + case ax::mojom::InputEventType::kDeleteWordBackward: + return "deleteWordBackward"; + case ax::mojom::InputEventType::kDeleteWordForward: + return "deleteWordForward"; + case ax::mojom::InputEventType::kDeleteSoftLineBackward: + return "deleteSoftLineBackward"; + case ax::mojom::InputEventType::kDeleteSoftLineForward: + return "deleteSoftLineForward"; + case ax::mojom::InputEventType::kDeleteHardLineBackward: + return "deleteHardLineBackward"; + case ax::mojom::InputEventType::kDeleteHardLineForward: + return "deleteHardLineForward"; + case ax::mojom::InputEventType::kDeleteContentBackward: + return "deleteContentBackward"; + case ax::mojom::InputEventType::kDeleteContentForward: + return "deleteContentForward"; + case ax::mojom::InputEventType::kDeleteByCut: + return "deleteByCut"; + case ax::mojom::InputEventType::kDeleteByDrag: + return "deleteByDrag"; + case ax::mojom::InputEventType::kHistoryUndo: + return "historyUndo"; + case ax::mojom::InputEventType::kHistoryRedo: + return "historyRedo"; + case ax::mojom::InputEventType::kFormatBold: + return "formatBold"; + case ax::mojom::InputEventType::kFormatItalic: + return "formatItalic"; + case ax::mojom::InputEventType::kFormatUnderline: + return "formatUnderline"; + case ax::mojom::InputEventType::kFormatStrikeThrough: + return "formatStrikeThrough"; + case ax::mojom::InputEventType::kFormatSuperscript: + return "formatSuperscript"; + case ax::mojom::InputEventType::kFormatSubscript: + return "formatSubscript"; + case ax::mojom::InputEventType::kFormatJustifyCenter: + return "formatJustifyCenter"; + case ax::mojom::InputEventType::kFormatJustifyFull: + return "formatJustifyFull"; + case ax::mojom::InputEventType::kFormatJustifyRight: + return "formatJustifyRight"; + case ax::mojom::InputEventType::kFormatJustifyLeft: + return "formatJustifyLeft"; + case ax::mojom::InputEventType::kFormatIndent: + return "formatIndent"; + case ax::mojom::InputEventType::kFormatOutdent: + return "formatOutdent"; + case ax::mojom::InputEventType::kFormatRemove: + return "formatRemove"; + case ax::mojom::InputEventType::kFormatSetBlockTextDirection: + return "formatSetBlockTextDirection"; } return ""; @@ -1144,6 +1227,8 @@ const char* ToString(ax::mojom::TextBoundary text_boundary) { switch (text_boundary) { + case ax::mojom::TextBoundary::kNone: + return "none"; case ax::mojom::TextBoundary::kCharacter: return "character"; case ax::mojom::TextBoundary::kFormat: @@ -1187,25 +1272,6 @@ return ""; } -const char* ToString(ax::mojom::TextDecorationStyle text_decoration_style) { - switch (text_decoration_style) { - case ax::mojom::TextDecorationStyle::kNone: - return "none"; - case ax::mojom::TextDecorationStyle::kSolid: - return "solid"; - case ax::mojom::TextDecorationStyle::kDashed: - return "dashed"; - case ax::mojom::TextDecorationStyle::kDotted: - return "dotted"; - case ax::mojom::TextDecorationStyle::kDouble: - return "double"; - case ax::mojom::TextDecorationStyle::kWavy: - return "wavy"; - } - - return ""; -} - const char* ToString(ax::mojom::TextAlign text_align) { switch (text_align) { case ax::mojom::TextAlign::kNone: @@ -1223,8 +1289,8 @@ return ""; } -const char* ToString(ax::mojom::WritingDirection text_direction) { - switch (text_direction) { +const char* ToString(ax::mojom::WritingDirection writing_direction) { + switch (writing_direction) { case ax::mojom::WritingDirection::kNone: return "none"; case ax::mojom::WritingDirection::kLtr: @@ -1272,6 +1338,25 @@ return ""; } +const char* ToString(ax::mojom::TextDecorationStyle text_decoration_style) { + switch (text_decoration_style) { + case ax::mojom::TextDecorationStyle::kNone: + return "none"; + case ax::mojom::TextDecorationStyle::kSolid: + return "solid"; + case ax::mojom::TextDecorationStyle::kDashed: + return "dashed"; + case ax::mojom::TextDecorationStyle::kDotted: + return "dotted"; + case ax::mojom::TextDecorationStyle::kDouble: + return "double"; + case ax::mojom::TextDecorationStyle::kWavy: + return "wavy"; + } + + return ""; +} + const char* ToString(ax::mojom::AriaCurrentState aria_current_state) { switch (aria_current_state) { case ax::mojom::AriaCurrentState::kNone:
diff --git a/ui/accessibility/ax_enum_util.h b/ui/accessibility/ax_enum_util.h index 2c48f29..aa6caa9 100644 --- a/ui/accessibility/ax_enum_util.h +++ b/ui/accessibility/ax_enum_util.h
@@ -76,18 +76,18 @@ // ax::mojom::Command AX_BASE_EXPORT const char* ToString(ax::mojom::Command command); +// ax::mojom::InputEventType +AX_BASE_EXPORT const char* ToString(ax::mojom::InputEventType input_event_type); + // ax::mojom::TextBoundary AX_BASE_EXPORT const char* ToString(ax::mojom::TextBoundary text_boundary); -// ax:mojom::TextDecorationStyle -AX_BASE_EXPORT const char* ToString( - ax::mojom::TextDecorationStyle text_decoration_style); - // ax::mojom::TextAlign AX_BASE_EXPORT const char* ToString(ax::mojom::TextAlign text_align); // ax::mojom::WritingDirection -AX_BASE_EXPORT const char* ToString(ax::mojom::WritingDirection text_direction); +AX_BASE_EXPORT const char* ToString( + ax::mojom::WritingDirection writing_direction); // ax::mojom::TextPosition AX_BASE_EXPORT const char* ToString(ax::mojom::TextPosition text_position); @@ -95,6 +95,10 @@ // ax::mojom::TextStyle AX_BASE_EXPORT const char* ToString(ax::mojom::TextStyle text_style); +// ax:mojom::TextDecorationStyle +AX_BASE_EXPORT const char* ToString( + ax::mojom::TextDecorationStyle text_decoration_style); + // ax::mojom::AriaCurrentState AX_BASE_EXPORT const char* ToString( ax::mojom::AriaCurrentState aria_current_state);
diff --git a/ui/accessibility/ax_enum_util_unittest.cc b/ui/accessibility/ax_enum_util_unittest.cc index c8a91abb..34be7b3 100644 --- a/ui/accessibility/ax_enum_util_unittest.cc +++ b/ui/accessibility/ax_enum_util_unittest.cc
@@ -164,15 +164,19 @@ TestEnumStringConversion<ax::mojom::Command>(); } -TEST(AXEnumUtilTest, TextAlign) { - TestEnumStringConversion<ax::mojom::TextAlign>(); +TEST(AXEnumUtilTest, InputEventType) { + TestEnumStringConversion<ax::mojom::InputEventType>(); } TEST(AXEnumUtilTest, TextBoundary) { TestEnumStringConversion<ax::mojom::TextBoundary>(); } -TEST(AXEnumUtilTest, TextDirection) { +TEST(AXEnumUtilTest, TextAlign) { + TestEnumStringConversion<ax::mojom::TextAlign>(); +} + +TEST(AXEnumUtilTest, WritingDirection) { TestEnumStringConversion<ax::mojom::WritingDirection>(); }
diff --git a/ui/accessibility/ax_enums.mojom b/ui/accessibility/ax_enums.mojom index 3b3c56d..bb2175f5 100644 --- a/ui/accessibility/ax_enums.mojom +++ b/ui/accessibility/ax_enums.mojom
@@ -847,28 +847,81 @@ // forward movement will always move to the next node in depth-first pre-order // traversal. enum MoveDirection { - kForward, + kNone, kBackward, - kNone = kForward + kForward }; -// Describes the edit or selection command that resulted in a selection or a -// text changed event. +// Describes the edit or selection command that resulted in a selection, a text +// changed or a text attributes changed event. +// +// An edit command, such as "kInsert" or "kDelete" is further described by its +// "InputEvent" - see the relevant enum in this file. +// A selection command may be further described by its "TextBoundary" and +// "MoveDirection" - see the relevant enums in this file. enum Command { + kNone, kClearSelection, - kCut, kDelete, kDictate, kExtendSelection, // The existing selection has been extended or shrunk. - kFormat, // The text attributes, such as font size, have changed. + kFormat, // Some text attributes, such as font weight, have changed. + kHistory, // An undo or a redo operation has been performed. kInsert, - kMarker, // A document marker has been added or removed. + kMarker, // Document markers have been added or removed. kMoveSelection, // The selection has been moved by a specific granularity. - kPaste, - kReplace, - kSetSelection, // A completely new selection has been set. - kType, - kNone = kType + kSetSelection // A completely new selection has been set. +}; + +// Describes an edit command in more detail. +// +// Please keep in sync with the following specification and file: +// https://w3c.github.io/input-events/#h-interface-inputevent-attributes +// //third_party/blink/renderer/core/events/input_event.h +enum InputEventType { + kNone, + // Insertion. + kInsertText, + kInsertLineBreak, + kInsertParagraph, + kInsertOrderedList, + kInsertUnorderedList, + kInsertHorizontalRule, + kInsertFromPaste, + kInsertFromDrop, + kInsertFromYank, + kInsertTranspose, + kInsertReplacementText, + kInsertCompositionText, + // Deletion. + kDeleteWordBackward, + kDeleteWordForward, + kDeleteSoftLineBackward, + kDeleteSoftLineForward, + kDeleteHardLineBackward, + kDeleteHardLineForward, + kDeleteContentBackward, + kDeleteContentForward, + kDeleteByCut, + kDeleteByDrag, + // History. + kHistoryUndo, + kHistoryRedo, + // Formatting. + kFormatBold, + kFormatItalic, + kFormatUnderline, + kFormatStrikeThrough, + kFormatSuperscript, + kFormatSubscript, + kFormatJustifyCenter, + kFormatJustifyFull, + kFormatJustifyRight, + kFormatJustifyLeft, + kFormatIndent, + kFormatOutdent, + kFormatRemove, + kFormatSetBlockTextDirection }; // Defines a set of text boundaries in the accessibility tree. @@ -883,6 +936,7 @@ // // TODO(nektar): Split TextBoundary into TextUnit and TextBoundary. enum TextBoundary { + kNone, kCharacter, kFormat, kLineEnd, @@ -901,8 +955,7 @@ kWebPage, kWordEnd, kWordStart, - kWordStartOrEnd, - kNone = kObject + kWordStartOrEnd }; // Types of text alignment according to the IAccessible2 Object Attributes spec.
diff --git a/ui/accessibility/ax_event_intent.cc b/ui/accessibility/ax_event_intent.cc index cb167a5..e4b89af 100644 --- a/ui/accessibility/ax_event_intent.cc +++ b/ui/accessibility/ax_event_intent.cc
@@ -10,6 +10,12 @@ AXEventIntent::AXEventIntent() = default; +AXEventIntent::AXEventIntent(ax::mojom::Command command) : command(command) {} + +AXEventIntent::AXEventIntent(ax::mojom::Command command, + ax::mojom::InputEventType input_event_type) + : command(command), input_event_type(input_event_type) {} + AXEventIntent::AXEventIntent(ax::mojom::Command command, ax::mojom::TextBoundary text_boundary, ax::mojom::MoveDirection move_direction) @@ -24,7 +30,8 @@ AXEventIntent& AXEventIntent::operator=(const AXEventIntent& intent) = default; bool operator==(const AXEventIntent& a, const AXEventIntent& b) { - return a.command == b.command && a.text_boundary == b.text_boundary && + return a.command == b.command && a.input_event_type == b.input_event_type && + a.text_boundary == b.text_boundary && a.move_direction == b.move_direction; } @@ -34,7 +41,8 @@ std::string AXEventIntent::ToString() const { return std::string("AXEventIntent(") + ui::ToString(command) + ',' + - ui::ToString(text_boundary) + ',' + ui::ToString(move_direction) + ')'; + ui::ToString(input_event_type) + ',' + ui::ToString(text_boundary) + + ',' + ui::ToString(move_direction) + ')'; } } // namespace ui
diff --git a/ui/accessibility/ax_event_intent.h b/ui/accessibility/ax_event_intent.h index 6734c7e4..ca8fc73 100644 --- a/ui/accessibility/ax_event_intent.h +++ b/ui/accessibility/ax_event_intent.h
@@ -17,10 +17,27 @@ // selection could have been extended to the beginning of the previous word, or // it could have been moved to the end of the next line. struct AX_BASE_EXPORT AXEventIntent final { + // Constructs an empty event intent. AXEventIntent(); + + // Constructs an event intent which contains only a command without any other + // arguments. This is used e.g. by the selection changed event when the + // current selection is cleared. + explicit AXEventIntent(ax::mojom::Command command); + + // Constructs an editing event intent; which is primarily attached to a text + // changed or a text attributes changed event. Note that for such intents both + // the "text_boundary" and "move_direction" members are set to "kNone". + AXEventIntent(ax::mojom::Command command, + ax::mojom::InputEventType input_event_type); + + // Constructs a selection event intent; which is attached to a selection + // changed event. Note that for such intents the "input_event_type" member is + // set to "kNone". AXEventIntent(ax::mojom::Command command, ax::mojom::TextBoundary text_boundary, ax::mojom::MoveDirection move_direction); + virtual ~AXEventIntent(); AXEventIntent(const AXEventIntent& intent); AXEventIntent& operator=(const AXEventIntent& intent); @@ -30,10 +47,11 @@ friend AX_BASE_EXPORT bool operator!=(const AXEventIntent& a, const AXEventIntent& b); - ax::mojom::Command command = ax::mojom::Command::kType; + ax::mojom::Command command = ax::mojom::Command::kNone; + ax::mojom::InputEventType input_event_type = ax::mojom::InputEventType::kNone; // TODO(nektar): Split TextBoundary into TextUnit and TextBoundary. - ax::mojom::TextBoundary text_boundary = ax::mojom::TextBoundary::kCharacter; - ax::mojom::MoveDirection move_direction = ax::mojom::MoveDirection::kForward; + ax::mojom::TextBoundary text_boundary = ax::mojom::TextBoundary::kNone; + ax::mojom::MoveDirection move_direction = ax::mojom::MoveDirection::kNone; // Returns a string representation of this data, for debugging. std::string ToString() const;
diff --git a/ui/accessibility/ax_param_traits_macros.h b/ui/accessibility/ax_param_traits_macros.h index b545df34b..c653f646 100644 --- a/ui/accessibility/ax_param_traits_macros.h +++ b/ui/accessibility/ax_param_traits_macros.h
@@ -38,6 +38,8 @@ ax::mojom::TextAffinity::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::EventFrom, ax::mojom::EventFrom::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::Command, ax::mojom::Command::kMaxValue) +IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::InputEventType, + ax::mojom::InputEventType::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::TextBoundary, ax::mojom::TextBoundary::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::MoveDirection, @@ -59,6 +61,7 @@ IPC_STRUCT_TRAITS_BEGIN(ui::AXEventIntent) IPC_STRUCT_TRAITS_MEMBER(command) + IPC_STRUCT_TRAITS_MEMBER(input_event_type) IPC_STRUCT_TRAITS_MEMBER(text_boundary) IPC_STRUCT_TRAITS_MEMBER(move_direction) IPC_STRUCT_TRAITS_END()
diff --git a/ui/accessibility/ax_position.h b/ui/accessibility/ax_position.h index e968794..a2f7952 100644 --- a/ui/accessibility/ax_position.h +++ b/ui/accessibility/ax_position.h
@@ -1460,8 +1460,15 @@ AXBoundaryBehavior boundary_behavior) const { AXPositionInstance resulting_position = CreateNullPosition(); switch (boundary) { + case ax::mojom::TextBoundary::kNone: + NOTREACHED(); + break; + case ax::mojom::TextBoundary::kCharacter: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousCharacterPosition(boundary_behavior); @@ -1474,6 +1481,9 @@ case ax::mojom::TextBoundary::kFormat: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousFormatStartPosition(boundary_behavior); @@ -1486,6 +1496,9 @@ case ax::mojom::TextBoundary::kLineEnd: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousLineEndPosition(boundary_behavior); @@ -1498,6 +1511,9 @@ case ax::mojom::TextBoundary::kLineStart: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousLineStartPosition(boundary_behavior); @@ -1510,6 +1526,9 @@ case ax::mojom::TextBoundary::kLineStartOrEnd: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousLineStartPosition(boundary_behavior); @@ -1522,6 +1541,9 @@ case ax::mojom::TextBoundary::kObject: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePositionAtStartOfAnchor(); break; @@ -1533,6 +1555,9 @@ case ax::mojom::TextBoundary::kPageEnd: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousPageEndPosition(boundary_behavior); @@ -1545,6 +1570,9 @@ case ax::mojom::TextBoundary::kPageStart: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousPageStartPosition(boundary_behavior); @@ -1557,6 +1585,9 @@ case ax::mojom::TextBoundary::kPageStartOrEnd: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousPageStartPosition(boundary_behavior); @@ -1569,6 +1600,9 @@ case ax::mojom::TextBoundary::kParagraphEnd: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousParagraphEndPosition(boundary_behavior); @@ -1582,6 +1616,9 @@ case ax::mojom::TextBoundary::kParagraphStart: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousParagraphStartPosition(boundary_behavior); @@ -1595,6 +1632,9 @@ case ax::mojom::TextBoundary::kParagraphStartOrEnd: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousParagraphStartPosition(boundary_behavior); @@ -1623,6 +1663,9 @@ << "We can't reach the start of the document if we are disallowed " "from crossing boundaries."; switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePositionAtStartOfDocument(); break; @@ -1634,6 +1677,9 @@ case ax::mojom::TextBoundary::kWordEnd: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousWordEndPosition(boundary_behavior); @@ -1646,6 +1692,9 @@ case ax::mojom::TextBoundary::kWordStart: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousWordStartPosition(boundary_behavior); @@ -1658,6 +1707,9 @@ case ax::mojom::TextBoundary::kWordStartOrEnd: switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + break; case ax::mojom::MoveDirection::kBackward: resulting_position = CreatePreviousWordStartPosition(boundary_behavior); @@ -1668,6 +1720,7 @@ } break; } + return resulting_position; } @@ -1909,6 +1962,9 @@ // position to be before or after the child, based on the direction of // motion, and also reset the affinity. switch (move_direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return CreateNullPosition(); case ax::mojom::MoveDirection::kBackward: // Keep the offset to be right before the embedded object // character. @@ -2607,27 +2663,36 @@ while (!at_start_condition.Run(text_position)) { AXPositionInstance next_position; - if (move_direction == ax::mojom::MoveDirection::kForward) { - next_position = text_position->CreateNextLeafTextPosition(); - } else { - if (text_position->AtStartOfAnchor()) { - next_position = text_position->CreatePreviousLeafTextPosition(); - } else { - text_position = text_position->CreatePositionAtStartOfAnchor(); - DCHECK(!text_position->IsNullPosition()); - continue; - } + switch (move_direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return CreateNullPosition(); + case ax::mojom::MoveDirection::kBackward: + if (text_position->AtStartOfAnchor()) { + next_position = text_position->CreatePreviousLeafTextPosition(); + } else { + text_position = text_position->CreatePositionAtStartOfAnchor(); + DCHECK(!text_position->IsNullPosition()); + continue; + } + break; + case ax::mojom::MoveDirection::kForward: + next_position = text_position->CreateNextLeafTextPosition(); + break; } if (next_position->IsNullPosition()) { if (boundary_behavior == AXBoundaryBehavior::StopAtAnchorBoundary) { switch (move_direction) { - case ax::mojom::MoveDirection::kForward: - return CreatePositionAtEndOfAnchor()->AsUnignoredPosition( - AXPositionAdjustmentBehavior::kMoveForward); + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return CreateNullPosition(); case ax::mojom::MoveDirection::kBackward: return CreatePositionAtStartOfAnchor()->AsUnignoredPosition( AXPositionAdjustmentBehavior::kMoveBackward); + case ax::mojom::MoveDirection::kForward: + return CreatePositionAtEndOfAnchor()->AsUnignoredPosition( + AXPositionAdjustmentBehavior::kMoveForward); } } @@ -2636,12 +2701,15 @@ // We can't simply return the following position; break and after // this loop we'll try to do some adjustments to text_position. switch (move_direction) { - case ax::mojom::MoveDirection::kForward: - text_position = text_position->CreatePositionAtEndOfAnchor(); - break; + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return CreateNullPosition(); case ax::mojom::MoveDirection::kBackward: text_position = text_position->CreatePositionAtStartOfAnchor(); break; + case ax::mojom::MoveDirection::kForward: + text_position = text_position->CreatePositionAtEndOfAnchor(); + break; } break; @@ -2667,12 +2735,15 @@ text_position->CreateAncestorPosition(common_anchor, move_direction); } else if (boundary_behavior == AXBoundaryBehavior::StopAtAnchorBoundary) { switch (move_direction) { - case ax::mojom::MoveDirection::kForward: - return CreatePositionAtEndOfAnchor()->AsUnignoredPosition( - AXPositionAdjustmentBehavior::kMoveForward); + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return CreateNullPosition(); case ax::mojom::MoveDirection::kBackward: return CreatePositionAtStartOfAnchor()->AsUnignoredPosition( AXPositionAdjustmentBehavior::kMoveBackward); + case ax::mojom::MoveDirection::kForward: + return CreatePositionAtEndOfAnchor()->AsUnignoredPosition( + AXPositionAdjustmentBehavior::kMoveForward); } } @@ -2728,28 +2799,37 @@ while (!at_end_condition.Run(text_position)) { AXPositionInstance next_position; - if (move_direction == ax::mojom::MoveDirection::kForward) { - if (text_position->AtEndOfAnchor()) { - next_position = text_position->CreateNextLeafTextPosition(); - } else { - text_position = text_position->CreatePositionAtEndOfAnchor(); - DCHECK(!text_position->IsNullPosition()); - continue; - } - } else { - next_position = text_position->CreatePreviousLeafTextPosition() - ->CreatePositionAtEndOfAnchor(); + switch (move_direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return CreateNullPosition(); + case ax::mojom::MoveDirection::kBackward: + next_position = text_position->CreatePreviousLeafTextPosition() + ->CreatePositionAtEndOfAnchor(); + break; + case ax::mojom::MoveDirection::kForward: + if (text_position->AtEndOfAnchor()) { + next_position = text_position->CreateNextLeafTextPosition(); + } else { + text_position = text_position->CreatePositionAtEndOfAnchor(); + DCHECK(!text_position->IsNullPosition()); + continue; + } + break; } if (next_position->IsNullPosition()) { if (boundary_behavior == AXBoundaryBehavior::StopAtAnchorBoundary) { switch (move_direction) { - case ax::mojom::MoveDirection::kForward: - return CreatePositionAtEndOfAnchor()->AsUnignoredPosition( - AXPositionAdjustmentBehavior::kMoveForward); + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return CreateNullPosition(); case ax::mojom::MoveDirection::kBackward: return CreatePositionAtStartOfAnchor()->AsUnignoredPosition( AXPositionAdjustmentBehavior::kMoveBackward); + case ax::mojom::MoveDirection::kForward: + return CreatePositionAtEndOfAnchor()->AsUnignoredPosition( + AXPositionAdjustmentBehavior::kMoveForward); } } @@ -2758,12 +2838,15 @@ // We can't simply return the following position; break and after // this loop we'll try to do some adjustments to text_position. switch (move_direction) { - case ax::mojom::MoveDirection::kForward: - text_position = text_position->CreatePositionAtEndOfAnchor(); - break; + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return CreateNullPosition(); case ax::mojom::MoveDirection::kBackward: text_position = text_position->CreatePositionAtStartOfAnchor(); break; + case ax::mojom::MoveDirection::kForward: + text_position = text_position->CreatePositionAtEndOfAnchor(); + break; } break; @@ -2789,12 +2872,15 @@ text_position->CreateAncestorPosition(common_anchor, move_direction); } else if (boundary_behavior == AXBoundaryBehavior::StopAtAnchorBoundary) { switch (move_direction) { - case ax::mojom::MoveDirection::kForward: - return CreatePositionAtEndOfAnchor()->AsUnignoredPosition( - AXPositionAdjustmentBehavior::kMoveForward); + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return CreateNullPosition(); case ax::mojom::MoveDirection::kBackward: return CreatePositionAtStartOfAnchor()->AsUnignoredPosition( AXPositionAdjustmentBehavior::kMoveBackward); + case ax::mojom::MoveDirection::kForward: + return CreatePositionAtEndOfAnchor()->AsUnignoredPosition( + AXPositionAdjustmentBehavior::kMoveForward); } } @@ -3810,10 +3896,13 @@ static AXPositionAdjustmentBehavior AdjustmentBehaviorFromBoundaryDirection( ax::mojom::MoveDirection move_direction) { switch (move_direction) { - case ax::mojom::MoveDirection::kForward: + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); return AXPositionAdjustmentBehavior::kMoveForward; case ax::mojom::MoveDirection::kBackward: return AXPositionAdjustmentBehavior::kMoveBackward; + case ax::mojom::MoveDirection::kForward: + return AXPositionAdjustmentBehavior::kMoveForward; } } @@ -3866,17 +3955,9 @@ return text_position; switch (move_direction) { - case ax::mojom::MoveDirection::kForward: { - const auto offsets_iterator = - std::upper_bound(boundary_offsets.begin(), boundary_offsets.end(), - int32_t{text_position->text_offset_}); - // If there is no next offset, the current offset should be unchanged. - if (offsets_iterator < boundary_offsets.end()) { - text_position->text_offset_ = int{*offsets_iterator}; - text_position->affinity_ = ax::mojom::TextAffinity::kDownstream; - } - break; - } + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return CreateNullPosition(); case ax::mojom::MoveDirection::kBackward: { auto offsets_iterator = std::lower_bound(boundary_offsets.begin(), boundary_offsets.end(), @@ -3893,6 +3974,17 @@ } break; } + case ax::mojom::MoveDirection::kForward: { + const auto offsets_iterator = + std::upper_bound(boundary_offsets.begin(), boundary_offsets.end(), + int32_t{text_position->text_offset_}); + // If there is no next offset, the current offset should be unchanged. + if (offsets_iterator < boundary_offsets.end()) { + text_position->text_offset_ = int{*offsets_iterator}; + text_position->affinity_ = ax::mojom::TextAffinity::kDownstream; + } + break; + } } return text_position; @@ -3915,14 +4007,9 @@ const std::vector<int32_t> boundary_offsets = get_offsets.Run(text_position); switch (move_direction) { - case ax::mojom::MoveDirection::kForward: - if (boundary_offsets.empty()) { - return text_position->CreatePositionAtEndOfAnchor(); - } else { - text_position->text_offset_ = int{boundary_offsets[0]}; - return text_position; - } - break; + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return CreateNullPosition(); case ax::mojom::MoveDirection::kBackward: if (boundary_offsets.empty()) { return text_position->CreatePositionAtStartOfAnchor(); @@ -3932,6 +4019,14 @@ return text_position; } break; + case ax::mojom::MoveDirection::kForward: + if (boundary_offsets.empty()) { + return text_position->CreatePositionAtEndOfAnchor(); + } else { + text_position->text_offset_ = int{boundary_offsets[0]}; + return text_position; + } + break; } } @@ -3954,12 +4049,29 @@ // IMPORTANT: This method basically moves the given position one character // forward/backward, but it could end up at the middle of a grapheme cluster, // so it shouldn't be used to move by ax::mojom::TextBoundary::kCharacter (for - // such purpose use Create[Next|Previous]CharacterPosition instead). + // such a purpose use Create[Next|Previous]CharacterPosition instead). AXPositionInstance CreateAdjacentLeafTextPosition( ax::mojom::MoveDirection move_direction) const { AXPositionInstance text_position = AsLeafTextPosition(); switch (move_direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return CreateNullPosition(); + case ax::mojom::MoveDirection::kBackward: + // If we are at a text offset greater than 0, we will simply decrease + // the offset by one; otherwise, create a position at the end of the + // previous leaf node with non-empty text and decrease its offset. + // + // Same as the comment above, using AtStartOfAnchor is enough to skip + // empty text nodes that are equivalent to the initial position. + while (text_position->AtStartOfAnchor()) { + text_position = text_position->CreatePreviousLeafTextPosition() + ->CreatePositionAtEndOfAnchor(); + } + if (!text_position->IsNullPosition()) + --text_position->text_offset_; + break; case ax::mojom::MoveDirection::kForward: // If we are at a text offset less than MaxTextOffset, we will simply // increase the offset by one; otherwise, create a position at the start @@ -3976,20 +4088,6 @@ if (!text_position->IsNullPosition()) ++text_position->text_offset_; break; - case ax::mojom::MoveDirection::kBackward: - // If we are at a text offset greater than 0, we will simply decrease - // the offset by one; otherwise, create a position at the end of the - // previous leaf node with non-empty text and decrease its offset. - // - // Same as the comment above, using AtStartOfAnchor is enough to skip - // empty text nodes that are equivalent to the initial position. - while (text_position->AtStartOfAnchor()) { - text_position = text_position->CreatePreviousLeafTextPosition() - ->CreatePositionAtEndOfAnchor(); - } - if (!text_position->IsNullPosition()) - --text_position->text_offset_; - break; } DCHECK(text_position->IsValid());
diff --git a/ui/accessibility/ax_text_utils.cc b/ui/accessibility/ax_text_utils.cc index bda3a61..c48dd61 100644 --- a/ui/accessibility/ax_text_utils.cc +++ b/ui/accessibility/ax_text_utils.cc
@@ -53,8 +53,10 @@ size_t start_offset, ax::mojom::MoveDirection direction, ax::mojom::TextAffinity affinity) { + DCHECK_NE(boundary, ax::mojom::TextBoundary::kNone); size_t text_size = text.size(); DCHECK_LE(start_offset, text_size); + DCHECK_NE(direction, ax::mojom::MoveDirection::kNone); base::i18n::BreakIterator::BreakType break_type = ICUBreakTypeForBoundaryType(boundary); @@ -123,6 +125,7 @@ if (break_iter.IsStartOfWord(result)) { // If we are searching forward and we are still at the start offset, // we need to find the next word. + DCHECK_NE(direction, ax::mojom::MoveDirection::kNone); if (direction == ax::mojom::MoveDirection::kBackward || result != start_offset) return result; @@ -132,12 +135,14 @@ if (break_iter.IsStartOfWord(result)) { // If we are searching forward and we are still at the start offset, // we need to find the next word. + DCHECK_NE(direction, ax::mojom::MoveDirection::kNone); if (direction == ax::mojom::MoveDirection::kBackward || result != start_offset) return result; } else if (break_iter.IsEndOfWord(result)) { // If we are searching backward and we are still at the end offset, we // need to find the previous word. + DCHECK_NE(direction, ax::mojom::MoveDirection::kNone); if (direction == ax::mojom::MoveDirection::kForward || result != start_offset) return result;
diff --git a/ui/accessibility/mojom/ax_event_intent.mojom b/ui/accessibility/mojom/ax_event_intent.mojom index 789c910..165206e 100644 --- a/ui/accessibility/mojom/ax_event_intent.mojom +++ b/ui/accessibility/mojom/ax_event_intent.mojom
@@ -9,6 +9,7 @@ // See ui::AXEventIntent for documentation. struct EventIntent { Command command; + InputEventType input_event_type; TextBoundary text_boundary; MoveDirection move_direction; };
diff --git a/ui/accessibility/mojom/ax_event_intent_mojom_traits.cc b/ui/accessibility/mojom/ax_event_intent_mojom_traits.cc index 9556a68..f37b4fb 100644 --- a/ui/accessibility/mojom/ax_event_intent_mojom_traits.cc +++ b/ui/accessibility/mojom/ax_event_intent_mojom_traits.cc
@@ -11,6 +11,7 @@ ax::mojom::EventIntentDataView data, ui::AXEventIntent* out) { out->command = data.command(); + out->input_event_type = data.input_event_type(); out->text_boundary = data.text_boundary(); out->move_direction = data.move_direction(); return true;
diff --git a/ui/accessibility/mojom/ax_event_intent_mojom_traits.h b/ui/accessibility/mojom/ax_event_intent_mojom_traits.h index 614c044e..2fd05aba 100644 --- a/ui/accessibility/mojom/ax_event_intent_mojom_traits.h +++ b/ui/accessibility/mojom/ax_event_intent_mojom_traits.h
@@ -15,6 +15,10 @@ static ax::mojom::Command command(const ui::AXEventIntent& p) { return p.command; } + static ax::mojom::InputEventType input_event_type( + const ui::AXEventIntent& p) { + return p.input_event_type; + } static ax::mojom::TextBoundary text_boundary(const ui::AXEventIntent& p) { return p.text_boundary; }
diff --git a/ui/accessibility/mojom/ax_event_intent_mojom_traits_unittest.cc b/ui/accessibility/mojom/ax_event_intent_mojom_traits_unittest.cc index 6c8d62b..f089744 100644 --- a/ui/accessibility/mojom/ax_event_intent_mojom_traits_unittest.cc +++ b/ui/accessibility/mojom/ax_event_intent_mojom_traits_unittest.cc
@@ -12,15 +12,30 @@ using mojo::test::SerializeAndDeserialize; -TEST(AXEventIntentMojomTraitsTest, RoundTrip) { +TEST(AXEventIntentMojomTraitsTest, RoundTripWithEditingIntent) { ui::AXEventIntent input; - input.command = ax::mojom::Command::kCut; + input.command = ax::mojom::Command::kInsert; + input.input_event_type = ax::mojom::InputEventType::kInsertLineBreak; + + ui::AXEventIntent output; + EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::EventIntent>(&input, &output)); + EXPECT_EQ(ax::mojom::Command::kInsert, output.command); + EXPECT_EQ(ax::mojom::InputEventType::kInsertLineBreak, + output.input_event_type); + EXPECT_EQ(ax::mojom::TextBoundary::kNone, output.text_boundary); + EXPECT_EQ(ax::mojom::MoveDirection::kNone, output.move_direction); +} + +TEST(AXEventIntentMojomTraitsTest, RoundTripWithSelectionIntent) { + ui::AXEventIntent input; + input.command = ax::mojom::Command::kMoveSelection; input.text_boundary = ax::mojom::TextBoundary::kWordEnd; input.move_direction = ax::mojom::MoveDirection::kForward; ui::AXEventIntent output; EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::EventIntent>(&input, &output)); - EXPECT_EQ(ax::mojom::Command::kCut, output.command); + EXPECT_EQ(ax::mojom::Command::kMoveSelection, output.command); + EXPECT_EQ(ax::mojom::InputEventType::kNone, output.input_event_type); EXPECT_EQ(ax::mojom::TextBoundary::kWordEnd, output.text_boundary); EXPECT_EQ(ax::mojom::MoveDirection::kForward, output.move_direction); }
diff --git a/ui/accessibility/mojom/ax_event_mojom_traits_unittest.cc b/ui/accessibility/mojom/ax_event_mojom_traits_unittest.cc index ba5657c..f9223d9 100644 --- a/ui/accessibility/mojom/ax_event_mojom_traits_unittest.cc +++ b/ui/accessibility/mojom/ax_event_mojom_traits_unittest.cc
@@ -22,11 +22,16 @@ input.event_type = ax::mojom::Event::kTextChanged; input.id = 111; input.event_from = ax::mojom::EventFrom::kUser; - ui::AXEventIntent cut_intent; - cut_intent.command = ax::mojom::Command::kCut; - cut_intent.text_boundary = ax::mojom::TextBoundary::kWordEnd; - cut_intent.move_direction = ax::mojom::MoveDirection::kForward; - const std::vector<ui::AXEventIntent> event_intents{cut_intent}; + ui::AXEventIntent editing_intent; + editing_intent.command = ax::mojom::Command::kDelete; + editing_intent.input_event_type = + ax::mojom::InputEventType::kDeleteWordForward; + ui::AXEventIntent selection_intent; + selection_intent.command = ax::mojom::Command::kMoveSelection; + selection_intent.text_boundary = ax::mojom::TextBoundary::kWordStart; + selection_intent.move_direction = ax::mojom::MoveDirection::kForward; + const std::vector<ui::AXEventIntent> event_intents{editing_intent, + selection_intent}; input.event_intents = event_intents; input.action_request_id = 222;
diff --git a/ui/accessibility/platform/BUILD.gn b/ui/accessibility/platform/BUILD.gn index d4e4e6b..9975fe48 100644 --- a/ui/accessibility/platform/BUILD.gn +++ b/ui/accessibility/platform/BUILD.gn
@@ -110,6 +110,8 @@ if (is_mac) { sources += [ + "ax_event_intent_mac.h", + "ax_event_intent_mac.mm", "ax_platform_node_mac.h", "ax_platform_node_mac.mm", ]
diff --git a/ui/accessibility/platform/ax_event_intent_mac.h b/ui/accessibility/platform/ax_event_intent_mac.h new file mode 100644 index 0000000..691e4b0 --- /dev/null +++ b/ui/accessibility/platform/ax_event_intent_mac.h
@@ -0,0 +1,157 @@ +// Copyright 2020 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 UI_ACCESSIBILITY_PLATFORM_AX_EVENT_INTENT_MAC_H_ +#define UI_ACCESSIBILITY_PLATFORM_AX_EVENT_INTENT_MAC_H_ + +#include "ui/accessibility/ax_enums.mojom-forward.h" +#include "ui/accessibility/ax_export.h" + +namespace ui { + +struct AXEventIntent; + +// Describes the type of the AXTextStateChangeIntent, as defined by Mac's +// accessibility framework. +// +// Broadly, there are two types of intents that may be attached to accessibility +// events: an editing intent or a selection intent. +// +// The enumeration values are taken from the WebKit source code, but they are +// modified slightly to comply with Chromium's C++ Style Guide. Please do not +// renumber. +enum class AXTextStateChangeType { + kUnknown = 0, + kEdit = 1, + kSelectionMove = 2, + kSelectionExtend = 3, + kSelectionBoundary = 4 +}; + +// Describes the type of the editing intent, as defined by Mac's accessibility +// framework. +// +// The enumeration values are taken from the WebKit source code, but they are +// modified slightly to comply with Chromium's C++ Style Guide. Please do not +// renumber. +enum class AXTextEditType { + kUnknown = 0, + kDelete = 1, + kInsert = 2, + kTyping = 3, + kDictation = 4, + kCut = 5, + kPaste = 6, + kAttributesChange = 7 // Change font, style, alignment, color, etc. +}; + +// Describes the directionality of a selection intent, as defined by Mac's +// accessibility framework. +// +// The enumeration values are taken from the WebKit source code, but they are +// modified slightly to comply with Chromium's C++ Style Guide. Please do not +// renumber. +enum class AXTextSelectionDirection { + kUnknown = 0, + kBeginning = 1, + kEnd = 2, + kPrevious = 3, + kNext = 4, + kDiscontiguous = 5 +}; + +// Describes the amount by which the selection has moved or has been extended +// by, as defined by Mac's accessibility framework. +// +// The enumeration values are taken from the WebKit source code, but they are +// modified slightly to comply with Chromium's C++ Style Guide. Please do not +// renumber. +enum class AXTextSelectionGranularity { + kUnknown = 0, + kCharacter = 1, + kWord = 2, + kLine = 3, + kSentence = 4, + kParagraph = 5, + kPage = 6, + kDocument = 7, + + // All granularity represents the action of selecting the whole document as a + // single action. Extending selection by some other granularity until it + // encompasses the whole document should not result in a all granularity + // notification. + kAll = 8 +}; + +// Describes a selection operation in an AXTextStateChangeIntent. +struct AXTextSelection final { + // Constructs a description of a selection operation, translating the given + // direction and granularity from Chromium's internal representation to what + // the Mac accessibility framework expects. + static AXTextSelection FromDirectionAndGranularity( + ax::mojom::TextBoundary text_boundary, + ax::mojom::MoveDirection move_direction); + + // Constructs a description of a selection operation that has no extra + // information, such as when the selection is set using the mouse and so its + // granularity would be hard to ascertain. + AXTextSelection(); + + // Constructs a description of a selection operation for which extra + // information can be provided. + AXTextSelection(AXTextSelectionDirection direction, + AXTextSelectionGranularity granularity, + bool focus_change); + + AXTextSelection(const AXTextSelection& selection); + + virtual ~AXTextSelection(); + + AXTextSelection& operator=(const AXTextSelection& selection); + + AXTextSelectionDirection direction = AXTextSelectionDirection::kUnknown; + AXTextSelectionGranularity granularity = AXTextSelectionGranularity::kUnknown; + bool focus_change = false; +}; + +// The equivalent of an accessibility event intent (ui::AXEventIntent), as +// defined by Mac's accessibility framework. +struct AX_EXPORT AXTextStateChangeIntent final { + // Constructs an intent that is used when the selection is set to a different + // iframe or control, and focus has move to that element. + static AXTextStateChangeIntent DefaultFocusTextStateChangeIntent(); + + // Constructs an intent that is used when the selection has moved to another + // location within the same control, (i.e. browser focus hasn't moved), or + // when the selection has been cleared. + static AXTextStateChangeIntent DefaultSelectionChangeIntent(); + + // Constructs an empty intent. + AXTextStateChangeIntent(); + + // Constructs a selection intent. + AXTextStateChangeIntent(AXTextStateChangeType type, + AXTextSelection selection); + + // Constructs an editing intent. + AXTextStateChangeIntent(AXTextEditType edit); + + AXTextStateChangeIntent(const AXTextStateChangeIntent& intent); + + virtual ~AXTextStateChangeIntent(); + + AXTextStateChangeIntent& operator=(const AXTextStateChangeIntent& intent); + + AXTextStateChangeType type = AXTextStateChangeType::kUnknown; + AXTextEditType edit = AXTextEditType::kUnknown; + AXTextSelection selection; +}; + +// Converts from Chromium's ui::AXEventIntent to Mac's AXTextStateChangeIntent. +AX_EXPORT AXTextStateChangeIntent +FromEventIntent(const AXEventIntent& event_intent); + +} // namespace ui + +#endif // UI_ACCESSIBILITY_PLATFORM_AX_EVENT_INTENT_MAC_H_
diff --git a/ui/accessibility/platform/ax_event_intent_mac.mm b/ui/accessibility/platform/ax_event_intent_mac.mm new file mode 100644 index 0000000..003051ab --- /dev/null +++ b/ui/accessibility/platform/ax_event_intent_mac.mm
@@ -0,0 +1,229 @@ +// Copyright 2020 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 "ui/accessibility/platform/ax_event_intent_mac.h" + +#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_event_intent.h" + +namespace ui { + +// static +AXTextSelection AXTextSelection::FromDirectionAndGranularity( + ax::mojom::TextBoundary text_boundary, + ax::mojom::MoveDirection move_direction) { + bool has_stayed_within_same_text_unit = false; + AXTextSelectionDirection direction = AXTextSelectionDirection::kDiscontiguous; + AXTextSelectionGranularity granularity = AXTextSelectionGranularity::kUnknown; + + switch (text_boundary) { + case ax::mojom::TextBoundary::kNone: + break; + case ax::mojom::TextBoundary::kCharacter: + granularity = AXTextSelectionGranularity::kCharacter; + break; + case ax::mojom::TextBoundary::kFormat: + break; // Not supported on Mac. + case ax::mojom::TextBoundary::kLineEnd: + granularity = AXTextSelectionGranularity::kLine; + break; + case ax::mojom::TextBoundary::kLineStart: + granularity = AXTextSelectionGranularity::kLine; + break; + case ax::mojom::TextBoundary::kLineStartOrEnd: + has_stayed_within_same_text_unit = true; + granularity = AXTextSelectionGranularity::kLine; + break; + case ax::mojom::TextBoundary::kObject: + break; + case ax::mojom::TextBoundary::kPageEnd: + granularity = AXTextSelectionGranularity::kPage; + break; + case ax::mojom::TextBoundary::kPageStart: + granularity = AXTextSelectionGranularity::kPage; + break; + case ax::mojom::TextBoundary::kPageStartOrEnd: + has_stayed_within_same_text_unit = true; + granularity = AXTextSelectionGranularity::kPage; + break; + case ax::mojom::TextBoundary::kParagraphEnd: + granularity = AXTextSelectionGranularity::kParagraph; + break; + case ax::mojom::TextBoundary::kParagraphStart: + granularity = AXTextSelectionGranularity::kParagraph; + break; + case ax::mojom::TextBoundary::kParagraphStartOrEnd: + has_stayed_within_same_text_unit = true; + granularity = AXTextSelectionGranularity::kParagraph; + break; + case ax::mojom::TextBoundary::kSentenceEnd: + granularity = AXTextSelectionGranularity::kSentence; + break; + case ax::mojom::TextBoundary::kSentenceStart: + granularity = AXTextSelectionGranularity::kSentence; + break; + case ax::mojom::TextBoundary::kSentenceStartOrEnd: + has_stayed_within_same_text_unit = true; + granularity = AXTextSelectionGranularity::kSentence; + break; + case ax::mojom::TextBoundary::kWebPage: + has_stayed_within_same_text_unit = true; + granularity = AXTextSelectionGranularity::kDocument; + break; + case ax::mojom::TextBoundary::kWordEnd: + granularity = AXTextSelectionGranularity::kWord; + break; + case ax::mojom::TextBoundary::kWordStart: + granularity = AXTextSelectionGranularity::kWord; + break; + case ax::mojom::TextBoundary::kWordStartOrEnd: + has_stayed_within_same_text_unit = true; + granularity = AXTextSelectionGranularity::kWord; + break; + } + + switch (move_direction) { + case ax::mojom::MoveDirection::kNone: + break; + case ax::mojom::MoveDirection::kBackward: + if (has_stayed_within_same_text_unit) { + direction = AXTextSelectionDirection::kBeginning; + } else { + direction = AXTextSelectionDirection::kPrevious; + } + break; + case ax::mojom::MoveDirection::kForward: + if (has_stayed_within_same_text_unit) { + direction = AXTextSelectionDirection::kEnd; + } else { + direction = AXTextSelectionDirection::kNext; + } + break; + } + + return AXTextSelection(direction, granularity, /* focus_change */ false); +} + +AXTextSelection::AXTextSelection() = default; + +AXTextSelection::AXTextSelection(AXTextSelectionDirection direction, + AXTextSelectionGranularity granularity, + bool focus_change) + : direction(direction), + granularity(granularity), + focus_change(focus_change) {} + +AXTextSelection::AXTextSelection(const AXTextSelection& selection) = default; + +AXTextSelection::~AXTextSelection() = default; + +AXTextSelection& AXTextSelection::operator=(const AXTextSelection& selection) = + default; + +// static +AXTextStateChangeIntent +AXTextStateChangeIntent::DefaultFocusTextStateChangeIntent() { + return AXTextStateChangeIntent( + AXTextStateChangeType::kSelectionMove, + AXTextSelection(AXTextSelectionDirection::kDiscontiguous, + AXTextSelectionGranularity::kUnknown, + /* focus_change */ true)); +} + +// static +AXTextStateChangeIntent +AXTextStateChangeIntent::DefaultSelectionChangeIntent() { + return AXTextStateChangeIntent( + AXTextStateChangeType::kSelectionMove, + AXTextSelection(AXTextSelectionDirection::kDiscontiguous, + AXTextSelectionGranularity::kUnknown, + /* focus_change */ false)); +} + +AXTextStateChangeIntent::AXTextStateChangeIntent() = default; + +AXTextStateChangeIntent::AXTextStateChangeIntent(AXTextStateChangeType type, + AXTextSelection selection) + : type(type), selection(selection) {} + +AXTextStateChangeIntent::AXTextStateChangeIntent(AXTextEditType edit) + : type(AXTextStateChangeType::kEdit), edit(edit) {} + +AXTextStateChangeIntent::AXTextStateChangeIntent( + const AXTextStateChangeIntent& intent) = default; + +AXTextStateChangeIntent::~AXTextStateChangeIntent() = default; + +AXTextStateChangeIntent& AXTextStateChangeIntent::operator=( + const AXTextStateChangeIntent& intent) = default; + +AXTextStateChangeIntent FromEventIntent(const AXEventIntent& event_intent) { + switch (event_intent.command) { + case ax::mojom::Command::kNone: + return AXTextStateChangeIntent(); // An unknown intent. + case ax::mojom::Command::kClearSelection: + return AXTextStateChangeIntent::DefaultSelectionChangeIntent(); + case ax::mojom::Command::kDelete: + switch (event_intent.input_event_type) { + case ax::mojom::InputEventType::kDeleteByCut: + case ax::mojom::InputEventType::kDeleteByDrag: + return AXTextStateChangeIntent(AXTextEditType::kCut); + default: + return AXTextStateChangeIntent(AXTextEditType::kDelete); + } + break; + case ax::mojom::Command::kDictate: + return AXTextStateChangeIntent(AXTextEditType::kDictation); + case ax::mojom::Command::kExtendSelection: + return AXTextStateChangeIntent( + AXTextStateChangeType::kSelectionExtend, + AXTextSelection::FromDirectionAndGranularity( + event_intent.text_boundary, event_intent.move_direction)); + case ax::mojom::Command::kFormat: + return AXTextStateChangeIntent(AXTextEditType::kAttributesChange); + case ax::mojom::Command::kHistory: + return AXTextStateChangeIntent(); // Not currently implemented on Mac. + case ax::mojom::Command::kInsert: + switch (event_intent.input_event_type) { + case ax::mojom::InputEventType::kInsertText: + case ax::mojom::InputEventType::kInsertLineBreak: + case ax::mojom::InputEventType::kInsertParagraph: + case ax::mojom::InputEventType::kInsertHorizontalRule: + return AXTextStateChangeIntent(AXTextEditType::kTyping); + case ax::mojom::InputEventType::kInsertFromPaste: + case ax::mojom::InputEventType::kInsertFromDrop: + case ax::mojom::InputEventType::kInsertFromYank: + return AXTextStateChangeIntent(AXTextEditType::kPaste); + default: + return AXTextStateChangeIntent(AXTextEditType::kInsert); + } + break; + case ax::mojom::Command::kMarker: + return AXTextStateChangeIntent(); // Not currently implemented on Mac. + case ax::mojom::Command::kMoveSelection: + // Mac calls a "kSelectionBoundary" an operation that moves the caret + // within an editable element by a given text unit, e.g. by word. + return AXTextStateChangeIntent( + AXTextStateChangeType::kSelectionBoundary, + AXTextSelection::FromDirectionAndGranularity( + event_intent.text_boundary, event_intent.move_direction)); + case ax::mojom::Command::kSetSelection: + // Mac calls a "kSelectionMove" an operation that sets the selection to a + // completely new location, such as tabbing to an edit field. + if (event_intent.text_boundary == ax::mojom::TextBoundary::kNone) { + // No granularity information is available. This means that focus must + // have moved to another control, or a new selection has been made using + // the mouse or touch in the same control. In the latter case, we'll + // also pretend that focus has changed. + return AXTextStateChangeIntent::DefaultFocusTextStateChangeIntent(); + } + + return AXTextStateChangeIntent( + AXTextStateChangeType::kSelectionMove, + AXTextSelection::FromDirectionAndGranularity( + event_intent.text_boundary, event_intent.move_direction)); + } +} + +} // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc index 3f34264f..5c51478 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -4888,6 +4888,9 @@ DCHECK(!offset_to_text_attributes_.empty()); switch (direction) { + case ax::mojom::MoveDirection::kNone: + NOTREACHED(); + return start_offset; case ax::mojom::MoveDirection::kBackward: { auto iterator = offset_to_text_attributes_.upper_bound(start_offset); --iterator;
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc index be78f37..bc24786b 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
@@ -1815,7 +1815,7 @@ g_object_unref(root_atk_object); } -TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkPopupWindowActive) { +TEST_F(AXPlatformNodeAuraLinuxTest, DISABLED_TestAtkPopupWindowActive) { AXNodeData root; root.id = 1; root.role = ax::mojom::Role::kApplication;
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc index 9d499d3..f74ed2d 100644 --- a/ui/accessibility/platform/ax_platform_node_base.cc +++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -1874,6 +1874,7 @@ int offset, ax::mojom::MoveDirection direction, ax::mojom::TextAffinity affinity) const { + DCHECK_NE(boundary, ax::mojom::TextBoundary::kNone); if (boundary != ax::mojom::TextBoundary::kSentenceStart) { base::Optional<int> boundary_offset = GetDelegate()->FindTextBoundary(boundary, offset, direction, affinity);
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc index 287c6b0c..9ec0e0d 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc
@@ -1015,6 +1015,7 @@ AXBoundaryBehavior boundary_behavior, ax::mojom::MoveDirection boundary_direction) { // Override At[Start|End]OfLinePredicate for behavior specific to UIA. + DCHECK_NE(boundary_type, ax::mojom::TextBoundary::kNone); switch (boundary_type) { case ax::mojom::TextBoundary::kLineStart: return position->CreateBoundaryStartPosition(
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc index 6dd1156..6f59471 100644 --- a/ui/base/x/x11_util.cc +++ b/ui/base/x/x11_util.cc
@@ -1128,6 +1128,23 @@ : DefaultX11IOErrorHandler); } +bool IsVulkanSurfaceSupported() { + static const char* extensions[] = { + "DRI3", // open source driver. + "ATIFGLRXDRI", // AMD proprietary driver. + "NV-CONTROL", // NVidia proprietary driver. + }; + auto* display = gfx::GetXDisplay(); + int ext_code, first_event, first_error; + for (const auto* extension : extensions) { + if (XQueryExtension(display, extension, &ext_code, &first_event, + &first_error)) { + return true; + } + } + return false; +} + // static XVisualManager* XVisualManager::GetInstance() { return base::Singleton<XVisualManager>::get(); @@ -1265,4 +1282,18 @@ return colormap_; } +ScopedUnsetDisplay::ScopedUnsetDisplay() { + const char* display = getenv("DISPLAY"); + if (display) { + display_.emplace(display); + unsetenv("DISPLAY"); + } +} + +ScopedUnsetDisplay::~ScopedUnsetDisplay() { + if (display_) { + setenv("DISPLAY", display_->c_str(), 1); + } +} + } // namespace ui
diff --git a/ui/base/x/x11_util.h b/ui/base/x/x11_util.h index ba04096..51343d67 100644 --- a/ui/base/x/x11_util.h +++ b/ui/base/x/x11_util.h
@@ -555,12 +555,8 @@ void SetX11ErrorHandlers(XErrorHandler error_handler, XIOErrorHandler io_error_handler); -// NOTE: This function should not be called directly from the -// X11 Error handler because it queries the server to decode the -// error message, which may trigger other errors. A suitable workaround -// is to post a task in the error handler to call this function. -COMPONENT_EXPORT(UI_BASE_X) -void LogErrorEventDescription(Display* dpy, const XErrorEvent& error_event); +// Return true if VulkanSurface is supported. +COMPONENT_EXPORT(UI_BASE_X) bool IsVulkanSurfaceSupported(); // -------------------------------------------------------------------------- // Selects a visual with a preference for alpha support on compositing window @@ -640,6 +636,16 @@ DISALLOW_COPY_AND_ASSIGN(XVisualManager); }; +class COMPONENT_EXPORT(UI_BASE_X) ScopedUnsetDisplay { + public: + ScopedUnsetDisplay(); + ~ScopedUnsetDisplay(); + + private: + base::Optional<std::string> display_; + DISALLOW_COPY_AND_ASSIGN(ScopedUnsetDisplay); +}; + } // namespace ui #endif // UI_BASE_X_X11_UTIL_H_
diff --git a/ui/chromeos/search_box/search_box_view_base.cc b/ui/chromeos/search_box/search_box_view_base.cc index 48251b0..1abc20c 100644 --- a/ui/chromeos/search_box/search_box_view_base.cc +++ b/ui/chromeos/search_box/search_box_view_base.cc
@@ -47,10 +47,6 @@ constexpr SkColor kSearchTextColor = SkColorSetRGB(0x33, 0x33, 0x33); -// Color of placeholder text in zero query state. -constexpr SkColor kZeroQuerySearchboxColor = - SkColorSetARGB(0x8A, 0x00, 0x00, 0x00); - } // namespace // A background that paints a solid white rounded rect with a thin grey @@ -340,13 +336,10 @@ is_search_box_active_ = active; UpdateSearchIcon(); - UpdateBackgroundColor(kSearchBoxBackgroundDefault); search_box_->set_placeholder_text_draw_flags( active ? (base::i18n::IsRTL() ? gfx::Canvas::TEXT_ALIGN_RIGHT : gfx::Canvas::TEXT_ALIGN_LEFT) : gfx::Canvas::TEXT_ALIGN_CENTER); - search_box_->set_placeholder_text_color(active ? kZeroQuerySearchboxColor - : search_box_color_); search_box_->SetCursorEnabled(active); if (active) { @@ -555,8 +548,6 @@ // TODO(crbug.com/755219): Unify this with SetBackgroundColor. void SearchBoxViewBase::UpdateBackgroundColor(SkColor color) { - if (is_search_box_active_) - color = kSearchBoxBackgroundDefault; GetSearchBoxBackground()->SetNativeControlColor(color); }
diff --git a/ui/compositor/dip_util.cc b/ui/compositor/dip_util.cc index c76d5535..98829ba 100644 --- a/ui/compositor/dip_util.cc +++ b/ui/compositor/dip_util.cc
@@ -23,31 +23,11 @@ namespace ui { -gfx::Point ConvertPointToDIP(const Layer* layer, - const gfx::Point& point_in_pixel) { - return gfx::ConvertPointToDIP(layer->device_scale_factor(), point_in_pixel); -} - -gfx::PointF ConvertPointToDIP(const Layer* layer, - const gfx::PointF& point_in_pixel) { - return gfx::ConvertPointToDIP(layer->device_scale_factor(), point_in_pixel); -} - -gfx::Size ConvertSizeToDIP(const Layer* layer, - const gfx::Size& size_in_pixel) { - return gfx::ConvertSizeToDIP(layer->device_scale_factor(), size_in_pixel); -} - gfx::Rect ConvertRectToDIP(const Layer* layer, const gfx::Rect& rect_in_pixel) { return gfx::ConvertRectToDIP(layer->device_scale_factor(), rect_in_pixel); } -gfx::Point ConvertPointToPixel(const Layer* layer, - const gfx::Point& point_in_dip) { - return gfx::ConvertPointToPixel(layer->device_scale_factor(), point_in_dip); -} - gfx::Size ConvertSizeToPixel(const Layer* layer, const gfx::Size& size_in_dip) { return gfx::ConvertSizeToPixel(layer->device_scale_factor(), size_in_dip);
diff --git a/ui/compositor/dip_util.h b/ui/compositor/dip_util.h index 6aac88e..d39cd1a 100644 --- a/ui/compositor/dip_util.h +++ b/ui/compositor/dip_util.h
@@ -9,7 +9,6 @@ #include "ui/gfx/geometry/point_f.h" namespace gfx { -class Point; class Size; class Rect; } // namespace gfx @@ -19,21 +18,9 @@ // Utility functions that convert point/size/rect between // DIP and pixel coordinates system. -COMPOSITOR_EXPORT gfx::Point ConvertPointToDIP( - const Layer* layer, - const gfx::Point& point_in_pixel); -COMPOSITOR_EXPORT gfx::PointF ConvertPointToDIP( - const Layer* layer, - const gfx::PointF& point_in_pixel); -COMPOSITOR_EXPORT gfx::Size ConvertSizeToDIP( - const Layer* layer, - const gfx::Size& size_in_pixel); COMPOSITOR_EXPORT gfx::Rect ConvertRectToDIP( const Layer* layer, const gfx::Rect& rect_in_pixel); -COMPOSITOR_EXPORT gfx::Point ConvertPointToPixel( - const Layer* layer, - const gfx::Point& point_in_dip); COMPOSITOR_EXPORT gfx::Size ConvertSizeToPixel( const Layer* layer, const gfx::Size& size_in_dip);
diff --git a/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.cc b/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.cc index 8c0a1ef..9c86fb16 100644 --- a/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.cc +++ b/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.cc
@@ -403,9 +403,6 @@ kOzoneNNPalmSwitchName)); } -const std::vector<int> NeuralStylusPalmDetectionFilter::kRequiredAbsMtCodes = { - ABS_MT_POSITION_X, ABS_MT_POSITION_Y, ABS_MT_TOUCH_MAJOR}; - bool NeuralStylusPalmDetectionFilter:: CompatibleWithNeuralStylusPalmDetectionFilter( const EventDeviceInfo& devinfo, @@ -425,6 +422,9 @@ } return true; }; + + static const std::vector<int> kRequiredAbsMtCodes = { + ABS_MT_POSITION_X, ABS_MT_POSITION_Y, ABS_MT_TOUCH_MAJOR}; if (!std::all_of(kRequiredAbsMtCodes.begin(), kRequiredAbsMtCodes.end(), code_check)) { return false;
diff --git a/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.h b/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.h index a3f3080..329059c 100644 --- a/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.h +++ b/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.h
@@ -7,7 +7,6 @@ #include <bitset> #include <cstdint> -#include <deque> #include <map> #include <memory> #include <string> @@ -94,8 +93,6 @@ const PalmFilterDeviceInfo palm_filter_dev_info_; std::unique_ptr<NeuralStylusPalmDetectionFilterModel> model_; - static const std::vector<int> kRequiredAbsMtCodes; - DISALLOW_COPY_AND_ASSIGN(NeuralStylusPalmDetectionFilter); };
diff --git a/ui/gfx/geometry/dip_util.cc b/ui/gfx/geometry/dip_util.cc index db8e1be5..60fb004 100644 --- a/ui/gfx/geometry/dip_util.cc +++ b/ui/gfx/geometry/dip_util.cc
@@ -6,7 +6,6 @@ #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/point.h" -#include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/point_f.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -15,6 +14,35 @@ namespace gfx { +PointF ConvertPointToDips(const Point& point_in_pixels, + float device_scale_factor) { + return ScalePoint(PointF(point_in_pixels), 1.f / device_scale_factor); +} + +PointF ConvertPointToDips(const PointF& point_in_pixels, + float device_scale_factor) { + return ScalePoint(point_in_pixels, 1.f / device_scale_factor); +} + +PointF ConvertPointToPixels(const Point& point_in_dips, + float device_scale_factor) { + return ScalePoint(PointF(point_in_dips), device_scale_factor); +} + +PointF ConvertPointToPixels(const PointF& point_in_dips, + float device_scale_factor) { + return ScalePoint(point_in_dips, device_scale_factor); +} + +SizeF ConvertSizeToDips(const Size& size_in_pixels, float device_scale_factor) { + return ScaleSize(SizeF(size_in_pixels), 1.f / device_scale_factor); +} + +SizeF ConvertSizeToDips(const SizeF& size_in_pixels, + float device_scale_factor) { + return ScaleSize(size_in_pixels, 1.f / device_scale_factor); +} + Insets ConvertInsetsToDIP(float scale_factor, const gfx::Insets& insets_in_pixel) { if (scale_factor == 1.f) @@ -22,24 +50,6 @@ return insets_in_pixel.Scale(1.f / scale_factor); } -Point ConvertPointToDIP(float scale_factor, const Point& point_in_pixel) { - if (scale_factor == 1.f) - return point_in_pixel; - return ScaleToFlooredPoint(point_in_pixel, 1.f / scale_factor); -} - -PointF ConvertPointToDIP(float scale_factor, const PointF& point_in_pixel) { - if (scale_factor == 1.f) - return point_in_pixel; - return ScalePoint(point_in_pixel, 1.f / scale_factor); -} - -Size ConvertSizeToDIP(float scale_factor, const Size& size_in_pixel) { - if (scale_factor == 1.f) - return size_in_pixel; - return ScaleToFlooredSize(size_in_pixel, 1.f / scale_factor); -} - Rect ConvertRectToDIP(float scale_factor, const Rect& rect_in_pixel) { if (scale_factor == 1.f) return rect_in_pixel; @@ -54,18 +64,6 @@ return insets_in_dip.Scale(scale_factor); } -Point ConvertPointToPixel(float scale_factor, const Point& point_in_dip) { - if (scale_factor == 1.f) - return point_in_dip; - return ScaleToFlooredPoint(point_in_dip, scale_factor); -} - -PointF ConvertPointToPixel(float scale_factor, const PointF& point_in_dip) { - if (scale_factor == 1.f) - return point_in_dip; - return ScalePoint(point_in_dip, scale_factor); -} - Size ConvertSizeToPixel(float scale_factor, const Size& size_in_dip) { if (scale_factor == 1.f) return size_in_dip;
diff --git a/ui/gfx/geometry/dip_util.h b/ui/gfx/geometry/dip_util.h index cb344c9..1916b050 100644 --- a/ui/gfx/geometry/dip_util.h +++ b/ui/gfx/geometry/dip_util.h
@@ -14,28 +14,48 @@ class PointF; class Rect; class Size; +class SizeF; + +// This file contains helper functions to move between DIPs (device-independent +// pixels) and physical pixels, by multiplying or dividing by device scale +// factor. These help show the intent of the caller by naming the operation, +// instead of directly performing a scale operation. More complicated +// transformations between coordinate spaces than DIP<->physical pixels should +// be done via more explicit means. +// +// Note that functions that receive integer values will convert them to floating +// point values, which can itself be a lossy operation for large integers. The +// intention of these methods is to be used for UI values which are relatively +// small. + +GEOMETRY_EXPORT gfx::PointF ConvertPointToDips( + const gfx::Point& point_in_pixels, + float device_scale_factor); +GEOMETRY_EXPORT gfx::PointF ConvertPointToDips( + const gfx::PointF& point_in_pixels, + float device_scale_factor); + +GEOMETRY_EXPORT gfx::PointF ConvertPointToPixels( + const gfx::Point& point_in_dips, + float device_scale_factor); +GEOMETRY_EXPORT gfx::PointF ConvertPointToPixels( + const gfx::PointF& point_in_dips, + float device_scale_factor); + +GEOMETRY_EXPORT gfx::SizeF ConvertSizeToDips(const gfx::Size& size_in_pixels, + float device_scale_factor); +GEOMETRY_EXPORT gfx::SizeF ConvertSizeToDips(const gfx::SizeF& size_in_pixels, + float device_scale_factor); GEOMETRY_EXPORT gfx::Insets ConvertInsetsToDIP( float scale_factor, const gfx::Insets& insets_in_pixel); -GEOMETRY_EXPORT gfx::Point ConvertPointToDIP(float scale_factor, - const gfx::Point& point_in_pixel); -GEOMETRY_EXPORT gfx::PointF ConvertPointToDIP( - float scale_factor, - const gfx::PointF& point_in_pixel); -GEOMETRY_EXPORT gfx::Size ConvertSizeToDIP(float scale_factor, - const gfx::Size& size_in_pixel); GEOMETRY_EXPORT gfx::Rect ConvertRectToDIP(float scale_factor, const gfx::Rect& rect_in_pixel); GEOMETRY_EXPORT gfx::Insets ConvertInsetsToPixel( float scale_factor, const gfx::Insets& insets_in_dip); -GEOMETRY_EXPORT gfx::Point ConvertPointToPixel(float scale_factor, - const gfx::Point& point_in_dip); -GEOMETRY_EXPORT gfx::PointF ConvertPointToPixel( - float scale_factor, - const gfx::PointF& point_in_dip); GEOMETRY_EXPORT gfx::Size ConvertSizeToPixel(float scale_factor, const gfx::Size& size_in_dip); GEOMETRY_EXPORT gfx::Rect ConvertRectToPixel(float scale_factor,
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc index 327df79..76301bf 100644 --- a/ui/gl/gl_surface_egl.cc +++ b/ui/gl/gl_surface_egl.cc
@@ -52,6 +52,10 @@ #define EGL_OPENGL_ES3_BIT 0x00000040 #endif +#if defined(USE_X11) +#include "ui/base/x/x11_util.h" +#endif + // Not present egl/eglext.h yet. #ifndef EGL_EXT_gl_colorspace_display_p3 @@ -347,6 +351,7 @@ // TODO(dbehr) Add an attrib to Angle to pass EGL platform. display_attribs.push_back(EGL_NONE); + // This is an EGL 1.5 function that we know ANGLE supports. It's used to pass // EGLAttribs (pointers) instead of EGLints into the display return eglGetPlatformDisplay( @@ -1289,6 +1294,14 @@ GetANGLEImplementationFromDisplayType(display_type)); } +#if defined(USE_X11) + // Unset DISPLAY env, so the vulkan can be initialized successfully, if the + // X server doesn't support Vulkan surface. + base::Optional<ui::ScopedUnsetDisplay> unset_display; + if (display_type == ANGLE_VULKAN && !ui::IsVulkanSurfaceSupported()) + unset_display.emplace(); +#endif // defined(USE_X11) + if (!eglInitialize(display, nullptr, nullptr)) { bool is_last = disp_index == init_displays.size() - 1;
diff --git a/ui/ozone/platform/x11/x11_screen_ozone.cc b/ui/ozone/platform/x11/x11_screen_ozone.cc index 76aeb9e..ac22d0a6 100644 --- a/ui/ozone/platform/x11/x11_screen_ozone.cc +++ b/ui/ozone/platform/x11/x11_screen_ozone.cc
@@ -10,6 +10,7 @@ #include "ui/events/platform/x11/x11_event_source.h" #include "ui/gfx/font_render_params.h" #include "ui/gfx/geometry/dip_util.h" +#include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/native_widget_types.h" #include "ui/platform_window/x11/x11_topmost_window_finder.h" #include "ui/platform_window/x11/x11_window.h" @@ -29,10 +30,6 @@ return device_scale_factor; } -gfx::Point PixelToDIPPoint(const gfx::Point& pixel_point) { - return gfx::ConvertPointToDIP(GetDeviceScaleFactor(), pixel_point); -} - } // namespace X11ScreenOzone::X11ScreenOzone() @@ -74,14 +71,20 @@ } gfx::Point X11ScreenOzone::GetCursorScreenPoint() const { + base::Optional<gfx::Point> point_in_pixels; if (ui::X11EventSource::HasInstance()) { - base::Optional<gfx::Point> point = - ui::X11EventSource::GetInstance() - ->GetRootCursorLocationFromCurrentEvent(); - if (point) - return PixelToDIPPoint(point.value()); + point_in_pixels = ui::X11EventSource::GetInstance() + ->GetRootCursorLocationFromCurrentEvent(); } - return PixelToDIPPoint(GetCursorLocation()); + if (!point_in_pixels) { + // This call is expensive so we explicitly only call it when + // |point_in_pixels| is not set. We note that base::Optional::value_or() + // would cause it to be called regardless. + point_in_pixels = GetCursorLocation(); + } + // TODO(danakj): Should this be rounded? Or kept as a floating point? + return gfx::ToFlooredPoint( + gfx::ConvertPointToDips(*point_in_pixels, GetDeviceScaleFactor())); } gfx::AcceleratedWidget X11ScreenOzone::GetAcceleratedWidgetAtScreenPoint(
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd index e4f2a50..aca9c1b 100644 --- a/ui/strings/ui_strings.grd +++ b/ui/strings/ui_strings.grd
@@ -895,6 +895,9 @@ <message name="IDS_ALL_APPS_INDICATOR" desc="Indicator text in the launcher on top of all apps."> ALL APPS </message> + <message name="IDS_APP_LIST_APP_FOCUS_NOTIFICATION_BADGE" desc="The spoken feedback text for when an app icon is focused and has a notification badge shown on the icon."> + <ph name="FOCUSED_APP_NAME">$1<ex>App Name</ex></ph> has new updates. + </message> <message name="IDS_APP_LIST_APP_DRAG_LOCATION_ACCESSIBILE_NAME" desc="The spoken feedback which tells the location that a dragged app has dropped to."> Moved to Page <ph name="PAGE_NUMBER">$1<ex>1</ex></ph>, row <ph name="ROW_NUMBER">$2<ex>4</ex></ph>, column <ph name="COLUMN_NUMBER">$3<ex>2</ex></ph>. </message>
diff --git a/ui/strings/ui_strings_grd/IDS_APP_LIST_APP_FOCUS_NOTIFICATION_BADGE.png.sha1 b/ui/strings/ui_strings_grd/IDS_APP_LIST_APP_FOCUS_NOTIFICATION_BADGE.png.sha1 new file mode 100644 index 0000000..dee6606 --- /dev/null +++ b/ui/strings/ui_strings_grd/IDS_APP_LIST_APP_FOCUS_NOTIFICATION_BADGE.png.sha1
@@ -0,0 +1 @@ +ccc2b3ba2e096d406d2a17cb8bd10ae9fb75cf54 \ No newline at end of file
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index 9b33346..ece2fe7 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -198,6 +198,7 @@ "layout/fill_layout.h", "layout/flex_layout.h", "layout/flex_layout_types.h", + "layout/flex_layout_view.h", "layout/grid_layout.h", "layout/layout_manager.h", "layout/layout_manager_base.h", @@ -399,6 +400,7 @@ "layout/fill_layout.cc", "layout/flex_layout.cc", "layout/flex_layout_types.cc", + "layout/flex_layout_view.cc", "layout/grid_layout.cc", "layout/layout_manager.cc", "layout/layout_manager_base.cc",
diff --git a/ui/views/bubble/bubble_dialog_model_host.cc b/ui/views/bubble/bubble_dialog_model_host.cc index 24c5c27..9406a719 100644 --- a/ui/views/bubble/bubble_dialog_model_host.cc +++ b/ui/views/bubble/bubble_dialog_model_host.cc
@@ -149,6 +149,12 @@ } View* BubbleDialogModelHost::GetInitiallyFocusedView() { + // TODO(pbos): Try to prevent uses of GetInitiallyFocusedView() after Close() + // and turn this in to a DCHECK for |model_| existence. This should fix + // https://crbug.com/1130181 for now. + if (!model_) + return BubbleDialogDelegateView::GetInitiallyFocusedView(); + base::Optional<int> unique_id = model_->initially_focused_field(GetPassKey()); if (!unique_id) @@ -186,6 +192,11 @@ // Widget::Close) model_->OnWindowClosing(GetPassKey()); + // TODO(pbos): Note that this is in place because GridLayout doesn't handle + // View removal correctly (keeps stale pointers). This is in place to prevent + // UAFs between Widget::Close() and destroying |this|. + SetLayoutManager(nullptr); + // TODO(pbos): Consider turning this into for-each-field remove field. RemoveAllChildViews(true); field_to_view_.clear();
diff --git a/ui/views/layout/flex_layout_view.cc b/ui/views/layout/flex_layout_view.cc new file mode 100644 index 0000000..051a85a --- /dev/null +++ b/ui/views/layout/flex_layout_view.cc
@@ -0,0 +1,144 @@ +// Copyright 2020 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 "ui/views/layout/flex_layout_view.h" + +#include <memory> + +namespace { + +// An enum giving different RenderText properties unique keys for the +// OnPropertyChanged call. +enum LabelPropertyKey { + kOrientation = 1, + kMainAxisAlignment, + kCrossAxisAlignment, + kInteriorMargin, + kMinimumCrossAxisSize, + kCollapseMargins, + kIncludeHostInsetsInLayout, + kIgnoreMainAxisMargins, + kFlexAllocationOrder, +}; + +} // namespace + +namespace views { + +FlexLayoutView::FlexLayoutView() + : layout_(SetLayoutManager(std::make_unique<FlexLayout>())) {} + +FlexLayoutView::~FlexLayoutView() = default; + +void FlexLayoutView::SetOrientation(LayoutOrientation orientation) { + if (orientation == layout_->orientation()) + return; + layout_->SetOrientation(orientation); + OnPropertyChanged(&layout_ + kOrientation, kPropertyEffectsLayout); +} + +LayoutOrientation FlexLayoutView::GetOrientation() const { + return layout_->orientation(); +} + +void FlexLayoutView::SetMainAxisAlignment(LayoutAlignment main_axis_alignment) { + if (main_axis_alignment == layout_->main_axis_alignment()) + return; + layout_->SetMainAxisAlignment(main_axis_alignment); + OnPropertyChanged(&layout_ + kMainAxisAlignment, kPropertyEffectsLayout); +} + +LayoutAlignment FlexLayoutView::GetMainAxisAlignment() const { + return layout_->main_axis_alignment(); +} + +void FlexLayoutView::SetCrossAxisAlignment( + LayoutAlignment cross_axis_alignment) { + if (cross_axis_alignment == layout_->cross_axis_alignment()) + return; + layout_->SetCrossAxisAlignment(cross_axis_alignment); + OnPropertyChanged(&layout_ + kCrossAxisAlignment, kPropertyEffectsLayout); +} + +LayoutAlignment FlexLayoutView::GetCrossAxisAlignment() const { + return layout_->cross_axis_alignment(); +} + +void FlexLayoutView::SetInteriorMargin(const gfx::Insets& interior_margin) { + if (interior_margin == layout_->interior_margin()) + return; + layout_->SetInteriorMargin(interior_margin); + OnPropertyChanged(&layout_ + kInteriorMargin, kPropertyEffectsLayout); +} + +const gfx::Insets& FlexLayoutView::GetInteriorMargin() const { + return layout_->interior_margin(); +} + +void FlexLayoutView::SetMinimumCrossAxisSize(int size) { + if (size == layout_->minimum_cross_axis_size()) + return; + layout_->SetMinimumCrossAxisSize(size); + OnPropertyChanged(&layout_ + kMinimumCrossAxisSize, kPropertyEffectsLayout); +} + +int FlexLayoutView::GetMinimumCrossAxisSize() const { + return layout_->minimum_cross_axis_size(); +} + +void FlexLayoutView::SetCollapseMargins(bool collapse_margins) { + if (collapse_margins == layout_->collapse_margins()) + return; + layout_->SetCollapseMargins(collapse_margins); + OnPropertyChanged(&layout_ + kCollapseMargins, kPropertyEffectsLayout); +} + +bool FlexLayoutView::GetCollapseMargins() const { + return layout_->collapse_margins(); +} + +void FlexLayoutView::SetIncludeHostInsetsInLayout( + bool include_host_insets_in_layout) { + if (include_host_insets_in_layout == layout_->include_host_insets_in_layout()) + return; + layout_->SetIncludeHostInsetsInLayout(include_host_insets_in_layout); + OnPropertyChanged(&layout_ + kIncludeHostInsetsInLayout, + kPropertyEffectsLayout); +} + +bool FlexLayoutView::GetIncludeHostInsetsInLayout() const { + return layout_->include_host_insets_in_layout(); +} + +void FlexLayoutView::SetIgnoreDefaultMainAxisMargins( + bool ignore_default_main_axis_margins) { + if (ignore_default_main_axis_margins == + layout_->ignore_default_main_axis_margins()) { + return; + } + layout_->SetIgnoreDefaultMainAxisMargins(ignore_default_main_axis_margins); + OnPropertyChanged(&layout_ + kIgnoreMainAxisMargins, kPropertyEffectsLayout); +} + +bool FlexLayoutView::GetIgnoreDefaultMainAxisMargins() const { + return layout_->ignore_default_main_axis_margins(); +} + +void FlexLayoutView::SetFlexAllocationOrder( + FlexAllocationOrder flex_allocation_order) { + if (flex_allocation_order == layout_->flex_allocation_order()) + return; + layout_->SetFlexAllocationOrder(flex_allocation_order); + OnPropertyChanged(&layout_ + kFlexAllocationOrder, kPropertyEffectsLayout); +} + +FlexAllocationOrder FlexLayoutView::GetFlexAllocationOrder() const { + return layout_->flex_allocation_order(); +} + +FlexRule FlexLayoutView::GetDefaultFlexRule() const { + return layout_->GetDefaultFlexRule(); +} + +} // namespace views
diff --git a/ui/views/layout/flex_layout_view.h b/ui/views/layout/flex_layout_view.h new file mode 100644 index 0000000..35192ec --- /dev/null +++ b/ui/views/layout/flex_layout_view.h
@@ -0,0 +1,71 @@ +// Copyright 2020 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 UI_VIEWS_LAYOUT_FLEX_LAYOUT_VIEW_H_ +#define UI_VIEWS_LAYOUT_FLEX_LAYOUT_VIEW_H_ + +#include "ui/views/layout/flex_layout.h" +#include "ui/views/layout/flex_layout_types.h" +#include "ui/views/view.h" +#include "ui/views/views_export.h" + +namespace views { + +class VIEWS_EXPORT FlexLayoutView : public View { + public: + FlexLayoutView(); + FlexLayoutView(const FlexLayoutView&) = delete; + FlexLayoutView operator=(const FlexLayoutView&) = delete; + ~FlexLayoutView() override; + + void SetOrientation(LayoutOrientation orientation); + LayoutOrientation GetOrientation() const; + + void SetMainAxisAlignment(LayoutAlignment main_axis_alignment); + LayoutAlignment GetMainAxisAlignment() const; + + void SetCrossAxisAlignment(LayoutAlignment cross_axis_alignment); + LayoutAlignment GetCrossAxisAlignment() const; + + void SetInteriorMargin(const gfx::Insets& interior_margin); + const gfx::Insets& GetInteriorMargin() const; + + void SetMinimumCrossAxisSize(int size); + int GetMinimumCrossAxisSize() const; + + void SetCollapseMargins(bool collapse_margins); + bool GetCollapseMargins() const; + + void SetIncludeHostInsetsInLayout(bool include_host_insets_in_layout); + bool GetIncludeHostInsetsInLayout() const; + + void SetIgnoreDefaultMainAxisMargins(bool ignore_default_main_axis_margins); + bool GetIgnoreDefaultMainAxisMargins() const; + + void SetFlexAllocationOrder(FlexAllocationOrder flex_allocation_order); + FlexAllocationOrder GetFlexAllocationOrder() const; + + // Returns a flex rule that allows flex layouts to be nested with expected + // behavior. + FlexRule GetDefaultFlexRule() const; + + // Moves and uses |value| as the default value for layout property |key|. + template <class T, class U> + void SetDefault(const ui::ClassProperty<T>* key, U&& value) { + layout_->SetDefault(key, value); + } + + // Copies and uses |value| as the default value for layout property |key|. + template <class T, class U> + void SetDefault(const ui::ClassProperty<T>* key, const U& value) { + layout_->SetDefault(key, value); + } + + private: + FlexLayout* layout_; +}; + +} // namespace views + +#endif // UI_VIEWS_LAYOUT_FLEX_LAYOUT_VIEW_H_
diff --git a/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/ui/views/widget/desktop_aura/desktop_screen_x11.cc index b43479c..b3fe507 100644 --- a/ui/views/widget/desktop_aura/desktop_screen_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
@@ -21,6 +21,7 @@ #include "ui/display/util/display_util.h" #include "ui/gfx/font_render_params.h" #include "ui/gfx/geometry/dip_util.h" +#include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/switches.h" #include "ui/platform_window/x11/x11_topmost_window_finder.h" @@ -48,14 +49,18 @@ gfx::Point DesktopScreenX11::GetCursorScreenPoint() { TRACE_EVENT0("views", "DesktopScreenX11::GetCursorScreenPoint()"); - base::Optional<gfx::Point> point; + base::Optional<gfx::Point> point_in_pixels; if (const auto* const event_source = ui::X11EventSource::GetInstance()) - point = event_source->GetRootCursorLocationFromCurrentEvent(); - return gfx::ConvertPointToDIP( - GetXDisplayScaleFactor(), - // NB: Do NOT call value_or() here, since that would defeat the purpose of - // caching |point|. - point ? point.value() : x11_display_manager_->GetCursorLocation()); + point_in_pixels = event_source->GetRootCursorLocationFromCurrentEvent(); + if (!point_in_pixels) { + // This call is expensive so we explicitly only call it when + // |point_in_pixels| is not set. We note that base::Optional::value_or() + // would cause it to be called regardless. + point_in_pixels = x11_display_manager_->GetCursorLocation(); + } + // TODO(danakj): Should this be rounded? Or kept as a floating point? + return gfx::ToFlooredPoint( + gfx::ConvertPointToDips(*point_in_pixels, GetXDisplayScaleFactor())); } bool DesktopScreenX11::IsWindowUnderCursor(gfx::NativeWindow window) { @@ -64,8 +69,11 @@ gfx::NativeWindow DesktopScreenX11::GetWindowAtScreenPoint( const gfx::Point& point) { + // TODO(danakj): Should this be rounded? + gfx::Point point_in_pixels = gfx::ToFlooredPoint( + gfx::ConvertPointToPixels(point, GetXDisplayScaleFactor())); auto window = ui::X11TopmostWindowFinder().FindLocalProcessWindowAt( - gfx::ConvertPointToPixel(GetXDisplayScaleFactor(), point), {}); + point_in_pixels, {}); return window != x11::Window::None ? views::DesktopWindowTreeHostPlatform::GetContentWindowForWidget( static_cast<gfx::AcceleratedWidget>(window)) @@ -78,9 +86,11 @@ std::set<gfx::AcceleratedWidget> ignore_widgets; for (auto* const window : ignore) ignore_widgets.emplace(window->GetHost()->GetAcceleratedWidget()); + // TODO(danakj): Should this be rounded? + gfx::Point point_in_pixels = gfx::ToFlooredPoint( + gfx::ConvertPointToPixels(point, GetXDisplayScaleFactor())); auto window = ui::X11TopmostWindowFinder().FindLocalProcessWindowAt( - gfx::ConvertPointToPixel(GetXDisplayScaleFactor(), point), - ignore_widgets); + point_in_pixels, ignore_widgets); return window != x11::Window::None ? views::DesktopWindowTreeHostPlatform::GetContentWindowForWidget( static_cast<gfx::AcceleratedWidget>(window))
diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn index 3570bc9..dc39a3b 100644 --- a/weblayer/BUILD.gn +++ b/weblayer/BUILD.gn
@@ -428,6 +428,7 @@ "//components/unified_consent:unified_consent", "//components/user_prefs", "//components/variations", + "//components/variations:variations_mojom", "//components/variations/net", "//components/variations/proto", "//components/variations/service",
diff --git a/weblayer/browser/browser_context_impl.cc b/weblayer/browser/browser_context_impl.cc index 7a5f4254..a13cf58 100644 --- a/weblayer/browser/browser_context_impl.cc +++ b/weblayer/browser/browser_context_impl.cc
@@ -26,6 +26,7 @@ #include "components/translate/core/browser/translate_prefs.h" #include "components/user_prefs/user_prefs.h" #include "components/variations/proto/study.pb.h" +#include "components/variations/variations.mojom.h" #include "components/variations/variations_client.h" #include "components/variations/variations_ids_provider.h" #include "content/public/browser/device_service.h" @@ -296,13 +297,10 @@ return browser_context_->IsOffTheRecord(); } - // TODO(crbug/1094303): Update the signature to accept a - // variations::Study_GoogleWebVisibility and pass the given value to - // GetClientDataHeader(). - std::string GetVariationsHeader() const override { + variations::mojom::VariationsHeadersPtr GetVariationsHeaders() + const override { return variations::VariationsIdsProvider::GetInstance() - ->GetClientDataHeader(IsSignedIn(), - variations::Study_GoogleWebVisibility_ANY); + ->GetClientDataHeaders(IsSignedIn()); } private: