diff --git a/DEPS b/DEPS index c310e5c..a954c518 100644 --- a/DEPS +++ b/DEPS
@@ -195,7 +195,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '61003cde76882c43ab593a5fd889fc90b7d10abf', + 'skia_revision': 'aa64c352b349a779e98d903eda594dd0ce502736', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -211,11 +211,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '0aca3ca9427d1d2aa8d8e706de62360c61af3598', + 'swiftshader_revision': '139f5c351e1ff62e465526d4d2f40d3b08a27169', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'daef088d069f8d49d8ba668f475dd21ca0e5c087', + 'pdfium_revision': 'e21911cc1c77d39dbc51001845bbfce2783e6514', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -258,7 +258,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'e9879d106b95b2c9f0b0fd6efe8f1e5186f64ada', + 'catapult_revision': 'cd2eebd327e35c839149f7a4d888b046d628df12', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # 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': '5a23b943626939e5bcc6c1dfddbbebd2c531e151', + 'devtools_frontend_revision': '46abe35c6554f1534495b880031b5aa72df4b60e', # 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': '793a07e366362f2e3cdf07e144c1eff8de18efba', + 'dawn_revision': '1c25198384e7ecfebbd3ac84203d3b1d46a0e228', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -901,7 +901,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '80d095c4dc414872855f79e4a66995c988912891', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'b073999c6f90103a36a923e63ae8cf7a5c9c6c8c', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1332,7 +1332,7 @@ 'packages': [ { 'package': 'fuchsia/third_party/aemu/linux-amd64', - 'version': '1wcgrsmCBOkqmqgVO1zI-z2_mk9oLiVRGlx-INget24C' + 'version': 'PL87Lj_q7GOEzYJ2eJIJAzMtQbuLWVnmjDQPqfu2O64C' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -1486,7 +1486,7 @@ }, 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '294729f33cbfac484a4b77c29dd42f03ffe65fa2', + Var('webrtc_git') + '/src.git' + '@' + '3326535126e435f1ba647885ce43a8f0f3d317eb', '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@6dc612511e7b53778e59f30b96f71f1af0ab7ca4', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@bba04cfcf31213de56b43886680cabc65635b69a', 'condition': 'checkout_src_internal', }, @@ -1566,7 +1566,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'P-2JwDZls8V1LNOlmHoxgPlVs68icpTYuJyIwCQQ-okC', + 'version': 'IzAbSag8-IGOAkL2GSMql94a4unzsZtFfkhskHgLSCkC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1577,7 +1577,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'TGyqQ0i-VwfJWUWkmWGzsrQ0c-MmVg_nP2-LKMWnCQYC', + 'version': 'cT9lCWDvv6veb3QkbQk0BRcglTeLjCZ2W35O2YG3ez0C', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/accessibility/accessibility_controller_impl.cc b/ash/accessibility/accessibility_controller_impl.cc index fd513d0..b5ae43b7 100644 --- a/ash/accessibility/accessibility_controller_impl.cc +++ b/ash/accessibility/accessibility_controller_impl.cc
@@ -1060,18 +1060,20 @@ switch_access_bubble_controller_->ShowMenu(anchor, actions_to_show); } +void AccessibilityControllerImpl::StartPointScan() { + if (::switches::IsSwitchAccessPointScanningEnabled()) { + if (!point_scan_controller_) + point_scan_controller_.reset(new PointScanController()); + + point_scan_controller_->Start(); + } +} + void AccessibilityControllerImpl:: DisablePolicyRecommendationRestorerForTesting() { Shell::Get()->policy_recommendation_restorer()->DisableForTesting(); } -void AccessibilityControllerImpl::StartPointScanning() { - if (!point_scan_controller_) - point_scan_controller_.reset(new PointScanController()); - - point_scan_controller_->Start(); -} - bool AccessibilityControllerImpl::IsStickyKeysSettingVisibleInTray() { return sticky_keys().IsVisibleInTray(); } @@ -1724,8 +1726,6 @@ switch_access_bubble_controller_ = std::make_unique<SwitchAccessMenuBubbleController>(); UpdateKeyCodesAfterSwitchAccessEnabled(); - if (::switches::IsSwitchAccessPointScanningEnabled()) - StartPointScanning(); if (skip_switch_access_notification_) { skip_switch_access_notification_ = false; return;
diff --git a/ash/accessibility/accessibility_controller_impl.h b/ash/accessibility/accessibility_controller_impl.h index 609d3fee..214427b6 100644 --- a/ash/accessibility/accessibility_controller_impl.h +++ b/ash/accessibility/accessibility_controller_impl.h
@@ -351,6 +351,7 @@ void ShowSwitchAccessBackButton(const gfx::Rect& anchor) override; void ShowSwitchAccessMenu(const gfx::Rect& anchor, std::vector<std::string> actions_to_show) override; + void StartPointScan() override; void SetDictationActive(bool is_active) override; void ToggleDictationFromSource(DictationToggleSource source) override; void HandleAutoclickScrollableBoundsFound(
diff --git a/ash/app_list/views/privacy_info_view.cc b/ash/app_list/views/privacy_info_view.cc index ddab3e9..e18b284 100644 --- a/ash/app_list/views/privacy_info_view.cc +++ b/ash/app_list/views/privacy_info_view.cc
@@ -43,22 +43,26 @@ constexpr int kCellSpacingDip = 18; constexpr int kIconSizeDip = 20; -// Link view used inside the privacy notice. -class PrivacyLinkView : public views::Link { +// Text view used inside the privacy notice. +class PrivacyTextView : public views::StyledLabel { public: - explicit PrivacyLinkView(const base::string16& title) : Link(title) {} + explicit PrivacyTextView(PrivacyInfoView* privacy_view) + : StyledLabel(), privacy_view_(privacy_view) {} // views::View: bool HandleAccessibleAction(const ui::AXActionData& action_data) override { switch (action_data.action) { - case ax::mojom::Action::kFocus: - // Do nothing because the search box needs to keep focus. + case ax::mojom::Action::kDoDefault: + privacy_view_->LinkClicked(); return true; default: break; } - return views::Link::HandleAccessibleAction(action_data); + return views::StyledLabel::HandleAccessibleAction(action_data); } + + private: + PrivacyInfoView* const privacy_view_; // Not owned. }; } // namespace @@ -97,7 +101,9 @@ if (selected_action_ == Action::kCloseButton) { cc::PaintFlags flags; flags.setAntiAlias(true); - flags.setColor(SkColorSetA(gfx::kGoogleGrey900, 0x14)); + flags.setColor(SkColorSetA( + AppListColorProvider::Get()->GetSearchResultViewHighlightColor(), + 0x14)); flags.setStyle(cc::PaintFlags::kFill_Style); canvas->DrawCircle(close_button_->bounds().CenterPoint(), close_button_->width() / 2, flags); @@ -147,7 +153,6 @@ CloseButtonPressed(); break; case Action::kNone: - case Action::kDefault: break; } } @@ -155,14 +160,8 @@ void PrivacyInfoView::SelectInitialResultAction(bool reverse_tab_order) { if (!reverse_tab_order) { - if (is_default_result()) { - // Hold the selection but do nothing. This is so that the text view is not - // selected immediately after the launcher opens. - selected_action_ = Action::kDefault; - } else { - selected_action_ = Action::kTextLink; - text_view_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); - } + selected_action_ = Action::kTextLink; + text_view_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); } else { selected_action_ = Action::kCloseButton; close_button_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); @@ -174,48 +173,20 @@ } bool PrivacyInfoView::SelectNextResultAction(bool reverse_tab_order) { - // There are three selection elements: default -> text view -> close button. - // The default selection is not traversed if selection is caused by user - // action. bool action_changed = false; - if (!reverse_tab_order) { - switch (selected_action_) { - case Action::kDefault: - // Move selection forward from default to the text view. - selected_action_ = Action::kTextLink; - text_view_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, - true); - action_changed = true; - break; - case Action::kTextLink: - // Move selection forward from the text view to the close button. - selected_action_ = Action::kCloseButton; - close_button_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, - true); - action_changed = true; - break; - case Action::kNone: - case Action::kCloseButton: - break; - } + // There are two traversal elements, the text view and close button. + if (!reverse_tab_order && selected_action_ == Action::kTextLink) { + // Move selection forward from the text view to the close button. + selected_action_ = Action::kCloseButton; + close_button_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); + action_changed = true; + } else if (reverse_tab_order && selected_action_ == Action::kCloseButton) { + // Move selection backward from the close button to the text view. + selected_action_ = Action::kTextLink; + text_view_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); + action_changed = true; } else { - switch (selected_action_) { - case Action::kCloseButton: - // Move selection backward from the close button to the text view. - selected_action_ = Action::kTextLink; - text_view_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, - true); - action_changed = true; - break; - case Action::kNone: - case Action::kDefault: - case Action::kTextLink: - break; - } - } - - if (!action_changed) { selected_action_ = Action::kNone; } @@ -226,9 +197,17 @@ } void PrivacyInfoView::NotifyA11yResultSelected() { - // Do not notify when this view is selected by default. Notifications for the - // child views are handled by SelectInitialResultAction and - // SelectNextResultAction. + switch (selected_action_) { + case Action::kTextLink: + text_view_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); + break; + case Action::kCloseButton: + close_button_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, + true); + break; + case Action::kNone: + break; + } } void PrivacyInfoView::ButtonPressed(views::Button* sender, @@ -277,13 +256,12 @@ size_t offset; const base::string16 text = l10n_util::GetStringFUTF16(info_string_id_, link, &offset); - text_view_ = AddChildView(std::make_unique<views::StyledLabel>()); + text_view_ = AddChildView(std::make_unique<PrivacyTextView>(this)); text_view_->SetText(text); text_view_->SetAutoColorReadabilityEnabled(false); - // Assign a container role to the text view so that ChromeVox focuses on - // the inner text elements individually. - text_view_->GetViewAccessibility().OverrideRole( - ax::mojom::Role::kGenericContainer); + text_view_->SetFocusBehavior(FocusBehavior::ALWAYS); + // Make the whole text view behave as a link for accessibility. + text_view_->GetViewAccessibility().OverrideRole(ax::mojom::Role::kLink); views::StyledLabel::RangeStyleInfo style; style.override_color = AppListColorProvider::Get()->GetSearchBoxTextColor(); @@ -294,7 +272,7 @@ // manually because default focus handling remains on the search box. views::StyledLabel::RangeStyleInfo link_style; link_style.disable_line_wrapping = true; - auto custom_view = std::make_unique<PrivacyLinkView>(link); + auto custom_view = std::make_unique<views::Link>(link); custom_view->set_callback(base::BindRepeating(&PrivacyInfoView::LinkClicked, base::Unretained(this))); custom_view->SetEnabledColor(gfx::kGoogleBlue700);
diff --git a/ash/app_list/views/privacy_info_view.h b/ash/app_list/views/privacy_info_view.h index 79f305d..49c814a9 100644 --- a/ash/app_list/views/privacy_info_view.h +++ b/ash/app_list/views/privacy_info_view.h
@@ -50,7 +50,7 @@ PrivacyInfoView(int info_string_id, int link_string_id); private: - enum class Action { kNone, kDefault, kTextLink, kCloseButton }; + enum class Action { kNone, kTextLink, kCloseButton }; void InitLayout(); void InitInfoIcon();
diff --git a/ash/app_list/views/search_box_view_unittest.cc b/ash/app_list/views/search_box_view_unittest.cc index 488fa18..75f8e5b 100644 --- a/ash/app_list/views/search_box_view_unittest.cc +++ b/ash/app_list/views/search_box_view_unittest.cc
@@ -667,11 +667,7 @@ EXPECT_TRUE(selection->is_default_result()); EXPECT_EQ(selection, privacy_container_view->GetResultViewAt(0)); - // The privacy view should have two additional non-default actions. - KeyPress(ui::VKEY_TAB); - selection = selection_controller->selected_result(); - EXPECT_EQ(selection, privacy_container_view->GetResultViewAt(0)); - + // The privacy view should have one additional action. KeyPress(ui::VKEY_TAB); selection = selection_controller->selected_result(); EXPECT_EQ(selection, privacy_container_view->GetResultViewAt(0)); @@ -681,26 +677,7 @@ ASSERT_TRUE(selection->result()); EXPECT_EQ(selection->result()->title(), base::ASCIIToUTF16("test")); - // Move focus forward to the close button and then the privacy view again. - // The privacy view should now have only two actions. - KeyPress(ui::VKEY_TAB); - selection = selection_controller->selected_result(); - EXPECT_FALSE(selection); - - KeyPress(ui::VKEY_TAB); - selection = selection_controller->selected_result(); - EXPECT_EQ(selection, privacy_container_view->GetResultViewAt(0)); - - KeyPress(ui::VKEY_TAB); - selection = selection_controller->selected_result(); - EXPECT_EQ(selection, privacy_container_view->GetResultViewAt(0)); - - KeyPress(ui::VKEY_TAB); - selection = selection_controller->selected_result(); - ASSERT_TRUE(selection->result()); - EXPECT_EQ(selection->result()->title(), base::ASCIIToUTF16("test")); - - // When navigating backwards, the privacy notice should have two actions. + // The privacy notice should also have two actions when navigating backwards. KeyPress(ui::VKEY_TAB, /*is_shift_down=*/true); selection = selection_controller->selected_result(); EXPECT_EQ(selection, privacy_container_view->GetResultViewAt(0)); @@ -740,7 +717,6 @@ // Navigate to the close button and press enter. The privacy info should no // longer be shown. KeyPress(ui::VKEY_TAB); - KeyPress(ui::VKEY_TAB); KeyPress(ui::VKEY_RETURN); EXPECT_FALSE(view_delegate()->ShouldShowAssistantPrivacyInfo()); } @@ -769,13 +745,13 @@ selection_controller->selected_result(); EXPECT_EQ(selection, privacy_container_view->GetResultViewAt(0)); - // The privacy view should have two additional actions. Tab to the next - // privacy view action. + // The privacy view should have one additional action. Tab to the next privacy + // view action. KeyPress(ui::VKEY_TAB); selection = selection_controller->selected_result(); EXPECT_EQ(selection, privacy_container_view->GetResultViewAt(0)); - // Create a new search result. The privacy view should only have one action + // Create a new search result. The privacy view should have no actions // remaining. CreateSearchResult(ash::SearchResultDisplayType::kList, 0.5, base::ASCIIToUTF16("testing"), base::string16()); @@ -783,10 +759,6 @@ KeyPress(ui::VKEY_TAB); selection = selection_controller->selected_result(); - EXPECT_EQ(selection, privacy_container_view->GetResultViewAt(0)); - - KeyPress(ui::VKEY_TAB); - selection = selection_controller->selected_result(); ASSERT_TRUE(selection); EXPECT_EQ(selection->result()->title(), base::ASCIIToUTF16("test")); }
diff --git a/ash/capture_mode/capture_label_view.cc b/ash/capture_mode/capture_label_view.cc index e35aef1..0c7d776 100644 --- a/ash/capture_mode/capture_label_view.cc +++ b/ash/capture_mode/capture_label_view.cc
@@ -13,6 +13,7 @@ #include "base/i18n/number_formatting.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/paint_vector_icon.h" +#include "ui/gfx/text_constants.h" #include "ui/views/background.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/label.h" @@ -52,6 +53,14 @@ label_button_->SetPaintToLayer(); label_button_->layer()->SetFillsBoundsOpaquely(false); label_button_->SetEnabledTextColors(text_color); + label_button_->SetHorizontalAlignment(gfx::ALIGN_CENTER); + label_button_->SetNotifyEnterExitOnChild(true); + + label_button_->SetInkDropMode(views::InkDropHostView::InkDropMode::ON); + const auto ripple_attributes = + color_provider->GetRippleAttributes(background_color); + label_button_->SetInkDropVisibleOpacity(ripple_attributes.inkdrop_opacity); + label_button_->SetInkDropBaseColor(ripple_attributes.base_color); label_ = AddChildView(std::make_unique<views::Label>(base::string16())); label_->SetPaintToLayer(); @@ -157,9 +166,7 @@ } void CaptureLabelView::Layout() { - gfx::Rect label_button_bounds = GetLocalBounds(); - label_button_bounds.ClampToCenteredSize(label_button_->GetPreferredSize()); - label_button_->SetBoundsRect(label_button_bounds); + label_button_->SetBoundsRect(GetLocalBounds()); gfx::Rect label_bounds = GetLocalBounds(); label_bounds.ClampToCenteredSize(label_->GetPreferredSize()); @@ -203,4 +210,7 @@ label_->SetText(base::FormatNumber(timeout_count_down_--)); } +BEGIN_METADATA(CaptureLabelView, views::View) +END_METADATA + } // namespace ash
diff --git a/ash/capture_mode/capture_label_view.h b/ash/capture_mode/capture_label_view.h index 7c10ae0..9898ab4 100644 --- a/ash/capture_mode/capture_label_view.h +++ b/ash/capture_mode/capture_label_view.h
@@ -24,6 +24,8 @@ class ASH_EXPORT CaptureLabelView : public views::View, public views::ButtonListener { public: + METADATA_HEADER(CaptureLabelView); + explicit CaptureLabelView(CaptureModeSession* capture_mode_session); CaptureLabelView(const CaptureLabelView&) = delete; CaptureLabelView& operator=(const CaptureLabelView&) = delete;
diff --git a/ash/capture_mode/capture_mode_session.cc b/ash/capture_mode/capture_mode_session.cc index d7bfedf..a61b0fd 100644 --- a/ash/capture_mode/capture_mode_session.cc +++ b/ash/capture_mode/capture_mode_session.cc
@@ -71,6 +71,11 @@ 6, SkColorSetARGB(38, 0, 0, 0)); +// The minimum padding on each side of the capture region. If the capture button +// cannot be placed in the center of the capture region and maintain this +// padding, it will be placed below or above the capture region. +constexpr int kCaptureRegionMinimumPaddingDp = 16; + // Mouse cursor warping is disabled when the capture source is a custom region. // Sets the mouse warp status to |enable| and return the original value. bool SetMouseWarpEnabled(bool enable) { @@ -137,8 +142,9 @@ views::Widget::InitParams CreateWidgetParams(aura::Window* parent, const gfx::Rect& bounds, const std::string& name) { - views::Widget::InitParams params( - views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + // Use a popup widget to get transient properties, such as not needing to + // click on the widget first to get capture before receiving events. + views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent; params.parent = parent; @@ -363,8 +369,8 @@ return; gfx::Point location = event->location(); - aura::Window* source = static_cast<aura::Window*>(event->target()); - aura::Window::ConvertPointToTarget(source, current_root_, &location); + aura::Window* event_target = static_cast<aura::Window*>(event->target()); + aura::Window::ConvertPointToTarget(event_target, current_root_, &location); const bool is_event_on_capture_bar = CaptureModeBarView::GetBounds(current_root_).Contains(location); @@ -381,7 +387,7 @@ case ui::ET_TOUCH_PRESSED: case ui::ET_TOUCH_MOVED: { gfx::Point screen_location(event->location()); - ::wm::ConvertPointToScreen(source, &screen_location); + ::wm::ConvertPointToScreen(event_target, &screen_location); capture_window_observer_->UpdateSelectedWindowAtPosition( screen_location); break; @@ -398,7 +404,7 @@ } // Let the capture button handle any events it can handle first. - if (ShouldCaptureLabelHandleEvent(location)) + if (ShouldCaptureLabelHandleEvent(event_target)) return; // Allow events that are located on the capture mode bar to pass through so we @@ -687,24 +693,57 @@ // For fullscreen and window capture mode, the capture label is placed in the // middle of the screen. For region capture mode, if it's in select phase, the // capture label is also placed in the middle of the screen, and if it's in - // fine tune phase, the capture label is placed in middle of the capture - // region. + // fine tune phase, the capture label is ideally placed in the middle of the + // capture region. If it cannot fit, then it will be placed slightly above or + // below the capture region. gfx::Rect bounds(current_root_->bounds()); const gfx::Rect capture_region = controller_->user_capture_region(); + const gfx::Size preferred_size = + capture_label_widget_->GetContentsView()->GetPreferredSize(); if (controller_->source() == CaptureModeSource::kRegion && !is_selecting_region_ && !capture_region.IsEmpty()) { bounds = capture_region; + + // The capture region must be at least the size of |preferred_size| plus + // some padding for the capture label to be centered inside it. + gfx::Size capture_region_min_size = preferred_size; + capture_region_min_size.Enlarge(kCaptureRegionMinimumPaddingDp, + kCaptureRegionMinimumPaddingDp); + if (bounds.width() > capture_region_min_size.width() && + bounds.height() > capture_region_min_size.height()) { + bounds.ClampToCenteredSize(preferred_size); + } else { + // The capture region is too small for the capture label to be inside it. + // Align |bounds| so that its horizontal centerpoint aligns with the + // capture regions centerpoint. + bounds.set_size(preferred_size); + bounds.set_x(capture_region.CenterPoint().x() - + preferred_size.width() / 2); + + // Try to put the capture label slightly below the capture region. If it + // does not fully fit in the root window bounds, place the capture label + // slightly above. + const int under_region_label_y = + capture_region.bottom() + kCaptureButtonDistanceFromRegionDp; + if (under_region_label_y + preferred_size.height() < + current_root_->bounds().bottom()) { + bounds.set_y(under_region_label_y); + } else { + bounds.set_y(capture_region.y() - kCaptureButtonDistanceFromRegionDp - + preferred_size.height()); + } + } + } else { + bounds.ClampToCenteredSize(preferred_size); } - bounds.ClampToCenteredSize( - capture_label_widget_->GetContentsView()->GetPreferredSize()); + capture_label_widget_->SetBounds(bounds); } bool CaptureModeSession::ShouldCaptureLabelHandleEvent( - const gfx::Point& location_in_root) { + aura::Window* event_target) { if (!capture_label_widget_ || - !capture_label_widget_->GetNativeWindow()->bounds().Contains( - location_in_root)) { + capture_label_widget_->GetNativeWindow() != event_target) { return false; }
diff --git a/ash/capture_mode/capture_mode_session.h b/ash/capture_mode/capture_mode_session.h index ca47e45..9ef22bd 100644 --- a/ash/capture_mode/capture_mode_session.h +++ b/ash/capture_mode/capture_mode_session.h
@@ -48,6 +48,10 @@ // The vertical distance from the size label to the custom capture region. static constexpr int kSizeLabelYDistanceFromRegionDp = 8; + // The vertical distance of the capture button from the capture region, if the + // capture button does not fit inside the capture region. + static constexpr int kCaptureButtonDistanceFromRegionDp = 24; + aura::Window* current_root() const { return current_root_; } CaptureModeBarView* capture_mode_bar_view() const { return capture_mode_bar_view_; @@ -82,6 +86,10 @@ void OnTabletModeStarted() override; void OnTabletModeEnded() override; + views::Widget* capture_label_widget_for_testing() const { + return capture_label_widget_.get(); + } + private: // Gets the bounds of current window selected for |kWindow| capture source. gfx::Rect GetSelectedWindowBounds() const; @@ -132,8 +140,12 @@ // Updates the capture label widget. void UpdateCaptureLabelWidget(); void UpdateCaptureLabelWidgetBounds(); - // Returns true if the capture label should handle the event. - bool ShouldCaptureLabelHandleEvent(const gfx::Point& location_in_root); + + // Returns true if the capture label should handle the event. |event_target| + // is the window which is receiving the event. The capture label should handle + // the event if its associated window is |event_target| and its capture button + // child is visible. + bool ShouldCaptureLabelHandleEvent(aura::Window* event_target); CaptureModeController* const controller_;
diff --git a/ash/capture_mode/capture_mode_unittests.cc b/ash/capture_mode/capture_mode_unittests.cc index 5f11ce50..39c1cad 100644 --- a/ash/capture_mode/capture_mode_unittests.cc +++ b/ash/capture_mode/capture_mode_unittests.cc
@@ -536,6 +536,44 @@ EXPECT_EQ(nullptr, GetDimensionsLabelWindow()); } +TEST_F(CaptureModeTest, CaptureRegionCaptureButtonLocation) { + UpdateDisplay("800x800"); + + auto* controller = StartImageRegionCapture(); + + // Select a large region. Verify that the capture button widget is centered. + SelectRegion(gfx::Rect(100, 100, 600, 600)); + + views::Widget* capture_button_widget = + controller->capture_mode_session()->capture_label_widget_for_testing(); + ASSERT_TRUE(capture_button_widget); + aura::Window* capture_button_window = + capture_button_widget->GetNativeWindow(); + EXPECT_EQ(gfx::Point(400, 400), + capture_button_window->bounds().CenterPoint()); + + // Drag the bottom corner so that the region is too small to fit the capture + // button. Verify that the button is aligned horizontally and placed below the + // region. + auto* event_generator = GetEventGenerator(); + event_generator->DragMouseTo(gfx::Point(120, 120)); + EXPECT_EQ(gfx::Rect(100, 100, 20, 20), controller->user_capture_region()); + EXPECT_EQ(110, capture_button_window->bounds().CenterPoint().x()); + const int distance_from_region = + CaptureModeSession::kCaptureButtonDistanceFromRegionDp; + EXPECT_EQ(120 + distance_from_region, capture_button_window->bounds().y()); + + // Click inside the region to drag the entire region to the bottom of the + // screen. Verify that the button is aligned horizontally and placed above the + // region. + event_generator->set_current_screen_location(gfx::Point(110, 110)); + event_generator->DragMouseTo(gfx::Point(110, 790)); + EXPECT_EQ(gfx::Rect(100, 780, 20, 20), controller->user_capture_region()); + EXPECT_EQ(110, capture_button_window->bounds().CenterPoint().x()); + EXPECT_EQ(780 - distance_from_region, + capture_button_window->bounds().bottom()); +} + TEST_F(CaptureModeTest, WindowCapture) { // Create 2 windows that overlap with each other. const gfx::Rect bounds1(0, 0, 200, 200);
diff --git a/ash/public/cpp/accessibility_controller.h b/ash/public/cpp/accessibility_controller.h index 9c08f80..1cd380a2 100644 --- a/ash/public/cpp/accessibility_controller.h +++ b/ash/public/cpp/accessibility_controller.h
@@ -80,6 +80,9 @@ const gfx::Rect& bounds, std::vector<std::string> actions_to_show) = 0; + // Start Switch Access point scanning + virtual void StartPointScan() = 0; + // Set whether dictation is active. virtual void SetDictationActive(bool is_active) = 0;
diff --git a/ash/public/cpp/caption_buttons/frame_size_button.cc b/ash/public/cpp/caption_buttons/frame_size_button.cc index 5c863e7..e67f494 100644 --- a/ash/public/cpp/caption_buttons/frame_size_button.cc +++ b/ash/public/cpp/caption_buttons/frame_size_button.cc
@@ -7,7 +7,6 @@ #include <memory> #include "ash/public/cpp/caption_buttons/snap_controller.h" -#include "ash/public/cpp/window_properties.h" #include "base/i18n/rtl.h" #include "base/metrics/user_metrics.h" #include "chromeos/ui/base/window_properties.h" @@ -91,7 +90,7 @@ DCHECK_EQ(window_, window); if ((key == chromeos::kIsShowingInOverviewKey && window_->GetProperty(chromeos::kIsShowingInOverviewKey)) || - key == kWindowStateTypeKey) { + key == chromeos::kWindowStateTypeKey) { // If the window is put in overview while we're in waiting-for-snapping // mode, or the window's window state has changed, cancel the snap. size_button_->CancelSnap();
diff --git a/ash/public/cpp/default_frame_header.cc b/ash/public/cpp/default_frame_header.cc index 440cce0..b205f83f 100644 --- a/ash/public/cpp/default_frame_header.cc +++ b/ash/public/cpp/default_frame_header.cc
@@ -9,6 +9,7 @@ #include "ash/public/cpp/caption_buttons/frame_caption_button_container_view.h" #include "ash/public/cpp/window_properties.h" #include "base/logging.h" // DCHECK +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/base/window_state_type.h" #include "third_party/skia/include/core/SkPath.h" #include "ui/gfx/canvas.h" @@ -106,8 +107,8 @@ // DefaultFrameHeader, protected: void DefaultFrameHeader::DoPaintHeader(gfx::Canvas* canvas) { - int corner_radius = IsNormalWindowStateType( - GetTargetWindow()->GetProperty(kWindowStateTypeKey)) + int corner_radius = IsNormalWindowStateType(GetTargetWindow()->GetProperty( + chromeos::kWindowStateTypeKey)) ? kTopCornerRadiusWhenRestored : 0;
diff --git a/ash/public/cpp/window_properties.cc b/ash/public/cpp/window_properties.cc index 84fd5fca..f1b6092d 100644 --- a/ash/public/cpp/window_properties.cc +++ b/ash/public/cpp/window_properties.cc
@@ -84,9 +84,6 @@ kWindowPinTypeKey, WindowPinType::kNone) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kWindowPositionManagedTypeKey, false) -DEFINE_UI_CLASS_PROPERTY_KEY(chromeos::WindowStateType, - kWindowStateTypeKey, - chromeos::WindowStateType::kDefault) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kWindowPipTypeKey, false)
diff --git a/ash/public/cpp/window_properties.h b/ash/public/cpp/window_properties.h index 2d92595..6febe80 100644 --- a/ash/public/cpp/window_properties.h +++ b/ash/public/cpp/window_properties.h
@@ -239,10 +239,6 @@ ASH_PUBLIC_EXPORT extern const aura::WindowProperty<bool>* const kWindowPositionManagedTypeKey; -// A property key to indicate ash's extended window state. -ASH_PUBLIC_EXPORT extern const aura::WindowProperty< - chromeos::WindowStateType>* const kWindowStateTypeKey; - // A property key to indicate pip window state. ASH_PUBLIC_EXPORT extern const aura::WindowProperty<bool>* const kWindowPipTypeKey;
diff --git a/ash/system/message_center/notifier_settings_view.cc b/ash/system/message_center/notifier_settings_view.cc index b7ae214..7f8e6cfe 100644 --- a/ash/system/message_center/notifier_settings_view.cc +++ b/ash/system/message_center/notifier_settings_view.cc
@@ -482,12 +482,12 @@ app_badging_view->SetBorder( views::CreateSolidSidedBorder(0, 0, 0, 1, kTopBorderColor)); header_view->AddChildView(std::move(app_badging_view)); - } - // Separator between toggle button rows. - auto separator = std::make_unique<views::Separator>(); - separator->SetColor(separator_color); - header_view->AddChildView(std::move(separator)); + // Separator between toggle button rows. + auto separator = std::make_unique<views::Separator>(); + separator->SetColor(separator_color); + header_view->AddChildView(std::move(separator)); + } // Row for the quiet mode toggle button. auto quiet_mode_icon = std::make_unique<views::ImageView>(); @@ -552,8 +552,7 @@ kNotificationCenterDoNotDisturbOnIcon, kMenuIconSize, icon_color)); } else { quiet_mode_icon_->SetImage(gfx::CreateVectorIcon( - kNotificationCenterDoNotDisturbOffIcon, kMenuIconSize, - AshColorProvider::GetDisabledColor(icon_color))); + kNotificationCenterDoNotDisturbOffIcon, kMenuIconSize, icon_color)); } }
diff --git a/ash/system/tray/tray_constants.h b/ash/system/tray/tray_constants.h index 045fdcd..40c8f93b 100644 --- a/ash/system/tray/tray_constants.h +++ b/ash/system/tray/tray_constants.h
@@ -107,7 +107,7 @@ constexpr gfx::Insets kUnifiedSliderRowPadding(0, 16, 8, 16); constexpr gfx::Insets kUnifiedSliderBubblePadding(12, 0, 4, 0); constexpr gfx::Insets kUnifiedSliderPadding(0, 16); -constexpr gfx::Insets kMicGainSliderViewPadding(0, 52, 0, 0); +constexpr gfx::Insets kMicGainSliderViewPadding(0, 52, 8, 0); constexpr gfx::Insets kMicGainSliderPadding(0, 8, 0, 48); constexpr int kMicGainSliderViewSpacing = 8; @@ -213,7 +213,8 @@ constexpr int kUnifiedTopShortcutButtonDefaultSpacing = 16; constexpr int kUnifiedTopShortcutButtonMinSpacing = 4; -// Constants used in the title row of a detailed view in UnifiedSystemTray. +// Constants used in the detailed view in UnifiedSystemTray. +constexpr gfx::Insets kUnifiedDetailedViewPadding(0, 0, 8, 0); constexpr gfx::Insets kUnifiedDetailedViewTitlePadding(0, 0, 0, 16); constexpr int kUnifiedDetailedViewTitleRowHeight = 64;
diff --git a/ash/system/tray/tray_detailed_view.cc b/ash/system/tray/tray_detailed_view.cc index dec7cf2..1ad1d1b5 100644 --- a/ash/system/tray/tray_detailed_view.cc +++ b/ash/system/tray/tray_detailed_view.cc
@@ -271,7 +271,7 @@ TrayDetailedView::TrayDetailedView(DetailedViewDelegate* delegate) : delegate_(delegate) { box_layout_ = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical)); + views::BoxLayout::Orientation::kVertical, kUnifiedDetailedViewPadding)); SetBackground(views::CreateSolidBackground( delegate_->GetBackgroundColor().value_or(SK_ColorTRANSPARENT))); }
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index 31ed30d..d094ae1 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -30,6 +30,7 @@ #include "base/auto_reset.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/base/window_state_type.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/layout_manager.h" @@ -621,9 +622,9 @@ window_->SetProperty(aura::client::kShowStateKey, new_window_state); } - if (GetStateType() != window_->GetProperty(kWindowStateTypeKey)) { + if (GetStateType() != window_->GetProperty(chromeos::kWindowStateTypeKey)) { base::AutoReset<bool> resetter(&ignore_property_change_, true); - window_->SetProperty(kWindowStateTypeKey, GetStateType()); + window_->SetProperty(chromeos::kWindowStateTypeKey, GetStateType()); } // sync up current window show state with PinType property. @@ -898,10 +899,10 @@ } return; } - if (key == kWindowStateTypeKey) { + if (key == chromeos::kWindowStateTypeKey) { if (!ignore_property_change_) { // This change came from somewhere else. Revert it. - window->SetProperty(kWindowStateTypeKey, GetStateType()); + window->SetProperty(chromeos::kWindowStateTypeKey, GetStateType()); } return; }
diff --git a/base/BUILD.gn b/base/BUILD.gn index 142c0252..859ccb21 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2135,6 +2135,7 @@ "trace_event/optional_trace_event.h", "trace_event/process_memory_dump.cc", "trace_event/process_memory_dump.h", + "trace_event/task_execution_macros.h", "trace_event/thread_instruction_count.cc", "trace_event/thread_instruction_count.h", "trace_event/trace_arguments.cc",
diff --git a/base/base_paths_fuchsia.cc b/base/base_paths_fuchsia.cc index a7ea21a..933bcd9 100644 --- a/base/base_paths_fuchsia.cc +++ b/base/base_paths_fuchsia.cc
@@ -26,11 +26,11 @@ return true; case DIR_APP_DATA: case DIR_CACHE: - *result = base::FilePath(base::fuchsia::kPersistedDataDirectoryPath); + *result = base::FilePath(base::kPersistedDataDirectoryPath); return true; case DIR_ASSETS: case DIR_SOURCE_ROOT: - *result = base::FilePath(base::fuchsia::kPackageRootDirectoryPath); + *result = base::FilePath(base::kPackageRootDirectoryPath); return true; } return false;
diff --git a/base/fuchsia/file_utils.cc b/base/fuchsia/file_utils.cc index 3abce00a..1a7a63c 100644 --- a/base/fuchsia/file_utils.cc +++ b/base/fuchsia/file_utils.cc
@@ -17,14 +17,13 @@ #include "base/macros.h" namespace base { -namespace fuchsia { const char kPersistedDataDirectoryPath[] = "/data"; const char kPersistedCacheDirectoryPath[] = "/cache"; const char kServiceDirectoryPath[] = "/svc"; const char kPackageRootDirectoryPath[] = "/pkg"; -fidl::InterfaceHandle<::fuchsia::io::Directory> OpenDirectory( +fidl::InterfaceHandle<::fuchsia::io::Directory> OpenDirectoryHandle( const base::FilePath& path) { ScopedFD fd(open(path.value().c_str(), O_DIRECTORY | O_RDONLY)); if (!fd.is_valid()) { @@ -45,5 +44,20 @@ return fidl::InterfaceHandle<::fuchsia::io::Directory>(std::move(channel)); } +// TODO(crbug.com/1073821): Remove this block when out-of-tree callers have been +// changed to use the non-fuchsia-sub-namespace version. +namespace fuchsia { + +const char kPersistedDataDirectoryPath[] = "/data"; +const char kPersistedCacheDirectoryPath[] = "/cache"; +const char kServiceDirectoryPath[] = "/svc"; +const char kPackageRootDirectoryPath[] = "/pkg"; + +fidl::InterfaceHandle<::fuchsia::io::Directory> OpenDirectory( + const base::FilePath& path) { + return ::base::OpenDirectoryHandle(path); +} + } // namespace fuchsia + } // namespace base
diff --git a/base/fuchsia/file_utils.h b/base/fuchsia/file_utils.h index 35b08c5..8e3a197 100644 --- a/base/fuchsia/file_utils.h +++ b/base/fuchsia/file_utils.h
@@ -11,7 +11,6 @@ #include "base/files/file_path.h" namespace base { -namespace fuchsia { // Persisted data directory, i.e. /data . Returned as DIR_APP_DATA from // PathService. @@ -28,10 +27,22 @@ // Returns fuchsia.io.Directory for the specified |path| or null InterfaceHandle // if the path doesn't exist or it's not a directory. +BASE_EXPORT fidl::InterfaceHandle<::fuchsia::io::Directory> OpenDirectoryHandle( + const base::FilePath& path); + +// TODO(crbug.com/1073821): Remove this block when out-of-tree callers have been +// changed to use the non-fuchsia-sub-namespace version. +namespace fuchsia { + +BASE_EXPORT extern const char kPersistedDataDirectoryPath[]; +BASE_EXPORT extern const char kPersistedCacheDirectoryPath[]; +BASE_EXPORT extern const char kServiceDirectoryPath[]; +BASE_EXPORT extern const char kPackageRootDirectoryPath[]; BASE_EXPORT fidl::InterfaceHandle<::fuchsia::io::Directory> OpenDirectory( const base::FilePath& path); } // namespace fuchsia + } // namespace base #endif // BASE_FUCHSIA_FILE_UTILS_H_
diff --git a/base/fuchsia/file_utils_unittest.cc b/base/fuchsia/file_utils_unittest.cc index 810732b..5a43e24 100644 --- a/base/fuchsia/file_utils_unittest.cc +++ b/base/fuchsia/file_utils_unittest.cc
@@ -9,7 +9,6 @@ #include "testing/gtest/include/gtest/gtest.h" namespace base { -namespace fuchsia { class OpenDirectoryTest : public testing::Test { protected: @@ -22,23 +21,32 @@ }; TEST_F(OpenDirectoryTest, Open) { - auto dir = OpenDirectory(temp_dir.GetPath()); + auto dir = OpenDirectoryHandle(temp_dir.GetPath()); ASSERT_TRUE(dir); } -// OpenDirectory() should fail when opening a directory that doesn't exist. +// OpenDirectoryHandle() should fail when opening a directory that doesn't +// exist. TEST_F(OpenDirectoryTest, OpenNonExistent) { - auto dir = OpenDirectory(temp_dir.GetPath().AppendASCII("non_existent")); + auto dir = + OpenDirectoryHandle(temp_dir.GetPath().AppendASCII("non_existent")); ASSERT_FALSE(dir); } -// OpenDirectory() should open only directories. +// OpenDirectoryHandle() should open only directories. TEST_F(OpenDirectoryTest, OpenFile) { auto file_path = temp_dir.GetPath().AppendASCII("test_file"); ASSERT_TRUE(WriteFile(file_path, "foo")); - auto dir = OpenDirectory(file_path); + auto dir = OpenDirectoryHandle(file_path); ASSERT_FALSE(dir); } -} // namespace fuchsia +// TODO(crbug.com/1073821): Remove this test. +// Tests the deprecated ::base::fuchsia::OpenDirectory() function works until +// all callers have been removed. +TEST_F(OpenDirectoryTest, OpenTransitional) { + auto dir = ::base::fuchsia::OpenDirectory(temp_dir.GetPath()); + ASSERT_TRUE(dir); +} + } // namespace base
diff --git a/base/numerics/safe_conversions.h b/base/numerics/safe_conversions.h index 7c1c265..34f4cb85 100644 --- a/base/numerics/safe_conversions.h +++ b/base/numerics/safe_conversions.h
@@ -13,7 +13,7 @@ #include "base/numerics/safe_conversions_impl.h" -#if !defined(__native_client__) && (defined(__ARMEL__) || defined(__arch64__)) +#if defined(__ARMEL__) && !defined(__native_client__) #include "base/numerics/safe_conversions_arm_impl.h" #define BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS (1) #else
diff --git a/base/process/launch_fuchsia.cc b/base/process/launch_fuchsia.cc index 17ea46f..fe39f485 100644 --- a/base/process/launch_fuchsia.cc +++ b/base/process/launch_fuchsia.cc
@@ -165,7 +165,7 @@ environ_modifications["PWD"] = cwd.value(); } - std::unique_ptr<char* []> new_environ; + std::unique_ptr<char*[]> new_environ; if (!environ_modifications.empty()) { char* const empty_environ = nullptr; char* const* old_environ = @@ -193,7 +193,7 @@ for (const auto& path_to_clone : options.paths_to_clone) { fidl::InterfaceHandle<::fuchsia::io::Directory> directory = - base::fuchsia::OpenDirectory(path_to_clone); + base::OpenDirectoryHandle(path_to_clone); if (!directory) { LOG(WARNING) << "Could not open handle for path: " << path_to_clone; return base::Process();
diff --git a/base/process/process_util_unittest.cc b/base/process/process_util_unittest.cc index 24ed3d1f..5593524 100644 --- a/base/process/process_util_unittest.cc +++ b/base/process/process_util_unittest.cc
@@ -266,12 +266,11 @@ // Attach the tempdir to "data", but also try to duplicate the existing "data" // directory. options.paths_to_clone.push_back( - base::FilePath(base::fuchsia::kPersistedDataDirectoryPath)); + base::FilePath(base::kPersistedDataDirectoryPath)); options.paths_to_clone.push_back(base::FilePath("/tmp")); options.paths_to_transfer.push_back( - {FilePath(base::fuchsia::kPersistedDataDirectoryPath), - base::fuchsia::OpenDirectory( - base::FilePath(tmpdir_with_staged.GetPath())) + {FilePath(base::kPersistedDataDirectoryPath), + base::OpenDirectoryHandle(base::FilePath(tmpdir_with_staged.GetPath())) .TakeChannel() .release()}); @@ -310,7 +309,7 @@ // Mount the tempdir to "/foo". zx::channel tmp_channel = - base::fuchsia::OpenDirectory(new_tmpdir.GetPath()).TakeChannel(); + base::OpenDirectoryHandle(new_tmpdir.GetPath()).TakeChannel(); ASSERT_TRUE(tmp_channel.is_valid()); LaunchOptions options; @@ -641,7 +640,7 @@ #endif TEST_F(ProcessUtilTest, MAYBE_GetTerminationStatusCrash) { const std::string signal_file = - ProcessUtilTest::GetSignalFilePath(kSignalFileCrash); + ProcessUtilTest::GetSignalFilePath(kSignalFileCrash); remove(signal_file.c_str()); Process process = SpawnChild("CrashingChildProcess"); ASSERT_TRUE(process.IsValid()); @@ -705,7 +704,7 @@ #endif TEST_F(ProcessUtilTest, MAYBE_GetTerminationStatusSigKill) { const std::string signal_file = - ProcessUtilTest::GetSignalFilePath(kSignalFileKill); + ProcessUtilTest::GetSignalFilePath(kSignalFileKill); remove(signal_file.c_str()); Process process = SpawnChild("KilledChildProcess"); ASSERT_TRUE(process.IsValid()); @@ -742,7 +741,7 @@ // test might not be relevant anyway. TEST_F(ProcessUtilTest, GetTerminationStatusSigTerm) { const std::string signal_file = - ProcessUtilTest::GetSignalFilePath(kSignalFileTerm); + ProcessUtilTest::GetSignalFilePath(kSignalFileTerm); remove(signal_file.c_str()); Process process = SpawnChild("TerminatedChildProcess"); ASSERT_TRUE(process.IsValid()); @@ -972,11 +971,13 @@ // // Atomically replaces |guard|/|guardflags| with |nguard|/|nguardflags| on |fd|. int change_fdguard_np(int fd, - const guardid_t *guard, u_int guardflags, - const guardid_t *nguard, u_int nguardflags, - int *fdflagsp) { - return syscall(SYS_change_fdguard_np, fd, guard, guardflags, - nguard, nguardflags, fdflagsp); + const guardid_t* guard, + u_int guardflags, + const guardid_t* nguard, + u_int nguardflags, + int* fdflagsp) { + return syscall(SYS_change_fdguard_np, fd, guard, guardflags, nguard, + nguardflags, fdflagsp); } // Attempt to set a file-descriptor guard on |fd|. In case of success, remove @@ -1036,8 +1037,8 @@ } } - int written = HANDLE_EINTR(write(write_pipe, &num_open_files, - sizeof(num_open_files))); + int written = + HANDLE_EINTR(write(write_pipe, &num_open_files, sizeof(num_open_files))); DCHECK_EQ(static_cast<size_t>(written), sizeof(num_open_files)); int ret = IGNORE_EINTR(close(write_pipe)); DPCHECK(ret == 0);
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index 3cf448d6..a62b35b 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -332,7 +332,7 @@ // that we can install a different /data. new_options.spawn_flags = FDIO_SPAWN_CLONE_STDIO | FDIO_SPAWN_CLONE_JOB; - const base::FilePath kDataPath(base::fuchsia::kPersistedDataDirectoryPath); + const base::FilePath kDataPath(base::kPersistedDataDirectoryPath); // Clone all namespace entries from the current process, except /data, which // is overridden below. @@ -375,7 +375,7 @@ // Bind the new test subdirectory to /data in the child process' namespace. new_options.paths_to_transfer.push_back( {kDataPath, - base::fuchsia::OpenDirectory(nested_data_path).TakeChannel().release()}); + base::OpenDirectoryHandle(nested_data_path).TakeChannel().release()}); #endif // defined(OS_FUCHSIA) #if defined(OS_LINUX) || defined(OS_CHROMEOS)
diff --git a/base/trace_event/base_tracing.h b/base/trace_event/base_tracing.h index c5831f237d..ae3c60e7 100644 --- a/base/trace_event/base_tracing.h +++ b/base/trace_event/base_tracing.h
@@ -16,8 +16,10 @@ // Update the check in //base/PRESUBMIT.py when adding new headers here. // TODO(crbug/1006541): Switch to perfetto for trace event implementation. #include "base/trace_event/blame_context.h" +#include "base/trace_event/heap_profiler.h" #include "base/trace_event/memory_allocator_dump_guid.h" #include "base/trace_event/memory_dump_provider.h" +#include "base/trace_event/task_execution_macros.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/traced_value.h" #include "base/trace_event/typed_macros.h"
diff --git a/base/trace_event/common/trace_event_common.h b/base/trace_event/common/trace_event_common.h index 28b7275..120481f3 100644 --- a/base/trace_event/common/trace_event_common.h +++ b/base/trace_event/common/trace_event_common.h
@@ -969,6 +969,7 @@ #define TRACE_TASK_EXECUTION(run_function, task) \ INTERNAL_TRACE_TASK_EXECUTION(run_function, task) +// Special trace event macro to trace log messages. #define TRACE_LOG_MESSAGE(file, message, line) \ INTERNAL_TRACE_LOG_MESSAGE(file, message, line)
diff --git a/base/trace_event/task_execution_macros.h b/base/trace_event/task_execution_macros.h new file mode 100644 index 0000000..156bcf0 --- /dev/null +++ b/base/trace_event/task_execution_macros.h
@@ -0,0 +1,121 @@ +// 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 BASE_TRACE_EVENT_TASK_EXECUTION_MACROS_H_ +#define BASE_TRACE_EVENT_TASK_EXECUTION_MACROS_H_ + +#include "base/location.h" +#include "base/trace_event/heap_profiler.h" +#include "base/trace_event/typed_macros.h" +#include "third_party/perfetto/include/perfetto/tracing/track_event_interned_data_index.h" +#include "third_party/perfetto/protos/perfetto/trace/interned_data/interned_data.pbzero.h" +#include "third_party/perfetto/protos/perfetto/trace/track_event/log_message.pbzero.h" +#include "third_party/perfetto/protos/perfetto/trace/track_event/source_location.pbzero.h" +#include "third_party/perfetto/protos/perfetto/trace/track_event/task_execution.pbzero.h" + +namespace { + +// TrackEventInternedDataIndex expects the same data structure to be used for +// all interned fields with the same field number. We can't use base::Location +// for log event's location since base::Location uses program counter based +// location. +struct TraceSourceLocation { + const char* function_name = nullptr; + const char* file_name = nullptr; + int line_number = 0; + + bool operator==(const TraceSourceLocation& other) const { + return file_name == other.file_name && + function_name == other.function_name && + line_number == other.line_number; + } +}; + +} // namespace + +namespace std { + +template <> +struct ::std::hash<TraceSourceLocation> { + std::size_t operator()(const TraceSourceLocation& loc) const { + return base::FastHash(base::as_bytes(base::make_span(&loc, 1))); + } +}; + +} // namespace std + +namespace { + +struct InternedSourceLocation + : public perfetto::TrackEventInternedDataIndex< + InternedSourceLocation, + perfetto::protos::pbzero::InternedData::kSourceLocationsFieldNumber, + TraceSourceLocation> { + static void Add(perfetto::protos::pbzero::InternedData* interned_data, + size_t iid, + const TraceSourceLocation& location) { + auto* msg = interned_data->add_source_locations(); + msg->set_iid(iid); + if (location.file_name != nullptr) + msg->set_file_name(location.file_name); + if (location.function_name != nullptr) + msg->set_function_name(location.function_name); + // TODO(ssid): Add line number once it is whitelisted in internal proto. + // TODO(ssid): Add program counter to the proto fields when + // !BUILDFLAG(ENABLE_LOCATION_SOURCE). + // TODO(http://crbug.com760702) remove file name and just pass the program + // counter to the heap profiler macro. + // TODO(ssid): Consider writing the program counter of the current task + // (from the callback function pointer) instead of location that posted the + // task. + } +}; + +struct InternedLogMessage + : public perfetto::TrackEventInternedDataIndex< + InternedLogMessage, + perfetto::protos::pbzero::InternedData::kLogMessageBodyFieldNumber, + std::string> { + static void Add(perfetto::protos::pbzero::InternedData* interned_data, + size_t iid, + const std::string& log_message) { + auto* msg = interned_data->add_log_message_body(); + msg->set_iid(iid); + msg->set_body(log_message); + } +}; + +} // namespace + +// Implementation detail: internal macro to trace a task execution with the +// location where it was posted from. +#define INTERNAL_TRACE_TASK_EXECUTION(run_function, task) \ + TRACE_EVENT("toplevel", run_function, [&](perfetto::EventContext ctx) { \ + ctx.event()->set_task_execution()->set_posted_from_iid( \ + InternedSourceLocation::Get(&ctx, \ + {(task).posted_from.function_name(), \ + (task).posted_from.file_name(), \ + (task).posted_from.line_number()})); \ + }); \ + TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION INTERNAL_TRACE_EVENT_UID( \ + task_event)((task).posted_from.file_name()); \ + TRACE_HEAP_PROFILER_API_SCOPED_WITH_PROGRAM_COUNTER \ + INTERNAL_TRACE_EVENT_UID(task_pc_event) \ + ((task).posted_from.program_counter()); + +// Implementation detail: internal macro to trace a log message, with the source +// location of the log statement. +#define INTERNAL_TRACE_LOG_MESSAGE(file, message, line) \ + TRACE_EVENT_INSTANT( \ + "log", "LogMessage", TRACE_EVENT_SCOPE_THREAD, \ + [&](perfetto::EventContext ctx) { \ + perfetto::protos::pbzero::LogMessage* log = \ + ctx.event()->set_log_message(); \ + log->set_source_location_iid(InternedSourceLocation::Get( \ + &ctx, \ + TraceSourceLocation{/*function_name=*/nullptr, file, line})); \ + log->set_body_iid(InternedLogMessage::Get(&ctx, message.as_string())); \ + }); + +#endif // BASE_TRACE_EVENT_TASK_EXECUTION_MACROS_H_
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h index 6c6a6c0..a0cd28cf 100644 --- a/base/trace_event/trace_event.h +++ b/base/trace_event/trace_event.h
@@ -22,7 +22,6 @@ #include "base/time/time_override.h" #include "base/trace_event/builtin_categories.h" #include "base/trace_event/common/trace_event_common.h" -#include "base/trace_event/heap_profiler.h" #include "base/trace_event/log_message.h" #include "base/trace_event/thread_instruction_count.h" #include "base/trace_event/trace_arguments.h" @@ -390,45 +389,6 @@ } \ } while (0) -#define INTERNAL_TRACE_LOG_MESSAGE(file, message, line) \ - TRACE_EVENT_INSTANT1( \ - "log", "LogMessage", \ - TRACE_EVENT_FLAG_TYPED_PROTO_ARGS | TRACE_EVENT_SCOPE_THREAD, "message", \ - std::make_unique<base::trace_event::LogMessage>(file, message, line)) - -#if BUILDFLAG(ENABLE_LOCATION_SOURCE) - -// Implementation detail: internal macro to trace a task execution with the -// location where it was posted from. -// -// This implementation is for when location sources are available. -// TODO(ssid): The program counter of the current task should be added here. -#define INTERNAL_TRACE_TASK_EXECUTION(run_function, task) \ - INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLAGS( \ - "toplevel", run_function, TRACE_EVENT_FLAG_TYPED_PROTO_ARGS, "src_file", \ - (task).posted_from.file_name(), "src_func", \ - (task).posted_from.function_name()); \ - TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION INTERNAL_TRACE_EVENT_UID( \ - task_event)((task).posted_from.file_name()); \ - TRACE_HEAP_PROFILER_API_SCOPED_WITH_PROGRAM_COUNTER \ - INTERNAL_TRACE_EVENT_UID(task_pc_event)((task).posted_from.program_counter()); - -#else - -// TODO(http://crbug.com760702) remove file name and just pass the program -// counter to the heap profiler macro. -// TODO(ssid): The program counter of the current task should be added here. -#define INTERNAL_TRACE_TASK_EXECUTION(run_function, task) \ - INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLAGS( \ - "toplevel", run_function, TRACE_EVENT_FLAG_TYPED_PROTO_ARGS, "src", \ - (task).posted_from.ToString()) \ - TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION INTERNAL_TRACE_EVENT_UID( \ - task_event)((task).posted_from.file_name()); \ - TRACE_HEAP_PROFILER_API_SCOPED_WITH_PROGRAM_COUNTER \ - INTERNAL_TRACE_EVENT_UID(task_pc_event)((task).posted_from.program_counter()); - -#endif - namespace trace_event_internal { // Specify these values when the corresponding argument of AddTraceEvent is not
diff --git a/build/fuchsia/aemu_target.py b/build/fuchsia/aemu_target.py index 684b019..f9fc6af 100644 --- a/build/fuchsia/aemu_target.py +++ b/build/fuchsia/aemu_target.py
@@ -20,10 +20,19 @@ class AemuTarget(qemu_target.QemuTarget): EMULATOR_NAME = 'aemu' - def __init__(self, out_dir, target_cpu, system_log_file, cpu_cores, - require_kvm, ram_size_mb, enable_graphics, hardware_gpu): - super(AemuTarget, self).__init__(out_dir, target_cpu, system_log_file, - cpu_cores, require_kvm, ram_size_mb) + def __init__(self, + out_dir, + target_cpu, + system_log_file, + cpu_cores, + require_kvm, + ram_size_mb, + enable_graphics, + hardware_gpu, + fuchsia_out_dir=None): + super(AemuTarget, + self).__init__(out_dir, target_cpu, system_log_file, cpu_cores, + require_kvm, ram_size_mb, fuchsia_out_dir) # TODO(crbug.com/1000907): Enable AEMU for arm64. if platform.machine() == 'aarch64':
diff --git a/build/fuchsia/common_args.py b/build/fuchsia/common_args.py index 6b3916c..5a8ce9eb 100644 --- a/build/fuchsia/common_args.py +++ b/build/fuchsia/common_args.py
@@ -43,6 +43,11 @@ 'subclass of Target that will be used. Only ' 'needed if device specific operations such as ' 'paving is required.') + device_args.add_argument('--fuchsia-out-dir', + help='Path to a Fuchsia build output directory. ' + 'Setting the GN arg ' + '"default_fuchsia_build_dir_for_installation" ' + 'will cause it to be passed here.') def _GetTargetClass(args): @@ -107,11 +112,6 @@ common_args.add_argument('--verbose', '-v', default=False, action='store_true', help='Enable debug-level logging.') - common_args.add_argument('--fuchsia-out-dir', - nargs='+', - help='Path to a Fuchsia build output directory. ' - 'If more than one outdir is supplied, the last one ' - 'in the sequence will be used.') def ConfigureLogging(args): @@ -150,10 +150,12 @@ known_args, _ = target_arg_parser.parse_known_args() target_args = vars(known_args) - # target_cpu is needed to determine target type, so we need to add - # it here to the args used to initialize the Target. + # target_cpu is needed to determine target type, and fuchsia_out_dir + # is needed for devices with Fuchsia built from source code. target_args.update({'target_cpu': module_args.target_cpu}) + target_args.update({'fuchsia_out_dir': module_args.fuchsia_out_dir}) if additional_args: target_args.update(additional_args) + return target_class(**target_args)
diff --git a/build/fuchsia/deploy_to_amber_repo.py b/build/fuchsia/deploy_to_amber_repo.py index 02dcf25..80ac2fe 100755 --- a/build/fuchsia/deploy_to_amber_repo.py +++ b/build/fuchsia/deploy_to_amber_repo.py
@@ -38,21 +38,16 @@ parser = argparse.ArgumentParser() parser.add_argument('--package', action='append', required=True, help='Paths to packages to install.') - parser.add_argument('--fuchsia-out-dir', nargs='+', + parser.add_argument('--fuchsia-out-dir', + required=True, help='Path to a Fuchsia build output directory. ' - 'If more than one outdir is supplied, the last one ' - 'in the sequence will be used.') + 'Setting the GN arg ' + '"default_fuchsia_build_dir_for_installation" ' + 'will cause it to be passed here.') args = parser.parse_args() assert args.package - if not args.fuchsia_out_dir or len(args.fuchsia_out_dir) == 0: - sys.stderr.write('No Fuchsia build output directory was specified.\n' + - 'To resolve this, Use the commandline argument ' + - '--fuchsia-out-dir\nor set the GN arg ' + - '"default_fuchsia_build_dir_for_installation".\n') - return 1 - - fuchsia_out_dir = os.path.expanduser(args.fuchsia_out_dir.pop()) + fuchsia_out_dir = os.path.expanduser(args.fuchsia_out_dir) repo = amber_repo.ExternalAmberRepo( os.path.join(fuchsia_out_dir, 'amber-files')) print('Installing packages and symbols in Amber repo %s...' % repo.GetPath())
diff --git a/build/fuchsia/device_target.py b/build/fuchsia/device_target.py index f68dbff1..17310d5 100644 --- a/build/fuchsia/device_target.py +++ b/build/fuchsia/device_target.py
@@ -89,8 +89,6 @@ self._host = host self._port = port self._fuchsia_out_dir = None - if fuchsia_out_dir: - self._fuchsia_out_dir = os.path.expanduser(fuchsia_out_dir) self._node_name = node_name self._os_check = os_check self._amber_repo = None @@ -98,7 +96,7 @@ if self._host and self._node_name: raise Exception('Only one of "--host" or "--name" can be specified.') - if self._fuchsia_out_dir: + if fuchsia_out_dir: if ssh_config: raise Exception('Only one of "--fuchsia-out-dir" or "--ssh_config" can ' 'be specified.')
diff --git a/build/fuchsia/emu_target.py b/build/fuchsia/emu_target.py index 440f1ab7..22726cb 100644 --- a/build/fuchsia/emu_target.py +++ b/build/fuchsia/emu_target.py
@@ -16,12 +16,15 @@ class EmuTarget(target.Target): - def __init__(self, out_dir, target_cpu, system_log_file): + def __init__(self, out_dir, target_cpu, system_log_file, fuchsia_out_dir): """out_dir: The directory which will contain the files that are generated to support the emulator deployment. target_cpu: The emulated target CPU architecture. Can be 'x64' or 'arm64'.""" + # fuchsia_out_dir is unused by emulator targets. + del fuchsia_out_dir + super(EmuTarget, self).__init__(out_dir, target_cpu) self._emu_process = None self._system_log_file = system_log_file
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index a3a002f8..ba36bfc 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20201009.3.1 +0.20201010.1.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index a3a002f8..ba36bfc 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20201009.3.1 +0.20201010.1.1
diff --git a/build/fuchsia/qemu_target.py b/build/fuchsia/qemu_target.py index 6c858233..d43e9d3 100644 --- a/build/fuchsia/qemu_target.py +++ b/build/fuchsia/qemu_target.py
@@ -40,9 +40,16 @@ class QemuTarget(emu_target.EmuTarget): EMULATOR_NAME = 'qemu' - def __init__(self, out_dir, target_cpu, system_log_file, cpu_cores, - require_kvm, ram_size_mb): - super(QemuTarget, self).__init__(out_dir, target_cpu, system_log_file) + def __init__(self, + out_dir, + target_cpu, + system_log_file, + cpu_cores, + require_kvm, + ram_size_mb, + fuchsia_out_dir=None): + super(QemuTarget, self).__init__(out_dir, target_cpu, system_log_file, + fuchsia_out_dir) self._cpu_cores=cpu_cores self._require_kvm=require_kvm self._ram_size_mb=ram_size_mb
diff --git a/cc/raster/synchronous_task_graph_runner.cc b/cc/raster/synchronous_task_graph_runner.cc index b7e0e94..03a5a46 100644 --- a/cc/raster/synchronous_task_graph_runner.cc +++ b/cc/raster/synchronous_task_graph_runner.cc
@@ -10,6 +10,7 @@ #include <utility> #include "base/threading/simple_thread.h" +#include "base/trace_event/heap_profiler.h" #include "base/trace_event/trace_event.h" namespace cc {
diff --git a/chrome/VERSION b/chrome/VERSION index a311285..3ad2607 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=88 MINOR=0 -BUILD=4288 +BUILD=4289 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 8f36311..5847138f 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -418,6 +418,7 @@ "//components/media_router/browser/android:java", "//components/messages/android:factory_java", "//components/messages/android:java", + "//components/messages/android:manager_java", "//components/minidump_uploader:minidump_uploader_java", "//components/module_installer/android:module_installer_java", "//components/module_installer/android:module_interface_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java index a70a738..e1c6796 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -81,7 +81,7 @@ import org.chromium.components.browser_ui.widget.MenuOrKeyboardActionController; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; import org.chromium.components.feature_engagement.EventConstants; -import org.chromium.components.messages.MessageQueueManager; +import org.chromium.components.messages.ManagedMessageDispatcher; import org.chromium.components.messages.MessagesFactory; import org.chromium.content_public.browser.ActionModeCallbackHelper; import org.chromium.content_public.browser.LoadUrlParams; @@ -158,7 +158,7 @@ private ObservableSupplier<TabModelSelector> mTabModelSelectorSupplier; private final OneshotSupplier<StartSurface> mStartSurfaceSupplier; @Nullable - private MessageQueueManager mMessageQueueManager; + private ManagedMessageDispatcher mMessageDispatcher; /** * Create a new {@link RootUiCoordinator} for the given activity. @@ -215,11 +215,6 @@ mOverviewModeBehaviorSupplier.onAvailable( mCallbackController.makeCancelable(this::setOverviewModeBehavior)); mStartSurfaceSupplier = startSurfaceSupplier; - - if (CachedFeatureFlags.isEnabled(ChromeFeatureList.MESSAGES_FOR_ANDROID_INFRASTRUCTURE)) { - mMessageQueueManager = - MessagesFactory.createMessageQueueManager(mActivity.getWindowAndroid()); - } } // TODO(pnoland, crbug.com/865801): remove this in favor of wiring it directly. @@ -234,9 +229,9 @@ mActivity.getLayoutManagerSupplier().removeObserver(mLayoutManagerSupplierCallback); - if (mMessageQueueManager != null) { - mMessageQueueManager.destroy(); - mMessageQueueManager = null; + if (mMessageDispatcher != null) { + MessagesFactory.detachMessageDispatcher(mMessageDispatcher); + mMessageDispatcher = null; } if (mOverlayPanelManager != null) { @@ -321,6 +316,12 @@ initFindToolbarManager(); initializeToolbar(); + if (CachedFeatureFlags.isEnabled(ChromeFeatureList.MESSAGES_FOR_ANDROID_INFRASTRUCTURE)) { + mMessageDispatcher = MessagesFactory.createMessageDispatcher( + mActivity.findViewById(R.id.message_container)); + MessagesFactory.attachMessageDispatcher( + mActivity.getWindowAndroid(), mMessageDispatcher); + } } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java index 9a5fda7d..e1418d9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java
@@ -5,7 +5,7 @@ package org.chromium.chrome.browser.ntp; import android.accounts.Account; -import android.support.test.InstrumentationRegistry; +import android.app.Activity; import android.view.View; import androidx.test.filters.LargeTest; @@ -21,7 +21,6 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -35,7 +34,6 @@ 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.content_public.browser.test.util.TestTouchUtils; import org.chromium.content_public.common.ContentUrlConstants; import org.chromium.url.GURL; @@ -86,7 +84,6 @@ @Test @MediumTest @Feature({"RecentTabsPage"}) - @FlakyTest(message = "crbug.com/1075804") public void testRecentlyClosedTabs() throws ExecutionException { mPage = loadRecentTabsPage(); // Set a recently closed tab and confirm a view is rendered for it. @@ -96,7 +93,8 @@ View view = waitForView(title); // Clear the recently closed tabs with the context menu and confirm the view is gone. - invokeContextMenu(view, RecentTabsRowAdapter.RecentlyClosedTabsGroup.ID_REMOVE_ALL); + openContextMenuAndInvokeItem(mActivityTestRule.getActivity(), view, + RecentTabsRowAdapter.RecentlyClosedTabsGroup.ID_REMOVE_ALL); Assert.assertEquals(0, mManager.getRecentlyClosedTabs(1).size()); waitForViewToDisappear(title); } @@ -193,10 +191,13 @@ }); } - private void invokeContextMenu(View view, int contextMenuItemId) throws ExecutionException { - TestTouchUtils.performLongClickOnMainSync( - InstrumentationRegistry.getInstrumentation(), view); - Assert.assertTrue(InstrumentationRegistry.getInstrumentation().invokeContextMenuAction( - mActivityTestRule.getActivity(), contextMenuItemId, 0)); + private static void openContextMenuAndInvokeItem( + final Activity activity, final View view, final int itemId) { + // IMPLEMENTATION NOTE: Instrumentation.invokeContextMenuAction would've been much simpler, + // but it requires the View to be focused which is hard to achieve in touch mode. + TestThreadUtils.runOnUiThreadBlocking(() -> { + view.performLongClick(); + activity.getWindow().performContextMenuIdentifierAction(itemId, 0); + }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java index c21e78e..7edcca5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java
@@ -25,7 +25,6 @@ import org.chromium.base.task.PostTask; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisableIf; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.MetricsUtils.HistogramDelta; import org.chromium.base.test.util.UrlUtils; import org.chromium.blink.mojom.MhtmlLoadResult; @@ -211,7 +210,6 @@ @Test @SmallTest - @DisabledTest(message = "crbug.com/786237") public void testShowOfflineSnackbarIfNecessary() throws Exception { // Arrange - build a mock controller for sensing. OfflinePageUtils.setSnackbarDurationForTesting(1000);
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 3afb55c..708a905 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-88.0.4285.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-amd64-88.0.4288.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index d7758580..3afcc3c 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3669,9 +3669,6 @@ {"arc-usb-host", flag_descriptions::kArcUsbHostName, flag_descriptions::kArcUsbHostDescription, kOsCrOS, FEATURE_VALUE_TYPE(arc::kUsbHostFeature)}, - {"arc-usb-storage-ui", flag_descriptions::kArcUsbStorageUIName, - flag_descriptions::kArcUsbStorageUIDescription, kOsCrOS, - FEATURE_VALUE_TYPE(arc::kUsbStorageUIFeature)}, #endif // OS_CHROMEOS #if defined(OS_WIN) {"enable-winrt-sensor-implementation",
diff --git a/chrome/browser/accessibility/accessibility_extension_api.cc b/chrome/browser/accessibility/accessibility_extension_api.cc index f218223..12525d2 100644 --- a/chrome/browser/accessibility/accessibility_extension_api.cc +++ b/chrome/browser/accessibility/accessibility_extension_api.cc
@@ -501,6 +501,21 @@ return RespondNow(NoArguments()); } +ExtensionFunction::ResponseAction +AccessibilityPrivateEnablePointScanFunction::Run() { + std::unique_ptr<accessibility_private::EnablePointScan::Params> params = + accessibility_private::EnablePointScan::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(params); + + if (params->enabled) { + ash::AccessibilityController::Get()->StartPointScan(); + } + + // TODO(crbug.com/1061537): Implement (!params->enabled) to disable point scan + + return RespondNow(NoArguments()); +} + AccessibilityPrivateGetBatteryDescriptionFunction:: AccessibilityPrivateGetBatteryDescriptionFunction() {}
diff --git a/chrome/browser/accessibility/accessibility_extension_api.h b/chrome/browser/accessibility/accessibility_extension_api.h index 2c95b9f..99fa27b 100644 --- a/chrome/browser/accessibility/accessibility_extension_api.h +++ b/chrome/browser/accessibility/accessibility_extension_api.h
@@ -159,6 +159,15 @@ ACCESSIBILITY_PRIVATE_UPDATESWITCHACCESSBUBBLE) }; +// API function that is called to start or end point scanning of the +// Switch Access extension. +class AccessibilityPrivateEnablePointScanFunction : public ExtensionFunction { + ~AccessibilityPrivateEnablePointScanFunction() override {} + ResponseAction Run() override; + DECLARE_EXTENSION_FUNCTION("accessibilityPrivate.enablePointScan", + ACCESSIBILITY_PRIVATE_ENABLEPOINTSCAN) +}; + // API function that is called to get the device's battery status as a string. class AccessibilityPrivateGetBatteryDescriptionFunction : public ExtensionFunction {
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 1416f14..608ac5f7 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -79,6 +79,7 @@ "//chrome/browser/apps/platform_apps", "//chrome/browser/apps/platform_apps/api", "//chrome/browser/chromeos/child_accounts/time_limits/web_time_limit_error_page", + "//chrome/browser/chromeos/nearby:bluetooth_adapter_util", "//chrome/browser/chromeos/power/ml/smart_dim", "//chrome/browser/chromeos/wilco_dtc_supportd:mojo_utils", "//chrome/browser/devtools", @@ -209,6 +210,7 @@ "//chromeos/services/multidevice_setup/public/cpp:auth_token_validator", "//chromeos/services/multidevice_setup/public/cpp:oobe_completion_tracker", "//chromeos/services/multidevice_setup/public/cpp:prefs", + "//chromeos/services/nearby/public/mojom", "//chromeos/services/network_config:in_process_instance", "//chromeos/services/network_config/public/cpp:cpp", "//chromeos/services/network_health/public/mojom", @@ -1901,6 +1903,10 @@ "multidevice_setup/multidevice_setup_service_factory.h", "multidevice_setup/oobe_completion_tracker_factory.cc", "multidevice_setup/oobe_completion_tracker_factory.h", + "nearby/nearby_connections_dependencies_provider.cc", + "nearby/nearby_connections_dependencies_provider.h", + "nearby/nearby_connections_dependencies_provider_factory.cc", + "nearby/nearby_connections_dependencies_provider_factory.h", "net/client_cert_filter_chromeos.cc", "net/client_cert_filter_chromeos.h", "net/client_cert_store_chromeos.cc",
diff --git a/chrome/browser/chromeos/browser_context_keyed_service_factories.cc b/chrome/browser/chromeos/browser_context_keyed_service_factories.cc index 87b3d4bc..6031f8f 100644 --- a/chrome/browser/chromeos/browser_context_keyed_service_factories.cc +++ b/chrome/browser/chromeos/browser_context_keyed_service_factories.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/chromeos/kerberos/kerberos_credentials_manager_factory.h" #include "chrome/browser/chromeos/launcher_search_provider/launcher_search_provider_service_factory.h" #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_factory.h" +#include "chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider_factory.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "chrome/browser/chromeos/phonehub/phone_hub_manager_factory.h" #include "chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_factory.h" @@ -71,6 +72,7 @@ ash::HoldingSpaceKeyedServiceFactory::GetInstance(); KerberosCredentialsManagerFactory::GetInstance(); launcher_search_provider::ServiceFactory::GetInstance(); + nearby::NearbyConnectionsDependenciesProviderFactory::GetInstance(); OwnerSettingsServiceChromeOSFactory::GetInstance(); phonehub::PhoneHubManagerFactory::GetInstance(); platform_keys::KeyPermissionsServiceFactory::GetInstance();
diff --git a/chrome/browser/chromeos/crosapi/account_manager_ash.cc b/chrome/browser/chromeos/crosapi/account_manager_ash.cc index abd93f6..c74ee21 100644 --- a/chrome/browser/chromeos/crosapi/account_manager_ash.cc +++ b/chrome/browser/chromeos/crosapi/account_manager_ash.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/callback.h" +#include "base/notreached.h" #include "chromeos/components/account_manager/account_manager.h" #include "mojo/public/cpp/bindings/remote.h" @@ -17,9 +18,12 @@ mojo::PendingReceiver<mojom::AccountManager> receiver) : account_manager_(account_manager), receiver_(this, std::move(receiver)) { DCHECK(account_manager_); + account_manager_->AddObserver(this); } -AccountManagerAsh::~AccountManagerAsh() = default; +AccountManagerAsh::~AccountManagerAsh() { + account_manager_->RemoveObserver(this); +} void AccountManagerAsh::IsInitialized(IsInitializedCallback callback) { std::move(callback).Run(account_manager_->IsInitialized()); @@ -32,4 +36,79 @@ std::move(callback).Run(std::move(receiver)); } +void AccountManagerAsh::OnTokenUpserted( + const chromeos::AccountManager::Account& account) { + for (auto& observer : observers_) + observer->OnTokenUpserted(ToMojoAccount(account)); +} + +void AccountManagerAsh::OnAccountRemoved( + const chromeos::AccountManager::Account& account) { + for (auto& observer : observers_) + observer->OnAccountRemoved(ToMojoAccount(account)); +} + +// static +chromeos::AccountManager::Account AccountManagerAsh::FromMojoAccount( + const mojom::AccountPtr& mojom_account) { + chromeos::AccountManager::Account account; + + account.key.id = mojom_account->key->id; + account.key.account_type = + FromMojoAccountType(mojom_account->key->account_type); + account.raw_email = mojom_account->raw_email; + + return account; +} + +// static +mojom::AccountPtr AccountManagerAsh::ToMojoAccount( + const chromeos::AccountManager::Account& account) { + mojom::AccountPtr mojom_account = mojom::Account::New(); + + mojom_account->key = mojom::AccountKey::New(); + mojom_account->key->id = account.key.id; + mojom_account->key->account_type = + ToMojoAccountType(account.key.account_type); + mojom_account->raw_email = account.raw_email; + + return mojom_account; +} + +// static +chromeos::account_manager::AccountType AccountManagerAsh::FromMojoAccountType( + const mojom::AccountType& account_type) { + switch (account_type) { + case mojom::AccountType::kUnspecified: + return chromeos::account_manager::AccountType::ACCOUNT_TYPE_UNSPECIFIED; + case mojom::AccountType::kGaia: + return chromeos::account_manager::AccountType::ACCOUNT_TYPE_GAIA; + case mojom::AccountType::kActiveDirectory: + return chromeos::account_manager::AccountType:: + ACCOUNT_TYPE_ACTIVE_DIRECTORY; + default: + // Ash does not know about this new account type. Don't consider this as + // as error to preserve forwards compatibility with lacros. + LOG(WARNING) << "Unknown account type: " << account_type; + return chromeos::account_manager::AccountType::ACCOUNT_TYPE_UNSPECIFIED; + } +} + +// static +mojom::AccountType AccountManagerAsh::ToMojoAccountType( + const chromeos::account_manager::AccountType& account_type) { + switch (account_type) { + case chromeos::account_manager::AccountType::ACCOUNT_TYPE_UNSPECIFIED: + return mojom::AccountType::kUnspecified; + case chromeos::account_manager::AccountType::ACCOUNT_TYPE_GAIA: + return mojom::AccountType::kGaia; + case chromeos::account_manager::AccountType::ACCOUNT_TYPE_ACTIVE_DIRECTORY: + return mojom::AccountType::kActiveDirectory; + } +} + +void AccountManagerAsh::FlushMojoForTesting() { + observers_.FlushForTesting(); +} + } // namespace crosapi
diff --git a/chrome/browser/chromeos/crosapi/account_manager_ash.h b/chrome/browser/chromeos/crosapi/account_manager_ash.h index c8965cb2..fb25c7c 100644 --- a/chrome/browser/chromeos/crosapi/account_manager_ash.h +++ b/chrome/browser/chromeos/crosapi/account_manager_ash.h
@@ -5,21 +5,19 @@ #ifndef CHROME_BROWSER_CHROMEOS_CROSAPI_ACCOUNT_MANAGER_ASH_H_ #define CHROME_BROWSER_CHROMEOS_CROSAPI_ACCOUNT_MANAGER_ASH_H_ +#include "chromeos/components/account_manager/account_manager.h" #include "chromeos/crosapi/mojom/account_manager.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote_set.h" -namespace chromeos { -class AccountManager; -} // namespace chromeos - namespace crosapi { // Implements the |crosapi::mojom::AccountManager| interface in ash-chrome. // It enables lacros-chrome to interact with accounts stored in the Chrome OS // Account Manager. -class AccountManagerAsh : public mojom::AccountManager { +class AccountManagerAsh : public mojom::AccountManager, + public chromeos::AccountManager::Observer { public: AccountManagerAsh(chromeos::AccountManager* account_manager, mojo::PendingReceiver<mojom::AccountManager> receiver); @@ -31,8 +29,27 @@ void IsInitialized(IsInitializedCallback callback) override; void AddObserver(AddObserverCallback callback) override; + // chromeos::AccountManager::Observer: + void OnTokenUpserted( + const chromeos::AccountManager::Account& account) override; + void OnAccountRemoved( + const chromeos::AccountManager::Account& account) override; + private: friend class AccountManagerAshTest; + friend class TestAccountManagerObserver; + + // Following util functions are static for ease of testing. + static chromeos::AccountManager::Account FromMojoAccount( + const mojom::AccountPtr& mojom_account); + static mojom::AccountPtr ToMojoAccount( + const chromeos::AccountManager::Account& account); + static chromeos::account_manager::AccountType FromMojoAccountType( + const mojom::AccountType& account_type); + static mojom::AccountType ToMojoAccountType( + const chromeos::account_manager::AccountType& account_type); + + void FlushMojoForTesting(); chromeos::AccountManager* const account_manager_; mojo::Receiver<mojom::AccountManager> receiver_;
diff --git a/chrome/browser/chromeos/crosapi/account_manager_ash_unittest.cc b/chrome/browser/chromeos/crosapi/account_manager_ash_unittest.cc index 77fad22..836a8a7 100644 --- a/chrome/browser/chromeos/crosapi/account_manager_ash_unittest.cc +++ b/chrome/browser/chromeos/crosapi/account_manager_ash_unittest.cc
@@ -6,13 +6,17 @@ #include <cstddef> #include <memory> +#include <type_traits> +#include <utility> #include "base/run_loop.h" #include "base/test/bind_test_util.h" #include "base/test/task_environment.h" #include "chromeos/components/account_manager/account_manager.h" +#include "chromeos/components/account_manager/tokens.pb.h" #include "chromeos/crosapi/mojom/account_manager.mojom-test-utils.h" #include "chromeos/crosapi/mojom/account_manager.mojom.h" +#include "components/prefs/testing_pref_service.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" @@ -21,6 +25,66 @@ namespace crosapi { +namespace { + +const char kFakeGaiaId[] = "fake-gaia-id"; +const char kFakeEmail[] = "fake_email@example.com"; +const char kFakeToken[] = "fake-token"; + +} // namespace + +class TestAccountManagerObserver + : public mojom::AccountManagerObserverInterceptorForTesting { + public: + TestAccountManagerObserver() : receiver_(this) {} + + TestAccountManagerObserver(const TestAccountManagerObserver&) = delete; + TestAccountManagerObserver& operator=(const TestAccountManagerObserver&) = + delete; + ~TestAccountManagerObserver() override = default; + + void Observe( + mojom::AccountManagerAsyncWaiter* const account_manager_async_waiter) { + mojo::PendingReceiver<mojom::AccountManagerObserver> receiver; + account_manager_async_waiter->AddObserver(&receiver); + receiver_.Bind(std::move(receiver)); + } + + int GetNumOnTokenUpsertedCalls() { return num_token_upserted_calls_; } + + chromeos::AccountManager::Account GetLastUpsertedAccount() { + return last_upserted_account_; + } + + int GetNumOnAccountRemovedCalls() { return num_account_removed_calls_; } + + chromeos::AccountManager::Account GetLastRemovedAccount() { + return last_removed_account_; + } + + private: + // mojom::AccountManagerObserverInterceptorForTesting override: + AccountManagerObserver* GetForwardingInterface() override { return this; } + + // mojom::AccountManagerObserverInterceptorForTesting override: + void OnTokenUpserted(mojom::AccountPtr account) override { + ++num_token_upserted_calls_; + last_upserted_account_ = AccountManagerAsh::FromMojoAccount(account); + } + + // mojom::AccountManagerObserverInterceptorForTesting override: + void OnAccountRemoved(mojom::AccountPtr account) override { + ++num_account_removed_calls_; + last_removed_account_ = AccountManagerAsh::FromMojoAccount(account); + } + + int num_token_upserted_calls_ = 0; + int num_account_removed_calls_ = 0; + chromeos::AccountManager::Account last_upserted_account_; + chromeos::AccountManager::Account last_removed_account_; + mojo::Receiver<mojom::AccountManagerObserver> receiver_; +}; + class AccountManagerAshTest : public ::testing::Test { public: AccountManagerAshTest() = default; @@ -39,11 +103,15 @@ void RunAllPendingTasks() { task_environment_.RunUntilIdle(); } + void FlushMojoForTesting() { account_manager_ash_->FlushMojoForTesting(); } + // Returns |true| if initialization was successful. bool InitializeAccountManager() { base::RunLoop run_loop; account_manager_.InitializeInEphemeralMode( test_url_loader_factory_.GetSafeWeakWrapper(), run_loop.QuitClosure()); + account_manager_.SetPrefService(&pref_service_); + account_manager_.RegisterPrefs(pref_service_.registry()); run_loop.Run(); return account_manager_.IsInitialized(); } @@ -54,10 +122,13 @@ return account_manager_async_waiter_.get(); } + chromeos::AccountManager* account_manager() { return &account_manager_; } + private: base::test::SingleThreadTaskEnvironment task_environment_; network::TestURLLoaderFactory test_url_loader_factory_; + TestingPrefServiceSimple pref_service_; chromeos::AccountManager account_manager_; mojo::Remote<mojom::AccountManager> remote_; std::unique_ptr<AccountManagerAsh> account_manager_ash_; @@ -96,4 +167,38 @@ EXPECT_EQ(0, GetNumObservers()); } +TEST_F(AccountManagerAshTest, LacrosObserversAreNotifiedOnAccountUpdates) { + const chromeos::AccountManager::AccountKey kTestAccountKey{ + kFakeGaiaId, chromeos::account_manager::AccountType::ACCOUNT_TYPE_GAIA}; + ASSERT_TRUE(InitializeAccountManager()); + TestAccountManagerObserver observer; + observer.Observe(account_manager_async_waiter()); + ASSERT_EQ(1, GetNumObservers()); + + EXPECT_EQ(0, observer.GetNumOnTokenUpsertedCalls()); + account_manager()->UpsertAccount(kTestAccountKey, kFakeEmail, kFakeToken); + FlushMojoForTesting(); + EXPECT_EQ(1, observer.GetNumOnTokenUpsertedCalls()); + EXPECT_EQ(kTestAccountKey, observer.GetLastUpsertedAccount().key); + EXPECT_EQ(kFakeEmail, observer.GetLastUpsertedAccount().raw_email); +} + +TEST_F(AccountManagerAshTest, LacrosObserversAreNotifiedOnAccountRemovals) { + const chromeos::AccountManager::AccountKey kTestAccountKey{ + kFakeGaiaId, chromeos::account_manager::AccountType::ACCOUNT_TYPE_GAIA}; + ASSERT_TRUE(InitializeAccountManager()); + TestAccountManagerObserver observer; + observer.Observe(account_manager_async_waiter()); + ASSERT_EQ(1, GetNumObservers()); + account_manager()->UpsertAccount(kTestAccountKey, kFakeEmail, kFakeToken); + FlushMojoForTesting(); + + EXPECT_EQ(0, observer.GetNumOnAccountRemovedCalls()); + account_manager()->RemoveAccount(kTestAccountKey); + FlushMojoForTesting(); + EXPECT_EQ(1, observer.GetNumOnAccountRemovedCalls()); + EXPECT_EQ(kTestAccountKey, observer.GetLastRemovedAccount().key); + EXPECT_EQ(kFakeEmail, observer.GetLastRemovedAccount().raw_email); +} + } // namespace crosapi
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index a5c7f16..62a522ef 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -123,6 +123,7 @@ #include "chromeos/services/assistant/public/cpp/assistant_service.h" #include "chromeos/services/machine_learning/public/cpp/service_connection.h" #include "chromeos/settings/cros_settings_names.h" +#include "chromeos/ui/base/window_properties.h" #include "components/arc/arc_prefs.h" #include "components/arc/metrics/arc_metrics_constants.h" #include "components/policy/core/browser/policy_conversions.h" @@ -812,7 +813,8 @@ chromeos::WindowStateType expected_type, base::OnceCallback<void(bool)> callback) : expected_type_(expected_type), callback_(std::move(callback)) { - DCHECK_NE(window->GetProperty(ash::kWindowStateTypeKey), expected_type_); + DCHECK_NE(window->GetProperty(chromeos::kWindowStateTypeKey), + expected_type_); scoped_observer_.Add(window); } ~WindowStateChangeObserver() override {} @@ -822,8 +824,8 @@ const void* key, intptr_t old) override { DCHECK(scoped_observer_.IsObserving(window)); - if (key == ash::kWindowStateTypeKey && - window->GetProperty(ash::kWindowStateTypeKey) == expected_type_) { + if (key == chromeos::kWindowStateTypeKey && + window->GetProperty(chromeos::kWindowStateTypeKey) == expected_type_) { scoped_observer_.RemoveAll(); std::move(callback_).Run(/*success=*/true); } @@ -3584,7 +3586,7 @@ window_info.window_type = GetAppWindowType( static_cast<ash::AppType>(window->GetProperty(aura::client::kAppType))); window_info.state_type = - ToWindowStateType(window->GetProperty(ash::kWindowStateTypeKey)); + ToWindowStateType(window->GetProperty(chromeos::kWindowStateTypeKey)); window_info.bounds_in_root = ToBoundsDictionary(window->GetBoundsInRootWindow()); window_info.target_bounds = ToBoundsDictionary(window->GetTargetBounds()); @@ -3715,7 +3717,7 @@ chromeos::WindowStateType expected_state = GetExpectedWindowState(params->change.event_type); - if (window->GetProperty(ash::kWindowStateTypeKey) == expected_state) { + if (window->GetProperty(chromeos::kWindowStateTypeKey) == expected_state) { if (params->change.fail_if_no_change && *(params->change.fail_if_no_change)) { return RespondNow( @@ -4081,6 +4083,40 @@ } /////////////////////////////////////////////////////////////////////////////// +// AutotestPrivateActivateAdjacentDesksToTargetIndexFunction +/////////////////////////////////////////////////////////////////////////////// + +AutotestPrivateActivateAdjacentDesksToTargetIndexFunction:: + AutotestPrivateActivateAdjacentDesksToTargetIndexFunction() = default; +AutotestPrivateActivateAdjacentDesksToTargetIndexFunction:: + ~AutotestPrivateActivateAdjacentDesksToTargetIndexFunction() = default; + +ExtensionFunction::ResponseAction +AutotestPrivateActivateAdjacentDesksToTargetIndexFunction::Run() { + std::unique_ptr< + api::autotest_private::ActivateAdjacentDesksToTargetIndex::Params> + params(api::autotest_private::ActivateAdjacentDesksToTargetIndex::Params:: + Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params); + + if (!ash::AutotestDesksApi().ActivateAdjacentDesksToTargetIndex( + params->index, + base::BindOnce( + &AutotestPrivateActivateAdjacentDesksToTargetIndexFunction:: + OnAnimationComplete, + this))) { + return RespondNow(OneArgument(std::make_unique<base::Value>(false))); + } + + return RespondLater(); +} + +void AutotestPrivateActivateAdjacentDesksToTargetIndexFunction:: + OnAnimationComplete() { + Respond(OneArgument(std::make_unique<base::Value>(true))); +} + +/////////////////////////////////////////////////////////////////////////////// // AutotestPrivateMouseClickFunction ///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h index 5d96a90..6818901 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h
@@ -1109,6 +1109,21 @@ void OnAnimationComplete(); }; +class AutotestPrivateActivateAdjacentDesksToTargetIndexFunction + : public ExtensionFunction { + public: + AutotestPrivateActivateAdjacentDesksToTargetIndexFunction(); + DECLARE_EXTENSION_FUNCTION( + "autotestPrivate.activateAdjacentDesksToTargetIndex", + AUTOTESTPRIVATE_ACTIVATEADJACENTDESKSTOTARGETINDEX) + + private: + ~AutotestPrivateActivateAdjacentDesksToTargetIndexFunction() override; + ResponseAction Run() override; + + void OnAnimationComplete(); +}; + class AutotestPrivateMouseClickFunction : public ExtensionFunction { public: AutotestPrivateMouseClickFunction();
diff --git a/chrome/browser/chromeos/kerberos/kerberos_credentials_manager.cc b/chrome/browser/chromeos/kerberos/kerberos_credentials_manager.cc index 6b6cb62..b277dfd 100644 --- a/chrome/browser/chromeos/kerberos/kerberos_credentials_manager.cc +++ b/chrome/browser/chromeos/kerberos/kerberos_credentials_manager.cc
@@ -935,7 +935,7 @@ // settings. Consider creating a standalone reauth dialog. chrome::SettingsWindowManager::GetInstance()->ShowOSSettings( primary_profile_, - chromeos::settings::mojom::kKerberosSubpagePath + + chromeos::settings::mojom::kKerberosAccountsSubpagePath + std::string("?kerberos_reauth=") + net::EscapeQueryParamValue(principal_name, false /* use_plus */));
diff --git a/chrome/browser/chromeos/nearby/BUILD.gn b/chrome/browser/chromeos/nearby/BUILD.gn new file mode 100644 index 0000000..9e6f030e --- /dev/null +++ b/chrome/browser/chromeos/nearby/BUILD.gn
@@ -0,0 +1,20 @@ +# 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. + +# Note: This target is separated from the rest of //chrome/browser/chromeos so +# that it can depend on the bluetooth::mojom::Adapter interface, which is only +# visible to a limited set of clients. +source_set("bluetooth_adapter_util") { + sources = [ + "bluetooth_adapter_util.cc", + "bluetooth_adapter_util.h", + ] + + deps = [ + "//base", + "//device/bluetooth", + "//device/bluetooth:deprecated_experimental_mojo", + "//mojo/public/cpp/bindings", + ] +}
diff --git a/chrome/browser/chromeos/nearby/bluetooth_adapter_util.cc b/chrome/browser/chromeos/nearby/bluetooth_adapter_util.cc new file mode 100644 index 0000000..0ce9a81 --- /dev/null +++ b/chrome/browser/chromeos/nearby/bluetooth_adapter_util.cc
@@ -0,0 +1,25 @@ +// 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 "chrome/browser/chromeos/nearby/bluetooth_adapter_util.h" + +#include <memory> +#include <utility> + +#include "device/bluetooth/adapter.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" + +namespace chromeos { +namespace nearby { + +void MakeSelfOwnedBluetoothAdapter( + mojo::PendingReceiver<bluetooth::mojom::Adapter> pending_receiver, + scoped_refptr<device::BluetoothAdapter> adapter) { + mojo::MakeSelfOwnedReceiver( + std::make_unique<bluetooth::Adapter>(std::move(adapter)), + std::move(pending_receiver)); +} + +} // namespace nearby +} // namespace chromeos
diff --git a/chrome/browser/chromeos/nearby/bluetooth_adapter_util.h b/chrome/browser/chromeos/nearby/bluetooth_adapter_util.h new file mode 100644 index 0000000..a889eef --- /dev/null +++ b/chrome/browser/chromeos/nearby/bluetooth_adapter_util.h
@@ -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. + +#ifndef CHROME_BROWSER_CHROMEOS_NEARBY_BLUETOOTH_ADAPTER_UTIL_H_ +#define CHROME_BROWSER_CHROMEOS_NEARBY_BLUETOOTH_ADAPTER_UTIL_H_ + +#include "base/memory/ref_counted.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" + +namespace bluetooth { +namespace mojom { +class Adapter; +} // namespace mojom +} // namespace bluetooth + +namespace device { +class BluetoothAdapter; +} // namespace device + +namespace chromeos { +namespace nearby { + +// Note: This helper function is implemented in its own file so that it can +// depend on the bluetooth::mojom::Adapter interface, which is only visible to a +// limited set of clients. +void MakeSelfOwnedBluetoothAdapter( + mojo::PendingReceiver<bluetooth::mojom::Adapter> pending_receiver, + scoped_refptr<device::BluetoothAdapter> adapter); + +} // namespace nearby +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_NEARBY_BLUETOOTH_ADAPTER_UTIL_H_
diff --git a/chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider.cc b/chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider.cc new file mode 100644 index 0000000..231a960 --- /dev/null +++ b/chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider.cc
@@ -0,0 +1,138 @@ +// 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 "chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider.h" + +#include "chrome/browser/chromeos/nearby/bluetooth_adapter_util.h" +#include "chrome/browser/nearby_sharing/webrtc_signaling_messenger.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sharing/webrtc/ice_config_fetcher.h" +#include "chrome/browser/sharing/webrtc/sharing_mojo_service.h" +#include "content/public/browser/storage_partition.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" +#include "net/base/network_isolation_key.h" +#include "services/network/public/mojom/network_context.mojom.h" +#include "services/network/public/mojom/p2p_trusted.mojom.h" + +namespace chromeos { +namespace nearby { +namespace { + +template <typename T> +struct MojoPipe { + mojo::PendingRemote<T> remote; + mojo::PendingReceiver<T> receiver{remote.InitWithNewPipeAndPassReceiver()}; +}; + +class P2PTrustedSocketManagerClientImpl + : public network::mojom::P2PTrustedSocketManagerClient { + public: + explicit P2PTrustedSocketManagerClientImpl( + mojo::PendingRemote<network::mojom::P2PTrustedSocketManager> + socket_manager) + : socket_manager_(std::move(socket_manager)) {} + ~P2PTrustedSocketManagerClientImpl() override = default; + + // network::mojom::P2PTrustedSocketManagerClient: + void InvalidSocketPortRangeRequested() override { NOTIMPLEMENTED(); } + void DumpPacket(const std::vector<uint8_t>& packet_header, + uint64_t packet_length, + bool incoming) override { + NOTIMPLEMENTED(); + } + + private: + mojo::Remote<network::mojom::P2PTrustedSocketManager> socket_manager_; +}; + +} // namespace + +NearbyConnectionsDependenciesProvider::NearbyConnectionsDependenciesProvider( + Profile* profile, + signin::IdentityManager* identity_manager) + : profile_(profile), identity_manager_(identity_manager) { + DCHECK(identity_manager_); +} + +NearbyConnectionsDependenciesProvider:: + ~NearbyConnectionsDependenciesProvider() = default; + +location::nearby::connections::mojom::NearbyConnectionsDependenciesPtr +NearbyConnectionsDependenciesProvider::GetDependencies() { + if (shut_down_) + return nullptr; + + auto dependencies = location::nearby::connections::mojom:: + NearbyConnectionsDependencies::New(); + + if (device::BluetoothAdapterFactory::IsBluetoothSupported()) + dependencies->bluetooth_adapter = GetBluetoothAdapterPendingRemote(); + else + dependencies->bluetooth_adapter = mojo::NullRemote(); + + dependencies->webrtc_dependencies = GetWebRtcDependencies(); + + return dependencies; +} + +void NearbyConnectionsDependenciesProvider::Shutdown() { + shut_down_ = true; +} + +mojo::PendingRemote<bluetooth::mojom::Adapter> +NearbyConnectionsDependenciesProvider::GetBluetoothAdapterPendingRemote() { + mojo::PendingRemote<bluetooth::mojom::Adapter> pending_adapter; + device::BluetoothAdapterFactory::Get()->GetAdapter( + base::BindOnce(&MakeSelfOwnedBluetoothAdapter, + pending_adapter.InitWithNewPipeAndPassReceiver())); + + return pending_adapter; +} + +location::nearby::connections::mojom::WebRtcDependenciesPtr +NearbyConnectionsDependenciesProvider::GetWebRtcDependencies() { + auto* network_context = + content::BrowserContext::GetDefaultStoragePartition(profile_) + ->GetNetworkContext(); + + MojoPipe<network::mojom::P2PTrustedSocketManagerClient> socket_manager_client; + MojoPipe<network::mojom::P2PTrustedSocketManager> trusted_socket_manager; + MojoPipe<network::mojom::P2PSocketManager> socket_manager; + MojoPipe<network::mojom::MdnsResponder> mdns_responder; + + mojo::MakeSelfOwnedReceiver( + std::make_unique<P2PTrustedSocketManagerClientImpl>( + std::move(trusted_socket_manager.remote)), + std::move(socket_manager_client.receiver)); + + // Create socket manager. + network_context->CreateP2PSocketManager( + net::NetworkIsolationKey::CreateTransient(), + std::move(socket_manager_client.remote), + std::move(trusted_socket_manager.receiver), + std::move(socket_manager.receiver)); + + // Create mdns responder. + network_context->CreateMdnsResponder(std::move(mdns_responder.receiver)); + + // Create ice config fetcher. + auto url_loader_factory = profile_->GetURLLoaderFactory(); + MojoPipe<sharing::mojom::IceConfigFetcher> ice_config_fetcher; + mojo::MakeSelfOwnedReceiver( + std::make_unique<IceConfigFetcher>(url_loader_factory), + std::move(ice_config_fetcher.receiver)); + + MojoPipe<sharing::mojom::WebRtcSignalingMessenger> messenger; + mojo::MakeSelfOwnedReceiver(std::make_unique<WebRtcSignalingMessenger>( + identity_manager_, url_loader_factory), + std::move(messenger.receiver)); + + return location::nearby::connections::mojom::WebRtcDependencies::New( + std::move(socket_manager.remote), std::move(mdns_responder.remote), + std::move(ice_config_fetcher.remote), std::move(messenger.remote)); +} + +} // namespace nearby +} // namespace chromeos
diff --git a/chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider.h b/chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider.h new file mode 100644 index 0000000..f07b7f2 --- /dev/null +++ b/chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider.h
@@ -0,0 +1,60 @@ +// 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_BROWSER_CHROMEOS_NEARBY_NEARBY_CONNECTIONS_DEPENDENCIES_PROVIDER_H_ +#define CHROME_BROWSER_CHROMEOS_NEARBY_NEARBY_CONNECTIONS_DEPENDENCIES_PROVIDER_H_ + +#include <memory> + +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "chromeos/services/nearby/public/mojom/sharing.mojom.h" +#include "components/keyed_service/core/keyed_service.h" + +class Profile; + +namespace signin { +class IdentityManager; +} // namespace signin + +namespace chromeos { +namespace nearby { + +// Provides dependencies required to initialize Nearby Connections. Implemented +// as a KeyedService because WebRTC dependencies are linked to the user's +// identity. +class NearbyConnectionsDependenciesProvider : public KeyedService { + public: + NearbyConnectionsDependenciesProvider( + Profile* profile, + signin::IdentityManager* identity_manager); + ~NearbyConnectionsDependenciesProvider() override; + + // Note: Returns null during session shutdown. + location::nearby::connections::mojom::NearbyConnectionsDependenciesPtr + GetDependencies(); + + private: + // KeyedService: + void Shutdown() override; + + mojo::PendingRemote<bluetooth::mojom::Adapter> + GetBluetoothAdapterPendingRemote(); + + location::nearby::connections::mojom::WebRtcDependenciesPtr + GetWebRtcDependencies(); + + bool shut_down_ = false; + + Profile* profile_; + signin::IdentityManager* identity_manager_; + + base::WeakPtrFactory<NearbyConnectionsDependenciesProvider> weak_ptr_factory_{ + this}; +}; + +} // namespace nearby +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_NEARBY_NEARBY_CONNECTIONS_DEPENDENCIES_PROVIDER_H_
diff --git a/chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider_factory.cc b/chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider_factory.cc new file mode 100644 index 0000000..a867239 --- /dev/null +++ b/chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider_factory.cc
@@ -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. + +#include "chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider_factory.h" + +#include "chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/signin/identity_manager_factory.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" + +namespace chromeos { +namespace nearby { + +// static +NearbyConnectionsDependenciesProvider* +NearbyConnectionsDependenciesProviderFactory::GetForProfile(Profile* profile) { + return static_cast<NearbyConnectionsDependenciesProvider*>( + NearbyConnectionsDependenciesProviderFactory::GetInstance() + ->GetServiceForBrowserContext(profile, /*create=*/true)); +} + +// static +NearbyConnectionsDependenciesProviderFactory* +NearbyConnectionsDependenciesProviderFactory::GetInstance() { + return base::Singleton<NearbyConnectionsDependenciesProviderFactory>::get(); +} + +NearbyConnectionsDependenciesProviderFactory:: + NearbyConnectionsDependenciesProviderFactory() + : BrowserContextKeyedServiceFactory( + "NearbyConnectionsDependenciesProvider", + BrowserContextDependencyManager::GetInstance()) { + DependsOn(IdentityManagerFactory::GetInstance()); +} + +NearbyConnectionsDependenciesProviderFactory:: + ~NearbyConnectionsDependenciesProviderFactory() = default; + +KeyedService* +NearbyConnectionsDependenciesProviderFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + Profile* profile = Profile::FromBrowserContext(context); + return new NearbyConnectionsDependenciesProvider( + profile, IdentityManagerFactory::GetForProfile(profile)); +} + +bool NearbyConnectionsDependenciesProviderFactory:: + ServiceIsCreatedWithBrowserContext() const { + return true; +} + +} // namespace nearby +} // namespace chromeos
diff --git a/chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider_factory.h b/chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider_factory.h new file mode 100644 index 0000000..b6fd189a --- /dev/null +++ b/chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider_factory.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 CHROME_BROWSER_CHROMEOS_NEARBY_NEARBY_CONNECTIONS_DEPENDENCIES_PROVIDER_FACTORY_H_ +#define CHROME_BROWSER_CHROMEOS_NEARBY_NEARBY_CONNECTIONS_DEPENDENCIES_PROVIDER_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +class Profile; + +namespace chromeos { +namespace nearby { + +class NearbyConnectionsDependenciesProvider; + +class NearbyConnectionsDependenciesProviderFactory + : public BrowserContextKeyedServiceFactory { + public: + static NearbyConnectionsDependenciesProvider* GetForProfile(Profile* profile); + + static NearbyConnectionsDependenciesProviderFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits< + NearbyConnectionsDependenciesProviderFactory>; + + NearbyConnectionsDependenciesProviderFactory(); + NearbyConnectionsDependenciesProviderFactory( + const NearbyConnectionsDependenciesProviderFactory&) = delete; + NearbyConnectionsDependenciesProviderFactory& operator=( + const NearbyConnectionsDependenciesProviderFactory&) = delete; + ~NearbyConnectionsDependenciesProviderFactory() override; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + bool ServiceIsCreatedWithBrowserContext() const override; +}; + +} // namespace nearby +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_NEARBY_NEARBY_CONNECTIONS_DEPENDENCIES_PROVIDER_FACTORY_H_
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 41a09a6..84c26c2 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -198,11 +198,6 @@ "expiry_milestone": 76 }, { - "name": "arc-usb-storage-ui", - "owners": [ "fukino" ], - "expiry_milestone": 78 - }, - { "name": "ash-debug-shortcuts", "owners": [ "//ash/OWNERS" ], // Used by developers for debugging and to dump extra information to logs
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 122df7a..2e00bf1 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3602,10 +3602,6 @@ const char kArcUsbHostDescription[] = "Allow Android apps to use USB host feature on ChromeOS devices."; -const char kArcUsbStorageUIName[] = "Enable ARC USB Storage UI"; -const char kArcUsbStorageUIDescription[] = - "Enable experimental UI for controlling ARC access to USB storage devices."; - const char kAshEnablePipRoundedCornersName[] = "Enable Picture-in-Picture rounded corners."; const char kAshEnablePipRoundedCornersDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index db42c69..f6bb6810f 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2077,9 +2077,6 @@ extern const char kArcUsbHostName[]; extern const char kArcUsbHostDescription[]; -extern const char kArcUsbStorageUIName[]; -extern const char kArcUsbStorageUIDescription[]; - extern const char kAshEnablePipRoundedCornersName[]; extern const char kAshEnablePipRoundedCornersDescription[];
diff --git a/chrome/browser/nearby_sharing/nearby_receive_manager.cc b/chrome/browser/nearby_sharing/nearby_receive_manager.cc index 6456396..b36983b 100644 --- a/chrome/browser/nearby_sharing/nearby_receive_manager.cc +++ b/chrome/browser/nearby_sharing/nearby_receive_manager.cc
@@ -29,9 +29,9 @@ << TransferMetadata::StatusToString( transfer_metadata.status()); + NotifyOnTransferUpdate(share_target, transfer_metadata); if (TransferMetadata::Status::kAwaitingLocalConfirmation == status) { share_targets_map_.insert_or_assign(share_target.id, share_target); - NotifyOnIncomingShare(share_target, transfer_metadata.token()); } else if (transfer_metadata.is_final_status()) { share_targets_map_.erase(share_target.id); } @@ -109,10 +109,10 @@ } } -void NearbyReceiveManager::NotifyOnIncomingShare( +void NearbyReceiveManager::NotifyOnTransferUpdate( const ShareTarget& share_target, - const base::Optional<std::string>& connection_token) { + const TransferMetadata& metadata) { for (auto& remote : observers_set_) { - remote->OnIncomingShare(share_target, connection_token); + remote->OnTransferUpdate(share_target, metadata.ToMojo()); } }
diff --git a/chrome/browser/nearby_sharing/nearby_receive_manager.h b/chrome/browser/nearby_sharing/nearby_receive_manager.h index 88e97d3..4c6ffe3b 100644 --- a/chrome/browser/nearby_sharing/nearby_receive_manager.h +++ b/chrome/browser/nearby_sharing/nearby_receive_manager.h
@@ -50,9 +50,8 @@ void OnShutdown() override {} private: - void NotifyOnIncomingShare( - const ShareTarget& share_target, - const base::Optional<std::string>& connection_token); + void NotifyOnTransferUpdate(const ShareTarget& share_target, + const TransferMetadata& metadata); NearbySharingService* nearby_sharing_service_;
diff --git a/chrome/browser/nearby_sharing/nearby_receive_manager_unittest.cc b/chrome/browser/nearby_sharing/nearby_receive_manager_unittest.cc index 1c44d02..e973611 100644 --- a/chrome/browser/nearby_sharing/nearby_receive_manager_unittest.cc +++ b/chrome/browser/nearby_sharing/nearby_receive_manager_unittest.cc
@@ -23,14 +23,14 @@ in_high_visibility_ = in_high_visibility; } - void OnIncomingShare( + void OnTransferUpdate( const ShareTarget& share_target, - const base::Optional<std::string>& connection_token) override { + nearby_share::mojom::TransferMetadataPtr metadata) override { last_share_target_ = share_target; - last_connection_token_ = connection_token; + last_metadata_ = *metadata; } - base::Optional<std::string> last_connection_token_; + base::Optional<nearby_share::mojom::TransferMetadata> last_metadata_; base::Optional<bool> in_high_visibility_; ShareTarget last_share_target_; mojo::Receiver<nearby_share::mojom::ReceiveObserver> receiver_{this}; @@ -164,8 +164,8 @@ receive_manager_.OnTransferUpdate(share_target_, transfer_metadata_); FlushMojoMessages(); EXPECT_EQ(share_target_.id, observer_.last_share_target_.id); - ASSERT_TRUE(observer_.last_connection_token_.has_value()); - EXPECT_EQ("1234", observer_.last_connection_token_); + ASSERT_TRUE(observer_.last_metadata_.has_value()); + EXPECT_EQ("1234", observer_.last_metadata_->token); ExpectAccept(); bool success = false; @@ -179,8 +179,8 @@ receive_manager_.OnTransferUpdate(share_target_, transfer_metadata_); FlushMojoMessages(); EXPECT_EQ(share_target_.id, observer_.last_share_target_.id); - ASSERT_TRUE(observer_.last_connection_token_.has_value()); - EXPECT_EQ("1234", observer_.last_connection_token_); + ASSERT_TRUE(observer_.last_metadata_.has_value()); + EXPECT_EQ("1234", observer_.last_metadata_->token); ExpectReject(); bool success = false; @@ -195,8 +195,8 @@ receive_manager_.OnTransferUpdate(share_target_, transfer_metadata_); FlushMojoMessages(); EXPECT_EQ(share_target_.id, observer_.last_share_target_.id); - ASSERT_TRUE(observer_.last_connection_token_.has_value()); - EXPECT_EQ("1234", observer_.last_connection_token_); + ASSERT_TRUE(observer_.last_metadata_.has_value()); + EXPECT_EQ("1234", observer_.last_metadata_->token); // Simulate the sender canceling before we accept the share target and causing // the accept to fail before hitting the service. @@ -217,8 +217,8 @@ receive_manager_.OnTransferUpdate(share_target_, transfer_metadata_); FlushMojoMessages(); EXPECT_EQ(share_target_.id, observer_.last_share_target_.id); - ASSERT_TRUE(observer_.last_connection_token_.has_value()); - EXPECT_EQ("1234", observer_.last_connection_token_); + ASSERT_TRUE(observer_.last_metadata_.has_value()); + EXPECT_EQ("1234", observer_.last_metadata_->token); // Simulate the sender canceling before we reject the share target and causing // the reject to fail before hitting the service.
diff --git a/chrome/browser/nearby_sharing/transfer_metadata.cc b/chrome/browser/nearby_sharing/transfer_metadata.cc index 41fb855a..9b88e1a 100644 --- a/chrome/browser/nearby_sharing/transfer_metadata.cc +++ b/chrome/browser/nearby_sharing/transfer_metadata.cc
@@ -4,6 +4,7 @@ #include <utility> +#include "chrome/browser/nearby_sharing/logging/logging.h" #include "chrome/browser/nearby_sharing/transfer_metadata.h" // static @@ -63,6 +64,58 @@ } } +// static +nearby_share::mojom::TransferStatus TransferMetadata::StatusToMojo( + Status status) { + switch (status) { + case Status::kUnknown: + return nearby_share::mojom::TransferStatus::kUnknown; + case Status::kConnecting: + return nearby_share::mojom::TransferStatus::kConnecting; + case Status::kAwaitingLocalConfirmation: + return nearby_share::mojom::TransferStatus::kAwaitingLocalConfirmation; + case Status::kAwaitingRemoteAcceptance: + return nearby_share::mojom::TransferStatus::kAwaitingRemoteAcceptance; + case Status::kAwaitingRemoteAcceptanceFailed: + return nearby_share::mojom::TransferStatus:: + kAwaitingRemoteAcceptanceFailed; + case Status::kInProgress: + return nearby_share::mojom::TransferStatus::kInProgress; + case Status::kComplete: + return nearby_share::mojom::TransferStatus::kComplete; + case Status::kFailed: + return nearby_share::mojom::TransferStatus::kFailed; + case Status::kRejected: + return nearby_share::mojom::TransferStatus::kRejected; + case Status::kCancelled: + return nearby_share::mojom::TransferStatus::kCancelled; + case Status::kTimedOut: + return nearby_share::mojom::TransferStatus::kTimedOut; + case Status::kMediaUnavailable: + return nearby_share::mojom::TransferStatus::kMediaUnavailable; + case Status::kNotEnoughSpace: + return nearby_share::mojom::TransferStatus::kNotEnoughSpace; + case Status::kUnsupportedAttachmentType: + return nearby_share::mojom::TransferStatus::kUnsupportedAttachmentType; + case Status::kMediaDownloading: + case Status::kExternalProviderLaunched: + // These statuses are not used anywhere. + NOTREACHED(); + return nearby_share::mojom::TransferStatus::kUnknown; + } + NOTREACHED(); +} + +nearby_share::mojom::TransferMetadataPtr TransferMetadata::ToMojo() const { + auto mojo_transfer_metadata = nearby_share::mojom::TransferMetadata::New(); + mojo_transfer_metadata->status = StatusToMojo(status()); + mojo_transfer_metadata->progress = progress(); + mojo_transfer_metadata->token = token(); + mojo_transfer_metadata->is_original = is_original(); + mojo_transfer_metadata->is_final_status = is_final_status(); + return mojo_transfer_metadata; +} + TransferMetadata::TransferMetadata(Status status, float progress, base::Optional<std::string> token,
diff --git a/chrome/browser/nearby_sharing/transfer_metadata.h b/chrome/browser/nearby_sharing/transfer_metadata.h index af1520bc..f13123f85 100644 --- a/chrome/browser/nearby_sharing/transfer_metadata.h +++ b/chrome/browser/nearby_sharing/transfer_metadata.h
@@ -8,6 +8,7 @@ #include <string> #include "base/optional.h" +#include "chrome/browser/ui/webui/nearby_share/nearby_share.mojom.h" #include "url/gurl.h" // Metadata about an ongoing transfer. Wraps transient data like status and @@ -38,6 +39,8 @@ static std::string StatusToString(TransferMetadata::Status status); + static nearby_share::mojom::TransferStatus StatusToMojo(Status status); + TransferMetadata(Status status, float progress, base::Optional<std::string> token, @@ -62,6 +65,8 @@ // True if this |TransferMetadata| is the last status for this transfer. bool is_final_status() const { return is_final_status_; } + nearby_share::mojom::TransferMetadataPtr ToMojo() const; + private: Status status_; float progress_;
diff --git a/chrome/browser/policy/messaging_layer/public/report_client.cc b/chrome/browser/policy/messaging_layer/public/report_client.cc index 1f9f80c..0a3f4200 100644 --- a/chrome/browser/policy/messaging_layer/public/report_client.cc +++ b/chrome/browser/policy/messaging_layer/public/report_client.cc
@@ -168,32 +168,23 @@ return; } - class ProcessRecordContext : public TaskRunnerContext<bool> { - public: - ProcessRecordContext( - EncryptedRecord record, - std::vector<EncryptedRecord>* records, - base::OnceCallback<void(bool)> processed_callback, - scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner) - : TaskRunnerContext<bool>(std::move(processed_callback), - sequenced_task_runner), - records_(records), - record_(std::move(record)) {} + sequenced_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + [](std::vector<EncryptedRecord>* records, EncryptedRecord record, + base::OnceCallback<void(bool)> processed_cb) { + records->emplace_back(std::move(record)); + std::move(processed_cb).Run(true); + }, + base::Unretained(encrypted_records_.get()), + std::move(data.ValueOrDie()), std::move(processed_cb))); +} - private: - ~ProcessRecordContext() override = default; - - void OnStart() override { - records_->emplace_back(std::move(record_)); - Response(true); - } - - std::vector<EncryptedRecord>* const records_; - const EncryptedRecord record_; - }; - - Start<ProcessRecordContext>(data.ValueOrDie(), encrypted_records_.get(), - std::move(processed_cb), sequenced_task_runner_); +void ReportingClient::Uploader::ProcessGap( + SequencingInformation start, + uint64_t count, + base::OnceCallback<void(bool)> processed_cb) { + LOG(FATAL) << "Gap not implemented yet"; } void ReportingClient::Uploader::Completed(Status final_status) {
diff --git a/chrome/browser/policy/messaging_layer/public/report_client.h b/chrome/browser/policy/messaging_layer/public/report_client.h index d6c9a03..03db7d10 100644 --- a/chrome/browser/policy/messaging_layer/public/report_client.h +++ b/chrome/browser/policy/messaging_layer/public/report_client.h
@@ -227,6 +227,9 @@ void ProcessRecord(StatusOr<EncryptedRecord> data, base::OnceCallback<void(bool)> processed_cb) override; + void ProcessGap(SequencingInformation start, + uint64_t count, + base::OnceCallback<void(bool)> processed_cb) override; void Completed(Status final_status) override;
diff --git a/chrome/browser/policy/messaging_layer/storage/storage.cc b/chrome/browser/policy/messaging_layer/storage/storage.cc index ea6314b..7bb64c5 100644 --- a/chrome/browser/policy/messaging_layer/storage/storage.cc +++ b/chrome/browser/policy/messaging_layer/storage/storage.cc
@@ -138,6 +138,13 @@ std::move(processed_cb)); } + void ProcessGap(SequencingInformation start, + uint64_t count, + base::OnceCallback<void(bool)> processed_cb) override { + storage_interface_->ProcessGap(std::move(start), count, + std::move(processed_cb)); + } + void Completed(Status final_status) override { storage_interface_->Completed(final_status); }
diff --git a/chrome/browser/policy/messaging_layer/storage/storage.h b/chrome/browser/policy/messaging_layer/storage/storage.h index 073d51cc..cbe929a9 100644 --- a/chrome/browser/policy/messaging_layer/storage/storage.h +++ b/chrome/browser/policy/messaging_layer/storage/storage.h
@@ -28,28 +28,8 @@ // according to the priority. class Storage : public base::RefCountedThreadSafe<Storage> { public: - // Interface for Upload, which must be implemented by an object returned by - // |StartUpload| callback (see below). - // Every time Storage starts an upload (by timer or immediately after Write) - // it uses this interface to hand available records over to the actual - // uploader. Storage takes ownership of it and automatically discards after - // |Completed| returns. Similar to StorageQueue::UploaderInterface, but with - // added priority parameter. - class UploaderInterface { - public: - virtual ~UploaderInterface() = default; - - // Unserializes every record and hands ownership over for processing (e.g. - // to add to the network message). Expects |processed_cb| to be called after - // the record or error status has been processed, with true if next record - // needs to be delivered and false if the Uploader should stop. - virtual void ProcessRecord(StatusOr<EncryptedRecord> record, - base::OnceCallback<void(bool)> processed_cb) = 0; - - // Finalizes the upload (e.g. sends the message to the server and gets - // response). - virtual void Completed(Status final_status) = 0; - }; + // Interface for Upload, forwarding to StorageQueue::UploaderInterface. + using UploaderInterface = StorageQueue::UploaderInterface; // Callback type for UploadInterface provider for specified queue. using StartUploadCb =
diff --git a/chrome/browser/policy/messaging_layer/storage/storage_queue.cc b/chrome/browser/policy/messaging_layer/storage/storage_queue.cc index 06a1cd1..1f9564f2 100644 --- a/chrome/browser/policy/messaging_layer/storage/storage_queue.cc +++ b/chrome/browser/policy/messaging_layer/storage/storage_queue.cc
@@ -656,6 +656,7 @@ void CallCurrentRecord(uint64_t generation_id, uint64_t seq_number, base::StringPiece blob) { + DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_); google::protobuf::io::ArrayInputStream stream( // Zero-copy stream. blob.data(), blob.size()); EncryptedRecord encrypted_record; @@ -1030,6 +1031,7 @@ Status StorageQueue::RemoveConfirmedData(uint64_t seq_number) { DCHECK_CALLED_ON_VALID_SEQUENCE(storage_queue_sequence_checker_); + // Update first available number, if new one is higher. if (first_seq_number_ <= seq_number) { first_seq_number_ = seq_number + 1; }
diff --git a/chrome/browser/policy/messaging_layer/storage/storage_queue.h b/chrome/browser/policy/messaging_layer/storage/storage_queue.h index 72ca81e7..fab33bb 100644 --- a/chrome/browser/policy/messaging_layer/storage/storage_queue.h +++ b/chrome/browser/policy/messaging_layer/storage/storage_queue.h
@@ -113,6 +113,14 @@ virtual void ProcessRecord(StatusOr<EncryptedRecord> record, base::OnceCallback<void(bool)> processed_cb) = 0; + // Makes a note of a gap [start, start + count). Expects |processed_cb| to + // be called after the record or error status has been processed, with true + // if next record needs to be delivered and false if the Uploader should + // stop. + virtual void ProcessGap(SequencingInformation start, + uint64_t count, + base::OnceCallback<void(bool)> processed_cb) = 0; + // Finalizes the upload (e.g. sends the message to server and gets // response). Called always, regardless of whether there were errors. virtual void Completed(Status final_status) = 0; @@ -161,14 +169,15 @@ // |uploader|->ProcessRecord (keeping ownership of the buffer) and resuming // after result callback returns 'true'. Only files that have been closed are // included in reading; |Upload| makes sure to close the last writeable file - // and create a new one before starting to send records to the |uploader|. If - // the monotonic order of sequencing is broken, INTERNAL error Status is - // reported. |Upload| can be stopped after any record by returning 'false' to - // |processed_cb| callback - in that case |Upload| will behave as if the end - // of data has been reached. While one or more |Upload|s are active, files can - // be added to the StorageQueue but cannot be deleted. If processing of the - // record takes significant time, |uploader| implementation should be offset - // to another thread to avoid locking StorageQueue. + // and create a new one before starting to send records to the |uploader|. + // If some records are not available or corrupt, |uploader|->ProcessGap is + // called. If the monotonic order of sequencing is broken, INTERNAL error + // Status is reported. |Upload| can be stopped after any record by returning + // 'false' to |processed_cb| callback - in that case |Upload| will behave as + // if the end of data has been reached. While one or more |Upload|s are + // active, files can be added to the StorageQueue but cannot be deleted. If + // processing of the record takes significant time, |uploader| implementation + // should be offset to another thread to avoid locking StorageQueue. // Helper methods: SwitchLastFileIfNotEmpty, CollectFilesForUpload. void Flush();
diff --git a/chrome/browser/policy/messaging_layer/storage/storage_queue_unittest.cc b/chrome/browser/policy/messaging_layer/storage/storage_queue_unittest.cc index 1dca6c30..f5d442e 100644 --- a/chrome/browser/policy/messaging_layer/storage/storage_queue_unittest.cc +++ b/chrome/browser/policy/messaging_layer/storage/storage_queue_unittest.cc
@@ -150,6 +150,12 @@ wrapped_record.record().data())); } + void ProcessGap(SequencingInformation start, + uint64_t count, + base::OnceCallback<void(bool)> processed_cb) override { + LOG(FATAL) << "Gap not implemented yet"; + } + void Completed(Status status) override { UploadComplete(status); } MOCK_METHOD(bool, UploadRecord, (uint64_t, base::StringPiece), (const));
diff --git a/chrome/browser/policy/messaging_layer/storage/storage_unittest.cc b/chrome/browser/policy/messaging_layer/storage/storage_unittest.cc index 8b36550..8cd7b8a 100644 --- a/chrome/browser/policy/messaging_layer/storage/storage_unittest.cc +++ b/chrome/browser/policy/messaging_layer/storage/storage_unittest.cc
@@ -157,6 +157,12 @@ wrapped_record.record().data())); } + void ProcessGap(SequencingInformation start, + uint64_t count, + base::OnceCallback<void(bool)> processed_cb) override { + LOG(FATAL) << "Gap not implemented yet"; + } + void Completed(Status status) override { UploadComplete(status); } MOCK_METHOD(bool,
diff --git a/chrome/browser/profiles/profile_browsertest.cc b/chrome/browser/profiles/profile_browsertest.cc index e691466..df09b21b 100644 --- a/chrome/browser/profiles/profile_browsertest.cc +++ b/chrome/browser/profiles/profile_browsertest.cc
@@ -54,10 +54,8 @@ #include "content/public/browser/storage_partition.h" #include "content/public/test/browser_test.h" #include "content/public/test/test_utils.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/common/extension.h" -#include "extensions/common/extension_builder.h" -#include "extensions/common/value_builder.h" +#include "extensions/buildflags/buildflags.h" +#include "mojo/public/cpp/bindings/remote.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/dns/mock_host_resolver.h" @@ -76,6 +74,14 @@ #include "chromeos/constants/chromeos_switches.h" #endif +#if BUILDFLAG(ENABLE_EXTENSIONS) +#include "extensions/browser/extension_protocols.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/common/extension.h" +#include "extensions/common/extension_builder.h" +#include "extensions/common/value_builder.h" +#endif + namespace { // A helper class which creates a SimpleURLLoader with an expected final status @@ -143,17 +149,21 @@ void Watch(Profile* profile) { observed_profiles_.Add(profile); } + bool destroyed() const { return destroyed_; } + + void WaitForDestruction() { run_loop_.Run(); } + + private: // ProfileObserver: void OnProfileWillBeDestroyed(Profile* profile) override { DCHECK(!destroyed_) << "Double profile destruction"; destroyed_ = true; + run_loop_.Quit(); observed_profiles_.Remove(profile); } - bool destroyed() const { return destroyed_; } - - private: bool destroyed_ = false; + base::RunLoop run_loop_; ScopedObserver<Profile, ProfileObserver> observed_profiles_{this}; DISALLOW_COPY_AND_ASSIGN(ProfileDestructionWatcher); @@ -583,7 +593,6 @@ // The following tests make sure that it's safe to shut down while one of the // Profile's URLLoaderFactories is in use by a SimpleURLLoader. - IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, SimpleURLLoaderUsingMainContextDuringShutdown) { ASSERT_TRUE(embedded_test_server()->Start()); @@ -595,7 +604,6 @@ // The following tests make sure that it's safe to destroy an incognito profile // while one of the its URLLoaderFactory is in use by a SimpleURLLoader. - IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, SimpleURLLoaderUsingMainContextDuringIncognitoTeardown) { ASSERT_TRUE(embedded_test_server()->Start()); @@ -609,7 +617,64 @@ .get()); } -// Verifies the cache directory supports multiple profiles when it's overriden +#if BUILDFLAG(ENABLE_EXTENSIONS) +// Regression test for https://crbug.com/1136214 - verification that +// ExtensionURLLoaderFactory won't hit a use-after-free bug when used after +// a Profile has been torn down already. +IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, + ExtensionURLLoaderFactoryAfterIncognitoTeardown) { + // Create a mojo::Remote to ExtensionURLLoaderFactory for the incognito + // profile. + Browser* incognito_browser = + OpenURLOffTheRecord(browser()->profile(), GURL("about:blank")); + Profile* incognito_profile = incognito_browser->profile(); + mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory; + url_loader_factory.Bind(extensions::CreateExtensionNavigationURLLoaderFactory( + incognito_profile, base::kInvalidUkmSourceId, + false /* is_web_view_request */)); + + // Verify that the factory works fine while the profile is still alive. + // We don't need to test with a real extension URL - it is sufficient to + // verify that the factory responds with ERR_BLOCKED_BY_CLIENT that indicates + // a missing extension. + GURL missing_extension_url("chrome-extension://no-such-extension/blah"); + { + SimpleURLLoaderHelper simple_loader_helper(url_loader_factory.get(), + missing_extension_url, + net::ERR_BLOCKED_BY_CLIENT); + simple_loader_helper.WaitForCompletion(); + } + + { + // Start monitoring |incognito_profile| for shutdown. + ProfileManager* profile_manager = g_browser_process->profile_manager(); + EXPECT_TRUE(profile_manager->IsValidProfile(incognito_profile)); + ProfileDestructionWatcher watcher; + watcher.Watch(incognito_profile); + + // Close all incognito tabs, starting profile shutdown. + incognito_browser->tab_strip_model()->CloseAllTabs(); + + // ProfileDestructionWatcher waits for + // BrowserContext::NotifyWillBeDestroyed, but after the RunLoop unwinds, the + // profile should already be gone - let's assert this below (since this + // ensures that |simple_loader_helper2| really tests what needs to be + // tested). + watcher.WaitForDestruction(); + EXPECT_FALSE(profile_manager->IsValidProfile(incognito_profile)); + } + + // Verify that the factory doesn't crash (https://crbug.com/1136214), but + // instead SimpleURLLoaderImpl::OnMojoDisconnect reports net::ERR_FAILED. + { + SimpleURLLoaderHelper simple_loader_helper2( + url_loader_factory.get(), missing_extension_url, net::ERR_FAILED); + simple_loader_helper2.WaitForCompletion(); + } +} +#endif + +// Verifies the cache directory supports multiple profiles when it's overridden // by group policy or command line switches. IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, DiskCacheDirOverride) { base::ScopedAllowBlockingForTesting allow_blocking;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/keyboard_handler_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/keyboard_handler_test.js index 6483c17..2234668d 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/keyboard_handler_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/keyboard_handler_test.js
@@ -45,22 +45,23 @@ assertEquals(0, keyboardHandler.passedThroughKeyDowns_.size); // Send the pass through command: Search+Shift+Escape. - const search = this.createMockKeyEvent(KeyCode.SEARCH, {metaKey: true}); + const search = + TestUtils.createMockKeyEvent(KeyCode.SEARCH, {metaKey: true}); keyboardHandler.onKeyDown(search); assertEquals(1, keyboardHandler.eatenKeyDowns_.size); assertEquals(0, keyboardHandler.passedThroughKeyDowns_.size); assertEquals('no_pass_through', keyboardHandler.passThroughState_); assertUndefined(ChromeVox.passThroughMode); - const searchShift = - this.createMockKeyEvent(KeyCode.SHIFT, {metaKey: true, shiftKey: true}); + const searchShift = TestUtils.createMockKeyEvent( + KeyCode.SHIFT, {metaKey: true, shiftKey: true}); keyboardHandler.onKeyDown(searchShift); assertEquals(2, keyboardHandler.eatenKeyDowns_.size); assertEquals(0, keyboardHandler.passedThroughKeyDowns_.size); assertEquals('no_pass_through', keyboardHandler.passThroughState_); assertUndefined(ChromeVox.passThroughMode); - const searchShiftEsc = this.createMockKeyEvent( + const searchShiftEsc = TestUtils.createMockKeyEvent( KeyCode.ESCAPE, {metaKey: true, shiftKey: true}); keyboardHandler.onKeyDown(searchShiftEsc); assertEquals(3, keyboardHandler.eatenKeyDowns_.size); @@ -97,7 +98,7 @@ assertEquals('pending_shortcut_keyups', keyboardHandler.passThroughState_); assertTrue(ChromeVox.passThroughMode); - const searchCtrl = this.createMockKeyEvent( + const searchCtrl = TestUtils.createMockKeyEvent( KeyCode.CONTROL, {metaKey: true, ctrlKey: true}); keyboardHandler.onKeyDown(searchCtrl); assertEquals(0, keyboardHandler.eatenKeyDowns_.size); @@ -106,7 +107,7 @@ assertTrue(ChromeVox.passThroughMode); const searchCtrlM = - this.createMockKeyEvent(KeyCode.M, {metaKey: true, ctrlKey: true}); + TestUtils.createMockKeyEvent(KeyCode.M, {metaKey: true, ctrlKey: true}); keyboardHandler.onKeyDown(searchCtrlM); assertEquals(0, keyboardHandler.eatenKeyDowns_.size); assertEquals(3, keyboardHandler.passedThroughKeyDowns_.size); @@ -144,17 +145,18 @@ // Send some random keys; ensure the pass through state variables never // change. - const search = this.createMockKeyEvent(KeyCode.SEARCH, {metaKey: true}); + const search = + TestUtils.createMockKeyEvent(KeyCode.SEARCH, {metaKey: true}); keyboardHandler.onKeyDown(search); assertNoPassThrough(); - const searchShift = this.createMockKeyEvent( + const searchShift = TestUtils.createMockKeyEvent( KeyCode.SHIFT, {metaKey: true, shiftKey: true}); keyboardHandler.onKeyDown(searchShift); assertNoPassThrough(); - const searchShiftM = - this.createMockKeyEvent(KeyCode.M, {metaKey: true, shiftKey: true}); + const searchShiftM = TestUtils.createMockKeyEvent( + KeyCode.M, {metaKey: true, shiftKey: true}); keyboardHandler.onKeyDown(searchShiftM); assertNoPassThrough(); @@ -167,15 +169,15 @@ keyboardHandler.onKeyUp(search); assertNoPassThrough(); - keyboardHandler.onKeyDown(this.createMockKeyEvent(KeyCode.A)); + keyboardHandler.onKeyDown(TestUtils.createMockKeyEvent(KeyCode.A)); assertNoPassThrough(); keyboardHandler.onKeyDown( - this.createMockKeyEvent(KeyCode.A, {altKey: true})); + TestUtils.createMockKeyEvent(KeyCode.A, {altKey: true})); assertNoPassThrough(); keyboardHandler.onKeyUp( - this.createMockKeyEvent(KeyCode.A, {altKey: true})); + TestUtils.createMockKeyEvent(KeyCode.A, {altKey: true})); assertNoPassThrough(); }); }); @@ -185,23 +187,24 @@ function() { this.runWithLoadedTree('<p>test</p>', function() { // Send a few key downs. - const search = this.createMockKeyEvent(KeyCode.SEARCH, {metaKey: true}); + const search = + TestUtils.createMockKeyEvent(KeyCode.SEARCH, {metaKey: true}); keyboardHandler.onKeyDown(search); assertEquals(1, keyboardHandler.eatenKeyDowns_.size); - const searchShift = this.createMockKeyEvent( + const searchShift = TestUtils.createMockKeyEvent( KeyCode.SHIFT, {metaKey: true, shiftKey: true}); keyboardHandler.onKeyDown(searchShift); assertEquals(2, keyboardHandler.eatenKeyDowns_.size); - const searchShiftM = - this.createMockKeyEvent(KeyCode.M, {metaKey: true, shiftKey: true}); + const searchShiftM = TestUtils.createMockKeyEvent( + KeyCode.M, {metaKey: true, shiftKey: true}); keyboardHandler.onKeyDown(searchShiftM); assertEquals(3, keyboardHandler.eatenKeyDowns_.size); // Now, send a key down, but no modifiers set, which is impossible to // actually press. This key is not eaten. - const m = this.createMockKeyEvent(KeyCode.M, {}); + const m = TestUtils.createMockKeyEvent(KeyCode.M, {}); keyboardHandler.onKeyDown(m); assertEquals(0, keyboardHandler.eatenKeyDowns_.size); @@ -220,26 +223,27 @@ ChromeVox.passThroughMode = true; // Send a few key downs (which are passed through). - const search = this.createMockKeyEvent(KeyCode.SEARCH, {metaKey: true}); + const search = + TestUtils.createMockKeyEvent(KeyCode.SEARCH, {metaKey: true}); keyboardHandler.onKeyDown(search); assertEquals(0, keyboardHandler.eatenKeyDowns_.size); assertEquals(1, keyboardHandler.passedThroughKeyDowns_.size); - const searchShift = this.createMockKeyEvent( + const searchShift = TestUtils.createMockKeyEvent( KeyCode.SHIFT, {metaKey: true, shiftKey: true}); keyboardHandler.onKeyDown(searchShift); assertEquals(0, keyboardHandler.eatenKeyDowns_.size); assertEquals(2, keyboardHandler.passedThroughKeyDowns_.size); - const searchShiftM = - this.createMockKeyEvent(KeyCode.M, {metaKey: true, shiftKey: true}); + const searchShiftM = TestUtils.createMockKeyEvent( + KeyCode.M, {metaKey: true, shiftKey: true}); keyboardHandler.onKeyDown(searchShiftM); assertEquals(0, keyboardHandler.eatenKeyDowns_.size); assertEquals(3, keyboardHandler.passedThroughKeyDowns_.size); // Now, send a key down, but no modifiers set, which is impossible to // actually press. This is passed through, so the count resets to 1. - const m = this.createMockKeyEvent(KeyCode.M, {}); + const m = TestUtils.createMockKeyEvent(KeyCode.M, {}); keyboardHandler.onKeyDown(m); assertEquals(0, keyboardHandler.eatenKeyDowns_.size); assertEquals(1, keyboardHandler.passedThroughKeyDowns_.size);
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor_test.js index 7a0ef71..5613428 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor_test.js
@@ -69,7 +69,8 @@ const keySequenceActionOne = UserActionMonitor.Action.fromActionInfo( {type: 'key_sequence', value: {keys: {keyCode: [KeyCode.SPACE]}}}); const keySequenceActionTwo = new UserActionMonitor.Action( - 'key_sequence', new KeySequence(this.createMockKeyEvent(KeyCode.A))); + 'key_sequence', + new KeySequence(TestUtils.createMockKeyEvent(KeyCode.A))); const gestureActionOne = UserActionMonitor.Action.fromActionInfo( {type: 'gesture', value: 'swipeUp1'}); const gestureActionTwo = @@ -146,7 +147,7 @@ try { monitor.onKeySequence( - new KeySequence(this.createMockKeyEvent(KeyCode.SPACE))); + new KeySequence(TestUtils.createMockKeyEvent(KeyCode.SPACE))); assertTrue(false); // Shouldn't execute. } catch (error) { assertEquals( @@ -227,14 +228,14 @@ const onFinished = () => finished = true; ChromeVoxState.instance.createUserActionMonitor(actions, onFinished); - keyboardHandler.onKeyDown(this.createMockKeyEvent(KeyCode.LEFT)); - keyboardHandler.onKeyUp(this.createMockKeyEvent(KeyCode.LEFT)); + keyboardHandler.onKeyDown(TestUtils.createMockKeyEvent(KeyCode.LEFT)); + keyboardHandler.onKeyUp(TestUtils.createMockKeyEvent(KeyCode.LEFT)); assertFalse(finished); - keyboardHandler.onKeyDown(this.createMockKeyEvent(KeyCode.RIGHT)); - keyboardHandler.onKeyUp(this.createMockKeyEvent(KeyCode.RIGHT)); + keyboardHandler.onKeyDown(TestUtils.createMockKeyEvent(KeyCode.RIGHT)); + keyboardHandler.onKeyUp(TestUtils.createMockKeyEvent(KeyCode.RIGHT)); assertFalse(finished); - keyboardHandler.onKeyDown(this.createMockKeyEvent(KeyCode.SPACE)); - keyboardHandler.onKeyUp(this.createMockKeyEvent(KeyCode.SPACE)); + keyboardHandler.onKeyDown(TestUtils.createMockKeyEvent(KeyCode.SPACE)); + keyboardHandler.onKeyUp(TestUtils.createMockKeyEvent(KeyCode.SPACE)); assertTrue(finished); }); }); @@ -252,21 +253,21 @@ const onFinished = () => finished = true; ChromeVoxState.instance.createUserActionMonitor(actions, onFinished); - keyboardHandler.onKeyDown(this.createMockKeyEvent(KeyCode.O)); - keyboardHandler.onKeyUp(this.createMockKeyEvent(KeyCode.O)); + keyboardHandler.onKeyDown(TestUtils.createMockKeyEvent(KeyCode.O)); + keyboardHandler.onKeyUp(TestUtils.createMockKeyEvent(KeyCode.O)); assertFalse(finished); - keyboardHandler.onKeyDown(this.createMockKeyEvent(KeyCode.B)); - keyboardHandler.onKeyUp(this.createMockKeyEvent(KeyCode.B)); + keyboardHandler.onKeyDown(TestUtils.createMockKeyEvent(KeyCode.B)); + keyboardHandler.onKeyUp(TestUtils.createMockKeyEvent(KeyCode.B)); assertFalse(finished); - keyboardHandler.onKeyDown(this.createMockKeyEvent(KeyCode.SEARCH)); - keyboardHandler.onKeyUp(this.createMockKeyEvent(KeyCode.SEARCH)); + keyboardHandler.onKeyDown(TestUtils.createMockKeyEvent(KeyCode.SEARCH)); + keyboardHandler.onKeyUp(TestUtils.createMockKeyEvent(KeyCode.SEARCH)); assertFalse(finished); keyboardHandler.onKeyDown( - this.createMockKeyEvent(KeyCode.O, {searchKeyHeld: true})); + TestUtils.createMockKeyEvent(KeyCode.O, {searchKeyHeld: true})); assertFalse(finished); keyboardHandler.onKeyUp( - this.createMockKeyEvent(KeyCode.O, {searchKeyHeld: true})); - keyboardHandler.onKeyDown(this.createMockKeyEvent(KeyCode.B)); + TestUtils.createMockKeyEvent(KeyCode.O, {searchKeyHeld: true})); + keyboardHandler.onKeyDown(TestUtils.createMockKeyEvent(KeyCode.B)); assertTrue(finished); }); }); @@ -294,10 +295,10 @@ ]; const onFinished = () => finished = true; - const altShiftLSequence = new KeySequence( - this.createMockKeyEvent(KeyCode.L, {altKey: true, shiftKey: true})); - const altShiftSSequence = new KeySequence( - this.createMockKeyEvent(KeyCode.S, {altKey: true, shiftKey: true})); + const altShiftLSequence = new KeySequence(TestUtils.createMockKeyEvent( + KeyCode.L, {altKey: true, shiftKey: true})); + const altShiftSSequence = new KeySequence(TestUtils.createMockKeyEvent( + KeyCode.S, {altKey: true, shiftKey: true})); let monitor; mockFeedback .call(() => { @@ -340,13 +341,13 @@ const onFinished = () => finished = true; const nextObject = - this.createMockKeyEvent(KeyCode.RIGHT, {searchKeyHeld: true}); + TestUtils.createMockKeyEvent(KeyCode.RIGHT, {searchKeyHeld: true}); const nextLine = - this.createMockKeyEvent(KeyCode.DOWN, {searchKeyHeld: true}); + TestUtils.createMockKeyEvent(KeyCode.DOWN, {searchKeyHeld: true}); const previousObject = - this.createMockKeyEvent(KeyCode.LEFT, {searchKeyHeld: true}); + TestUtils.createMockKeyEvent(KeyCode.LEFT, {searchKeyHeld: true}); const previousLine = - this.createMockKeyEvent(KeyCode.UP, {searchKeyHeld: true}); + TestUtils.createMockKeyEvent(KeyCode.UP, {searchKeyHeld: true}); ChromeVoxState.instance.createUserActionMonitor(actions, onFinished); mockFeedback.expectSpeech('Start') @@ -402,15 +403,15 @@ assertFalse(closed); assertFalse(finished); keyboardHandler.onKeyDown( - this.createMockKeyEvent(KeyCode.CONTROL, {ctrlKey: true})); + TestUtils.createMockKeyEvent(KeyCode.CONTROL, {ctrlKey: true})); + assertFalse(closed); + assertFalse(finished); + keyboardHandler.onKeyDown(TestUtils.createMockKeyEvent( + KeyCode.ALT, {ctrlKey: true, altKey: true})); assertFalse(closed); assertFalse(finished); keyboardHandler.onKeyDown( - this.createMockKeyEvent(KeyCode.ALT, {ctrlKey: true, altKey: true})); - assertFalse(closed); - assertFalse(finished); - keyboardHandler.onKeyDown( - this.createMockKeyEvent(KeyCode.Z, {ctrlKey: true, altKey: true})); + TestUtils.createMockKeyEvent(KeyCode.Z, {ctrlKey: true, altKey: true})); assertTrue(closed); // |finished| remains false since we didn't press the expected key sequence. assertFalse(finished);
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js index 8b28022..4e6b0b04c 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js
@@ -500,7 +500,7 @@ return ChromeVoxState.instance.getCurrentRange().start.node; }; const simulateKeyPress = (keyCode, opt_modifiers) => { - const keyEvent = this.createMockKeyEvent(keyCode, opt_modifiers); + const keyEvent = TestUtils.createMockKeyEvent(keyCode, opt_modifiers); keyboardHandler.onKeyDown(keyEvent); keyboardHandler.onKeyUp(keyEvent); };
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/testing/common.js b/chrome/browser/resources/chromeos/accessibility/chromevox/testing/common.js index 8078800..5a42485 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/testing/common.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/testing/common.js
@@ -41,6 +41,31 @@ } return stringified.replace(/^[^\/]+\/\*!?/, '').replace(/\*\/[^\/]+$/, ''); } + + /** + * Create a mock event object. + * @param {number} keyCode + * @param {{altGraphKey: boolean=, + * altKey: boolean=, + * ctrlKey: boolean=, + * metaKey: boolean=, + * searchKeyHeld: boolean=, + * shiftKey: boolean=, + * stickyMode: boolean=, + * prefixKey: boolean=}=} opt_modifiers + * @return {Object} The mock event. + */ + static createMockKeyEvent(keyCode, opt_modifiers) { + const modifiers = opt_modifiers === undefined ? {} : opt_modifiers; + const keyEvent = {}; + keyEvent.keyCode = keyCode; + for (const key in modifiers) { + keyEvent[key] = modifiers[key]; + } + keyEvent.preventDefault = _ => {}; + keyEvent.stopPropagation = _ => {}; + return keyEvent; + } }
diff --git a/chrome/browser/resources/chromeos/accessibility/common/event_generator_test.js b/chrome/browser/resources/chromeos/accessibility/common/event_generator_test.js index 98d88a7..11b9973 100644 --- a/chrome/browser/resources/chromeos/accessibility/common/event_generator_test.js +++ b/chrome/browser/resources/chromeos/accessibility/common/event_generator_test.js
@@ -10,34 +10,39 @@ /** Test fixture for array_util.js. */ EventGeneratorTest = class extends ChromeVoxNextE2ETest {}; -TEST_F('EventGeneratorTest', 'MouseEventsProcessedSequentially', function() { - const mouseEventLog = []; - chrome.accessibilityPrivate.sendSyntheticMouseEvent = (event) => - mouseEventLog.push(event); +// Fails on ChromeOS - https://crbug.com/1136991 +TEST_F( + 'EventGeneratorTest', 'DISABLED_MouseEventsProcessedSequentially', + function() { + const mouseEventLog = []; + chrome.accessibilityPrivate.sendSyntheticMouseEvent = (event) => + mouseEventLog.push(event); - // Set a 1ms delay so that a timeout is set between the press and release. - EventGenerator.sendMouseClick(100, 100, /*delayMs=*/ 1); - assertEquals(1, mouseEventLog.length, 'First event should be synchronous'); + // Set a 1ms delay so that a timeout is set between the press and release. + EventGenerator.sendMouseClick(100, 100, /*delayMs=*/ 1); + assertEquals( + 1, mouseEventLog.length, 'First event should be synchronous'); - EventGenerator.sendMouseClick(200, 200, /*delayMs=*/ 1); - assertEquals( - 1, mouseEventLog.length, - 'Second mouse click shouldn\'t start until first has finished'); + EventGenerator.sendMouseClick(200, 200, /*delayMs=*/ 1); + assertEquals( + 1, mouseEventLog.length, + 'Second mouse click shouldn\'t start until first has finished'); - const checkEventLog = () => { - assertEquals( - 4, mouseEventLog.length, 'Both click events should have completed.'); - assertEquals('press', mouseEventLog[0].type); - assertEquals('release', mouseEventLog[1].type); - assertEquals(mouseEventLog[0].x, mouseEventLog[1].x); - assertEquals(mouseEventLog[0].y, mouseEventLog[1].y); + const checkEventLog = () => { + assertEquals( + 4, mouseEventLog.length, + 'Both click events should have completed.'); + assertEquals('press', mouseEventLog[0].type); + assertEquals('release', mouseEventLog[1].type); + assertEquals(mouseEventLog[0].x, mouseEventLog[1].x); + assertEquals(mouseEventLog[0].y, mouseEventLog[1].y); - assertEquals('press', mouseEventLog[2].type); - assertEquals('release', mouseEventLog[3].type); - assertEquals(mouseEventLog[2].x, mouseEventLog[3].x); - assertEquals(mouseEventLog[2].y, mouseEventLog[3].y); - }; - // Experimentally, the code takes 13ms to set all timeouts on a development - // machine. Wait 150ms to increase stability. - setTimeout(this.newCallback(checkEventLog), 150); -}); + assertEquals('press', mouseEventLog[2].type); + assertEquals('release', mouseEventLog[3].type); + assertEquals(mouseEventLog[2].x, mouseEventLog[3].x); + assertEquals(mouseEventLog[2].y, mouseEventLog[3].y); + }; + // Experimentally, the code takes 13ms to set all timeouts on a + // development machine. Wait 150ms to increase stability. + setTimeout(this.newCallback(checkEventLog), 150); + });
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access/action_manager.js b/chrome/browser/resources/chromeos/accessibility/switch_access/action_manager.js index e985578..ef16932 100644 --- a/chrome/browser/resources/chromeos/accessibility/switch_access/action_manager.js +++ b/chrome/browser/resources/chromeos/accessibility/switch_access/action_manager.js
@@ -152,6 +152,7 @@ * @private */ addGlobalActions_(actions) { + actions.push(SwitchAccessMenuAction.POINT_SCAN); actions.push(SwitchAccessMenuAction.SETTINGS); return actions; } @@ -193,6 +194,8 @@ case SwitchAccessMenuAction.SETTINGS: chrome.accessibilityPrivate.openSettingsSubpage( 'manageAccessibility/switchAccess'); + case SwitchAccessMenuAction.POINT_SCAN: + chrome.accessibilityPrivate.enablePointScan(true); return true; default: return false;
diff --git a/chrome/browser/resources/read_later/app.html b/chrome/browser/resources/read_later/app.html index e1cc65b..4732bbc 100644 --- a/chrome/browser/resources/read_later/app.html +++ b/chrome/browser/resources/read_later/app.html
@@ -1,32 +1,28 @@ <style include="mwb-shared-style"> #header { align-items: center; - font-size: 15px; + display: flex; + font-size: var(--mwb-primary-text-font-size); + height: var(--mwb-item-height); margin: 0; - padding: var(--mwb-list-item-vertical-margin) - var(--mwb-list-item-horizontal-margin); + padding-inline-start: var(--mwb-list-item-horizontal-margin); } #read-later-list { - max-height: 458px; + max-height: 444px; overflow-x: hidden; overflow-y: auto; } .sub-heading { + align-items: center; + border-bottom: 1px solid #dbdbdb; color: var(--cr-secondary-text-color); - font-size: var(--mwb-secondary-text-font-size); - padding: var(--mwb-list-item-vertical-margin) - 0 - calc(var(--mwb-list-item-vertical-margin) / 2) - var(--mwb-list-item-horizontal-margin); - } - - .sub-heading::after { - border-bottom: 1px solid var(--cr-secondary-text-color); - content: ''; - display: block; - margin-top: calc(var(--mwb-list-item-vertical-margin) / 2); + display: flex; + font-size: 11px; + height: 24px; + margin-inline-start: var(--mwb-list-item-horizontal-margin); + margin-top: 4px; } </style>
diff --git a/chrome/browser/resources/read_later/read_later_item.html b/chrome/browser/resources/read_later/read_later_item.html index b3af5194..4a7ee2b 100644 --- a/chrome/browser/resources/read_later/read_later_item.html +++ b/chrome/browser/resources/read_later/read_later_item.html
@@ -1,11 +1,14 @@ <style> - :host(:hover) .button-container, - :host(.selected) .button-container { + .button-container { display: flex; + margin-inline-start: calc(var(--mwb-icon-size) / 2); + overflow: hidden; + width: 0; } - .button-container { - display: none; + :host(:hover) .button-container { + overflow: visible; + width: auto; } .text-container { @@ -33,9 +36,24 @@ } cr-icon-button { - --cr-icon-button-margin-end: calc(var(--mwb-icon-size) / 4); - --cr-icon-button-margin-start: calc(var(--mwb-icon-size) / 4); - --cr-icon-button-size: var(--mwb-icon-size); + border-radius: 50%; + --cr-icon-button-fill-color: transparent; + --cr-icon-button-icon-size: var(--mwb-icon-size); + --cr-icon-button-size: 24px; + --cr-icon-button-margin-start: 0; + --cr-icon-button-margin-end: 0; + } + + :host(:hover) cr-icon-button { + --cr-icon-button-fill-color: var(--google-grey-refresh-700); + } + + cr-icon-button:hover { + background-color: rgba(var(--google-grey-900-rgb), .1); + } + + #deleteButton { + margin-inline-start: calc(var(--cr-icon-button-size) / 2); } </style> @@ -47,14 +65,14 @@ </div> <div class="button-container"> <cr-icon-button id="updateStatusButton" - aria-label="[[getUpdateStatusButtonTooltip_( - '$i18n{tooltipMarkAsUnread}', '$i18n{tooltipMarkAsRead}', data.read)]]" + aria-label="[[getUpdateStatusButtonTooltip_('$i18n{tooltipMarkAsUnread}', + '$i18n{tooltipMarkAsRead}', data.read)]]" disable-ripple iron-icon="cr:check" title="[[getUpdateStatusButtonTooltip_( '$i18n{tooltipMarkAsUnread}', '$i18n{tooltipMarkAsRead}', data.read)]]" on-click="onUpdateStatusClick_"> </cr-icon-button> <cr-icon-button id="deleteButton" aria-label="$i18n{tooltipDelete}" - iron-icon="cr:close" title="$i18n{tooltipDelete}" + disable-ripple iron-icon="cr:close" title="$i18n{tooltipDelete}" on-click="onItemDeleteClick_"> </cr-icon-button> </div>
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 13355a816..116928e 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
@@ -119,7 +119,7 @@ // reasons (timeout, user cancel, etc). During a receive transfer, it // happens before we start connecting (because we need to stop // advertising) so we need to wait a bit to see if we see an - // onIncomingShare event within a reasonable timeout. This is the normal + // onTransferUpdate event within a reasonable timeout. This is the normal // case and it should happen quickly when it is a real connection. In the // timeout case, we are just exiting high visibility normally and can // close for now, and the small timeout won't impact UX. Ideally we should @@ -129,16 +129,19 @@ }, /** - * Mojo callback called when a shareTarget is requesting an incoming share - * and the user must manually confirm. + * Mojo callback when transfer status changes. * @param {!nearbyShare.mojom.ShareTarget} shareTarget - * @param {?string} connectionToken + * @param {!nearbyShare.mojom.TransferMetadata} metadata */ - onIncomingShare(shareTarget, connectionToken) { - clearTimeout(this.closeTimeoutId_); - this.shareTarget = shareTarget; - this.connectionToken = connectionToken; - this.showConfirmPage(); + onTransferUpdate(shareTarget, metadata) { + if (metadata.status === + nearbyShare.mojom.TransferStatus.kAwaitingLocalConfirmation) { + clearTimeout(this.closeTimeoutId_); + this.shareTarget = shareTarget; + this.connectionToken = + (metadata && metadata.token) ? metadata.token : null; + this.showConfirmPage(); + } }, /**
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn index db665d9..1c73133 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn
@@ -34,6 +34,7 @@ js_library("account_manager") { deps = [ "..:deep_linking_behavior", + "..:metrics_recorder", "..:os_route", "../..:router", "../../people_page:account_manager_browser_proxy", @@ -259,6 +260,7 @@ sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.m.js" ] deps = [ "..:deep_linking_behavior.m", + "..:metrics_recorder.m", "..:os_route.m", "../..:router.m", "../../people_page:account_manager_browser_proxy.m",
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html index 1e3aec1..9ccd38e9 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html +++ b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html
@@ -12,6 +12,7 @@ <link rel="import" href="../localized_link/localized_link.html"> <link rel="import" href="../../i18n_setup.html"> <link rel="import" href="../deep_linking_behavior.html"> +<link rel="import" href="../metrics_recorder.html"> <link rel="import" href="../os_route.html"> <link rel="import" href="../../router.html"> <link rel="import" href="../../settings_shared_css.html">
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.js b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.js index ff8f287..5460fd6 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.js +++ b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.js
@@ -161,6 +161,9 @@ * @private */ addAccount_(event) { + settings.recordSettingChange( + chromeos.settings.mojom.Setting.kAddAccount, + {intValue: this.accounts_.length + 1}); this.browserProxy_.addAccount(); },
diff --git a/chrome/browser/resources/settings/chromeos/os_route.js b/chrome/browser/resources/settings/chromeos/os_route.js index 92d5e32ca..ae24519 100644 --- a/chrome/browser/resources/settings/chromeos/os_route.js +++ b/chrome/browser/resources/settings/chromeos/os_route.js
@@ -115,7 +115,8 @@ r.OS_PEOPLE, mojom.MANAGE_OTHER_PEOPLE_SUBPAGE_PATH, Subpage.kManageOtherPeople); r.KERBEROS_ACCOUNTS = createSubpage( - r.OS_PEOPLE, mojom.KERBEROS_SUBPAGE_PATH, Subpage.kKerberos); + r.OS_PEOPLE, mojom.KERBEROS_ACCOUNTS_SUBPAGE_PATH, + Subpage.kKerberosAccounts); } // Device section.
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc index 66ee1a6..bd7b78df 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
@@ -2290,81 +2290,81 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, VerifyNumberOfRecentNavigationsToCollect) { EXPECT_EQ(0, CountOfRecentNavigationsToAppend( - /*sber=*/false, /*incognito=*/false, + /*extended_reporting_enabled=*/false, /*is_incognito=*/false, SafeBrowsingNavigationObserverManager::SUCCESS)); EXPECT_EQ(0, CountOfRecentNavigationsToAppend( - /*sber=*/false, /*incognito=*/true, + /*extended_reporting_enabled=*/false, /*is_incognito=*/true, SafeBrowsingNavigationObserverManager::SUCCESS)); EXPECT_EQ(0, CountOfRecentNavigationsToAppend( - /*sber=*/false, /*incognito=*/false, + /*extended_reporting_enabled=*/false, /*is_incognito=*/false, SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_PAGE)); EXPECT_EQ(0, CountOfRecentNavigationsToAppend( - /*sber=*/false, /*incognito=*/true, + /*extended_reporting_enabled=*/false, /*is_incognito=*/true, SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_PAGE)); EXPECT_EQ( 0, CountOfRecentNavigationsToAppend( - /*sber=*/false, /*incognito=*/false, + /*extended_reporting_enabled=*/false, /*is_incognito=*/false, SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER)); EXPECT_EQ( 0, CountOfRecentNavigationsToAppend( - /*sber=*/false, /*incognito=*/true, + /*extended_reporting_enabled=*/false, /*is_incognito=*/true, SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER)); EXPECT_EQ(0, CountOfRecentNavigationsToAppend( - /*sber=*/false, /*incognito=*/false, + /*extended_reporting_enabled=*/false, /*is_incognito=*/false, SafeBrowsingNavigationObserverManager::INVALID_URL)); EXPECT_EQ(0, CountOfRecentNavigationsToAppend( - /*sber=*/false, /*incognito=*/true, + /*extended_reporting_enabled=*/false, /*is_incognito=*/true, SafeBrowsingNavigationObserverManager::INVALID_URL)); EXPECT_EQ( 0, CountOfRecentNavigationsToAppend( - /*sber=*/false, /*incognito=*/false, + /*extended_reporting_enabled=*/false, /*is_incognito=*/false, SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND)); EXPECT_EQ( 0, CountOfRecentNavigationsToAppend( - /*sber=*/false, /*incognito=*/true, + /*extended_reporting_enabled=*/false, /*is_incognito=*/true, SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND)); EXPECT_EQ(5, CountOfRecentNavigationsToAppend( - /*sber=*/true, /*incognito=*/false, + /*extended_reporting_enabled=*/true, /*is_incognito=*/false, SafeBrowsingNavigationObserverManager::SUCCESS)); EXPECT_EQ(0, CountOfRecentNavigationsToAppend( - /*sber=*/true, /*incognito=*/true, + /*extended_reporting_enabled=*/true, /*is_incognito=*/true, SafeBrowsingNavigationObserverManager::SUCCESS)); EXPECT_EQ(5, CountOfRecentNavigationsToAppend( - /*sber=*/true, /*incognito=*/false, + /*extended_reporting_enabled=*/true, /*is_incognito=*/false, SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_PAGE)); EXPECT_EQ(0, CountOfRecentNavigationsToAppend( - /*sber=*/true, /*incognito=*/true, + /*extended_reporting_enabled=*/true, /*is_incognito=*/true, SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_PAGE)); EXPECT_EQ( 0, CountOfRecentNavigationsToAppend( - /*sber=*/true, /*incognito=*/false, + /*extended_reporting_enabled=*/true, /*is_incognito=*/false, SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER)); EXPECT_EQ( 0, CountOfRecentNavigationsToAppend( - /*sber=*/true, /*incognito=*/true, + /*extended_reporting_enabled=*/true, /*is_incognito=*/true, SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER)); EXPECT_EQ(5, CountOfRecentNavigationsToAppend( - /*sber=*/true, /*incognito=*/false, + /*extended_reporting_enabled=*/true, /*is_incognito=*/false, SafeBrowsingNavigationObserverManager::INVALID_URL)); EXPECT_EQ(0, CountOfRecentNavigationsToAppend( - /*sber=*/true, /*incognito=*/true, + /*extended_reporting_enabled=*/true, /*is_incognito=*/true, SafeBrowsingNavigationObserverManager::INVALID_URL)); EXPECT_EQ( 5, CountOfRecentNavigationsToAppend( - /*sber=*/true, /*incognito=*/false, + /*extended_reporting_enabled=*/true, /*is_incognito=*/false, SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND)); EXPECT_EQ( 0, CountOfRecentNavigationsToAppend( - /*sber=*/true, /*incognito=*/true, + /*extended_reporting_enabled=*/true, /*is_incognito=*/true, SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND)); }
diff --git a/chrome/browser/ui/app_list/app_list_test_util.cc b/chrome/browser/ui/app_list/app_list_test_util.cc index 7534fa3..40f1b99 100644 --- a/chrome/browser/ui/app_list/app_list_test_util.cc +++ b/chrome/browser/ui/app_list/app_list_test_util.cc
@@ -44,8 +44,7 @@ InitializeInstalledExtensionService(pref_path, source_install_dir); service_->Init(); - if (base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions)) - ConfigureWebAppProvider(); + ConfigureWebAppProvider(); // Let any async services complete their set-up. base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc index 1cf14e2..9b43169 100644 --- a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc +++ b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc
@@ -47,6 +47,8 @@ const gfx::Rect& anchor, std::vector<std::string> actions) {} +void FakeAccessibilityController::StartPointScan() {} + void FakeAccessibilityController::SetDictationActive(bool is_active) {} void FakeAccessibilityController::ToggleDictationFromSource(
diff --git a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h index a290d34..16c442e 100644 --- a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h +++ b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h
@@ -33,6 +33,7 @@ void ShowSwitchAccessBackButton(const gfx::Rect& anchor) override; void ShowSwitchAccessMenu(const gfx::Rect& anchor, std::vector<std::string> actions) override; + void StartPointScan() override; void SetDictationActive(bool is_active) override; void ToggleDictationFromSource(ash::DictationToggleSource source) override; void HandleAutoclickScrollableBoundsFound(
diff --git a/chrome/browser/ui/ash/ash_test_util.cc b/chrome/browser/ui/ash/ash_test_util.cc index 1f8801e..5e21914 100644 --- a/chrome/browser/ui/ash/ash_test_util.cc +++ b/chrome/browser/ui/ash/ash_test_util.cc
@@ -4,8 +4,8 @@ #include "chrome/browser/ui/ash/ash_test_util.h" -#include "ash/public/cpp/window_properties.h" #include "base/run_loop.h" +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/base/window_state_type.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/window.h" @@ -30,14 +30,14 @@ void OnWindowPropertyChanged(aura::Window* window, const void* key, intptr_t old) override { - if (key == ash::kWindowStateTypeKey && IsSnapped()) + if (key == chromeos::kWindowStateTypeKey && IsSnapped()) run_loop_.Quit(); } void Wait() { run_loop_.Run(); } bool IsSnapped() const { - return window_->GetProperty(ash::kWindowStateTypeKey) == type_; + return window_->GetProperty(chromeos::kWindowStateTypeKey) == type_; } private:
diff --git a/chrome/browser/ui/ash/chrome_new_window_client.cc b/chrome/browser/ui/ash/chrome_new_window_client.cc index 6fbc768..60de8eb 100644 --- a/chrome/browser/ui/ash/chrome_new_window_client.cc +++ b/chrome/browser/ui/ash/chrome_new_window_client.cc
@@ -122,7 +122,7 @@ {ChromePage::HELP, chromeos::settings::mojom::kAboutChromeOsSectionPath}, {ChromePage::INTERNET, chromeos::settings::mojom::kNetworkSectionPath}, {ChromePage::KERBEROSACCOUNTS, - chromeos::settings::mojom::kKerberosSubpagePath}, + chromeos::settings::mojom::kKerberosAccountsSubpagePath}, {ChromePage::KEYBOARDOVERLAY, chromeos::settings::mojom::kKeyboardSubpagePath}, {ChromePage::KNOWNNETWORKS,
diff --git a/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc b/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc index d5914ba2..ed69316 100644 --- a/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc +++ b/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc
@@ -383,7 +383,8 @@ base_url.Resolve(chromeos::settings::mojom::kNetworkSectionPath)); TestOpenChromePage( ChromePage::KERBEROSACCOUNTS, - base_url.Resolve(chromeos::settings::mojom::kKerberosSubpagePath)); + base_url.Resolve( + chromeos::settings::mojom::kKerberosAccountsSubpagePath)); TestOpenChromePage( ChromePage::KNOWNNETWORKS, base_url.Resolve(chromeos::settings::mojom::kKnownNetworksSubpagePath));
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.cc b/chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.cc index 0c1d02c9..c9c2f6a3 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.cc
@@ -91,7 +91,10 @@ void HoldingSpaceDownloadsDelegate::OnDownloadCreated( content::DownloadManager* manager, download::DownloadItem* item) { - download_item_observer_.Add(item); + // Ignore `OnDownloadCreated()` events prior to `manager` initialization. For + // those events we bind any observers necessary in `OnManagerInitialized()`. + if (!is_restoring_persistence() && manager->IsManagerInitialized()) + download_item_observer_.Add(item); } void HoldingSpaceDownloadsDelegate::OnDownloadUpdated(
diff --git a/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_item_controller.cc b/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_item_controller.cc index c8c9f314..509c3e7 100644 --- a/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_item_controller.cc +++ b/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_item_controller.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_item_controller.h" -#include "ash/public/cpp/window_properties.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/chromeos/arc/pip/arc_pip_bridge.h" @@ -12,6 +11,7 @@ #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/base/window_state_type.h" #include "components/favicon/content/content_favicon_driver.h" #include "components/services/app_service/public/mojom/types.mojom.h" @@ -45,7 +45,7 @@ // showing the menu on the shelf icon. for (ui::BaseWindow* window : windows()) { aura::Window* native_window = window->GetNativeWindow(); - if (native_window->GetProperty(ash::kWindowStateTypeKey) == + if (native_window->GetProperty(chromeos::kWindowStateTypeKey) == chromeos::WindowStateType::kPip) { Profile* profile = ChromeLauncherController::instance()->profile(); arc::ArcPipBridge* pip_bridge =
diff --git a/chrome/browser/ui/views/frame/browser_frame_header_ash.cc b/chrome/browser/ui/views/frame/browser_frame_header_ash.cc index 90f0bdc0..8ee5569a 100644 --- a/chrome/browser/ui/views/frame/browser_frame_header_ash.cc +++ b/chrome/browser/ui/views/frame/browser_frame_header_ash.cc
@@ -8,9 +8,9 @@ #include "ash/public/cpp/caption_buttons/frame_caption_button_container_view.h" #include "ash/public/cpp/frame_utils.h" #include "ash/public/cpp/tablet_mode.h" -#include "ash/public/cpp/window_properties.h" #include "base/check.h" #include "chrome/app/vector_icons/vector_icons.h" +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/base/window_state_type.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" @@ -177,7 +177,8 @@ appearance_provider_->GetFrameHeaderOverlayImage(active); chromeos::WindowStateType state_type = - target_widget()->GetNativeWindow()->GetProperty(ash::kWindowStateTypeKey); + target_widget()->GetNativeWindow()->GetProperty( + chromeos::kWindowStateTypeKey); int corner_radius = chromeos::IsNormalWindowStateType(state_type) ? ash::kTopCornerRadiusWhenRestored : 0;
diff --git a/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc b/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc index 9b14c58..7cf7213 100644 --- a/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc +++ b/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc
@@ -33,6 +33,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/ui/ui_features.h" +#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" #include "chrome/browser/ui/views/chrome_view_class_properties.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" @@ -804,8 +805,27 @@ TabStripUILayout WebUITabStripContainerView::GetLayout() { DCHECK(tab_contents_container_); - return TabStripUILayout::CalculateForWebViewportSize( - tab_contents_container_->size()); + + gfx::Size tab_contents_size = tab_contents_container_->size(); + + // Because some pages can display the bookmark bar even when the bookmark bar + // is disabled (e.g. NTP) and some pages never display the bookmark bar (e.g. + // crashed tab pages, pages in guest browser windows), we will always reserve + // room for the bookmarks bar so that the size and shape of the effective + // viewport doesn't change. + // + // This may cause the thumbnail to crop off the extreme right and left edge of + // the image in some cases, but a very slight crop is preferable to constantly + // changing thumbnail sizes. + // + // See: crbug.com/1066652 for more info + const int max_bookmark_height = GetLayoutConstant(BOOKMARK_BAR_HEIGHT); + const views::View* bookmarks = browser_view_->bookmark_bar(); + const int bookmark_bar_height = + (bookmarks && bookmarks->GetVisible()) ? bookmarks->height() : 0; + tab_contents_size.Enlarge(0, -(max_bookmark_height - bookmark_bar_height)); + + return TabStripUILayout::CalculateForWebViewportSize(tab_contents_size); } SkColor WebUITabStripContainerView::GetColor(int id) const {
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index 6cb317f..51d32b6 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -101,7 +101,7 @@ DCHECK(context); chromeos::WindowStateType type = GetWindowForTabDraggingProperties(context)->GetProperty( - ash::kWindowStateTypeKey); + chromeos::kWindowStateTypeKey); return type == chromeos::WindowStateType::kLeftSnapped || type == chromeos::WindowStateType::kRightSnapped; }
diff --git a/chrome/browser/ui/webui/nearby_share/nearby_share.mojom b/chrome/browser/ui/webui/nearby_share/nearby_share.mojom index 895425b..b97ed422 100644 --- a/chrome/browser/ui/webui/nearby_share/nearby_share.mojom +++ b/chrome/browser/ui/webui/nearby_share/nearby_share.mojom
@@ -40,17 +40,55 @@ OnShareTargetLost(ShareTarget share_target); }; -// Status of the current transfer. +// Status of the current transfer. This mirrors the Status enum at +// chrome/browser/nearby_sharing/transfer_metadata.h, but drops the unused +// statuses kMediaDownloading and kExternalProviderLaunched. enum TransferStatus { + kUnknown, + // A remote device is connecting. + kConnecting, // The user of the local device needs to accept or reject the transfer. This // involves showing a token on both devices to be compared by the user. kAwaitingLocalConfirmation, // The remote device needs to accept the transfer. We still need to show the // token on this device so the other user can compare it. kAwaitingRemoteAcceptance, + // The connection was lost before the remote accepted/rejected. + kAwaitingRemoteAcceptanceFailed, // The current transfer is now in progress after both users accepted the // transfer on their devices. kInProgress, + // The current transfer is complete and successful. + kComplete, + // The current transfer failed. + kFailed, + // The remote device rejected the transfer. + kRejected, + // The remote device cancelled the transfer. + kCancelled, + // The connection to a remote device timed out. + kTimedOut, + // The attachment could not be found, or the payload could not be created. + kMediaUnavailable, + // Not enough disk space to store the payload. + kNotEnoughSpace, + // The file type is not supported for sharing. + kUnsupportedAttachmentType, +}; + +// Metadata associated with the current transfer. +struct TransferMetadata { + // Status of the current transfer. + TransferStatus status; + // Represents transfer progress as a percentage. + float progress; + // Represents the UKey2 token from Nearby Connections. Null if no + // UKey2 comparison is needed for this transfer. + string? token; + // Indicates whether this metadata has been seen before. + bool is_original; + // Indicates whether this is the last status for this transfer. + bool is_final_status; }; // Interface to be notified about transfer updates. Includes an optional token @@ -141,11 +179,8 @@ // changed and the new value is provided. OnHighVisibilityChanged(bool in_high_visibility); - // Called when a share request has arrived and the user must be asked to - // accept or reject the call. This will only trigger when the receive manager - // is in high visibility, otherwise the notification manager (background - // receive surface) will handle the events. - OnIncomingShare(ShareTarget share_target, string? connection_token); + // Called when the status of the current transfer changes. + OnTransferUpdate(ShareTarget share_target, TransferMetadata metadata); }; // Allows the caller to observe changes to or query high visibility, or
diff --git a/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom b/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom index 2d64d88..fda6238 100644 --- a/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom +++ b/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom
@@ -59,7 +59,7 @@ kSecurityAndSignIn = 304, kFingerprint = 305, kManageOtherPeople = 306, - kKerberos = 307, + kKerberosAccounts = 307, // Device section. kPointers = 400, @@ -162,7 +162,7 @@ const string kSecurityAndSignInSubpagePath = "lockScreen"; const string kFingerprintSubpagePath = "lockScreen/fingerprint"; const string kManageOtherPeopleSubpagePath = "accounts"; -const string kKerberosSubpagePath = "kerberosAccounts"; +const string kKerberosAccountsSubpagePath = "kerberosAccounts"; // Device section. const string kDeviceSectionPath = "device";
diff --git a/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc b/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc index dc36534..e2d65d3 100644 --- a/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc +++ b/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc
@@ -46,7 +46,7 @@ chromeos::settings::mojom::kSecurityAndSignInSubpagePath, chromeos::settings::mojom::kFingerprintSubpagePath, chromeos::settings::mojom::kManageOtherPeopleSubpagePath, - chromeos::settings::mojom::kKerberosSubpagePath, + chromeos::settings::mojom::kKerberosAccountsSubpagePath, // Device section. chromeos::settings::mojom::kDeviceSectionPath,
diff --git a/chrome/browser/ui/webui/settings/chromeos/people_section.cc b/chrome/browser/ui/webui/settings/chromeos/people_section.cc index f2f4bd2..74bf141 100644 --- a/chrome/browser/ui/webui/settings/chromeos/people_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/people_section.cc
@@ -7,6 +7,7 @@ #include "ash/public/cpp/ash_features.h" #include "base/bind.h" #include "base/i18n/number_formatting.h" +#include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" @@ -235,25 +236,25 @@ const std::vector<SearchConcept>& GetKerberosSearchConcepts() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ {IDS_OS_SETTINGS_TAG_KERBEROS_ADD, - mojom::kKerberosSubpagePath, + mojom::kKerberosAccountsSubpagePath, mojom::SearchResultIcon::kAvatar, mojom::SearchResultDefaultRank::kMedium, mojom::SearchResultType::kSetting, {.setting = mojom::Setting::kAddKerberosTicket}}, {IDS_OS_SETTINGS_TAG_KERBEROS_REMOVE, - mojom::kKerberosSubpagePath, + mojom::kKerberosAccountsSubpagePath, mojom::SearchResultIcon::kAvatar, mojom::SearchResultDefaultRank::kMedium, mojom::SearchResultType::kSetting, {.setting = mojom::Setting::kRemoveKerberosTicket}}, {IDS_OS_SETTINGS_TAG_KERBEROS, - mojom::kKerberosSubpagePath, + mojom::kKerberosAccountsSubpagePath, mojom::SearchResultIcon::kAvatar, mojom::SearchResultDefaultRank::kMedium, mojom::SearchResultType::kSubpage, - {.subpage = mojom::Subpage::kKerberos}}, + {.subpage = mojom::Subpage::kKerberosAccounts}}, {IDS_OS_SETTINGS_TAG_KERBEROS_ACTIVE, - mojom::kKerberosSubpagePath, + mojom::kKerberosAccountsSubpagePath, mojom::SearchResultIcon::kAvatar, mojom::SearchResultDefaultRank::kMedium, mojom::SearchResultType::kSetting, @@ -920,8 +921,15 @@ bool PeopleSection::LogMetric(mojom::Setting setting, base::Value& value) const { - // Unimplemented. - return false; + switch (setting) { + case mojom::Setting::kAddAccount: + base::UmaHistogramCounts1000("ChromeOS.Settings.People.AddAccountCount", + value.GetInt()); + return true; + + default: + return false; + } } void PeopleSection::RegisterHierarchy(HierarchyGenerator* generator) const { @@ -1010,17 +1018,18 @@ kManageOtherPeopleSettings, generator); // Kerberos. - generator->RegisterTopLevelSubpage( - IDS_SETTINGS_KERBEROS_ACCOUNTS_PAGE_TITLE, mojom::Subpage::kKerberos, - mojom::SearchResultIcon::kAvatar, mojom::SearchResultDefaultRank::kMedium, - mojom::kKerberosSubpagePath); + generator->RegisterTopLevelSubpage(IDS_SETTINGS_KERBEROS_ACCOUNTS_PAGE_TITLE, + mojom::Subpage::kKerberosAccounts, + mojom::SearchResultIcon::kAvatar, + mojom::SearchResultDefaultRank::kMedium, + mojom::kKerberosAccountsSubpagePath); static constexpr mojom::Setting kKerberosSettings[] = { mojom::Setting::kAddKerberosTicket, mojom::Setting::kRemoveKerberosTicket, mojom::Setting::kSetActiveKerberosTicket, }; - RegisterNestedSettingBulk(mojom::Subpage::kKerberos, kKerberosSettings, - generator); + RegisterNestedSettingBulk(mojom::Subpage::kKerberosAccounts, + kKerberosSettings, generator); } void PeopleSection::FetchAccounts() {
diff --git a/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker.h b/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker.h index bf0fcf6..6d5e320e 100644 --- a/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker.h +++ b/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker.h
@@ -39,7 +39,9 @@ // SettingsUserActionTracker(); friend class SettingsUserActionTrackerTest; FRIEND_TEST_ALL_PREFIXES(SettingsUserActionTrackerTest, - TestRecordSettingChanged); + TestRecordSettingChangedBool); + FRIEND_TEST_ALL_PREFIXES(SettingsUserActionTrackerTest, + TestRecordSettingChangedInt); // mojom::UserActionRecorder: void RecordPageFocus() override;
diff --git a/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker_unittest.cc index de415ce..d545b37f 100644 --- a/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker_unittest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker_unittest.cc
@@ -33,6 +33,8 @@ void SetUp() override { fake_hierarchy_.AddSettingMetadata(mojom::Section::kBluetooth, mojom::Setting::kBluetoothOnOff); + fake_hierarchy_.AddSettingMetadata(mojom::Section::kPeople, + mojom::Setting::kAddAccount); } base::HistogramTester histogram_tester_; @@ -41,7 +43,7 @@ SettingsUserActionTracker tracker_; }; -TEST_F(SettingsUserActionTrackerTest, TestRecordSettingChanged) { +TEST_F(SettingsUserActionTrackerTest, TestRecordSettingChangedBool) { // Record that the bluetooth enabled setting was toggled off. tracker_.RecordSettingChangeWithDetails( mojom::Setting::kBluetoothOnOff, @@ -63,5 +65,26 @@ mojom::Setting::kBluetoothOnOff); } +TEST_F(SettingsUserActionTrackerTest, TestRecordSettingChangedInt) { + // Record that the user tried to add a 3rd account. + tracker_.RecordSettingChangeWithDetails( + mojom::Setting::kAddAccount, mojom::SettingChangeValue::NewIntValue(3)); + + // The umbrella metric for which setting was changed should be updated. Note + // that kAddAccount has enum value of 300. + histogram_tester_.ExpectTotalCount("ChromeOS.Settings.SettingChanged", + /*count=*/1); + histogram_tester_.ExpectBucketCount("ChromeOS.Settings.SettingChanged", + /*sample=*/300, + /*count=*/1); + + // The LogMetric fn in the People section should have been called. + const FakeOsSettingsSection* people_section = + static_cast<const FakeOsSettingsSection*>( + fake_sections_.GetSection(mojom::Section::kPeople)); + EXPECT_TRUE(people_section->logged_metrics().back() == + mojom::Setting::kAddAccount); +} + } // namespace settings. } // namespace chromeos.
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 22cf1ad..7b143b8 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1602266368-0e61a032fa7157fa29bc804c0d7295bad87c6193.profdata +chrome-linux-master-1602329287-d9e640c0f4fb081a95bb071b07a3e8b9abe79208.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 0cd4f90..cc69157 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1602266368-92d2928e0040ad47ba60bbcac401f36efe1994de.profdata +chrome-mac-master-1602329287-377f3782d4c02db29be26bdaf518b1d3cd99dfb6.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index c5cc205..abc7604 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1602201537-a14eb3c04e9257cb13970f54aebda7b1af96d2f4.profdata +chrome-win32-master-1602329287-4430a8255045839af70a229385d0ebd7f7aeb9aa.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 5734b6b8..6342722 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1602244639-9ed9777b412f549b6770ee430e4768c83e1e2c1e.profdata +chrome-win64-master-1602319457-99315dd935bfb1b8d29d7c96af31a8803cbd1a16.profdata
diff --git a/chrome/common/extensions/api/accessibility_private.json b/chrome/common/extensions/api/accessibility_private.json index 1ef1a1e..f1aba0f 100644 --- a/chrome/common/extensions/api/accessibility_private.json +++ b/chrome/common/extensions/api/accessibility_private.json
@@ -332,6 +332,19 @@ "platforms": ["chromeos"] }, { + "name": "enablePointScan", + "type": "function", + "description": "Enables or disables point scanning in Switch Access.", + "parameters": [ + { + "name": "enabled", + "type": "boolean", + "description": "True for start point scanning, false for end point scanning." + } + ], + "platforms": ["chromeos"] + }, + { "name": "setNativeChromeVoxArcSupportForCurrentApp", "type": "function", "description": "Sets current ARC app to use native ARC support.",
diff --git a/chrome/common/extensions/api/autotest_private.idl b/chrome/common/extensions/api/autotest_private.idl index 36a7111..4d83442 100644 --- a/chrome/common/extensions/api/autotest_private.idl +++ b/chrome/common/extensions/api/autotest_private.idl
@@ -986,6 +986,14 @@ // cannot be removed. static void removeActiveDesk(DesksCallback callback); + // Activates the desk at the given |index| by chaining multiple + // activate-desk animations. + // |index|: the zero-based index of the desk desired to be activated. + // |callback|: called indicating success when the animation completes, or + // failure when the desk at |index| is already the active desk. + static void activateAdjacentDesksToTargetIndex(long index, + DesksCallback callback); + // Create mouse events to cause a mouse click. // |button|: the mouse button for the click event. // |callback|: called after the mouse click finishes.
diff --git a/chrome/test/data/webui/settings/chromeos/fake_receive_manager.js b/chrome/test/data/webui/settings/chromeos/fake_receive_manager.js index 47ad209..6a9e4a62 100644 --- a/chrome/test/data/webui/settings/chromeos/fake_receive_manager.js +++ b/chrome/test/data/webui/settings/chromeos/fake_receive_manager.js
@@ -40,7 +40,14 @@ simulateShareTargetArrival(name, connectionToken) { const target = {id: {low: 1, high: 2}, name: name, type: 1}; - this.observer_.onIncomingShare(target, connectionToken); + const metadata = { + 'status': nearbyShare.mojom.TransferStatus.kAwaitingLocalConfirmation, + progress: 0.0, + token: connectionToken, + is_original: true, + is_final_status: false + }; + this.observer_.onTransferUpdate(target, metadata); return target; }
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 a35a7b88..e1b891ba 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
@@ -128,7 +128,7 @@ }); test( - 'unregister surface, onIncomingShare, does not close dialog', + 'unregister surface, OnTransferUpdate, does not close dialog', async function() { // When attached we enter high visibility mode by default assertTrue(isVisible('nearby-share-high-visibility-page'));
diff --git a/chrome/tools/build/linux/FILES.cfg b/chrome/tools/build/linux/FILES.cfg index 54b6b6a..204419e1 100644 --- a/chrome/tools/build/linux/FILES.cfg +++ b/chrome/tools/build/linux/FILES.cfg
@@ -154,20 +154,6 @@ 'buildtype': ['official'], 'archive': 'remoting-me2me-host-linux.zip', }, - # Remoting symbols: - { - 'filename': 'remote_assistance_host.debug', - 'arch': ['64bit'], - 'buildtype': ['dev', 'official'], - 'archive': 'remoting-debug-info.zip', - }, - { - # Include all debug symbols that start with `remoting`. - 'filename': 'remoting*.debug', - 'arch': ['64bit'], - 'buildtype': ['dev', 'official'], - 'archive': 'remoting-debug-info.zip', - }, # Breakpad symbols: { 'filename': 'chrome.breakpad.x64',
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index 2d52f83c..7ca713c 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -37,6 +37,7 @@ #include "chromecast/browser/cast_browser_context.h" #include "chromecast/browser/cast_browser_process.h" #include "chromecast/browser/cast_content_browser_client.h" +#include "chromecast/browser/cast_extension_url_loader_factory.h" #include "chromecast/browser/cast_feature_list_creator.h" #include "chromecast/browser/cast_system_memory_pressure_evaluator.h" #include "chromecast/browser/cast_system_memory_pressure_evaluator_adjuster.h" @@ -384,6 +385,7 @@ extensions::EnsureBrowserContextKeyedServiceFactoriesBuilt(); extensions::CastExtensionSystemFactory::GetInstance(); + CastExtensionURLLoaderFactory::EnsureShutdownNotifierFactoryBuilt(); } #endif
diff --git a/chromecast/browser/cast_extension_url_loader_factory.cc b/chromecast/browser/cast_extension_url_loader_factory.cc index 71b8353..0fdd582 100644 --- a/chromecast/browser/cast_extension_url_loader_factory.cc +++ b/chromecast/browser/cast_extension_url_loader_factory.cc
@@ -10,11 +10,13 @@ #include <vector> #include "base/strings/strcat.h" +#include "chromecast/browser/extensions/cast_extension_system_factory.h" #include "chromecast/common/cast_redirect_manifest_handler.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" #include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_registry_factory.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/network/public/mojom/url_loader.mojom.h" @@ -181,6 +183,16 @@ content::BrowserContext::GetDefaultStoragePartition(browser_context) ->GetURLLoaderFactoryForBrowserProcess()) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + // base::Unretained is safe below, because lifetime of + // |browser_context_shutdown_subscription_| guarantees that + // OnBrowserContextDestroyed won't be called after |this| is destroyed. + browser_context_shutdown_subscription_ = + BrowserContextShutdownNotifierFactory::GetInstance() + ->Get(browser_context) + ->Subscribe(base::BindRepeating( + &CastExtensionURLLoaderFactory::OnBrowserContextDestroyed, + base::Unretained(this))); } CastExtensionURLLoaderFactory::~CastExtensionURLLoaderFactory() = default; @@ -234,13 +246,43 @@ network_factory_); } +void CastExtensionURLLoaderFactory::OnBrowserContextDestroyed() { + // When the BrowserContext gets destroyed, |this| factory is not able to serve + // any more requests. + DisconnectReceiversAndDestroy(); +} + +// static +CastExtensionURLLoaderFactory::BrowserContextShutdownNotifierFactory* +CastExtensionURLLoaderFactory::BrowserContextShutdownNotifierFactory:: + GetInstance() { + static base::NoDestructor<BrowserContextShutdownNotifierFactory> s_factory; + return s_factory.get(); +} + +CastExtensionURLLoaderFactory::BrowserContextShutdownNotifierFactory:: + BrowserContextShutdownNotifierFactory() + : BrowserContextKeyedServiceShutdownNotifierFactory( + "CastExtensionURLLoaderFactory::" + "BrowserContextShutdownNotifierFactory") { + DependsOn(extensions::ExtensionRegistryFactory::GetInstance()); + DependsOn(extensions::CastExtensionSystemFactory::GetInstance()); +} + // static mojo::PendingRemote<network::mojom::URLLoaderFactory> CastExtensionURLLoaderFactory::Create( content::BrowserContext* browser_context, mojo::PendingRemote<network::mojom::URLLoaderFactory> extension_factory) { + DCHECK(browser_context); + mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_remote; + // Return an unbound |pending_remote| if the |browser_context| has already + // started shutting down. + if (browser_context->ShutdownStarted()) + return pending_remote; + // The CastExtensionURLLoaderFactory will delete itself when there are no more // receivers - see the NonNetworkURLLoaderFactoryBase::OnDisconnect method. new CastExtensionURLLoaderFactory( @@ -250,5 +292,10 @@ return pending_remote; } +// static +void CastExtensionURLLoaderFactory::EnsureShutdownNotifierFactoryBuilt() { + BrowserContextShutdownNotifierFactory::GetInstance(); +} + } // namespace shell } // namespace chromecast
diff --git a/chromecast/browser/cast_extension_url_loader_factory.h b/chromecast/browser/cast_extension_url_loader_factory.h index b3c1c0c..f39c9ef 100644 --- a/chromecast/browser/cast_extension_url_loader_factory.h +++ b/chromecast/browser/cast_extension_url_loader_factory.h
@@ -5,7 +5,12 @@ #ifndef CHROMECAST_BROWSER_CAST_EXTENSION_URL_LOADER_FACTORY_H_ #define CHROMECAST_BROWSER_CAST_EXTENSION_URL_LOADER_FACTORY_H_ +#include <memory> + #include "base/macros.h" +#include "base/no_destructor.h" +#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h" +#include "components/keyed_service/core/keyed_service_shutdown_notifier.h" #include "content/public/browser/non_network_url_loader_factory_base.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -44,6 +49,8 @@ content::BrowserContext* browser_context, mojo::PendingRemote<network::mojom::URLLoaderFactory> extension_factory); + static void EnsureShutdownNotifierFactoryBuilt(); + private: ~CastExtensionURLLoaderFactory() override; @@ -65,10 +72,31 @@ const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) override; + void OnBrowserContextDestroyed(); + + class BrowserContextShutdownNotifierFactory + : public BrowserContextKeyedServiceShutdownNotifierFactory { + public: + static BrowserContextShutdownNotifierFactory* GetInstance(); + + // No copying. + BrowserContextShutdownNotifierFactory( + const BrowserContextShutdownNotifierFactory&) = delete; + BrowserContextShutdownNotifierFactory& operator=( + const BrowserContextShutdownNotifierFactory&) = delete; + + private: + friend class base::NoDestructor<BrowserContextShutdownNotifierFactory>; + BrowserContextShutdownNotifierFactory(); + }; + extensions::ExtensionRegistry* extension_registry_; mojo::Remote<network::mojom::URLLoaderFactory> extension_factory_; scoped_refptr<network::SharedURLLoaderFactory> network_factory_; + std::unique_ptr<KeyedServiceShutdownNotifier::Subscription> + browser_context_shutdown_subscription_; + DISALLOW_COPY_AND_ASSIGN(CastExtensionURLLoaderFactory); };
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 5544157..696f4d3 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -13520.0.0 \ No newline at end of file +13522.0.0 \ No newline at end of file
diff --git a/chromeos/profiles/orderfile.newest.txt b/chromeos/profiles/orderfile.newest.txt index 6c5d733..20f5bed 100644 --- a/chromeos/profiles/orderfile.newest.txt +++ b/chromeos/profiles/orderfile.newest.txt
@@ -1 +1 @@ -chromeos-chrome-orderfile-field-87-4265.0-1601890590-benchmark-87.0.4280.9-r1.orderfile.xz +chromeos-chrome-orderfile-field-87-4265.0-1601890590-benchmark-87.0.4280.15-r1.orderfile.xz
diff --git a/chromeos/ui/base/window_properties.cc b/chromeos/ui/base/window_properties.cc index 1fd45e46..57b76565 100644 --- a/chromeos/ui/base/window_properties.cc +++ b/chromeos/ui/base/window_properties.cc
@@ -4,10 +4,14 @@ #include "chromeos/ui/base/window_properties.h" +#include "chromeos/ui/base/window_state_type.h" #include "ui/aura/window.h" namespace chromeos { DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIsShowingInOverviewKey, false) +DEFINE_UI_CLASS_PROPERTY_KEY(WindowStateType, + kWindowStateTypeKey, + WindowStateType::kDefault) } // namespace chromeos
diff --git a/chromeos/ui/base/window_properties.h b/chromeos/ui/base/window_properties.h index 9b12271..aab2a63 100644 --- a/chromeos/ui/base/window_properties.h +++ b/chromeos/ui/base/window_properties.h
@@ -15,6 +15,8 @@ namespace chromeos { +enum class WindowStateType; + // Shell-specific window property keys for use by ash and lacros clients. // Alphabetical sort. @@ -23,6 +25,10 @@ COMPONENT_EXPORT(CHROMEOS_UI_BASE) extern const aura::WindowProperty<bool>* const kIsShowingInOverviewKey; +// A property key to indicate ash's extended window state. +COMPONENT_EXPORT(CHROMEOS_UI_BASE) +extern const aura::WindowProperty<WindowStateType>* const kWindowStateTypeKey; + // Alphabetical sort. } // namespace chromeos
diff --git a/components/heap_profiling/multi_process/test_driver.cc b/components/heap_profiling/multi_process/test_driver.cc index cf61046..fb67ecb 100644 --- a/components/heap_profiling/multi_process/test_driver.cc +++ b/components/heap_profiling/multi_process/test_driver.cc
@@ -17,6 +17,7 @@ #include "base/stl_util.h" #include "base/test/bind_test_util.h" #include "base/threading/platform_thread.h" +#include "base/trace_event/heap_profiler.h" #include "base/trace_event/heap_profiler_event_filter.h" #include "base/values.h" #include "build/build_config.h"
diff --git a/components/messages/android/BUILD.gn b/components/messages/android/BUILD.gn index da349bd..e51ca03 100644 --- a/components/messages/android/BUILD.gn +++ b/components/messages/android/BUILD.gn
@@ -11,7 +11,8 @@ "java/src/org/chromium/components/messages/MessageBannerView.java", "java/src/org/chromium/components/messages/MessageBannerViewBinder.java", "java/src/org/chromium/components/messages/MessageContainer.java", - "java/src/org/chromium/components/messages/MessageQueueManager.java", + "java/src/org/chromium/components/messages/MessageDispatcher.java", + "java/src/org/chromium/components/messages/MessageDispatcherProvider.java", "java/src/org/chromium/components/messages/MessageStateHandler.java", "java/src/org/chromium/components/messages/SingleActionMessage.java", ] @@ -38,6 +39,15 @@ ] } +# Build target for Messages manager code, that owns and initializes +# MessageDispatcher. +android_library("manager_java") { + sources = [ + "java/src/org/chromium/components/messages/ManagedMessageDispatcher.java", + ] + deps = [ ":java" ] +} + static_library("feature_flags") { sources = [ "messages_feature.cc", @@ -79,6 +89,7 @@ deps = [ ":java", + ":manager_java", "//ui/android:ui_full_java", ] }
diff --git a/components/messages/android/internal/BUILD.gn b/components/messages/android/internal/BUILD.gn index e31cdf6..3eac12b 100644 --- a/components/messages/android/internal/BUILD.gn +++ b/components/messages/android/internal/BUILD.gn
@@ -6,12 +6,14 @@ android_library("java") { sources = [ - "java/src/org/chromium/components/messages/MessageQueueManagerImpl.java", + "java/src/org/chromium/components/messages/MessageDispatcherImpl.java", + "java/src/org/chromium/components/messages/MessageQueueManager.java", "java/src/org/chromium/components/messages/MessagesFactory.java", ] deps = [ "..:java", + "..:manager_java", "//base:base_java", "//third_party/android_deps:androidx_annotation_annotation_java", "//ui/android:ui_full_java", @@ -22,7 +24,9 @@ # Skip platform checks since Robolectric depends on requires_android targets. bypass_platform_checks = true testonly = true - sources = [ "java/src/org/chromium/components/messages/MessageQueueManagerImplTest.java" ] + sources = [ + "java/src/org/chromium/components/messages/MessageQueueManagerTest.java", + ] deps = [ ":java", "..:java",
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageDispatcherImpl.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageDispatcherImpl.java new file mode 100644 index 0000000..8b0029d --- /dev/null +++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageDispatcherImpl.java
@@ -0,0 +1,36 @@ +// 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.components.messages; + +import org.chromium.ui.modelutil.PropertyModel; + +/** + * This class implements public MessageDispatcher interface, delegating the actual work to + * MessageQueueManager. + */ +public class MessageDispatcherImpl implements ManagedMessageDispatcher { + private final MessageQueueManager mMessageQueueManager = new MessageQueueManager(); + private final MessageContainer mMessageContainer; + + /** + * Build a new message dispatcher + * @param messageContainer A container view for displaying message banners. + */ + public MessageDispatcherImpl(MessageContainer messageContainer) { + mMessageContainer = messageContainer; + } + + @Override + public void enqueueMessage(PropertyModel messageProperties) { + MessageStateHandler messageStateHandler = + new SingleActionMessage(mMessageContainer, messageProperties); + mMessageQueueManager.enqueueMessage(messageStateHandler, messageProperties); + } + + @Override + public void dismissMessage(PropertyModel messageProperties) { + mMessageQueueManager.dismissMessage(messageProperties); + } +}
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerImpl.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManager.java similarity index 64% rename from components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerImpl.java rename to components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManager.java index 4a04b47..d3aae5c 100644 --- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerImpl.java +++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManager.java
@@ -6,10 +6,6 @@ import androidx.annotation.Nullable; -import org.chromium.base.UnownedUserData; -import org.chromium.base.UnownedUserDataKey; -import org.chromium.ui.base.WindowAndroid; - import java.util.ArrayDeque; import java.util.HashMap; import java.util.Map; @@ -19,42 +15,13 @@ * A class managing the queue of messages. Its primary role is to decide when to show/hide current * message and which message to show next. */ -class MessageQueueManagerImpl implements MessageQueueManager, UnownedUserData { - private static final UnownedUserDataKey<MessageQueueManagerImpl> KEY = - new UnownedUserDataKey<>(MessageQueueManagerImpl.class); - +class MessageQueueManager { private final Queue<MessageStateHandler> mMessageQueue = new ArrayDeque<>(); private final Map<Object, MessageStateHandler> mMessageMap = new HashMap<>(); @Nullable private MessageStateHandler mCurrentDisplayedMessage; - /** - * Get the activity's MessageQueueManager from the provided WindowAndroid. - * @param window The window to get the manager from. - * @return The activity's MessageQueueManager. - */ - public static MessageQueueManagerImpl from(WindowAndroid window) { - return KEY.retrieveDataFromHost(window.getUnownedUserDataHost()); - } - - public MessageQueueManagerImpl() {} - - /** - * Attaches MessageQueueManager to a given window. This window will be used later to retrieve - * activity's MessageQueueManager. - * @param window The window to attach to. - */ - public void attachToWindowAndroid(WindowAndroid window) { - KEY.attachToHost(window.getUnownedUserDataHost(), this); - } - - /** - * Destroys MessageQueueManager, detaching it from the WindowAndroid it was attached to. - */ - @Override - public void destroy() { - KEY.detachFromAllHosts(this); - } + public MessageQueueManager() {} /** * Enqueues a message. Associates the message with its key; the key is used later to dismiss the
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerImplTest.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerTest.java similarity index 87% rename from components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerImplTest.java rename to components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerTest.java index 928d08f..f45d7c6 100644 --- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerImplTest.java +++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerTest.java
@@ -17,10 +17,10 @@ import org.chromium.base.test.BaseRobolectricTestRunner; /** - * Unit tests for MessageQueueManagerImpl. + * Unit tests for MessageQueueManager. */ @RunWith(BaseRobolectricTestRunner.class) -public class MessageQueueManagerImplTest { +public class MessageQueueManagerTest { /** * Tests lifecycle of a single message: * - enqueueMessage() calls show() @@ -29,7 +29,7 @@ @Test @SmallTest public void testEnqueueMessage() { - MessageQueueManagerImpl queueManager = new MessageQueueManagerImpl(); + MessageQueueManager queueManager = new MessageQueueManager(); MessageStateHandler m1 = Mockito.mock(MessageStateHandler.class); MessageStateHandler m2 = Mockito.mock(MessageStateHandler.class); @@ -52,7 +52,7 @@ @Test @SmallTest public void testOneMessageShownAtATime() { - MessageQueueManagerImpl queueManager = new MessageQueueManagerImpl(); + MessageQueueManager queueManager = new MessageQueueManager(); MessageStateHandler m1 = Mockito.mock(MessageStateHandler.class); MessageStateHandler m2 = Mockito.mock(MessageStateHandler.class); @@ -74,7 +74,7 @@ @Test @SmallTest public void testDismissBeforeShow() { - MessageQueueManagerImpl queueManager = new MessageQueueManagerImpl(); + MessageQueueManager queueManager = new MessageQueueManager(); MessageStateHandler m1 = Mockito.mock(MessageStateHandler.class); MessageStateHandler m2 = Mockito.mock(MessageStateHandler.class); @@ -98,7 +98,7 @@ @Test(expected = IllegalStateException.class) @SmallTest public void testEnqueueDuplicateKey() { - MessageQueueManagerImpl queueManager = new MessageQueueManagerImpl(); + MessageQueueManager queueManager = new MessageQueueManager(); MessageStateHandler m1 = Mockito.mock(MessageStateHandler.class); MessageStateHandler m2 = Mockito.mock(MessageStateHandler.class); Object key = new Object(); @@ -113,7 +113,7 @@ @Test @SmallTest public void testDismissMessageTwice() { - MessageQueueManagerImpl queueManager = new MessageQueueManagerImpl(); + MessageQueueManager queueManager = new MessageQueueManager(); MessageStateHandler m1 = Mockito.mock(MessageStateHandler.class); queueManager.enqueueMessage(m1, m1); queueManager.dismissMessage(m1);
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessagesFactory.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessagesFactory.java index 176cdc00..4a1c5845 100644 --- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessagesFactory.java +++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessagesFactory.java
@@ -9,13 +9,29 @@ /** A factory for constructing different Messages related objects. */ public class MessagesFactory { /** - * Creates an instance of MessageQueueManager and attaches it to WindowAndroid. - * @param windowAndroid The WindowAndroid to attach MessageQueueManager to. - * @return The constructed MessageQueueManager. + * Creates an instance of ManagedMessageDispatcher. + * @return The constructed ManagedMessageDispatcher. */ - public static MessageQueueManager createMessageQueueManager(WindowAndroid windowAndroid) { - MessageQueueManagerImpl messageQueueManager = new MessageQueueManagerImpl(); - messageQueueManager.attachToWindowAndroid(windowAndroid); - return messageQueueManager; + public static ManagedMessageDispatcher createMessageDispatcher(MessageContainer container) { + return new MessageDispatcherImpl(container); } -} \ No newline at end of file + + /** + * Attaches MessageDispatcher as UnownedUserData to WindowAndroid making it accessible to + * components outside of chrome/android. + * @param windowAndroid The WindowAndroid to attach ManagedMessageDispatcher to. + * @param messageDispatcher The MessageDispatcher to attach. + */ + public static void attachMessageDispatcher( + WindowAndroid windowAndroid, ManagedMessageDispatcher messageDispatcher) { + MessageDispatcherProvider.attach(windowAndroid, messageDispatcher); + } + + /** + * Detaches MessageDispatcher from WindowAndroid. + * @param messageDispatcher The MessageDispatcher to detach from WindowAndroid. + */ + public static void detachMessageDispatcher(ManagedMessageDispatcher messageDispatcher) { + MessageDispatcherProvider.detach(messageDispatcher); + } +}
diff --git a/components/messages/android/java/src/org/chromium/components/messages/ManagedMessageDispatcher.java b/components/messages/android/java/src/org/chromium/components/messages/ManagedMessageDispatcher.java new file mode 100644 index 0000000..7718970 --- /dev/null +++ b/components/messages/android/java/src/org/chromium/components/messages/ManagedMessageDispatcher.java
@@ -0,0 +1,11 @@ +// 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.components.messages; + +/** + * An interface for the MessageDispatcher owning object. + */ +public interface ManagedMessageDispatcher + extends MessageDispatcher, MessageDispatcherProvider.Unowned {}
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageDispatcher.java b/components/messages/android/java/src/org/chromium/components/messages/MessageDispatcher.java new file mode 100644 index 0000000..bbadd2d --- /dev/null +++ b/components/messages/android/java/src/org/chromium/components/messages/MessageDispatcher.java
@@ -0,0 +1,26 @@ +// 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.components.messages; + +import org.chromium.ui.modelutil.PropertyModel; + +/** + * The public interface for Messages. To interact with messages, feature should obtain a reference + * to MessageDispatcher through MessageDispatcherProvider and call methods of MessageDispatcher. + */ +public interface MessageDispatcher { + /** + * Enqueues a message defined by its properties. + * @param messageProperties The PropertyModel with message's visual properties. + */ + void enqueueMessage(PropertyModel messageProperties); + + /** + * Dismisses a message referenced by its PropertyModel. Hdes the message if it is currently + * displayed. Displays the next message in the queue if available. + * @param messageProperties The PropertyModel of the messageto be dismissed. + */ + void dismissMessage(PropertyModel messageProperties); +}
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageDispatcherProvider.java b/components/messages/android/java/src/org/chromium/components/messages/MessageDispatcherProvider.java new file mode 100644 index 0000000..906dff5f --- /dev/null +++ b/components/messages/android/java/src/org/chromium/components/messages/MessageDispatcherProvider.java
@@ -0,0 +1,38 @@ +// 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.components.messages; + +import org.chromium.base.UnownedUserData; +import org.chromium.base.UnownedUserDataKey; +import org.chromium.ui.base.WindowAndroid; + +/** + * The class that handles association of MessageDispatcher with WindowAndroid and retrieval of the + * associated MessageDispatcher. + */ +public class MessageDispatcherProvider { + /** An interface that allows a MessageDispatcher to be associated with an unowned data host. */ + interface Unowned extends MessageDispatcher, UnownedUserData {} + + /** The key used to bind the MessageDispatcher to the unowned data host. */ + private static final UnownedUserDataKey<Unowned> KEY = new UnownedUserDataKey<>(Unowned.class); + + /** + * Retrieves the shared MessageDispatcher from the provided WindowAndroid. + * @param windowAndroid The window to retrieve MessageDispatcher from. + * @return An instance of MessageDispatcher associated with the window. + */ + public static MessageDispatcher from(WindowAndroid windowAndroid) { + return KEY.retrieveDataFromHost(windowAndroid.getUnownedUserDataHost()); + } + + static void attach(WindowAndroid windowAndroid, Unowned controller) { + KEY.attachToHost(windowAndroid.getUnownedUserDataHost(), controller); + } + + static void detach(Unowned controller) { + KEY.detachFromAllHosts(controller); + } +}
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageQueueManager.java b/components/messages/android/java/src/org/chromium/components/messages/MessageQueueManager.java deleted file mode 100644 index 799d9d1..0000000 --- a/components/messages/android/java/src/org/chromium/components/messages/MessageQueueManager.java +++ /dev/null
@@ -1,16 +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. - -package org.chromium.components.messages; - -/** - * The public interface for managing the queue of messages. The embedder should retain reference to - * MessageQueueManager and destroy it when the Activity gets destroyed. - */ -public interface MessageQueueManager { - /** - * Destroys MessageQueueManager, detaching it from the WindowAndroid it was attached to. - */ - void destroy(); -}
diff --git a/components/omnibox/browser/local_history_zero_suggest_provider.cc b/components/omnibox/browser/local_history_zero_suggest_provider.cc index 6cd32c8..d2117a29 100644 --- a/components/omnibox/browser/local_history_zero_suggest_provider.cc +++ b/components/omnibox/browser/local_history_zero_suggest_provider.cc
@@ -108,6 +108,12 @@ done_ = true; matches_.clear(); + if (!base::FeatureList::IsEnabled( + omnibox::kOmniboxLocalZeroSuggestForAuthenticatedUsers) && + client_->IsAuthenticated()) { + return; + } + // Allow local history query suggestions only when the user is not in an // off-the-record context. if (client_->IsOffTheRecord())
diff --git a/components/omnibox/browser/local_history_zero_suggest_provider_unittest.cc b/components/omnibox/browser/local_history_zero_suggest_provider_unittest.cc index 3b9850b..3f91155 100644 --- a/components/omnibox/browser/local_history_zero_suggest_provider_unittest.cc +++ b/components/omnibox/browser/local_history_zero_suggest_provider_unittest.cc
@@ -245,14 +245,13 @@ "Omnibox.LocalHistoryZeroSuggest.AsyncDeleteTime", 0); } -// Tests that suggestions are returned only user is not in an off-the-record -// context, regardless of the user's authentication state. +// Tests that suggestions are returned only if user is not in an off-the-record +// context. TEST_F(LocalHistoryZeroSuggestProviderTest, Incognito) { LoadURLs({ {default_search_provider(), "hello world", "&foo=bar", 1}, }); - EXPECT_CALL(*client_.get(), IsAuthenticated()).Times(0); EXPECT_CALL(*client_.get(), IsOffTheRecord()) .Times(2) .WillOnce(testing::Return(true)) @@ -265,6 +264,64 @@ ExpectMatches({{"hello world", 500}}); } +// Tests that suggestions are returned regardless of the authentication state +// when omnibox::kOmniboxLocalZeroSuggestForAuthenticatedUsers is enabled. +#if defined(OS_IOS) +// Tests that enable additional features fail on iOS. +#define MAYBE_ZeroSuggestForAuthenticatedUsers_Enabled \ + DISABLED_ZeroSuggestForAuthenticatedUsers_Enabled +#else +#define MAYBE_ZeroSuggestForAuthenticatedUsers_Enabled \ + ZeroSuggestForAuthenticatedUsers_Enabled +#endif +TEST_F(LocalHistoryZeroSuggestProviderTest, + MAYBE_ZeroSuggestForAuthenticatedUsers_Enabled) { + LoadURLs({ + {default_search_provider(), "hello world", "&foo=bar", 1}, + }); + + scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>(); + scoped_feature_list_->InitAndEnableFeature( + omnibox::kOmniboxLocalZeroSuggestForAuthenticatedUsers); + + EXPECT_CALL(*client_.get(), IsAuthenticated()).Times(0); + + StartProviderAndWaitUntilDone(); + ExpectMatches({{"hello world", 500}}); +} + +// Tests that suggestions are returned for signed-out users only when +// when omnibox::kOmniboxLocalZeroSuggestForAuthenticatedUsers is disabled. +#if defined(OS_IOS) +// Tests that enable additional features fail on iOS. +#define MAYBE_ZeroSuggestForAuthenticatedUsers_Disabled \ + DISABLED_ZeroSuggestForAuthenticatedUsers_Disabled +#else +#define MAYBE_ZeroSuggestForAuthenticatedUsers_Disabled \ + ZeroSuggestForAuthenticatedUsers_Disabled +#endif +TEST_F(LocalHistoryZeroSuggestProviderTest, + MAYBE_ZeroSuggestForAuthenticatedUsers_Disabled) { + LoadURLs({ + {default_search_provider(), "hello world", "&foo=bar", 1}, + }); + + scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>(); + scoped_feature_list_->InitAndDisableFeature( + omnibox::kOmniboxLocalZeroSuggestForAuthenticatedUsers); + + EXPECT_CALL(*client_.get(), IsAuthenticated()) + .Times(2) + .WillOnce(testing::Return(true)) + .WillOnce(testing::Return(false)); + + StartProviderAndWaitUntilDone(); + ExpectMatches({}); + + StartProviderAndWaitUntilDone(); + ExpectMatches({{"hello world", 500}}); +} + // Tests that suggestions are returned only if FeatureFlags is configured // to return local history suggestions in the NTP. #if defined(OS_IOS)
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc index ecbb75c0..df6dcd9 100644 --- a/components/omnibox/common/omnibox_features.cc +++ b/components/omnibox/common/omnibox_features.cc
@@ -203,6 +203,13 @@ const base::Feature kOmniboxLocalZeroSuggestAgeThreshold{ "OmniboxLocalZeroSuggestAgeThreshold", base::FEATURE_DISABLED_BY_DEFAULT}; +// If enabled, enables local zero-prefix suggestions for signed in users. +// Local zero-prefix suggestions are enabled for signed in users by default. We +// will be experimenting with DISABLING this behavior. +const base::Feature kOmniboxLocalZeroSuggestForAuthenticatedUsers{ + "OmniboxLocalZeroSuggestForAuthenticatedUsers", + base::FEATURE_ENABLED_BY_DEFAULT}; + // If enabled, ranks the local zero-prefix suggestions based on frecency // (combined frequency and recency). const base::Feature kOmniboxLocalZeroSuggestFrecencyRanking{
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h index 79e3d4a..81e63ef 100644 --- a/components/omnibox/common/omnibox_features.h +++ b/components/omnibox/common/omnibox_features.h
@@ -58,6 +58,7 @@ // On-Focus Suggestions a.k.a. ZeroSuggest. extern const base::Feature kClobberTriggersContextualWebZeroSuggest; extern const base::Feature kOmniboxLocalZeroSuggestAgeThreshold; +extern const base::Feature kOmniboxLocalZeroSuggestForAuthenticatedUsers; extern const base::Feature kOmniboxLocalZeroSuggestFrecencyRanking; extern const base::Feature kOmniboxTrendingZeroPrefixSuggestionsOnNTP; extern const base::Feature kOnFocusSuggestionsContextualWeb;
diff --git a/components/safe_browsing/content/web_ui/BUILD.gn b/components/safe_browsing/content/web_ui/BUILD.gn index f176fdb..36709990 100644 --- a/components/safe_browsing/content/web_ui/BUILD.gn +++ b/components/safe_browsing/content/web_ui/BUILD.gn
@@ -26,7 +26,6 @@ "//components/safe_browsing/core/browser:referrer_chain_provider", "//components/safe_browsing/core/common:safe_browsing_prefs", "//components/safe_browsing/core/db:v4_local_database_manager", - "//components/safe_browsing/core/realtime:policy_engine", "//components/safe_browsing/core/web_ui:constants", "//components/strings:components_strings_grit", "//components/sync/protocol:protocol",
diff --git a/components/safe_browsing/content/web_ui/resources/safe_browsing.html b/components/safe_browsing/content/web_ui/resources/safe_browsing.html index 75689ec..6329254 100644 --- a/components/safe_browsing/content/web_ui/resources/safe_browsing.html +++ b/components/safe_browsing/content/web_ui/resources/safe_browsing.html
@@ -92,7 +92,6 @@ </tabpanel> <tabpanel> <h2>RT Lookup Pings</h2> - <p id="rt-lookup-experiment-enabled" class="result-container"></p> <table id="rt-lookup-ping-list" class="request-response"></table> </tabpanel> <tabpanel>
diff --git a/components/safe_browsing/content/web_ui/resources/safe_browsing.js b/components/safe_browsing/content/web_ui/resources/safe_browsing.js index f5ec1b4..c846c67 100644 --- a/components/safe_browsing/content/web_ui/resources/safe_browsing.js +++ b/components/safe_browsing/content/web_ui/resources/safe_browsing.js
@@ -111,9 +111,6 @@ addRTLookupResponse(result); }); - cr.sendWithPromise('getRTLookupExperimentEnabled', []) - .then((enabled) => addRTLookupExperimentEnabled(enabled)); - cr.sendWithPromise('getLogMessages', []).then((logMessages) => { logMessages.forEach(function(message) { addLogMessage(message); @@ -323,12 +320,6 @@ } } - function addRTLookupExperimentEnabled(enabled) { - const enabledFormatted = $('rt-lookup-template').content.cloneNode(true); - enabledFormatted.querySelector('#experiment-bool').textContent = enabled; - $('rt-lookup-experiment-enabled').appendChild(enabledFormatted); - } - function addLogMessage(result) { const logDiv = $('log-messages'); const eventFormatted = "[" + (new Date(result["time"])).toLocaleString() +
diff --git a/components/safe_browsing/content/web_ui/safe_browsing_ui.cc b/components/safe_browsing/content/web_ui/safe_browsing_ui.cc index 68db04f..f124e1c 100644 --- a/components/safe_browsing/content/web_ui/safe_browsing_ui.cc +++ b/components/safe_browsing/content/web_ui/safe_browsing_ui.cc
@@ -37,7 +37,6 @@ #include "components/enterprise/common/proto/connectors.pb.h" #include "components/safe_browsing/core/proto/webprotect.pb.h" #endif -#include "components/safe_browsing/core/realtime/policy_engine.h" #include "components/safe_browsing/core/web_ui/constants.h" #include "components/strings/grit/components_strings.h" #include "components/user_prefs/user_prefs.h" @@ -1992,17 +1991,6 @@ ResolveJavascriptCallback(base::Value(callback_id), responses_sent); } -void SafeBrowsingUIHandler::GetRTLookupExperimentEnabled( - const base::ListValue* args) { - base::ListValue value; - value.Append(base::Value(RealTimePolicyEngine::IsUrlLookupEnabled())); - - AllowJavascript(); - std::string callback_id; - args->GetString(0, &callback_id); - ResolveJavascriptCallback(base::Value(callback_id), value); -} - void SafeBrowsingUIHandler::GetReferrerChain(const base::ListValue* args) { std::string url_string; args->GetString(1, &url_string); @@ -2240,10 +2228,6 @@ base::BindRepeating(&SafeBrowsingUIHandler::GetRTLookupResponses, base::Unretained(this))); web_ui()->RegisterMessageCallback( - "getRTLookupExperimentEnabled", - base::BindRepeating(&SafeBrowsingUIHandler::GetRTLookupExperimentEnabled, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( "getLogMessages", base::BindRepeating(&SafeBrowsingUIHandler::GetLogMessages, base::Unretained(this)));
diff --git a/components/safe_browsing/content/web_ui/safe_browsing_ui.h b/components/safe_browsing/content/web_ui/safe_browsing_ui.h index e363c8c..2a619de 100644 --- a/components/safe_browsing/content/web_ui/safe_browsing_ui.h +++ b/components/safe_browsing/content/web_ui/safe_browsing_ui.h
@@ -128,10 +128,6 @@ // currently open chrome://safe-browsing tab was opened. void GetRTLookupResponses(const base::ListValue* args); - // Show whether real time lookup experiment is enabled. This is useful for - // testing on Android, because it also takes memory threshold into account. - void GetRTLookupExperimentEnabled(const base::ListValue* args); - // Get the current referrer chain for a given URL. void GetReferrerChain(const base::ListValue* args);
diff --git a/components/safe_browsing/core/realtime/policy_engine.h b/components/safe_browsing/core/realtime/policy_engine.h index e69ae30..148bcd9 100644 --- a/components/safe_browsing/core/realtime/policy_engine.h +++ b/components/safe_browsing/core/realtime/policy_engine.h
@@ -74,7 +74,6 @@ bool is_off_the_record); friend class SafeBrowsingService; - friend class SafeBrowsingUIHandler; private: static bool IsInExcludedCountry(const std::string& country_code);
diff --git a/components/services/heap_profiling/public/cpp/profiling_client.cc b/components/services/heap_profiling/public/cpp/profiling_client.cc index ff58a17..d39fdb8 100644 --- a/components/services/heap_profiling/public/cpp/profiling_client.cc +++ b/components/services/heap_profiling/public/cpp/profiling_client.cc
@@ -14,6 +14,7 @@ #include "base/sampling_heap_profiler/sampling_heap_profiler.h" #include "base/task/post_task.h" #include "base/task/thread_pool.h" +#include "base/trace_event/heap_profiler_allocation_context_tracker.h" #include "base/trace_event/heap_profiler_event_filter.h" #include "base/trace_event/malloc_dump_provider.h" #include "base/trace_event/memory_dump_manager.h"
diff --git a/components/timers/alarm_timer_chromeos.cc b/components/timers/alarm_timer_chromeos.cc index af98c065..bd3947c 100644 --- a/components/timers/alarm_timer_chromeos.cc +++ b/components/timers/alarm_timer_chromeos.cc
@@ -17,6 +17,7 @@ #include "base/memory/ptr_util.h" #include "base/pending_task.h" #include "base/task/common/task_annotator.h" +#include "base/trace_event/task_execution_macros.h" #include "base/trace_event/trace_event.h" namespace timers {
diff --git a/components/tracing/test/trace_event_perftest.cc b/components/tracing/test/trace_event_perftest.cc index 5f93f59c..c2317ce 100644 --- a/components/tracing/test/trace_event_perftest.cc +++ b/components/tracing/test/trace_event_perftest.cc
@@ -11,6 +11,7 @@ #include "base/run_loop.h" #include "base/test/task_environment.h" #include "base/threading/thread.h" +#include "base/trace_event/task_execution_macros.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/traced_value.h" #include "perf_test_helpers.h"
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index 62084d4..67a7d8b 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -418,6 +418,7 @@ 'pageshow', 'freeze', 'resume', + 'unload', ]; for (event_name of event_list) { let result = event_name; @@ -3256,6 +3257,117 @@ "window.visibilitychange", "window.pageshow.persisted")); } +// Track the events dispatched when a page is deemed ineligible for back-forward +// cache after we've dispatched the 'pagehide' event with persisted set to true. +IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, + EventsForPageIneligibleAfterPagehidePersisted) { + ASSERT_TRUE(CreateHttpsServer()->Start()); + GURL url_1(https_server()->GetURL("a.com", "/title1.html")); + GURL url_2(https_server()->GetURL("a.com", "/title2.html")); + + // 1) Navigate to |url_1|. + EXPECT_TRUE(NavigateToURL(shell(), url_1)); + RenderFrameHostImpl* rfh_1 = current_frame_host(); + RenderFrameDeletedObserver delete_observer_rfh_1(rfh_1); + // 2) Use WebRTC (a non-sticky blocklisted feature), so that we would still do + // a RFH swap on same-site navigation and fire the 'pagehide' event during + // commit of the new page with 'persisted' set to true, but the page will not + // be eligible for back-forward cache after commit. + EXPECT_TRUE(ExecJs(rfh_1, "new RTCPeerConnection()")); + + EXPECT_TRUE(ExecJs(rfh_1, R"( + window.onpagehide = (e) => { + if (e.persisted) { + window.domAutomationController.send('pagehide.persisted'); + } + } + document.onvisibilitychange = () => { + if (document.visibilityState == 'hidden') { + window.domAutomationController.send('visibilitychange.hidden'); + } + } + window.onunload = () => { + window.domAutomationController.send('unload'); + } + )")); + + DOMMessageQueue dom_message_queue(shell()->web_contents()); + // 3) Navigate to |url_2|. + EXPECT_TRUE(NavigateToURL(shell(), url_2)); + // |rfh_1| will not get into the back-forward cache and eventually get deleted + // because it uses a blocklisted feature. + delete_observer_rfh_1.WaitUntilDeleted(); + + // Only the pagehide and visibilitychange events will be dispatched. + int num_messages_received = 0; + std::string expected_messages[] = {"\"pagehide.persisted\"", + "\"visibilitychange.hidden\""}; + std::string message; + while (dom_message_queue.PopMessage(&message)) { + EXPECT_EQ(expected_messages[num_messages_received], message); + num_messages_received++; + } + EXPECT_EQ(num_messages_received, 2); +} + +// Track the events dispatched when a page is deemed ineligible for back-forward +// cache before we've dispatched the pagehide event on it. +IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, + EventsForPageIneligibleBeforePagehide) { + ASSERT_TRUE(CreateHttpsServer()->Start()); + GURL url_1(https_server()->GetURL("a.com", "/title1.html")); + GURL url_2(https_server()->GetURL("b.com", "/title2.html")); + + // 1) Navigate to |url_1|. + EXPECT_TRUE(NavigateToURL(shell(), url_1)); + RenderFrameHostImpl* rfh_1 = current_frame_host(); + RenderFrameDeletedObserver delete_observer_rfh_1(rfh_1); + // 2) Use keyboard lock (a sticky blocklisted feature), so that the page is + // known to be ineligible for bfcache at commit time, before we dispatch the + // pagehide event. + EXPECT_TRUE(ExecJs(rfh_1, R"( + new Promise(resolve => { + navigator.keyboard.lock(); + resolve(); + }); + )")); + + EXPECT_TRUE(ExecJs(rfh_1, R"( + window.onpagehide = (e) => { + if (!e.persisted) { + window.domAutomationController.send('pagehide.not_persisted'); + } + } + document.onvisibilitychange = () => { + if (document.visibilityState == 'hidden') { + window.domAutomationController.send('visibilitychange.hidden'); + } + } + window.onunload = () => { + window.domAutomationController.send('unload'); + } + )")); + + DOMMessageQueue dom_message_queue(shell()->web_contents()); + // 3) Navigate to |url_2|. + EXPECT_TRUE(NavigateToURL(shell(), url_2)); + // |rfh_1| will not get into the back-forward cache and eventually get deleted + // because it uses a blocklisted feature. + delete_observer_rfh_1.WaitUntilDeleted(); + + // "pagehide", "visibilitychange", and "unload" events will be dispatched. + int num_messages_received = 0; + std::string expected_messages[] = {"\"pagehide.not_persisted\"", + "\"visibilitychange.hidden\"", + "\"unload\""}; + std::string message; + while (dom_message_queue.PopMessage(&message)) { + EXPECT_EQ(expected_messages[num_messages_received], message); + num_messages_received++; + } + EXPECT_EQ(num_messages_received, 3); +} + IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, EvictPageWithInfiniteLoop) { ASSERT_TRUE(embedded_test_server()->Start()); GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
diff --git a/content/browser/bluetooth/bluetooth_device_chooser_controller.cc b/content/browser/bluetooth/bluetooth_device_chooser_controller.cc index 4fab4dc..604357f 100644 --- a/content/browser/bluetooth/bluetooth_device_chooser_controller.cc +++ b/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
@@ -157,38 +157,6 @@ return false; } -std::unique_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter( - const base::Optional< - std::vector<blink::mojom::WebBluetoothLeScanFilterPtr>>& filters) { - // There isn't much support for GATT over BR/EDR from neither platforms nor - // devices so performing a Dual scan will find devices that the API is not - // able to interact with. To avoid wasting power and confusing users with - // devices they are not able to interact with, we only perform an LE Scan. - auto discovery_filter = std::make_unique<device::BluetoothDiscoveryFilter>( - device::BLUETOOTH_TRANSPORT_LE); - - if (filters) { - for (const auto& filter : filters.value()) { - device::BluetoothDiscoveryFilter::DeviceInfoFilter device_filter; - bool useful_filter = false; - if (filter->services) { - device_filter.uuids = - base::flat_set<device::BluetoothUUID>(filter->services.value()); - useful_filter = true; - } - if (filter->name) { - device_filter.name = filter->name.value(); - useful_filter = true; - } - if (useful_filter) { - discovery_filter->AddDeviceFilter(device_filter); - } - } - } - - return discovery_filter; -} - void StopDiscoverySession( std::unique_ptr<device::BluetoothDiscoverySession> discovery_session) { // Nothing goes wrong if the discovery session fails to stop, and we don't @@ -568,4 +536,45 @@ } } +// static +std::unique_ptr<device::BluetoothDiscoveryFilter> +BluetoothDeviceChooserController::ComputeScanFilter( + const base::Optional< + std::vector<blink::mojom::WebBluetoothLeScanFilterPtr>>& filters) { + // There isn't much support for GATT over BR/EDR from neither platforms nor + // devices so performing a Dual scan will find devices that the API is not + // able to interact with. To avoid wasting power and confusing users with + // devices they are not able to interact with, we only perform an LE Scan. + auto discovery_filter = std::make_unique<device::BluetoothDiscoveryFilter>( + device::BLUETOOTH_TRANSPORT_LE); + + if (filters) { + for (const auto& filter : filters.value()) { + device::BluetoothDiscoveryFilter::DeviceInfoFilter device_filter; + // Keep track of whether this filter can be converted accurately. + bool has_supported_fields = false; + if (filter->services) { + device_filter.uuids = + base::flat_set<device::BluetoothUUID>(filter->services.value()); + has_supported_fields = true; + } + if (filter->name) { + device_filter.name = filter->name.value(); + has_supported_fields = true; + } + + // If we don't have any supported fields in this filter then we cannot + // filter any devices as we don't want to filter out devices which would + // have passed these unsupported filter criteria. + if (!has_supported_fields) { + discovery_filter->ClearDeviceFilters(); + return discovery_filter; + } + discovery_filter->AddDeviceFilter(device_filter); + } + } + + return discovery_filter; +} + } // namespace content
diff --git a/content/browser/bluetooth/bluetooth_device_chooser_controller.h b/content/browser/bluetooth/bluetooth_device_chooser_controller.h index 746ad34..7f6909f 100644 --- a/content/browser/bluetooth/bluetooth_device_chooser_controller.h +++ b/content/browser/bluetooth/bluetooth_device_chooser_controller.h
@@ -20,6 +20,7 @@ class BluetoothAdapter; class BluetoothDevice; class BluetoothDiscoverySession; +class BluetoothDiscoveryFilter; } namespace content { @@ -94,6 +95,10 @@ TestScanDurationSetting setting = TestScanDurationSetting::IMMEDIATE_TIMEOUT); + static std::unique_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter( + const base::Optional< + std::vector<blink::mojom::WebBluetoothLeScanFilterPtr>>& filters); + private: // Populates the chooser with the GATT connected devices. void PopulateConnectedDevices();
diff --git a/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc b/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc index cb23903..39213de1 100644 --- a/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc +++ b/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc
@@ -3,8 +3,13 @@ // found in the LICENSE file. #include "content/browser/bluetooth/bluetooth_device_chooser_controller.h" +#include "device/bluetooth/bluetooth_discovery_filter.h" #include "testing/gtest/include/gtest/gtest.h" +constexpr char kHeartRateUUIDString[] = "0000180d-0000-1000-8000-00805f9b34fb"; +constexpr char kBatteryServiceUUIDString[] = + "0000180f-0000-1000-8000-00805f9b34fb"; + namespace content { class BluetoothDeviceChooserControllerTest : public testing::Test {}; @@ -36,4 +41,129 @@ 4, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(127)); } +TEST_F(BluetoothDeviceChooserControllerTest, ComputeScanFilterTest) { + // No supported OS level filters have a name prefix filter. Since filters are + // unioned we must not filter any devices if we have a name prefix filter. + { + auto filter = blink::mojom::WebBluetoothLeScanFilter::New(); + filter->name_prefix = "test name prefix"; + + std::vector<blink::mojom::WebBluetoothLeScanFilterPtr> scan_filters; + scan_filters.emplace_back(std::move(filter)); + + std::unique_ptr<device::BluetoothDiscoveryFilter> resulting_filter = + BluetoothDeviceChooserController::ComputeScanFilter( + std::move(scan_filters)); + + const base::flat_set<device::BluetoothDiscoveryFilter::DeviceInfoFilter>* + device_info_filters = resulting_filter->GetDeviceFilters(); + + EXPECT_TRUE(device_info_filters->empty()); + } + // Ensures ComputeScanFilter adds all UUIDs to the BluetoothDiscoveryFilter + // that it creates + { + std::vector<device::BluetoothUUID> services; + services.emplace_back(device::BluetoothUUID(kHeartRateUUIDString)); + services.emplace_back(device::BluetoothUUID(kBatteryServiceUUIDString)); + + auto filter = blink::mojom::WebBluetoothLeScanFilter::New(); + filter->services = std::move(services); + + std::vector<blink::mojom::WebBluetoothLeScanFilterPtr> scan_filters; + scan_filters.emplace_back(std::move(filter)); + + std::unique_ptr<device::BluetoothDiscoveryFilter> resulting_filter = + BluetoothDeviceChooserController::ComputeScanFilter( + std::move(scan_filters)); + + const base::flat_set<device::BluetoothDiscoveryFilter::DeviceInfoFilter>* + device_info_filters = resulting_filter->GetDeviceFilters(); + + EXPECT_TRUE(device_info_filters->begin()->uuids.contains( + device::BluetoothUUID(kHeartRateUUIDString))); + EXPECT_TRUE(device_info_filters->begin()->uuids.contains( + device::BluetoothUUID(kBatteryServiceUUIDString))); + EXPECT_TRUE(device_info_filters->begin()->name.empty()); + } + // Ensures ComputeScanFilter adds the correct name to the + // BluetoothDiscoveryFilter that it creates + { + auto filter = blink::mojom::WebBluetoothLeScanFilter::New(); + filter->name = "test name"; + + std::vector<blink::mojom::WebBluetoothLeScanFilterPtr> scan_filters; + scan_filters.emplace_back(std::move(filter)); + + std::unique_ptr<device::BluetoothDiscoveryFilter> resulting_filter = + BluetoothDeviceChooserController::ComputeScanFilter( + std::move(scan_filters)); + + const base::flat_set<device::BluetoothDiscoveryFilter::DeviceInfoFilter>* + device_info_filters = resulting_filter->GetDeviceFilters(); + + EXPECT_TRUE(device_info_filters->begin()->uuids.empty()); + EXPECT_EQ(device_info_filters->begin()->name, "test name"); + } + // Ensures ComputeScanFilter adds both the name and the UUIDs to the + // BluetoothDiscoveryFilter that it creates + { + std::vector<device::BluetoothUUID> services; + services.emplace_back(device::BluetoothUUID(kHeartRateUUIDString)); + services.emplace_back(device::BluetoothUUID(kBatteryServiceUUIDString)); + + auto filter = blink::mojom::WebBluetoothLeScanFilter::New(); + filter->services = std::move(services); + filter->name = "test name"; + + std::vector<blink::mojom::WebBluetoothLeScanFilterPtr> scan_filters; + scan_filters.emplace_back(std::move(filter)); + + std::unique_ptr<device::BluetoothDiscoveryFilter> resulting_filter = + BluetoothDeviceChooserController::ComputeScanFilter( + std::move(scan_filters)); + + const base::flat_set<device::BluetoothDiscoveryFilter::DeviceInfoFilter>* + device_info_filters = resulting_filter->GetDeviceFilters(); + + EXPECT_TRUE(device_info_filters->begin()->uuids.contains( + device::BluetoothUUID(kHeartRateUUIDString))); + EXPECT_TRUE(device_info_filters->begin()->uuids.contains( + device::BluetoothUUID(kBatteryServiceUUIDString))); + EXPECT_EQ(device_info_filters->begin()->name, "test name"); + } + // Ensures we will not filter any devices if we have at least one + // name_prefix only filter even with other filters present. + { + std::vector<device::BluetoothUUID> services; + services.emplace_back(device::BluetoothUUID(kHeartRateUUIDString)); + std::vector<device::BluetoothUUID> services2; + services2.emplace_back(device::BluetoothUUID(kBatteryServiceUUIDString)); + + auto filter = blink::mojom::WebBluetoothLeScanFilter::New(); + filter->services = std::move(services); + filter->name = "test name"; + + auto prefix_filter = blink::mojom::WebBluetoothLeScanFilter::New(); + prefix_filter->name_prefix = "test name prefix"; + + auto filter2 = blink::mojom::WebBluetoothLeScanFilter::New(); + filter2->services = std::move(services2); + filter2->name = "test name2"; + + std::vector<blink::mojom::WebBluetoothLeScanFilterPtr> scan_filters; + scan_filters.emplace_back(std::move(filter)); + scan_filters.emplace_back(std::move(prefix_filter)); + + std::unique_ptr<device::BluetoothDiscoveryFilter> resulting_filter = + BluetoothDeviceChooserController::ComputeScanFilter( + std::move(scan_filters)); + + const base::flat_set<device::BluetoothDiscoveryFilter::DeviceInfoFilter>* + device_info_filters = resulting_filter->GetDeviceFilters(); + + EXPECT_TRUE(device_info_filters->empty()); + } +} + } // namespace content \ No newline at end of file
diff --git a/content/browser/hid/hid_service.cc b/content/browser/hid/hid_service.cc index e82e310..da81e01 100644 --- a/content/browser/hid/hid_service.cc +++ b/content/browser/hid/hid_service.cc
@@ -183,22 +183,25 @@ WebContents* web_contents = WebContents::FromRenderFrameHost(render_frame_host()); - base::EraseIf(watcher_ids_, [&](const auto& watcher_entry) { - const auto* device_info = - delegate->GetDeviceInfo(web_contents, watcher_entry.first); - if (!device_info) - return true; + size_t watchers_removed = + base::EraseIf(watcher_ids_, [&](const auto& watcher_entry) { + const auto* device_info = + delegate->GetDeviceInfo(web_contents, watcher_entry.first); + if (!device_info) + return true; - if (delegate->HasDevicePermission(web_contents, origin(), *device_info)) { - return false; - } + if (delegate->HasDevicePermission(web_contents, origin(), + *device_info)) { + return false; + } - watchers_.Remove(watcher_entry.second); - return true; - }); + watchers_.Remove(watcher_entry.second); + return true; + }); // If needed decrement the active frame count. - OnWatcherRemoved(false /* cleanup_watcher_ids */); + if (watchers_removed) + OnWatcherRemoved(/*cleanup_watcher_ids=*/false); } void HidService::FinishGetDevices(
diff --git a/content/browser/hid/hid_service_unittest.cc b/content/browser/hid/hid_service_unittest.cc index d352460..22d3277 100644 --- a/content/browser/hid/hid_service_unittest.cc +++ b/content/browser/hid/hid_service_unittest.cc
@@ -388,4 +388,19 @@ EXPECT_FALSE(connection.is_connected()); } +TEST_F(HidServiceTest, RevokeDevicePermissionWithoutConnection) { + NavigateAndCommit(GURL(kTestUrl)); + + mojo::Remote<blink::mojom::HidService> service; + contents()->GetMainFrame()->GetHidService( + service.BindNewPipeAndPassReceiver()); + + // Simulate user revoking permission. + url::Origin origin = url::Origin::Create(GURL(kTestUrl)); + hid_delegate().OnPermissionRevoked(origin, origin); + + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(contents()->IsConnectedToHidDevice()); +} + } // namespace content
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java index 81f9d4a..b439fb4 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java
@@ -379,6 +379,22 @@ mAllowedMenuItems = allowedMenuItems; } + @Override + public int getAllowedMenuItemIfAny(ActionMode mode, MenuItem item) { + if (!isActionModeValid()) return 0; + + int id = item.getItemId(); + int groupId = item.getGroupId(); + if (id == R.id.select_action_menu_share) { + return MENU_ITEM_SHARE; + } else if (id == R.id.select_action_menu_web_search) { + return MENU_ITEM_WEB_SEARCH; + } else if (groupId == R.id.select_action_menu_text_processing_menus) { + return MENU_ITEM_PROCESS_TEXT; + } + return 0; + } + @VisibleForTesting @CalledByNative public void showSelectionMenu(int left, int top, int right, int bottom, int handleHeight,
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java b/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java index d95fc55..863a741 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java
@@ -100,7 +100,14 @@ * Set the action mode menu items allowed on the content. * @param allowedMenuItems bit field of item-flag mapping. */ - public abstract void setAllowedMenuItems(int menItems); + public abstract void setAllowedMenuItems(int allowedMenuItems); + + /** + * If the passed in mode and menu matches one of the MENU_ITEM_* items, return it. + * Otherwise, return 0. Only call from inside the implementation of + * ActionMode.Callback#onActionItemClicked. + */ + public abstract int getAllowedMenuItemIfAny(ActionMode mode, MenuItem item); /** * @see {@link ActionMode.Callback#onCreateActionMode(ActionMode, Menu)}
diff --git a/content/public/browser/non_network_url_loader_factory_base.cc b/content/public/browser/non_network_url_loader_factory_base.cc index f66b0eb..7bb7797 100644 --- a/content/public/browser/non_network_url_loader_factory_base.cc +++ b/content/public/browser/non_network_url_loader_factory_base.cc
@@ -17,6 +17,19 @@ NonNetworkURLLoaderFactoryBase::~NonNetworkURLLoaderFactoryBase() = default; +void NonNetworkURLLoaderFactoryBase::DisconnectReceiversAndDestroy() { + // Clear |receivers_| to explicitly make sure that no further method + // invocations or disconnection notifications will happen. (per the + // comment of mojo::ReceiverSet::Clear) + receivers_.Clear(); + + // Similarly to OnDisconnect, if there are no more |receivers_|, then no + // instance methods of |this| can be called in the future (mojo methods Clone + // and CreateLoaderAndStart should be the only public entrypoints). + // Therefore, it is safe to delete |this| at this point. + delete this; +} + void NonNetworkURLLoaderFactoryBase::Clone( mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -27,8 +40,13 @@ void NonNetworkURLLoaderFactoryBase::OnDisconnect() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (receivers_.empty()) + if (receivers_.empty()) { + // If there are no more |receivers_|, then no instance methods of |this| can + // be called in the future (mojo methods Clone and CreateLoaderAndStart + // should be the only public entrypoints). Therefore, it is safe to delete + // |this| at this point. delete this; + } } } // namespace content
diff --git a/content/public/browser/non_network_url_loader_factory_base.h b/content/public/browser/non_network_url_loader_factory_base.h index 67a16eea..591ce7e 100644 --- a/content/public/browser/non_network_url_loader_factory_base.h +++ b/content/public/browser/non_network_url_loader_factory_base.h
@@ -39,6 +39,18 @@ ~NonNetworkURLLoaderFactoryBase() override; + // Sometimes a derived class can no longer function, even when the set of + // |receivers_| is still non-empty. This should be rare (typically the + // lifetime of users of mojo::Remote<network::mojom::URLLoaderFactory> should + // be shorter than whatever the factory depends on), but may happen in some + // corner cases (e.g. in a race between 1) BrowserContext destruction and 2) + // CreateLoaderAndStart mojo call). + // + // When a derived class gets notified that its dependencies got destroyed, it + // should call DisconnectReceiversAndDestroy to prevent any future calls to + // CreateLoaderAndStart. + void DisconnectReceiversAndDestroy(); + THREAD_CHECKER(thread_checker_); private:
diff --git a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt index 2c7f592..f04fcba 100644 --- a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
@@ -5,7 +5,8 @@ # mac # win win10 win7 ] # tags: [ debug ] -# tags: [ intel intel-0x3e92 intel-0xa2e intel-0x5912 intel-0xd26 +# tags: [ amd amd-0x699f +# intel intel-0x3e92 intel-0xa2e intel-0x5912 intel-0xd26 # nvidia nvidia-0x1cb3 # qualcomm-adreno-(tm)-418 ] # results: [ Failure RetryOnFailure Skip ] @@ -103,17 +104,24 @@ # Using YUY2 instead of NV12 on Windows 10 HD 630 GPUs due to NV12 support # showing up as SOFTWARE which causes zero copy to fail. +crbug.com/1079393 [ win10 intel-0x5912 ] OverlayModeTraceTest_DirectComposition_Video_MP4_NV12 [ Failure ] +crbug.com/1079393 [ win10 intel-0x5912 ] OverlayModeTraceTest_DirectComposition_Video_VP9_NV12 [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Underlay [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Underlay_DXVA [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Underlay_Fullsize [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_MP4 [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_MP4_DXVA [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_MP4_FourColors_Aspect_4x3 [ Failure ] +crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_MP4_FourColors_Rot_180 [ Failure ] +crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_MP4_FourColors_Rot_270 [ Failure ] +crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_MP4_FourColors_Rot_90 [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_MP4_Fullsize [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_MP4_NV12 [ Failure ] +crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_MP4_VP_SCALING [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_VP9 [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_VP9_DXVA [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_VP9_NV12 [ Failure ] +crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_VP9_VP_SCALING [ Failure ] # Fuchsia Flakes. crbug.com/1058255 [ fuchsia ] TraceTest_WebGLGreenTriangle_AA_Alpha [ Skip ] @@ -138,3 +146,7 @@ # BGRA swap chains don't consistently get promoted to overlays. crbug.com/1119491 [ win intel ] OverlayModeTraceTest_DirectComposition_Video_MP4_BGRA [ Skip ] crbug.com/1119491 [ win intel ] OverlayModeTraceTest_DirectComposition_Video_VP9_BGRA [ Skip ] + +# YUY2 swap chains don't work on AMD. +crbug.com/1132381 [ win amd-0x699f ] VideoPathTraceTest_DirectComposition_Video_MP4_YUY2 [ Failure ] +crbug.com/1132381 [ win amd-0x699f ] VideoPathTraceTest_DirectComposition_Video_VP9_YUY2 [ Failure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index 3c66cd7..8229ad9 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -600,6 +600,7 @@ crbug.com/1095679 [ android qualcomm-adreno-(tm)-418 no-passthrough ] conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html [ RetryOnFailure ] crbug.com/1095679 [ android qualcomm-adreno-(tm)-418 no-passthrough ] conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ RetryOnFailure ] crbug.com/1095679 [ android qualcomm-adreno-(tm)-418 no-passthrough ] conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ] +crbug.com/1135785 [ android qualcomm-adreno-(tm)-418 no-passthrough ] conformance/textures/misc/texture-video-transparent.html [ RetryOnFailure ] # Timing out on this device for unknown reasons. crbug.com/1099148 [ android qualcomm-adreno-(tm)-418 ] deqp/data/gles2/shaders/swizzles.html [ Skip ] crbug.com/1122644 [ android qualcomm-adreno-(tm)-418 ] conformance/textures/misc/texture-upload-size.html [ Skip ]
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn index 50a3a0c..15346647 100644 --- a/device/bluetooth/BUILD.gn +++ b/device/bluetooth/BUILD.gn
@@ -59,8 +59,9 @@ # Experimental implementation not ready for production use yet. See # public/mojom/README.md - # Single approved client: + # Approved clients: "//chrome/browser/ui/webui/bluetooth_internals:*", + "//chrome/browser/chromeos/nearby:bluetooth_adapter_util", # Implementation tests # Ideally only device_unittests, however android & fushia generate
diff --git a/device/bluetooth/bluetooth_discovery_filter.cc b/device/bluetooth/bluetooth_discovery_filter.cc index 9ad3b1f..e5a885c7 100644 --- a/device/bluetooth/bluetooth_discovery_filter.cc +++ b/device/bluetooth/bluetooth_discovery_filter.cc
@@ -95,6 +95,10 @@ return &device_filters_; } +void BluetoothDiscoveryFilter::ClearDeviceFilters() { + device_filters_.clear(); +} + void BluetoothDiscoveryFilter::CopyFrom( const BluetoothDiscoveryFilter& filter) { transport_ = filter.transport_;
diff --git a/device/bluetooth/bluetooth_discovery_filter.h b/device/bluetooth/bluetooth_discovery_filter.h index dade11d..ad2527f 100644 --- a/device/bluetooth/bluetooth_discovery_filter.h +++ b/device/bluetooth/bluetooth_discovery_filter.h
@@ -93,6 +93,8 @@ // Returns true if all fields in filter are empty bool IsDefault() const; + void ClearDeviceFilters(); + // Returns result of merging two filters together. If at least one of the // filters is NULL this will return an empty filter static std::unique_ptr<device::BluetoothDiscoveryFilter> Merge(
diff --git a/extensions/browser/browser_context_keyed_service_factories.cc b/extensions/browser/browser_context_keyed_service_factories.cc index afdb3c8..176bf55 100644 --- a/extensions/browser/browser_context_keyed_service_factories.cc +++ b/extensions/browser/browser_context_keyed_service_factories.cc
@@ -39,6 +39,7 @@ #include "extensions/browser/event_router_factory.h" #include "extensions/browser/extension_message_filter.h" #include "extensions/browser/extension_prefs_factory.h" +#include "extensions/browser/extension_protocols.h" #include "extensions/browser/guest_view/extensions_guest_view_message_filter.h" #include "extensions/browser/process_manager_factory.h" #include "extensions/browser/renderer_startup_helper.h" @@ -83,6 +84,7 @@ declarative_net_request::RulesMonitorService::GetFactoryInstance(); DeclarativeUserScriptManagerFactory::GetInstance(); DisplaySourceEventRouterFactory::GetInstance(); + EnsureExtensionURLLoaderFactoryShutdownNotifierFactoryBuilt(); EventRouterFactory::GetInstance(); ExtensionMessageFilter::EnsureShutdownNotifierFactoryBuilt(); ExtensionsGuestViewMessageFilter::EnsureShutdownNotifierFactoryBuilt();
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index ce31f93..5789324 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1580,6 +1580,8 @@ FILEMANAGERPRIVATEINTERNAL_GETPDFTHUMBNAIL = 1517, AUTOTESTPRIVATE_REMOVEALLNOTIFICATIONS = 1518, VIRTUALKEYBOARDPRIVATE_OPENSUGGESTIONSETTINGS = 1519, + ACCESSIBILITY_PRIVATE_ENABLEPOINTSCAN = 1520, + AUTOTESTPRIVATE_ACTIVATEADJACENTDESKSTOTARGETINDEX = 1521, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/browser/extension_protocols.cc b/extensions/browser/extension_protocols.cc index 34e8114..e4e1bf4 100644 --- a/extensions/browser/extension_protocols.cc +++ b/extensions/browser/extension_protocols.cc
@@ -29,6 +29,7 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" +#include "base/no_destructor.h" #include "base/numerics/safe_conversions.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -38,6 +39,8 @@ #include "base/threading/thread_restrictions.h" #include "base/timer/elapsed_timer.h" #include "build/build_config.h" +#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h" +#include "components/keyed_service/core/keyed_service_shutdown_notifier.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -53,6 +56,7 @@ #include "extensions/browser/content_verify_job.h" #include "extensions/browser/extension_navigation_ui_data.h" #include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_registry_factory.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/extension_util.h" #include "extensions/browser/extensions_browser_client.h" @@ -61,6 +65,7 @@ #include "extensions/browser/info_map.h" #include "extensions/browser/media_router_extension_access_logger.h" #include "extensions/browser/process_map.h" +#include "extensions/browser/process_map_factory.h" #include "extensions/browser/url_request_util.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" @@ -459,8 +464,15 @@ base::UkmSourceId ukm_source_id, bool is_web_view_request, int render_process_id) { + DCHECK(browser_context); + mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_remote; + // Return an unbound |pending_remote| if the |browser_context| has already + // started shutting down. + if (browser_context->ShutdownStarted()) + return pending_remote; + // Manages its own lifetime. new ExtensionURLLoaderFactory( browser_context, ukm_source_id, is_web_view_request, render_process_id, @@ -469,6 +481,10 @@ return pending_remote; } + static void EnsureShutdownNotifierFactoryBuilt() { + BrowserContextShutdownNotifierFactory::GetInstance(); + } + private: // Constructs ExtensionURLLoaderFactory bound to the |factory_receiver|. // @@ -490,6 +506,16 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); extension_info_map_ = extensions::ExtensionSystem::Get(browser_context_)->info_map(); + + // base::Unretained is safe below, because lifetime of + // |browser_context_shutdown_subscription_| guarantees that + // OnBrowserContextDestroyed won't be called after |this| is destroyed. + browser_context_shutdown_subscription_ = + BrowserContextShutdownNotifierFactory::GetInstance() + ->Get(browser_context) + ->Subscribe(base::BindRepeating( + &ExtensionURLLoaderFactory::OnBrowserContextDestroyed, + base::Unretained(this))); } ~ExtensionURLLoaderFactory() override = default; @@ -506,6 +532,12 @@ override { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (browser_context_->ShutdownStarted()) { + mojo::Remote<network::mojom::URLLoaderClient>(std::move(client)) + ->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED)); + return; + } + client = WrapWithMetricsIfNeeded(request.url, ukm_source_id_, std::move(client)); @@ -723,6 +755,38 @@ /* allow_directory_listing */ false, std::move(response_headers)); } + void OnBrowserContextDestroyed() { + // When |browser_context_| gets destroyed, |this| factory is not able to + // serve any more requests. + DisconnectReceiversAndDestroy(); + } + + class BrowserContextShutdownNotifierFactory + : public BrowserContextKeyedServiceShutdownNotifierFactory { + public: + static BrowserContextShutdownNotifierFactory* GetInstance() { + static base::NoDestructor<BrowserContextShutdownNotifierFactory> + s_factory; + return s_factory.get(); + } + + // No copying. + BrowserContextShutdownNotifierFactory( + const BrowserContextShutdownNotifierFactory&) = delete; + BrowserContextShutdownNotifierFactory& operator=( + const BrowserContextShutdownNotifierFactory&) = delete; + + private: + friend class base::NoDestructor<BrowserContextShutdownNotifierFactory>; + BrowserContextShutdownNotifierFactory() + : BrowserContextKeyedServiceShutdownNotifierFactory( + "ExtensionURLLoaderFactory::" + "BrowserContextShutdownNotifierFactory") { + DependsOn(ExtensionRegistryFactory::GetInstance()); + DependsOn(ProcessMapFactory::GetInstance()); + } + }; + content::BrowserContext* browser_context_; bool is_web_view_request_; base::UkmSourceId ukm_source_id_; @@ -733,6 +797,9 @@ const int render_process_id_; scoped_refptr<extensions::InfoMap> extension_info_map_; + std::unique_ptr<KeyedServiceShutdownNotifier::Subscription> + browser_context_shutdown_subscription_; + DISALLOW_COPY_AND_ASSIGN(ExtensionURLLoaderFactory); }; @@ -828,4 +895,8 @@ browser_context, ukm_source_id, is_web_view_request, render_process_id); } +void EnsureExtensionURLLoaderFactoryShutdownNotifierFactoryBuilt() { + ExtensionURLLoaderFactory::EnsureShutdownNotifierFactoryBuilt(); +} + } // namespace extensions
diff --git a/extensions/browser/extension_protocols.h b/extensions/browser/extension_protocols.h index 946774ba..7980d1f 100644 --- a/extensions/browser/extension_protocols.h +++ b/extensions/browser/extension_protocols.h
@@ -77,6 +77,8 @@ mojo::PendingRemote<network::mojom::URLLoaderFactory> CreateExtensionURLLoaderFactory(int render_process_id, int render_frame_id); +void EnsureExtensionURLLoaderFactoryShutdownNotifierFactoryBuilt(); + } // namespace extensions #endif // EXTENSIONS_BROWSER_EXTENSION_PROTOCOLS_H_
diff --git a/extensions/common/url_pattern.cc b/extensions/common/url_pattern.cc index 7a69da7f..1126c48b 100644 --- a/extensions/common/url_pattern.cc +++ b/extensions/common/url_pattern.cc
@@ -160,15 +160,9 @@ match_subdomains_(false), port_("*") { ParseResult result = Parse(pattern); - if (result != ParseResult::kSuccess) { - const char* error_string = GetParseResultString(result); - // Temporarily add more logging to investigate why this code path is - // reached. For http://crbug.com/856948 - LOG(ERROR) << "Invalid pattern was given " << pattern << " result " - << error_string; - NOTREACHED() << "URLPattern invalid: '" << pattern - << "'; error: " << error_string; - } + DCHECK_EQ(ParseResult::kSuccess, result) + << "Parsing unexpectedly failed for pattern: " << pattern << ": " + << GetParseResultString(result); } URLPattern::URLPattern(const URLPattern& other) = default;
diff --git a/extensions/common/url_pattern.h b/extensions/common/url_pattern.h index 4547825..feda6fb 100644 --- a/extensions/common/url_pattern.h +++ b/extensions/common/url_pattern.h
@@ -98,6 +98,7 @@ // Convenience to construct a URLPattern from a string. If the string is not // known ahead of time, use Parse() instead, which returns success or failure. + // This method will DCHECK if parsing fails. URLPattern(int valid_schemes, base::StringPiece pattern); URLPattern();
diff --git a/fuchsia/cast_streaming/cast_message_port_impl.cc b/fuchsia/cast_streaming/cast_message_port_impl.cc index 906f305..e362fe7 100644 --- a/fuchsia/cast_streaming/cast_message_port_impl.cc +++ b/fuchsia/cast_streaming/cast_message_port_impl.cc
@@ -267,7 +267,7 @@ client_->OnMessage(sender_id, message_namespace, str_message); } else if (message_namespace == kInjectNamespace) { SendInjectResponse(sender_id, str_message); - } else if (message_namespace == kSystemNamespace) { + } else if (message_namespace != kSystemNamespace) { // System messages are ignored, log messages from unknown namespaces. DVLOG(2) << "Unknown message from " << sender_id << ", namespace=" << message_namespace
diff --git a/fuchsia/cast_streaming/cast_streaming_session.cc b/fuchsia/cast_streaming/cast_streaming_session.cc index 3e5d348a..3561e302 100644 --- a/fuchsia/cast_streaming/cast_streaming_session.cc +++ b/fuchsia/cast_streaming/cast_streaming_session.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/notreached.h" +#include "base/timer/timer.h" #include "components/openscreen_platform/network_context.h" #include "components/openscreen_platform/network_util.h" #include "components/openscreen_platform/task_runner.h" @@ -26,6 +27,9 @@ constexpr char kVideoCodecH264[] = "h264"; constexpr char kVideoCodecVp8[] = "vp8"; +// Timeout to end the Session when no offer message is sent. +constexpr base::TimeDelta kInitTimeout = base::TimeDelta::FromSeconds(5); + } // namespace namespace cast_streaming { @@ -48,19 +52,24 @@ : task_runner_(task_runner), environment_(&openscreen::Clock::now, &task_runner_), cast_message_port_impl_(std::move(message_port_request)), - // TODO(crbug.com/1087520): Add streaming session Constraints and - // DisplayDescription. - receiver_session_(this, - &environment_, - &cast_message_port_impl_, - openscreen::cast::ReceiverSession::Preferences( - {openscreen::cast::VideoCodec::kH264, - openscreen::cast::VideoCodec::kVp8}, - {openscreen::cast::AudioCodec::kAac, - openscreen::cast::AudioCodec::kOpus})), client_(client) { DCHECK(task_runner); DCHECK(client_); + + // TODO(crbug.com/1087520): Add streaming session Constraints and + // DisplayDescription. + receiver_session_ = std::make_unique<openscreen::cast::ReceiverSession>( + this, &environment_, &cast_message_port_impl_, + openscreen::cast::ReceiverSession::Preferences( + {openscreen::cast::VideoCodec::kH264, + openscreen::cast::VideoCodec::kVp8}, + {openscreen::cast::AudioCodec::kAac, + openscreen::cast::AudioCodec::kOpus})); + + init_timeout_timer_.Start( + FROM_HERE, kInitTimeout, + base::BindOnce(&CastStreamingSession::Internal::OnInitializationTimeout, + base::Unretained(this))); } ~Internal() final = default; @@ -69,14 +78,22 @@ Internal& operator=(const Internal&) = delete; private: + void OnInitializationTimeout() { + DVLOG(1) << __func__; + DCHECK(!is_initialized_); + client_->OnInitializationFailure(); + is_initialized_ = true; + } + // openscreen::cast::ReceiverSession::Client implementation. void OnNegotiated( const openscreen::cast::ReceiverSession* session, openscreen::cast::ReceiverSession::ConfiguredReceivers receivers) final { DVLOG(1) << __func__; - DCHECK_EQ(session, &receiver_session_); + DCHECK_EQ(session, receiver_session_.get()); + init_timeout_timer_.Stop(); - if (initialized_called_) { + if (is_initialized_) { // TODO(crbug.com/1116185): Handle multiple offer messages properly. return; } @@ -99,11 +116,15 @@ } // Initialize the audio consumer. + // We can use unretained pointers here because StreamConsumer is owned by + // this object and |client_| is guaranteed to outlive this object. audio_consumer_ = std::make_unique<StreamConsumer>( receivers.audio->receiver, std::move(data_pipe_producer), base::BindRepeating( &CastStreamingSession::Client::OnAudioBufferReceived, - base::Unretained(client_))); + base::Unretained(client_)), + base::BindOnce(&CastStreamingSession::Internal::OnDataTimeout, + base::Unretained(this))); // Gather data for the audio decoder config. media::ChannelLayout channel_layout = @@ -143,11 +164,15 @@ } // Initialize the video consumer. + // We can use unretained pointers here because StreamConsumer is owned by + // this object and |client_| is guaranteed to outlive this object. video_consumer_ = std::make_unique<StreamConsumer>( receivers.video->receiver, std::move(data_pipe_producer), base::BindRepeating( &CastStreamingSession::Client::OnVideoBufferReceived, - base::Unretained(client_))); + base::Unretained(client_)), + base::BindOnce(&CastStreamingSession::Internal::OnDataTimeout, + base::Unretained(this))); // Gather data for the video decoder config. const std::string& video_codec = @@ -193,14 +218,15 @@ client_->OnInitializationSuccess(std::move(audio_stream_info), std::move(video_stream_info)); } - initialized_called_ = true; + is_initialized_ = true; } // TODO(https://crbug.com/1116185): Handle |reason| and reset streams on a // new offer message. void OnReceiversDestroying(const openscreen::cast::ReceiverSession* session, ReceiversDestroyingReason reason) final { - DCHECK_EQ(session, &receiver_session_); + // This can be called when |receiver_session_| is being destroyed, so we + // do not sanity-check |session| here. DVLOG(1) << __func__; audio_consumer_.reset(); video_consumer_.reset(); @@ -209,20 +235,26 @@ void OnError(const openscreen::cast::ReceiverSession* session, openscreen::Error error) final { - DCHECK_EQ(session, &receiver_session_); + DCHECK_EQ(session, receiver_session_.get()); LOG(ERROR) << error; - if (!initialized_called_) { + if (!is_initialized_) { client_->OnInitializationFailure(); - initialized_called_ = true; + is_initialized_ = true; } } + void OnDataTimeout() { + DVLOG(1) << __func__; + receiver_session_.reset(); + } + openscreen_platform::TaskRunner task_runner_; openscreen::cast::Environment environment_; CastMessagePortImpl cast_message_port_impl_; - openscreen::cast::ReceiverSession receiver_session_; + std::unique_ptr<openscreen::cast::ReceiverSession> receiver_session_; + base::OneShotTimer init_timeout_timer_; - bool initialized_called_ = false; + bool is_initialized_ = false; CastStreamingSession::Client* const client_; std::unique_ptr<openscreen::cast::Receiver::Consumer> audio_consumer_; std::unique_ptr<openscreen::cast::Receiver::Consumer> video_consumer_;
diff --git a/fuchsia/cast_streaming/stream_consumer.cc b/fuchsia/cast_streaming/stream_consumer.cc index 353ac52..ff2a53f 100644 --- a/fuchsia/cast_streaming/stream_consumer.cc +++ b/fuchsia/cast_streaming/stream_consumer.cc
@@ -10,9 +10,17 @@ namespace cast_streaming { +namespace { + +// Timeout to stop the Session when no data is received. +constexpr base::TimeDelta kNoDataTimeout = base::TimeDelta::FromSeconds(10); + +} // namespace + StreamConsumer::StreamConsumer(openscreen::cast::Receiver* receiver, mojo::ScopedDataPipeProducerHandle data_pipe, - FrameReceivedCB frame_received_cb) + FrameReceivedCB frame_received_cb, + base::OnceClosure on_timeout) : receiver_(receiver), data_pipe_(std::move(data_pipe)), frame_received_cb_(std::move(frame_received_cb)), @@ -27,7 +35,10 @@ base::Unretained(this))); if (result != MOJO_RESULT_OK) { CloseDataPipeOnError(); + return; } + + data_timeout_timer_.Start(FROM_HERE, kNoDataTimeout, std::move(on_timeout)); } StreamConsumer::~StreamConsumer() { @@ -39,6 +50,7 @@ receiver_->SetConsumer(nullptr); pipe_watcher_.Cancel(); data_pipe_.reset(); + data_timeout_timer_.Stop(); } void StreamConsumer::OnPipeWritable(MojoResult result) { @@ -72,6 +84,7 @@ void StreamConsumer::OnFramesReady(int next_frame_buffer_size) { DCHECK(data_pipe_); + data_timeout_timer_.Reset(); if (pending_buffer_remaining_bytes_ != 0) { // There already is a pending frame. Ignore this one for now.
diff --git a/fuchsia/cast_streaming/stream_consumer.h b/fuchsia/cast_streaming/stream_consumer.h index eef5f14b..0fc3ffd 100644 --- a/fuchsia/cast_streaming/stream_consumer.h +++ b/fuchsia/cast_streaming/stream_consumer.h
@@ -8,6 +8,7 @@ #include <fuchsia/media/cpp/fidl.h> #include "base/callback.h" +#include "base/timer/timer.h" #include "media/mojo/mojom/media_types.mojom.h" #include "mojo/public/cpp/system/data_pipe.h" #include "mojo/public/cpp/system/simple_watcher.h" @@ -33,9 +34,11 @@ // |receiver| sends frames to this object. It must outlive this object. // |frame_received_cb| is called on every new frame, after a new frame has // been written to |data_pipe|. On error, |data_pipe| will be closed. + // If no data is received for 10 seconds, |on_timeout| will be closed. StreamConsumer(openscreen::cast::Receiver* receiver, mojo::ScopedDataPipeProducerHandle data_pipe, - FrameReceivedCB frame_received_cb); + FrameReceivedCB frame_received_cb, + base::OnceClosure on_timeout); ~StreamConsumer() final; StreamConsumer(const StreamConsumer&) = delete; @@ -70,6 +73,9 @@ // Remaining bytes to write from |pending_buffer_| to |data_pipe_|. size_t pending_buffer_remaining_bytes_ = 0; + + // Timer to trigger connection closure if no data is received for 10 seconds. + base::OneShotTimer data_timeout_timer_; }; } // namespace cast_streaming
diff --git a/fuchsia/engine/browser/cast_streaming_session_client.cc b/fuchsia/engine/browser/cast_streaming_session_client.cc index 5b022f9..5c0508a 100644 --- a/fuchsia/engine/browser/cast_streaming_session_client.cc +++ b/fuchsia/engine/browser/cast_streaming_session_client.cc
@@ -89,6 +89,13 @@ // Tear down the Mojo connection. cast_streaming_receiver_.reset(); + + // Tear down all remaining Mojo objects if needed. This is necessary if the + // Cast Streaming Session ending was initiated by the receiver component. + if (audio_remote_) + audio_remote_.reset(); + if (video_remote_) + video_remote_.reset(); } void CastStreamingSessionClient::OnMojoDisconnect() {
diff --git a/fuchsia/engine/browser/content_directory_browsertest.cc b/fuchsia/engine/browser/content_directory_browsertest.cc index aae0ab1..59906c8 100644 --- a/fuchsia/engine/browser/content_directory_browsertest.cc +++ b/fuchsia/engine/browser/content_directory_browsertest.cc
@@ -83,13 +83,13 @@ provider.set_name("testdata"); base::FilePath pkg_path; base::PathService::Get(base::DIR_ASSETS, &pkg_path); - provider.set_directory(base::fuchsia::OpenDirectory( + provider.set_directory(base::OpenDirectoryHandle( pkg_path.AppendASCII("fuchsia/engine/test/data"))); providers.emplace_back(std::move(provider)); provider = {}; provider.set_name("alternate"); - provider.set_directory(base::fuchsia::OpenDirectory( + provider.set_directory(base::OpenDirectoryHandle( pkg_path.AppendASCII("fuchsia/engine/test/data"))); providers.emplace_back(std::move(provider));
diff --git a/fuchsia/engine/context_provider_impl_unittest.cc b/fuchsia/engine/context_provider_impl_unittest.cc index 27dea37..b395265 100644 --- a/fuchsia/engine/context_provider_impl_unittest.cc +++ b/fuchsia/engine/context_provider_impl_unittest.cc
@@ -104,7 +104,7 @@ fuchsia::web::CreateContextParams BuildCreateContextParams() { fuchsia::web::CreateContextParams output; zx_status_t result = fdio_service_connect( - base::fuchsia::kServiceDirectoryPath, + base::kServiceDirectoryPath, output.mutable_service_directory()->NewRequest().TakeChannel().release()); ZX_CHECK(result == ZX_OK, result) << "Failed to open /svc"; return output; @@ -113,7 +113,7 @@ fidl::InterfaceHandle<fuchsia::io::Directory> OpenCacheDirectory() { fidl::InterfaceHandle<fuchsia::io::Directory> cache_handle; zx_status_t result = - fdio_service_connect(base::fuchsia::kPersistedCacheDirectoryPath, + fdio_service_connect(base::kPersistedCacheDirectoryPath, cache_handle.NewRequest().TakeChannel().release()); ZX_CHECK(result == ZX_OK, result) << "Failed to open /cache"; return cache_handle; @@ -350,7 +350,7 @@ // Pass a handle data dir to the context. create_params.set_data_directory( - base::fuchsia::OpenDirectory(profile_temp_dir.GetPath())); + base::OpenDirectoryHandle(profile_temp_dir.GetPath())); provider_ptr_->Create(std::move(create_params), context.NewRequest()); @@ -370,8 +370,7 @@ // Pass in a handle to a file instead of a directory. CHECK(base::CreateTemporaryFile(&temp_file_path)); - create_params.set_data_directory( - base::fuchsia::OpenDirectory(temp_file_path)); + create_params.set_data_directory(base::OpenDirectoryHandle(temp_file_path)); provider_ptr_->Create(std::move(create_params), context.NewRequest());
diff --git a/fuchsia/engine/renderer/cast_streaming_demuxer.cc b/fuchsia/engine/renderer/cast_streaming_demuxer.cc index dc8413ca..2f7bc6de 100644 --- a/fuchsia/engine/renderer/cast_streaming_demuxer.cc +++ b/fuchsia/engine/renderer/cast_streaming_demuxer.cc
@@ -63,7 +63,7 @@ return; if (current_buffer_->end_of_stream()) { - std::move(pending_read_cb_).Run(Status::kAborted, nullptr); + std::move(pending_read_cb_).Run(Status::kError, nullptr); return; } @@ -198,7 +198,6 @@ CastStreamingDemuxer::~CastStreamingDemuxer() { DVLOG(1) << __func__; - DCHECK(media_task_runner_->BelongsToCurrentThread()); if (was_initialization_successful_) { original_task_runner_->PostTask(
diff --git a/fuchsia/engine/test/web_engine_shell.cc b/fuchsia/engine/test/web_engine_shell.cc index 1e77c90b..a2d06f69 100644 --- a/fuchsia/engine/test/web_engine_shell.cc +++ b/fuchsia/engine/test/web_engine_shell.cc
@@ -156,7 +156,7 @@ fuchsia::web::ContentDirectoryProvider content_directory; base::FilePath pkg_path; base::PathService::Get(base::DIR_ASSETS, &pkg_path); - content_directory.set_directory(base::fuchsia::OpenDirectory( + content_directory.set_directory(base::OpenDirectoryHandle( pkg_path.AppendASCII("fuchsia/engine/test/shell_data"))); content_directory.set_name("shell-data"); std::vector<fuchsia::web::ContentDirectoryProvider> content_directories; @@ -168,8 +168,8 @@ // embedder application. By passing a handle to this process' service // directory to the ContextProvider, we are allowing the Context access to the // same set of services available to this application. - create_context_params.set_service_directory(base::fuchsia::OpenDirectory( - base::FilePath(base::fuchsia::kServiceDirectoryPath))); + create_context_params.set_service_directory( + base::OpenDirectoryHandle(base::FilePath(base::kServiceDirectoryPath))); // Enable other WebEngine features. fuchsia::web::ContextFeatureFlags features = @@ -188,12 +188,11 @@ // DRM services require cdm_data_directory to be populated, so create a // directory under /data and use that as the cdm_data_directory. base::FilePath cdm_data_path = - base::FilePath(base::fuchsia::kPersistedDataDirectoryPath) - .Append("cdm_data"); + base::FilePath(base::kPersistedDataDirectoryPath).Append("cdm_data"); base::File::Error error; CHECK(base::CreateDirectoryAndGetError(cdm_data_path, &error)) << error; create_context_params.set_cdm_data_directory( - base::fuchsia::OpenDirectory(cdm_data_path)); + base::OpenDirectoryHandle(cdm_data_path)); CHECK(create_context_params.cdm_data_directory()); base::RunLoop run_loop;
diff --git a/fuchsia/engine/web_engine_debug_integration_test.cc b/fuchsia/engine/web_engine_debug_integration_test.cc index cda82e7..0576bf5 100644 --- a/fuchsia/engine/web_engine_debug_integration_test.cc +++ b/fuchsia/engine/web_engine_debug_integration_test.cc
@@ -88,7 +88,7 @@ ASSERT_FALSE(web_engine_path.empty()); debug_dir_ = std::make_unique<sys::ServiceDirectory>( - base::fuchsia::OpenDirectory(web_engine_path.Append("out/debug"))); + base::OpenDirectoryHandle(web_engine_path.Append("out/debug"))); debug_dir_->Connect(debug_.NewRequest()); // Attach the DevToolsListener. EnableDevTools has an acknowledgement @@ -126,8 +126,8 @@ UserModeDebugging user_mode_debugging, std::string url) { // Create a Context, a Frame and navigate it to |url|. - auto directory = base::fuchsia::OpenDirectory( - base::FilePath(base::fuchsia::kServiceDirectoryPath)); + auto directory = + base::OpenDirectoryHandle(base::FilePath(base::kServiceDirectoryPath)); if (!directory.is_valid()) return;
diff --git a/fuchsia/engine/web_engine_integration_test_base.cc b/fuchsia/engine/web_engine_integration_test_base.cc index 2b1e1f0..1f69f2d 100644 --- a/fuchsia/engine/web_engine_integration_test_base.cc +++ b/fuchsia/engine/web_engine_integration_test_base.cc
@@ -35,7 +35,7 @@ provider.set_name("testdata"); base::FilePath pkg_path; CHECK(base::PathService::Get(base::DIR_ASSETS, &pkg_path)); - provider.set_directory(base::fuchsia::OpenDirectory( + provider.set_directory(base::OpenDirectoryHandle( pkg_path.AppendASCII("fuchsia/engine/test/data"))); return provider; } @@ -51,8 +51,8 @@ fuchsia::web::CreateContextParams WebEngineIntegrationTestBase::DefaultContextParams() const { fuchsia::web::CreateContextParams create_params; - auto directory = base::fuchsia::OpenDirectory( - base::FilePath(base::fuchsia::kServiceDirectoryPath)); + auto directory = + base::OpenDirectoryHandle(base::FilePath(base::kServiceDirectoryPath)); EXPECT_TRUE(directory.is_valid()); create_params.set_service_directory(std::move(directory)); return create_params; @@ -66,7 +66,7 @@ provider.set_name("testdata"); base::FilePath pkg_path; CHECK(base::PathService::Get(base::DIR_ASSETS, &pkg_path)); - provider.set_directory(base::fuchsia::OpenDirectory( + provider.set_directory(base::OpenDirectoryHandle( pkg_path.AppendASCII("fuchsia/engine/test/data"))); create_params.mutable_content_directories()->emplace_back(
diff --git a/fuchsia/runners/cast/cast_runner.cc b/fuchsia/runners/cast/cast_runner.cc index af4f3a3..d10501e 100644 --- a/fuchsia/runners/cast/cast_runner.cc +++ b/fuchsia/runners/cast/cast_runner.cc
@@ -218,8 +218,8 @@ // TODO(b/154204041) Migrate to using persistent data, and specifying an // explicit quota for CDM storage. - params.set_cdm_data_directory(base::fuchsia::OpenDirectory( - base::FilePath(base::fuchsia::kPersistedCacheDirectoryPath))); + params.set_cdm_data_directory(base::OpenDirectoryHandle( + base::FilePath(base::kPersistedCacheDirectoryPath))); CHECK(params.cdm_data_directory()); const char kCastPlayreadyKeySystem[] = "com.chromecast.playready";
diff --git a/fuchsia/runners/cast/cast_runner_integration_test.cc b/fuchsia/runners/cast/cast_runner_integration_test.cc index ee1b7563..3a64dc04 100644 --- a/fuchsia/runners/cast/cast_runner_integration_test.cc +++ b/fuchsia/runners/cast/cast_runner_integration_test.cc
@@ -349,7 +349,7 @@ provider.set_name("testdata"); base::FilePath pkg_path; CHECK(base::PathService::Get(base::DIR_ASSETS, &pkg_path)); - provider.set_directory(base::fuchsia::OpenDirectory( + provider.set_directory(base::OpenDirectoryHandle( pkg_path.AppendASCII("fuchsia/runners/cast/testdata"))); std::vector<fuchsia::web::ContentDirectoryProvider> providers; providers.emplace_back(std::move(provider)); @@ -405,8 +405,7 @@ std::make_unique<sys::ServiceDirectory>(std::move(svc_directory)); // Place the ServiceDirectory in the |flat_namespace|. - startup_info.flat_namespace.paths.emplace_back( - base::fuchsia::kServiceDirectoryPath); + startup_info.flat_namespace.paths.emplace_back(base::kServiceDirectoryPath); startup_info.flat_namespace.directories.emplace_back( directory.TakeChannel());
diff --git a/fuchsia/runners/cast/cast_streaming.cc b/fuchsia/runners/cast/cast_streaming.cc index 88754ed..3f6156b 100644 --- a/fuchsia/runners/cast/cast_streaming.cc +++ b/fuchsia/runners/cast/cast_streaming.cc
@@ -22,7 +22,7 @@ fuchsia::web::ContentDirectoryProvider content_directory; content_directory.set_directory( - base::fuchsia::OpenDirectory(pkg_path.AppendASCII(kCastDataDirectory))); + base::OpenDirectoryHandle(pkg_path.AppendASCII(kCastDataDirectory))); content_directory.set_name(kCastStreamingContentDirectoryName); std::vector<fuchsia::web::ContentDirectoryProvider> content_directories; content_directories.emplace_back(std::move(content_directory));
diff --git a/fuchsia/runners/cast/data/receiver.html b/fuchsia/runners/cast/data/receiver.html index 29a914e1..faf7eb4 100644 --- a/fuchsia/runners/cast/data/receiver.html +++ b/fuchsia/runners/cast/data/receiver.html
@@ -17,7 +17,7 @@ </head> <body> - <video src="data:cast_streaming_receiver" autoplay> + <video src="data:cast_streaming_receiver"> <script> // The Cast Streaming session must stop when the stream is no longer visible. crbug.com/1111886 @@ -27,10 +27,10 @@ } }); - // TODO(crbug.com/1087528): This should not be necessary. Figure out why - // autoplay is not enough here. var video = document.querySelector('video'); - video.play(); + video.addEventListener('ended', window.close); + video.addEventListener('error', window.close); + video.play().catch(window.close); </script> </body> </html>
diff --git a/fuchsia/runners/web/main.cc b/fuchsia/runners/web/main.cc index af1329c..477360c 100644 --- a/fuchsia/runners/web/main.cc +++ b/fuchsia/runners/web/main.cc
@@ -29,23 +29,22 @@ fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER | fuchsia::web::ContextFeatureFlags::WIDEVINE_CDM); - create_context_params.set_service_directory(base::fuchsia::OpenDirectory( - base::FilePath(base::fuchsia::kServiceDirectoryPath))); + create_context_params.set_service_directory( + base::OpenDirectoryHandle(base::FilePath(base::kServiceDirectoryPath))); CHECK(create_context_params.service_directory()); - create_context_params.set_data_directory(base::fuchsia::OpenDirectory( - base::FilePath(base::fuchsia::kPersistedDataDirectoryPath))); + create_context_params.set_data_directory(base::OpenDirectoryHandle( + base::FilePath(base::kPersistedDataDirectoryPath))); CHECK(create_context_params.data_directory()); // DRM services require cdm_data_directory to be populated, so create a // directory under /data and use that as the cdm_data_directory. base::FilePath cdm_data_path = - base::FilePath(base::fuchsia::kPersistedDataDirectoryPath) - .Append("cdm_data"); + base::FilePath(base::kPersistedDataDirectoryPath).Append("cdm_data"); base::File::Error error; CHECK(base::CreateDirectoryAndGetError(cdm_data_path, &error)) << error; create_context_params.set_cdm_data_directory( - base::fuchsia::OpenDirectory(cdm_data_path)); + base::OpenDirectoryHandle(cdm_data_path)); CHECK(create_context_params.cdm_data_directory()); #if BUILDFLAG(WEB_RUNNER_REMOTE_DEBUGGING_PORT) != 0
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 9eae539..95df932 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -4971,7 +4971,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -5004,7 +5004,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -5037,7 +5037,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -5348,7 +5348,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -6077,7 +6077,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -6108,7 +6108,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -6633,7 +6633,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -7657,7 +7657,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -7804,7 +7804,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -8674,7 +8674,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -8706,7 +8706,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -9424,7 +9424,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -9457,7 +9457,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -10386,7 +10386,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -10564,7 +10564,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -10597,7 +10597,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -10630,7 +10630,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -10663,7 +10663,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -10785,7 +10785,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -10883,7 +10883,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -10918,7 +10918,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -10953,7 +10953,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11019,7 +11019,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11085,7 +11085,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11120,7 +11120,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11155,7 +11155,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11190,7 +11190,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11225,7 +11225,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11260,7 +11260,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11293,7 +11293,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11384,7 +11384,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11446,7 +11446,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11479,7 +11479,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11512,7 +11512,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11544,7 +11544,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11576,7 +11576,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11609,7 +11609,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11642,7 +11642,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11675,7 +11675,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11766,7 +11766,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11799,7 +11799,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11832,7 +11832,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11865,7 +11865,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11927,7 +11927,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -11960,7 +11960,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12022,7 +12022,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12141,7 +12141,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12406,7 +12406,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12469,7 +12469,7 @@ experimental: YES experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12503,7 +12503,7 @@ experimental: YES experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12537,7 +12537,7 @@ experimental: YES experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12682,7 +12682,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12714,7 +12714,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12800,7 +12800,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12833,7 +12833,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12892,7 +12892,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12925,7 +12925,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12958,7 +12958,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -12991,7 +12991,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -13024,7 +13024,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -13057,7 +13057,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -13090,7 +13090,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -13152,7 +13152,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -13353,7 +13353,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -13385,7 +13385,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -13416,7 +13416,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -13652,7 +13652,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -13685,7 +13685,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -13717,7 +13717,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -13805,7 +13805,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true @@ -13866,7 +13866,7 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { key: "chromium.resultdb.result_sink" - value: 30 + value: 0 } resultdb { enable: true
diff --git a/infra/config/lib/ci.star b/infra/config/lib/ci.star index 5be49c0..a6a5ad1 100644 --- a/infra/config/lib/ci.star +++ b/infra/config/lib/ci.star
@@ -693,7 +693,7 @@ # TODO(crbug.com/1108016): Move this kwarg to ci.builder(), after # ResultSink and result_adapter is confirmed to work. experiments = { - "chromium.resultdb.result_sink": 30, + "chromium.resultdb.result_sink": 0, }, **kwargs )
diff --git a/ios/chrome/browser/ui/settings/password/BUILD.gn b/ios/chrome/browser/ui/settings/password/BUILD.gn index 0ac4f31..3f25afa 100644 --- a/ios/chrome/browser/ui/settings/password/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/BUILD.gn
@@ -233,6 +233,7 @@ ":password_constants", "//base:base", "//base/test:test_support", + "//components/password_manager/core/common", "//components/strings:components_strings_grit", "//ios/chrome/app/strings:ios_strings_grit", "//ios/chrome/browser/ui/settings:settings_root_constants",
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.mm index c74c413..e1901d4 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.mm
@@ -9,4 +9,4 @@ #endif NSString* const kPasswordDetailsViewControllerId = - @"kPasswordDetailsViewControllerId"; + @"PasswordDetailsTableViewId";
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm index 0ae4468b..3c89c5c 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
@@ -210,6 +210,8 @@ item.identifyingIcon = [[UIImage imageNamed:image] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; item.identifyingIconEnabled = YES; + item.identifyingIconAccessibilityLabel = + l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_SHOW_BUTTON); } return item; }
diff --git a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm index 00d88eb..ba4d7ced 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm
@@ -8,7 +8,9 @@ #include "base/callback.h" #include "base/ios/ios_util.h" +#include "base/test/scoped_feature_list.h" #include "base/time/time.h" +#include "components/password_manager/core/common/password_manager_features.h" #include "components/strings/grit/components_strings.h" #include "ios/chrome/browser/ui/settings/password/passwords_settings_app_interface.h" #import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h" @@ -46,6 +48,7 @@ // go here, the rest into the unittest. using chrome_test_util::ButtonWithAccessibilityLabel; +using chrome_test_util::ButtonWithAccessibilityLabelId; using chrome_test_util::NavigationBarDoneButton; using chrome_test_util::SettingsDoneButton; using chrome_test_util::SettingsMenuBackButton; @@ -58,6 +61,11 @@ // it too high could result in scrolling way past the searched element. constexpr int kScrollAmount = 150; +NSString* GetTextFieldForID(int category_id) { + return [NSString + stringWithFormat:@"%@_textField", l10n_util::GetNSString(category_id)]; +} + // Returns the GREYElementInteraction* for the item on the password list with // the given |matcher|. It scrolls in |direction| if necessary to ensure that // the matched item is interactable. @@ -84,22 +92,12 @@ id<GREYMatcher> matcher) { return [[EarlGrey selectElementWithMatcher:grey_allOf(matcher, grey_interactable(), nil)] - usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, - kScrollAmount) + usingSearchAction:grey_scrollToContentEdge(kGREYContentEdgeTop) onElementWithMatcher:grey_accessibilityID(kPasswordDetailsTableViewId)]; } // Returns the GREYElementInteraction* for the item on the deletion alert // identified with the given |matcher|. -GREYElementInteraction* GetInteractionForPasswordDetailDeletionAlert( - id<GREYMatcher> matcher) { - return [[EarlGrey - selectElementWithMatcher:grey_allOf(matcher, grey_interactable(), nil)] - inRoot:grey_accessibilityID(kPasswordDetailsDeletionAlertViewId)]; -} - -// Returns the GREYElementInteraction* for the item on the deletion alert -// identified with the given |matcher|. GREYElementInteraction* GetInteractionForPasswordsExportConfirmAlert( id<GREYMatcher> matcher) { return [[EarlGrey @@ -120,34 +118,6 @@ return grey_accessibilityID(kPasswordsSearchBarId); } -id<GREYMatcher> SiteHeader() { - return grey_allOf( - grey_accessibilityLabel( - l10n_util::GetNSString(IDS_IOS_SHOW_PASSWORD_VIEW_SITE)), - grey_accessibilityTrait(UIAccessibilityTraitHeader), nullptr); -} - -id<GREYMatcher> UsernameHeader() { - return grey_allOf( - grey_accessibilityLabel( - l10n_util::GetNSString(IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME)), - grey_accessibilityTrait(UIAccessibilityTraitHeader), nullptr); -} - -id<GREYMatcher> PasswordHeader() { - return grey_allOf( - grey_accessibilityLabel( - l10n_util::GetNSString(IDS_IOS_SHOW_PASSWORD_VIEW_PASSWORD)), - grey_accessibilityTrait(UIAccessibilityTraitHeader), nullptr); -} - -id<GREYMatcher> FederationHeader() { - return grey_allOf( - grey_accessibilityLabel( - l10n_util::GetNSString(IDS_IOS_SHOW_PASSWORD_VIEW_FEDERATION)), - grey_accessibilityTrait(UIAccessibilityTraitHeader), nullptr); -} - GREYLayoutConstraint* Below() { return [GREYLayoutConstraint layoutConstraintWithAttribute:kGREYLayoutAttributeTop @@ -158,39 +128,24 @@ } // Matcher for the Copy site button in Password Details view. -id<GREYMatcher> CopySiteButton() { +id<GREYMatcher> PasswordDetailWebsite() { return grey_allOf( - ButtonWithAccessibilityLabel( - [NSString stringWithFormat:@"%@: %@", - l10n_util::GetNSString( - IDS_IOS_SHOW_PASSWORD_VIEW_SITE), - l10n_util::GetNSString( - IDS_IOS_SETTINGS_SITE_COPY_BUTTON)]), - grey_interactable(), nullptr); + grey_accessibilityID(GetTextFieldForID(IDS_IOS_SHOW_PASSWORD_VIEW_SITE)), + grey_kindOfClassName(@"UITextField"), nil); } // Matcher for the Copy username button in Password Details view. -id<GREYMatcher> CopyUsernameButton() { - return grey_allOf( - ButtonWithAccessibilityLabel([NSString - stringWithFormat:@"%@: %@", - l10n_util::GetNSString( - IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME), - l10n_util::GetNSString( - IDS_IOS_SETTINGS_USERNAME_COPY_BUTTON)]), - grey_interactable(), nullptr); +id<GREYMatcher> PasswordDetailUsername() { + return grey_allOf(grey_accessibilityID( + GetTextFieldForID(IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME)), + grey_kindOfClassName(@"UITextField"), nil); } // Matcher for the Copy password button in Password Details view. -id<GREYMatcher> CopyPasswordButton() { - return grey_allOf( - ButtonWithAccessibilityLabel([NSString - stringWithFormat:@"%@: %@", - l10n_util::GetNSString( - IDS_IOS_SHOW_PASSWORD_VIEW_PASSWORD), - l10n_util::GetNSString( - IDS_IOS_SETTINGS_PASSWORD_COPY_BUTTON)]), - grey_interactable(), nullptr); +id<GREYMatcher> PasswordDetailPassword() { + return grey_allOf(grey_accessibilityID( + GetTextFieldForID(IDS_IOS_SHOW_PASSWORD_VIEW_PASSWORD)), + grey_kindOfClassName(@"UITextField"), nil); } // Matcher for the Show password button in Password Details view. @@ -202,8 +157,16 @@ // Matcher for the Delete button in Password Details view. id<GREYMatcher> DeleteButton() { + return grey_allOf( + ButtonWithAccessibilityLabelId(IDS_IOS_SETTINGS_TOOLBAR_DELETE), + grey_not(grey_accessibilityTrait(UIAccessibilityTraitNotEnabled)), + nullptr); +} + +// Matcher for the Delete button in Confirmation Alert for password deletion. +id<GREYMatcher> DeleteConfirmationButton() { return grey_allOf(ButtonWithAccessibilityLabel(l10n_util::GetNSString( - IDS_IOS_SETTINGS_PASSWORD_DELETE_BUTTON)), + IDS_IOS_CONFIRM_PASSWORD_DELETION)), grey_interactable(), nullptr); } @@ -300,10 +263,24 @@ performAction:grey_tap()]; } +void CopyPasswordDetailWithID(int detail_id) { + [GetInteractionForPasswordDetailItem(grey_allOf( + grey_accessibilityID(GetTextFieldForID(detail_id)), + grey_kindOfClassName(@"UITextField"), nil)) performAction:grey_tap()]; + + // Tap the context menu item for copying. + [[EarlGrey selectElementWithMatcher:PopUpMenuItemWithLabel( + IDS_IOS_SETTINGS_SITE_COPY_MENU_ITEM)] + performAction:grey_tap()]; +} + } // namespace // Various tests for the Save Passwords section of the settings. -@interface PasswordsSettingsTestCase : ChromeTestCase +@interface PasswordsSettingsTestCase : ChromeTestCase { + base::test::ScopedFeatureList _featureList; +} + @end @implementation PasswordsSettingsTestCase @@ -319,6 +296,18 @@ [super tearDown]; } +- (AppLaunchConfiguration)appConfigurationForTestCase { + AppLaunchConfiguration config; + + // Password Check Feature is enabled for all tests. This is done because it + // is inefficient to use ensureAppLaunchedWithConfiguration for each test. + // This should be removed once test config is modified. + // TODO(crbug.com/1075494): Remove this once feature is launched. + config.features_enabled.push_back(password_manager::features::kPasswordCheck); + + return config; +} + // Verifies the UI elements are accessible on the Passwords page. - (void)testAccessibilityOnPasswords { // Saving a form is needed for using the "password details" view. @@ -356,13 +345,12 @@ [GetInteractionForPasswordEntry(@"example.com, concrete username") performAction:grey_tap()]; + // Check the snackbar in case of successful reauthentication. [PasswordSettingsAppInterface setUpMockReauthenticationModule]; [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: ReauthenticationResult::kSuccess]; - // Check the snackbar in case of successful reauthentication. - [GetInteractionForPasswordDetailItem(CopyPasswordButton()) - performAction:grey_tap()]; + CopyPasswordDetailWithID(IDS_IOS_SHOW_PASSWORD_VIEW_PASSWORD); NSString* snackbarLabel = l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_WAS_COPIED_MESSAGE); @@ -373,8 +361,8 @@ // Check the snackbar in case of failed reauthentication. [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: ReauthenticationResult::kFailure]; - [GetInteractionForPasswordDetailItem(CopyPasswordButton()) - performAction:grey_tap()]; + + CopyPasswordDetailWithID(IDS_IOS_SHOW_PASSWORD_VIEW_PASSWORD); snackbarLabel = l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_WAS_NOT_COPIED_MESSAGE); @@ -392,7 +380,7 @@ // Checks that an attempt to show a password provides an appropriate feedback // when reauthentication succeeds. -- (void)testShowPasswordToastAuthSucceeded { +- (void)testShowPasswordAuthSucceeded { // Saving a form is needed for using the "password details" view. SaveExamplePasswordForm(); @@ -405,14 +393,12 @@ [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: ReauthenticationResult::kSuccess]; - // Check the snackbar in case of successful reauthentication. [GetInteractionForPasswordDetailItem(ShowPasswordButton()) performAction:grey_tap()]; - // Check that the password is displayed. - [[EarlGrey - selectElementWithMatcher:grey_accessibilityLabel(@"concrete password")] - assertWithMatcher:grey_sufficientlyVisible()]; + // Ensure that password is shown. + [GetInteractionForPasswordDetailItem(grey_textFieldValue( + @"concrete password")) assertWithMatcher:grey_notNil()]; [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] performAction:grey_tap()]; @@ -442,8 +428,7 @@ performAction:grey_tap()]; // Check that the password is not displayed. - [[EarlGrey - selectElementWithMatcher:grey_accessibilityLabel(@"concrete password")] + [[EarlGrey selectElementWithMatcher:grey_textFieldValue(@"concrete password")] assertWithMatcher:grey_nil()]; // Note that there is supposed to be no message (cf. the case of the copy @@ -468,8 +453,7 @@ [GetInteractionForPasswordEntry(@"example.com, concrete username") performAction:grey_tap()]; - [GetInteractionForPasswordDetailItem(CopyUsernameButton()) - performAction:grey_tap()]; + CopyPasswordDetailWithID(IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME); NSString* snackbarLabel = l10n_util::GetNSString(IDS_IOS_SETTINGS_USERNAME_WAS_COPIED_MESSAGE); // The tap checks the existence of the snackbar and also closes it. @@ -494,8 +478,8 @@ [GetInteractionForPasswordEntry(@"example.com, concrete username") performAction:grey_tap()]; - [GetInteractionForPasswordDetailItem(CopySiteButton()) - performAction:grey_tap()]; + CopyPasswordDetailWithID(IDS_IOS_SHOW_PASSWORD_VIEW_SITE); + NSString* snackbarLabel = l10n_util::GetNSString(IDS_IOS_SETTINGS_SITE_WAS_COPIED_MESSAGE); // The tap checks the existence of the snackbar and also closes it. @@ -521,11 +505,16 @@ [GetInteractionForPasswordEntry(@"example.com, concrete username") performAction:grey_tap()]; - [GetInteractionForPasswordDetailItem(DeleteButton()) + [PasswordSettingsAppInterface setUpMockReauthenticationModule]; + [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: + ReauthenticationResult::kSuccess]; + + [[EarlGrey selectElementWithMatcher:NavigationBarEditButton()] performAction:grey_tap()]; - [GetInteractionForPasswordDetailDeletionAlert(ButtonWithAccessibilityLabel( - l10n_util::GetNSString(IDS_IOS_CONFIRM_PASSWORD_DELETION))) + [[EarlGrey selectElementWithMatcher:DeleteButton()] performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:DeleteConfirmationButton()] performAction:grey_tap()]; // Wait until the alert and the detail view are dismissed. @@ -576,11 +565,16 @@ [GetInteractionForPasswordEntry(@"example.com, concrete username") performAction:grey_tap()]; - [GetInteractionForPasswordDetailItem(DeleteButton()) + [PasswordSettingsAppInterface setUpMockReauthenticationModule]; + [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: + ReauthenticationResult::kSuccess]; + + [[EarlGrey selectElementWithMatcher:NavigationBarEditButton()] performAction:grey_tap()]; - [GetInteractionForPasswordDetailDeletionAlert(ButtonWithAccessibilityLabel( - l10n_util::GetNSString(IDS_IOS_CONFIRM_PASSWORD_DELETION))) + [[EarlGrey selectElementWithMatcher:DeleteButton()] performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:DeleteConfirmationButton()] performAction:grey_tap()]; // Wait until the alert and the detail view are dismissed. @@ -623,11 +617,12 @@ [GetInteractionForPasswordEntry(@"blocked.com") performAction:grey_tap()]; - [GetInteractionForPasswordDetailItem(DeleteButton()) + [[EarlGrey selectElementWithMatcher:NavigationBarEditButton()] performAction:grey_tap()]; - [GetInteractionForPasswordDetailDeletionAlert(ButtonWithAccessibilityLabel( - l10n_util::GetNSString(IDS_IOS_CONFIRM_PASSWORD_DELETION))) + [[EarlGrey selectElementWithMatcher:DeleteButton()] performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:DeleteConfirmationButton()] performAction:grey_tap()]; // Wait until the alert and the detail view are dismissed. @@ -671,11 +666,17 @@ [GetInteractionForPasswordEntry(@"example.com, concrete username") performAction:grey_tap()]; - [GetInteractionForPasswordDetailItem(DeleteButton()) + [PasswordSettingsAppInterface setUpMockReauthenticationModule]; + [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: + ReauthenticationResult::kSuccess]; + + [[EarlGrey selectElementWithMatcher:NavigationBarEditButton()] performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:DeleteButton()] performAction:grey_tap()]; + // Tap the alert's Cancel button to cancel. - if (base::ios::IsRunningOnOrLater(13, 2, 0) && [ChromeEarlGrey isIPadIdiom]) { + if ([ChromeEarlGrey isIPadIdiom]) { [[EarlGrey selectElementWithMatcher:grey_accessibilityID( kPasswordDetailsTableViewId)] performAction:grey_tap()]; @@ -689,10 +690,10 @@ performAction:grey_tap()]; } - // Check that the current view is still the detail view, by locating the Copy - // button. - [[EarlGrey selectElementWithMatcher:CopyPasswordButton()] - assertWithMatcher:grey_sufficientlyVisible()]; + // Check that the current view is still the detail view. + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + kPasswordDetailsTableViewId)] + assertWithMatcher:grey_notNil()]; // Verify that the deletion did not happen. GREYAssertEqual(1u, [PasswordSettingsAppInterface passwordStoreResultsCount], @@ -732,7 +733,7 @@ // Check that the current view is not the detail view, by failing to locate // the Copy button. - [[EarlGrey selectElementWithMatcher:CopyPasswordButton()] + [[EarlGrey selectElementWithMatcher:PasswordDetailPassword()] assertWithMatcher:grey_nil()]; [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] @@ -741,77 +742,6 @@ performAction:grey_tap()]; } -// Checks that attempts to copy the site via the context menu item provide an -// appropriate feedback. -- (void)testCopySiteMenuItem { - // Saving a form is needed for using the "password details" view. - SaveExamplePasswordForm(); - - OpenPasswordSettings(); - - [GetInteractionForPasswordEntry(@"example.com, concrete username") - performAction:grey_tap()]; - - // Tap the site cell to display the context menu. - [GetInteractionForPasswordDetailItem(grey_accessibilityLabel( - @"https://example.com/")) performAction:grey_tap()]; - - // Tap the context menu item for copying. - [[EarlGrey selectElementWithMatcher:PopUpMenuItemWithLabel( - IDS_IOS_SETTINGS_SITE_COPY_MENU_ITEM)] - performAction:grey_tap()]; - - // Check the snackbar. - NSString* snackbarLabel = - l10n_util::GetNSString(IDS_IOS_SETTINGS_SITE_WAS_COPIED_MESSAGE); - // The tap checks the existence of the snackbar and also closes it. - [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(snackbarLabel)] - performAction:grey_tap()]; - - [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] - performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] - performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] - performAction:grey_tap()]; -} - -// Checks that attempts to copy the username via the context menu item provide -// an appropriate feedback. -- (void)testCopyUsernameMenuItem { - // Saving a form is needed for using the "password details" view. - SaveExamplePasswordForm(); - - OpenPasswordSettings(); - - [GetInteractionForPasswordEntry(@"example.com, concrete username") - performAction:grey_tap()]; - - // Tap the username cell to display the context menu. - [GetInteractionForPasswordDetailItem( - grey_accessibilityLabel(@"concrete username")) performAction:grey_tap()]; - - // Tap the context menu item for copying. - [[EarlGrey - selectElementWithMatcher:PopUpMenuItemWithLabel( - IDS_IOS_SETTINGS_USERNAME_COPY_MENU_ITEM)] - performAction:grey_tap()]; - - // Check the snackbar. - NSString* snackbarLabel = - l10n_util::GetNSString(IDS_IOS_SETTINGS_USERNAME_WAS_COPIED_MESSAGE); - // The tap checks the existence of the snackbar and also closes it. - [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(snackbarLabel)] - performAction:grey_tap()]; - - [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] - performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] - performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] - performAction:grey_tap()]; -} - // Checks that attempts to copy the password via the context menu item provide // an appropriate feedback. - (void)testCopyPasswordMenuItem { @@ -860,62 +790,6 @@ performAction:grey_tap()]; } -// Checks that attempts to show and hide the password via the context menu item -// provide an appropriate feedback. -- (void)testShowHidePasswordMenuItem { - if (![ChromeEarlGrey isIPadIdiom]) { - // TODO(crbug.com/1109644): Enable the test on iPhone once the bug is fixed. - EARL_GREY_TEST_DISABLED(@"Disabled for iPhone."); - } - - // Saving a form is needed for using the "password details" view. - SaveExamplePasswordForm(); - - OpenPasswordSettings(); - - [GetInteractionForPasswordEntry(@"example.com, concrete username") - performAction:grey_tap()]; - - // Tap the password cell to display the context menu. - [GetInteractionForPasswordDetailItem(grey_text(kMaskedPassword)) - performAction:grey_tap()]; - - // Make sure to capture the reauthentication module in a variable until the - // end of the test, otherwise it might get deleted too soon and break the - // functionality of copying and viewing passwords. - [PasswordSettingsAppInterface setUpMockReauthenticationModule]; - [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: - ReauthenticationResult::kSuccess]; - - // Tap the context menu item for showing. - [[EarlGrey - selectElementWithMatcher:PopUpMenuItemWithLabel( - IDS_IOS_SETTINGS_PASSWORD_SHOW_MENU_ITEM)] - performAction:grey_tap()]; - - // Tap the password cell to display the context menu again, and to check that - // the password was unmasked. - [GetInteractionForPasswordDetailItem( - grey_accessibilityLabel(@"concrete password")) performAction:grey_tap()]; - - // Tap the context menu item for hiding. - [[EarlGrey - selectElementWithMatcher:PopUpMenuItemWithLabel( - IDS_IOS_SETTINGS_PASSWORD_HIDE_MENU_ITEM)] - performAction:grey_tap()]; - - // Check that the password is masked again. - [GetInteractionForPasswordDetailItem(grey_text(kMaskedPassword)) - performAction:grey_tap()]; - - [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] - performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] - performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] - performAction:grey_tap()]; -} - // Checks that federated credentials have no password but show the federation. - (void)testFederated { GREYAssert([PasswordSettingsAppInterface @@ -929,24 +803,26 @@ [GetInteractionForPasswordEntry(@"example.com, federated username") performAction:grey_tap()]; - // Check that the Site, Username, Federation and Delete Saved Password - // sections are there. - [GetInteractionForPasswordDetailItem(SiteHeader()) - assertWithMatcher:grey_notNil()]; - [GetInteractionForPasswordDetailItem(UsernameHeader()) - assertWithMatcher:grey_notNil()]; - // For federation check both the section header and content. - [GetInteractionForPasswordDetailItem(FederationHeader()) - assertWithMatcher:grey_notNil()]; - [GetInteractionForPasswordDetailItem(grey_text(@"famous.provider.net")) - assertWithMatcher:grey_notNil()]; - [GetInteractionForPasswordDetailItem(DeleteButton()) - assertWithMatcher:grey_notNil()]; + // Check that the Site and Username are present and correct. + [[EarlGrey selectElementWithMatcher:PasswordDetailWebsite()] + assertWithMatcher:grey_textFieldValue(@"https://example.com/")]; + [[EarlGrey selectElementWithMatcher:PasswordDetailUsername()] + assertWithMatcher:grey_textFieldValue(@"federated username")]; // Check that the password is not present. - [GetInteractionForPasswordDetailItem(PasswordHeader()) + [[EarlGrey selectElementWithMatcher:PasswordDetailPassword()] assertWithMatcher:grey_nil()]; + // Check that editing doesn't require reauth. + [PasswordSettingsAppInterface setUpMockReauthenticationModule]; + [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: + ReauthenticationResult::kFailure]; + [[EarlGrey selectElementWithMatcher:NavigationBarEditButton()] + performAction:grey_tap()]; + // Ensure delete button is present after entering editing mode. + [[EarlGrey selectElementWithMatcher:DeleteButton()] + assertWithMatcher:grey_notNil()]; + [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] performAction:grey_tap()]; [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] @@ -965,44 +841,17 @@ [GetInteractionForPasswordEntry(@"example.com, concrete username") performAction:grey_tap()]; - [GetInteractionForPasswordDetailItem(SiteHeader()) - assertWithMatcher:grey_notNil()]; - id<GREYMatcher> siteCell = grey_accessibilityLabel(@"https://example.com/"); - [GetInteractionForPasswordDetailItem(siteCell) - assertWithMatcher:grey_layout(@[ Below() ], SiteHeader())]; - [GetInteractionForPasswordDetailItem(CopySiteButton()) - assertWithMatcher:grey_layout(@[ Below() ], siteCell)]; + [[EarlGrey selectElementWithMatcher:PasswordDetailWebsite()] + assertWithMatcher:grey_textFieldValue(@"https://example.com/")]; + [[EarlGrey selectElementWithMatcher:PasswordDetailUsername()] + assertWithMatcher:grey_textFieldValue(@"concrete username")]; + [[EarlGrey selectElementWithMatcher:PasswordDetailPassword()] + assertWithMatcher:grey_textFieldValue(kMaskedPassword)]; - [GetInteractionForPasswordDetailItem(UsernameHeader()) - assertWithMatcher:grey_layout(@[ Below() ], CopySiteButton())]; - id<GREYMatcher> usernameCell = grey_accessibilityLabel(@"concrete username"); - [GetInteractionForPasswordDetailItem(usernameCell) - assertWithMatcher:grey_layout(@[ Below() ], UsernameHeader())]; - [GetInteractionForPasswordDetailItem(CopyUsernameButton()) - assertWithMatcher:grey_layout(@[ Below() ], usernameCell)]; - - id<GREYMatcher> passwordHeader = - grey_allOf(PasswordHeader(), - grey_kindOfClassName(@"UITableViewHeaderFooterView"), nil); - [GetInteractionForPasswordDetailItem(passwordHeader) - assertWithMatcher:grey_layout(@[ Below() ], CopyUsernameButton())]; - id<GREYMatcher> passwordCell = grey_accessibilityLabel( - l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_HIDDEN_LABEL)); - [GetInteractionForPasswordDetailItem(passwordCell) - assertWithMatcher:grey_layout(@[ Below() ], passwordHeader)]; - [GetInteractionForPasswordDetailItem(CopyPasswordButton()) - assertWithMatcher:grey_layout(@[ Below() ], passwordCell)]; - [GetInteractionForPasswordDetailItem(ShowPasswordButton()) - assertWithMatcher:grey_layout(@[ Below() ], CopyPasswordButton())]; - - [GetInteractionForPasswordDetailItem(DeleteButton()) - assertWithMatcher:grey_layout(@[ Below() ], ShowPasswordButton())]; - - // Check that the federation block is not present. Match directly to also - // catch the case where the block would be present but not currently visible - // due to the scrolling state. - [[EarlGrey selectElementWithMatcher:FederationHeader()] - assertWithMatcher:grey_nil()]; + [GetInteractionForPasswordDetailItem(PasswordDetailPassword()) + assertWithMatcher:grey_layout(@[ Below() ], PasswordDetailUsername())]; + [GetInteractionForPasswordDetailItem(PasswordDetailUsername()) + assertWithMatcher:grey_layout(@[ Below() ], PasswordDetailWebsite())]; [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] performAction:grey_tap()]; @@ -1023,25 +872,11 @@ [GetInteractionForPasswordEntry(@"example.com") performAction:grey_tap()]; - [GetInteractionForPasswordDetailItem(SiteHeader()) - assertWithMatcher:grey_notNil()]; - id<GREYMatcher> siteCell = grey_accessibilityLabel(@"https://example.com/"); - [GetInteractionForPasswordDetailItem(siteCell) - assertWithMatcher:grey_layout(@[ Below() ], SiteHeader())]; - [GetInteractionForPasswordDetailItem(CopySiteButton()) - assertWithMatcher:grey_layout(@[ Below() ], siteCell)]; - - [GetInteractionForPasswordDetailItem(DeleteButton()) - assertWithMatcher:grey_layout(@[ Below() ], CopySiteButton())]; - - // Check that the other blocks are not present. Match directly to also catch - // the case where those blocks would be present but not currently visible due - // to the scrolling state. - [[EarlGrey selectElementWithMatcher:UsernameHeader()] + [[EarlGrey selectElementWithMatcher:PasswordDetailWebsite()] + assertWithMatcher:grey_textFieldValue(@"https://example.com/")]; + [[EarlGrey selectElementWithMatcher:PasswordDetailUsername()] assertWithMatcher:grey_nil()]; - [[EarlGrey selectElementWithMatcher:PasswordHeader()] - assertWithMatcher:grey_nil()]; - [[EarlGrey selectElementWithMatcher:FederationHeader()] + [[EarlGrey selectElementWithMatcher:PasswordDetailPassword()] assertWithMatcher:grey_nil()]; [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] @@ -1066,37 +901,16 @@ [GetInteractionForPasswordEntry(@"example.com, federated username") performAction:grey_tap()]; - [GetInteractionForPasswordDetailItem(SiteHeader()) - assertWithMatcher:grey_notNil()]; - id<GREYMatcher> siteCell = grey_accessibilityLabel(@"https://example.com/"); - [GetInteractionForPasswordDetailItem(siteCell) - assertWithMatcher:grey_layout(@[ Below() ], SiteHeader())]; - [GetInteractionForPasswordDetailItem(CopySiteButton()) - assertWithMatcher:grey_layout(@[ Below() ], siteCell)]; - - [GetInteractionForPasswordDetailItem(UsernameHeader()) - assertWithMatcher:grey_layout(@[ Below() ], CopySiteButton())]; - id<GREYMatcher> usernameCell = grey_accessibilityLabel(@"federated username"); - [GetInteractionForPasswordDetailItem(usernameCell) - assertWithMatcher:grey_layout(@[ Below() ], UsernameHeader())]; - [GetInteractionForPasswordDetailItem(CopyUsernameButton()) - assertWithMatcher:grey_layout(@[ Below() ], usernameCell)]; - - [GetInteractionForPasswordDetailItem(FederationHeader()) - assertWithMatcher:grey_layout(@[ Below() ], CopyUsernameButton())]; - id<GREYMatcher> federationCell = grey_text(@"famous.provider.net"); - [GetInteractionForPasswordDetailItem(federationCell) - assertWithMatcher:grey_layout(@[ Below() ], FederationHeader())]; - - [GetInteractionForPasswordDetailItem(DeleteButton()) - assertWithMatcher:grey_layout(@[ Below() ], federationCell)]; - - // Check that the password is not present. Match directly to also catch the - // case where the password header would be present but not currently visible - // due to the scrolling state. - [[EarlGrey selectElementWithMatcher:PasswordHeader()] + [[EarlGrey selectElementWithMatcher:PasswordDetailWebsite()] + assertWithMatcher:grey_textFieldValue(@"https://example.com/")]; + [[EarlGrey selectElementWithMatcher:PasswordDetailUsername()] + assertWithMatcher:grey_textFieldValue(@"federated username")]; + [[EarlGrey selectElementWithMatcher:PasswordDetailPassword()] assertWithMatcher:grey_nil()]; + [GetInteractionForPasswordDetailItem(PasswordDetailUsername()) + assertWithMatcher:grey_layout(@[ Below() ], PasswordDetailWebsite())]; + [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] performAction:grey_tap()]; [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] @@ -1110,15 +924,13 @@ - (void)testStoredEntriesAlwaysShown { SaveExamplePasswordForm(); - GREYAssert([PasswordSettingsAppInterface - saveExampleBlockedOrigin:@"https://blocked.com"], - @"Stored form was not found in the PasswordStore results."); - OpenPasswordSettings(); // Toggle the "Save Passwords" control off and back on and check that stored // items are still present. - constexpr BOOL kExpectedState[] = {YES, NO}; + BOOL isSwitchEnabled = + [PasswordSettingsAppInterface isCredentialsServiceEnabled]; + BOOL kExpectedState[] = {isSwitchEnabled, !isSwitchEnabled}; for (BOOL expected_state : kExpectedState) { // Toggle the switch. It is located near the top, so if not interactable, // try scrolling up. @@ -1136,8 +948,6 @@ // Check the stored items. Scroll down if needed. [GetInteractionForPasswordEntry(@"example.com, concrete username") assertWithMatcher:grey_notNil()]; - [GetInteractionForPasswordEntry(@"blocked.com") - assertWithMatcher:grey_notNil()]; } [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] @@ -1214,8 +1024,7 @@ [PasswordSettingsAppInterface setUpMockReauthenticationModule]; [PasswordSettingsAppInterface mockReauthenticationModuleCanAttempt:NO]; - [GetInteractionForPasswordDetailItem(CopyPasswordButton()) - performAction:grey_tap()]; + CopyPasswordDetailWithID(IDS_IOS_SHOW_PASSWORD_VIEW_PASSWORD); NSString* title = l10n_util::GetNSString(IDS_IOS_SETTINGS_SET_UP_SCREENLOCK_TITLE); @@ -1223,6 +1032,10 @@ assertWithMatcher:grey_sufficientlyVisible()]; [[EarlGrey selectElementWithMatcher:chrome_test_util::OKButton()] performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] + performAction:grey_tap()]; [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] performAction:grey_tap()]; } @@ -1303,12 +1116,12 @@ assertWithMatcher:grey_notNil()]; // Aim at an entry almost at the end of the list. - constexpr int kRemoteIndex = kPasswordsCount - 2; + constexpr int kRemoteIndex = kPasswordsCount - 4; // The scrolling in GetInteractionForPasswordEntry has too fine steps to // reach the desired part of the list quickly. The following gives it a head - // start of almost the desired position, counting 30 points per entry and - // aiming 3 entries before |kRemoteIndex|. - constexpr int kJump = (kRemoteIndex - 3) * 30; + // start of the desired position, counting 30 points per entry and + // aiming at |kRemoteIndex|. + constexpr int kJump = kRemoteIndex * 30 + 150; [[EarlGrey selectElementWithMatcher:grey_accessibilityID(kPasswordsTableViewId)] performAction:grey_scrollInDirection(kGREYDirectionDown, kJump)]; @@ -1317,10 +1130,10 @@ kRemoteIndex, kRemoteIndex]) performAction:grey_tap()]; // Check that the detail view loaded correctly by verifying the site content. - id<GREYMatcher> siteCell = grey_accessibilityLabel([NSString - stringWithFormat:@"https://www%02d.example.com/", kRemoteIndex]); - [GetInteractionForPasswordDetailItem(siteCell) - assertWithMatcher:grey_notNil()]; + [[EarlGrey selectElementWithMatcher:PasswordDetailWebsite()] + assertWithMatcher:grey_textFieldValue([NSString + stringWithFormat:@"https://www%02d.example.com/", + kRemoteIndex])]; [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] performAction:grey_tap()]; @@ -1469,15 +1282,17 @@ assertWithMatcher:grey_nil()]; [GetInteractionForPasswordEntry(@"exclude2.com") assertWithMatcher:grey_notNil()]; + [[EarlGrey + selectElementWithMatcher:ButtonWithAccessibilityLabelId(IDS_CANCEL)] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] + performAction:grey_tap()]; } // Test search and delete all passwords and blocked items. - (void)testSearchAndDeleteAllPasswords { - // TODO(crbug.com/1129441): This is failing regularly downstream on iOS14. - if (@available(iOS 14, *)) { - EARL_GREY_TEST_DISABLED(@"Test disabled on iOS14."); - } - SaveExamplePasswordForms(); SaveExampleBlockedForms(); @@ -1489,6 +1304,10 @@ // [[EarlGrey selectElementWithMatcher:SearchTextField()] // performAction:grey_typeText(@"u\n")]; + [[EarlGrey + selectElementWithMatcher:grey_accessibilityID(kPasswordsTableViewId)] + performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)]; + TapEdit(); // Select all. @@ -1496,6 +1315,7 @@ performAction:grey_tap()]; [GetInteractionForPasswordEntry(@"example12.com, user2") performAction:grey_tap()]; + [GetInteractionForPasswordEntry(@"exclude1.com") performAction:grey_tap()]; [GetInteractionForPasswordEntry(@"exclude2.com") performAction:grey_tap()];
diff --git a/ios/chrome/test/app/BUILD.gn b/ios/chrome/test/app/BUILD.gn index eb3edd97..1ae1ab0c 100644 --- a/ios/chrome/test/app/BUILD.gn +++ b/ios/chrome/test/app/BUILD.gn
@@ -81,6 +81,7 @@ "//ios/chrome/browser/ui/settings/password", "//ios/chrome/browser/ui/settings/password:password_ui", "//ios/chrome/browser/ui/settings/password:test_support", + "//ios/chrome/browser/ui/settings/password/password_details:password_details_ui", "//ios/chrome/browser/ui/tab_grid", "//ios/chrome/browser/ui/tabs", "//ios/chrome/browser/ui/util",
diff --git a/ios/chrome/test/app/password_test_util.mm b/ios/chrome/test/app/password_test_util.mm index 56b6cfe9..f93ae119 100644 --- a/ios/chrome/test/app/password_test_util.mm +++ b/ios/chrome/test/app/password_test_util.mm
@@ -6,6 +6,7 @@ #include "base/mac/foundation_util.h" #import "ios/chrome/browser/ui/settings/password/legacy_password_details_table_view_controller+testing.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.h" #import "ios/chrome/browser/ui/settings/password/passwords_table_view_controller.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/util/top_view_controller.h" @@ -53,12 +54,11 @@ SettingsNavigationController* settings_navigation_controller = base::mac::ObjCCastStrict<SettingsNavigationController>( top_view_controller::TopPresentedViewController()); - LegacyPasswordDetailsTableViewController* - password_details_table_view_controller = - base::mac::ObjCCastStrict<LegacyPasswordDetailsTableViewController>( - settings_navigation_controller.topViewController); - [password_details_table_view_controller - setReauthenticationModule:mock_reauthentication_module]; + PasswordDetailsTableViewController* password_details_table_view_controller = + base::mac::ObjCCastStrict<PasswordDetailsTableViewController>( + settings_navigation_controller.topViewController); + password_details_table_view_controller.reauthModule = + mock_reauthentication_module; return mock_reauthentication_module; }
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 index 5d1973ca..c66a0a9 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -d197a3a59d58f21d676c122cbf07014e26a5a2c5 \ No newline at end of file +d691a7cfbbc42ed80b4fe79ed7e9ec6854fb5d63 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 index cdddfb8..b031d7aa 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -3f46e3c72fd4a0b953fa39a301dd57f8d60e85e4 \ No newline at end of file +b801dbbdc5d9a27894f9189b34259e161c04b448 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 index d14a35f..61a25efd 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -ebcdef0f6b320efb61eff802c1eea98d9e07ce69 \ No newline at end of file +ca9b30dd0c29bd05f0e95aca58b59bc678d2eaf6 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 index 4726eabfb..8cf0c1c 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -f3e4eeb0c4b99fdd668a763002f995745e18ee78 \ No newline at end of file +8d6cadf9f048470943b7750bca71609029309d45 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 index 61b1d99..89a803d4 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -968775bc0020cfc9d317d5391cfbf112edfcd540 \ No newline at end of file +8059e77f0778e35612f9284ae31284a0aef3625e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 index b965f22..f592089 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -4d87b3d11fc9be5f90248d01e22b369808e2a9ff \ No newline at end of file +e8426bac0180ccbc1eeb628214dc8c249c58cbe2 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 index 09d0bf9..15157237 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -4de2901ca4eb1136131e2b88026537ed3aa11a4e \ No newline at end of file +19a534b52c943d122a6d78f1aeaf4e76b58fb5b2 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 index 4fc6fa17..c04f921 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -63fea9288610814e72c1a9cc12ac760164f734be \ No newline at end of file +a5eaed1bb014e147e0e635c065a1af201092fa25 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 index dfaade87..ad55020 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -dcc174d3ec0250665b01c8b71ae3451679026e56 \ No newline at end of file +2503671c74bebfcf7a33c8fd39d26d7103d464e1 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 index c0821b1..938cbe25 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -62da03440236a10e7ca329ef88dbe623ed1c74ee \ No newline at end of file +9487a1b644d08b6191d11a7ece96a065a7a4c4c7 \ No newline at end of file
diff --git a/media/filters/video_renderer_algorithm.cc b/media/filters/video_renderer_algorithm.cc index 08a95cb..0d33804 100644 --- a/media/filters/video_renderer_algorithm.cc +++ b/media/filters/video_renderer_algorithm.cc
@@ -243,42 +243,32 @@ // Even though we may not be able to remove anything due to having only one // frame, correct any estimates which may have been set during EnqueueFrame(). UpdateFrameStatistics(); + UpdateEffectiveFramesQueued(); // We always leave at least one frame in the queue, so if there's only one // frame there's nothing we can expire. - if (frame_queue_.size() == 1) { - UpdateEffectiveFramesQueued(); + if (frame_queue_.size() == 1) return 0; - } DCHECK_GT(average_frame_duration_, base::TimeDelta()); - // Finds and removes all frames which are too old to be used; I.e., the end of - // their render interval is further than |max_acceptable_drift_| from the - // given |deadline|. We also always expire anything inserted before the last - // rendered frame. + // Finds and removes all frames which are too old to be used. size_t frames_dropped_without_rendering = 0; - size_t frames_to_expire = 0; - const base::TimeTicks minimum_start_time = - deadline - max_acceptable_drift_ - average_frame_duration_; - for (; frames_to_expire < frame_queue_.size() - 1; ++frames_to_expire) { - const ReadyFrame& frame = frame_queue_[frames_to_expire]; - if (frame.start_time >= minimum_start_time) - break; + size_t frames_to_expire = std::min( + frame_queue_.size() - 1, frame_queue_.size() - effective_frames_queued_); + + if (!frames_to_expire) + return 0; + + for (size_t i = 0; i < frames_to_expire; ++i) { + const ReadyFrame& frame = frame_queue_[i]; if (frame.render_count == frame.drop_count) ++frames_dropped_without_rendering; } - if (!frames_to_expire) { - UpdateEffectiveFramesQueued(); - return 0; - } - cadence_frame_counter_ += frames_to_expire; frame_queue_.erase(frame_queue_.begin(), frame_queue_.begin() + frames_to_expire); - - UpdateEffectiveFramesQueued(); return frames_dropped_without_rendering; }
diff --git a/media/filters/video_renderer_algorithm_unittest.cc b/media/filters/video_renderer_algorithm_unittest.cc index 6707f4e..e343079 100644 --- a/media/filters/video_renderer_algorithm_unittest.cc +++ b/media/filters/video_renderer_algorithm_unittest.cc
@@ -1245,12 +1245,12 @@ tg.step(2); // Two frames are removed, one displayed frame (which should not be counted as // dropped) and one undisplayed one. - ASSERT_EQ(1u, algorithm_.RemoveExpiredFrames(tg.current())); + ASSERT_EQ(2u, algorithm_.RemoveExpiredFrames(tg.current())); // Since we just removed the last rendered frame, OnLastFrameDropped() should // be ignored. algorithm_.OnLastFrameDropped(); frame = RenderAndStep(&tg, &frames_dropped); - EXPECT_EQ(1u, frames_dropped); + EXPECT_EQ(0u, frames_dropped); EXPECT_EQ(2u, frames_queued()); EXPECT_EQ(1u, EffectiveFramesQueued()); ASSERT_TRUE(frame);
diff --git a/media/fuchsia/cdm/service/fuchsia_cdm_manager.cc b/media/fuchsia/cdm/service/fuchsia_cdm_manager.cc index 81f3b03..5e6546fa 100644 --- a/media/fuchsia/cdm/service/fuchsia_cdm_manager.cc +++ b/media/fuchsia/cdm/service/fuchsia_cdm_manager.cc
@@ -93,7 +93,7 @@ } fidl::InterfaceHandle<fuchsia::io::Directory> data_directory = - base::fuchsia::OpenDirectory(storage_path); + base::OpenDirectoryHandle(storage_path); if (!data_directory.is_valid()) { DLOG(ERROR) << "Unable to OpenDirectory " << storage_path; return base::nullopt;
diff --git a/mojo/public/mojom/base/token.mojom b/mojo/public/mojom/base/token.mojom index ac5f32c..62f85b3 100644 --- a/mojo/public/mojom/base/token.mojom +++ b/mojo/public/mojom/base/token.mojom
@@ -5,6 +5,7 @@ module mojo_base.mojom; // Corresponds to |base::Token| defined in base/token.h +[Stable] struct Token { uint64 high; uint64 low;
diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium index 68395c7..87108826 100644 --- a/net/third_party/nss/README.chromium +++ b/net/third_party/nss/README.chromium
@@ -4,6 +4,7 @@ Security Critical: Yes License: MPL 2 License File: LICENSE +CPEPrefix: cpe:/a:mozilla:nss:3.23 This directory includes a file derived from NSS's libssl, from the hg repo at: https://hg.mozilla.org/projects/nss
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc index f905fbdc..e8032e4 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
@@ -26,6 +26,7 @@ #include "base/threading/thread_id_name_manager.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" +#include "base/trace_event/task_execution_macros.h" #include "base/trace_event/thread_instruction_count.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_log.h" @@ -1018,20 +1019,17 @@ TEST_F(TraceEventDataSourceTest, TaskExecutionEvent) { CreateTraceEventDataSource(); - INTERNAL_TRACE_EVENT_ADD( - TRACE_EVENT_PHASE_INSTANT, "toplevel", "ThreadControllerImpl::RunTask", - TRACE_EVENT_SCOPE_THREAD | TRACE_EVENT_FLAG_TYPED_PROTO_ARGS, "src_file", - "my_file", "src_func", "my_func"); - INTERNAL_TRACE_EVENT_ADD( - TRACE_EVENT_PHASE_INSTANT, "toplevel", "ThreadControllerImpl::RunTask", - TRACE_EVENT_SCOPE_THREAD | TRACE_EVENT_FLAG_TYPED_PROTO_ARGS, "src_file", - "my_file", "src_func", "my_func"); + base::PendingTask task; + task.posted_from = + base::Location("my_func", "my_file", 0, /*program_counter=*/&task); + { TRACE_TASK_EXECUTION("ThreadControllerImpl::RunTask1", task); } + { TRACE_TASK_EXECUTION("ThreadControllerImpl::RunTask1", task); } size_t packet_index = ExpectStandardPreamble(); auto* e_packet = producer_client()->GetFinalizedPacket(packet_index++); ExpectTraceEvent(e_packet, /*category_iid=*/1u, /*name_iid=*/1u, - TRACE_EVENT_PHASE_INSTANT, TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_PHASE_BEGIN); const auto& annotations = e_packet->track_event().debug_annotations(); EXPECT_EQ(annotations.size(), 0); @@ -1043,9 +1041,9 @@ EXPECT_EQ(locations[0].function_name(), "my_func"); // Second event should refer to the same interning entries. - auto* e_packet2 = producer_client()->GetFinalizedPacket(packet_index++); + auto* e_packet2 = producer_client()->GetFinalizedPacket(++packet_index); ExpectTraceEvent(e_packet2, /*category_iid=*/1u, /*name_iid=*/1u, - TRACE_EVENT_PHASE_INSTANT, TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_PHASE_BEGIN); EXPECT_EQ(e_packet2->track_event().task_execution().posted_from_iid(), 1u); EXPECT_EQ(e_packet2->interned_data().source_locations().size(), 0); @@ -1054,16 +1052,16 @@ TEST_F(TraceEventDataSourceTest, TaskExecutionEventWithoutFunction) { CreateTraceEventDataSource(); - INTERNAL_TRACE_EVENT_ADD( - TRACE_EVENT_PHASE_INSTANT, "toplevel", "ThreadControllerImpl::RunTask", - TRACE_EVENT_SCOPE_THREAD | TRACE_EVENT_FLAG_TYPED_PROTO_ARGS, "src", - "my_file"); + base::PendingTask task; + task.posted_from = base::Location(/*function_name=*/nullptr, "my_file", 0, + /*program_counter=*/&task); + { TRACE_TASK_EXECUTION("ThreadControllerImpl::RunTask", task); } size_t packet_index = ExpectStandardPreamble(); auto* e_packet = producer_client()->GetFinalizedPacket(packet_index++); ExpectTraceEvent(e_packet, /*category_iid=*/1u, /*name_iid=*/1u, - TRACE_EVENT_PHASE_INSTANT, TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_PHASE_BEGIN, TRACE_EVENT_SCOPE_THREAD); const auto& annotations = e_packet->track_event().debug_annotations(); EXPECT_EQ(annotations.size(), 0);
diff --git a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc index 38ee903..75d5d52 100644 --- a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc +++ b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc
@@ -67,12 +67,6 @@ constexpr uint64_t kThreadInstructionCountTrackUuidBit = static_cast<uint64_t>(1u) << 34; -// Names of events that should be converted into a TaskExecution event. -const char* kTaskExecutionEventCategory = "toplevel"; -const char* kTaskExecutionEventNames[3] = {"ThreadControllerImpl::RunTask", - "ThreadPool_RunTask", - "SimpleAlarmTimer::OnTimerFired"}; - void AddConvertableToTraceFormat( base::trace_event::ConvertableToTraceFormat* value, perfetto::protos::pbzero::DebugAnnotation* annotation) { @@ -474,13 +468,6 @@ const size_t kMaxSize = base::trace_event::TraceArguments::kMaxSize; InterningIndexEntry interned_annotation_names[kMaxSize] = { InterningIndexEntry{}}; - InterningIndexEntry interned_source_location{}; - InterningIndexEntry interned_log_message_body{}; - - const char* src_file = nullptr; - const char* src_func = nullptr; - const char* log_message_body = nullptr; - int line_number = 0; // No need to write the event name for end events (sync or nestable async). // Trace processor will match them without, provided event nesting is correct. @@ -510,49 +497,8 @@ } } } else { - // TODO(eseckler): Remove special handling of typed events here once we - // support them in TRACE_EVENT macros. - if (flags & TRACE_EVENT_FLAG_TYPED_PROTO_ARGS) { - if (trace_event->arg_size() == 2u) { - DCHECK_EQ(strcmp(category_name, kTaskExecutionEventCategory), 0); - DCHECK(strcmp(trace_event->name(), kTaskExecutionEventNames[0]) == 0 || - strcmp(trace_event->name(), kTaskExecutionEventNames[1]) == 0 || - strcmp(trace_event->name(), kTaskExecutionEventNames[2]) == 0); - // Double argument task execution event (src_file, src_func). - DCHECK_EQ(trace_event->arg_type(0), TRACE_VALUE_TYPE_STRING); - DCHECK_EQ(trace_event->arg_type(1), TRACE_VALUE_TYPE_STRING); - src_file = trace_event->arg_value(0).as_string; - src_func = trace_event->arg_value(1).as_string; - } else { - // arg_size == 1 enforced by the maximum number of parameter == 2. - DCHECK_EQ(trace_event->arg_size(), 1u); - - if (trace_event->arg_type(0) == TRACE_VALUE_TYPE_STRING) { - // Single argument task execution event (src_file). - DCHECK_EQ(strcmp(category_name, kTaskExecutionEventCategory), 0); - DCHECK( - strcmp(trace_event->name(), kTaskExecutionEventNames[0]) == 0 || - strcmp(trace_event->name(), kTaskExecutionEventNames[1]) == 0 || - strcmp(trace_event->name(), kTaskExecutionEventNames[2]) == 0); - src_file = trace_event->arg_value(0).as_string; - } else { - DCHECK_EQ(trace_event->arg_type(0), TRACE_VALUE_TYPE_CONVERTABLE); - DCHECK(strcmp(category_name, "log") == 0); - DCHECK(strcmp(trace_event->name(), "LogMessage") == 0); - const base::trace_event::LogMessage* value = - static_cast<base::trace_event::LogMessage*>( - trace_event->arg_value(0).as_convertable); - src_file = value->file(); - line_number = value->line_number(); - log_message_body = value->message().c_str(); - - interned_log_message_body = - interned_log_message_bodies_.LookupOrAdd(value->message()); - } // else - } // else - interned_source_location = interned_source_locations_.LookupOrAdd( - std::make_tuple(src_file, src_func, line_number)); + NOTREACHED(); } else if (!privacy_filtering_enabled_) { for (size_t i = 0; i < trace_event->arg_size() && trace_event->arg_name(i); ++i) { @@ -626,14 +572,7 @@ track_event->add_category_iids(interned_category.id); } - if (interned_log_message_body.id) { - auto* log_message = track_event->set_log_message(); - log_message->set_source_location_iid(interned_source_location.id); - log_message->set_body_iid(interned_log_message_body.id); - } else if (interned_source_location.id) { - track_event->set_task_execution()->set_posted_from_iid( - interned_source_location.id); - } else if (!privacy_filtering_enabled_) { + if (!privacy_filtering_enabled_) { WriteDebugAnnotations(trace_event, track_event, interned_annotation_names); } @@ -796,19 +735,7 @@ std::make_tuple(IndexType::kName, IndexData{trace_event_name}, std::move(interned_name))); } - if (interned_log_message_body.id && !interned_log_message_body.was_emitted) { - pending_interning_updates_.push_back( - std::make_tuple(IndexType::kLogMessage, IndexData{log_message_body}, - std::move(interned_log_message_body))); - } - if (interned_source_location.id) { - if (!interned_source_location.was_emitted) { - pending_interning_updates_.push_back(std::make_tuple( - IndexType::kSourceLocation, - IndexData{std::make_tuple(src_file, src_func, line_number)}, - std::move(interned_source_location))); - } - } else if (!privacy_filtering_enabled_) { + if (!privacy_filtering_enabled_) { for (size_t i = 0; i < trace_event->arg_size() && trace_event->arg_name(i); ++i) { DCHECK(interned_annotation_names[i].id);
diff --git a/skia/ext/test_fonts_fuchsia.cc b/skia/ext/test_fonts_fuchsia.cc index 509cfb43..71454a9 100644 --- a/skia/ext/test_fonts_fuchsia.cc +++ b/skia/ext/test_fonts_fuchsia.cc
@@ -38,7 +38,7 @@ if (!base::PathService::Get(base::DIR_ASSETS, &assets_path)) LOG(FATAL) << "Can't get DIR_ASSETS"; launch_info.flat_namespace->directories.push_back( - base::fuchsia::OpenDirectory(assets_path.AppendASCII("test_fonts")) + base::OpenDirectoryHandle(assets_path.AppendASCII("test_fonts")) .TakeChannel()); fidl::InterfaceHandle<fuchsia::io::Directory> font_provider_services_dir;
diff --git a/third_party/blink/public/common/privacy_budget/identifiable_surface.h b/third_party/blink/public/common/privacy_budget/identifiable_surface.h index 1bb0f368..4a4000ab 100644 --- a/third_party/blink/public/common/privacy_budget/identifiable_surface.h +++ b/third_party/blink/public/common/privacy_budget/identifiable_surface.h
@@ -184,6 +184,11 @@ // will key this type on a digest of both the enums' values. kWebGLShaderPrecisionFormat = 16, + // A type for recording reads of the offsetWidth and offsetHeight properties + // when we believe it may be trying to detect the size of the scrollbar. + // The input for this surface should be a member of ScrollbarSurfaces. + kScrollbarSize = 17, + // WebGL2RenderingContext.getInternal kWebGLInternalFormatParameter = 18, @@ -208,6 +213,13 @@ kMax = (1 << kTypeBits) - 1 }; + enum class ScrollbarSurface : uint64_t { + kBodyOffsetWidth = 0, + kBodyOffsetHeight = 1, + kElemScrollbarWidth = 2, + kElemScrollbarHeight = 3, + }; + // Default constructor is invalid. IdentifiableSurface() : IdentifiableSurface(kInvalidHash) {}
diff --git a/third_party/blink/public/mojom/memory_usage_monitor_linux.mojom b/third_party/blink/public/mojom/memory_usage_monitor_linux.mojom index 4859cea..9407211 100644 --- a/third_party/blink/public/mojom/memory_usage_monitor_linux.mojom +++ b/third_party/blink/public/mojom/memory_usage_monitor_linux.mojom
@@ -4,12 +4,13 @@ module blink.mojom; -import "mojo/public/mojom/base/file.mojom"; +import "mojo/public/mojom/base/read_only_file.mojom"; // The interface to provide status and statm files to the renderer's memory // usage monitor. The interface is required only for Linux. interface MemoryUsageMonitorLinux { // The sandbox prevents the renderer from open()-ing any file, meaning // the file descriptors have to be provided by the browser process. - SetProcFiles(mojo_base.mojom.File statm_file, mojo_base.mojom.File status_file); + SetProcFiles(mojo_base.mojom.ReadOnlyFile statm_file, + mojo_base.mojom.ReadOnlyFile status_file); };
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 37754b14..4478cae59 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -4087,83 +4087,95 @@ if (parser_) parser_->StopParsing(); - if (load_event_progress_ == kLoadEventNotRun) + if (load_event_progress_ == kLoadEventNotRun || + load_event_progress_ > kUnloadEventInProgress) { + return; + } + + Element* current_focused_element = FocusedElement(); + if (auto* input = DynamicTo<HTMLInputElement>(current_focused_element)) + input->EndEditing(); + + // If we've dispatched the pagehide event with 'persisted' set to true, it + // means we've dispatched the visibilitychange event before too. Also, we + // shouldn't dispatch the unload event because that event should only be + // fired when the pagehide event's 'persisted' bit is set to false. + bool dispatched_pagehide_persisted = + GetPage() && GetPage()->DispatchedPagehidePersistedAndStillHidden(); + + if (load_event_progress_ >= kPageHideInProgress || + dispatched_pagehide_persisted) { + load_event_progress_ = kUnloadEventHandled; + return; + } + + load_event_progress_ = kPageHideInProgress; + LocalDOMWindow* window = domWindow(); + // We check for DispatchedPagehideAndStillHidden() here because it's possible + // to dispath pagehide with 'persisted' set to false before this and pass the + // |dispatched_pagehide_persisted| above, if we enable same-site + // ProactivelySwapBrowsingInstance but not BackForwardCache. + if (window && !GetPage()->DispatchedPagehideAndStillHidden()) { + const base::TimeTicks pagehide_event_start = base::TimeTicks::Now(); + window->DispatchEvent( + *PageTransitionEvent::Create(event_type_names::kPagehide, false), this); + const base::TimeTicks pagehide_event_end = base::TimeTicks::Now(); + DEFINE_STATIC_LOCAL( + CustomCountHistogram, pagehide_histogram, + ("DocumentEventTiming.PageHideDuration", 0, 10000000, 50)); + pagehide_histogram.CountMicroseconds(pagehide_event_end - + pagehide_event_start); + } + if (!dom_window_) return; - if (load_event_progress_ <= kUnloadEventInProgress) { - Element* current_focused_element = FocusedElement(); - if (auto* input = DynamicTo<HTMLInputElement>(current_focused_element)) - input->EndEditing(); - if (load_event_progress_ < kPageHideInProgress) { - load_event_progress_ = kPageHideInProgress; - LocalDOMWindow* window = domWindow(); - if (window && !GetPage()->DispatchedPagehideAndStillHidden()) { - const base::TimeTicks pagehide_event_start = base::TimeTicks::Now(); - window->DispatchEvent( - *PageTransitionEvent::Create(event_type_names::kPagehide, false), - this); - const base::TimeTicks pagehide_event_end = base::TimeTicks::Now(); - DEFINE_STATIC_LOCAL( - CustomCountHistogram, pagehide_histogram, - ("DocumentEventTiming.PageHideDuration", 0, 10000000, 50)); - pagehide_histogram.CountMicroseconds(pagehide_event_end - - pagehide_event_start); - } - if (!dom_window_) - return; - - // This must be queried before |load_event_progress_| is changed to - // kUnloadVisibilityChangeInProgress because that would change the result. - bool page_visible = IsPageVisible(); - load_event_progress_ = kUnloadVisibilityChangeInProgress; - if (page_visible) { - // Dispatch visibilitychange event, but don't bother doing - // other notifications as we're about to be unloaded. - const base::TimeTicks pagevisibility_hidden_event_start = - base::TimeTicks::Now(); - DispatchEvent( - *Event::CreateBubble(event_type_names::kVisibilitychange)); - const base::TimeTicks pagevisibility_hidden_event_end = - base::TimeTicks::Now(); - DEFINE_STATIC_LOCAL(CustomCountHistogram, pagevisibility_histogram, - ("DocumentEventTiming.PageVibilityHiddenDuration", - 0, 10000000, 50)); - pagevisibility_histogram.CountMicroseconds( - pagevisibility_hidden_event_end - - pagevisibility_hidden_event_start); - DispatchEvent( - *Event::CreateBubble(event_type_names::kWebkitvisibilitychange)); - } - if (!dom_window_) - return; - - GetFrame()->Loader().SaveScrollAnchor(); - - load_event_progress_ = kUnloadEventInProgress; - Event& unload_event = *Event::Create(event_type_names::kUnload); - const base::TimeTicks unload_event_start = base::TimeTicks::Now(); - dom_window_->DispatchEvent(unload_event, this); - const base::TimeTicks unload_event_end = base::TimeTicks::Now(); - - if (unload_timing) { - // Record unload event timing when navigating cross-document. - DEFINE_STATIC_LOCAL( - CustomCountHistogram, unload_histogram, - ("DocumentEventTiming.UnloadDuration", 0, 10000000, 50)); - unload_histogram.CountMicroseconds(unload_event_end - - unload_event_start); - - // Fill in the unload timing if the new document origin has access to - // them. - if (committing_origin->CanRequest(Url())) { - auto& timing = unload_timing->emplace(); - timing.unload_event_start = unload_event_start; - timing.unload_event_end = unload_event_end; - } - } - } - load_event_progress_ = kUnloadEventHandled; + // This must be queried before |load_event_progress_| is changed to + // kUnloadVisibilityChangeInProgress because that would change the result. + bool page_visible = IsPageVisible(); + load_event_progress_ = kUnloadVisibilityChangeInProgress; + if (page_visible) { + // Dispatch visibilitychange event, but don't bother doing + // other notifications as we're about to be unloaded. + const base::TimeTicks pagevisibility_hidden_event_start = + base::TimeTicks::Now(); + DispatchEvent(*Event::CreateBubble(event_type_names::kVisibilitychange)); + const base::TimeTicks pagevisibility_hidden_event_end = + base::TimeTicks::Now(); + DEFINE_STATIC_LOCAL( + CustomCountHistogram, pagevisibility_histogram, + ("DocumentEventTiming.PageVibilityHiddenDuration", 0, 10000000, 50)); + pagevisibility_histogram.CountMicroseconds( + pagevisibility_hidden_event_end - pagevisibility_hidden_event_start); + DispatchEvent( + *Event::CreateBubble(event_type_names::kWebkitvisibilitychange)); } + if (!dom_window_) + return; + + GetFrame()->Loader().SaveScrollAnchor(); + + load_event_progress_ = kUnloadEventInProgress; + Event& unload_event = *Event::Create(event_type_names::kUnload); + const base::TimeTicks unload_event_start = base::TimeTicks::Now(); + dom_window_->DispatchEvent(unload_event, this); + const base::TimeTicks unload_event_end = base::TimeTicks::Now(); + + if (unload_timing) { + // Record unload event timing when navigating cross-document. + DEFINE_STATIC_LOCAL( + CustomCountHistogram, unload_histogram, + ("DocumentEventTiming.UnloadDuration", 0, 10000000, 50)); + unload_histogram.CountMicroseconds(unload_event_end - unload_event_start); + + // Fill in the unload timing if the new document origin has access to + // them. + if (committing_origin->CanRequest(Url())) { + auto& timing = unload_timing->emplace(); + timing.unload_event_start = unload_event_start; + timing.unload_event_end = unload_event_end; + } + } + load_event_progress_ = kUnloadEventHandled; } void Document::DispatchFreezeEvent() {
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc index c829b72..9550a35 100644 --- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc +++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -91,7 +91,6 @@ #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/focus_controller.h" #include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/script/classic_script.h" #include "third_party/blink/renderer/core/scroll/scroll_animator_base.h" @@ -649,20 +648,11 @@ } wants_wheel_events_ = wants_wheel_events; - if (auto* page = element_->GetDocument().GetPage()) { - if (ScrollingCoordinator* scrolling_coordinator = - page->GetScrollingCoordinator()) { - // Only call scrolling_coordinator if attached. SetWantsWheelEvents can - // be called from Plugin Initialization when it is not yet attached. - if (IsAttached()) { - LocalFrameView* frame_view = element_->GetDocument().GetFrame()->View(); - scrolling_coordinator->NotifyGeometryChanged(frame_view); - // Scroll hit test data depend on wheel events. They are painted in the - // background phase. - GetLayoutEmbeddedContent()->SetBackgroundNeedsFullPaintInvalidation(); - } - } + if (IsAttached()) { + // Scroll hit test data depend on wheel events. They are painted in the + // background phase. + GetLayoutEmbeddedContent()->SetBackgroundNeedsFullPaintInvalidation(); } }
diff --git a/third_party/blink/renderer/core/frame/event_handler_registry.cc b/third_party/blink/renderer/core/frame/event_handler_registry.cc index f33133d5..85c70ec0 100644 --- a/third_party/blink/renderer/core/frame/event_handler_registry.cc +++ b/third_party/blink/renderer/core/frame/event_handler_registry.cc
@@ -103,32 +103,24 @@ return targets_[handler_class].size(); } -bool EventHandlerRegistry::UpdateEventHandlerTargets( +void EventHandlerRegistry::UpdateEventHandlerTargets( ChangeOperation op, EventHandlerClass handler_class, EventTarget* target) { EventTargetSet* targets = &targets_[handler_class]; - if (op == kAdd) { - if (!targets->insert(target).is_new_entry) { - // Just incremented refcount, no real change. - return false; - } - } else { - DCHECK(op == kRemove || op == kRemoveAll); - DCHECK(op == kRemoveAll || targets->Contains(target)); - - if (op == kRemoveAll) { - if (!targets->Contains(target)) - return false; + switch (op) { + case kAdd: + targets->insert(target); + return; + case kRemove: + DCHECK(targets->Contains(target)); + targets->erase(target); + return; + case kRemoveAll: targets->RemoveAll(target); - } else { - if (!targets->erase(target)) { - // Just decremented refcount, no real update. - return false; - } - } + return; } - return true; + NOTREACHED(); } bool EventHandlerRegistry::UpdateEventHandlerInternal( @@ -136,21 +128,13 @@ EventHandlerClass handler_class, EventTarget* target) { unsigned old_num_handlers = targets_[handler_class].size(); - bool target_set_changed = - UpdateEventHandlerTargets(op, handler_class, target); + UpdateEventHandlerTargets(op, handler_class, target); unsigned new_num_handlers = targets_[handler_class].size(); bool handlers_changed = old_num_handlers != new_num_handlers; + if (op != kRemoveAll && handlers_changed) + NotifyHandlersChanged(target, handler_class, new_num_handlers > 0); - if (op != kRemoveAll) { - if (handlers_changed) - NotifyHandlersChanged(target, handler_class, new_num_handlers > 0); - - if (target_set_changed) { - NotifyDidAddOrRemoveEventHandlerTarget(GetLocalFrameForTarget(target), - handler_class); - } - } return handlers_changed; } @@ -235,10 +219,6 @@ bool has_handlers = targets_[handler_class].Contains(&target); NotifyHandlersChanged(&target, handler_class, has_handlers); } - if (target_set_changed[i]) { - NotifyDidAddOrRemoveEventHandlerTarget(GetLocalFrameForTarget(&target), - handler_class); - } } } @@ -326,24 +306,6 @@ } } -void EventHandlerRegistry::NotifyDidAddOrRemoveEventHandlerTarget( - LocalFrame* frame, - EventHandlerClass handler_class) { - // TODO(keishi): Added for crbug.com/1090687. Change to CHECK once bug is - // fixed. - if (!GetPage()) - return; - ScrollingCoordinator* scrolling_coordinator = - GetPage()->GetScrollingCoordinator(); - if (scrolling_coordinator && - (handler_class == kTouchAction || - handler_class == kTouchStartOrMoveEventBlocking || - handler_class == kTouchStartOrMoveEventBlockingLowLatency)) { - scrolling_coordinator->TouchEventTargetRectsDidChange( - &frame->LocalFrameRoot()); - } -} - void EventHandlerRegistry::Trace(Visitor* visitor) const { visitor->Trace(frame_); visitor->template RegisterWeakCallbackMethod<
diff --git a/third_party/blink/renderer/core/frame/event_handler_registry.h b/third_party/blink/renderer/core/frame/event_handler_registry.h index 6df2f6a6..0ac46004 100644 --- a/third_party/blink/renderer/core/frame/event_handler_registry.h +++ b/third_party/blink/renderer/core/frame/event_handler_registry.h
@@ -96,7 +96,7 @@ // Returns true if the operation actually added a new target or completely // removed an existing one. - bool UpdateEventHandlerTargets(ChangeOperation, + void UpdateEventHandlerTargets(ChangeOperation, EventHandlerClass, EventTarget*); @@ -108,11 +108,6 @@ EventHandlerClass, bool has_active_handlers); - // Called to notify clients whenever a single event handler target is - // registered or unregistered. If several handlers are registered for the - // same target, only the first registration will trigger this notification. - void NotifyDidAddOrRemoveEventHandlerTarget(LocalFrame*, EventHandlerClass); - // Record a change operation to a given event handler class and notify any // parent registry and other clients accordingly. void UpdateEventHandlerOfType(ChangeOperation,
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 8dbb4fb..804247a 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2007,12 +2007,6 @@ return; ScheduleUpdatePluginsIfNecessary(); - - if (ScrollingCoordinator* scrolling_coordinator = - this->GetScrollingCoordinator()) { - scrolling_coordinator->NotifyGeometryChanged(this); - } - SendResizeEventIfNeeded(); } @@ -2761,12 +2755,6 @@ if (!is_capturing_layout) repainted = PaintTree(benchmark_mode); - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - if (GetLayoutView()->Compositor()->InCompositingMode()) { - GetScrollingCoordinator()->UpdateAfterPaint(this); - } - } - if (benchmark_mode == PaintBenchmarkMode::kForcePaintArtifactCompositorUpdate || // TODO(paint-dev): Separate requirement for update for repaint and full @@ -3011,10 +2999,6 @@ if (GraphicsLayer* root_graphics_layer = layout_view->Compositor()->PaintRootGraphicsLayer()) { repainted = root_graphics_layer->PaintRecursively(benchmark_mode); - // If the painted result changed, the recorded hit test data may have - // changed which will affect the mapped hit test geometry. - if (repainted && GetScrollingCoordinator()) - GetScrollingCoordinator()->NotifyGeometryChanged(this); } else { needs_clear_repaint_flags = true; } @@ -3614,30 +3598,12 @@ client->ScheduleAnimation(this, delay); } -void LocalFrameView::ScrollableAreasDidChange() { - // Layout may update scrollable area bounding boxes. It also sets the same - // dirty flag making this one redundant (See - // |ScrollingCoordinator::notifyGeometryChanged|). - // So if layout is expected, ignore this call allowing scrolling coordinator - // to be notified post-layout to recompute gesture regions. - // TODO(wjmaclean): It would be nice to move the !NeedsLayout() check from - // here to SetScrollGestureRegionIsDirty(), but at present doing so breaks - // web tests. This suggests that there is something that wants to set the - // dirty bit when layout is needed, and won't re-try setting the bit after - // layout has completed - it would be nice to find that and fix it. - if (!NeedsLayout()) - GetScrollingContext()->SetScrollGestureRegionIsDirty(true); -} - void LocalFrameView::AddScrollableArea( PaintLayerScrollableArea* scrollable_area) { DCHECK(scrollable_area); if (!scrollable_areas_) scrollable_areas_ = MakeGarbageCollected<ScrollableAreaSet>(); scrollable_areas_->insert(scrollable_area); - - if (GetScrollingCoordinator()) - ScrollableAreasDidChange(); } void LocalFrameView::RemoveScrollableArea( @@ -3645,9 +3611,6 @@ if (!scrollable_areas_) return; scrollable_areas_->erase(scrollable_area); - - if (GetScrollingCoordinator()) - ScrollableAreasDidChange(); } void LocalFrameView::AddAnimatingScrollableArea( @@ -4131,8 +4094,6 @@ void LocalFrameView::Show() { if (!IsSelfVisible()) { SetSelfVisible(true); - if (GetScrollingCoordinator()) - GetScrollingContext()->SetScrollGestureRegionIsDirty(true); SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree); if (IsParentVisible()) { ForAllChildViewsAndPlugins( @@ -4152,8 +4113,6 @@ }); } SetSelfVisible(false); - if (GetScrollingCoordinator()) - GetScrollingContext()->SetScrollGestureRegionIsDirty(true); SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree); } } @@ -4314,10 +4273,6 @@ } void LocalFrameView::InvalidateForThrottlingChange() { - // ScrollingCoordinator needs to update according to the new throttling - // status. - if (ScrollingCoordinator* coordinator = this->GetScrollingCoordinator()) - coordinator->NotifyGeometryChanged(this); // Start ticking animation frames again if necessary. if (GetPage()) GetPage()->Animator().ScheduleVisualUpdate(frame_.Get());
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h index 0ea76e5..822bcdca 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -677,10 +677,6 @@ const cc::Layer* RootCcLayer() const; - // Should be called whenever this LocalFrameView adds or removes a - // scrollable area, or gains/loses a composited layer. - void ScrollableAreasDidChange(); - ScrollingCoordinatorContext* GetScrollingContext() const; cc::AnimationHost* GetCompositorAnimationHost() const; CompositorAnimationTimeline* GetCompositorAnimationTimeline() const;
diff --git a/third_party/blink/renderer/core/html/canvas/image_data.cc b/third_party/blink/renderer/core/html/canvas/image_data.cc index 7c2f5aa..772f6ee 100644 --- a/third_party/blink/renderer/core/html/canvas/image_data.cc +++ b/third_party/blink/renderer/core/html/canvas/image_data.cc
@@ -336,8 +336,6 @@ if (!image_data) return nullptr; - // TODO(crbug.com/1115317): Verify if the color type uint16 needs to be - // considered separately. ImageDataArray data = image_data->data(); SkColorType color_type = image_info.colorType(); bool create_f32_image_data = (color_type == kRGBA_1010102_SkColorType || @@ -346,9 +344,15 @@ color_type == kRGBA_F32_SkColorType); if (!create_f32_image_data) { - image_info = image_info.makeColorType(kRGBA_8888_SkColorType); - paint_image.readPixels(image_info, data.GetAsUint8ClampedArray()->Data(), - image_info.minRowBytes(), 0, 0); + if (color_type == kR16G16B16A16_unorm_SkColorType) { + image_info = image_info.makeColorType(kR16G16B16A16_unorm_SkColorType); + paint_image.readPixels(image_info, data.GetAsUint16Array()->Data(), + image_info.minRowBytes(), 0, 0); + } else { + image_info = image_info.makeColorType(kRGBA_8888_SkColorType); + paint_image.readPixels(image_info, data.GetAsUint8ClampedArray()->Data(), + image_info.minRowBytes(), 0, 0); + } } else { image_info = image_info.makeColorType(kRGBA_F32_SkColorType); paint_image.readPixels(image_info, data.GetAsFloat32Array()->Data(), @@ -620,13 +624,11 @@ ScriptWrappable::AssociateWithWrapper(isolate, wrapper_type, wrapper); if (!wrapper.IsEmpty() && data_.IsUint8ClampedArray()) { - // Create a V8 Uint8ClampedArray object and set the "data" property + // Create a V8 object with |data_| and set the "data" property // of the ImageData object to the created v8 object, eliminating the // C++ callback when accessing the "data" property. - // TODO(crbug.com/1115317): |pixel_array| should be compatible with uint_8, - // float16 and float32. - v8::Local<v8::Value> pixel_array = - ToV8(data_.GetAsUint8ClampedArray().Get(), wrapper, isolate); + + v8::Local<v8::Value> pixel_array = ToV8(data_, wrapper, isolate); bool defined_property; if (pixel_array.IsEmpty() || !wrapper @@ -793,6 +795,17 @@ kNonOpaque); } +SkImageInfo ImageData::GetSkImageInfo() { + SkColorType color_type = kN32_SkColorType; + if (data_u16_) { + color_type = kR16G16B16A16_unorm_SkColorType; + } else if (data_f32_) { + color_type = kRGBA_F32_SkColorType; + } + return SkImageInfo::Make(width(), height(), color_type, + GetCanvasColorParams().GetSkAlphaType()); +} + bool ImageData::ImageDataInCanvasColorSettings( CanvasColorSpace canvas_color_space, CanvasPixelFormat canvas_pixel_format,
diff --git a/third_party/blink/renderer/core/html/canvas/image_data.h b/third_party/blink/renderer/core/html/canvas/image_data.h index 6283c49..66d026c 100644 --- a/third_party/blink/renderer/core/html/canvas/image_data.h +++ b/third_party/blink/renderer/core/html/canvas/image_data.h
@@ -149,6 +149,7 @@ DOMArrayBufferBase* BufferBase() const; CanvasColorParams GetCanvasColorParams(); + SkImageInfo GetSkImageInfo(); // DataU8ColorType param specifies if the converted pixels in uint8 pixel // format should respect the "native" 32bit ARGB format of Skia's blitters.
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc index 1aaacce..4c5c62b 100644 --- a/third_party/blink/renderer/core/html/html_element.cc +++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -26,6 +26,8 @@ #include "third_party/blink/renderer/core/html/html_element.h" #include "base/stl_util.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h" #include "third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h" #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h" #include "third_party/blink/renderer/bindings/core/v8/string_treat_null_as_empty_string_or_trusted_script.h" @@ -51,6 +53,7 @@ #include "third_party/blink/renderer/core/events/keyboard_event.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/deprecation.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/html/custom/custom_element.h" @@ -69,10 +72,12 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/input_type_names.h" #include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h" +#include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/layout_box_model_object.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/mathml_names.h" #include "third_party/blink/renderer/core/page/spatial_navigation.h" +#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/svg/svg_svg_element.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_script.h" #include "third_party/blink/renderer/core/xml_names.h" @@ -1492,17 +1497,81 @@ return 0; } +void HTMLElement::RecordScrollbarSizeForStudy(int offset_measurement, + bool is_width) { + if (!IdentifiabilityStudySettings::Get()->IsTypeAllowed( + IdentifiableSurface::Type::kScrollbarSize)) + return; + + // Check for presence of a scrollbar. + PaintLayerScrollableArea* area; + if (this == GetDocument().ScrollingElementNoLayout()) { + auto* view = GetDocument().View(); + if (!view) + return; + area = view->LayoutViewport(); + } else { + auto* layout = GetLayoutBox(); + if (!layout) + return; + area = layout->GetScrollableArea(); + } + if (!area || area->HasOverlayOverflowControls()) + return; + + Scrollbar* scrollbar = + is_width ? area->VerticalScrollbar() : area->HorizontalScrollbar(); + // We intentionally exclude platform overlay scrollbars since their size + // cannot be detected in JavaScript using the methods below. + if (!scrollbar) + return; + + IdentifiableSurface::ScrollbarSurface surface; + int scrollbar_size; + + // There are two common ways to detect the size of a scrollbar in a DOM + // window. They are: + // 1. Compute the difference of the window.inner[Width|Height] and the + // corresponding document.scrollingElement.offset[Width|Height]. + // 2. Any HTML element that insets the layout to fit a scrollbar, so it is + // measurable by a JavaScript program on a site. + if (this == GetDocument().scrollingElement()) { + LocalDOMWindow* dom_window = GetDocument().domWindow(); + scrollbar_size = + (is_width ? dom_window->innerWidth() : dom_window->innerHeight()) - + offset_measurement; + surface = is_width + ? IdentifiableSurface::ScrollbarSurface::kBodyOffsetWidth + : IdentifiableSurface::ScrollbarSurface::kBodyOffsetHeight; + } else { + scrollbar_size = + offset_measurement - (is_width ? clientWidth() : clientHeight()); + surface = is_width + ? IdentifiableSurface::ScrollbarSurface::kElemScrollbarWidth + : IdentifiableSurface::ScrollbarSurface::kElemScrollbarHeight; + } + + blink::IdentifiabilityMetricBuilder(GetDocument().UkmSourceID()) + .Set(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kScrollbarSize, surface), + scrollbar_size) + .Record(GetDocument().UkmRecorder()); +} + int HTMLElement::offsetWidthForBinding() { GetDocument().EnsurePaintLocationDataValidForNode( this, DocumentUpdateReason::kJavaScript); Element* offset_parent = unclosedOffsetParent(); - if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject()) - return AdjustForAbsoluteZoom::AdjustLayoutUnit( - LayoutUnit( - layout_object->PixelSnappedOffsetWidth(offset_parent)), - layout_object->StyleRef()) - .Round(); - return 0; + int result = 0; + if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject()) { + result = + AdjustForAbsoluteZoom::AdjustLayoutUnit( + LayoutUnit(layout_object->PixelSnappedOffsetWidth(offset_parent)), + layout_object->StyleRef()) + .Round(); + RecordScrollbarSizeForStudy(result, /* isWidth= */ true); + } + return result; } DISABLE_CFI_PERF @@ -1510,13 +1579,16 @@ GetDocument().EnsurePaintLocationDataValidForNode( this, DocumentUpdateReason::kJavaScript); Element* offset_parent = unclosedOffsetParent(); - if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject()) - return AdjustForAbsoluteZoom::AdjustLayoutUnit( - LayoutUnit( - layout_object->PixelSnappedOffsetHeight(offset_parent)), - layout_object->StyleRef()) - .Round(); - return 0; + int result = 0; + if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject()) { + result = + AdjustForAbsoluteZoom::AdjustLayoutUnit( + LayoutUnit(layout_object->PixelSnappedOffsetHeight(offset_parent)), + layout_object->StyleRef()) + .Round(); + RecordScrollbarSizeForStudy(result, /* isWidth= */ false); + } + return result; } Element* HTMLElement::unclosedOffsetParent() {
diff --git a/third_party/blink/renderer/core/html/html_element.h b/third_party/blink/renderer/core/html/html_element.h index 0f54c2fa..94cba571 100644 --- a/third_party/blink/renderer/core/html/html_element.h +++ b/third_party/blink/renderer/core/html/html_element.h
@@ -212,6 +212,8 @@ void HandleKeypressEvent(KeyboardEvent&); + void RecordScrollbarSizeForStudy(int, bool); + static AttributeTriggers* TriggersForAttributeName( const QualifiedName& attr_name);
diff --git a/third_party/blink/renderer/core/html/html_plugin_element.cc b/third_party/blink/renderer/core/html/html_plugin_element.cc index 778843e..4078a29 100644 --- a/third_party/blink/renderer/core/html/html_plugin_element.cc +++ b/third_party/blink/renderer/core/html/html_plugin_element.cc
@@ -51,7 +51,6 @@ #include "third_party/blink/renderer/core/loader/mixed_content_checker.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/plugin_data.h" -#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" @@ -675,15 +674,6 @@ // TODO(esprehn): WebPluginContainerImpl::SetCcLayer() also schedules a // compositing update, do we need both? SetNeedsCompositingUpdate(); - // Make sure any input event handlers introduced by the plugin are taken into - // account. - if (Page* page = GetDocument().GetFrame()->GetPage()) { - if (ScrollingCoordinator* scrolling_coordinator = - page->GetScrollingCoordinator()) { - LocalFrameView* frame_view = GetDocument().GetFrame()->View(); - scrolling_coordinator->NotifyGeometryChanged(frame_view); - } - } return true; }
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc index ca8a5da..ff02f37 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow.cc +++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -693,12 +693,10 @@ LayoutUnit total_available_logical_width = BorderAndPaddingLogicalWidth() + AvailableLogicalWidth(); - if (StyleRef().IsHorizontalWritingMode() && - !StyleRef().IsLeftToRightDirection()) { + if (ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()) start_position -= LogicalLeftScrollbarWidth(); - } else { + else start_position += LogicalLeftScrollbarWidth(); - } LayoutUnit child_margin_start = MarginStartForChild(child); LayoutUnit new_position = start_position + child_margin_start;
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 2b974623..9104f29f 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -89,7 +89,6 @@ #include "third_party/blink/renderer/core/layout/shapes/shape_outside_info.h" #include "third_party/blink/renderer/core/page/autoscroll_controller.h" #include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h" #include "third_party/blink/renderer/core/page/scrolling/snap_coordinator.h" #include "third_party/blink/renderer/core/paint/background_image_geometry.h" #include "third_party/blink/renderer/core/paint/box_paint_invalidator.h" @@ -666,11 +665,6 @@ } } - if (diff.TransformChanged()) { - if (auto* coordinator = GetFrame()->GetPage()->GetScrollingCoordinator()) - coordinator->NotifyGeometryChanged(GetFrameView()); - } - // Update the script style map, from the new computed style. if (IsCustomItem()) GetCustomLayoutChild()->styleMap()->UpdateStyle(GetDocument(), StyleRef());
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc index a7b7a3ac..260f56a 100644 --- a/third_party/blink/renderer/core/layout/layout_view.cc +++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -49,7 +49,6 @@ #include "third_party/blink/renderer/core/page/named_pages_mapper.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h" -#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h" #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" @@ -936,13 +935,6 @@ auto result = LayoutBlockFlow::RecalcLayoutOverflow(); if (result.layout_overflow_changed) { - // Changing overflow should notify scrolling coordinator to ensures that it - // updates non-fast scroll rects even if there is no layout. - if (ScrollingCoordinator* scrolling_coordinator = - GetDocument().GetPage()->GetScrollingCoordinator()) { - GetFrameView()->GetScrollingContext()->SetScrollGestureRegionIsDirty( - true); - } if (NeedsLayout()) return result; if (GetFrameView()->VisualViewportSuppliesScrollbars())
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc index b6e2afb..083cf427 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
@@ -269,32 +269,6 @@ return !IsListMarker(); } -bool NGInlineCursorPosition::IsPartOfCulledInlineBox( - const LayoutInline& layout_inline) const { - DCHECK(!layout_inline.ShouldCreateBoxFragment()); - DCHECK(*this); - const LayoutObject* const layout_object = GetLayoutObject(); - // We use |IsInline()| to exclude floating and out-of-flow objects. - if (!layout_object || !layout_object->IsInline() || - layout_object->IsAtomicInlineLevel()) - return false; - DCHECK(!layout_object->IsFloatingOrOutOfFlowPositioned()); - DCHECK(!BoxFragment() || !BoxFragment()->IsFormattingContextRoot()); - for (const LayoutObject* parent = layout_object->Parent(); parent; - parent = parent->Parent()) { - // Children of culled inline should be included. - if (parent == &layout_inline) - return true; - // Grand children should be included only if children are also culled. - if (const auto* parent_layout_inline = ToLayoutInlineOrNull(parent)) { - if (!parent_layout_inline->ShouldCreateBoxFragment()) - continue; - } - return false; - } - return false; -} - bool NGInlineCursor::IsLastLineInInlineBlock() const { DCHECK(Current().IsLineBox()); if (!GetLayoutBlockFlow()->IsAtomicInlineLevel()) @@ -1700,23 +1674,15 @@ return nullptr; } -void NGInlineCursor::CulledInlineTraversal::SetUseFragmentTree( - const LayoutInline& layout_inline) { - layout_inline_ = &layout_inline; - use_fragment_tree_ = true; -} - const LayoutObject* NGInlineCursor::CulledInlineTraversal::MoveToFirstFor( const LayoutInline& layout_inline) { layout_inline_ = &layout_inline; - use_fragment_tree_ = false; current_object_ = Find(layout_inline.FirstChild()); return current_object_; } const LayoutObject* NGInlineCursor::CulledInlineTraversal::MoveToNext() { - if (!current_object_) - return nullptr; + DCHECK(current_object_); current_object_ = Find(current_object_->NextInPreOrderAfterChildren(layout_inline_)); return current_object_; @@ -1724,19 +1690,6 @@ void NGInlineCursor::MoveToFirstForCulledInline( const LayoutInline& layout_inline) { - // When |this| is a descendant cursor, |this| may be limited to a very small - // subset of the |LayoutObject| descendants, and that traversing - // |LayoutObject| descendants is much more expensive. Prefer checking every - // fragment in that case. - if (IsDescendantsCursor()) { - culled_inline_.SetUseFragmentTree(layout_inline); - DCHECK(!CanMoveAcrossFragmentainer()); - MoveToFirst(); - while (Current() && !Current().IsPartOfCulledInlineBox(layout_inline)) - MoveToNext(); - return; - } - if (const LayoutObject* layout_object = culled_inline_.MoveToFirstFor(layout_inline)) { MoveTo(*layout_object); @@ -1748,16 +1701,6 @@ void NGInlineCursor::MoveToNextForCulledInline() { DCHECK(culled_inline_); - if (culled_inline_.UseFragmentTree()) { - const LayoutInline* layout_inline = culled_inline_.GetLayoutInline(); - DCHECK(layout_inline); - DCHECK(!CanMoveAcrossFragmentainer()); - do { - MoveToNext(); - } while (Current() && !Current().IsPartOfCulledInlineBox(*layout_inline)); - return; - } - MoveToNextForSameLayoutObjectExceptCulledInline(); // If we're at the end of fragments for the current |LayoutObject| that // contributes to the current culled inline, find the next |LayoutObject|.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h index cb3f104e..8f69168 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
@@ -532,13 +532,8 @@ public: CulledInlineTraversal() = default; - const LayoutInline* GetLayoutInline() const { return layout_inline_; } - - explicit operator bool() const { return layout_inline_; } - void Reset() { layout_inline_ = nullptr; } - - bool UseFragmentTree() const { return use_fragment_tree_; } - void SetUseFragmentTree(const LayoutInline& layout_inline); + explicit operator bool() const { return current_object_; } + void Reset() { current_object_ = nullptr; } // Returns first/next |LayoutObject| that contribute to |layout_inline|. const LayoutObject* MoveToFirstFor(const LayoutInline& layout_inline); @@ -549,7 +544,6 @@ const LayoutObject* current_object_ = nullptr; const LayoutInline* layout_inline_ = nullptr; - bool use_fragment_tree_ = false; }; void MoveToFirstForCulledInline(const LayoutInline& layout_inline);
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc index c87fcba..8ad0fb9 100644 --- a/third_party/blink/renderer/core/page/page.cc +++ b/third_party/blink/renderer/core/page/page.cc
@@ -558,6 +558,11 @@ mojom::blink::PagehideDispatch::kNotDispatched; } +bool Page::DispatchedPagehidePersistedAndStillHidden() { + return lifecycle_state_->pagehide_dispatch == + mojom::blink::PagehideDispatch::kDispatchedPersisted; +} + void Page::OnSetPageFrozen(bool frozen) { if (frozen_ == frozen) return;
diff --git a/third_party/blink/renderer/core/page/page.h b/third_party/blink/renderer/core/page/page.h index 4e4e496..c184b1fd 100644 --- a/third_party/blink/renderer/core/page/page.h +++ b/third_party/blink/renderer/core/page/page.h
@@ -374,6 +374,10 @@ // still hidden (possibly preserved in the back-forward cache, or unloaded). bool DispatchedPagehideAndStillHidden(); + // Similar to above, but will only return true if we've dispatched 'pagehide' + // with the 'persisted' property set to 'true'. + bool DispatchedPagehidePersistedAndStillHidden(); + static void PrepareForLeakDetection(); private:
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc index 99d2ed6..4b0c31e 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -71,11 +71,6 @@ visitor->Trace(vertical_scrollbars_); } -void ScrollingCoordinator::NotifyGeometryChanged(LocalFrameView* frame_view) { - frame_view->GetScrollingContext()->SetScrollGestureRegionIsDirty(true); - frame_view->GetScrollingContext()->SetTouchEventTargetRectsAreDirty(true); -} - ScrollableArea* ScrollingCoordinator::ScrollableAreaWithElementIdInAllLocalFrames( const CompositorElementId& id) { @@ -129,78 +124,6 @@ } } -void ScrollingCoordinator::UpdateAfterPaint(LocalFrameView* frame_view) { - DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - - LocalFrame* frame = &frame_view->GetFrame(); - DCHECK(frame->IsLocalRoot()); - - bool scroll_gesture_region_dirty = - frame_view->GetScrollingContext()->ScrollGestureRegionIsDirty(); - bool touch_event_rects_dirty = - frame_view->GetScrollingContext()->TouchEventTargetRectsAreDirty(); - - if (!scroll_gesture_region_dirty && !touch_event_rects_dirty) - return; - - SCOPED_UMA_AND_UKM_TIMER(frame_view->EnsureUkmAggregator(), - LocalFrameUkmAggregator::kScrollingCoordinator); - TRACE_EVENT0("input", "ScrollingCoordinator::UpdateAfterPaint"); - - if (scroll_gesture_region_dirty) { - UpdateNonFastScrollableRegions(frame); - frame_view->GetScrollingContext()->SetScrollGestureRegionIsDirty(false); - } - - if (touch_event_rects_dirty) { - UpdateTouchEventTargetRectsIfNeeded(frame); - frame_view->GetScrollingContext()->SetTouchEventTargetRectsAreDirty(false); - } -} - -// Set the non-fast scrollable regions on |layer|'s cc layer. -static void UpdateLayerNonFastScrollableRegions(GraphicsLayer& layer) { - // CompositeAfterPaint does this update in PaintArtifactCompositor. - DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - - DCHECK(layer.PaintsContentOrHitTest()); - - auto offset = layer.GetOffsetFromTransformNode(); - gfx::Vector2dF layer_offset = gfx::Vector2dF(offset.X(), offset.Y()); - PaintArtifactCompositor::UpdateNonFastScrollableRegions( - layer.CcLayer(), layer_offset, layer.GetPropertyTreeState().Unalias(), - PaintChunkSubset(layer.GetPaintController().GetPaintArtifactShared())); -} - -// Compute the regions of the page where we can't handle scroll gestures on -// the impl thread. This currently includes: -// 1. All scrollable areas, such as subframes, overflow divs and list boxes, -// whose composited scrolling are not enabled. We need to do this even if -// the frame view whose layout was updated is not the main frame. -// 2. Resize control areas, e.g. the small rect at the right bottom of -// div/textarea/iframe when CSS property "resize" is enabled. -// 3. Plugin areas. -void ScrollingCoordinator::UpdateNonFastScrollableRegions(LocalFrame* frame) { - auto* view_layer = frame->View()->GetLayoutView()->Layer(); - if (auto* root = view_layer->Compositor()->PaintRootGraphicsLayer()) - ForAllPaintingGraphicsLayers(*root, UpdateLayerNonFastScrollableRegions); -} - -// Set the touch action rects on the cc layer from the touch action data stored -// on the GraphicsLayer's paint chunks. -static void UpdateLayerTouchActionRects(GraphicsLayer& layer) { - // CompositeAfterPaint does this update in PaintArtifactCompositor. - DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - - DCHECK(layer.PaintsContentOrHitTest()); - - auto offset = layer.GetOffsetFromTransformNode(); - gfx::Vector2dF layer_offset = gfx::Vector2dF(offset.X(), offset.Y()); - PaintArtifactCompositor::UpdateTouchActionRects( - layer.CcLayer(), layer_offset, layer.GetPropertyTreeState().Unalias(), - PaintChunkSubset(layer.GetPaintController().GetPaintArtifactShared())); -} - void ScrollingCoordinator::WillDestroyScrollableArea( ScrollableArea* scrollable_area) { RemoveScrollbarLayer(scrollable_area, kHorizontalScrollbar); @@ -370,52 +293,11 @@ scrollable_area->GetCompositorAnimationTimeline()); } -void ScrollingCoordinator::UpdateTouchEventTargetRectsIfNeeded( - LocalFrame* frame) { - TRACE_EVENT0("input", - "ScrollingCoordinator::updateTouchEventTargetRectsIfNeeded"); - - DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - - auto* view_layer = frame->View()->GetLayoutView()->Layer(); - if (auto* root = view_layer->Compositor()->PaintRootGraphicsLayer()) - ForAllPaintingGraphicsLayers(*root, UpdateLayerTouchActionRects); -} - void ScrollingCoordinator::Reset(LocalFrame* frame) { horizontal_scrollbars_.clear(); vertical_scrollbars_.clear(); } -void ScrollingCoordinator::TouchEventTargetRectsDidChange(LocalFrame* frame) { - if (!frame) - return; - - // If frame is not a local root, then the call to StaleInCompositingMode() - // below may unexpectedly fail. - DCHECK(frame->IsLocalRoot()); - LocalFrameView* frame_view = frame->View(); - if (!frame_view) - return; - - // Wait until after layout to update. - // TODO(pdr): This check is wrong as we need to mark the rects as dirty - // regardless of whether the frame view needs layout. Remove this check. - if (frame_view->NeedsLayout()) - return; - - // FIXME: scheduleAnimation() is just a method of forcing the compositor to - // realize that it needs to commit here. We should expose a cleaner API for - // this. - auto* layout_view = frame->ContentLayoutObject(); - if (layout_view && layout_view->Compositor() && - layout_view->Compositor()->StaleInCompositingMode()) { - frame_view->ScheduleAnimation(); - } - - frame_view->GetScrollingContext()->SetTouchEventTargetRectsAreDirty(true); -} - void ScrollingCoordinator::AnimationHostInitialized( cc::AnimationHost& animation_host, LocalFrameView* view) { @@ -456,17 +338,6 @@ weak_ptr_factory_.InvalidateWeakPtrs(); } -bool ScrollingCoordinator::CoordinatesScrollingForFrameView( - LocalFrameView* frame_view) const { - DCHECK(IsMainThread()); - - // We currently only support composited mode. - auto* layout_view = frame_view->GetFrame().ContentLayoutObject(); - if (!layout_view) - return false; - return layout_view->UsesCompositing(); -} - bool ScrollingCoordinator::IsForMainFrame( ScrollableArea* scrollable_area) const { if (!IsA<LocalFrame>(page_->MainFrame())) @@ -477,15 +348,4 @@ page_->DeprecatedLocalMainFrame()->View()->LayoutViewport(); } -void ScrollingCoordinator::FrameViewRootLayerDidChange( - LocalFrameView* frame_view) { - DCHECK(IsMainThread()); - DCHECK(page_); - - if (!CoordinatesScrollingForFrameView(frame_view)) - return; - - NotifyGeometryChanged(frame_view); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h index 0590be5b..f8d8490d 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
@@ -77,20 +77,6 @@ void WillBeDestroyed(); - // Return whether this scrolling coordinator handles scrolling for the given - // frame view. - bool CoordinatesScrollingForFrameView(LocalFrameView*) const; - - // Called when any frame has done its layout or compositing has changed. - void NotifyGeometryChanged(LocalFrameView*); - - // Update non-fast scrollable regions and touch event target rects. - // TODO(pdr): Refactor this out of ScrollingCoordinator. - void UpdateAfterPaint(LocalFrameView*); - - // Should be called whenever the root layer for the given frame view changes. - void FrameViewRootLayerDidChange(LocalFrameView*); - void WillDestroyScrollableArea(ScrollableArea*); // Updates scroll offset in cc scroll tree immediately. We don't wait for @@ -113,11 +99,6 @@ void ScrollableAreaScrollLayerDidChange(PaintLayerScrollableArea*); void ScrollableAreaScrollbarLayerDidChange(PaintLayerScrollableArea*, ScrollbarOrientation); - // LocalFrame* must be a local root if non-null. - void TouchEventTargetRectsDidChange(LocalFrame*); - - void UpdateNonFastScrollableRegions(LocalFrame*); - void UpdateTouchEventTargetRectsIfNeeded(LocalFrame*); cc::AnimationHost* GetCompositorAnimationHost() { return animation_host_; } CompositorAnimationTimeline* GetCompositorAnimationTimeline() { @@ -150,11 +131,6 @@ Member<Page> page_; - // Dirty flags used to identify what really needs to be computed after - // compositing is updated. - bool touch_event_target_rects_are_dirty_; - bool should_scroll_on_main_thread_dirty_; - private: void SetScrollbarLayer(ScrollableArea*, ScrollbarOrientation,
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h index 8a90cb03..a4b1b926f 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h
@@ -36,30 +36,10 @@ } cc::AnimationHost* GetCompositorAnimationHost() { return animation_host_; } - // Non-fast scrollable regions need updating by ScrollingCoordinator. - bool ScrollGestureRegionIsDirty() const { - return scroll_gesture_region_is_dirty_; - } - // Touch event target rects need updating by ScrollingCoordinator. - bool TouchEventTargetRectsAreDirty() const { - return touch_event_target_rects_are_dirty_; - } - - // Only ScrollingCoordinator should ever set |dirty| to |false|. - void SetScrollGestureRegionIsDirty(bool dirty) { - scroll_gesture_region_is_dirty_ = dirty; - } - void SetTouchEventTargetRectsAreDirty(bool dirty) { - touch_event_target_rects_are_dirty_ = dirty; - } - private: std::unique_ptr<CompositorAnimationTimeline> animation_timeline_; cc::AnimationHost* animation_host_ = nullptr; - bool scroll_gesture_region_is_dirty_ = false; - bool touch_event_target_rects_are_dirty_ = false; - DISALLOW_COPY_AND_ASSIGN(ScrollingCoordinatorContext); };
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc index d204f8d..e1d6107 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
@@ -210,11 +210,6 @@ LocalFrameView* frame_view = GetFrame()->View(); Page* page = GetFrame()->GetPage(); ASSERT_TRUE(page->GetScrollingCoordinator()); - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - ASSERT_TRUE( - page->GetScrollingCoordinator()->CoordinatesScrollingForFrameView( - frame_view)); - } // Fast scrolling should be enabled by default. const auto* outer_scroll_node = @@ -1454,91 +1449,6 @@ CurrentScrollOffset(inner_viewport_scroll_node)); } -TEST_P(ScrollingTest, UpdateUMAMetricUpdated) { - // The metrics are recorced in ScrollingCoordinator::UpdateAfterPaint() which - // is not called in CompositeAfterPaint. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - - HistogramTester histogram_tester; - LoadHTML(R"HTML( - <div id='bg' style='background: blue;'></div> - <div id='scroller' style='overflow: scroll; width: 10px; height: 10px; background: blue'> - <div id='forcescroll' style='height: 1000px;'></div> - </div> - )HTML"); - - // The initial counts should be zero. - histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 0); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 0); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 0); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.AggregatedPreFCP", 0); - - // After an initial compositing update, we should have one scrolling update - // recorded as PreFCP. - GetWebView()->MainFrameViewWidget()->RecordStartOfFrameMetrics(); - ForceFullCompositingUpdate(); - GetWebView()->MainFrameViewWidget()->RecordEndOfFrameMetrics( - base::TimeTicks(), 0); - histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 1); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 1); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 0); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.AggregatedPreFCP", 0); - - // An update with no scrolling changes should not cause a scrolling update. - GetWebView()->MainFrameViewWidget()->RecordStartOfFrameMetrics(); - ForceFullCompositingUpdate(); - GetWebView()->MainFrameViewWidget()->RecordEndOfFrameMetrics( - base::TimeTicks(), 0); - histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 1); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 1); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 0); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.AggregatedPreFCP", 0); - - // A change to background color does not need to cause a scrolling update but, - // because we record hit test data, we also cause a scrolling coordinator - // update when the background paints. Also render some text to get past FCP. - // Note that this frame is still considered pre-FCP. - auto* background = GetFrame()->GetDocument()->getElementById("bg"); - background->removeAttribute(html_names::kStyleAttr); - background->setInnerHTML("Some Text"); - GetWebView()->MainFrameViewWidget()->RecordStartOfFrameMetrics(); - ForceFullCompositingUpdate(); - GetWebView()->MainFrameViewWidget()->RecordEndOfFrameMetrics( - base::TimeTicks(), 0); - histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 2); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 2); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 0); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.AggregatedPreFCP", 1); - - // Removing a scrollable area should cause a scrolling update. - auto* scroller = GetFrame()->GetDocument()->getElementById("scroller"); - scroller->removeAttribute(html_names::kStyleAttr); - GetWebView()->MainFrameViewWidget()->RecordStartOfFrameMetrics(); - ForceFullCompositingUpdate(); - GetWebView()->MainFrameViewWidget()->RecordEndOfFrameMetrics( - base::TimeTicks(), 0); - histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 3); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 2); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 1); - histogram_tester.ExpectTotalCount( - "Blink.ScrollingCoordinator.UpdateTime.AggregatedPreFCP", 1); -} - TEST_P(ScrollingTest, NonCompositedNonFastScrollableRegion) { GetWebView()->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled( false);
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc index 2af1e3c..27d4c5f 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -1258,9 +1258,6 @@ if (scrolling_coordinator) { scrolling_coordinator->ScrollableAreaScrollLayerDidChange( scrollable_area); - const auto& object = GetLayoutObject(); - if (auto* layout_view = DynamicTo<LayoutView>(object)) - layout_view->GetFrameView()->ScrollableAreasDidChange(); } } } else if (scrolling_contents_layer_) { @@ -1269,9 +1266,6 @@ if (scrolling_coordinator && scrollable_area) { scrolling_coordinator->ScrollableAreaScrollLayerDidChange( scrollable_area); - const auto& object = GetLayoutObject(); - if (auto* layout_view = DynamicTo<LayoutView>(object)) - layout_view->GetFrameView()->ScrollableAreasDidChange(); } }
diff --git a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc index 2c83054..4a2adfc 100644 --- a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc +++ b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
@@ -43,7 +43,6 @@ #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h" #include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h" #include "third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h" @@ -322,14 +321,8 @@ CompositingLayerAssigner layer_assigner(this); layer_assigner.Assign(update_root, layers_needing_paint_invalidation); - if (layer_assigner.LayersChanged()) { + if (layer_assigner.LayersChanged()) update_type = std::max(update_type, kCompositingUpdateRebuildTree); - if (ScrollingCoordinator* scrolling_coordinator = - GetScrollingCoordinator()) { - LocalFrameView* frame_view = layout_view_->GetFrameView(); - scrolling_coordinator->NotifyGeometryChanged(frame_view); - } - } } GraphicsLayer* current_parent = nullptr; @@ -417,16 +410,6 @@ composited_layer_mapping_changed = true; RestartAnimationOnCompositor(layer->GetLayoutObject()); - - // At this time, the ScrollingCoordinator only supports the top-level - // frame. - if (layer->IsRootLayer() && layout_view_->GetFrame()->IsLocalRoot()) { - if (ScrollingCoordinator* scrolling_coordinator = - GetScrollingCoordinator()) { - scrolling_coordinator->FrameViewRootLayerDidChange( - layout_view_->GetFrameView()); - } - } break; case kRemoveOwnCompositedLayerMapping: // PutInSquashingLayer means you might have to remove the composited layer @@ -616,13 +599,6 @@ } } -ScrollingCoordinator* PaintLayerCompositor::GetScrollingCoordinator() const { - if (Page* page = GetPage()) - return page->GetScrollingCoordinator(); - - return nullptr; -} - Page* PaintLayerCompositor::GetPage() const { return layout_view_->GetFrameView()->GetFrame().GetPage(); }
diff --git a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h index 7154b1a..2c76a1ba 100644 --- a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h +++ b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
@@ -42,7 +42,6 @@ class LayoutView; class Page; class Scrollbar; -class ScrollingCoordinator; enum CompositingStateTransitionType { kNoCompositingStateChange, @@ -170,8 +169,6 @@ Page* GetPage() const; - ScrollingCoordinator* GetScrollingCoordinator() const; - // Checks the given graphics layer against the compositor's horizontal and // vertical scrollbar graphics layers, returning the associated Scrollbar // instance if any, else nullptr.
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index 89fee6b9..2515fb6 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -126,7 +126,6 @@ #include "third_party/blink/renderer/core/page/print_context.h" #include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h" #include "third_party/blink/renderer/core/page/scrolling/scroll_state.h" -#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h" #include "third_party/blink/renderer/core/page/spatial_navigation_controller.h" #include "third_party/blink/renderer/core/page/validation_message_client.h" #include "third_party/blink/renderer/core/page/viewport_description.h" @@ -2197,16 +2196,6 @@ return document->GetFrame()->View()->MainThreadScrollingReasonsAsText(); } -void Internals::markGestureScrollRegionDirty( - Document* document, - ExceptionState& exception_state) const { - FrameView* frame_view = document->View(); - if (!frame_view || !frame_view->IsLocalFrameView()) - return; - LocalFrameView* lfv = static_cast<LocalFrameView*>(frame_view); - lfv->GetScrollingContext()->SetScrollGestureRegionIsDirty(true); -} - DOMRectList* Internals::nonFastScrollableRects( Document* document, ExceptionState& exception_state) const {
diff --git a/third_party/blink/renderer/core/testing/internals.h b/third_party/blink/renderer/core/testing/internals.h index 4dc7737..9faef56 100644 --- a/third_party/blink/renderer/core/testing/internals.h +++ b/third_party/blink/renderer/core/testing/internals.h
@@ -358,7 +358,6 @@ String scrollingStateTreeAsText(Document*) const; String mainThreadScrollingReasons(Document*, ExceptionState&) const; - void markGestureScrollRegionDirty(Document*, ExceptionState&) const; DOMRectList* nonFastScrollableRects(Document*, ExceptionState&) const; void evictAllResources() const;
diff --git a/third_party/blink/renderer/core/testing/internals.idl b/third_party/blink/renderer/core/testing/internals.idl index fd393d1b..edf43e7 100644 --- a/third_party/blink/renderer/core/testing/internals.idl +++ b/third_party/blink/renderer/core/testing/internals.idl
@@ -206,7 +206,6 @@ DOMString scrollingStateTreeAsText(Document document); [RaisesException] DOMString mainThreadScrollingReasons(Document document); [RaisesException] DOMRectList nonFastScrollableRects(Document document); - [RaisesException] void markGestureScrollRegionDirty(Document document); void evictAllResources();
diff --git a/third_party/blink/renderer/modules/imagecapture/image_capture.cc b/third_party/blink/renderer/modules/imagecapture/image_capture.cc index 6dca159..70eff50 100644 --- a/third_party/blink/renderer/modules/imagecapture/image_capture.cc +++ b/third_party/blink/renderer/modules/imagecapture/image_capture.cc
@@ -771,8 +771,7 @@ media::mojom::blink::PhotoStatePtr photo_state) { UpdateMediaTrackCapabilities(base::DoNothing(), std::move(photo_state)); - MediaStreamVideoTrack* video_track = MediaStreamVideoTrack::GetVideoTrack( - WebMediaStreamTrack(stream_track_->Component())); + auto* video_track = MediaStreamVideoTrack::From(stream_track_->Component()); DCHECK(video_track); base::Optional<double> pan = video_track->pan();
diff --git a/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc b/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc index 30a8c9d..38b6d77 100644 --- a/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc +++ b/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc
@@ -286,8 +286,8 @@ blink::MediaStreamVideoTrack* ApplyConstraintsProcessor::GetCurrentVideoTrack() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - MediaStreamVideoTrack* track = MediaStreamVideoTrack::GetVideoTrack( - WebMediaStreamTrack(current_request_->Track())); + MediaStreamVideoTrack* track = + MediaStreamVideoTrack::From(current_request_->Track()); DCHECK(track); return track; }
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc index e51c6fa..4a267ac 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
@@ -181,8 +181,7 @@ MediaStreamVideoSource* native_source = MediaStreamVideoSource::GetVideoSource(source); DCHECK(native_source); - MediaStreamVideoTrack* original_track = - MediaStreamVideoTrack::GetVideoTrack(WebMediaStreamTrack(original)); + MediaStreamVideoTrack* original_track = MediaStreamVideoTrack::From(original); DCHECK(original_track); clone->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>( native_source, original_track->adapter_settings(), @@ -250,7 +249,7 @@ component_->SetMuted(ready_state_ == MediaStreamSource::kReadyStateMuted); MediaStreamVideoTrack* const video_track = - MediaStreamVideoTrack::GetVideoTrack(WebMediaStreamTrack(Component())); + MediaStreamVideoTrack::From(Component()); if (video_track && component_->Source() && component_->Source()->GetType() == MediaStreamSource::kTypeVideo) { bool pan_tilt_zoom_allowed =
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_sink.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_sink.cc index 3eb247d..c8ed9f8 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_video_sink.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_sink.cc
@@ -30,8 +30,7 @@ const EncodedVideoFrameCB& callback) { DCHECK(connected_encoded_track_.IsNull()); connected_encoded_track_ = track; - MediaStreamVideoTrack* const video_track = - MediaStreamVideoTrack::GetVideoTrack(track); + MediaStreamVideoTrack* const video_track = MediaStreamVideoTrack::From(track); DCHECK(video_track); video_track->AddEncodedSink(this, callback); } @@ -43,7 +42,7 @@ void MediaStreamVideoSink::DisconnectEncodedFromTrack() { MediaStreamVideoTrack* const video_track = - MediaStreamVideoTrack::GetVideoTrack(connected_encoded_track_); + MediaStreamVideoTrack::From(connected_encoded_track_); if (video_track) { video_track->RemoveEncodedSink(this); } @@ -55,8 +54,7 @@ if (connected_track_.IsNull()) return; - if (auto* const video_track = - MediaStreamVideoTrack::GetVideoTrack(connected_track_)) + if (auto* const video_track = MediaStreamVideoTrack::From(connected_track_)) video_track->OnFrameDropped(reason); }
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_source_test.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_source_test.cc index e63e9ea..f47919e 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_video_source_test.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_source_test.cc
@@ -449,8 +449,7 @@ EXPECT_EQ(track.Source().GetReadyState(), WebMediaStreamSource::kReadyStateLive); - MediaStreamVideoTrack* native_track = - MediaStreamVideoTrack::GetVideoTrack(track); + MediaStreamVideoTrack* native_track = MediaStreamVideoTrack::From(track); MediaStreamTrackPlatform::Settings settings; native_track->GetSettings(settings); EXPECT_EQ(settings.width, 640); @@ -480,8 +479,7 @@ EXPECT_EQ(track.Source().GetReadyState(), WebMediaStreamSource::kReadyStateLive); - MediaStreamVideoTrack* native_track = - MediaStreamVideoTrack::GetVideoTrack(track); + MediaStreamVideoTrack* native_track = MediaStreamVideoTrack::From(track); MediaStreamTrackPlatform::Settings settings; native_track->GetSettings(settings); EXPECT_EQ(settings.width, 640); @@ -683,15 +681,13 @@ // Simulate assigning |track1| to a sink, then removing it from the sink, and // then stopping it. - MediaStreamVideoTrack* track1 = - MediaStreamVideoTrack::GetVideoTrack(web_track1); + MediaStreamVideoTrack* track1 = MediaStreamVideoTrack::From(web_track1); mock_source()->UpdateHasConsumers(track1, true); mock_source()->UpdateHasConsumers(track1, false); track1->Stop(); // Simulate assigning |track2| to a sink. The source should not be suspended. - MediaStreamVideoTrack* track2 = - MediaStreamVideoTrack::GetVideoTrack(web_track2); + MediaStreamVideoTrack* track2 = MediaStreamVideoTrack::From(web_track2); mock_source()->UpdateHasConsumers(track2, true); EXPECT_FALSE(mock_source()->is_suspended()); } @@ -702,8 +698,7 @@ EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks()); EXPECT_EQ(0, NumberOfFailedConstraintsCallbacks()); - MediaStreamVideoTrack* track1 = - MediaStreamVideoTrack::GetVideoTrack(web_track1); + MediaStreamVideoTrack* track1 = MediaStreamVideoTrack::From(web_track1); EXPECT_CALL(*this, MockNotification()); // This is equivalent to track.stop() in JavaScript. track1->StopAndNotify(WTF::Bind(&MediaStreamVideoSourceTest::MockNotification, @@ -779,8 +774,8 @@ InSequence s; EXPECT_CALL(*mock_source(), OnCapturingLinkSecured(true)); WebMediaStreamTrack track = CreateTrack(); - mock_source()->UpdateCapturingLinkSecure( - MediaStreamVideoTrack::GetVideoTrack(track), true); + mock_source()->UpdateCapturingLinkSecure(MediaStreamVideoTrack::From(track), + true); EXPECT_CALL(*mock_source(), OnCapturingLinkSecured(false)); MockMediaStreamVideoSink sink; @@ -788,8 +783,8 @@ EXPECT_CALL(*mock_source(), OnCapturingLinkSecured(true)); sink.DisconnectEncodedFromTrack(); EXPECT_CALL(*mock_source(), OnCapturingLinkSecured(false)); - mock_source()->UpdateCapturingLinkSecure( - MediaStreamVideoTrack::GetVideoTrack(track), false); + mock_source()->UpdateCapturingLinkSecure(MediaStreamVideoTrack::From(track), + false); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc index 73d097c5..fa36dc3 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
@@ -430,16 +430,14 @@ } // static -MediaStreamVideoTrack* MediaStreamVideoTrack::GetVideoTrack( - const WebMediaStreamTrack& track) { - if (track.IsNull()) +MediaStreamVideoTrack* MediaStreamVideoTrack::From( + const MediaStreamComponent* component) { + if (!component || + component->Source()->GetType() != MediaStreamSource::kTypeVideo) { return nullptr; + } - MediaStreamComponent& component = *track; - if (component.Source()->GetType() != MediaStreamSource::kTypeVideo) - return nullptr; - - return static_cast<MediaStreamVideoTrack*>(component.GetPlatformTrack()); + return static_cast<MediaStreamVideoTrack*>(component->GetPlatformTrack()); } MediaStreamVideoTrack::MediaStreamVideoTrack(
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.h b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.h index ceed5e4..6475e37 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.h +++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.h
@@ -55,7 +55,7 @@ MediaStreamVideoSource::ConstraintsOnceCallback callback, bool enabled); - static MediaStreamVideoTrack* GetVideoTrack(const WebMediaStreamTrack& track); + static MediaStreamVideoTrack* From(const MediaStreamComponent* track); // Constructors for video tracks. MediaStreamVideoTrack(
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_track_test.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_track_test.cc index b8b7820..d1e9e2e 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_video_track_test.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_track_test.cc
@@ -238,8 +238,7 @@ WebMediaStreamTrack track = CreateTrack(); sink.ConnectToTrack(track); - MediaStreamVideoTrack* video_track = - MediaStreamVideoTrack::GetVideoTrack(track); + MediaStreamVideoTrack* video_track = MediaStreamVideoTrack::From(track); DeliverDefaultSizeVideoFrameAndWaitForRenderer(&sink); EXPECT_EQ(1, sink.number_of_frames()); @@ -264,7 +263,7 @@ InitializeSource(); WebMediaStreamTrack track = CreateTrack(); MockMediaStreamVideoSink sink; - auto* video_track = MediaStreamVideoTrack::GetVideoTrack(track); + auto* video_track = MediaStreamVideoTrack::From(track); video_track->StopAndNotify(base::BindOnce([] {})); sink.ConnectToTrack(track); sink.ConnectEncodedToTrack(track); @@ -304,7 +303,7 @@ EXPECT_EQ(WebMediaStreamSource::kReadyStateLive, sink2.state()); MediaStreamVideoTrack* const native_track1 = - MediaStreamVideoTrack::GetVideoTrack(track1); + MediaStreamVideoTrack::From(track1); native_track1->Stop(); EXPECT_EQ(WebMediaStreamSource::kReadyStateEnded, sink1.state()); EXPECT_EQ(MediaStreamSource::kReadyStateLive, @@ -312,7 +311,7 @@ sink1.DisconnectFromTrack(); MediaStreamVideoTrack* const native_track2 = - MediaStreamVideoTrack::GetVideoTrack(track2); + MediaStreamVideoTrack::From(track2); native_track2->Stop(); EXPECT_EQ(WebMediaStreamSource::kReadyStateEnded, sink2.state()); EXPECT_EQ(MediaStreamSource::kReadyStateEnded, @@ -342,7 +341,7 @@ InitializeSource(); WebMediaStreamTrack track = CreateTrack(); MediaStreamVideoTrack* const native_track = - MediaStreamVideoTrack::GetVideoTrack(track); + MediaStreamVideoTrack::From(track); MediaStreamTrackPlatform::Settings settings; native_track->GetSettings(settings); // These values come straight from the mock video track implementation. @@ -362,7 +361,7 @@ kAdjustedFrameRate); WebMediaStreamTrack track = CreateTrackWithSettings(adapter_settings); MediaStreamVideoTrack* const native_track = - MediaStreamVideoTrack::GetVideoTrack(track); + MediaStreamVideoTrack::From(track); MediaStreamTrackPlatform::Settings settings; native_track->GetSettings(settings); EXPECT_EQ(kAdjustedWidth, settings.width); @@ -375,7 +374,7 @@ InitializeSource(); WebMediaStreamTrack track = CreateTrack(); MediaStreamVideoTrack* const native_track = - MediaStreamVideoTrack::GetVideoTrack(track); + MediaStreamVideoTrack::From(track); native_track->Stop(); MediaStreamTrackPlatform::Settings settings; native_track->GetSettings(settings); @@ -392,7 +391,7 @@ WebMediaStreamTrack track = CreateTrack(); sink.ConnectToTrack(track); MediaStreamVideoTrack* const native_track = - MediaStreamVideoTrack::GetVideoTrack(track); + MediaStreamVideoTrack::From(track); MediaStreamTrackPlatform::Settings settings; auto frame1 = media::VideoFrame::CreateBlackFrame(gfx::Size(600, 400)); @@ -415,7 +414,7 @@ MockMediaStreamVideoSink sink; WebMediaStreamTrack track = CreateTrack(); sink.ConnectToTrack(track); - MediaStreamVideoTrack::GetVideoTrack(track)->SetContentHint(GetParam()); + MediaStreamVideoTrack::From(track)->SetContentHint(GetParam()); EXPECT_EQ(sink.content_hint(), GetParam()); sink.DisconnectFromTrack(); } @@ -500,7 +499,7 @@ DeliverEncodedVideoFrameAndWait(key_frame, &sink); // Key frame when disabled -> shouldn't get dispatched - MediaStreamVideoTrack::GetVideoTrack(track)->SetEnabled(false); + MediaStreamVideoTrack::From(track)->SetEnabled(false); EXPECT_FALSE(sink.enabled()); { EXPECT_CALL(sink, OnEncodedVideoFrame).Times(0); @@ -511,7 +510,7 @@ // Delta frame when disabled -> shouldn't get dispatched until key frame // appears. EXPECT_CALL(*mock_source(), OnRequestRefreshFrame); - MediaStreamVideoTrack::GetVideoTrack(track)->SetEnabled(true); + MediaStreamVideoTrack::From(track)->SetEnabled(true); EXPECT_TRUE(sink.enabled()); { EXPECT_CALL(sink, OnEncodedVideoFrame).Times(0); @@ -532,7 +531,7 @@ MockMediaStreamVideoSink sink; WebMediaStreamTrack track = CreateTrack(); sink.ConnectEncodedToTrack(track); - MediaStreamVideoTrack::GetVideoTrack(track)->SetContentHint(GetParam()); + MediaStreamVideoTrack::From(track)->SetContentHint(GetParam()); EXPECT_EQ(sink.content_hint(), GetParam()); sink.DisconnectEncodedFromTrack(); } @@ -575,7 +574,7 @@ MockMediaStreamVideoSink sink; WebMediaStreamTrack track = CreateTrackWithSettings(VideoTrackAdapterSettings()); - auto* video_track = MediaStreamVideoTrack::GetVideoTrack(track); + auto* video_track = MediaStreamVideoTrack::From(track); video_track->SetMinimumFrameRate(kMinFrameRate); video_track->SetIsScreencastForTesting(true); @@ -596,7 +595,7 @@ WebMediaStreamTrack track = CreateTrackWithSettings(VideoTrackAdapterSettings()); - auto* video_track = MediaStreamVideoTrack::GetVideoTrack(track); + auto* video_track = MediaStreamVideoTrack::From(track); video_track->SetMinimumFrameRate(kMinFrameRate); // Refresh frame timer will not be run when |is_screencast_| is false. video_track->SetIsScreencastForTesting(false); @@ -617,7 +616,7 @@ WebMediaStreamTrack track = CreateTrackWithSettings(VideoTrackAdapterSettings()); - auto* video_track = MediaStreamVideoTrack::GetVideoTrack(track); + auto* video_track = MediaStreamVideoTrack::From(track); video_track->SetIsScreencastForTesting(true); sink.ConnectToTrack(track); @@ -634,7 +633,7 @@ WebMediaStreamTrack track = MediaStreamVideoTrack::CreateVideoTrack( mock_source(), WebPlatformMediaStreamSource::ConstraintsOnceCallback(), true); - MediaStreamVideoTrack::GetVideoTrack(track)->SetIsScreencastForTesting(true); + MediaStreamVideoTrack::From(track)->SetIsScreencastForTesting(true); Persistent<MediaStreamComponent> media_stream_component = *track; blink::MediaStreamVideoWebRtcSink webrtc_sink( @@ -655,7 +654,7 @@ WebMediaStreamTrack track = MediaStreamVideoTrack::CreateVideoTrack( mock_source(), WebPlatformMediaStreamSource::ConstraintsOnceCallback(), true); - MediaStreamVideoTrack::GetVideoTrack(track)->SetIsScreencastForTesting(true); + MediaStreamVideoTrack::From(track)->SetIsScreencastForTesting(true); // First sink. MockMediaStreamVideoSink sink; @@ -682,7 +681,7 @@ WebMediaStreamTrack track = MediaStreamVideoTrack::CreateVideoTrack( mock_source(), WebPlatformMediaStreamSource::ConstraintsOnceCallback(), true); - MediaStreamVideoTrack::GetVideoTrack(track)->SetIsScreencastForTesting(true); + MediaStreamVideoTrack::From(track)->SetIsScreencastForTesting(true); // First sink. MockMediaStreamVideoSink sink;
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc b/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc index f53db188..af4af43b 100644 --- a/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc +++ b/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc
@@ -129,8 +129,7 @@ expected_source_frame_rate); EXPECT_EQ(component->Source()->GetReadyState(), MediaStreamSource::kReadyStateLive); - MediaStreamVideoTrack* track = - MediaStreamVideoTrack::GetVideoTrack(WebMediaStreamTrack(component)); + MediaStreamVideoTrack* track = MediaStreamVideoTrack::From(component); EXPECT_EQ(track->source(), source); MediaStreamTrackPlatform::Settings settings; @@ -1182,8 +1181,7 @@ TEST_F(UserMediaClientTest, ApplyConstraintsVideoDeviceSingleTrack) { EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_)); MediaStreamComponent* component = RequestLocalVideoTrack(); - MediaStreamVideoTrack* track = - MediaStreamVideoTrack::GetVideoTrack(WebMediaStreamTrack(component)); + MediaStreamVideoTrack* track = MediaStreamVideoTrack::From(component); blink::MediaStreamVideoSource* source = track->source(); CheckVideoSource(source, 0, 0, 0.0);
diff --git a/third_party/blink/renderer/modules/mediastream/web_media_stream_utils.cc b/third_party/blink/renderer/modules/mediastream/web_media_stream_utils.cc index 648eab54..c88f2bba 100644 --- a/third_party/blink/renderer/modules/mediastream/web_media_stream_utils.cc +++ b/third_party/blink/renderer/modules/mediastream/web_media_stream_utils.cc
@@ -21,16 +21,14 @@ WebMediaStreamSink* sink, const VideoCaptureDeliverFrameCB& callback, bool is_sink_secure) { - MediaStreamVideoTrack* const video_track = - MediaStreamVideoTrack::GetVideoTrack(track); + MediaStreamVideoTrack* const video_track = MediaStreamVideoTrack::From(track); DCHECK(video_track); video_track->AddSink(sink, callback, is_sink_secure); } void RemoveSinkFromMediaStreamTrack(const WebMediaStreamTrack& track, WebMediaStreamSink* sink) { - MediaStreamVideoTrack* const video_track = - MediaStreamVideoTrack::GetVideoTrack(track); + MediaStreamVideoTrack* const video_track = MediaStreamVideoTrack::From(track); if (video_track) video_track->RemoveSink(sink); }
diff --git a/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc b/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc index 182e713..ed13308 100644 --- a/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc +++ b/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc
@@ -161,8 +161,7 @@ MediaStreamComponent* component, PeerConnectionDependencyFactory* factory, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { - MediaStreamVideoTrack* video_track = - MediaStreamVideoTrack::GetVideoTrack(WebMediaStreamTrack(component)); + MediaStreamVideoTrack* video_track = MediaStreamVideoTrack::From(component); DCHECK(video_track); absl::optional<bool> needs_denoising =
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc index eae548e..64ec47e 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
@@ -395,11 +395,10 @@ void StopAllTracks(MediaStreamDescriptor* descriptor) { for (auto component : descriptor->AudioComponents()) - MediaStreamAudioTrack::From(WebMediaStreamTrack(component.Get()))->Stop(); + MediaStreamAudioTrack::From(component.Get())->Stop(); for (auto component : descriptor->VideoComponents()) { - MediaStreamVideoTrack::GetVideoTrack(WebMediaStreamTrack(component.Get())) - ->Stop(); + MediaStreamVideoTrack::From(component.Get())->Stop(); } }
diff --git a/third_party/blink/renderer/modules/shapedetection/shape_detector.cc b/third_party/blink/renderer/modules/shapedetection/shape_detector.cc index cb8f225ea..28715ca 100644 --- a/third_party/blink/renderer/modules/shapedetection/shape_detector.cc +++ b/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
@@ -120,24 +120,17 @@ } SkBitmap sk_bitmap; - if (!sk_bitmap.tryAllocPixels( - SkImageInfo::Make(image_data->width(), image_data->height(), - kN32_SkColorType, kOpaque_SkAlphaType), - image_data->width() * 4 /* bytes per pixel */)) { + SkImageInfo sk_image_info = image_data->GetSkImageInfo(); + if (!sk_bitmap.tryAllocPixels(sk_image_info, sk_image_info.minRowBytes())) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, "Failed to allocate pixels for current frame.")); return promise; } - base::CheckedNumeric<int> allocation_size = image_data->Size().Area() * 4; - CHECK_EQ(allocation_size.ValueOrDefault(0), sk_bitmap.computeByteSize()); - - // TODO(crbug.com/1115317): Should be compatible with uint_8, float16 and - // float32. - memcpy(sk_bitmap.getPixels(), - image_data->data().GetAsUint8ClampedArray()->Data(), - sk_bitmap.computeByteSize()); + size_t byte_size = sk_bitmap.computeByteSize(); + CHECK_EQ(byte_size, image_data->BufferBase()->ByteLengthAsSizeT()); + memcpy(sk_bitmap.getPixels(), image_data->BufferBase()->Data(), byte_size); return DoDetect(resolver, std::move(sk_bitmap)); }
diff --git a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc index 74bfb7c..9bdfead2 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
@@ -131,8 +131,6 @@ layer_state.Effect().HasBackdropEffect() || !layer_state.Effect().Filter().IsEmpty()); - PaintChunksToCcLayer::UpdateBackgroundColor(*cc_picture_layer_, paint_chunks); - return cc_picture_layer_; }
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc index 85de5399..09313a5 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -118,13 +118,6 @@ return layers_as_json.Finalize(); } -static void UpdateLayerProperties(const GraphicsLayer& graphics_layer) { - PaintChunksToCcLayer::UpdateBackgroundColor( - graphics_layer.CcLayer(), - PaintChunkSubset( - graphics_layer.GetPaintController().GetPaintArtifactShared())); -} - scoped_refptr<cc::Layer> PaintArtifactCompositor::WrappedCcLayerForPendingLayer( const PendingLayer& pending_layer) { if (pending_layer.compositing_type != PendingLayer::kForeignLayer && @@ -139,8 +132,6 @@ layer = &pending_layer.graphics_layer->CcLayer(); layer_offset = FloatPoint(pending_layer.graphics_layer->GetOffsetFromTransformNode()); - if (pending_layer.graphics_layer->Repainted()) - UpdateLayerProperties(*pending_layer.graphics_layer); } else { DCHECK_EQ(pending_layer.compositing_type, PendingLayer::kForeignLayer); // UpdateTouchActionRects() depends on the layer's offset, but when the @@ -314,83 +305,6 @@ return cc_layer; } -void PaintArtifactCompositor::UpdateTouchActionRects( - cc::Layer& layer, - const gfx::Vector2dF& layer_offset, - const PropertyTreeState& layer_state, - const PaintChunkSubset& paint_chunks) { - cc::TouchActionRegion touch_action_in_layer_space; - for (const auto& chunk : paint_chunks) { - const auto* hit_test_data = chunk.hit_test_data.get(); - if (!hit_test_data || hit_test_data->touch_action_rects.IsEmpty()) - continue; - - const auto& chunk_state = chunk.properties.GetPropertyTreeState().Unalias(); - for (const auto& touch_action_rect : hit_test_data->touch_action_rects) { - auto rect = FloatClipRect(FloatRect(touch_action_rect.rect)); - if (!GeometryMapper::LocalToAncestorVisualRect(chunk_state, layer_state, - rect)) { - continue; - } - rect.MoveBy(FloatPoint(-layer_offset.x(), -layer_offset.y())); - touch_action_in_layer_space.Union( - touch_action_rect.allowed_touch_action, - (gfx::Rect)EnclosingIntRect(rect.Rect())); - } - } - layer.SetTouchActionRegion(std::move(touch_action_in_layer_space)); -} - -void PaintArtifactCompositor::UpdateNonFastScrollableRegions( - cc::Layer& layer, - const gfx::Vector2dF& layer_offset, - const PropertyTreeState& layer_state, - const PaintChunkSubset& paint_chunks, - PropertyTreeManager* property_tree_manager) { - cc::Region non_fast_scrollable_regions_in_layer_space; - for (const auto& chunk : paint_chunks) { - // Add any non-fast scrollable hit test data from the paint chunk. - const auto* hit_test_data = chunk.hit_test_data.get(); - if (!hit_test_data || hit_test_data->scroll_hit_test_rect.IsEmpty()) - continue; - - // Skip the scroll hit test rect if it is for scrolling this cc::Layer. - // This is only needed for CompositeAfterPaint because - // pre-CompositeAfterPaint does not paint scroll hit test data for - // composited scrollers. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - if (const auto* scroll_translation = hit_test_data->scroll_translation) { - const auto& scroll_node = *scroll_translation->ScrollNode(); - auto scroll_element_id = scroll_node.GetCompositorElementId(); - if (layer.element_id() == scroll_element_id) - continue; - // Ensure the cc scroll node to prepare for possible descendant nodes - // referenced by later composited layers. This can't be done by ensuring - // parent transform node in EnsureCompositorTransformNode() if the - // transform tree and the scroll tree have different topologies. - // This is not necessary with ScrollUnification which ensures the - // complete scroll tree. - if (!RuntimeEnabledFeatures::ScrollUnificationEnabled()) { - DCHECK(property_tree_manager); - property_tree_manager->EnsureCompositorScrollNode( - *scroll_translation); - } - } - } - - FloatClipRect rect(FloatRect(chunk.hit_test_data->scroll_hit_test_rect)); - const auto& chunk_state = chunk.properties.GetPropertyTreeState().Unalias(); - if (!GeometryMapper::LocalToAncestorVisualRect(chunk_state, layer_state, - rect)) { - continue; - } - rect.MoveBy(FloatPoint(-layer_offset.x(), -layer_offset.y())); - non_fast_scrollable_regions_in_layer_space.Union( - EnclosingIntRect(rect.Rect())); - } - layer.SetNonFastScrollableRegion(non_fast_scrollable_regions_in_layer_space); -} - bool PaintArtifactCompositor::HasComposited( CompositorElementId element_id) const { // |Update| creates PropertyTrees on the LayerTreeHost to represent the @@ -1256,15 +1170,7 @@ pending_layer, new_content_layer_clients, new_scroll_hit_test_layers, new_scrollbar_layers); - // In Pre-CompositeAfterPaint, touch action rects and non-fast scrollable - // regions are updated through ScrollingCoordinator. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - UpdateTouchActionRects(*layer, layer->offset_to_transform_parent(), - property_state, pending_layer.chunks); - UpdateNonFastScrollableRegions( - *layer, layer->offset_to_transform_parent(), property_state, - pending_layer.chunks, &property_tree_manager); - } + UpdateLayerProperties(*layer, pending_layer, &property_tree_manager); layer->SetLayerTreeHost(root_layer_->layer_tree_host()); @@ -1347,6 +1253,24 @@ .Utf8(); } +void PaintArtifactCompositor::UpdateLayerProperties( + cc::Layer& layer, + const PendingLayer& pending_layer, + PropertyTreeManager* property_tree_manager) { + // Properties of foreign layers are managed by their owners. + if (pending_layer.compositing_type == PendingLayer::kForeignLayer) + return; + + PaintChunkSubset chunks = pending_layer.chunks; + if (pending_layer.graphics_layer && + pending_layer.graphics_layer->PaintsContentOrHitTest()) { + chunks = PaintChunkSubset(pending_layer.graphics_layer->GetPaintController() + .GetPaintArtifactShared()); + } + PaintChunksToCcLayer::UpdateLayerProperties( + layer, pending_layer.property_tree_state, chunks, property_tree_manager); +} + void PaintArtifactCompositor::UpdateRepaintedLayerProperties() const { // TODO(paint-dev): Implement repaint-only update for CompositeAfterPaint. if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) @@ -1356,8 +1280,10 @@ if (pending_layer.compositing_type != PendingLayer::kPreCompositedLayer) continue; DCHECK(pending_layer.graphics_layer); - if (pending_layer.graphics_layer->Repainted()) - UpdateLayerProperties(*pending_layer.graphics_layer); + if (pending_layer.graphics_layer->Repainted()) { + UpdateLayerProperties(pending_layer.graphics_layer->CcLayer(), + pending_layer); + } } UpdateDebugInfo();
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h index 5f08ff30..8611f85 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
@@ -31,16 +31,11 @@ class ScrollbarLayerBase; } -namespace gfx { -class Vector2dF; -} - namespace blink { class ContentLayerClientImpl; class GraphicsLayer; class JSONObject; -class PropertyTreeManager; class SynthesizedClip; using CompositorScrollCallbacks = cc::ScrollCallbacks; @@ -199,22 +194,6 @@ return content_layer_clients_; } - // Update the cc::Layer's touch action region from the touch action rects of - // the paint chunks. - static void UpdateTouchActionRects(cc::Layer&, - const gfx::Vector2dF& layer_offset, - const PropertyTreeState& layer_state, - const PaintChunkSubset& paint_chunks); - - // Update the cc::Layer's non-fast scrollable region from the non-fast regions - // in the paint chunks. - static void UpdateNonFastScrollableRegions( - cc::Layer&, - const gfx::Vector2dF& layer_offset, - const PropertyTreeState& layer_state, - const PaintChunkSubset& paint_chunks, - PropertyTreeManager* = nullptr); - void SetNeedsUpdate() { needs_update_ = true; } bool NeedsUpdate() const { return needs_update_; } void ClearNeedsUpdateForTesting() { needs_update_ = false; } @@ -298,8 +277,9 @@ CompositingType compositing_type; }; - void UpdateRepaintedLayerProperties( - const HashSet<const GraphicsLayer*>& repainted_layers) const; + static void UpdateLayerProperties(cc::Layer&, + const PendingLayer&, + PropertyTreeManager* = nullptr); void DecompositeTransforms();
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc index 1dd13da3..20eded2f 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
@@ -10,6 +10,7 @@ #include "cc/paint/paint_op_buffer.h" #include "cc/paint/render_surface_filters.h" #include "third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper.h" +#include "third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/display_item_list.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h" @@ -809,9 +810,8 @@ // - The same color is used for the layer's safe opaque background color, but // without the size requirement, as safe opaque background color should // always get a value if possible. -void PaintChunksToCcLayer::UpdateBackgroundColor( - cc::Layer& layer, - const PaintChunkSubset& paint_chunks) { +static void UpdateBackgroundColor(cc::Layer& layer, + const PaintChunkSubset& paint_chunks) { SkColor color = SK_ColorTRANSPARENT; uint64_t area = 0; for (const auto& chunk : paint_chunks) { @@ -831,4 +831,98 @@ layer.SetBackgroundColor(color); } +static void UpdateTouchActionRegion( + const HitTestData& hit_test_data, + const PropertyTreeState& layer_state, + const PropertyTreeState& chunk_state, + const FloatPoint& layer_offset, + cc::TouchActionRegion& touch_action_region) { + for (const auto& touch_action_rect : hit_test_data.touch_action_rects) { + auto rect = FloatClipRect(FloatRect(touch_action_rect.rect)); + if (!GeometryMapper::LocalToAncestorVisualRect(chunk_state, layer_state, + rect)) { + continue; + } + rect.MoveBy(-layer_offset); + touch_action_region.Union(touch_action_rect.allowed_touch_action, + gfx::Rect(EnclosingIntRect(rect.Rect()))); + } +} + +static void UpdateNonFastScrollableRegion( + cc::Layer& layer, + const HitTestData& hit_test_data, + const PropertyTreeState& layer_state, + const PropertyTreeState& chunk_state, + const FloatPoint& layer_offset, + PropertyTreeManager* property_tree_manager, + cc::Region& non_fast_scrollable_region) { + if (hit_test_data.scroll_hit_test_rect.IsEmpty()) + return; + + // Skip the scroll hit test rect if it is for scrolling this cc::Layer. + // This is only needed for CompositeAfterPaint because + // pre-CompositeAfterPaint does not paint scroll hit test data for + // composited scrollers. + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + if (const auto* scroll_translation = hit_test_data.scroll_translation) { + const auto& scroll_node = *scroll_translation->ScrollNode(); + auto scroll_element_id = scroll_node.GetCompositorElementId(); + if (layer.element_id() == scroll_element_id) + return; + // Ensure the cc scroll node to prepare for possible descendant nodes + // referenced by later composited layers. This can't be done by ensuring + // parent transform node in EnsureCompositorTransformNode() if the + // transform tree and the scroll tree have different topologies. + // This is not necessary with ScrollUnification which ensures the + // complete scroll tree. + if (!RuntimeEnabledFeatures::ScrollUnificationEnabled()) { + DCHECK(property_tree_manager); + property_tree_manager->EnsureCompositorScrollNode(*scroll_translation); + } + } + } + + FloatClipRect rect(FloatRect(hit_test_data.scroll_hit_test_rect)); + if (!GeometryMapper::LocalToAncestorVisualRect(chunk_state, layer_state, + rect)) + return; + + rect.MoveBy(-layer_offset); + non_fast_scrollable_region.Union(EnclosingIntRect(rect.Rect())); +} + +static void UpdateTouchActionAndNonFastScrollableRegions( + cc::Layer& layer, + const PropertyTreeState& layer_state, + const PaintChunkSubset& chunks, + PropertyTreeManager* property_tree_manager) { + gfx::Vector2dF cc_layer_offset = layer.offset_to_transform_parent(); + FloatPoint layer_offset(cc_layer_offset.x(), cc_layer_offset.y()); + cc::TouchActionRegion touch_action_region; + cc::Region non_fast_scrollable_region; + for (const auto& chunk : chunks) { + if (!chunk.hit_test_data) + continue; + auto chunk_state = chunk.properties.GetPropertyTreeState().Unalias(); + UpdateTouchActionRegion(*chunk.hit_test_data, layer_state, chunk_state, + layer_offset, touch_action_region); + UpdateNonFastScrollableRegion( + layer, *chunk.hit_test_data, layer_state, chunk_state, layer_offset, + property_tree_manager, non_fast_scrollable_region); + } + layer.SetTouchActionRegion(std::move(touch_action_region)); + layer.SetNonFastScrollableRegion(std::move(non_fast_scrollable_region)); +} + +void PaintChunksToCcLayer::UpdateLayerProperties( + cc::Layer& layer, + const PropertyTreeState& layer_state, + const PaintChunkSubset& chunks, + PropertyTreeManager* property_tree_manager) { + UpdateBackgroundColor(layer, chunks); + UpdateTouchActionAndNonFastScrollableRegions(layer, layer_state, chunks, + property_tree_manager); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.h b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.h index c549b21..5b311bb 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.h +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.h
@@ -25,6 +25,7 @@ namespace blink { class PaintChunkSubset; +class PropertyTreeManager; class PropertyTreeState; class RasterInvalidationTracking; @@ -71,8 +72,10 @@ cc::DisplayItemList::UsageHint, RasterUnderInvalidationCheckingParams* = nullptr); - static void UpdateBackgroundColor(cc::Layer& layer, - const PaintChunkSubset& paint_chunks); + static void UpdateLayerProperties(cc::Layer& layer, + const PropertyTreeState& layer_state, + const PaintChunkSubset&, + PropertyTreeManager* = nullptr); }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index eda38c9..7312a356 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1668,7 +1668,7 @@ }, { name: "ScrollbarGutter", - status: "test", + status: "experimental", }, { name: "ScrollCustomization",
diff --git a/third_party/blink/tools/OWNERS b/third_party/blink/tools/OWNERS index 6e9e9c7b..aacb4c1 100644 --- a/third_party/blink/tools/OWNERS +++ b/third_party/blink/tools/OWNERS
@@ -4,5 +4,8 @@ tkent@chromium.org wangxianzhu@chromium.org +# For Fuchsia related files +per-file *fuchsia.py=file://build/fuchsia/OWNERS + # TEAM: blink-infra@chromium.org # COMPONENT: Blink>Infra
diff --git a/third_party/blink/web_tests/compositing/layer-creation/fixed-position-change-out-of-view-in-view-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/fixed-position-change-out-of-view-in-view-expected.txt index 4b6aca6d..f11fea8e 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/fixed-position-change-out-of-view-in-view-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/fixed-position-change-out-of-view-in-view-expected.txt
@@ -121,7 +121,6 @@ "name": "LayoutNGBlockFlow (positioned) DIV id='fixed2'", "contentsOpaque": true, "drawsContent": false, - "backgroundColor": "#C0C0C0", "transform": 2 }, {
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 19155fb1..b9d4da1 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -242378,7 +242378,7 @@ [] ], "safari-technology-preview.rb": [ - "0268ac4b4485d9f688636954fb5b3cc2ade01f3a", + "1a3620529c0403522a3ace06f9f1606d1633c5f8", [] ], "system_info.yml": [ @@ -349804,7 +349804,7 @@ ] ], "reporting-to-endpoint.https.html": [ - "416732497bdd58f654cbfd883721352a8c7ecba7", + "7294bdeafab2c32512983954ed20d617a1418f29", [ null, {
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html index 4167324..7294bdea 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html
@@ -26,53 +26,57 @@ return new Promise(resolve => step_timeout(resolve, ms)); } -async function pollReports(endpoint, reports) { - while (true) { - await wait(200); - const res = await fetch(`resources/report.py?endpoint=${endpoint}`, {cache: 'no-store'}); - if (res.status !== 200) { - continue; - } - for (const report of await res.json()) { - reports.push(report); - } +async function fetchReports(endpoint) { + const res = await fetch(`resources/report.py?endpoint=${endpoint}`, {cache: 'no-store'}); + if (res.status == 200) { + return await res.json(); } + return []; } -const reports = []; -const reportsForReportOnly = []; -pollReports('endpoint', reports); -pollReports('report-only-endpoint', reportsForReportOnly); - -function checkCorpReportExistence(reports, blockedUrl, contextUrl, destination, disposition) { +async function checkCorpReportExistence(endpoint, blockedUrl, contextUrl, destination, disposition) { blockedUrl = new URL(blockedUrl, location).href; contextUrl = new URL(contextUrl, location).href; - for (const report of reports) { - if (report.type !== 'coep' || report.url !== contextUrl || - report.body.type !== 'corp') { - continue; + + const timeout = 3000; + const retryDelay = 200; + for (let i = 0; i * retryDelay < timeout; i++) { + const reports = await fetchReports(endpoint); + for (const report of reports) { + if (report.type !== 'coep' || report.url !== contextUrl || + report.body.type !== 'corp') { + continue; + } + if (report.body.blockedURL === blockedUrl && + report.body.disposition === disposition) { + assert_equals(report.body.destination, destination); + return; + } } - if (report.body.blockedURL === blockedUrl && - report.body.disposition === disposition) { - assert_equals(report.body.destination, destination); - return; - } + await wait(retryDelay); } assert_unreached(`A report whose blockedURL is ${blockedUrl} and url is ${contextUrl} is not found.`); } -function checkNavigationReportExistence(reports, blockedUrl, contextUrl, disposition) { +async function checkNavigationReportExistence(endpoint, blockedUrl, contextUrl, disposition) { blockedUrl = new URL(blockedUrl, location).href; contextUrl = new URL(contextUrl, location).href; - for (const report of reports) { - if (report.type !== 'coep' || report.url !== contextUrl || - report.body.type !== 'navigation') { - continue; + const timeout = 3000; + const retryDelay = 200; + for (let i = 0; i * retryDelay < timeout; i++) { + const reports = await fetchReports(endpoint); + + for (const report of reports) { + if (report.type !== 'coep' || report.url !== contextUrl || + report.body.type !== 'navigation') { + continue; + } + if (report.body.blockedURL === blockedUrl && + report.body.disposition === disposition) { + return; + } } - if (report.body.blockedURL === blockedUrl && - report.body.disposition === disposition) { - return; - } + await wait(retryDelay); } assert_unreached(`A report whose blockedURL is ${blockedUrl} and url is ${contextUrl} is not found.`); } @@ -93,12 +97,9 @@ // header, so it is blocked. iframe.contentWindow.fetch(url, init).catch(() => {}); - // Wait 3 seconds for reports to settle. - await wait(3000); - - checkCorpReportExistence(reports, url, iframe.src, '', 'enforce'); - checkCorpReportExistence( - reportsForReportOnly, url, iframe.src, '', 'reporting'); + await checkCorpReportExistence('endpoint', url, iframe.src, '', 'enforce'); + await checkCorpReportExistence( + 'report-only-endpoint', url, iframe.src, '', 'reporting'); }, 'subresource CORP'); promise_test(async t => { @@ -124,12 +125,10 @@ // header, so it is blocked. attachFrame(url); - // Wait 3 seconds for reports to settle. - await wait(3000); - - checkCorpReportExistence(reports, url, iframe.src, 'iframe', 'enforce'); - checkCorpReportExistence( - reportsForReportOnly, url, iframe.src, 'iframe', 'reporting'); + await checkCorpReportExistence( + 'endpoint', url, iframe.src, 'iframe', 'enforce'); + await checkCorpReportExistence( + 'report-only-endpoint', url, iframe.src, 'iframe', 'reporting'); }, 'navigation CORP'); promise_test(async (t) => { @@ -147,12 +146,10 @@ document.body.appendChild(iframe); - // Wait 3 seconds for reports to settle. - await wait(3000); - - checkNavigationReportExistence(reports, targetUrl, iframe.src, 'enforce'); - checkNavigationReportExistence( - reportsForReportOnly, targetUrl, iframe.src, 'reporting'); + await checkNavigationReportExistence( + 'endpoint', targetUrl, iframe.src, 'enforce'); + await checkNavigationReportExistence( + 'report-only-endpoint', targetUrl, iframe.src, 'reporting'); }, 'COEP violation on nested frame navigation'); -</script>$ +</script>
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/azure/safari-technology-preview.rb b/third_party/blink/web_tests/external/wpt/tools/ci/azure/safari-technology-preview.rb index 0268ac4b..1a36205 100644 --- a/third_party/blink/web_tests/external/wpt/tools/ci/azure/safari-technology-preview.rb +++ b/third_party/blink/web_tests/external/wpt/tools/ci/azure/safari-technology-preview.rb
@@ -1,10 +1,10 @@ cask "safari-technology-preview" do if MacOS.version <= :catalina - version "113,001-46217-20200908-26bf578a-dcb0-4f70-b930-d9131bbf5d8a" - sha256 "09f86d0808e067a46584e9394767040012d7bbae453bb9842cabbf593d9185d9" + version "114,001-54431-20201007-6899e5c7-457d-484b-bf38-fce2fcc967da" + sha256 "1803c0affc0e7b28d945e122e99ed5741c19b9f2a949b473133adf916023db5b" else - version "113,001-43557-20200908-b620aaf9-e006-4855-8bdf-e7e76b5950bc" - sha256 "3dcf197b8c2c181861d0c3f3d00fbb65940d1c1aaf11511c76c94fb153d0a7f0" + version "114,001-53239-20201007-7bed156d-ab68-4db2-8ff0-3fa2e23fa2c0" + sha256 "c93ff3b5d485fce80b86f9656ffba3f5b967b189776cd20aea16a4c681419414" end url "https://secure-appldnld.apple.com/STP/#{version.after_comma}/SafariTechnologyPreview.dmg"
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-change-out-of-view-in-view-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-change-out-of-view-in-view-expected.txt index 4b97748..8877f53 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-change-out-of-view-in-view-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-change-out-of-view-in-view-expected.txt
@@ -121,7 +121,6 @@ "name": "LayoutBlockFlow (positioned) DIV id='fixed2'", "contentsOpaque": true, "drawsContent": false, - "backgroundColor": "#C0C0C0", "transform": 2 }, {
diff --git a/third_party/blink/web_tests/flag-specific/force-device-scale-factor=1.5/compositing/layer-creation/fixed-position-change-out-of-view-in-view-expected.txt b/third_party/blink/web_tests/flag-specific/force-device-scale-factor=1.5/compositing/layer-creation/fixed-position-change-out-of-view-in-view-expected.txt index df409413..1cc7f8a 100644 --- a/third_party/blink/web_tests/flag-specific/force-device-scale-factor=1.5/compositing/layer-creation/fixed-position-change-out-of-view-in-view-expected.txt +++ b/third_party/blink/web_tests/flag-specific/force-device-scale-factor=1.5/compositing/layer-creation/fixed-position-change-out-of-view-in-view-expected.txt
@@ -122,7 +122,6 @@ "name": "LayoutNGBlockFlow (positioned) DIV id='fixed2'", "contentsOpaque": true, "drawsContent": false, - "backgroundColor": "#C0C0C0", "transform": 2 }, {
diff --git a/third_party/closure_compiler/externs/accessibility_private.js b/third_party/closure_compiler/externs/accessibility_private.js index b3f6beb..bba6f222 100644 --- a/third_party/closure_compiler/externs/accessibility_private.js +++ b/third_party/closure_compiler/externs/accessibility_private.js
@@ -274,6 +274,13 @@ chrome.accessibilityPrivate.updateSwitchAccessBubble = function(bubble, show, anchor, actions) {}; /** + * Enable point scanning in Switch Access. + * @param {boolean} enabled True for start point scanning, false for end point + * scanning. + */ +chrome.accessibilityPrivate.enablePointScan = function(enabled) {}; + +/** * Sets current ARC app to use native ARC support. * @param {boolean} enabled True for ChromeVox (native), false for TalkBack. */
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 4e4e308..4ea129a3 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -25041,6 +25041,8 @@ <int value="1517" label="FILEMANAGERPRIVATEINTERNAL_GETPDFTHUMBNAIL"/> <int value="1518" label="AUTOTESTPRIVATE_REMOVEALLNOTIFICATIONS"/> <int value="1519" label="VIRTUALKEYBOARDPRIVATE_OPENSUGGESTIONSETTINGS"/> + <int value="1520" label="ACCESSIBILITY_PRIVATE_ENABLEPOINTSCAN"/> + <int value="1521" label="AUTOTESTPRIVATE_ACTIVATEADJACENTDESKSTOTARGETINDEX"/> </enum> <enum name="ExtensionIconState"> @@ -54472,7 +54474,7 @@ <int value="304" label="Security And Sign In"/> <int value="305" label="Fingerprint"/> <int value="306" label="Manage Other People"/> - <int value="307" label="Kerberos"/> + <int value="307" label="Kerberos Accounts"/> <int value="400" label="Pointers"/> <int value="401" label="Keyboard"/> <int value="402" label="Stylus"/>
diff --git a/tools/metrics/histograms/histograms_xml/chromeos/histograms.xml b/tools/metrics/histograms/histograms_xml/chromeos/histograms.xml index cf53e4ab..f78e64c 100644 --- a/tools/metrics/histograms/histograms_xml/chromeos/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/chromeos/histograms.xml
@@ -712,6 +712,18 @@ </summary> </histogram> +<histogram name="ChromeOS.Settings.People.AddAccountCount" units="accounts" + expires_after="2021-09-30"> + <owner>khorimoto@chromium.org</owner> + <owner>hsuregan@chromium.org</owner> + <owner>cros-customization@google.com</owner> + <summary> + Records when users click the Add Account button on the People page. The + number of the account that would be added is saved, e.g. a sample of 2 means + the user entered the add account dialog for a 2nd account. + </summary> +</histogram> + <histogram name="ChromeOS.Settings.SearchLatency" units="ms" expires_after="2021-04-04"> <owner>khorimoto@chromium.org</owner>
diff --git a/tools/perf/benchmarks/silk_flags.py b/tools/perf/benchmarks/silk_flags.py deleted file mode 100644 index 478194a6..0000000 --- a/tools/perf/benchmarks/silk_flags.py +++ /dev/null
@@ -1,23 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - - -def CustomizeBrowserOptionsForSoftwareRasterization(options): - """Enables flags needed for forced software rasterization.""" - options.AppendExtraBrowserArgs('--disable-gpu-rasterization') - - -def CustomizeBrowserOptionsForGpuRasterization(options): - """Enables flags needed for forced GPU rasterization using Ganesh.""" - options.AppendExtraBrowserArgs('--force-gpu-rasterization') - - -def CustomizeBrowserOptionsForSyncScrolling(options): - """Enables flags needed for synchronous (main thread) scrolling.""" - options.AppendExtraBrowserArgs('--disable-threaded-scrolling') - -def CustomizeBrowserOptionsForThreadTimes(options): - """Disables options known to cause noise in thread times""" - # Remove once crbug.com/621128 is fixed. - options.AppendExtraBrowserArgs('--disable-top-sites')
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 2f71dcdb..a4fd83024 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,12 +5,12 @@ "remote_path": "perfetto_binaries/trace_processor_shell/win/935a915963e1482109b102c82585d78c12112b31/trace_processor_shell.exe" }, "mac": { - "hash": "002f2269c464fd57c15cac6a921fad003228af1e", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/815983783a765fa04e31bb514020fd1c55291a71/trace_processor_shell" + "hash": "f401bbb73573f5ce4747f8226200b560733980c0", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/109c355900d140e616c7ddc66c57e626678133ca/trace_processor_shell" }, "linux": { - "hash": "5ee28a927ebcff327e0ef054a0fc33ea07dca9f7", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/815983783a765fa04e31bb514020fd1c55291a71/trace_processor_shell" + "hash": "04d376f2376bc6bd96b6a019256f61d92237d05a", + "remote_path": "perfetto_binaries/trace_processor_shell/linux/109c355900d140e616c7ddc66c57e626678133ca/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/gfx/x/connection.cc b/ui/gfx/x/connection.cc index d2b1d98e..a29aabc 100644 --- a/ui/gfx/x/connection.cc +++ b/ui/gfx/x/connection.cc
@@ -28,6 +28,33 @@ #include "ui/gfx/x/xproto_internal.h" #include "ui/gfx/x/xproto_types.h" +extern "C" { +typedef struct { + int type; + unsigned long serial; + Bool send_event; + Display* display; + Window window; + Window root; + Window subwindow; + Time time; + int x, y; + int x_root, y_root; + unsigned int state; + unsigned int keycode; + Bool same_screen; +} XKeyEvent; + +// This is temporarily required to fix XKB key event processing (bugs 1125886, +// 1136265, 1136248, 1136206). It should be removed and replaced with an +// XProto equivalent. +int XLookupString(XKeyEvent* event_struct, + char* buffer_return, + int bytes_buffer, + ::KeySym* keysym_return, + void* status_in_out); +} + namespace x11 { namespace { @@ -487,8 +514,16 @@ KeySym Connection::KeycodeToKeysym(uint32_t keycode, unsigned int modifiers) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - auto sym = TranslateKey(keycode, modifiers); - return sym == static_cast<KeySym>(XK_VoidSymbol) ? kNoSymbol : sym; + + XKeyEvent key_event{ + .type = KeyEvent::Press, + .display = display_, + .state = modifiers, + .keycode = keycode, + }; + ::KeySym keysym; + XLookupString(&key_event, nullptr, 0, &keysym, nullptr); + return static_cast<x11::KeySym>(keysym); } std::unique_ptr<Connection> Connection::Clone() const {
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabTest.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabTest.java index cd82339..63569c6 100644 --- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabTest.java +++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabTest.java
@@ -20,6 +20,8 @@ import org.chromium.base.test.util.CallbackHelper; import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.weblayer.ActionModeCallback; +import org.chromium.weblayer.ActionModeItemType; import org.chromium.weblayer.Browser; import org.chromium.weblayer.Tab; import org.chromium.weblayer.TabListCallback; @@ -287,4 +289,21 @@ // The WebContents should not have been hidden as a result of the rotation. Assert.assertFalse(mActivityTestRule.executeScriptAndExtractBoolean("gotHide", false)); } + + @Test + @SmallTest + @MinWebLayerVersion(88) + public void setFloatingActionModeOverride() throws Exception { + mActivity = mActivityTestRule.launchShellWithUrl("about:blank"); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mActivity.getBrowser().getActiveTab().setFloatingActionModeOverride( + ActionModeItemType.SHARE, new ActionModeCallback() { + @Override + public void onActionItemClicked( + @ActionModeItemType int item, String selectedText) {} + }); + }); + + // Smoke test. It's not possible to trigger an action mode click in a test. + } }
diff --git a/weblayer/browser/java/BUILD.gn b/weblayer/browser/java/BUILD.gn index 52cc7e5..a0101fe 100644 --- a/weblayer/browser/java/BUILD.gn +++ b/weblayer/browser/java/BUILD.gn
@@ -340,6 +340,7 @@ android_library("interfaces_java") { sources = [ "org/chromium/weblayer_private/interfaces/APICallException.java", + "org/chromium/weblayer_private/interfaces/ActionModeItemType.java", "org/chromium/weblayer_private/interfaces/BrowserFragmentArgs.java", "org/chromium/weblayer_private/interfaces/BrowsingDataType.java", "org/chromium/weblayer_private/interfaces/CookieChangeCause.java",
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java b/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java index 6b1103e..4927ae6 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java
@@ -7,31 +7,68 @@ import android.app.SearchManager; import android.content.Intent; import android.content.pm.PackageManager; +import android.os.RemoteException; import android.view.ActionMode; import android.view.Menu; import android.view.MenuItem; +import androidx.annotation.Nullable; + import org.chromium.base.PackageManagerUtils; import org.chromium.content_public.browser.ActionModeCallbackHelper; import org.chromium.content_public.browser.SelectionPopupController; import org.chromium.content_public.browser.WebContents; +import org.chromium.weblayer_private.interfaces.APICallException; +import org.chromium.weblayer_private.interfaces.ActionModeItemType; +import org.chromium.weblayer_private.interfaces.ITabClient; +import org.chromium.weblayer_private.interfaces.ObjectWrapper; /** * A class that handles selection action mode for WebLayer. */ public final class ActionModeCallback implements ActionMode.Callback { private final ActionModeCallbackHelper mHelper; + // Can be null during init. + private @Nullable ITabClient mTabClient; + + // Bitfield of @ActionModeItemType values. + private int mActionModeOverride; + + // Convert from content ActionModeCallbackHelper.MENU_ITEM_* values to + // @ActionModeItemType values. + private static int contentToWebLayerType(int contentType) { + switch (contentType) { + case ActionModeCallbackHelper.MENU_ITEM_SHARE: + return ActionModeItemType.SHARE; + case ActionModeCallbackHelper.MENU_ITEM_WEB_SEARCH: + return ActionModeItemType.WEB_SEARCH; + case ActionModeCallbackHelper.MENU_ITEM_PROCESS_TEXT: + case 0: + return 0; + default: + assert false; + return 0; + } + } public ActionModeCallback(WebContents webContents) { mHelper = SelectionPopupController.fromWebContents(webContents).getActionModeCallbackHelper(); } + public void setTabClient(ITabClient tabClient) { + mTabClient = tabClient; + } + + public void setOverride(int actionModeItemTypes) { + mActionModeOverride = actionModeItemTypes; + } + @Override public final boolean onCreateActionMode(ActionMode mode, Menu menu) { int allowedActionModes = ActionModeCallbackHelper.MENU_ITEM_PROCESS_TEXT | ActionModeCallbackHelper.MENU_ITEM_SHARE; - if (isWebSearchAvailable()) { + if ((mActionModeOverride & ActionModeItemType.WEB_SEARCH) != 0 || isWebSearchAvailable()) { allowedActionModes |= ActionModeCallbackHelper.MENU_ITEM_WEB_SEARCH; } mHelper.setAllowedMenuItems(allowedActionModes); @@ -53,7 +90,19 @@ @Override public final boolean onActionItemClicked(ActionMode mode, MenuItem item) { - return mHelper.onActionItemClicked(mode, item); + int menuItemType = contentToWebLayerType(mHelper.getAllowedMenuItemIfAny(mode, item)); + if ((menuItemType & mActionModeOverride) == 0) { + return mHelper.onActionItemClicked(mode, item); + } + assert WebLayerFactoryImpl.getClientMajorVersion() >= 88; + try { + mTabClient.onActionItemClicked( + menuItemType, ObjectWrapper.wrap(mHelper.getSelectedText())); + } catch (RemoteException e) { + throw new APICallException(e); + } + mode.finish(); + return true; } @Override
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java index 5f862a7..8e04d59e 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
@@ -140,6 +140,7 @@ private DisplayCutoutController mDisplayCutoutController; private boolean mPostContainerViewInitDone; + private ActionModeCallback mActionModeCallback; private WebLayerAccessibilityUtil.Observer mAccessibilityObserver; @@ -323,7 +324,8 @@ mPostContainerViewInitDone = true; SelectionPopupController controller = SelectionPopupController.fromWebContents(mWebContents); - controller.setActionModeCallback(new ActionModeCallback(mWebContents)); + mActionModeCallback = new ActionModeCallback(mWebContents); + controller.setActionModeCallback(mActionModeCallback); controller.setSelectionClient(SelectionClient.createSmartSelectionClient(mWebContents)); } @@ -524,6 +526,7 @@ StrictModeWorkaround.apply(); mClient = client; mTabCallbackProxy = new TabCallbackProxy(mNativeTab, client); + mActionModeCallback.setTabClient(mClient); } @Override @@ -591,11 +594,13 @@ @Override public void setTranslateTargetLanguage(String targetLanguage) { + StrictModeWorkaround.apply(); TabImplJni.get().setTranslateTargetLanguage(mNativeTab, targetLanguage); } @Override public void setScrollOffsetsEnabled(boolean enabled) { + StrictModeWorkaround.apply(); if (enabled) { if (mGestureStateListenerWithScroll == null) { mGestureStateListenerWithScroll = new GestureStateListenerWithScroll() { @@ -619,6 +624,12 @@ } } + @Override + public void setFloatingActionModeOverride(int actionModeItemTypes) { + StrictModeWorkaround.apply(); + mActionModeCallback.setOverride(actionModeItemTypes); + } + public void removeFaviconCallbackProxy(FaviconCallbackProxy proxy) { mFaviconCallbackProxies.remove(proxy); }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ActionModeItemType.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ActionModeItemType.java new file mode 100644 index 0000000..bbce17545 --- /dev/null +++ b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ActionModeItemType.java
@@ -0,0 +1,17 @@ +// 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.weblayer_private.interfaces; + +import androidx.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@IntDef({ActionModeItemType.SHARE, ActionModeItemType.WEB_SEARCH}) +@Retention(RetentionPolicy.SOURCE) +public @interface ActionModeItemType { + int SHARE = 1 << 0; + int WEB_SEARCH = 1 << 1; +}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITab.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITab.aidl index f2deacbb..3b41e1656 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITab.aidl +++ b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITab.aidl
@@ -75,4 +75,7 @@ // Added in 87 void setScrollOffsetsEnabled(in boolean enabled) = 26; + + // Added in 88 + void setFloatingActionModeOverride(in int actionModeItemTypes) = 27; }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl index 94e02e8..02a0780 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl +++ b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl
@@ -46,4 +46,8 @@ // Added in M87 void onVerticalScrollOffsetChanged(in int offset) = 11; + + // Added in M88 + void onActionItemClicked( + in int actionModeItemType, in IObjectWrapper selectedString) = 12; }
diff --git a/weblayer/public/java/BUILD.gn b/weblayer/public/java/BUILD.gn index c93fe494..a346309 100644 --- a/weblayer/public/java/BUILD.gn +++ b/weblayer/public/java/BUILD.gn
@@ -35,6 +35,8 @@ android_library("java") { sources = [ + "org/chromium/weblayer/ActionModeCallback.java", + "org/chromium/weblayer/ActionModeItemType.java", "org/chromium/weblayer/BroadcastReceiver.java", "org/chromium/weblayer/Browser.java", "org/chromium/weblayer/BrowserControlsOffsetCallback.java",
diff --git a/weblayer/public/java/org/chromium/weblayer/ActionModeCallback.java b/weblayer/public/java/org/chromium/weblayer/ActionModeCallback.java new file mode 100644 index 0000000..7014837 --- /dev/null +++ b/weblayer/public/java/org/chromium/weblayer/ActionModeCallback.java
@@ -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. + +package org.chromium.weblayer; + +/** + * Used to override floating some action mode menu items. + * + * @since 88 + */ +public abstract class ActionModeCallback { + /** + * Called when an overridden item type is clicked. The action mode is closed after this returns. + * @param selectedText the raw selected text. Client is responsible for trimming it to fit into + * some use cases as the text can be very large. + */ + public void onActionItemClicked(@ActionModeItemType int item, String selectedText) {} +}
diff --git a/weblayer/public/java/org/chromium/weblayer/ActionModeItemType.java b/weblayer/public/java/org/chromium/weblayer/ActionModeItemType.java new file mode 100644 index 0000000..b85fcd1 --- /dev/null +++ b/weblayer/public/java/org/chromium/weblayer/ActionModeItemType.java
@@ -0,0 +1,17 @@ +// 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.weblayer; + +import androidx.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@IntDef({ActionModeItemType.SHARE, ActionModeItemType.WEB_SEARCH}) +@Retention(RetentionPolicy.SOURCE) +public @interface ActionModeItemType { + int SHARE = org.chromium.weblayer_private.interfaces.ActionModeItemType.SHARE; + int WEB_SEARCH = org.chromium.weblayer_private.interfaces.ActionModeItemType.WEB_SEARCH; +}
diff --git a/weblayer/public/java/org/chromium/weblayer/Tab.java b/weblayer/public/java/org/chromium/weblayer/Tab.java index 9fd1304..646f2b9 100644 --- a/weblayer/public/java/org/chromium/weblayer/Tab.java +++ b/weblayer/public/java/org/chromium/weblayer/Tab.java
@@ -56,6 +56,7 @@ private FullscreenCallbackClientImpl mFullscreenCallbackClient; private NewTabCallback mNewTabCallback; private final ObserverList<ScrollOffsetCallback> mScrollOffsetCallbacks; + private @Nullable ActionModeCallback mActionModeCallback; // Id from the remote side. private final int mId; @@ -740,6 +741,29 @@ } } + /** + * Allow controlling and overriding custom items in the floating seleciton menu. + * Note floating action mode is available on M and up. + * @param actionModeItemTypes a bit field of values in ActionModeItemType. + * @param callback can be null if actionModeItemTypes is 0. + * + * @since 88 + */ + public void setFloatingActionModeOverride( + int actionModeItemTypes, @Nullable ActionModeCallback callback) { + ThreadCheck.ensureOnUiThread(); + throwIfDestroyed(); + if (WebLayer.getSupportedMajorVersionInternal() < 88) { + throw new UnsupportedOperationException(); + } + mActionModeCallback = callback; + try { + mImpl.setFloatingActionModeOverride(actionModeItemTypes); + } catch (RemoteException e) { + throw new APICallException(e); + } + } + // Called by Browser when removed. void onRemovedFromBrowser() { if (mDestroyOnRemove) { @@ -904,6 +928,16 @@ callback.onVerticalScrollOffsetChanged(value); } } + + @Override + public void onActionItemClicked( + int actionModeItemType, IObjectWrapper selectedStringWrapper) { + StrictModeWorkaround.apply(); + String selectedString = ObjectWrapper.unwrap(selectedStringWrapper, String.class); + if (mActionModeCallback != null) { + mActionModeCallback.onActionItemClicked(actionModeItemType, selectedString); + } + } } private static final class ErrorPageCallbackClientImpl extends IErrorPageCallbackClient.Stub {