diff --git a/AUTHORS b/AUTHORS index e714607d..97f5e95c 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -709,6 +709,7 @@ Marc des Garets <marc.desgarets@googlemail.com> Marcin Wiacek <marcin@mwiacek.com> Marco Rodrigues <gothicx@gmail.com> +Marcos Caceres <marcos@marcosc.com> Mariam Ali <alimariam@noogler.google.com> Mario Pistrich <m.pistrich@gmail.com> Mario Sanchez Prada <mario.prada@samsung.com>
diff --git a/DEPS b/DEPS index fb1d3bb..38186db7 100644 --- a/DEPS +++ b/DEPS
@@ -235,7 +235,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': '87a0078b890928828c08790bb2c846724234edcb', + 'skia_revision': '7e54e3083fba9b0f07536c155e91eab6dcc84f91', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -243,7 +243,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'bcc8970347f1a51b650e4a79f5e4ddec11047e79', + 'angle_revision': '43be4d9cd8e461e9c26fb28bb8f2f26b65aea75c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -282,7 +282,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': 'e294a95ca85f4d1aa2cd1a6e00e572acd7f03871', + 'freetype_revision': 'ede96b239b90bf9c9d9a01f06005ae09fb4fa19b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -310,7 +310,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': '0404c7edc03c2ded9787ba7d00f821414ce4285a', + 'devtools_frontend_revision': '7008714d9a82c52dddf836fabf22dd17469c7328', # 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. @@ -350,7 +350,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': 'a4c8c8d5bffb66900d5bc76b143ce956f4fa6a13', + 'dawn_revision': 'd174cef8fa6b677efd4d6ba71babebea41e5282b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -1637,7 +1637,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'e42f534de7afea5942ecae5993d9211e258918aa', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '339965f93cdaaee297fe0764f1765de0ae1bd9f3', + Var('webrtc_git') + '/src.git' + '@' + '3cef26662aec5f992eb08491f19d1179ce685d5a', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1695,7 +1695,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@646a59e1f51fa8237c7104a6c7805d3d7581d021', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@26afe693b62d30de8c9836b9c2e90760b5589ca7', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index c49937a4..9789e3f6 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -39,7 +39,7 @@ system_webview_apk_or_module_tmpl(target_name) { forward_variables_from(invoker, "*") deps = upstream_only_webview_deps - min_sdk_version = 21 + min_sdk_version = default_min_sdk_version if (android_64bit_target_cpu && defined(include_32_bit_webview) && !include_32_bit_webview) { android_manifest = system_webview_64_android_manifest @@ -108,7 +108,7 @@ system_webview_bundle("system_webview_bundle") { base_module_target = ":system_webview_base_bundle_module" bundle_name = "SystemWebView" - min_sdk_version = 21 + min_sdk_version = default_min_sdk_version compress_shared_libraries = true } @@ -145,7 +145,7 @@ system_webview_bundle("system_webview_64_bundle") { base_module_target = ":system_webview_64_base_bundle_module" bundle_name = "SystemWebView64" - min_sdk_version = 21 + min_sdk_version = default_min_sdk_version compress_shared_libraries = true include_32_bit_webview = false } @@ -172,7 +172,7 @@ base_module_target = ":system_webview_32_base_bundle_module" bundle_name = "SystemWebView32" include_64_bit_webview = false - min_sdk_version = 21 + min_sdk_version = default_min_sdk_version compress_shared_libraries = true } }
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn index 5849f86..6e209783 100644 --- a/android_webview/test/BUILD.gn +++ b/android_webview/test/BUILD.gn
@@ -211,7 +211,7 @@ apk_name = "WebViewInstrumentationTest" apk_under_test = ":webview_instrumentation_apk" android_manifest = "../javatests/AndroidManifest.xml" - min_sdk_version = 21 + min_sdk_version = default_min_sdk_version deps = [ ":webview_instrumentation_test_mock_services_java",
diff --git a/ash/app_list/model/search/search_result.h b/ash/app_list/model/search/search_result.h index 8104b5b9..6504a99 100644 --- a/ash/app_list/model/search/search_result.h +++ b/ash/app_list/model/search/search_result.h
@@ -110,6 +110,9 @@ Category category() const { return metadata_->category; } void set_category(Category category) { metadata_->category = category; } + bool best_match() const { return metadata_->best_match; } + void set_best_match(bool best_match) { metadata_->best_match = best_match; } + DisplayType display_type() const { return metadata_->display_type; } void set_display_type(DisplayType display_type) { metadata_->display_type = display_type;
diff --git a/ash/capture_mode/capture_mode_api.cc b/ash/capture_mode/capture_mode_api.cc index 8a4f34f..b16ba24 100644 --- a/ash/capture_mode/capture_mode_api.cc +++ b/ash/capture_mode/capture_mode_api.cc
@@ -12,8 +12,4 @@ CaptureModeController::Get()->CaptureScreenshotsOfAllDisplays(); } -bool IsCaptureModeSessionActive() { - return CaptureModeController::Get()->IsActive(); -} - } // namespace ash
diff --git a/ash/capture_mode/capture_mode_session.h b/ash/capture_mode/capture_mode_session.h index 684c237..0044d0b 100644 --- a/ash/capture_mode/capture_mode_session.h +++ b/ash/capture_mode/capture_mode_session.h
@@ -172,6 +172,7 @@ friend class CaptureModeAdvancedSettingsTestApi; friend class CaptureModeSessionFocusCycler; friend class CaptureModeSessionTestApi; + friend class CaptureModeTestApi; class CursorSetter; class ScopedA11yOverrideWindowSetter;
diff --git a/ash/capture_mode/capture_mode_test_api.cc b/ash/capture_mode/capture_mode_test_api.cc index 0e36e77..cffe594 100644 --- a/ash/capture_mode/capture_mode_test_api.cc +++ b/ash/capture_mode/capture_mode_test_api.cc
@@ -6,10 +6,12 @@ #include "ash/capture_mode/capture_mode_controller.h" #include "ash/capture_mode/capture_mode_metrics.h" +#include "ash/capture_mode/capture_mode_session.h" #include "ash/capture_mode/capture_mode_types.h" #include "ash/capture_mode/video_recording_watcher.h" #include "base/auto_reset.h" #include "base/check.h" +#include "base/run_loop.h" namespace ash { @@ -92,6 +94,32 @@ .get(); } +void CaptureModeTestApi::SimulateOpeningFolderSelectionDialog() { + DCHECK(controller_->IsActive()); + auto* session = controller_->capture_mode_session(); + DCHECK(!session->capture_mode_settings_widget_); + session->SetSettingsMenuShown(true); + DCHECK(session->capture_mode_settings_widget_); + session->OpenFolderSelectionDialog(); + + // In browser tests, the dialog creation is asynchronous, so we'll need to + // wait for it. + if (GetFolderSelectionDialogWindow()) + return; + + base::RunLoop loop; + session->folder_selection_dialog_controller_ + ->on_dialog_window_added_callback_for_test_ = loop.QuitClosure(); + loop.Run(); +} + +aura::Window* CaptureModeTestApi::GetFolderSelectionDialogWindow() { + DCHECK(controller_->IsActive()); + auto* session = controller_->capture_mode_session(); + auto* dialog_controller = session->folder_selection_dialog_controller_.get(); + return dialog_controller ? dialog_controller->dialog_window() : nullptr; +} + void CaptureModeTestApi::SetType(bool for_video) { controller_->SetType(for_video ? CaptureModeType::kVideo : CaptureModeType::kImage);
diff --git a/ash/capture_mode/folder_selection_dialog_controller.cc b/ash/capture_mode/folder_selection_dialog_controller.cc index 2a0271641..8c34520 100644 --- a/ash/capture_mode/folder_selection_dialog_controller.cc +++ b/ash/capture_mode/folder_selection_dialog_controller.cc
@@ -59,13 +59,14 @@ DCHECK(root); DCHECK(root->IsRootWindow()); - window_observation_.Observe(wm::TransientWindowManager::GetOrCreate( - dialog_background_dimmer_.window())); + auto* owner = dialog_background_dimmer_.window(); + owner->SetId(kShellWindowId_CaptureModeFolderSelectionDialogOwner); + window_observation_.Observe(wm::TransientWindowManager::GetOrCreate(owner)); dialog_background_dimmer_.SetDimColor( AshColorProvider::Get()->GetShieldLayerColor( AshColorProvider::ShieldLayerType::kShield40)); - dialog_background_dimmer_.window()->Show(); + owner->Show(); select_folder_dialog_->SelectFile( ui::SelectFileDialog::SELECT_FOLDER, @@ -74,7 +75,7 @@ /*file_types=*/nullptr, /*file_type_index=*/0, /*default_extension=*/base::FilePath::StringType(), - /*owning_window=*/dialog_background_dimmer_.window(), + /*owning_window=*/owner, /*params=*/nullptr); } @@ -104,7 +105,6 @@ DCHECK(!dialog_window_); dialog_window_ = transient; - dialog_window_->SetId(kShellWindowId_CaptureModeFolderSelectionDialog); // The dialog should never resize, minimize or maximize. auto* widget = views::Widget::GetWidgetForNativeWindow(dialog_window_); @@ -114,6 +114,9 @@ widget_delegate->SetCanResize(false); widget_delegate->SetCanMinimize(false); widget_delegate->SetCanMaximize(false); + + if (on_dialog_window_added_callback_for_test_) + std::move(on_dialog_window_added_callback_for_test_).Run(); } void FolderSelectionDialogController::OnTransientChildRemoved(
diff --git a/ash/capture_mode/folder_selection_dialog_controller.h b/ash/capture_mode/folder_selection_dialog_controller.h index 5b7bd83..9aef395 100644 --- a/ash/capture_mode/folder_selection_dialog_controller.h +++ b/ash/capture_mode/folder_selection_dialog_controller.h
@@ -6,6 +6,7 @@ #define ASH_CAPTURE_MODE_FOLDER_SELECTION_DIALOG_CONTROLLER_H_ #include "ash/wm/window_dimmer.h" +#include "base/callback_forward.h" #include "base/files/file_path.h" #include "base/memory/scoped_refptr.h" #include "base/scoped_observation.h" @@ -67,6 +68,8 @@ aura::Window* transient) override; private: + friend class CaptureModeTestApi; + Delegate* const delegate_; // Dims everything behind the dialog (including the capture bar, the settings @@ -81,6 +84,9 @@ // |select_folder_dialog_| as a transient child of the dimming window. aura::Window* dialog_window_ = nullptr; + // An optional callback that will be invoked when |dialog_window_| gets added. + base::OnceClosure on_dialog_window_added_callback_for_test_; + // We observe the transient window manager of the dimming window to know when // the dialog window is added or removed. base::ScopedObservation<wm::TransientWindowManager,
diff --git a/ash/public/cpp/app_list/app_list_types.h b/ash/public/cpp/app_list/app_list_types.h index 8c9afd5..c9996e5 100644 --- a/ash/public/cpp/app_list/app_list_types.h +++ b/ash/public/cpp/app_list/app_list_types.h
@@ -188,19 +188,21 @@ // to be displayed in the search box should be associated with one category. It // is an error for results displayed in the search box to have a kUnknown // category, but results displayed in other views - eg. the Continue section - -// may use kUnknown. These values are not yet stable, and should not yet be used -// for metrics. +// may use kUnknown. +// +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum class AppListSearchResultCategory { kUnknown = 0, - kBestMatch = 1, - kApp = 2, + kApps = 1, + kAppShortcuts = 2, kWeb = 3, kFiles = 4, - kAssistant = 5, - kSettings = 6, - kHelp = 7, - kPlayStore = 8, - kMaxValue = kPlayStore, + kSettings = 5, + kHelp = 6, + kPlayStore = 7, + kSearchAndAssistant = 8, + kMaxValue = kSearchAndAssistant, }; // Which UI container(s) the result should be displayed in. @@ -369,6 +371,10 @@ // section. AppListSearchResultCategory category = AppListSearchResultCategory::kUnknown; + // Whether this result is a top match and should be shown in the Top Matches + // section instead of its category. + bool best_match = false; + // The type of this result. AppListSearchResultType result_type = AppListSearchResultType::kUnknown;
diff --git a/ash/public/cpp/capture_mode/capture_mode_api.h b/ash/public/cpp/capture_mode/capture_mode_api.h index 0f41aef..2d399c8 100644 --- a/ash/public/cpp/capture_mode/capture_mode_api.h +++ b/ash/public/cpp/capture_mode/capture_mode_api.h
@@ -14,9 +14,6 @@ // Note: this won't start a capture mode session. void ASH_EXPORT CaptureScreenshotsOfAllDisplays(); -// Returns true if a capture mode session is currently active. -bool ASH_EXPORT IsCaptureModeSessionActive(); - } // namespace ash #endif // ASH_PUBLIC_CPP_CAPTURE_MODE_CAPTURE_MODE_API_H_
diff --git a/ash/public/cpp/capture_mode/capture_mode_test_api.h b/ash/public/cpp/capture_mode/capture_mode_test_api.h index 782dd967..8a4f603f 100644 --- a/ash/public/cpp/capture_mode/capture_mode_test_api.h +++ b/ash/public/cpp/capture_mode/capture_mode_test_api.h
@@ -9,6 +9,10 @@ #include "base/callback_forward.h" #include "base/files/file_path.h" +namespace aura { +class Window; +} // namespace aura + namespace gfx { class Rect; } // namespace gfx @@ -72,6 +76,14 @@ // Can only be called while recording is in progress for a Projector session. RecordingOverlayController* GetRecordingOverlayController(); + // Simulates the flow taken by users to open the folder selection dialog from + // the settings menu, and waits until this dialog gets added. + void SimulateOpeningFolderSelectionDialog(); + + // Returns a pointer to the folder selection dialog window or nullptr if no + // such window exists. + aura::Window* GetFolderSelectionDialogWindow(); + private: // Sets the capture mode type to a video capture if |for_video| is true, or // image capture otherwise.
diff --git a/ash/public/cpp/shell_window_ids.h b/ash/public/cpp/shell_window_ids.h index 99bbe640..e37a610 100644 --- a/ash/public/cpp/shell_window_ids.h +++ b/ash/public/cpp/shell_window_ids.h
@@ -202,11 +202,12 @@ // multiple displays connected. kShellWindowId_DisplayIdentificationHighlightWindow, - // The window hosting the folder selection menu for capture mode, which is not - // parented to a top-level container, yet it needs to be uniquely identified - // so that we can allow a WindowState to be created for it, since it can be - // dragged around. - kShellWindowId_CaptureModeFolderSelectionDialog, + // The window specified as the owner of the folder selection menu for capture + // mode, which will be a transient window parent of the about to be created + // dialog window. This is needed in order to prevent + // |SelectFileDialogExtension| from favoring to parent the dialog to a browser + // window (if one exists). + kShellWindowId_CaptureModeFolderSelectionDialogOwner, }; // A list of system modal container IDs. The order of the list is important that
diff --git a/ash/system/network/OWNERS b/ash/system/network/OWNERS index 7632e21..cb2f47e 100644 --- a/ash/system/network/OWNERS +++ b/ash/system/network/OWNERS
@@ -1,4 +1,5 @@ azeemarshad@chromium.org +gordonseto@google.com jonmann@chromium.org khorimoto@chromium.org stevenjb@chromium.org
diff --git a/ash/system/status_area_widget_delegate.cc b/ash/system/status_area_widget_delegate.cc index 3130cbf..459eaee 100644 --- a/ash/system/status_area_widget_delegate.cc +++ b/ash/system/status_area_widget_delegate.cc
@@ -178,6 +178,7 @@ } void StatusAreaWidgetDelegate::CalculateTargetBounds() { + // Prevents creating new layout manager when adding the tray buttons. if (is_adding_tray_buttons_) return; // Use a grid layout so that the trays can be centered in each cell, and @@ -239,6 +240,10 @@ } void StatusAreaWidgetDelegate::ChildPreferredSizeChanged(View* child) { + // Prevents resizing and layout row and column change when adding the tray + // buttons. + if (is_adding_tray_buttons_) + return; const gfx::Size current_size = size(); const gfx::Size new_size = GetPreferredSize(); if (new_size == current_size)
diff --git a/ash/system/time/calendar_month_view.h b/ash/system/time/calendar_month_view.h index f07cfd0a..e21ca1a8 100644 --- a/ash/system/time/calendar_month_view.h +++ b/ash/system/time/calendar_month_view.h
@@ -73,7 +73,7 @@ int column_set_id, bool is_in_current_month); - // Owned by `UnifiedCalendarViewController`. + // Owned by `CalendarView`. CalendarViewController* const calendar_view_controller_; // If today's cell is in this view.
diff --git a/ash/system/time/calendar_view.cc b/ash/system/time/calendar_view.cc index a70c1b6b..e2be34c 100644 --- a/ash/system/time/calendar_view.cc +++ b/ash/system/time/calendar_view.cc
@@ -185,11 +185,10 @@ }; CalendarView::CalendarView(DetailedViewDelegate* delegate, - UnifiedSystemTrayController* controller, - CalendarViewController* calendar_view_controller) + UnifiedSystemTrayController* controller) : TrayDetailedView(delegate), controller_(controller), - calendar_view_controller_(calendar_view_controller) { + calendar_view_controller_(std::make_unique<CalendarViewController>()) { CreateTitleRow(IDS_ASH_CALENDAR_TITLE); // Add the header. @@ -259,7 +258,8 @@ SetMonthViews(); scoped_scroll_view_observer_.Observe(scroll_view_); - scoped_calendar_view_controller_observer_.Observe(calendar_view_controller_); + scoped_calendar_view_controller_observer_.Observe( + calendar_view_controller_.get()); scoped_view_observer_.AddObservation(scroll_view_); scoped_view_observer_.AddObservation(content_view_); } @@ -443,8 +443,8 @@ } views::View* CalendarView::AddLabelWithId(LabelType type, bool add_at_front) { - auto label = - std::make_unique<MonthYearHeaderView>(type, calendar_view_controller_); + auto label = std::make_unique<MonthYearHeaderView>( + type, calendar_view_controller_.get()); if (add_at_front) return content_view_->AddChildViewAt(std::move(label), 0); return content_view_->AddChildView(std::move(label)); @@ -452,8 +452,8 @@ CalendarMonthView* CalendarView::AddMonth(base::Time month_first_date, bool add_at_front) { - auto month = std::make_unique<CalendarMonthView>(month_first_date, - calendar_view_controller_); + auto month = std::make_unique<CalendarMonthView>( + month_first_date, calendar_view_controller_.get()); month->SetBorder(views::CreateEmptyBorder(kMonthVerticalPadding, 0, kMonthVerticalPadding, 0)); if (add_at_front) {
diff --git a/ash/system/time/calendar_view.h b/ash/system/time/calendar_view.h index a4744c69..60bf891 100644 --- a/ash/system/time/calendar_view.h +++ b/ash/system/time/calendar_view.h
@@ -33,8 +33,7 @@ METADATA_HEADER(CalendarView); CalendarView(DetailedViewDelegate* delegate, - UnifiedSystemTrayController* controller, - CalendarViewController* calendar_view_controller); + UnifiedSystemTrayController* controller); CalendarView(const CalendarView& other) = delete; CalendarView& operator=(const CalendarView& other) = delete; ~CalendarView() override; @@ -58,6 +57,10 @@ views::Button* CreateInfoButton(views::Button::PressedCallback callback, int info_accessible_name_id) override; + CalendarViewController* calendar_view_controller() { + return calendar_view_controller_.get(); + } + private: // The header of each month view which shows the month's name. If the year of // this month is not the same as the current month, the year is also shown in @@ -117,8 +120,7 @@ // Unowned. UnifiedSystemTrayController* controller_; - // Owned by `UnifiedCalendarViewController`. - CalendarViewController* const calendar_view_controller_; + std::unique_ptr<CalendarViewController> calendar_view_controller_; // The content of the `scroll_view_`, which carries months and month labels. // Owned by `CalendarView`.
diff --git a/ash/system/time/calendar_view_unittest.cc b/ash/system/time/calendar_view_unittest.cc index 6509a18..5889a83 100644 --- a/ash/system/time/calendar_view_unittest.cc +++ b/ash/system/time/calendar_view_unittest.cc
@@ -25,7 +25,6 @@ void SetUp() override { AshTestBase::SetUp(); - controller_ = std::make_unique<CalendarViewController>(); delegate_ = std::make_unique<DetailedViewDelegate>(/*tray_controller=*/nullptr); tray_model_ = std::make_unique<UnifiedSystemTrayModel>(/*shelf=*/nullptr); @@ -35,7 +34,6 @@ void TearDown() override { calendar_view_.reset(); - controller_.reset(); delegate_.reset(); tray_controller_.reset(); tray_model_.reset(); @@ -43,11 +41,10 @@ AshTestBase::TearDown(); } - void CreateCalendarView(base::Time date) { + void CreateCalendarView() { calendar_view_.reset(); - controller_->UpdateMonth(date); - calendar_view_ = std::make_unique<CalendarView>( - delegate_.get(), tray_controller_.get(), controller_.get()); + calendar_view_ = + std::make_unique<CalendarView>(delegate_.get(), tray_controller_.get()); // TODO(https://crbug.com/1236276): remove calling `Layout()` once we can // pop up the view from the tray. (https://crbug.com/1254491) And add tests // for focusing behaviors. @@ -121,7 +118,14 @@ TEST_F(CalendarViewTest, Init) { base::Time date; ASSERT_TRUE(base::Time::FromString("24 Aug 2021 10:00 GMT", &date)); - CreateCalendarView(date); + + // Set time override. + SetFakeNow(date); + base::subtle::ScopedTimeClockOverrides time_override( + &CalendarViewTest::FakeTimeNow, /*time_ticks_override=*/nullptr, + /*thread_ticks_override=*/nullptr); + + CreateCalendarView(); EXPECT_EQ(u"July", GetPreviousLabelText()); EXPECT_EQ(u"August", GetCurrentLabelText()); @@ -138,11 +142,20 @@ EXPECT_EQ( u"29", static_cast<views::LabelButton*>(next_month()->children()[0])->GetText()); +} - // Test corner cases of the `CalendarView`. +// Test the init view of the `CalendarView` starting with December. +TEST_F(CalendarViewTest, InitDec) { base::Time dec_date; ASSERT_TRUE(base::Time::FromString("24 Dec 2021 10:00 GMT", &dec_date)); - CreateCalendarView(dec_date); + + // Set time override. + SetFakeNow(dec_date); + base::subtle::ScopedTimeClockOverrides time_override( + &CalendarViewTest::FakeTimeNow, /*time_ticks_override=*/nullptr, + /*thread_ticks_override=*/nullptr); + + CreateCalendarView(); EXPECT_EQ(u"November", GetPreviousLabelText()); EXPECT_EQ(u"December", GetCurrentLabelText()); @@ -165,7 +178,13 @@ base::Time date; ASSERT_TRUE(base::Time::FromString("24 Oct 2021 10:00 GMT", &date)); - CreateCalendarView(date); + // Set time override. + SetFakeNow(date); + base::subtle::ScopedTimeClockOverrides time_override( + &CalendarViewTest::FakeTimeNow, /*time_ticks_override=*/nullptr, + /*thread_ticks_override=*/nullptr); + + CreateCalendarView(); EXPECT_EQ(u"September", GetPreviousLabelText()); EXPECT_EQ(u"October", GetCurrentLabelText()); @@ -212,7 +231,7 @@ &CalendarViewTest::FakeTimeNow, /*time_ticks_override=*/nullptr, /*thread_ticks_override=*/nullptr); - CreateCalendarView(date); + CreateCalendarView(); EXPECT_EQ(u"September", GetPreviousLabelText()); EXPECT_EQ(u"October", GetCurrentLabelText());
diff --git a/ash/system/time/unified_calendar_view_controller.cc b/ash/system/time/unified_calendar_view_controller.cc index ae7360ff..aa464f5e 100644 --- a/ash/system/time/unified_calendar_view_controller.cc +++ b/ash/system/time/unified_calendar_view_controller.cc
@@ -16,23 +16,24 @@ UnifiedSystemTrayController* tray_controller) : detailed_view_delegate_( std::make_unique<DetailedViewDelegate>(tray_controller)), - calendar_view_controller_(std::make_unique<CalendarViewController>()), tray_controller_(tray_controller) {} -UnifiedCalendarViewController::~UnifiedCalendarViewController() {} +UnifiedCalendarViewController::~UnifiedCalendarViewController() = default; views::View* UnifiedCalendarViewController::CreateView() { DCHECK(!view_); - view_ = new CalendarView(detailed_view_delegate_.get(), tray_controller_, - calendar_view_controller_.get()); + view_ = new CalendarView(detailed_view_delegate_.get(), tray_controller_); return view_; } std::u16string UnifiedCalendarViewController::GetAccessibleName() const { + // Shows `Now()` as the initial time if calendar view is not created yet. + base::Time current_time = + view_ ? view_->calendar_view_controller()->current_date() + : base::Time::Now(); return l10n_util::GetStringFUTF16( IDS_ASH_CALENDAR_BUBBLE_ACCESSIBLE_DESCRIPTION, - base::TimeFormatWithPattern(calendar_view_controller_->current_date(), - "MMMM yyyy")); + base::TimeFormatWithPattern(current_time, "MMMM yyyy")); } } // namespace ash
diff --git a/ash/system/time/unified_calendar_view_controller.h b/ash/system/time/unified_calendar_view_controller.h index d40d8ff..1355ac3 100644 --- a/ash/system/time/unified_calendar_view_controller.h +++ b/ash/system/time/unified_calendar_view_controller.h
@@ -13,7 +13,6 @@ class DetailedViewDelegate; class UnifiedSystemTrayController; class CalendarView; -class CalendarViewController; // Controller of `CalendarView` in UnifiedSystemTray. class UnifiedCalendarViewController : public DetailedViewController { @@ -32,7 +31,6 @@ private: const std::unique_ptr<DetailedViewDelegate> detailed_view_delegate_; - std::unique_ptr<CalendarViewController> const calendar_view_controller_; // Unowned, the object that instantiated us. UnifiedSystemTrayController* const tray_controller_;
diff --git a/ash/webui/diagnostics_ui/backend/network_health_provider.cc b/ash/webui/diagnostics_ui/backend/network_health_provider.cc index fddecaa..e4ade11 100644 --- a/ash/webui/diagnostics_ui/backend/network_health_provider.cc +++ b/ash/webui/diagnostics_ui/backend/network_health_provider.cc
@@ -475,7 +475,6 @@ void NetworkHealthProvider::OnDeviceStateListReceived( std::vector<network_mojom::DeviceStatePropertiesPtr> devices) { - bool list_changed = false; base::flat_set<std::string> networks_seen; // Iterate all devices. If the device is already known, then update it's @@ -506,7 +505,6 @@ if (!matched) { std::string observer_guid = AddNewNetwork(device); networks_seen.insert(std::move(observer_guid)); - list_changed = true; } } @@ -515,7 +513,6 @@ const std::string& observer_guid = it->first; if (!base::Contains(networks_seen, observer_guid)) { it = networks_.erase(it); - list_changed = true; continue; }
diff --git a/ash/webui/shortcut_customization_ui/resources/BUILD.gn b/ash/webui/shortcut_customization_ui/resources/BUILD.gn index a7108a9..57d6e677 100644 --- a/ash/webui/shortcut_customization_ui/resources/BUILD.gn +++ b/ash/webui/shortcut_customization_ui/resources/BUILD.gn
@@ -76,8 +76,10 @@ js_library("accelerator_edit_view") { deps = [ + ":accelerator_lookup_manager", ":accelerator_view", ":icons", + ":mojo_interface_provider", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_button:cr_button.m", ]
diff --git a/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.js b/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.js index b01c5b4..9f8392ed2 100644 --- a/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.js +++ b/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.js
@@ -11,8 +11,10 @@ import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {AcceleratorLookupManager} from './accelerator_lookup_manager.js'; import {ViewState} from './accelerator_view.js' -import {AcceleratorInfo, AcceleratorKeys, AcceleratorSource, AcceleratorState, AcceleratorType} from './shortcut_types.js'; +import {getShortcutProvider} from './mojo_interface_provider.js' +import {AcceleratorConfigResult, AcceleratorInfo, AcceleratorKeys, AcceleratorSource, AcceleratorState, AcceleratorType, ShortcutProviderInterface} from './shortcut_types.js'; /** * @fileoverview @@ -91,6 +93,17 @@ } } + /** @override */ + constructor() { + super(); + + /** @private {!ShortcutProviderInterface} */ + this.shortcutProvider_ = getShortcutProvider(); + + /** @private {!AcceleratorLookupManager} */ + this.lookupManager_ = AcceleratorLookupManager.getInstance(); + } + /** @protected */ onStatusMessageChanged_() { if (this.statusMessage === '') { @@ -107,7 +120,21 @@ /** @protected */ onDeleteButtonClicked_() { - // TODO(jimmyxgong): Implement this function + this.shortcutProvider_ + .removeAccelerator( + this.source, this.action, this.acceleratorInfo.accelerator) + .then((result) => { + if (result === AcceleratorConfigResult.kSuccess) { + this.lookupManager_.removeAccelerator( + this.source, this.action, this.acceleratorInfo.accelerator); + + this.dispatchEvent(new CustomEvent('request-update-accelerator', { + bubbles: true, + composed: true, + detail: {source: this.source, action: this.action} + })); + } + }); } /** @protected */
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index 5bc2abf..df3cefd 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -971,12 +971,8 @@ // WindowState is only for windows in top level container, unless they are // temporarily hidden when launched by window restore. The will be reparented // to a top level container soon, and need a WindowState. - // The window of capture mode folder selection dialog is also special. It's - // not parented to a top level container, but it needs a window state since it - // can be dragged around. if (!IsToplevelContainer(window->parent()) && - !IsTemporarilyHiddenForFullrestore(window) && - window->GetId() != kShellWindowId_CaptureModeFolderSelectionDialog) { + !IsTemporarilyHiddenForFullrestore(window)) { return nullptr; }
diff --git a/build/fuchsia/device_target.py b/build/fuchsia/device_target.py index c9d5ab2f..92643bf7 100644 --- a/build/fuchsia/device_target.py +++ b/build/fuchsia/device_target.py
@@ -254,3 +254,12 @@ self.RunCommandPiped('dm reboot') time.sleep(_REBOOT_SLEEP_PERIOD) self.Start() + + def Stop(self): + try: + super(DeviceTarget, self).Stop() + finally: + # End multiplexed ssh connection, ensure that ssh logging stops before + # tests/scripts return. + if self.IsStarted(): + self.RunCommand(['-O', 'exit'])
diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc index d1f8dca..473269e 100644 --- a/cc/layers/picture_layer_unittest.cc +++ b/cc/layers/picture_layer_unittest.cc
@@ -53,6 +53,7 @@ EXPECT_EQ(0, host->SourceFrameNumber()); host->WillCommit(nullptr); + EXPECT_EQ(1, host->SourceFrameNumber()); host->CommitComplete(); EXPECT_EQ(1, host->SourceFrameNumber());
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index f7e4f32..57ef1655 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -511,6 +511,7 @@ commit_completion_event_ = std::move(completion); swap_promise_manager_.WillCommit(); client_->WillCommit(); + source_frame_number_++; } void LayerTreeHost::WaitForCommitCompletion() { @@ -533,7 +534,6 @@ // This DCHECK ensures that WaitForCommitCompletion() will not block. DCHECK(!in_commit()); WaitForCommitCompletion(); - source_frame_number_++; client_->DidCommit(impl_commit_start_time_, impl_commit_finish_time_); impl_commit_start_time_ = impl_commit_finish_time_ = base::TimeTicks(); if (did_complete_scale_animation_) {
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index c096695..20e37bb 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -112,7 +112,7 @@ output = chrome_public_android_manifest variables = chrome_public_jinja_variables variables += [ - "min_sdk_version=21", + "min_sdk_version=$default_min_sdk_version", "target_sdk_version=$android_sdk_version", ] } @@ -2806,7 +2806,7 @@ variables = default_chrome_public_jinja_variables variables += [ "manifest_package=$chrome_public_test_manifest_package", - "min_sdk_version=21", + "min_sdk_version=$default_min_sdk_version", "target_sdk_version=$android_sdk_version", ] } @@ -2818,7 +2818,7 @@ variables = default_chrome_public_jinja_variables variables += [ "manifest_package=$chrome_public_test_manifest_package", - "min_sdk_version=21", + "min_sdk_version=$default_min_sdk_version", "target_sdk_version=$android_sdk_version", ] } @@ -2829,7 +2829,7 @@ output = chrome_public_test_vr_apk_manifest variables = chrome_public_jinja_variables variables += [ - "min_sdk_version=21", + "min_sdk_version=$default_min_sdk_version", "target_sdk_version=$android_sdk_version", ] } @@ -3367,7 +3367,7 @@ } is_monochrome_or_trichrome = false manifest_package = chrome_public_manifest_package - min_sdk_version = 21 + min_sdk_version = default_min_sdk_version module_descs = chrome_modern_module_descs version_code = chrome_modern_version_code
diff --git a/chrome/android/aapt2.config b/chrome/android/aapt2.config index 6cfe45eb..ea85a3e 100644 --- a/chrome/android/aapt2.config +++ b/chrome/android/aapt2.config
@@ -1,2 +1,3 @@ +drawable/ic_launcher#no_collapse drawable/ic_launcher_round#no_collapse drawable/shortcut_incognito#no_collapse
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni index 8f483b15..f25c7aa5 100644 --- a/chrome/android/chrome_public_apk_tmpl.gni +++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -139,7 +139,7 @@ } else if (_is_monochrome) { min_sdk_version = 24 } else { - min_sdk_version = 21 + min_sdk_version = default_min_sdk_version } resource_exclusion_regex = common_resource_exclusion_regex
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFeatures.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFeatures.java index 542dde8..bf7c448 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFeatures.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFeatures.java
@@ -18,9 +18,30 @@ * {@code false}</li> * <li>{@code bookmark_visuals_enabled}: boolean; refresh the visual looks of the bookmarks * manager. Default: {@code false}</li> + * <li>{@code bookmarks_refresh_min_version}: boolean; see {@link #VERSION}.</li> * </ul> */ public class BookmarkFeatures { + /** + * An indicator of the code version specific to bookmarks and the reading list. It allows + * feature flags to be individually enabled without changing the {@code min_version} for the + * whole study. + * + * <p>Feature flag params using the {@code VERSION} value: + * <ul> + * <li>{@code bookmarks_improved_save_flow_min_version} - {@link + * ChromeFeatureList#BOOKMARKS_IMPROVED_SAVE_FLOW} + * <li>{@code bookmarks_refresh_min_version} - {@link ChromeFeatureList#BOOKMARKS_REFRESH} + * <li>{@code read_later_min_version} - {@link ChromeFeatureList#READ_LATER} + * </ul> + * + * <p>These parameters allow to control for cases where a significant bug fix or change of param + * semantics was merged into release, and prior versions of the code are not to be enabled. In + * such case the patch increments the {@code VERSION}, while experiment sets {@code + * *_min_version} to set a lower bound on existing implementation with the fix. + */ + static final int VERSION = 0; + private static final boolean BOOKMARK_VISUALS_ENABLED_DEFAULT = false; private static final boolean IMPROVED_SAVE_FLOW_AUTODISMISS_ENABLED_DEFAULT = true; // This is the same as the default dismiss time for snackbars. @@ -32,7 +53,11 @@ public static boolean isImprovedSaveFlowEnabled() { return FeatureList.isInitialized() - && ChromeFeatureList.isEnabled(ChromeFeatureList.BOOKMARKS_IMPROVED_SAVE_FLOW); + && ChromeFeatureList.isEnabled(ChromeFeatureList.BOOKMARKS_IMPROVED_SAVE_FLOW) + && ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.BOOKMARKS_IMPROVED_SAVE_FLOW, + "bookmarks_improved_save_flow_min_version", 0) + <= VERSION; } public static boolean isImprovedSaveFlowAutodismissEnabled() { @@ -53,7 +78,10 @@ public static boolean isBookmarksRefreshEnabled() { return FeatureList.isInitialized() - && ChromeFeatureList.isEnabled(ChromeFeatureList.BOOKMARKS_REFRESH); + && ChromeFeatureList.isEnabled(ChromeFeatureList.BOOKMARKS_REFRESH) + && ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.BOOKMARKS_REFRESH, "bookmarks_refresh_min_version", 0) + <= VERSION; } public static boolean isBookmarksVisualRefreshEnabled() { @@ -74,4 +102,4 @@ && ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( ChromeFeatureList.BOOKMARKS_REFRESH, "edit_bookmark_in_app_menu", false); } -} \ No newline at end of file +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListFeatures.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListFeatures.java index d871f213..c72c0b9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListFeatures.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListFeatures.java
@@ -24,16 +24,22 @@ * discards the "last bookmark location". Default: {@link #DEFAULT_SESSION_LENGTH_SECONDS}</li> * <li>{@code use_root_bookmark_as_default}: boolean; use the root folder rather than "Mobile * bookmarks" as the default bookmark folder. Default: {@code false}</li> + * <li>{@code read_later_min_version}: boolean; see {@link BookmarkFeatures#VERSION}.</li> * </ul> */ public class ReadingListFeatures { + /** @see BookmarkFeatures#VERSION */ + static final int VERSION = BookmarkFeatures.VERSION; private static final int DEFAULT_SESSION_LENGTH_SECONDS = (int) TimeUnit.HOURS.toSeconds(1); private ReadingListFeatures() {} public static boolean isReadingListEnabled() { return FeatureList.isInitialized() - && ChromeFeatureList.isEnabled(ChromeFeatureList.READ_LATER); + && ChromeFeatureList.isEnabled(ChromeFeatureList.READ_LATER) + && ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.READ_LATER, "read_later_min_version", 0) + <= VERSION; } /** Returns whether the root folder should be used as the default location. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardView.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardView.java index 95915ff..365fe3b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardView.java
@@ -141,7 +141,7 @@ @Override public boolean isItemSupported(@ContextMenuManager.ContextMenuItemId int menuItemId) { - return menuItemId != ContextMenuManager.ContextMenuItemId.LEARN_MORE; + return true; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java index d6c5b9a..4d8aa3a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -60,22 +60,22 @@ public static class FirstRunFlowSequencerDelegate { /** @return true if the sync consent promo page should be shown. */ boolean shouldShowSyncConsentPage(Activity activity, List<Account> accounts) { - // We show the sync consent page if sync is allowed, and not signed in, and - // - "skip the first use hints" is not set, or - // - "skip the first use hints" is set, but there is at least one account. final IdentityManager identityManager = IdentityServicesProvider.get().getIdentityManager( Profile.getLastUsedRegularProfile()); - final boolean isSignedInWithSync = identityManager.hasPrimaryAccount(ConsentLevel.SYNC); - final boolean shouldShowSyncConsentPreMICe = isSyncAllowed() && !isSignedInWithSync - && (!shouldSkipFirstUseHints(activity) || !accounts.isEmpty()); - + if (identityManager.hasPrimaryAccount(ConsentLevel.SYNC) || !isSyncAllowed()) { + // No need to show the sync consent page if users already consented to sync or + // if sync is not allowed. + return false; + } if (FREMobileIdentityConsistencyFieldTrial.isEnabled()) { - final boolean isSignedInWithoutSync = - identityManager.hasPrimaryAccount(ConsentLevel.SIGNIN); - return shouldShowSyncConsentPreMICe && isSignedInWithoutSync; + // Show the sync consent page only to the signed-in users. + return identityManager.hasPrimaryAccount(ConsentLevel.SIGNIN); } else { - return shouldShowSyncConsentPreMICe; + // We show the sync consent page if sync is allowed, and not signed in, and + // - "skip the first use hints" is not set, or + // - "skip the first use hints" is set, but there is at least one account. + return !shouldSkipFirstUseHints(activity) || !accounts.isEmpty(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/ContextMenuManager.java b/chrome/android/java/src/org/chromium/chrome/browser/native_page/ContextMenuManager.java index 0c05176a..ad1f07d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/native_page/ContextMenuManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/native_page/ContextMenuManager.java
@@ -36,8 +36,7 @@ @IntDef({ContextMenuItemId.SEARCH, ContextMenuItemId.OPEN_IN_NEW_TAB, ContextMenuItemId.OPEN_IN_NEW_TAB_IN_GROUP, ContextMenuItemId.OPEN_IN_INCOGNITO_TAB, ContextMenuItemId.OPEN_IN_NEW_WINDOW, ContextMenuItemId.SAVE_FOR_OFFLINE, - ContextMenuItemId.ADD_TO_MY_APPS, ContextMenuItemId.REMOVE, - ContextMenuItemId.LEARN_MORE}) + ContextMenuItemId.ADD_TO_MY_APPS, ContextMenuItemId.REMOVE}) @Retention(RetentionPolicy.SOURCE) public @interface ContextMenuItemId { // The order of the items will be based on the value of their ID. So if new items are added, @@ -51,9 +50,8 @@ int SAVE_FOR_OFFLINE = 5; int ADD_TO_MY_APPS = 6; int REMOVE = 7; - int LEARN_MORE = 8; - int NUM_ENTRIES = 9; + int NUM_ENTRIES = 8; } private final NativePageNavigationDelegate mNavigationDelegate; @@ -273,8 +271,6 @@ } case ContextMenuItemId.REMOVE: return true; - case ContextMenuItemId.LEARN_MORE: - return true; case ContextMenuItemId.ADD_TO_MY_APPS: return false; default: @@ -305,8 +301,6 @@ return R.string.contextmenu_save_link; case ContextMenuItemId.REMOVE: return R.string.remove; - case ContextMenuItemId.LEARN_MORE: - return R.string.learn_more; } assert false; return 0; @@ -344,10 +338,6 @@ delegate.removeItem(); RecordUserAction.record(mUserActionPrefix + ".ContextMenu.RemoveItem"); return true; - case ContextMenuItemId.LEARN_MORE: - mNavigationDelegate.navigateToHelpPage(); - RecordUserAction.record(mUserActionPrefix + ".ContextMenu.LearnMore"); - return true; default: return false; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsConfig.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsConfig.java index 9c778918..c106812 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsConfig.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsConfig.java
@@ -12,7 +12,6 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.components.browser_ui.widget.displaystyle.UiConfig; import java.lang.annotation.Retention; @@ -45,16 +44,6 @@ private SuggestionsConfig() {} /** - * @return Whether scrolling to the bottom of suggestions triggers a load. - */ - public static boolean scrollToLoad() { - // The scroll to load feature does not work well for users who require accessibility mode. - if (ChromeAccessibilityUtil.get().isAccessibilityEnabled()) return false; - - return ChromeFeatureList.isEnabled(ChromeFeatureList.CONTENT_SUGGESTIONS_SCROLL_TO_LOAD); - } - - /** * @param resources The resources to fetch the color from. * @return The background color for the suggestions sheet content. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileGroup.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileGroup.java index 035d34f..88901d6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileGroup.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileGroup.java
@@ -25,7 +25,6 @@ import org.chromium.chrome.browser.offlinepages.OfflinePageItem; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.suggestions.SiteSuggestion; -import org.chromium.chrome.browser.suggestions.SuggestionsConfig; import org.chromium.chrome.browser.suggestions.SuggestionsMetrics; import org.chromium.chrome.browser.suggestions.SuggestionsOfflineModelObserver; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; @@ -598,8 +597,6 @@ case ContextMenuItemId.REMOVE: return mSuggestion.sectionType == TileSectionType.PERSONALIZED && mSuggestion.source != TileSource.EXPLORE; - case ContextMenuItemId.LEARN_MORE: - return SuggestionsConfig.scrollToLoad(); case ContextMenuItemId.OPEN_IN_INCOGNITO_TAB: return mSuggestion.source != TileSource.EXPLORE; default:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProviderFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProviderFactory.java index 8fdee79..ae77de13 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProviderFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProviderFactory.java
@@ -47,6 +47,7 @@ import org.chromium.components.webapps.ShortcutSource; import org.chromium.components.webapps.WebApkDistributor; import org.chromium.device.mojom.ScreenOrientationLockType; +import org.chromium.ui.util.ColorUtils; import org.chromium.webapk.lib.common.WebApkCommonUtils; import org.chromium.webapk.lib.common.WebApkMetaDataUtils; import org.chromium.webapk.lib.common.splash.SplashLayout; @@ -262,11 +263,10 @@ IntentUtils.safeGetString(bundle, WebApkMetaDataKeys.DISPLAY_MODE)); int orientation = orientationFromString( IntentUtils.safeGetString(bundle, WebApkMetaDataKeys.ORIENTATION)); - long themeColor = WebApkMetaDataUtils.getLongFromMetaData(bundle, - WebApkMetaDataKeys.THEME_COLOR, WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING); - long backgroundColor = - WebApkMetaDataUtils.getLongFromMetaData(bundle, WebApkMetaDataKeys.BACKGROUND_COLOR, - WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING); + long themeColor = WebApkMetaDataUtils.getLongFromMetaData( + bundle, WebApkMetaDataKeys.THEME_COLOR, ColorUtils.INVALID_COLOR); + long backgroundColor = WebApkMetaDataUtils.getLongFromMetaData( + bundle, WebApkMetaDataKeys.BACKGROUND_COLOR, ColorUtils.INVALID_COLOR); // Fetch the default background color from the WebAPK's resources. Fetching the default // background color from the WebAPK is important for consistency when:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java index 0ad0e93..3ee3a7a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java
@@ -28,6 +28,7 @@ import org.chromium.components.webapk.lib.common.WebApkConstants; import org.chromium.components.webapps.ShortcutSource; import org.chromium.device.mojom.ScreenOrientationLockType; +import org.chromium.ui.util.ColorUtils; import java.io.File; @@ -226,10 +227,8 @@ mPreferences.getString(KEY_ICON, null), version, mPreferences.getInt(KEY_DISPLAY_MODE, DisplayMode.STANDALONE), mPreferences.getInt(KEY_ORIENTATION, ScreenOrientationLockType.DEFAULT), - mPreferences.getLong( - KEY_THEME_COLOR, WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING), - mPreferences.getLong( - KEY_BACKGROUND_COLOR, WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING), + mPreferences.getLong(KEY_THEME_COLOR, ColorUtils.INVALID_COLOR), + mPreferences.getLong(KEY_BACKGROUND_COLOR, ColorUtils.INVALID_COLOR), mPreferences.getBoolean(KEY_IS_ICON_GENERATED, false), mPreferences.getBoolean(KEY_IS_ICON_ADAPTIVE, false)); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProviderFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProviderFactory.java index d9ac55d5..bfcf55f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProviderFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProviderFactory.java
@@ -19,6 +19,7 @@ import org.chromium.chrome.browser.browserservices.intents.WebappIntentUtils; import org.chromium.components.webapps.ShortcutSource; import org.chromium.device.mojom.ScreenOrientationLockType; +import org.chromium.ui.util.ColorUtils; import org.chromium.webapk.lib.common.splash.SplashLayout; /** @@ -66,8 +67,8 @@ return null; } - long themeColor = IntentUtils.safeGetLongExtra(intent, WebappConstants.EXTRA_THEME_COLOR, - WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING); + long themeColor = IntentUtils.safeGetLongExtra( + intent, WebappConstants.EXTRA_THEME_COLOR, ColorUtils.INVALID_COLOR); boolean hasValidToolbarColor = WebappIntentUtils.isLongColorValid(themeColor); int toolbarColor = hasValidToolbarColor ? (int) themeColor : WebappIntentDataProvider.getDefaultToolbarColor(); @@ -85,9 +86,8 @@ int orientation = IntentUtils.safeGetIntExtra( intent, WebappConstants.EXTRA_ORIENTATION, ScreenOrientationLockType.DEFAULT); int source = sourceFromIntent(intent); - Integer backgroundColor = WebappIntentUtils.colorFromLongColor( - IntentUtils.safeGetLongExtra(intent, WebappConstants.EXTRA_BACKGROUND_COLOR, - WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING)); + Integer backgroundColor = WebappIntentUtils.colorFromLongColor(IntentUtils.safeGetLongExtra( + intent, WebappConstants.EXTRA_BACKGROUND_COLOR, ColorUtils.INVALID_COLOR)); boolean isIconGenerated = IntentUtils.safeGetBooleanExtra( intent, WebappConstants.EXTRA_IS_ICON_GENERATED, false); boolean isIconAdaptive = IntentUtils.safeGetBooleanExtra(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java index 96fdb7ec..f9a9e40a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java
@@ -21,6 +21,7 @@ import androidx.test.filters.MediumTest; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -32,6 +33,7 @@ import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.ui.SigninPromoController; @@ -82,6 +84,8 @@ SigninPromoController.getPromoShowCountPreferenceName( SigninAccessPoint.BOOKMARK_MANAGER)); SigninPromoController.setPrefSigninPromoDeclinedBookmarksForTests(false); + SharedPreferencesManager.getInstance().removeKey( + ChromePreferenceKeys.SYNC_PROMO_TOTAL_SHOW_COUNT); } @Test @@ -111,6 +115,9 @@ @Test @MediumTest public void testPromoImpressionCountIncrementAfterDisplayingSigninPromo() { + Assert.assertEquals(0, + SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.SYNC_PROMO_TOTAL_SHOW_COUNT)); assertEquals(0, SharedPreferencesManager.getInstance().readInt( SigninPromoController.getPromoShowCountPreferenceName( @@ -121,6 +128,9 @@ SharedPreferencesManager.getInstance().readInt( SigninPromoController.getPromoShowCountPreferenceName( SigninAccessPoint.BOOKMARK_MANAGER))); + Assert.assertEquals(1, + SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.SYNC_PROMO_TOTAL_SHOW_COUNT)); } private void closeBookmarkManager() {
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 6cd5b31..b4f4f1b2 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
@@ -23,6 +23,8 @@ import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; @@ -74,6 +76,8 @@ public void tearDown() { leaveRecentTabsPage(); RecentTabsManager.setRecentlyClosedTabManagerForTests(null); + SharedPreferencesManager.getInstance().removeKey( + ChromePreferenceKeys.SYNC_PROMO_TOTAL_SHOW_COUNT); } @Test @@ -98,19 +102,31 @@ @LargeTest @Feature("RenderTest") public void testPersonalizedSigninPromoInRecentTabsPage() throws Exception { + Assert.assertEquals(0, + SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.SYNC_PROMO_TOTAL_SHOW_COUNT)); mAccountManagerTestRule.addAccountWithNameAndAvatar( AccountManagerTestRule.TEST_ACCOUNT_EMAIL); mPage = loadRecentTabsPage(); mRenderTestRule.render(mPage.getView(), "personalized_signin_promo_recent_tabs_page"); + Assert.assertEquals(1, + SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.SYNC_PROMO_TOTAL_SHOW_COUNT)); } @Test @LargeTest @Feature("RenderTest") public void testPersonalizedSyncPromoInRecentTabsPage() throws Exception { + Assert.assertEquals(0, + SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.SYNC_PROMO_TOTAL_SHOW_COUNT)); mAccountManagerTestRule.addTestAccountThenSignin(); mPage = loadRecentTabsPage(); mRenderTestRule.render(mPage.getView(), "personalized_sync_promo_recent_tabs_page"); + Assert.assertEquals(1, + SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.SYNC_PROMO_TOTAL_SHOW_COUNT)); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java index a5ea548..924cf0e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
@@ -64,6 +64,7 @@ import org.chromium.chrome.browser.password_check.PasswordCheck; import org.chromium.chrome.browser.password_check.PasswordCheckFactory; import org.chromium.chrome.browser.password_manager.settings.PasswordSettings; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.privacy.settings.PrivacySettings; import org.chromium.chrome.browser.safety_check.SafetyCheckSettingsFragment; @@ -157,6 +158,8 @@ } SharedPreferencesManager.getInstance().removeKey( SigninPromoController.getPromoShowCountPreferenceName(SigninAccessPoint.SETTINGS)); + SharedPreferencesManager.getInstance().removeKey( + ChromePreferenceKeys.SYNC_PROMO_TOTAL_SHOW_COUNT); } @Test @@ -401,12 +404,21 @@ @Test @MediumTest public void testSyncPromoShownIsNotOverCounted() { + int promoShowCount = SharedPreferencesManager.getInstance().readInt( + SigninPromoController.getPromoShowCountPreferenceName(SigninAccessPoint.SETTINGS)); + Assert.assertEquals(0, promoShowCount); + Assert.assertEquals(0, + SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.SYNC_PROMO_TOTAL_SHOW_COUNT)); launchSettingsActivity(); onViewWaiting(allOf(withId(R.id.signin_promo_view_container), isDisplayed())); - int promoShowCount = SharedPreferencesManager.getInstance().readInt( + promoShowCount = SharedPreferencesManager.getInstance().readInt( SigninPromoController.getPromoShowCountPreferenceName(SigninAccessPoint.SETTINGS)); - Assert.assertEquals("Promo shown count should only be increased by 1", 1, promoShowCount); + Assert.assertEquals(1, promoShowCount); + Assert.assertEquals(1, + SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.SYNC_PROMO_TOTAL_SHOW_COUNT)); } private void launchSettingsActivity() {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java index 291efd9..99694a10c 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java
@@ -59,6 +59,7 @@ import org.chromium.components.webapk.lib.common.WebApkMetaDataKeys; import org.chromium.components.webapps.WebApkDistributor; import org.chromium.device.mojom.ScreenOrientationLockType; +import org.chromium.ui.util.ColorUtils; import org.chromium.webapk.lib.common.WebApkConstants; import org.chromium.webapk.lib.common.splash.SplashLayout; import org.chromium.webapk.test.WebApkTestHelper; @@ -1136,11 +1137,11 @@ assertNotEquals(oldDefaultBackgroundColor, splashLayoutDefaultBackgroundColor); ManifestData androidManifestData = defaultManifestData(); - androidManifestData.backgroundColor = WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING; + androidManifestData.backgroundColor = ColorUtils.INVALID_COLOR; androidManifestData.defaultBackgroundColor = oldDefaultBackgroundColor; ManifestData fetchedManifestData = defaultManifestData(); - fetchedManifestData.backgroundColor = WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING; + fetchedManifestData.backgroundColor = ColorUtils.INVALID_COLOR; fetchedManifestData.defaultBackgroundColor = splashLayoutDefaultBackgroundColor; assertFalse(checkUpdateNeededForFetchedManifest(androidManifestData, fetchedManifestData));
diff --git a/chrome/browser/android/browserservices/intents/BUILD.gn b/chrome/browser/android/browserservices/intents/BUILD.gn index e5b2416..1aa6553 100644 --- a/chrome/browser/android/browserservices/intents/BUILD.gn +++ b/chrome/browser/android/browserservices/intents/BUILD.gn
@@ -59,5 +59,6 @@ "//third_party/blink/public/mojom:mojom_platform_java", "//third_party/hamcrest:hamcrest_library_java", "//third_party/junit", + "//ui/android:ui_no_recycler_view_java", ] }
diff --git a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebApkInfoTest.java b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebApkInfoTest.java index 565ae424..b393d6d 100644 --- a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebApkInfoTest.java +++ b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebApkInfoTest.java
@@ -34,6 +34,7 @@ import org.chromium.components.webapps.ShortcutSource; import org.chromium.components.webapps.WebApkDistributor; import org.chromium.device.mojom.ScreenOrientationLockType; +import org.chromium.ui.util.ColorUtils; import org.chromium.webapk.lib.common.WebApkConstants; import org.chromium.webapk.lib.common.splash.SplashLayout; import org.chromium.webapk.test.WebApkTestHelper; @@ -696,8 +697,7 @@ public void testBackgroundColorFallbackToDefaultNoCustomDefault() { Bundle bundle = new Bundle(); bundle.putString(WebApkMetaDataKeys.START_URL, START_URL); - bundle.putString(WebApkMetaDataKeys.BACKGROUND_COLOR, - WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING + "L"); + bundle.putString(WebApkMetaDataKeys.BACKGROUND_COLOR, ColorUtils.INVALID_COLOR + "L"); WebApkTestHelper.registerWebApkWithMetaData(WEBAPK_PACKAGE_NAME, bundle, null); Intent intent = new Intent(); @@ -720,8 +720,7 @@ Bundle bundle = new Bundle(); bundle.putString(WebApkMetaDataKeys.START_URL, START_URL); - bundle.putString(WebApkMetaDataKeys.BACKGROUND_COLOR, - WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING + "L"); + bundle.putString(WebApkMetaDataKeys.BACKGROUND_COLOR, ColorUtils.INVALID_COLOR + "L"); bundle.putInt( WebApkMetaDataKeys.DEFAULT_BACKGROUND_COLOR_ID, defaultBackgroundColorResourceId); WebApkTestHelper.registerWebApkWithMetaData(WEBAPK_PACKAGE_NAME, bundle, null);
diff --git a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappConstants.java b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappConstants.java index c40243be..ec262e020 100644 --- a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappConstants.java +++ b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappConstants.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.browserservices.intents; import org.chromium.content_public.common.ScreenOrientationConstants; -import org.chromium.ui.util.ColorUtils; /** * This class contains constants related to adding shortcuts to the Android Home @@ -46,8 +45,5 @@ // be correctly populated into the WebappRegistry/WebappDataStorage. public static final int WEBAPP_SHORTCUT_VERSION = 3; - // This value is equal to kInvalidOrMissingColor in the C++ blink::Manifest struct. - public static final long MANIFEST_COLOR_INVALID_OR_MISSING = ColorUtils.INVALID_COLOR; - private WebappConstants() {} }
diff --git a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfo.java b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfo.java index 31e837c..be926a80 100644 --- a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfo.java +++ b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfo.java
@@ -15,6 +15,7 @@ import org.chromium.components.webapps.ShortcutSource; import org.chromium.components.webapps.WebApkDistributor; import org.chromium.device.mojom.ScreenOrientationLockType; +import org.chromium.ui.util.ColorUtils; import java.util.List; import java.util.Map; @@ -95,11 +96,11 @@ /** * Returns the toolbar color if it is valid, and - * WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING otherwise. + * ColorUtils.INVALID_COLOR otherwise. */ public long toolbarColor() { return hasValidToolbarColor() ? mProvider.getColorProvider().getToolbarColor() - : WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING; + : ColorUtils.INVALID_COLOR; } /** @@ -112,7 +113,7 @@ /** * Background color is actually a 32 bit unsigned integer which encodes a color * in ARGB format. Return value is a long because we also need to encode the - * error state of WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING. + * error state of ColorUtils.INVALID_COLOR. */ public long backgroundColor() { return WebappIntentUtils.colorFromIntegerColor(getWebappExtras().backgroundColor);
diff --git a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfoTest.java b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfoTest.java index 171231e2..b98c5b2 100644 --- a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfoTest.java +++ b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfoTest.java
@@ -19,6 +19,7 @@ import org.chromium.chrome.test.util.browser.webapps.WebappTestHelper; import org.chromium.components.webapps.ShortcutSource; import org.chromium.device.mojom.ScreenOrientationLockType; +import org.chromium.ui.util.ColorUtils; /** * Tests the WebappInfo class's ability to parse various URLs. @@ -166,9 +167,8 @@ intent.putExtra(WebappConstants.EXTRA_NAME, name); intent.putExtra(WebappConstants.EXTRA_SHORT_NAME, shortName); WebappInfo info = createWebappInfo(intent); - Assert.assertEquals(WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING, info.toolbarColor()); - Assert.assertEquals( - WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING, info.backgroundColor()); + Assert.assertEquals(ColorUtils.INVALID_COLOR, info.toolbarColor()); + Assert.assertEquals(ColorUtils.INVALID_COLOR, info.backgroundColor()); } @Test
diff --git a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappIntentUtils.java b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappIntentUtils.java index 82b893a9..783cf26 100644 --- a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappIntentUtils.java +++ b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappIntentUtils.java
@@ -9,6 +9,7 @@ import android.provider.Browser; import org.chromium.base.IntentUtils; +import org.chromium.ui.util.ColorUtils; import org.chromium.webapk.lib.common.WebApkConstants; import java.util.HashSet; @@ -47,22 +48,22 @@ /** * Converts color from signed Integer where an unspecified color is represented as null to * to unsigned long where an unspecified color is represented as - * {@link WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING}. + * {@link ColorUtils.INVALID_COLOR}. */ public static long colorFromIntegerColor(Integer color) { if (color != null) { return color.intValue(); } - return WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING; + return ColorUtils.INVALID_COLOR; } public static boolean isLongColorValid(long longColor) { - return (longColor != WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING); + return (longColor != ColorUtils.INVALID_COLOR); } /** * Converts color from unsigned long where an unspecified color is represented as - * {@link WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING} to a signed Integer where an + * {@link ColorUtils.INVALID_COLOR} to a signed Integer where an * unspecified color is represented as null. */ public static Integer colorFromLongColor(long longColor) {
diff --git a/chrome/browser/android/shortcut_helper.cc b/chrome/browser/android/shortcut_helper.cc index fe1d7a1b..afb14278 100644 --- a/chrome/browser/android/shortcut_helper.cc +++ b/chrome/browser/android/shortcut_helper.cc
@@ -18,7 +18,7 @@ #include "components/webapps/browser/android/shortcut_info.h" #include "content/public/browser/manifest_icon_downloader.h" #include "content/public/browser/web_contents.h" -#include "ui/android/color_helpers.h" +#include "ui/android/color_utils_android.h" #include "ui/gfx/android/java_bitmap.h" #include "url/gurl.h"
diff --git a/chrome/browser/android/webapk/webapk_handler_delegate.cc b/chrome/browser/android/webapk/webapk_handler_delegate.cc index 26beb171..eefbce9 100644 --- a/chrome/browser/android/webapk/webapk_handler_delegate.cc +++ b/chrome/browser/android/webapk/webapk_handler_delegate.cc
@@ -10,7 +10,7 @@ #include "chrome/android/chrome_jni_headers/WebApkHandlerDelegate_jni.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom.h" #include "third_party/skia/include/core/SkColor.h" -#include "ui/android/color_helpers.h" +#include "ui/android/color_utils_android.h" using base::android::JavaParamRef;
diff --git a/chrome/browser/android/webapk/webapk_installer.cc b/chrome/browser/android/webapk/webapk_installer.cc index 96372e36..bca7697 100644 --- a/chrome/browser/android/webapk/webapk_installer.cc +++ b/chrome/browser/android/webapk/webapk_installer.cc
@@ -53,7 +53,7 @@ #include "services/network/public/cpp/simple_url_loader.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" -#include "ui/android/color_helpers.h" +#include "ui/android/color_utils_android.h" #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/codec/png_codec.h" #include "url/origin.h"
diff --git a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc index d4dcd7ed..5135c17 100644 --- a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc +++ b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc
@@ -26,7 +26,7 @@ #include "third_party/blink/public/common/manifest/manifest_util.h" #include "third_party/blink/public/mojom/manifest/manifest.mojom.h" #include "third_party/smhasher/src/MurmurHash2.h" -#include "ui/android/color_helpers.h" +#include "ui/android/color_utils_android.h" #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/codec/png_codec.h" #include "url/gurl.h"
diff --git a/chrome/browser/android/webapk/webapk_update_manager.cc b/chrome/browser/android/webapk/webapk_update_manager.cc index ede51fc..cef42d0 100644 --- a/chrome/browser/android/webapk/webapk_update_manager.cc +++ b/chrome/browser/android/webapk/webapk_update_manager.cc
@@ -26,7 +26,7 @@ #include "content/public/browser/browser_thread.h" #include "third_party/blink/public/mojom/manifest/manifest.mojom.h" #include "third_party/skia/include/core/SkBitmap.h" -#include "ui/android/color_helpers.h" +#include "ui/android/color_utils_android.h" #include "ui/gfx/android/java_bitmap.h" #include "url/gurl.h"
diff --git a/chrome/browser/apps/app_service/DEPS b/chrome/browser/apps/app_service/DEPS index e7cb331..9de64387 100644 --- a/chrome/browser/apps/app_service/DEPS +++ b/chrome/browser/apps/app_service/DEPS
@@ -1,5 +1,5 @@ include_rules = [ - "+components/services/app_service/app_service_impl.h", + "+components/services/app_service/app_service_mojom_impl.h", "+components/services/app_service/public", "+components/app_restore", "+components/webapk",
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.cc b/chrome/browser/apps/app_service/app_service_proxy_base.cc index 09c6a4a9..38549c0 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_base.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_base.cc
@@ -21,7 +21,7 @@ #include "chrome/browser/ash/file_manager/app_id.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/web_app_id_constants.h" -#include "components/services/app_service/app_service_impl.h" +#include "components/services/app_service/app_service_mojom_impl.h" #include "components/services/app_service/public/cpp/intent_constants.h" #include "components/services/app_service/public/cpp/intent_filter_util.h" #include "components/services/app_service/public/cpp/intent_util.h" @@ -130,9 +130,10 @@ browser_app_launcher_ = std::make_unique<apps::BrowserAppLauncher>(profile_); - app_service_impl_ = - std::make_unique<apps::AppServiceImpl>(profile_->GetPath()); - app_service_impl_->BindReceiver(app_service_.BindNewPipeAndPassReceiver()); + app_service_mojom_impl_ = + std::make_unique<apps::AppServiceMojomImpl>(profile_->GetPath()); + app_service_mojom_impl_->BindReceiver( + app_service_.BindNewPipeAndPassReceiver()); if (app_service_.is_connected()) { // The AppServiceProxy is a subscriber: something that wants to be able to
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.h b/chrome/browser/apps/app_service/app_service_proxy_base.h index 6d19bac..74b4afa 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_base.h +++ b/chrome/browser/apps/app_service/app_service_proxy_base.h
@@ -31,7 +31,7 @@ namespace apps { -class AppServiceImpl; +class AppServiceMojomImpl; struct IntentLaunchInfo { IntentLaunchInfo(); @@ -337,7 +337,7 @@ // This proxy privately owns its instance of the App Service. This should not // be exposed except through the Mojo interface connected to |app_service_|. - std::unique_ptr<apps::AppServiceImpl> app_service_impl_; + std::unique_ptr<apps::AppServiceMojomImpl> app_service_mojom_impl_; mojo::Remote<apps::mojom::AppService> app_service_; apps::AppRegistryCache app_registry_cache_;
diff --git a/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc b/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc index 7a301ac2..e34c165 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc
@@ -31,7 +31,7 @@ #include "components/app_restore/features.h" #include "components/app_restore/full_restore_save_handler.h" #include "components/app_restore/full_restore_utils.h" -#include "components/services/app_service/app_service_impl.h" +#include "components/services/app_service/app_service_mojom_impl.h" #include "components/services/app_service/public/cpp/app_capability_access_cache_wrapper.h" #include "components/services/app_service/public/cpp/app_registry_cache_wrapper.h" #include "components/services/app_service/public/cpp/types_util.h" @@ -254,7 +254,7 @@ } void AppServiceProxyChromeOs::FlushMojoCallsForTesting() { - app_service_impl_->FlushMojoCallsForTesting(); + app_service_mojom_impl_->FlushMojoCallsForTesting(); if (built_in_chrome_os_apps_) { built_in_chrome_os_apps_->FlushMojoCallsForTesting(); }
diff --git a/chrome/browser/apps/app_service/app_service_proxy_desktop.cc b/chrome/browser/apps/app_service/app_service_proxy_desktop.cc index 6a2aaf1..9837b5b7 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_desktop.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_desktop.cc
@@ -7,7 +7,7 @@ #include "chrome/browser/apps/app_service/publishers/extension_apps.h" #include "chrome/browser/web_applications/app_service/web_apps.h" #include "chrome/browser/web_applications/web_app_provider.h" -#include "components/services/app_service/app_service_impl.h" +#include "components/services/app_service/app_service_mojom_impl.h" namespace apps { @@ -52,7 +52,7 @@ } void AppServiceProxy::FlushMojoCallsForTesting() { - app_service_impl_->FlushMojoCallsForTesting(); + app_service_mojom_impl_->FlushMojoCallsForTesting(); receivers_.FlushForTesting(); }
diff --git a/chrome/browser/apps/app_service/app_service_proxy_lacros.cc b/chrome/browser/apps/app_service/app_service_proxy_lacros.cc index 3038a0b..7e2f4f8a 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_lacros.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_lacros.cc
@@ -26,7 +26,7 @@ #include "chrome/browser/web_applications/app_service/web_apps_publisher_host.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chromeos/lacros/lacros_service.h" -#include "components/services/app_service/app_service_impl.h" +#include "components/services/app_service/app_service_mojom_impl.h" #include "components/services/app_service/public/cpp/intent_filter_util.h" #include "components/services/app_service/public/cpp/intent_util.h" #include "components/services/app_service/public/cpp/types_util.h"
diff --git a/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc b/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc index 185a7266..613fa3d 100644 --- a/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc +++ b/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc
@@ -1016,14 +1016,12 @@ IN_PROC_BROWSER_TEST_F(BrowserAppInstanceTrackerTest, ActivateTabInstance) { // Setup: a browser with 2 tabs (app A and a non-app tab). Browser* browser = nullptr; - aura::Window* window = nullptr; content::WebContents* web_contents_a; content::WebContents* web_contents_c; // Open app A in a tab. browser = CreateBrowser(); - window = browser->window()->GetNativeWindow(); web_contents_a = InsertForegroundTab(browser, "https://a.example.org"); // Open a second tab with no app.
diff --git a/chrome/browser/apps/app_service/webapk/webapk_install_task.cc b/chrome/browser/apps/app_service/webapk/webapk_install_task.cc index 6e2f857..6fd7dac2 100644 --- a/chrome/browser/apps/app_service/webapk/webapk_install_task.cc +++ b/chrome/browser/apps/app_service/webapk/webapk_install_task.cc
@@ -11,6 +11,7 @@ #include "base/command_line.h" #include "base/location.h" #include "base/logging.h" +#include "base/metrics/histogram_functions.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/task/task_traits.h" @@ -457,12 +458,19 @@ std::unique_ptr<std::string> response_body) { timer_.Stop(); - int response_code = -1; - if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers) - response_code = url_loader_->ResponseInfo()->headers->response_code(); + int response_or_error_code = -1; + if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers) { + response_or_error_code = + url_loader_->ResponseInfo()->headers->response_code(); + } else { + response_or_error_code = url_loader_->NetError(); + } + base::UmaHistogramSparse(kWebApkMinterErrorCodeHistogram, + response_or_error_code); - if (!response_body || response_code != net::HTTP_OK) { - LOG(WARNING) << "WebAPK server returned response code " << response_code; + if (!response_body || response_or_error_code != net::HTTP_OK) { + LOG(WARNING) << "WebAPK server request returned error " + << response_or_error_code; DeliverResult(WebApkInstallStatus::kNetworkError); return; }
diff --git a/chrome/browser/apps/app_service/webapk/webapk_install_task_unittest.cc b/chrome/browser/apps/app_service/webapk/webapk_install_task_unittest.cc index 7e62c02..ce0a554 100644 --- a/chrome/browser/apps/app_service/webapk/webapk_install_task_unittest.cc +++ b/chrome/browser/apps/app_service/webapk/webapk_install_task_unittest.cc
@@ -224,6 +224,8 @@ apps::WebApkInstallStatus::kSuccess, 1); histograms.ExpectBucketCount(apps::kWebApkArcInstallResultHistogram, arc::mojom::WebApkInstallResult::kSuccess, 1); + histograms.ExpectBucketCount(apps::kWebApkMinterErrorCodeHistogram, + net::HTTP_OK, 1); } TEST_F(WebApkInstallTaskTest, ShareTarget) { @@ -290,6 +292,8 @@ ASSERT_EQ(apps::webapk_prefs::GetWebApkAppIds(profile()).size(), 0); histograms.ExpectBucketCount(apps::kWebApkInstallResultHistogram, apps::WebApkInstallStatus::kNetworkError, 1); + histograms.ExpectBucketCount(apps::kWebApkMinterErrorCodeHistogram, + net::HTTP_BAD_REQUEST, 1); } TEST_F(WebApkInstallTaskTest, FailedArcInstall) {
diff --git a/chrome/browser/apps/app_service/webapk/webapk_metrics.cc b/chrome/browser/apps/app_service/webapk/webapk_metrics.cc index 92b9e9e..40bc57e 100644 --- a/chrome/browser/apps/app_service/webapk/webapk_metrics.cc +++ b/chrome/browser/apps/app_service/webapk/webapk_metrics.cc
@@ -15,6 +15,8 @@ "ChromeOS.WebAPK.Install.ArcInstallResult"; const char kWebApkArcUpdateResultHistogram[] = "ChromeOS.WebAPK.Update.ArcInstallResult"; +const char kWebApkMinterErrorCodeHistogram[] = + "ChromeOS.WebAPK.MinterResponseOrErrorCode"; void RecordWebApkInstallResult(bool is_update, WebApkInstallStatus result) { const char* histogram =
diff --git a/chrome/browser/apps/app_service/webapk/webapk_metrics.h b/chrome/browser/apps/app_service/webapk/webapk_metrics.h index c5e0e64..c511b4d 100644 --- a/chrome/browser/apps/app_service/webapk/webapk_metrics.h +++ b/chrome/browser/apps/app_service/webapk/webapk_metrics.h
@@ -37,6 +37,7 @@ extern const char kWebApkUpdateResultHistogram[]; extern const char kWebApkArcInstallResultHistogram[]; extern const char kWebApkArcUpdateResultHistogram[]; +extern const char kWebApkMinterErrorCodeHistogram[]; // Records the overall result of installing/updating a WebAPK to UMA. void RecordWebApkInstallResult(bool is_update, WebApkInstallStatus result);
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index 1648c25..b47600f 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -1840,6 +1840,14 @@ content::CollectAllRenderFrameHosts(embedder_main_frame), testing::UnorderedElementsAre(embedder_main_frame, other_guest_main_frame, unattached_guest_main_frame)); + + // In either case, GetParentOrOuterDocument does not escape GuestViews. + EXPECT_EQ(nullptr, other_guest_main_frame->GetParentOrOuterDocument()); + EXPECT_EQ(nullptr, unattached_guest_main_frame->GetParentOrOuterDocument()); + EXPECT_EQ(other_guest_main_frame, + other_guest_main_frame->GetOutermostMainFrame()); + EXPECT_EQ(unattached_guest_main_frame, + unattached_guest_main_frame->GetOutermostMainFrame()); } IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestContentLoadEvent) {
diff --git a/chrome/browser/ash/drive/drivefs_native_message_host.cc b/chrome/browser/ash/drive/drivefs_native_message_host.cc index 5d353db..9afa036 100644 --- a/chrome/browser/ash/drive/drivefs_native_message_host.cc +++ b/chrome/browser/ash/drive/drivefs_native_message_host.cc
@@ -21,6 +21,7 @@ #include "extensions/browser/extension_registry.h" #include "extensions/common/api/messaging/messaging_endpoint.h" #include "extensions/common/api/messaging/port_id.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/permissions/permissions_data.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -206,7 +207,8 @@ } const extensions::PortId port_id(base::UnguessableToken::Create(), - /* port_number= */ 1, /* is_opener= */ true); + /* port_number= */ 1, /* is_opener= */ true, + extensions::SerializationFormat::kJson); extensions::MessageService* const message_service = extensions::MessageService::Get(profile); auto native_message_host = CreateDriveFsInitiatedNativeMessageHost(
diff --git a/chrome/browser/ash/guest_os/vm_sk_forwarding_native_message_host.cc b/chrome/browser/ash/guest_os/vm_sk_forwarding_native_message_host.cc index 9aad636e..f225807 100644 --- a/chrome/browser/ash/guest_os/vm_sk_forwarding_native_message_host.cc +++ b/chrome/browser/ash/guest_os/vm_sk_forwarding_native_message_host.cc
@@ -24,6 +24,7 @@ #include "extensions/browser/api/messaging/native_message_host.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/api/messaging/messaging_endpoint.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/extension.h" #include "url/gurl.h" @@ -118,7 +119,8 @@ const std::string& json_message, base::OnceCallback<void(const std::string& response)> response_callback) { const extensions::PortId port_id(base::UnguessableToken::Create(), - 1 /* port_number */, true /* is_opener */); + 1 /* port_number */, true /* is_opener */, + extensions::SerializationFormat::kJson); extensions::MessageService* const message_service = extensions::MessageService::Get(profile);
diff --git a/chrome/browser/ash/input_method/suggestions_service_client.cc b/chrome/browser/ash/input_method/suggestions_service_client.cc index e88ecd22..08fea08a 100644 --- a/chrome/browser/ash/input_method/suggestions_service_client.cc +++ b/chrome/browser/ash/input_method/suggestions_service_client.cc
@@ -85,20 +85,18 @@ ->GetMachineLearningService() .LoadTextSuggester( text_suggester_.BindNewPipeAndPassReceiver(), std::move(spec), - base::BindOnce( - [](base::WeakPtr<SuggestionsServiceClient> weak_this, - chromeos::machine_learning::mojom::LoadModelResult result) { - if (weak_this) { - weak_this->text_suggester_loaded_ = - result == - chromeos::machine_learning::mojom::LoadModelResult::OK; - } - }, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&SuggestionsServiceClient::OnTextSuggesterLoaded, + weak_ptr_factory_.GetWeakPtr())); } SuggestionsServiceClient::~SuggestionsServiceClient() = default; +void SuggestionsServiceClient::OnTextSuggesterLoaded( + chromeos::machine_learning::mojom::LoadModelResult result) { + text_suggester_loaded_ = + result == chromeos::machine_learning::mojom::LoadModelResult::OK; +} + void SuggestionsServiceClient::RequestSuggestions( const std::string& preceding_text, const ime::TextSuggestionMode& suggestion_mode,
diff --git a/chrome/browser/ash/input_method/suggestions_service_client.h b/chrome/browser/ash/input_method/suggestions_service_client.h index 0bf05b6c..43eeb69 100644 --- a/chrome/browser/ash/input_method/suggestions_service_client.h +++ b/chrome/browser/ash/input_method/suggestions_service_client.h
@@ -12,6 +12,7 @@ #include "base/time/time.h" #include "chrome/browser/ash/input_method/suggestions_source.h" #include "chromeos/services/ime/public/cpp/suggestions.h" +#include "chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom.h" #include "chromeos/services/machine_learning/public/mojom/text_suggester.mojom.h" #include "mojo/public/cpp/bindings/remote.h" @@ -33,6 +34,11 @@ bool IsAvailable() override; private: + // Called once the text suggester model has been loaded and is (or is not) + // available for use. + void OnTextSuggesterLoaded( + chromeos::machine_learning::mojom::LoadModelResult result); + // Called when results are returned from the suggestions service void OnSuggestionsReturned( base::TimeTicks time_request_was_made,
diff --git a/chrome/browser/ash/login/users/avatar/user_image_sync_observer.cc b/chrome/browser/ash/login/users/avatar/user_image_sync_observer.cc index d78edec..28a8767 100644 --- a/chrome/browser/ash/login/users/avatar/user_image_sync_observer.cc +++ b/chrome/browser/ash/login/users/avatar/user_image_sync_observer.cc
@@ -89,12 +89,10 @@ void UserImageSyncObserver::OnInitialSync() { int synced_index; - bool local_image_updated = false; if (!GetSyncedImageIndex(&synced_index) || local_image_changed_) { UpdateSyncedImageFromLocal(); } else if (IsIndexSupported(synced_index)) { UpdateLocalImageFromSynced(); - local_image_updated = true; } }
diff --git a/chrome/browser/ash/ownership/owner_settings_service_ash.cc b/chrome/browser/ash/ownership/owner_settings_service_ash.cc index 91d9de6..9035e6b 100644 --- a/chrome/browser/ash/ownership/owner_settings_service_ash.cc +++ b/chrome/browser/ash/ownership/owner_settings_service_ash.cc
@@ -688,6 +688,8 @@ // kVariationsRestrictParameter // kDeviceDisabled // kDeviceDisabledMessage + // ReportDeviceNetworkTelemetryCollectionRateMs + // ReportDeviceNetworkTelemetryEventCheckingRateMs LOG(FATAL) << "Device setting " << path << " is read-only."; }
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder.cc b/chrome/browser/ash/policy/core/device_policy_decoder.cc index cc71403d..a5266db 100644 --- a/chrome/browser/ash/policy/core/device_policy_decoder.cc +++ b/chrome/browser/ash/policy/core/device_policy_decoder.cc
@@ -694,6 +694,16 @@ } } +void DecodeIntegerReportingPolicy(PolicyMap* policies, + const std::string& policy_path, + google::protobuf::int64 int_value) { + std::unique_ptr<base::Value> value = DecodeIntegerValue(int_value); + if (value) { + policies->Set(policy_path, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_CLOUD, std::move(*value), nullptr); + } +} + void DecodeReportingPolicies(const em::ChromeDeviceSettingsProto& policy, PolicyMap* policies) { if (policy.has_device_reporting()) { @@ -794,13 +804,8 @@ base::Value(container.report_board_status()), nullptr); } if (container.has_device_status_frequency()) { - std::unique_ptr<base::Value> value( - DecodeIntegerValue(container.device_status_frequency())); - if (value) { - policies->Set(key::kReportUploadFrequency, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, - std::move(*value), nullptr); - } + DecodeIntegerReportingPolicy(policies, key::kReportUploadFrequency, + container.device_status_frequency()); } if (container.has_report_cpu_info()) { policies->Set(key::kReportDeviceCpuInfo, POLICY_LEVEL_MANDATORY, @@ -862,6 +867,16 @@ POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, base::Value(container.report_login_logout()), nullptr); } + if (container.has_report_network_telemetry_collection_rate_ms()) { + DecodeIntegerReportingPolicy( + policies, key::kReportDeviceNetworkTelemetryCollectionRateMs, + container.report_network_telemetry_collection_rate_ms()); + } + if (container.has_report_network_telemetry_event_checking_rate_ms()) { + DecodeIntegerReportingPolicy( + policies, key::kReportDeviceNetworkTelemetryEventCheckingRateMs, + container.report_network_telemetry_event_checking_rate_ms()); + } } if (policy.has_device_heartbeat_settings()) { @@ -873,13 +888,8 @@ base::Value(container.heartbeat_enabled()), nullptr); } if (container.has_heartbeat_frequency()) { - std::unique_ptr<base::Value> value( - DecodeIntegerValue(container.heartbeat_frequency())); - if (value) { - policies->Set(key::kHeartbeatFrequency, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, - std::move(*value), nullptr); - } + DecodeIntegerReportingPolicy(policies, key::kHeartbeatFrequency, + container.heartbeat_frequency()); } }
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc b/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc index f8b74ad..227b4865 100644 --- a/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc +++ b/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc
@@ -67,6 +67,13 @@ protected: std::unique_ptr<base::Value> GetWallpaperDict() const; std::unique_ptr<base::Value> GetBluetoothServiceAllowedList() const; + void DecodeDevicePolicyTestHelper( + const em::ChromeDeviceSettingsProto& device_policy, + const std::string& policy_path, + base::Value expected_value) const; + void DecodeUnsetDevicePolicyTestHelper( + const em::ChromeDeviceSettingsProto& device_policy, + const std::string& policy_path) const; }; std::unique_ptr<base::Value> DevicePolicyDecoderTest::GetWallpaperDict() const { @@ -87,6 +94,36 @@ return list; } +void DevicePolicyDecoderTest::DecodeDevicePolicyTestHelper( + const em::ChromeDeviceSettingsProto& device_policy, + const std::string& policy_path, + base::Value expected_value) const { + PolicyBundle bundle; + PolicyMap& policies = bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")); + + base::WeakPtr<ExternalDataManager> external_data_manager; + + DecodeDevicePolicy(device_policy, external_data_manager, &policies); + + const base::Value* actual_value = policies.GetValue(policy_path); + ASSERT_NE(actual_value, nullptr); + EXPECT_EQ(*actual_value, expected_value); +} + +void DevicePolicyDecoderTest::DecodeUnsetDevicePolicyTestHelper( + const em::ChromeDeviceSettingsProto& device_policy, + const std::string& policy_path) const { + PolicyBundle bundle; + PolicyMap& policies = bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")); + + base::WeakPtr<ExternalDataManager> external_data_manager; + + DecodeDevicePolicy(device_policy, external_data_manager, &policies); + + const base::Value* actual_value = policies.GetValue(policy_path); + EXPECT_EQ(actual_value, nullptr); +} + TEST_F(DevicePolicyDecoderTest, DecodeJsonStringAndNormalizeJSONParseError) { std::string error; absl::optional<base::Value> decoded_json = DecodeJsonStringAndNormalize( @@ -173,130 +210,136 @@ } TEST_F(DevicePolicyDecoderTest, ReportDeviceLoginLogout) { - PolicyBundle bundle; - PolicyMap& policies = bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")); - - base::WeakPtr<ExternalDataManager> external_data_manager; - em::ChromeDeviceSettingsProto device_policy; - device_policy.mutable_device_reporting()->set_report_login_logout(true); - DecodeDevicePolicy(device_policy, external_data_manager, &policies); + DecodeUnsetDevicePolicyTestHelper(device_policy, + key::kReportDeviceLoginLogout); - const base::Value* report_device_login_logout_value = - policies.GetValue(key::kReportDeviceLoginLogout); - ASSERT_NE(report_device_login_logout_value, nullptr); - ASSERT_TRUE(report_device_login_logout_value->is_bool()); - EXPECT_TRUE(report_device_login_logout_value->GetBool()); + base::Value report_login_logout_value(true); + device_policy.mutable_device_reporting()->set_report_login_logout( + report_login_logout_value.GetBool()); + + DecodeDevicePolicyTestHelper(device_policy, key::kReportDeviceLoginLogout, + std::move(report_login_logout_value)); +} + +TEST_F(DevicePolicyDecoderTest, ReportDeviceNetworkTelemetryCollectionRateMs) { + em::ChromeDeviceSettingsProto device_policy; + + DecodeUnsetDevicePolicyTestHelper( + device_policy, key::kReportDeviceNetworkTelemetryCollectionRateMs); + + base::Value collection_rate_ms_value(120000); + device_policy.mutable_device_reporting() + ->set_report_network_telemetry_collection_rate_ms( + collection_rate_ms_value.GetInt()); + + DecodeDevicePolicyTestHelper( + device_policy, key::kReportDeviceNetworkTelemetryCollectionRateMs, + std::move(collection_rate_ms_value)); +} + +TEST_F(DevicePolicyDecoderTest, + ReportDeviceNetworkTelemetryEventCheckingRateMs) { + em::ChromeDeviceSettingsProto device_policy; + + DecodeUnsetDevicePolicyTestHelper( + device_policy, key::kReportDeviceNetworkTelemetryEventCheckingRateMs); + + base::Value event_checking_rate_ms_value(80000); + device_policy.mutable_device_reporting() + ->set_report_network_telemetry_event_checking_rate_ms( + event_checking_rate_ms_value.GetInt()); + + DecodeDevicePolicyTestHelper( + device_policy, key::kReportDeviceNetworkTelemetryEventCheckingRateMs, + std::move(event_checking_rate_ms_value)); } TEST_F(DevicePolicyDecoderTest, EnableDeviceGranularReporting) { - PolicyBundle bundle; - PolicyMap& policies = bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")); - - base::WeakPtr<ExternalDataManager> external_data_manager; - em::ChromeDeviceSettingsProto device_policy; - device_policy.mutable_device_reporting()->set_enable_granular_reporting(true); - DecodeDevicePolicy(device_policy, external_data_manager, &policies); + DecodeUnsetDevicePolicyTestHelper(device_policy, + key::kEnableDeviceGranularReporting); - const base::Value* enable_granular_reporting_value = - policies.GetValue(key::kEnableDeviceGranularReporting); - ASSERT_NE(enable_granular_reporting_value, nullptr); - ASSERT_TRUE(enable_granular_reporting_value->is_bool()); - EXPECT_TRUE(enable_granular_reporting_value->GetBool()); + base::Value enable_granular_reporting_value(true); + device_policy.mutable_device_reporting()->set_enable_granular_reporting( + enable_granular_reporting_value.GetBool()); + + DecodeDevicePolicyTestHelper(device_policy, + key::kEnableDeviceGranularReporting, + std::move(enable_granular_reporting_value)); } TEST_F(DevicePolicyDecoderTest, ReportDeviceAudioStatus) { - PolicyBundle bundle; - PolicyMap& policies = bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")); - - base::WeakPtr<ExternalDataManager> external_data_manager; - em::ChromeDeviceSettingsProto device_policy; - device_policy.mutable_device_reporting()->set_report_audio_status(true); - DecodeDevicePolicy(device_policy, external_data_manager, &policies); + DecodeUnsetDevicePolicyTestHelper(device_policy, + key::kReportDeviceAudioStatus); - const base::Value* report_device_audio_status_value = - policies.GetValue(key::kReportDeviceAudioStatus); - ASSERT_NE(report_device_audio_status_value, nullptr); - ASSERT_TRUE(report_device_audio_status_value->is_bool()); - EXPECT_TRUE(report_device_audio_status_value->GetBool()); + base::Value report_audio_status_value(true); + device_policy.mutable_device_reporting()->set_report_audio_status( + report_audio_status_value.GetBool()); + + DecodeDevicePolicyTestHelper(device_policy, key::kReportDeviceAudioStatus, + std::move(report_audio_status_value)); } TEST_F(DevicePolicyDecoderTest, ReportDeviceSecurityStatus) { - PolicyBundle bundle; - PolicyMap& policies = bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")); - - base::WeakPtr<ExternalDataManager> external_data_manager; - em::ChromeDeviceSettingsProto device_policy; - device_policy.mutable_device_reporting()->set_report_security_status(true); - DecodeDevicePolicy(device_policy, external_data_manager, &policies); + DecodeUnsetDevicePolicyTestHelper(device_policy, + key::kReportDeviceSecurityStatus); - const base::Value* report_device_security_status_value = - policies.GetValue(key::kReportDeviceSecurityStatus); - ASSERT_NE(report_device_security_status_value, nullptr); - ASSERT_TRUE(report_device_security_status_value->is_bool()); - EXPECT_TRUE(report_device_security_status_value->GetBool()); + base::Value report_security_status_value(true); + device_policy.mutable_device_reporting()->set_report_security_status( + report_security_status_value.GetBool()); + + DecodeDevicePolicyTestHelper(device_policy, key::kReportDeviceSecurityStatus, + std::move(report_security_status_value)); } TEST_F(DevicePolicyDecoderTest, ReportDeviceNetworkConfiguration) { - PolicyBundle bundle; - PolicyMap& policies = bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")); - - base::WeakPtr<ExternalDataManager> external_data_manager; - em::ChromeDeviceSettingsProto device_policy; + + DecodeUnsetDevicePolicyTestHelper(device_policy, + key::kReportDeviceNetworkConfiguration); + + base::Value report_network_configuration_value(true); device_policy.mutable_device_reporting()->set_report_network_configuration( - true); + report_network_configuration_value.GetBool()); - DecodeDevicePolicy(device_policy, external_data_manager, &policies); - - const base::Value* report_device_network_configuration_value = - policies.GetValue(key::kReportDeviceNetworkConfiguration); - ASSERT_NE(report_device_network_configuration_value, nullptr); - ASSERT_TRUE(report_device_network_configuration_value->is_bool()); - EXPECT_TRUE(report_device_network_configuration_value->GetBool()); + DecodeDevicePolicyTestHelper(device_policy, + key::kReportDeviceNetworkConfiguration, + std::move(report_network_configuration_value)); } TEST_F(DevicePolicyDecoderTest, ReportDeviceNetworkStatus) { - PolicyBundle bundle; - PolicyMap& policies = bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")); - - base::WeakPtr<ExternalDataManager> external_data_manager; - em::ChromeDeviceSettingsProto device_policy; - device_policy.mutable_device_reporting()->set_report_network_status(true); - DecodeDevicePolicy(device_policy, external_data_manager, &policies); + DecodeUnsetDevicePolicyTestHelper(device_policy, + key::kReportDeviceNetworkStatus); - const base::Value* report_device_network_status_value = - policies.GetValue(key::kReportDeviceNetworkStatus); - ASSERT_NE(report_device_network_status_value, nullptr); - ASSERT_TRUE(report_device_network_status_value->is_bool()); - EXPECT_TRUE(report_device_network_status_value->GetBool()); + base::Value report_network_status_value(true); + device_policy.mutable_device_reporting()->set_report_network_status( + report_network_status_value.GetBool()); + + DecodeDevicePolicyTestHelper(device_policy, key::kReportDeviceNetworkStatus, + std::move(report_network_status_value)); } TEST_F(DevicePolicyDecoderTest, kReportDeviceOsUpdateStatus) { - PolicyBundle bundle; - PolicyMap& policies = bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")); - - base::WeakPtr<ExternalDataManager> external_data_manager; - em::ChromeDeviceSettingsProto device_policy; - device_policy.mutable_device_reporting()->set_report_os_update_status(true); - DecodeDevicePolicy(device_policy, external_data_manager, &policies); + DecodeUnsetDevicePolicyTestHelper(device_policy, + key::kReportDeviceOsUpdateStatus); - const base::Value* report_device_os_update_status_value = - policies.GetValue(key::kReportDeviceOsUpdateStatus); - ASSERT_NE(report_device_os_update_status_value, nullptr); - ASSERT_TRUE(report_device_os_update_status_value->is_bool()); - EXPECT_TRUE(report_device_os_update_status_value->GetBool()); + base::Value report_os_update_status_value(true); + device_policy.mutable_device_reporting()->set_report_os_update_status( + report_os_update_status_value.GetBool()); + + DecodeDevicePolicyTestHelper(device_policy, key::kReportDeviceOsUpdateStatus, + std::move(report_os_update_status_value)); } TEST_F(DevicePolicyDecoderTest, DecodeServiceUUIDListSuccess) { @@ -321,17 +364,19 @@ TEST_F(DevicePolicyDecoderTest, DecodeLoginScreenPromptOnMultipleMatchingCertificates) { em::ChromeDeviceSettingsProto device_policy; - device_policy.mutable_login_screen_prompt_on_multiple_matching_certificates() - ->set_value(true); - PolicyMap policies; - DecodeDevicePolicy(device_policy, /*external_data_manager=*/{}, &policies); - - const base::Value* policy_value = policies.GetValue( + DecodeUnsetDevicePolicyTestHelper( + device_policy, key::kDeviceLoginScreenPromptOnMultipleMatchingCertificates); - ASSERT_NE(policy_value, nullptr); - ASSERT_TRUE(policy_value->is_bool()); - EXPECT_TRUE(policy_value->GetBool()); + + base::Value login_screen_prompt_value(true); + device_policy.mutable_login_screen_prompt_on_multiple_matching_certificates() + ->set_value(login_screen_prompt_value.GetBool()); + + DecodeDevicePolicyTestHelper( + device_policy, + key::kDeviceLoginScreenPromptOnMultipleMatchingCertificates, + std::move(login_screen_prompt_value)); } } // namespace policy
diff --git a/chrome/browser/ash/settings/device_settings_provider.cc b/chrome/browser/ash/settings/device_settings_provider.cc index 3a48ae0..77487180 100644 --- a/chrome/browser/ash/settings/device_settings_provider.cc +++ b/chrome/browser/ash/settings/device_settings_provider.cc
@@ -137,6 +137,8 @@ kReportDeviceNetworkConfiguration, kReportDeviceNetworkInterfaces, kReportDeviceNetworkStatus, + kReportDeviceNetworkTelemetryCollectionRateMs, + kReportDeviceNetworkTelemetryEventCheckingRateMs, kReportDeviceSessionStatus, kReportDeviceSecurityStatus, kReportDeviceTimezoneInfo, @@ -738,6 +740,17 @@ new_values_cache->SetBoolean(kReportDeviceLoginLogout, reporting_policy.report_login_logout()); } + if (reporting_policy.has_report_network_telemetry_collection_rate_ms()) { + new_values_cache->SetInteger( + kReportDeviceNetworkTelemetryCollectionRateMs, + reporting_policy.report_network_telemetry_collection_rate_ms()); + } + if (reporting_policy + .has_report_network_telemetry_event_checking_rate_ms()) { + new_values_cache->SetInteger( + kReportDeviceNetworkTelemetryEventCheckingRateMs, + reporting_policy.report_network_telemetry_event_checking_rate_ms()); + } } }
diff --git a/chrome/browser/ash/settings/device_settings_provider_unittest.cc b/chrome/browser/ash/settings/device_settings_provider_unittest.cc index b23f7b13..0e8efed 100644 --- a/chrome/browser/ash/settings/device_settings_provider_unittest.cc +++ b/chrome/browser/ash/settings/device_settings_provider_unittest.cc
@@ -116,6 +116,8 @@ proto->set_report_app_info(enable_reporting); proto->set_report_print_jobs(enable_reporting); proto->set_report_login_logout(enable_reporting); + proto->set_report_network_telemetry_collection_rate_ms(frequency); + proto->set_report_network_telemetry_event_checking_rate_ms(frequency); proto->set_device_status_frequency(frequency); BuildAndInstallDevicePolicy(); } @@ -208,9 +210,17 @@ EXPECT_EQ(expected_enable_value, *provider_->Get(setting)) << "Value for " << setting << " does not match expected"; } + + const char* const reporting_frequency_settings[] = { + kReportUploadFrequency, + kReportDeviceNetworkTelemetryCollectionRateMs, + kReportDeviceNetworkTelemetryEventCheckingRateMs, + }; const base::Value expected_frequency_value(expected_frequency); - EXPECT_EQ(expected_frequency_value, - *provider_->Get(kReportUploadFrequency)); + for (auto* frequency_setting : reporting_frequency_settings) { + EXPECT_EQ(expected_frequency_value, *provider_->Get(frequency_setting)) + << "Value for " << frequency_setting << " does not match expected"; + } } // Helper routine to ensure log upload policy has been correctly
diff --git a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_messaging.cc b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_messaging.cc index 039f4b4..54fd74c 100644 --- a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_messaging.cc +++ b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_messaging.cc
@@ -29,6 +29,7 @@ #include "extensions/browser/api/messaging/native_message_host.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/api/messaging/messaging_endpoint.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/extension.h" #include "mojo/public/cpp/system/handle.h" #include "url/gurl.h" @@ -348,7 +349,8 @@ base::OnceCallback<void(const std::string& response)> send_response_callback) { const extensions::PortId port_id(base::UnguessableToken::Create(), - 1 /* port_number */, true /* is_opener */); + 1 /* port_number */, true /* is_opener */, + extensions::SerializationFormat::kJson); extensions::MessageService* const message_service = extensions::MessageService::Get(profile); auto native_message_host =
diff --git a/chrome/browser/chromeos/eche_app/eche_app_manager_factory.cc b/chrome/browser/chromeos/eche_app/eche_app_manager_factory.cc index 46417b62..8fb62d0 100644 --- a/chrome/browser/chromeos/eche_app/eche_app_manager_factory.cc +++ b/chrome/browser/chromeos/eche_app/eche_app_manager_factory.cc
@@ -29,6 +29,9 @@ #include "chromeos/components/eche_app_ui/eche_uid_provider.h" #include "chromeos/components/eche_app_ui/system_info.h" #include "chromeos/components/phonehub/phone_hub_manager.h" +#include "chromeos/services/secure_channel/presence_monitor_impl.h" +#include "chromeos/services/secure_channel/public/cpp/client/presence_monitor_client_impl.h" +#include "chromeos/services/secure_channel/public/cpp/shared/presence_monitor.h" #include "chromeos/strings/grit/chromeos_strings.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/pref_registry/pref_registry_syncable.h" @@ -197,9 +200,17 @@ if (!secure_channel_client) return nullptr; + auto presence_monitor = + std::make_unique<secure_channel::PresenceMonitorImpl>(); + std::unique_ptr<secure_channel::PresenceMonitorClient> + presence_monitor_client = + secure_channel::PresenceMonitorClientImpl::Factory::Create( + std::move(presence_monitor)); + return new EcheAppManager( profile->GetPrefs(), GetSystemInfo(profile), phone_hub_manager, device_sync_client, multidevice_setup_client, secure_channel_client, + std::move(presence_monitor_client), base::BindRepeating(&LaunchEcheApp, profile), base::BindRepeating(&CloseEcheApp, profile), base::BindRepeating(&EcheAppManagerFactory::ShowNotification,
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc index 3a7bdf74..47e4487 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
@@ -595,9 +595,17 @@ DevToolsToggleAction::Inspect()); break; case extensions::api::file_manager_private::INSPECTION_TYPE_BACKGROUND: - // Open inspector for background page. - extensions::devtools_util::InspectBackgroundPage( - extension(), Profile::FromBrowserContext(browser_context())); + // Open inspector for background page if extension pointer is not null. + // Files app SWA is not an extension and thus has no associated background + // page. + if (extension()) { + extensions::devtools_util::InspectBackgroundPage( + extension(), Profile::FromBrowserContext(browser_context())); + } else { + return RespondNow( + Error(base::StringPrintf("Inspection type(%d) not supported.", + static_cast<int>(params->type)))); + } break; default: NOTREACHED();
diff --git a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc index 78cb4a9..cc68710 100644 --- a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc +++ b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc
@@ -353,14 +353,12 @@ base::Value::ListView& event_arguments) { std::unique_ptr<message_center::Notification> notification; file_manager_private::DriveConfirmDialogEvent dialog_event; - const char* id; std::u16string title = l10n_util::GetStringUTF16(IDS_FILE_BROWSER_DRIVE_DIRECTORY_LABEL); std::u16string message; if (file_manager_private::DriveConfirmDialogEvent::Populate( event_arguments[0], &dialog_event)) { std::vector<message_center::ButtonInfo> notification_buttons; - id = file_manager_private::ToString(dialog_event.type); scoped_refptr<message_center::NotificationDelegate> delegate = new message_center::HandleNotificationClickDelegate(base::BindRepeating( &SystemNotificationManager::HandleDriveDialogClick,
diff --git a/chrome/browser/chromeos/extensions/incoming_native_messaging_apitest.cc b/chrome/browser/chromeos/extensions/incoming_native_messaging_apitest.cc index 5ea3807c..fa4a0f9 100644 --- a/chrome/browser/chromeos/extensions/incoming_native_messaging_apitest.cc +++ b/chrome/browser/chromeos/extensions/incoming_native_messaging_apitest.cc
@@ -21,6 +21,7 @@ #include "extensions/browser/api/messaging/native_message_host.h" #include "extensions/common/api/messaging/messaging_endpoint.h" #include "extensions/common/api/messaging/port_id.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/test/result_catcher.h" #include "ipc/ipc_message.h" #include "testing/gmock/include/gmock/gmock.h" @@ -75,7 +76,8 @@ std::unique_ptr<extensions::NativeMessageHost> native_message_host) { auto* const message_service = extensions::MessageService::Get(profile()); const extensions::PortId port_id(base::UnguessableToken::Create(), - 1 /* port_number */, true /* is_opener */); + 1 /* port_number */, true /* is_opener */, + extensions::SerializationFormat::kJson); auto native_message_port = std::make_unique<extensions::NativeMessagePort>( message_service->GetChannelDelegate(), port_id, std::move(native_message_host));
diff --git a/chrome/browser/commerce/merchant_viewer/android/BUILD.gn b/chrome/browser/commerce/merchant_viewer/android/BUILD.gn index 0b2a36e3..d4e3ae3 100644 --- a/chrome/browser/commerce/merchant_viewer/android/BUILD.gn +++ b/chrome/browser/commerce/merchant_viewer/android/BUILD.gn
@@ -180,6 +180,7 @@ "//third_party/android_deps:espresso_java", "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/android_support_test_runner:runner_java", + "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_test_core_java", "//third_party/androidx:androidx_test_runner_java",
diff --git a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustBottomSheetCoordinator.java b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustBottomSheetCoordinator.java index 3b07c40..eaafad6 100644 --- a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustBottomSheetCoordinator.java +++ b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustBottomSheetCoordinator.java
@@ -74,8 +74,8 @@ } /** Displays the details tab sheet. */ - public void requestOpenSheet(GURL url, String title) { - setupSheet(); + public void requestOpenSheet(GURL url, String title, Runnable onBottomSheetDismissed) { + setupSheet(onBottomSheetDismissed); mMediator.navigateToUrl(url, title); mBottomSheetController.requestShowContent(mSheetContent, true); } @@ -85,7 +85,7 @@ mBottomSheetController.hideContent(mSheetContent, true); } - private void setupSheet() { + private void setupSheet(Runnable onBottomSheetDismissed) { if (mSheetContent != null) { return; } @@ -106,6 +106,13 @@ public void onSheetContentChanged(BottomSheetContent newContent) { if (newContent != mSheetContent) { mMetrics.recordMetricsForBottomSheetClosed(mCloseReason); + if (onBottomSheetDismissed != null + && (mCloseReason == StateChangeReason.NONE + || mCloseReason == StateChangeReason.SWIPE + || mCloseReason == StateChangeReason.BACK_PRESS + || mCloseReason == StateChangeReason.TAP_SCRIM)) { + onBottomSheetDismissed.run(); + } destroySheet(); } }
diff --git a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewModel.java b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewModel.java index e3a00b5..3bd604a9 100644 --- a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewModel.java +++ b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewModel.java
@@ -41,8 +41,9 @@ /** * Called when message primary action is tapped. * @param trustSignals The signal associated with this message. + * @param messageAssociatedUrl The url associated with this message context. */ - void onMessagePrimaryAction(MerchantTrustSignals trustSignals); + void onMessagePrimaryAction(MerchantTrustSignals trustSignals, String messageAssociatedUrl); } public static PropertyModel create(Context context, MerchantTrustSignals trustSignals, @@ -62,7 +63,9 @@ .with(MessageBannerProperties.ON_DISMISSED, (reason) -> actionsHandler.onMessageDismissed(reason, messageAssociatedUrl)) .with(MessageBannerProperties.ON_PRIMARY_ACTION, - () -> actionsHandler.onMessagePrimaryAction(trustSignals)) + () + -> actionsHandler.onMessagePrimaryAction( + trustSignals, messageAssociatedUrl)) .build(); }
diff --git a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMetrics.java b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMetrics.java index 57354de..3806ff8 100644 --- a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMetrics.java +++ b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMetrics.java
@@ -37,6 +37,24 @@ int MAX_VALUE = 2; } + /** + * Which ui the bottom sheet is opened from. + * + * Needs to stay in sync with MerchantTrustBottomSheetOpenedSource in enums.xml. These values + * are persisted to logs. Entries should not be renumbered and numeric values should never be + * reused. + */ + @IntDef({BottomSheetOpenedSource.UNKNOWN, BottomSheetOpenedSource.FROM_MESSAGE, + BottomSheetOpenedSource.FROM_PAGE_INFO}) + @Retention(RetentionPolicy.SOURCE) + public @interface BottomSheetOpenedSource { + int UNKNOWN = 0; + int FROM_MESSAGE = 1; + int FROM_PAGE_INFO = 2; + // Always update MAX_VALUE to match the last item in the list. + int MAX_VALUE = 2; + } + // Metrics for merchant trust signal message. private boolean mDidRecordMessagePrepared; private boolean mDidRecordMessageShown;
diff --git a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinator.java b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinator.java index 009da682..be39af0b 100644 --- a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinator.java +++ b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinator.java
@@ -16,6 +16,7 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; +import org.chromium.chrome.browser.merchant_viewer.MerchantTrustMetrics.BottomSheetOpenedSource; import org.chromium.chrome.browser.merchant_viewer.MerchantTrustMetrics.MessageClearReason; import org.chromium.chrome.browser.merchant_viewer.proto.MerchantTrustSignalsOuterClass.MerchantTrustSignals; import org.chromium.chrome.browser.preferences.Pref; @@ -233,24 +234,37 @@ } @Override - public void onMessagePrimaryAction(MerchantTrustSignals trustSignals) { + public void onMessagePrimaryAction( + MerchantTrustSignals trustSignals, String messageAssociatedUrl) { mMetrics.recordMetricsForMessageTapped(); - launchDetailsPage(new GURL(trustSignals.getMerchantDetailsPageUrl())); + launchDetailsPage(new GURL(trustSignals.getMerchantDetailsPageUrl()), + () + -> onBottomSheetDismissed( + BottomSheetOpenedSource.FROM_MESSAGE, messageAssociatedUrl)); } // PageInfoStoreInfoController.StoreInfoActionHandler implementation. @Override public void onStoreInfoClicked(MerchantTrustSignals trustSignals) { - launchDetailsPage(new GURL(trustSignals.getMerchantDetailsPageUrl())); + launchDetailsPage(new GURL(trustSignals.getMerchantDetailsPageUrl()), + () -> onBottomSheetDismissed(BottomSheetOpenedSource.FROM_PAGE_INFO, null)); // If user has clicked the "Store info" row, send a signal to disable {@link // FeatureConstants.PAGE_INFO_STORE_INFO_FEATURE}. final Tracker tracker = TrackerFactory.getTrackerForProfile(mProfileSupplier.get()); tracker.notifyEvent(EventConstants.PAGE_INFO_STORE_INFO_ROW_CLICKED); } - private void launchDetailsPage(GURL url) { + private void launchDetailsPage(GURL url, Runnable onBottomSheetDismissed) { mDetailsTabCoordinator.requestOpenSheet(url, - mContext.getResources().getString(R.string.merchant_viewer_preview_sheet_title)); + mContext.getResources().getString(R.string.merchant_viewer_preview_sheet_title), + onBottomSheetDismissed); + } + + private void onBottomSheetDismissed( + @BottomSheetOpenedSource int openSource, @Nullable String messageAssociatedUrl) { + if (openSource == BottomSheetOpenedSource.FROM_MESSAGE && messageAssociatedUrl != null) { + maybeShowStoreIcon(messageAssociatedUrl); + } } /**
diff --git a/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustBottomSheetCoordinatorTest.java b/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustBottomSheetCoordinatorTest.java index 28c2ca1..19789ad 100644 --- a/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustBottomSheetCoordinatorTest.java +++ b/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustBottomSheetCoordinatorTest.java
@@ -84,6 +84,9 @@ @Mock private MerchantTrustBottomSheetMediator mMockMediator; + @Mock + private Runnable mMockOnBottomSheetDismissed; + @Captor private ArgumentCaptor<EmptyBottomSheetObserver> mBottomSheetObserverCaptor; @@ -119,8 +122,10 @@ } private void requestOpenSheetAndVerify() { - TestThreadUtils.runOnUiThreadBlocking( - () -> { mDetailsTabCoordinator.requestOpenSheet(mMockGurl, DUMMY_SHEET_TITLE); }); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mDetailsTabCoordinator.requestOpenSheet( + mMockGurl, DUMMY_SHEET_TITLE, mMockOnBottomSheetDismissed); + }); verify(mMockMediator, times(1)) .setupSheetWebContents(any(ThinWebView.class), any(PropertyModel.class)); verify(mMockBottomSheetController, times(1)) @@ -148,6 +153,7 @@ () -> { mBottomSheetObserverCaptor.getValue().onSheetContentChanged(null); }); verify(mMockMetrics, times(1)) .recordMetricsForBottomSheetClosed(eq(StateChangeReason.BACK_PRESS)); + verify(mMockOnBottomSheetDismissed, times(1)).run(); verify(mMockDecorView, times(1)) .removeOnLayoutChangeListener(any(OnLayoutChangeListener.class)); verify(mMockBottomSheetController, times(1))
diff --git a/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinatorTest.java b/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinatorTest.java index 3d5cd977..4686099e 100644 --- a/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinatorTest.java +++ b/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinatorTest.java
@@ -27,6 +27,8 @@ import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; @@ -133,6 +135,9 @@ @Mock private Tracker mMockTracker; + @Captor + private ArgumentCaptor<Runnable> mOnBottomSheetDismissedCaptor; + private static final String FAKE_HOST = "fake_host"; private static final String DIFFERENT_HOST = "different_host"; private static final String FAKE_URL = "fake_url"; @@ -487,10 +492,13 @@ @SmallTest @Test public void testOnMessagePrimaryAction() { - mCoordinator.onMessagePrimaryAction(mDummyMerchantTrustSignals); + mCoordinator.onMessagePrimaryAction(mDummyMerchantTrustSignals, FAKE_URL); verify(mMockMetrics, times(1)).recordMetricsForMessageTapped(); verify(mMockDetailsTabCoordinator, times(1)) - .requestOpenSheet(any(GURL.class), any(String.class)); + .requestOpenSheet(any(GURL.class), any(String.class), + mOnBottomSheetDismissedCaptor.capture()); + mOnBottomSheetDismissedCaptor.getValue().run(); + verify(mCoordinator, times(1)).maybeShowStoreIcon(eq(FAKE_URL)); } @SmallTest @@ -500,9 +508,12 @@ mCoordinator.onStoreInfoClicked(mDummyMerchantTrustSignals); verify(mMockDetailsTabCoordinator, times(1)) - .requestOpenSheet(any(GURL.class), any(String.class)); + .requestOpenSheet(any(GURL.class), any(String.class), + mOnBottomSheetDismissedCaptor.capture()); verify(mMockTracker, times(1)) .notifyEvent(eq(EventConstants.PAGE_INFO_STORE_INFO_ROW_CLICKED)); + mOnBottomSheetDismissedCaptor.getValue().run(); + verify(mCoordinator, times(0)).maybeShowStoreIcon(any()); TrackerFactory.setTrackerForTests(null); }
diff --git a/chrome/browser/component_updater/cros_component_installer_chromeos.cc b/chrome/browser/component_updater/cros_component_installer_chromeos.cc index fe0e50b..15aa188 100644 --- a/chrome/browser/component_updater/cros_component_installer_chromeos.cc +++ b/chrome/browser/component_updater/cros_component_installer_chromeos.cc
@@ -35,7 +35,7 @@ // All downloadable Chrome OS components. const ComponentConfig kConfigs[] = { - {"cros-termina", ComponentConfig::PolicyType::kEnvVersion, "960.1", + {"cros-termina", ComponentConfig::PolicyType::kEnvVersion, "970.1", "e9d960f84f628e1f42d05de4046bb5b3154b6f1f65c08412c6af57a29aecaffb"}, {"rtanalytics-light", ComponentConfig::PolicyType::kEnvVersion, "96.0", "69f09d33c439c2ab55bbbe24b47ab55cb3f6c0bd1f1ef46eefea3216ec925038"},
diff --git a/chrome/browser/component_updater/recovery_improved_component_installer.cc b/chrome/browser/component_updater/recovery_improved_component_installer.cc index 42b026e..a7ba327 100644 --- a/chrome/browser/component_updater/recovery_improved_component_installer.cc +++ b/chrome/browser/component_updater/recovery_improved_component_installer.cc
@@ -110,8 +110,13 @@ void RecoveryComponentActionHandler::WaitForCommand(base::Process process) { int exit_code = 0; const base::TimeDelta kMaxWaitTime = base::Seconds(600); - const bool succeeded = - process.WaitForExitWithTimeout(kMaxWaitTime, &exit_code); + bool succeeded = false; + if (!process.IsValid()) { + exit_code = + static_cast<int>(update_client::InstallError::LAUNCH_PROCESS_FAILED) + } else { + succeeded = process.WaitForExitWithTimeout(kMaxWaitTime, &exit_code); + } base::DeletePathRecursively(unpack_path_); main_task_runner_->PostTask( FROM_HERE, base::BindOnce(std::move(callback_), succeeded, exit_code, 0));
diff --git a/chrome/browser/content_creation/reactions/internal/android/BUILD.gn b/chrome/browser/content_creation/reactions/internal/android/BUILD.gn index aac4017..b4e3a20 100644 --- a/chrome/browser/content_creation/reactions/internal/android/BUILD.gn +++ b/chrome/browser/content_creation/reactions/internal/android/BUILD.gn
@@ -10,12 +10,14 @@ "java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorFactory.java", "java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java", "java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsDialog.java", + "java/src/org/chromium/chrome/browser/content_creation/reactions/ReactionGifDrawable.java", "java/src/org/chromium/chrome/browser/content_creation/reactions/ReactionServiceFactory.java", "java/src/org/chromium/chrome/browser/content_creation/reactions/scene/ReactionLayout.java", "java/src/org/chromium/chrome/browser/content_creation/reactions/scene/SceneCoordinator.java", "java/src/org/chromium/chrome/browser/content_creation/reactions/scene/SceneEditorDelegate.java", "java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarControlsDelegate.java", "java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java", + "java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarReactionsDelegate.java", ] deps = [ @@ -33,6 +35,7 @@ "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_fragment_fragment_java", + "//third_party/gif_player:gif_player_java", "//ui/android:ui_no_recycler_view_java", ]
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java index 010e411..435e65b 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java
@@ -59,7 +59,7 @@ * @param view The root {@link View} of the dialog. */ private void onViewCreated(View view) { - mToolbarCoordinator = new ToolbarCoordinator(view, this); + mToolbarCoordinator = new ToolbarCoordinator(view, this, mSceneCoordinator); } // LightweightReactionsCoordinator implementation.
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/ReactionGifDrawable.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/ReactionGifDrawable.java new file mode 100644 index 0000000..449b05f --- /dev/null +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/ReactionGifDrawable.java
@@ -0,0 +1,20 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.content_creation.reactions; + +import android.graphics.Bitmap; + +import jp.tomorrowkey.android.gifplayer.BaseGifDrawable; +import jp.tomorrowkey.android.gifplayer.BaseGifImage; + +/** + * An extension of the BaseGifDrawable class that allows stepping through the frames of the GIF + * without updating the View, to facilitate decoding the GIF for exporting purposes. + */ +public class ReactionGifDrawable extends BaseGifDrawable { + public ReactionGifDrawable(BaseGifImage gifImage, Bitmap.Config bitmapConfig) { + super(gifImage, bitmapConfig); + } +}
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/ReactionLayout.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/ReactionLayout.java index be386a2..136eefb6 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/ReactionLayout.java +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/ReactionLayout.java
@@ -53,7 +53,7 @@ super.onFinishInflate(); mReaction = findViewById(R.id.reaction_view); setUpCopyButton(); - mDeleteButton = findViewById(R.id.delete_button); + setUpDeleteButton(); mAdjustButton = findViewById(R.id.adjust_button); } @@ -94,4 +94,9 @@ } }); } + + private void setUpDeleteButton() { + mDeleteButton = findViewById(R.id.delete_button); + mDeleteButton.setOnClickListener(view -> mSceneEditorDelegate.removeReaction(this)); + } }
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/SceneCoordinator.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/SceneCoordinator.java index 73a00de..68fc88e 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/SceneCoordinator.java +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/SceneCoordinator.java
@@ -11,6 +11,8 @@ import androidx.appcompat.content.res.AppCompatResources; import org.chromium.chrome.browser.content_creation.reactions.internal.R; +import org.chromium.chrome.browser.content_creation.reactions.toolbar.ToolbarReactionsDelegate; +import org.chromium.components.content_creation.reactions.ReactionMetadata; import org.chromium.ui.LayoutInflaterUtils; import org.chromium.ui.base.ViewUtils; @@ -20,7 +22,7 @@ /** * Manages the scene UI and the reactions on the scene. */ -public class SceneCoordinator implements SceneEditorDelegate { +public class SceneCoordinator implements SceneEditorDelegate, ToolbarReactionsDelegate { private static final int DEFAULT_REACTION_SIZE_DP = 100; private static final int REACTION_OFFSET_DP = 45; private static final int MAX_REACTION_COUNT = 10; @@ -78,7 +80,7 @@ markActiveStatus(reactionLayout, true); } - // SceneEditorCallback implementation. + // SceneEditorDelegate implementation. @Override public boolean canAddReaction() { return mReactionLayouts.size() < MAX_REACTION_COUNT; @@ -104,6 +106,7 @@ @Override public void removeReaction(ReactionLayout reactionLayout) { + markActiveStatus(reactionLayout, false); mSceneBackground.removeView(reactionLayout); mReactionLayouts.remove(reactionLayout); } @@ -121,4 +124,10 @@ mActiveReaction = null; } } + + // ToolbarReactionsDelegate implementation. + @Override + public void onToolbarReactionTapped(ReactionMetadata reactionData) { + // No-op for now, will either add a new reaction or change the currently selected one. + } }
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java index e5ba8b45..4df517f 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java
@@ -13,12 +13,19 @@ * Coordinator for the Lightweight Reactions toolbar. */ public class ToolbarCoordinator { - public ToolbarCoordinator(View parentView, ToolbarControlsDelegate delegate) { + private final ToolbarControlsDelegate mControlsDelegate; + private final ToolbarReactionsDelegate mReactionsDelegate; + + public ToolbarCoordinator(View parentView, ToolbarControlsDelegate controlsDelegate, + ToolbarReactionsDelegate reactionsDelegate) { + mControlsDelegate = controlsDelegate; + mReactionsDelegate = reactionsDelegate; + RelativeLayout toolbarLayout = parentView.findViewById(R.id.lightweight_reactions_toolbar); View closeButton = toolbarLayout.findViewById(R.id.close_button); - closeButton.setOnClickListener(v -> delegate.cancelButtonTapped()); + closeButton.setOnClickListener(v -> mControlsDelegate.cancelButtonTapped()); View doneButton = toolbarLayout.findViewById(R.id.done_button); - doneButton.setOnClickListener(v -> delegate.doneButtonTapped()); + doneButton.setOnClickListener(v -> mControlsDelegate.doneButtonTapped()); } }
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarReactionsDelegate.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarReactionsDelegate.java new file mode 100644 index 0000000..ce9f74e9 --- /dev/null +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarReactionsDelegate.java
@@ -0,0 +1,17 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.content_creation.reactions.toolbar; + +import org.chromium.components.content_creation.reactions.ReactionMetadata; + +/** + * Interface used by the toolbar to delegate action handlers for tapping reactions. + */ +public interface ToolbarReactionsDelegate { + /** + * Invoked when the user taps a reaction. + */ + public void onToolbarReactionTapped(ReactionMetadata reactionData); +} \ No newline at end of file
diff --git a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc index cf94fb6..19541a7 100644 --- a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc +++ b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc
@@ -290,7 +290,8 @@ return RespondNow(Error("cannot find specified tab")); } - content::RenderFrameHost* frame = web_contents->GetMainFrame(); + content::RenderFrameHost* frame = RenderFrameHostForTabAndFrameId( + browser_context(), params->options.tab_id, params->options.frame_id); if (!frame) { return RespondNow(Error("cannot find frame")); }
diff --git a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc index 392b7ed8c..f500bee 100644 --- a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc +++ b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc
@@ -270,6 +270,7 @@ base::Value::DictStorage dict; dict.emplace("appId", app_id); dict.emplace("tabId", tab_id_); + dict.emplace("frameId", -1); // Ignored. dict.emplace("origin", app_id); auto args = std::make_unique<base::Value>(base::Value::Type::LIST); args->Append(base::Value(std::move(dict))); @@ -304,6 +305,7 @@ base::Value::DictStorage dict; dict.emplace("appId", origin); dict.emplace("tabId", tab_id_); + dict.emplace("frameId", 0 /* main frame */); dict.emplace("origin", origin); auto args = std::make_unique<base::Value>(base::Value::Type::LIST); args->Append(base::Value(std::move(dict)));
diff --git a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_browsertest.cc b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_browsertest.cc index 3bcbdb9..eaa2bb5 100644 --- a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_browsertest.cc +++ b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_browsertest.cc
@@ -2,8 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/base_switches.h" +#include "base/strings/strcat.h" #include "base/strings/string_util.h" +#include "base/test/scoped_feature_list.h" #include "base/test/with_feature_override.h" +#include "build/build_config.h" #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -11,10 +15,15 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/embedder_support/switches.h" +#include "components/permissions/permission_request_manager.h" +#include "components/permissions/test/permission_request_observer.h" #include "components/prefs/pref_service.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/url_loader_interceptor.h" +#include "device/fido/features.h" #include "extensions/browser/pref_names.h" #include "extensions/common/extension_features.h" #include "net/dns/mock_host_resolver.h" @@ -30,14 +39,26 @@ namespace { constexpr char kCryptoTokenExtensionId[] = "kmendfapggjehodndflmmgagdbamhnfd"; + +// Origin for running tests with an Origin Trial token. Hostname needs to be +// from `net::EmbeddedTestServer::CERT_TEST_NAMES`. constexpr char kOriginTrialOrigin[] = "https://a.test"; +// Domain to serve files from. This should be different from `kOriginTrialToken` +// domain. Needs to be from `net::EmbeddedTestServer::CERT_TEST_NAMES`. +constexpr char kNonOriginTrialDomain[] = "b.test"; + class CryptotokenBrowserTest : public base::test::WithFeatureOverride, public InProcessBrowserTest { protected: CryptotokenBrowserTest() : base::test::WithFeatureOverride( - extensions_features::kU2FSecurityKeyAPI) {} + extensions_features::kU2FSecurityKeyAPI) { +#if defined(OS_WIN) + // Don't dispatch requests to the native Windows API. + scoped_feature_list_.InitAndDisableFeature(device::kWebAuthUseNativeWinApi); +#endif + } void SetUpCommandLine(base::CommandLine* command_line) override { // The public key for the default privatey key used by the @@ -73,13 +94,24 @@ void TearDownOnMainThread() override { url_loader_interceptor_.reset(); } + // Returns the frame to use when attempting to connect to Cryptotoken in the + // methods below. Uses the main frame by default or + // |frame_to_use_for_connecting_| if a test overrides it. + content::RenderFrameHost* FrameToUseForConnecting() { + return frame_to_use_for_connecting_ ? frame_to_use_for_connecting_ + : browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetMainFrame(); + } + void ExpectChromeRuntimeIsUndefined() { const std::string script = base::StringPrintf( R"(let port = chrome.runtime.connect('%s', {});)", kCryptoTokenExtensionId); - const content::EvalJsResult result = content::EvalJs( - browser()->tab_strip_model()->GetActiveWebContents(), script); + const content::EvalJsResult result = + content::EvalJs(FrameToUseForConnecting(), script); EXPECT_THAT( result.error, testing::StartsWith("a JavaScript error:\nTypeError: Cannot read " @@ -95,8 +127,8 @@ }); }))", kCryptoTokenExtensionId); - const content::EvalJsResult result = content::EvalJs( - browser()->tab_strip_model()->GetActiveWebContents(), script); + const content::EvalJsResult result = + content::EvalJs(FrameToUseForConnecting(), script); EXPECT_EQ(true, result); } @@ -113,14 +145,89 @@ }); }))", kCryptoTokenExtensionId); - const content::EvalJsResult result = content::EvalJs( - browser()->tab_strip_model()->GetActiveWebContents(), script); + const content::EvalJsResult result = + content::EvalJs(FrameToUseForConnecting(), script); EXPECT_EQ("Could not establish connection. Receiving end does not exist.", result); } + // Indicates whether `ExpectSignSuccess()` should expect a U2F deprecation + // prompt to be shown. + enum class PromptExpectation { + kNoPrompt, + kShowPrompt, + }; + + void ExpectSignSuccess(const std::string& app_id, + PromptExpectation prompt_expectation) { + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(FrameToUseForConnecting()); + if (prompt_expectation == PromptExpectation::kShowPrompt) { + // Automatically resolve permission prompts shown by Cryptotoken on the + // target frame. + permissions::PermissionRequestManager* request_manager = + permissions::PermissionRequestManager::FromWebContents(web_contents); + request_manager->set_auto_response_for_test( + permissions::PermissionRequestManager::DENY_ALL); + } + + permissions::PermissionRequestObserver permission_request_observer( + web_contents); + const std::string script = base::StringPrintf( + R"(new Promise((resolve,reject) => { + chrome.runtime.sendMessage('%s', + { + type: 'u2f_sign_request', + appId: '%s', + challenge: 'aGVsbG8gd29ybGQ', + registeredKeys: [ + { + version: 'U2F_V2', + keyHandle: 'aGVsbG8gd29ybGQ', + transports: ['usb'], + appId: '%s', + } + ], + timeoutSeconds: 3, + requestId: 1 + }, + (args) => { + if (chrome.runtime.lastError !== undefined) { + resolve('runtime error: ' + chrome.runtime.lastError); + return; + } + if ('responseData' in args && + 'errorCode' in args.responseData) { + resolve('errorCode:' + + args.responseData.errorCode + + ",errorMessage:" + + args.responseData.errorMessage); + return; + } + reject(); // Requests can never succeed. + }); + }))", + kCryptoTokenExtensionId, app_id.c_str(), app_id.c_str()); + const content::EvalJsResult result = + content::EvalJs(FrameToUseForConnecting(), script); + if (prompt_expectation == PromptExpectation::kShowPrompt) { + // Denied prompt results in a DEVICE_INELIGIBLE error. + EXPECT_EQ("errorCode:4,errorMessage:The operation was not allowed", + result); + EXPECT_EQ(true, permission_request_observer.request_shown()); + } else { + // Without a prompt, the request times out eventually. N.B. the + // `timeoutSeconds` parameter above needs to be high enough to allow time + // for the prompt to show in the kShowPrompt case, but not too high to + // cause test stalls and timeouts + EXPECT_EQ("errorCode:5,errorMessage:undefined", result); + EXPECT_EQ(false, permission_request_observer.request_shown()); + } + } + net::EmbeddedTestServer http_server_{net::EmbeddedTestServer::TYPE_HTTP}; net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS}; + content::RenderFrameHost* frame_to_use_for_connecting_ = nullptr; private: // content::URLLoaderInterceptor callback @@ -145,18 +252,24 @@ "Origin-Trial: %s\n\n", kOriginTrialToken); content::URLLoaderInterceptor::WriteResponse( - headers, "<html><head></head><body>OK</body></html>", + headers, + "<html><head></head><body>OK\n" + "<iframe id=\"otIframe\"></iframe>" + "</body></html>", params->client.get()); return true; } +#if defined(OS_WIN) + base::test::ScopedFeatureList scoped_feature_list_; +#endif std::unique_ptr<content::URLLoaderInterceptor> url_loader_interceptor_; }; IN_PROC_BROWSER_TEST_P(CryptotokenBrowserTest, Connect) { // CryptoToken can only be connected to if the feature flag is enabled. ASSERT_TRUE(ui_test_utils::NavigateToURL( - browser(), https_server_.GetURL("a.test", "/empty.html"))); + browser(), https_server_.GetURL(kNonOriginTrialDomain, "/empty.html"))); if (IsParamFeatureEnabled()) { ExpectConnectSuccess(); } else { @@ -164,6 +277,17 @@ } } +IN_PROC_BROWSER_TEST_P(CryptotokenBrowserTest, SignShowsPrompt) { + if (!IsParamFeatureEnabled()) { + // Can't connect with the API disabled. + return; + } + GURL url = https_server_.GetURL(kNonOriginTrialDomain, "/empty.html"); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + std::string app_id = url::Origin::Create(url).Serialize(); + ExpectSignSuccess(app_id, PromptExpectation::kShowPrompt); +} + IN_PROC_BROWSER_TEST_P(CryptotokenBrowserTest, ConnectWithOriginTrial) { // Connection succeeds regardless of feature flag state with the origin trial. ASSERT_TRUE( @@ -171,20 +295,107 @@ ExpectConnectSuccess(); } +IN_PROC_BROWSER_TEST_P(CryptotokenBrowserTest, + SignWithOriginTrialDoesNotShowPrompt) { + GURL url = GURL(kOriginTrialOrigin); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + std::string app_id = url::Origin::Create(url).Serialize(); + ExpectSignSuccess(app_id, PromptExpectation::kNoPrompt); +} + +IN_PROC_BROWSER_TEST_P(CryptotokenBrowserTest, + ConnectWithOriginTrialInCrossOriginIframe) { + // Cross-origin iframe can connect with a trial token even if the parent frame + // is not enrolled in the trial. + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), https_server_.GetURL(kNonOriginTrialDomain, "/iframe.html"))); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(content::NavigateIframeToURL(web_contents, "test", + GURL(kOriginTrialOrigin))); + frame_to_use_for_connecting_ = content::FrameMatchingPredicate( + web_contents->GetPrimaryPage(), + base::BindRepeating(&content::FrameIsChildOfMainFrame)); + ExpectConnectSuccess(); +} + +IN_PROC_BROWSER_TEST_P( + CryptotokenBrowserTest, + SignWithOriginTrialInCrossOriginIframeDoesNotShowPrompt) { + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), https_server_.GetURL(kNonOriginTrialDomain, "/iframe.html"))); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + GURL url = GURL(kOriginTrialOrigin); + ASSERT_TRUE(content::NavigateIframeToURL(web_contents, "test", url)); + frame_to_use_for_connecting_ = content::FrameMatchingPredicate( + web_contents->GetPrimaryPage(), + base::BindRepeating(&content::FrameIsChildOfMainFrame)); + + // Also make sure no permissions are showing on the main frame either. + permissions::PermissionRequestManager* request_manager = + permissions::PermissionRequestManager::FromWebContents(web_contents); + request_manager->set_auto_response_for_test( + permissions::PermissionRequestManager::DENY_ALL); + permissions::PermissionRequestObserver permission_request_observer( + web_contents); + + std::string app_id = url::Origin::Create(url).Serialize(); + ExpectSignSuccess(app_id, PromptExpectation::kNoPrompt); + EXPECT_FALSE(permission_request_observer.request_shown()); +} + +IN_PROC_BROWSER_TEST_P(CryptotokenBrowserTest, + OriginTrailDoesNotAffectChildIframes) { + GURL parent_url = GURL(kOriginTrialOrigin); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), parent_url)); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + GURL child_url = https_server_.GetURL(kNonOriginTrialDomain, "/empty.html"); + ASSERT_TRUE( + content::NavigateIframeToURL(web_contents, "otIframe", child_url)); + frame_to_use_for_connecting_ = content::FrameMatchingPredicate( + web_contents->GetPrimaryPage(), + base::BindRepeating(&content::FrameIsChildOfMainFrame)); + + if (IsParamFeatureEnabled()) { + // With the feature flag enabled, the U2F API is active; but the OT that + // would suppress the prompt on the main frame, does not suppress the prompt + // on the child frame. + ExpectConnectSuccess(); + std::string app_id = url::Origin::Create(child_url).Serialize(); + ExpectSignSuccess(app_id, PromptExpectation::kShowPrompt); + } else { + // With the feature flag off, the U2F API is inactive on the child frame, + // even though it is enabled via OT on the parent frame. + ExpectConnectFailure(); + } +} + IN_PROC_BROWSER_TEST_P(CryptotokenBrowserTest, ConnectWithEnterprisePolicy) { // Connection succeeds regardless of feature flag state with the enterprise // policy overriding deprecation changes. browser()->profile()->GetPrefs()->Set( extensions::pref_names::kU2fSecurityKeyApiEnabled, base::Value(true)); - ASSERT_TRUE( - ui_test_utils::NavigateToURL(browser(), GURL(kOriginTrialOrigin))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), https_server_.GetURL(kNonOriginTrialDomain, "/empty.html"))); ExpectConnectSuccess(); } +IN_PROC_BROWSER_TEST_P(CryptotokenBrowserTest, + SignWithEnterprisePolicyDoesNotShowPrompt) { + browser()->profile()->GetPrefs()->Set( + extensions::pref_names::kU2fSecurityKeyApiEnabled, base::Value(true)); + GURL url = GURL(https_server_.GetURL(kNonOriginTrialDomain, "/empty.html")); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + std::string app_id = url::Origin::Create(url).Serialize(); + ExpectSignSuccess(app_id, PromptExpectation::kNoPrompt); +} + IN_PROC_BROWSER_TEST_P(CryptotokenBrowserTest, InsecureOriginCannotConnect) { // Connections from insecure origins always fail. ASSERT_TRUE(ui_test_utils::NavigateToURL( - browser(), http_server_.GetURL("a.test", "/empty.html"))); + browser(), http_server_.GetURL(kNonOriginTrialDomain, "/empty.html"))); ExpectChromeRuntimeIsUndefined(); }
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc index 42392bc4..45cf0bc 100644 --- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
@@ -2249,10 +2249,7 @@ disable_reason::DISABLE_BLOCKED_BY_POLICY, true); disable_extension_and_check_allocation( - disable_reason::DISABLE_REMOTELY_FOR_MALWARE, true); - - disable_extension_and_check_allocation( - disable_reason::DISABLE_REMOTELY_FOR_MALWARE | + disable_reason::DISABLE_BLOCKED_BY_POLICY | disable_reason::DISABLE_USER_ACTION, true);
diff --git a/chrome/browser/extensions/api/messaging/native_message_port.cc b/chrome/browser/extensions/api/messaging/native_message_port.cc index 2d3bd51..0ddc42a 100644 --- a/chrome/browser/extensions/api/messaging/native_message_port.cc +++ b/chrome/browser/extensions/api/messaging/native_message_port.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/extensions/api/messaging/native_message_process_host.h" #include "content/public/browser/browser_thread.h" #include "extensions/common/api/messaging/message.h" +#include "extensions/common/api/messaging/serialization_format.h" namespace extensions { @@ -115,8 +116,11 @@ void NativeMessagePort::PostMessageFromNativeHost(const std::string& message) { DCHECK(thread_checker_.CalledOnValidThread()); if (weak_channel_delegate_) { + // Native messaging always uses JSON since a native host doesn't understand + // structured cloning serialization. weak_channel_delegate_->PostMessage( - port_id_, Message(message, false /* user_gesture */)); + port_id_, + Message(message, SerializationFormat::kJson, false /* user_gesture */)); } }
diff --git a/chrome/browser/extensions/api/messaging/native_messaging_launch_from_native.cc b/chrome/browser/extensions/api/messaging/native_messaging_launch_from_native.cc index 1c0249b..498466b3 100644 --- a/chrome/browser/extensions/api/messaging/native_messaging_launch_from_native.cc +++ b/chrome/browser/extensions/api/messaging/native_messaging_launch_from_native.cc
@@ -29,6 +29,7 @@ #include "extensions/browser/event_router.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/api/messaging/messaging_endpoint.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/permissions/permission_set.h" #include "extensions/common/permissions/permissions_data.h" @@ -228,7 +229,8 @@ return; } const extensions::PortId port_id(base::UnguessableToken::Create(), - 1 /* port_number */, true /* is_opener */); + 1 /* port_number */, true /* is_opener */, + extensions::SerializationFormat::kJson); extensions::MessageService* const message_service = extensions::MessageService::Get(profile); // TODO(crbug.com/967262): Apply policy for allow_user_level.
diff --git a/chrome/browser/extensions/extension_allowlist_unittest.cc b/chrome/browser/extensions/extension_allowlist_unittest.cc index e262f4d5..600334c 100644 --- a/chrome/browser/extensions/extension_allowlist_unittest.cc +++ b/chrome/browser/extensions/extension_allowlist_unittest.cc
@@ -149,8 +149,10 @@ EXPECT_EQ(BitMapBlocklistState::BLOCKLISTED_MALWARE, blocklist_prefs::GetSafeBrowsingExtensionBlocklistState( kExtensionId1, extension_prefs())); - EXPECT_EQ(disable_reason::DISABLE_REMOTELY_FOR_MALWARE | - disable_reason::DISABLE_NOT_ALLOWLISTED, + EXPECT_TRUE(blocklist_prefs::HasOmahaBlocklistState( + kExtensionId1, BitMapBlocklistState::BLOCKLISTED_MALWARE, + extension_prefs())); + EXPECT_EQ(disable_reason::DISABLE_NOT_ALLOWLISTED, extension_prefs()->GetDisableReasons(kExtensionId1)); EXPECT_TRUE(IsBlocklisted(kExtensionId1)); @@ -164,7 +166,10 @@ EXPECT_EQ(BitMapBlocklistState::BLOCKLISTED_MALWARE, blocklist_prefs::GetSafeBrowsingExtensionBlocklistState( kExtensionId1, extension_prefs())); - EXPECT_EQ(disable_reason::DISABLE_REMOTELY_FOR_MALWARE, + EXPECT_TRUE(blocklist_prefs::HasOmahaBlocklistState( + kExtensionId1, BitMapBlocklistState::BLOCKLISTED_MALWARE, + extension_prefs())); + EXPECT_EQ(disable_reason::DISABLE_NONE, extension_prefs()->GetDisableReasons(kExtensionId1)); EXPECT_TRUE(IsBlocklisted(kExtensionId1));
diff --git a/chrome/browser/extensions/extension_error_ui_default_unittest.cc b/chrome/browser/extensions/extension_error_ui_default_unittest.cc index b1704103..43a7834 100644 --- a/chrome/browser/extensions/extension_error_ui_default_unittest.cc +++ b/chrome/browser/extensions/extension_error_ui_default_unittest.cc
@@ -9,6 +9,7 @@ #include "chrome/grit/generated_resources.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/browser_task_environment.h" +#include "extensions/browser/blocklist_extension_prefs.h" #include "extensions/browser/disable_reason.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_system.h" @@ -117,10 +118,9 @@ extensions::ExtensionBuilder( "Bar", extensions::ExtensionBuilder::Type::PLATFORM_APP) .Build(); - extensions::ExtensionPrefs::Get(delegate.GetContext()) - ->AddDisableReason( - extension->id(), - extensions::disable_reason::DISABLE_REMOTELY_FOR_MALWARE); + extensions::blocklist_prefs::AddOmahaBlocklistState( + extension->id(), extensions::BitMapBlocklistState::BLOCKLISTED_MALWARE, + extensions::ExtensionPrefs::Get(delegate.GetContext())); delegate.InsertForbidden(extension); extensions::ExtensionErrorUIDefault ui(&delegate);
diff --git a/chrome/browser/extensions/extension_prefs_unittest.cc b/chrome/browser/extensions/extension_prefs_unittest.cc index 9874822a..97ae419 100644 --- a/chrome/browser/extensions/extension_prefs_unittest.cc +++ b/chrome/browser/extensions/extension_prefs_unittest.cc
@@ -28,6 +28,8 @@ #include "content/public/browser/notification_source.h" #include "content/public/test/mock_notification_observer.h" #include "extensions/browser/blocklist_extension_prefs.h" +#include "extensions/browser/blocklist_state.h" +#include "extensions/browser/disable_reason.h" #include "extensions/browser/extension_pref_value_map.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/install_flag.h" @@ -1125,6 +1127,13 @@ // The pref is not migrated to the new pref yet. EXPECT_FALSE(prefs()->IsBlocklistedExtensionAcknowledged(extension_->id())); + prefs()->SetExtensionDisabled( + extension_->id(), + disable_reason::DEPRECATED_DISABLE_REMOTELY_FOR_MALWARE); + // The pref is not migrated to the new pref yet. + EXPECT_FALSE(blocklist_prefs::HasOmahaBlocklistState( + extension_->id(), BitMapBlocklistState::BLOCKLISTED_MALWARE, prefs())); + prefs()->MigrateOldBlocklistPrefs(); } @@ -1144,6 +1153,13 @@ // The old pref should be cleared. EXPECT_FALSE(is_blocklist_acknowledged_pref); EXPECT_TRUE(prefs()->IsBlocklistedExtensionAcknowledged(extension_->id())); + + EXPECT_TRUE(blocklist_prefs::HasOmahaBlocklistState( + extension_->id(), BitMapBlocklistState::BLOCKLISTED_MALWARE, prefs())); + // The old pref should be cleared. + EXPECT_FALSE(prefs()->HasDisableReason( + extension_->id(), + disable_reason::DEPRECATED_DISABLE_REMOTELY_FOR_MALWARE)); } private:
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index a2ea327..04d17c22 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -875,8 +875,9 @@ return; } - if (extension_prefs_->HasDisableReason( - extension_id, disable_reason::DISABLE_REMOTELY_FOR_MALWARE)) { + if (blocklist_prefs::HasOmahaBlocklistState( + extension_id, BitMapBlocklistState::BLOCKLISTED_MALWARE, + extension_prefs_)) { // The extension is already disabled. No work needs to be done. return; } @@ -888,8 +889,9 @@ // Add the extension to the blocklisted extensions set. UpdateBlocklistedExtensions({extension_id}, registry_->blocklisted_extensions().GetIDs()); - extension_prefs_->AddDisableReason( - extension_id, disable_reason::DISABLE_REMOTELY_FOR_MALWARE); + blocklist_prefs::AddOmahaBlocklistState( + extension_id, BitMapBlocklistState::BLOCKLISTED_MALWARE, + extension_prefs_); // Show an error for the newly blocklisted extension. error_controller_->ShowErrorIfNeeded(); } @@ -897,12 +899,15 @@ void ExtensionService::MaybeEnableRemotelyDisabledExtension( const std::string& extension_id) { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - int disable_reasons = extension_prefs_->GetDisableReasons(extension_id); - if ((disable_reasons & disable_reason::DISABLE_REMOTELY_FOR_MALWARE) == 0) + if (!blocklist_prefs::HasOmahaBlocklistState( + extension_id, BitMapBlocklistState::BLOCKLISTED_MALWARE, + extension_prefs_)) { return; + } - extension_prefs_->RemoveDisableReason( - extension_id, disable_reason::DISABLE_REMOTELY_FOR_MALWARE); + blocklist_prefs::RemoveOmahaBlocklistState( + extension_id, BitMapBlocklistState::BLOCKLISTED_MALWARE, + extension_prefs_); ExtensionIdSet unchanged = registry_->blocklisted_extensions().GetIDs(); DCHECK(base::Contains(unchanged, extension_id)); @@ -2217,8 +2222,9 @@ // to |unchanged| set. for (const auto& extension_id : registry_->blocklisted_extensions().GetIDs()) { - if (extension_prefs_->HasDisableReason( - extension_id, disable_reason::DISABLE_REMOTELY_FOR_MALWARE)) { + if (blocklist_prefs::HasOmahaBlocklistState( + extension_id, BitMapBlocklistState::BLOCKLISTED_MALWARE, + extension_prefs_)) { unchanged.insert(extension_id); } }
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 5cbc294b..42160dc 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -3525,8 +3525,8 @@ ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); service()->PerformActionBasedOnOmahaAttributes(good0, attributes); - EXPECT_EQ(disable_reason::DISABLE_REMOTELY_FOR_MALWARE, - prefs->GetDisableReasons(good0)); + EXPECT_TRUE(blocklist_prefs::HasOmahaBlocklistState( + good0, BitMapBlocklistState::BLOCKLISTED_MALWARE, prefs)); EXPECT_TRUE(DoesIntegerPrefExist(good0, kPrefBlocklistState)); EXPECT_FALSE(registry()->enabled_extensions().Contains(good0)); EXPECT_TRUE(registry()->blocklisted_extensions().Contains(good0)); @@ -3535,9 +3535,9 @@ test_blocklist.Clear(false); task_environment()->RunUntilIdle(); - // If the extension has a DISABLE_REMOTELY_FOR_MALWARE disable reason, - // the extension should still not be enabled even if it's no on the - // SB blocklist. This disable reason needs to be removed prior to + // If the extension has a BLOCKLISTED_MALWARE state in the Omaha blocklist + // pref, the extension should still not be enabled even if it's not on the SB + // blocklist. This state needs to be removed prior to // unblocklisting/re-enabling. EXPECT_FALSE(registry()->enabled_extensions().Contains(good0)); EXPECT_TRUE(registry()->blocklisted_extensions().Contains(good0)); @@ -4738,8 +4738,8 @@ ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); service()->PerformActionBasedOnOmahaAttributes(good_crx, attributes); - EXPECT_EQ(disable_reason::DISABLE_REMOTELY_FOR_MALWARE, - prefs->GetDisableReasons(good_crx)); + EXPECT_TRUE(blocklist_prefs::HasOmahaBlocklistState( + good_crx, BitMapBlocklistState::BLOCKLISTED_MALWARE, prefs)); EXPECT_TRUE(blocklist_prefs::IsExtensionBlocklisted(good_crx, prefs)); attributes.SetKey("_malware", base::Value(false)); @@ -4757,19 +4757,19 @@ InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx)); + base::Value attributes(base::Value::Type::DICTIONARY); + attributes.SetKey("_malware", base::Value(true)); ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); - service()->DisableExtension(good_crx, - disable_reason::DISABLE_REMOTELY_FOR_MALWARE | - disable_reason::DISABLE_USER_ACTION); + service()->DisableExtension(good_crx, disable_reason::DISABLE_USER_ACTION); EXPECT_TRUE(registry()->disabled_extensions().GetByID(good_crx)); - service()->BlocklistExtensionForTest(good_crx); + service()->PerformActionBasedOnOmahaAttributes(good_crx, attributes); EXPECT_TRUE(blocklist_prefs::IsExtensionBlocklisted(good_crx, prefs)); - base::Value empty_attr(base::Value::Type::DICTIONARY); - service()->PerformActionBasedOnOmahaAttributes(good_crx, empty_attr); + attributes.SetKey("_malware", base::Value(false)); + service()->PerformActionBasedOnOmahaAttributes(good_crx, attributes); EXPECT_TRUE(registry()->disabled_extensions().GetByID(good_crx)); - EXPECT_FALSE(prefs->GetDisableReasons(good_crx) & - disable_reason::DISABLE_REMOTELY_FOR_MALWARE); + EXPECT_FALSE(blocklist_prefs::HasOmahaBlocklistState( + good_crx, BitMapBlocklistState::BLOCKLISTED_MALWARE, prefs)); EXPECT_FALSE(blocklist_prefs::IsExtensionBlocklisted(good_crx, prefs)); } @@ -4787,11 +4787,6 @@ EXPECT_TRUE(blocklist_prefs::IsExtensionBlocklisted(good0, prefs)); EXPECT_TRUE(blocklist_prefs::IsExtensionBlocklisted(good1, prefs)); - // Test that a disable reason can be added to a blocklisted extension. - prefs->AddDisableReason(good0, disable_reason::DISABLE_REMOTELY_FOR_MALWARE); - EXPECT_TRUE(prefs->HasDisableReason( - good0, disable_reason::DISABLE_REMOTELY_FOR_MALWARE)); - // Test that a blocklisted extension can be disabled. service()->DisableExtension(good1, disable_reason::DISABLE_BLOCKED_BY_POLICY); EXPECT_TRUE(prefs->HasDisableReason(
diff --git a/chrome/browser/extensions/omaha_attributes_handler_unittest.cc b/chrome/browser/extensions/omaha_attributes_handler_unittest.cc index 06e4c227..c30adcd 100644 --- a/chrome/browser/extensions/omaha_attributes_handler_unittest.cc +++ b/chrome/browser/extensions/omaha_attributes_handler_unittest.cc
@@ -210,8 +210,9 @@ ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId)); - EXPECT_EQ(disable_reason::DISABLE_REMOTELY_FOR_MALWARE | - disable_reason::DISABLE_GREYLIST, + EXPECT_TRUE(blocklist_prefs::HasOmahaBlocklistState( + kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_MALWARE, prefs)); + EXPECT_EQ(disable_reason::DISABLE_GREYLIST, prefs->GetDisableReasons(kTestExtensionId)); // Remove malware.
diff --git a/chrome/browser/extensions/preinstalled_apps_browsertest.cc b/chrome/browser/extensions/preinstalled_apps_browsertest.cc index 313f0791..d3df4bb 100644 --- a/chrome/browser/extensions/preinstalled_apps_browsertest.cc +++ b/chrome/browser/extensions/preinstalled_apps_browsertest.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/web_applications/preinstalled_web_app_utils.h" #include "chrome/browser/web_applications/test/fake_os_integration_manager.h" #include "chrome/browser/web_applications/test/fake_web_app_provider.h" +#include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_helpers.h" @@ -185,6 +186,8 @@ // We override this to also wait for the PreinstalledWebAppManager. void WaitForSystemReady() override { PreinstalledAppsBrowserTest::WaitForSystemReady(); + web_app::test::WaitUntilReady( + web_app::WebAppProvider::GetForTest(browser()->profile())); // For web app migration tests, we want to set up extension app shortcut // locations to test that they are preserved.
diff --git a/chrome/browser/extensions/updater/extension_updater.cc b/chrome/browser/extensions/updater/extension_updater.cc index 55514b8..01737b3c 100644 --- a/chrome/browser/extensions/updater/extension_updater.cc +++ b/chrome/browser/extensions/updater/extension_updater.cc
@@ -37,6 +37,7 @@ #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" #include "crypto/sha2.h" +#include "extensions/browser/blocklist_extension_prefs.h" #include "extensions/browser/extension_file_task_runner.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" @@ -448,9 +449,11 @@ params.fetch_priority, &update_check_params); ExtensionSet remotely_disabled_extensions; for (auto extension : registry_->blocklisted_extensions()) { - if (extension_prefs_->HasDisableReason( - extension->id(), disable_reason::DISABLE_REMOTELY_FOR_MALWARE)) + if (blocklist_prefs::HasOmahaBlocklistState( + extension->id(), BitMapBlocklistState::BLOCKLISTED_MALWARE, + extension_prefs_)) { remotely_disabled_extensions.Insert(extension); + } } AddToDownloader(&remotely_disabled_extensions, pending_ids, request_id, params.fetch_priority, &update_check_params);
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc index 96755be..fe91ec3 100644 --- a/chrome/browser/extensions/updater/extension_updater_unittest.cc +++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -2682,8 +2682,9 @@ blocklist_prefs::SetSafeBrowsingExtensionBlocklistState( remotely_blocklisted_id, BitMapBlocklistState::BLOCKLISTED_MALWARE, service.extension_prefs()); - service.extension_prefs()->AddDisableReason( - remotely_blocklisted_id, disable_reason::DISABLE_REMOTELY_FOR_MALWARE); + blocklist_prefs::AddOmahaBlocklistState( + remotely_blocklisted_id, BitMapBlocklistState::BLOCKLISTED_MALWARE, + service.extension_prefs()); // We expect that both enabled and remotely blocklisted extensions are // auto-updated.
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 6a17bf2..aa66710 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -199,7 +199,6 @@ &kChromeSurveyNextAndroid, &kCommandLineOnNonRooted, &kConditionalTabStripAndroid, - &kContentSuggestionsScrollToLoad, &kContextMenuEnableLensShoppingAllowlist, &kContextMenuGoogleLensChip, &kContextMenuSearchWithGoogleLens, @@ -501,9 +500,6 @@ const base::Feature kCommandLineOnNonRooted{"CommandLineOnNonRooted", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kContentSuggestionsScrollToLoad{ - "ContentSuggestionsScrollToLoad", base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kContextMenuEnableLensShoppingAllowlist{ "ContextMenuEnableLensShoppingAllowlist", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 96fafc2..9b30c2d 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -61,7 +61,6 @@ extern const base::Feature kContextMenuShopWithGoogleLens; extern const base::Feature kContextMenuSearchAndShopWithGoogleLens; extern const base::Feature kContextMenuTranslateWithGoogleLens; -extern const base::Feature kContentSuggestionsScrollToLoad; extern const base::Feature kContextualSearchDebug; extern const base::Feature kContextualSearchForceCaption; extern const base::Feature kContextualSearchLegacyHttpPolicy;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index c44ba310..2bd063b7 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -276,8 +276,6 @@ public static final String COMMERCE_PRICE_TRACKING = "CommercePriceTracking"; public static final String CONDITIONAL_TAB_STRIP_ANDROID = "ConditionalTabStripAndroid"; public static final String CONTACTS_PICKER_SELECT_ALL = "ContactsPickerSelectAll"; - public static final String CONTENT_SUGGESTIONS_SCROLL_TO_LOAD = - "ContentSuggestionsScrollToLoad"; public static final String CONTEXT_MENU_ENABLE_LENS_SHOPPING_ALLOWLIST = "ContextMenuEnableLensShoppingAllowlist"; public static final String CONTEXT_MENU_GOOGLE_LENS_CHIP = "ContextMenuGoogleLensChip";
diff --git a/chrome/browser/lacros/lacros_prefs.cc b/chrome/browser/lacros/lacros_prefs.cc index e3b7e9f8..61ca315 100644 --- a/chrome/browser/lacros/lacros_prefs.cc +++ b/chrome/browser/lacros/lacros_prefs.cc
@@ -23,6 +23,11 @@ // browser settings. It could reasonably move to a browser-specific // location with suitable #ifdefs. registry->RegisterBooleanPref(::prefs::kSettingsShowOSBanner, true); + + // The following two prefs are used in imageWriterPrivate extension api + // implementation code, which are supported in Lacros. + registry->RegisterBooleanPref(::prefs::kExternalStorageDisabled, false); + registry->RegisterBooleanPref(::prefs::kExternalStorageReadOnly, false); } } // namespace lacros_prefs
diff --git a/chrome/browser/media/router/discovery/dial/dial_service_unittest.cc b/chrome/browser/media/router/discovery/dial/dial_service_unittest.cc index e889484..33af47ba 100644 --- a/chrome/browser/media/router/discovery/dial/dial_service_unittest.cc +++ b/chrome/browser/media/router/discovery/dial/dial_service_unittest.cc
@@ -17,7 +17,6 @@ #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" #include "net/base/network_interfaces.h" -#include "net/log/test_net_log.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -55,14 +54,13 @@ DialServiceTest() : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP), mock_ip_(net::IPAddress::IPv4AllZeros()), - dial_service_(&test_net_log_) { + dial_service_(net::NetLog::Get()) { dial_service_.AddObserver(&mock_observer_); dial_socket_ = dial_service_.CreateDialSocket(); } protected: content::BrowserTaskEnvironment task_environment_; - net::RecordingTestNetLog test_net_log_; net::IPAddress mock_ip_; DialServiceImpl dial_service_; std::unique_ptr<DialServiceImpl::DialSocket> dial_socket_;
diff --git a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc index 9588b01..8839177 100644 --- a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
@@ -5,6 +5,7 @@ #include <string> #include "base/path_service.h" +#include "base/strings/strcat.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" @@ -40,6 +41,8 @@ static const char kMainHtmlFileName[] = "webrtc_getdisplaymedia_test.html"; static const char kSameOriginRenamedTitle[] = "Renamed Same Origin Tab"; +enum class DisplaySurfaceType { kTab, kWindow, kScreen }; + enum class GetDisplayMediaVariant : int { kStandard = 0, kPreferCurrentTab = 1 @@ -61,6 +64,20 @@ constexpr char kAppWindowTitle[] = "AppWindow Display Capture Test"; +std::string DisplaySurfaceTypeAsString( + DisplaySurfaceType display_surface_type) { + switch (display_surface_type) { + case DisplaySurfaceType::kTab: + return "browser"; + case DisplaySurfaceType::kWindow: + return "window"; + case DisplaySurfaceType::kScreen: + return "screen"; + } + NOTREACHED(); + return "error"; +} + void RunGetDisplayMedia(content::WebContents* tab, const std::string& constraints, bool is_fake_ui, @@ -594,3 +611,169 @@ &result)); EXPECT_EQ(result, "live"); } + +class GetDisplayMediaVideoTrackBrowserTest + : public WebRtcTestBase, + public testing::WithParamInterface< + std::tuple<bool, bool, DisplaySurfaceType>> { + public: + GetDisplayMediaVideoTrackBrowserTest() + : conditional_focus_enabled_(std::get<0>(GetParam())), + region_capture_enabled_(std::get<1>(GetParam())), + display_surface_type_(std::get<2>(GetParam())) {} + + ~GetDisplayMediaVideoTrackBrowserTest() override = default; + + void SetUpInProcessBrowserTestFixture() override { + DetectErrorsInJavaScript(); + } + + void SetUpOnMainThread() override { + WebRtcTestBase::SetUpOnMainThread(); + + ASSERT_TRUE(embedded_test_server()->Start()); + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // The picker itself shows previews which are unsupported in Lacros tests. + base::Value matchlist(base::Value::Type::LIST); + matchlist.Append("*"); + browser()->profile()->GetPrefs()->Set(prefs::kTabCaptureAllowedByOrigins, + matchlist); +#endif + } + + // Unlike SetUp(), this is called from the test body. This allows skipping + // this test for (platform, test-case) combinations which are not supported. + void SetupTest() { + // Fire up the page. + tab_ = OpenTestPageInNewTab(kMainHtmlPage); + + // Initiate the capture. + std::string result; + ASSERT_TRUE(content::ExecuteScriptAndExtractString( + tab_->GetMainFrame(), + "runGetDisplayMedia({video: true, audio: true}, " + "\"top-level-document\");", + &result)); + ASSERT_EQ(result, "capture-success"); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + WebRtcTestBase::SetUpCommandLine(command_line); + + std::vector<std::string> enabled_blink_features; + if (conditional_focus_enabled_) { + enabled_blink_features.push_back("ConditionalFocus"); + } + if (region_capture_enabled_) { + enabled_blink_features.push_back("RegionCapture"); + } + if (!enabled_blink_features.empty()) { + command_line->AppendSwitchASCII( + switches::kEnableBlinkFeatures, + base::JoinString(enabled_blink_features, ",")); + } + + command_line->AppendSwitch(switches::kUseFakeUIForMediaStream); + command_line->AppendSwitchASCII( + switches::kUseFakeDeviceForMediaStream, + base::StrCat({"display-media-type=", + DisplaySurfaceTypeAsString(display_surface_type_)})); + } + + std::string GetVideoTrackType() { + std::string result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + tab_->GetMainFrame(), "getVideoTrackType();", &result)); + return result; + } + + std::string GetVideoCloneTrackType() { + std::string result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + tab_->GetMainFrame(), "getVideoCloneTrackType();", &result)); + return result; + } + + bool HasAudioTrack() { + std::string result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + tab_->GetMainFrame(), "hasAudioTrack();", &result)); + EXPECT_TRUE(result == "true" || result == "false"); + return result == "true"; + } + + std::string GetAudioTrackType() { + std::string result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + tab_->GetMainFrame(), "getAudioTrackType();", &result)); + return result; + } + + std::string ExpectedVideoTrackType() const { + switch (display_surface_type_) { + case DisplaySurfaceType::kTab: + return region_capture_enabled_ + ? "BrowserCaptureMediaStreamTrack" + : conditional_focus_enabled_ ? "FocusableMediaStreamTrack" + : "MediaStreamTrack"; + case DisplaySurfaceType::kWindow: + return conditional_focus_enabled_ || region_capture_enabled_ + ? "FocusableMediaStreamTrack" + : "MediaStreamTrack"; + case DisplaySurfaceType::kScreen: + return "MediaStreamTrack"; + } + NOTREACHED(); + return "Error"; + } + + protected: + const bool conditional_focus_enabled_; + const bool region_capture_enabled_; + const DisplaySurfaceType display_surface_type_; + + private: + content::WebContents* tab_ = nullptr; +}; + +INSTANTIATE_TEST_SUITE_P( + _, + GetDisplayMediaVideoTrackBrowserTest, + testing::Combine(/*conditional_focus_enabled=*/testing::Bool(), + /*region_capture_enabled=*/testing::Bool(), + /*display_surface_type=*/ + testing::Values(DisplaySurfaceType::kTab, + DisplaySurfaceType::kWindow, + DisplaySurfaceType::kScreen)), + [](const testing::TestParamInfo< + GetDisplayMediaVideoTrackBrowserTest::ParamType>& info) { + return base::StrCat( + {std::get<0>(info.param) ? "ConditionalFocus" : "", + std::get<1>(info.param) ? "RegionCapture" : "", + std::get<2>(info.param) == DisplaySurfaceType::kTab + ? "Tab" + : std::get<2>(info.param) == DisplaySurfaceType::kWindow + ? "Window" + : "Screen"}); + }); + +// Normally, each of these these would have its own test, but the number of +// combinations and the setup time for browser-tests make this undesirable, +// especially given the simplicity of each of these tests. +// After both (a) Conditional Focus and (b) Region Capture ship, this can +// simpplified to three non-parameterized tests (tab/window/screen). +IN_PROC_BROWSER_TEST_P(GetDisplayMediaVideoTrackBrowserTest, RunCombinedTest) { + SetupTest(); + + // Test #1: The video track is of the expected type. + EXPECT_EQ(GetVideoTrackType(), ExpectedVideoTrackType()); + + // Test #2: Video clones are of the same type as the original. + EXPECT_EQ(GetVideoTrackType(), GetVideoCloneTrackType()); + + // Test #3: Audio tracks are all simply MediaStreamTrack. + if (HasAudioTrack()) { + EXPECT_EQ(GetAudioTrackType(), "MediaStreamTrack"); + } +}
diff --git a/chrome/browser/metrics/extensions_metrics_provider.cc b/chrome/browser/metrics/extensions_metrics_provider.cc index 8e0fcaf..e3367268 100644 --- a/chrome/browser/metrics/extensions_metrics_provider.cc +++ b/chrome/browser/metrics/extensions_metrics_provider.cc
@@ -254,8 +254,6 @@ ExtensionInstallProto::CUSTODIAN_APPROVAL_REQUIRED}, {extensions::disable_reason::DISABLE_BLOCKED_BY_POLICY, ExtensionInstallProto::BLOCKED_BY_POLICY}, - {extensions::disable_reason::DISABLE_REMOTELY_FOR_MALWARE, - ExtensionInstallProto::DISABLE_REMOTELY_FOR_MALWARE}, {extensions::disable_reason::DISABLE_REINSTALL, ExtensionInstallProto::REINSTALL}, {extensions::disable_reason::DISABLE_NOT_ALLOWLISTED,
diff --git a/chrome/browser/metrics/extensions_metrics_provider_unittest.cc b/chrome/browser/metrics/extensions_metrics_provider_unittest.cc index 3da5a04..e8a2989 100644 --- a/chrome/browser/metrics/extensions_metrics_provider_unittest.cc +++ b/chrome/browser/metrics/extensions_metrics_provider_unittest.cc
@@ -319,17 +319,6 @@ EXPECT_EQ(ExtensionInstallProto::CORRUPTED, install.disable_reasons().Get(1)); } - // Adding additional disable reasons should result in all reasons being - // reported. - prefs()->AddDisableReason( - extension->id(), - extensions::disable_reason::DISABLE_REMOTELY_FOR_MALWARE); - { - ExtensionInstallProto install = ConstructProto(*extension); - ASSERT_EQ(3, install.disable_reasons_size()); - EXPECT_EQ(ExtensionInstallProto::DISABLE_REMOTELY_FOR_MALWARE, - install.disable_reasons().Get(2)); - } } {
diff --git a/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.cc b/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.cc index aec30c4..f893e4e9 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.cc
@@ -403,7 +403,7 @@ // ReplaceFile failed, log the error code and attempt to utilize base::Move // instead as the file could be on a different storage partition. - UMA_HISTOGRAM_ENUMERATION( + base::UmaHistogramExactLinear( "OptimizationGuide.PredictionModelDownloadManager.ReplaceFileError." + GetStringNameForOptimizationTarget( model_info.optimization_target()),
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java index 844735c..581f62d 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -862,9 +862,11 @@ public static final String SIGNIN_ACCOUNT_RENAME_EVENT_INDEX = "prefs_sync_account_rename_event_index"; - /** SigninPromo Show Count preference. */ - public static final KeyPrefix SIGNIN_PROMO_SHOW_COUNT = - new KeyPrefix("Chrome.SigninPromo.ShowCount.*"); + /** SyncPromo Show Count preference. */ + public static final KeyPrefix SYNC_PROMO_SHOW_COUNT = + new KeyPrefix("Chrome.SyncPromo.ShowCount.*"); + /** SyncPromo total shown count preference across all access points. */ + public static final String SYNC_PROMO_TOTAL_SHOW_COUNT = "Chrome.SyncPromo.TotalShowCount"; /** * Generic signin and sync promo preferences. @@ -1127,9 +1129,10 @@ SHARING_LAST_SHARED_COMPONENT_NAME, SHOW_START_SEGMENTATION_RESULT, SIGNIN_PROMO_IMPRESSIONS_COUNT_NTP, - SIGNIN_PROMO_SHOW_COUNT.pattern(), + SYNC_PROMO_SHOW_COUNT.pattern(), SIGNIN_PROMO_NTP_FIRST_SHOWN_TIME, SIGNIN_PROMO_NTP_LAST_SHOWN_TIME, + SYNC_PROMO_TOTAL_SHOW_COUNT, START_NEXT_SHOW_ON_STARTUP_DECISION_MS, START_SHOW_ON_STARTUP, TAP_FEED_CARDS_COUNT,
diff --git a/chrome/browser/resources/cryptotoken/enroller.js b/chrome/browser/resources/cryptotoken/enroller.js index 2cd41ac0..ed75e75 100644 --- a/chrome/browser/resources/cryptotoken/enroller.js +++ b/chrome/browser/resources/cryptotoken/enroller.js
@@ -417,6 +417,7 @@ { 'appId': appId, 'tabId': messageSender.tab.id, + 'frameId': 0, // ignored 'origin': sender.origin, }, resolve); @@ -897,7 +898,12 @@ Enroller.prototype.checkU2fApiPermission_ = function( appId, challenge, request, attestationMode) { chrome.cryptotokenPrivate.canMakeU2fApiRequest( - {tabId: this.sender_.tabId, origin: this.sender_.origin, appId: appId}, + { + tabId: this.sender_.tabId, + frameId: this.sender_.frameId, + origin: this.sender_.origin, + appId: appId + }, (result) => { if (!result) { this.notifyError_({
diff --git a/chrome/browser/resources/cryptotoken/signer.js b/chrome/browser/resources/cryptotoken/signer.js index 692a8aac..5921de98c 100644 --- a/chrome/browser/resources/cryptotoken/signer.js +++ b/chrome/browser/resources/cryptotoken/signer.js
@@ -510,7 +510,12 @@ this.doSignWebAuthnContinue_(decodedChallenge, credentialList, appid); } else { chrome.cryptotokenPrivate.canMakeU2fApiRequest( - {tabId: this.sender_.tabId, origin: this.sender_.origin, appId: appid}, + { + tabId: this.sender_.tabId, + frameId: this.sender_.frameId, + origin: this.sender_.origin, + appId: appid + }, (result) => { if (!result) { this.notifyError_({
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notification_row.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notification_row.html index c5d9f2e..4be458a6 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notification_row.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notification_row.html
@@ -16,7 +16,7 @@ } #appToggle { - padding: 0 20px 0 0; + margin-inline-end: 20px; } #appIcon {
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc index 5e67260..89880c8 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -57,6 +57,7 @@ #include "components/safe_browsing/content/browser/ui_manager.h" #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h" #include "components/safe_browsing/core/browser/db/database_manager.h" +#include "components/safe_browsing/core/browser/realtime/policy_engine.h" #include "components/safe_browsing/core/browser/safe_browsing_metrics_collector.h" #include "components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher.h" #include "components/safe_browsing/core/browser/verdict_cache_manager.h" @@ -1491,6 +1492,13 @@ } ChromeUserPopulation::PageLoadToken token = cache_manager_->GetPageLoadToken(main_frame_url); + if (RealTimePolicyEngine::CanPerformFullURLLookup( + profile_->GetPrefs(), profile_->IsOffTheRecord(), + g_browser_process->variations_service())) { + base::UmaHistogramBoolean( + "SafeBrowsing.PageLoadToken.PasswordProtectionHasToken", + token.has_token_value()); + } // It's possible that the token is not found because real time URL check is // not performed for this navigation. Create a new page load token in this // case.
diff --git a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninPromoController.java b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninPromoController.java index da8d485..e4e7275 100644 --- a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninPromoController.java +++ b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninPromoController.java
@@ -208,13 +208,11 @@ public static String getPromoShowCountPreferenceName(@AccessPoint int accessPoint) { switch (accessPoint) { case SigninAccessPoint.BOOKMARK_MANAGER: - return ChromePreferenceKeys.SIGNIN_PROMO_SHOW_COUNT.createKey(BOOKMARKS); + return ChromePreferenceKeys.SYNC_PROMO_SHOW_COUNT.createKey(BOOKMARKS); case SigninAccessPoint.NTP_CONTENT_SUGGESTIONS: - return ChromePreferenceKeys.SIGNIN_PROMO_SHOW_COUNT.createKey(NTP); - case SigninAccessPoint.RECENT_TABS: - return ChromePreferenceKeys.SIGNIN_PROMO_SHOW_COUNT.createKey(RECENT_TABS); + return ChromePreferenceKeys.SYNC_PROMO_SHOW_COUNT.createKey(NTP); case SigninAccessPoint.SETTINGS: - return ChromePreferenceKeys.SIGNIN_PROMO_SHOW_COUNT.createKey(SETTINGS); + return ChromePreferenceKeys.SYNC_PROMO_SHOW_COUNT.createKey(SETTINGS); default: throw new IllegalArgumentException( "Unexpected value for access point: " + accessPoint); @@ -426,8 +424,12 @@ /** Increases promo show count by one. */ public void increasePromoShowCount() { + if (mAccessPoint != SigninAccessPoint.RECENT_TABS) { + SharedPreferencesManager.getInstance().incrementInt( + getPromoShowCountPreferenceName(mAccessPoint)); + } SharedPreferencesManager.getInstance().incrementInt( - getPromoShowCountPreferenceName(mAccessPoint)); + ChromePreferenceKeys.SYNC_PROMO_TOTAL_SHOW_COUNT); if (mAccessPoint == SigninAccessPoint.NTP_CONTENT_SUGGESTIONS) { final long currentTime = System.currentTimeMillis();
diff --git a/chrome/browser/ui/android/autofill/autofill_progress_dialog_view_android.cc b/chrome/browser/ui/android/autofill/autofill_progress_dialog_view_android.cc index d7d48b3..4d3dcb0 100644 --- a/chrome/browser/ui/android/autofill/autofill_progress_dialog_view_android.cc +++ b/chrome/browser/ui/android/autofill/autofill_progress_dialog_view_android.cc
@@ -39,7 +39,13 @@ return dialog_view; } -void AutofillProgressDialogViewAndroid::Dismiss() { +void AutofillProgressDialogViewAndroid::Dismiss( + bool show_confirmation_before_closing) { + if (show_confirmation_before_closing) { + ShowConfirmation(); + return; + } + JNIEnv* env = base::android::AttachCurrentThread(); if (!java_object_.is_null()) { Java_AutofillProgressDialogBridge_dismiss(env, java_object_);
diff --git a/chrome/browser/ui/android/autofill/autofill_progress_dialog_view_android.h b/chrome/browser/ui/android/autofill/autofill_progress_dialog_view_android.h index f911cf39..52ec4b7 100644 --- a/chrome/browser/ui/android/autofill/autofill_progress_dialog_view_android.h +++ b/chrome/browser/ui/android/autofill/autofill_progress_dialog_view_android.h
@@ -24,7 +24,7 @@ ~AutofillProgressDialogViewAndroid() override; // AutofillProgressDialogView. - void Dismiss() override; + void Dismiss(bool show_confirmation_before_closing) override; // Called by the Java code when the progress dialog is dismissed. void OnDismissed(JNIEnv* env); @@ -33,7 +33,7 @@ void ShowDialog(); // Show the confirmation icon and text. - void ShowConfirmation() override; + void ShowConfirmation(); private: AutofillProgressDialogController* controller_;
diff --git a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AutofillProgressDialogBridge.java b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AutofillProgressDialogBridge.java index a33f08b4..0c67c32 100644 --- a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AutofillProgressDialogBridge.java +++ b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AutofillProgressDialogBridge.java
@@ -107,6 +107,8 @@ .setVisibility(View.VISIBLE); ((TextView) mProgressDialogContentView.findViewById(R.id.message)) .setText(confirmationMessage); + // TODO(crbug.com/1243475): Dismiss the Java View after some delay if confirmation has + // been shown. } }
diff --git a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java index 0aca9035..23de5b3 100644 --- a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java +++ b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java
@@ -206,7 +206,7 @@ */ private static void recordAutoDarkSettingsChangeSource( @AutoDarkSettingsChangeSource int source, boolean enabled) { - String histogram = "Android.DarkTheme.AutoDark.SettingsChangeSource." + String histogram = "Android.DarkTheme.AutoDarkMode.SettingsChangeSource." + (enabled ? "Enabled" : "Disabled"); RecordHistogram.recordEnumeratedHistogram( histogram, source, AutoDarkSettingsChangeSource.NUM_ENTRIES);
diff --git a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeControllerUnitTest.java b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeControllerUnitTest.java index 753600e..81a5436 100644 --- a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeControllerUnitTest.java +++ b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeControllerUnitTest.java
@@ -286,7 +286,7 @@ private void assertAutoDarkModeChangeSourceRecorded( @AutoDarkSettingsChangeSource int source, boolean enabled, int expectedCounts) { - String histogramName = "Android.DarkTheme.AutoDark.SettingsChangeSource." + String histogramName = "Android.DarkTheme.AutoDarkMode.SettingsChangeSource." + (enabled ? "Enabled" : "Disabled"); int actualCount = RecordHistogram.getHistogramValueCountForTesting(histogramName, source); Assert.assertEquals("Histogram <" + histogramName + "> for sample <" + source
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index c42d3a9f..c09efe1 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -2279,7 +2279,7 @@ Preview page <ph name="BEGIN_NEW"><new></ph>New<ph name="END_NEW"></new></ph> </message> <message name="IDS_CONTEXTMENU_READ_LATER" desc="Context sensitive menu item for marking a link to be read later. We're also labeling it *New* to draw attention to it when first released. [CHAR_LIMIT=30]"> - Add to Reading List <ph name="BEGIN_NEW"><new></ph>New<ph name="END_NEW"></new></ph> + Add to reading list <ph name="BEGIN_NEW"><new></ph>New<ph name="END_NEW"></new></ph> </message> <message name="IDS_CONTEXTMENU_PERFORMANCE_INFO_FAST" desc="This string is shown in the context sensitive menu for links and is shown underneath the link URL. It indicates to the user that the link's target page is fast-loading and responsive. [CHAR_LIMIT=30]"> Fast page @@ -3225,14 +3225,14 @@ <message name="IDS_MENU_EDIT_BOOKMARK" desc="Menu item for editing the content of the bookmark for the current page. [CHAR_LIMIT=27]"> Edit Bookmark </message> - <message name="IDS_MENU_ADD_TO_READING_LIST" desc="Menu item for adding the current page to the 'Reading List' to read later. [CHAR_LIMIT=27]"> - Add to Reading List + <message name="IDS_MENU_ADD_TO_READING_LIST" desc="Menu item for adding the current page to the reading list. [CHAR_LIMIT=27]"> + Add to reading list </message> - <message name="IDS_MENU_DELETE_FROM_READING_LIST" desc="Menu item for removing the current page from the 'Reading List'. [CHAR_LIMIT=27]"> - Delete from Reading List + <message name="IDS_MENU_DELETE_FROM_READING_LIST" desc="Menu item for removing the current page from the reading list. [CHAR_LIMIT=27]"> + Delete from reading list </message> - <message name="IDS_MENU_EDIT_READING_LIST" desc="Menu item for opening and editing the 'Reading List'. Shown only when the current page is already on the Reading List. [CHAR_LIMIT=27]"> - Edit Reading List + <message name="IDS_MENU_EDIT_READING_LIST" desc="Menu item for opening and editing the reading list. Shown only when the current page is already on the reading list. [CHAR_LIMIT=27]"> + Edit reading list </message> <message name="IDS_MENU_FIND_IN_PAGE" desc="Menu item allowing users to find text within the current page. [CHAR_LIMIT=27]"> Find in page @@ -3455,7 +3455,7 @@ Save this page for later and get a reminder </message> <message name="IDS_READING_LIST_SAVE_PAGES_FOR_LATER" desc="The text on the reading list in product help bubble to introduce the feature to the user."> - Add pages to your Reading List to get a reminder + Add pages to your reading list for later </message> <message name="IDS_READING_LIST_FIND_IN_BOOKMARKS" desc="The text to inform the user to find the reading list in bookmarks UI."> Find your reading list in Bookmarks
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_READ_LATER.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_READ_LATER.png.sha1 index cb17f7aa..eca993fa 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_READ_LATER.png.sha1 +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_READ_LATER.png.sha1
@@ -1 +1 @@ -e8b9ef1faf769b5ac2aff34b9d2de2e3ad67216b \ No newline at end of file +f37cc0fb8a8a4955e1cedcc2f2a403040cf93c4e \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_ADD_TO_READING_LIST.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_ADD_TO_READING_LIST.png.sha1 index 7e2996e..d335978 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_ADD_TO_READING_LIST.png.sha1 +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_ADD_TO_READING_LIST.png.sha1
@@ -1 +1 @@ -ae82e7ea79689aef45d76de26fa8baf61b961b3b \ No newline at end of file +f957c8672dd7f7bd3d133cd8ea74458b3c269e93 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_DELETE_FROM_READING_LIST.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_DELETE_FROM_READING_LIST.png.sha1 index adb7c28b..31cf388a3 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_DELETE_FROM_READING_LIST.png.sha1 +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_DELETE_FROM_READING_LIST.png.sha1
@@ -1 +1 @@ -b080c9f217e7dff4dce75ca962b404efe215572a \ No newline at end of file +045ee313c247d75dba791334a0983198d6631e49 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_EDIT_READING_LIST.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_EDIT_READING_LIST.png.sha1 index e3eba9e..a51e205 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_EDIT_READING_LIST.png.sha1 +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_EDIT_READING_LIST.png.sha1
@@ -1 +1 @@ -a843887c2997190f3c846699e12ed973ea88a481 \ No newline at end of file +f74ab9e5c668d66c8bd760f0dda525fbbba20c87 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READING_LIST_SAVE_PAGES_FOR_LATER.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READING_LIST_SAVE_PAGES_FOR_LATER.png.sha1 index 202456aa..6edcd955 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READING_LIST_SAVE_PAGES_FOR_LATER.png.sha1 +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READING_LIST_SAVE_PAGES_FOR_LATER.png.sha1
@@ -1 +1 @@ -89c19bdab51f56cc41109a57ca8c2227ceea5f5a \ No newline at end of file +35263b1e4ddad400502674b738a2d6cc423ced1f \ No newline at end of file
diff --git a/chrome/browser/ui/app_list/app_list_sort_browsertest.cc b/chrome/browser/ui/app_list/app_list_sort_browsertest.cc index 4dde6130..04dc28a0 100644 --- a/chrome/browser/ui/app_list/app_list_sort_browsertest.cc +++ b/chrome/browser/ui/app_list/app_list_sort_browsertest.cc
@@ -7,6 +7,7 @@ #include "ash/public/cpp/test/app_list_test_api.h" #include "ash/public/cpp/test/shell_test_api.h" #include "ash/shell.h" +#include "base/feature_list.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" @@ -47,8 +48,15 @@ ash::AcceleratorController::Get()->PerformActionIfEnabled( ash::TOGGLE_APP_LIST_FULLSCREEN, {}); - // Assume that there are two default apps. - ASSERT_EQ(2, app_list_test_api_.GetTopListItemCount()); + const int default_app_count = app_list_test_api_.GetTopListItemCount(); + + if (base::FeatureList::IsEnabled(chromeos::features::kLacrosSupport)) { + // Assume that there are three default apps, one being the Lacros browser. + ASSERT_EQ(3, app_list_test_api_.GetTopListItemCount()); + } else { + // Assume that there are two default apps. + ASSERT_EQ(2, app_list_test_api_.GetTopListItemCount()); + } app1_id_ = LoadExtension(test_data_dir_.AppendASCII("app1"))->id(); ASSERT_FALSE(app1_id_.empty()); @@ -58,7 +66,7 @@ // app in this test. app3_id_ = LoadExtension(test_data_dir_.AppendASCII("app4"))->id(); ASSERT_FALSE(app3_id_.empty()); - EXPECT_EQ(5, app_list_test_api_.GetTopListItemCount()); + EXPECT_EQ(default_app_count + 3, app_list_test_api_.GetTopListItemCount()); event_generator_ = std::make_unique<ui::test::EventGenerator>( ash::Shell::GetPrimaryRootWindow());
diff --git a/chrome/browser/ui/app_list/search/arc/recommend_apps_fetcher_impl.cc b/chrome/browser/ui/app_list/search/arc/recommend_apps_fetcher_impl.cc index 9d96433..ee085945 100644 --- a/chrome/browser/ui/app_list/search/arc/recommend_apps_fetcher_impl.cc +++ b/chrome/browser/ui/app_list/search/arc/recommend_apps_fetcher_impl.cc
@@ -153,12 +153,10 @@ // TODO(thanhdng): Add a UMA histogram here recording the time difference. std::unique_ptr<network::SimpleURLLoader> loader(std::move(app_list_loader_)); - int response_code = 0; if (!loader->ResponseInfo() || !loader->ResponseInfo()->headers) { delegate_->OnLoadError(); return; } - response_code = loader->ResponseInfo()->headers->response_code(); // TODO(thanhndng): Add a UMA histogram here recording the response code. // If the recommended app list could not be downloaded, show an error message
diff --git a/chrome/browser/ui/app_list/search/chrome_search_result.cc b/chrome/browser/ui/app_list/search/chrome_search_result.cc index 78e4ceb0..fee5f00 100644 --- a/chrome/browser/ui/app_list/search/chrome_search_result.cc +++ b/chrome/browser/ui/app_list/search/chrome_search_result.cc
@@ -72,6 +72,11 @@ SetSearchResultMetadata(); } +void ChromeSearchResult::SetBestMatch(bool best_match) { + metadata_->best_match = best_match; + SetSearchResultMetadata(); +} + void ChromeSearchResult::SetDisplayType(DisplayType display_type) { metadata_->display_type = display_type; SetSearchResultMetadata();
diff --git a/chrome/browser/ui/app_list/search/chrome_search_result.h b/chrome/browser/ui/app_list/search/chrome_search_result.h index 0d6c1c42e..d9a519b 100644 --- a/chrome/browser/ui/app_list/search/chrome_search_result.h +++ b/chrome/browser/ui/app_list/search/chrome_search_result.h
@@ -66,6 +66,7 @@ } const std::string& id() const { return metadata_->id; } Category category() const { return metadata_->category; } + bool best_match() const { return metadata_->best_match; } DisplayType display_type() const { return metadata_->display_type; } ash::AppListSearchResultType result_type() const { return metadata_->result_type; @@ -100,6 +101,7 @@ void SetRating(float rating); void SetFormattedPrice(const std::u16string& formatted_price); void SetCategory(Category category); + void SetBestMatch(bool best_match); void SetDisplayType(DisplayType display_type); void SetResultType(ResultType result_type); void SetMetricsType(MetricsType metrics_type);
diff --git a/chrome/browser/ui/app_list/search/ranking/category_item_ranker.cc b/chrome/browser/ui/app_list/search/ranking/category_item_ranker.cc index ed42957..206c830 100644 --- a/chrome/browser/ui/app_list/search/ranking/category_item_ranker.cc +++ b/chrome/browser/ui/app_list/search/ranking/category_item_ranker.cc
@@ -22,7 +22,9 @@ category_scores_.clear(); } -void CategoryItemRanker::Rank(ResultsMap& results, ProviderType provider) { +void CategoryItemRanker::Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) { UpdateCategoryScore(results, provider); RescoreResults(results); }
diff --git a/chrome/browser/ui/app_list/search/ranking/category_item_ranker.h b/chrome/browser/ui/app_list/search/ranking/category_item_ranker.h index cce9f50..19f2e1a 100644 --- a/chrome/browser/ui/app_list/search/ranking/category_item_ranker.h +++ b/chrome/browser/ui/app_list/search/ranking/category_item_ranker.h
@@ -24,7 +24,9 @@ // Ranker: void Start(const std::u16string& query) override; - void Rank(ResultsMap& results, ProviderType provider) override; + void Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) override; private: // Updates the score of |provider|'s category in |category_scores_|.
diff --git a/chrome/browser/ui/app_list/search/ranking/category_usage_ranker.cc b/chrome/browser/ui/app_list/search/ranking/category_usage_ranker.cc index 41a4637..9cf964c 100644 --- a/chrome/browser/ui/app_list/search/ranking/category_usage_ranker.cc +++ b/chrome/browser/ui/app_list/search/ranking/category_usage_ranker.cc
@@ -50,17 +50,18 @@ // |category_ranker_| has a small recency component to its scores, so the // categories will appear in reverse order to the Record calls. This must // record every category except unknown and best match. - category_ranker_->Record(CategoryToString(Category::kAssistant)); + category_ranker_->Record(CategoryToString(Category::kSearchAndAssistant)); category_ranker_->Record(CategoryToString(Category::kPlayStore)); - category_ranker_->Record(CategoryToString(Category::kWeb)); - category_ranker_->Record(CategoryToString(Category::kFiles)); - category_ranker_->Record(CategoryToString(Category::kHelp)); category_ranker_->Record(CategoryToString(Category::kSettings)); - category_ranker_->Record(CategoryToString(Category::kApp)); + category_ranker_->Record(CategoryToString(Category::kFiles)); + category_ranker_->Record(CategoryToString(Category::kWeb)); + category_ranker_->Record(CategoryToString(Category::kAppShortcuts)); + category_ranker_->Record(CategoryToString(Category::kApps)); + category_ranker_->Record(CategoryToString(Category::kHelp)); - // Check we've recorded every category except unknown and best match. + // Check we've recorded every category except unknown. DCHECK_EQ(category_ranker_->Rank().size(), - static_cast<size_t>(Category::kMaxValue) - 1); + static_cast<size_t>(Category::kMaxValue)); } CategoryUsageRanker::~CategoryUsageRanker() {} @@ -93,7 +94,9 @@ } } -void CategoryUsageRanker::Rank(ResultsMap& results, ProviderType provider) { +void CategoryUsageRanker::Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) { // Update each result's score to be: // kCategoryScoreFactor*(category rank) + (result relevance) const auto it = results.find(provider);
diff --git a/chrome/browser/ui/app_list/search/ranking/category_usage_ranker.h b/chrome/browser/ui/app_list/search/ranking/category_usage_ranker.h index 5c0ee63..3941b0f 100644 --- a/chrome/browser/ui/app_list/search/ranking/category_usage_ranker.h +++ b/chrome/browser/ui/app_list/search/ranking/category_usage_ranker.h
@@ -25,7 +25,9 @@ // Ranker: void Start(const std::u16string& query) override; - void Rank(ResultsMap& results, ProviderType provider) override; + void Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) override; void Train(const LaunchData& launch) override; private:
diff --git a/chrome/browser/ui/app_list/search/ranking/filtering_ranker.cc b/chrome/browser/ui/app_list/search/ranking/filtering_ranker.cc index fcb1762..d13ce6e 100644 --- a/chrome/browser/ui/app_list/search/ranking/filtering_ranker.cc +++ b/chrome/browser/ui/app_list/search/ranking/filtering_ranker.cc
@@ -24,7 +24,9 @@ last_query_ = query; } -void FilteringRanker::Rank(ResultsMap& results, ProviderType provider) { +void FilteringRanker::Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) { // Don't perform any filtering on zero-state. if (last_query_.empty()) return;
diff --git a/chrome/browser/ui/app_list/search/ranking/filtering_ranker.h b/chrome/browser/ui/app_list/search/ranking/filtering_ranker.h index 7018187..a2641d6 100644 --- a/chrome/browser/ui/app_list/search/ranking/filtering_ranker.h +++ b/chrome/browser/ui/app_list/search/ranking/filtering_ranker.h
@@ -22,7 +22,9 @@ // Ranker: void Start(const std::u16string& query) override; - void Rank(ResultsMap& results, ProviderType provider) override; + void Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) override; private: std::u16string last_query_;
diff --git a/chrome/browser/ui/app_list/search/ranking/ranker.h b/chrome/browser/ui/app_list/search/ranking/ranker.h index cf2df364..8714349 100644 --- a/chrome/browser/ui/app_list/search/ranking/ranker.h +++ b/chrome/browser/ui/app_list/search/ranking/ranker.h
@@ -39,7 +39,9 @@ // // The goal of a ranker should be to update scores in the Scoring structs // within |results|. Generally, one ranker should map to one score member. - virtual void Rank(ResultsMap& results, ProviderType provider) {} + virtual void Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) {} // Called each time a user launches a result. virtual void Train(const LaunchData& launch) {}
diff --git a/chrome/browser/ui/app_list/search/ranking/ranker_delegate.cc b/chrome/browser/ui/app_list/search/ranking/ranker_delegate.cc index 88d371f..ea236ef 100644 --- a/chrome/browser/ui/app_list/search/ranking/ranker_delegate.cc +++ b/chrome/browser/ui/app_list/search/ranking/ranker_delegate.cc
@@ -16,9 +16,11 @@ ranker->Start(query); } -void RankerDelegate::Rank(ResultsMap& results, ProviderType provider) { +void RankerDelegate::Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) { for (auto& ranker : rankers_) - ranker->Rank(results, provider); + ranker->Rank(results, categories, provider); } void RankerDelegate::Train(const LaunchData& launch) {
diff --git a/chrome/browser/ui/app_list/search/ranking/ranker_delegate.h b/chrome/browser/ui/app_list/search/ranking/ranker_delegate.h index 73edbe6..e233720 100644 --- a/chrome/browser/ui/app_list/search/ranking/ranker_delegate.h +++ b/chrome/browser/ui/app_list/search/ranking/ranker_delegate.h
@@ -30,7 +30,9 @@ // Ranker: void Start(const std::u16string& query) override; - void Rank(ResultsMap& results, ProviderType provider) override; + void Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) override; void Train(const LaunchData& launch) override; private:
diff --git a/chrome/browser/ui/app_list/search/ranking/score_normalizing_ranker.cc b/chrome/browser/ui/app_list/search/ranking/score_normalizing_ranker.cc index 53a489d..b864112 100644 --- a/chrome/browser/ui/app_list/search/ranking/score_normalizing_ranker.cc +++ b/chrome/browser/ui/app_list/search/ranking/score_normalizing_ranker.cc
@@ -59,7 +59,8 @@ ScoreNormalizingRanker::~ScoreNormalizingRanker() {} -void ScoreNormalizingRanker::Rank(ResultsMap& results, ProviderType provider) { -} +void ScoreNormalizingRanker::Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) {} } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/ranking/score_normalizing_ranker.h b/chrome/browser/ui/app_list/search/ranking/score_normalizing_ranker.h index e63d296..3c087486 100644 --- a/chrome/browser/ui/app_list/search/ranking/score_normalizing_ranker.h +++ b/chrome/browser/ui/app_list/search/ranking/score_normalizing_ranker.h
@@ -31,7 +31,9 @@ ScoreNormalizingRanker& operator=(const ScoreNormalizingRanker&) = delete; // Ranker: - void Rank(ResultsMap& results, ProviderType provider) override; + void Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) override; private: // TODO(crbug.com/1247475): Score normalizers removed due to stability issues.
diff --git a/chrome/browser/ui/app_list/search/ranking/top_match_ranker.cc b/chrome/browser/ui/app_list/search/ranking/top_match_ranker.cc index 3a138c6c..4caebd1 100644 --- a/chrome/browser/ui/app_list/search/ranking/top_match_ranker.cc +++ b/chrome/browser/ui/app_list/search/ranking/top_match_ranker.cc
@@ -46,7 +46,9 @@ TopMatchRanker::~TopMatchRanker() {} -void TopMatchRanker::Rank(ResultsMap& results, ProviderType provider) { +void TopMatchRanker::Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) { const auto it = results.find(provider); DCHECK(it != results.end());
diff --git a/chrome/browser/ui/app_list/search/ranking/top_match_ranker.h b/chrome/browser/ui/app_list/search/ranking/top_match_ranker.h index ec0ba31..83a10cc8 100644 --- a/chrome/browser/ui/app_list/search/ranking/top_match_ranker.h +++ b/chrome/browser/ui/app_list/search/ranking/top_match_ranker.h
@@ -27,7 +27,9 @@ TopMatchRanker& operator=(const TopMatchRanker&) = delete; // Ranker: - void Rank(ResultsMap& results, ProviderType provider) override; + void Rank(ResultsMap& results, + CategoriesMap& categories, + ProviderType provider) override; }; } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/ranking/types.cc b/chrome/browser/ui/app_list/search/ranking/types.cc index 82726d6..1d2850e 100644 --- a/chrome/browser/ui/app_list/search/ranking/types.cc +++ b/chrome/browser/ui/app_list/search/ranking/types.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/app_list/search/ranking/types.h" +#include <stddef.h> + #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h"
diff --git a/chrome/browser/ui/app_list/search/ranking/types.h b/chrome/browser/ui/app_list/search/ranking/types.h index 37733c76..94b50f6 100644 --- a/chrome/browser/ui/app_list/search/ranking/types.h +++ b/chrome/browser/ui/app_list/search/ranking/types.h
@@ -7,7 +7,6 @@ #include "ash/public/cpp/app_list/app_list_types.h" #include "base/files/file_path.h" -#include "chrome/browser/ui/app_list/search/search_controller.h" namespace app_list {
diff --git a/chrome/browser/ui/app_list/search/ranking/util.cc b/chrome/browser/ui/app_list/search/ranking/util.cc index 4a834217..b194949 100644 --- a/chrome/browser/ui/app_list/search/ranking/util.cc +++ b/chrome/browser/ui/app_list/search/ranking/util.cc
@@ -27,8 +27,9 @@ case ResultType::kInstalledApp: case ResultType::kInstantApp: case ResultType::kInternalApp: + return Category::kApps; case ResultType::kArcAppShortcut: - return Category::kApp; + return Category::kAppShortcuts; case ResultType::kOmnibox: case ResultType::kAnswerCard: return Category::kWeb; @@ -39,9 +40,6 @@ case ResultType::kFileSearch: case ResultType::kDriveSearch: return Category::kFiles; - case ResultType::kAssistantChip: - case ResultType::kAssistantText: - return Category::kAssistant; case ResultType::kOsSettings: return Category::kSettings; case ResultType::kHelpApp: @@ -49,6 +47,9 @@ case ResultType::kPlayStoreReinstallApp: case ResultType::kPlayStoreApp: return Category::kPlayStore; + case ResultType::kAssistantChip: + case ResultType::kAssistantText: + return Category::kSearchAndAssistant; // Never used in the search backend. case ResultType::kUnknown: // Suggested content toggle fake result type. Used only in ash, not in the @@ -57,7 +58,7 @@ // Deprecated. case ResultType::kLauncher: NOTREACHED(); - return Category::kApp; + return Category::kApps; } } @@ -65,23 +66,22 @@ switch (category) { case Category::kUnknown: return u"(unknown) "; - case Category::kBestMatch: - // The debug string for best match is handled elsewhere. - return u""; - case Category::kApp: + case Category::kApps: + return u"(apps) "; + case Category::kAppShortcuts: return u"(apps) "; case Category::kWeb: return u"(web) "; case Category::kFiles: return u"(files) "; - case Category::kAssistant: - return u"(assistant) "; case Category::kSettings: return u"(settings) "; case Category::kHelp: return u"(help) "; case Category::kPlayStore: return u"(play store) "; + case Category::kSearchAndAssistant: + return u"(assistant) "; } }
diff --git a/chrome/browser/ui/app_list/search/ranking/util.h b/chrome/browser/ui/app_list/search/ranking/util.h index e592fb5..9f43444 100644 --- a/chrome/browser/ui/app_list/search/ranking/util.h +++ b/chrome/browser/ui/app_list/search/ranking/util.h
@@ -9,6 +9,7 @@ #include "base/files/file_path.h" #include "chrome/browser/ui/app_list/search/ranking/types.h" +#include "chrome/browser/ui/app_list/search/search_controller.h" class Profile; @@ -21,8 +22,8 @@ // Given a search result type, returns the category it should be placed in. Category ResultTypeToCategory(ResultType result_type); -// TODO(crbug.com/1199206): Once the UI has support for categories this can be -// removed. +// TODO(crbug.com/1199206): Once the UI has support for categories the following +// methods can be removed. // Given a category, returns a debug string of its name suitable for the interim // UI.
diff --git a/chrome/browser/ui/app_list/search/search_controller.h b/chrome/browser/ui/app_list/search/search_controller.h index 09aa130..c4c40ba9 100644 --- a/chrome/browser/ui/app_list/search/search_controller.h +++ b/chrome/browser/ui/app_list/search/search_controller.h
@@ -14,6 +14,7 @@ #include "base/callback.h" #include "base/containers/flat_map.h" +#include "base/logging.h" #include "base/macros.h" #include "base/observer_list_types.h" #include "chrome/browser/ui/app_list/search/mixer.h" @@ -41,6 +42,7 @@ using Results = std::vector<std::unique_ptr<ChromeSearchResult>>; using ResultsMap = base::flat_map<ProviderType, Results>; +using CategoriesMap = base::flat_map<Category, double>; // Controller that collects query from given SearchBoxModel, dispatches it // to all search providers, then invokes the mixer to mix and to publish the
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new.cc b/chrome/browser/ui/app_list/search/search_controller_impl_new.cc index a5f670f1..7eceb562 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl_new.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl_new.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/ui/app_list/search/ranking/ranker_delegate.h" #include "chrome/browser/ui/app_list/search/ranking/score_normalizing_ranker.h" #include "chrome/browser/ui/app_list/search/ranking/top_match_ranker.h" +#include "chrome/browser/ui/app_list/search/ranking/util.h" #include "chrome/browser/ui/app_list/search/search_metrics_observer.h" #include "chrome/browser/ui/app_list/search/search_provider.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/chip_ranker.h" @@ -92,6 +93,7 @@ last_query_ = query; results_.clear(); + categories_.clear(); for (Observer& observer : observer_list_) observer.OnResultsCleared(); @@ -162,7 +164,7 @@ results_[provider_type] = std::move(results); // Update ranking of all results. - ranker_->Rank(results_, provider_type); + ranker_->Rank(results_, categories_, provider_type); // Compile a single list of results and sort by their relevance. std::vector<ChromeSearchResult*> all_results; @@ -194,6 +196,15 @@ return a->display_score() > b->display_score(); }); + // Create a vector of categories in display order. + std::vector<std::pair<Category, double>> sorted_category_pairs( + categories_.begin(), categories_.end()); + std::sort(sorted_category_pairs.begin(), sorted_category_pairs.end(), + [](const auto& a, const auto& b) { return a.second > b.second; }); + std::vector<Category> sorted_categories; + for (const auto& pair : sorted_category_pairs) + sorted_categories.push_back(pair.first); + if (!observer_list_.empty()) { std::vector<const ChromeSearchResult*> observer_results; for (auto* result : all_results) @@ -202,8 +213,7 @@ observer.OnResultsAdded(last_query_, observer_results); } - // TODO(crbug.com/1199206): Send category ranks. - model_updater_->PublishSearchResults(all_results, /*categories=*/{}); + model_updater_->PublishSearchResults(all_results, sorted_categories); } ChromeSearchResult* SearchControllerImplNew::FindSearchResult(
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new.h b/chrome/browser/ui/app_list/search/search_controller_impl_new.h index 71506cc..66947a0 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl_new.h +++ b/chrome/browser/ui/app_list/search/search_controller_impl_new.h
@@ -101,6 +101,9 @@ // Storage for all search results for the current query. ResultsMap results_; + // Storage for category scores for the current query. + CategoriesMap categories_; + std::unique_ptr<SearchMetricsObserver> metrics_observer_; using Providers = std::vector<std::unique_ptr<SearchProvider>>; Providers providers_;
diff --git a/chrome/browser/ui/ash/capture_mode/capture_mode_browsertest.cc b/chrome/browser/ui/ash/capture_mode/capture_mode_browsertest.cc index baf2dd77..2d50357 100644 --- a/chrome/browser/ui/ash/capture_mode/capture_mode_browsertest.cc +++ b/chrome/browser/ui/ash/capture_mode/capture_mode_browsertest.cc
@@ -2,14 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ash/constants/ash_features.h" #include "ash/public/cpp/capture_mode/capture_mode_test_api.h" +#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/test/shell_test_api.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/ash/file_manager/file_manager_test_util.h" +#include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/browser_test.h" #include "ui/aura/window.h" #include "ui/events/test/event_generator.h" +#include "ui/wm/core/window_util.h" // Testing class to test CrOS capture mode, which is a feature to take // screenshots and record video. @@ -31,3 +37,41 @@ ash::CaptureModeTestApi().StartForWindow(/*for_video=*/false); EXPECT_TRUE(shell_test_api.IsContextMenuShown()); } + +class AdvancedSettingsCaptureModeBrowserTest + : public extensions::ExtensionBrowserTest { + public: + AdvancedSettingsCaptureModeBrowserTest() { + scoped_feature_list_.InitAndEnableFeature( + ash::features::kImprovedScreenCaptureSettings); + } + + ~AdvancedSettingsCaptureModeBrowserTest() override = default; + + // extensions::ExtensionBrowserTest: + void SetUpOnMainThread() override { + extensions::ExtensionBrowserTest::SetUpOnMainThread(); + CHECK(profile()); + file_manager::test::AddDefaultComponentExtensionsOnMainThread(profile()); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +// Tests that the capture mode folder selection dialog window gets parented +// correctly when a browser window is available. +IN_PROC_BROWSER_TEST_F(AdvancedSettingsCaptureModeBrowserTest, + FolderSelectionDialogParentedCorrectly) { + ASSERT_TRUE(browser()); + ash::CaptureModeTestApi test_api; + test_api.StartForFullscreen(/*for_video=*/false); + test_api.SimulateOpeningFolderSelectionDialog(); + auto* dialog_window = test_api.GetFolderSelectionDialogWindow(); + ASSERT_TRUE(dialog_window); + auto* transient_root = wm::GetTransientRoot(dialog_window); + ASSERT_TRUE(transient_root); + EXPECT_EQ(transient_root->GetId(), + ash::kShellWindowId_CaptureModeFolderSelectionDialogOwner); + EXPECT_NE(transient_root, browser()->window()->GetNativeWindow()); +}
diff --git a/chrome/browser/ui/ash/thumbnail_loader.cc b/chrome/browser/ui/ash/thumbnail_loader.cc index ea76ac2..c257891 100644 --- a/chrome/browser/ui/ash/thumbnail_loader.cc +++ b/chrome/browser/ui/ash/thumbnail_loader.cc
@@ -24,6 +24,7 @@ #include "extensions/browser/api/messaging/native_message_host.h" #include "extensions/common/api/messaging/messaging_endpoint.h" #include "extensions/common/api/messaging/port_id.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/extension.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "services/data_decoder/public/cpp/data_decoder.h" @@ -286,7 +287,8 @@ base::BindOnce(&ThumbnailLoader::OnThumbnailLoaded, weak_factory_.GetWeakPtr(), request_id, request.size)); const extensions::PortId port_id(base::UnguessableToken::Create(), - 1 /* port_number */, true /* is_opener */); + 1 /* port_number */, true /* is_opener */, + extensions::SerializationFormat::kJson); auto native_message_port = std::make_unique<extensions::NativeMessagePort>( message_service->GetChannelDelegate(), port_id, std::move(native_message_host));
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 3fd7c23d..306e07f 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -770,6 +770,19 @@ autofill_error_dialog_controller_.Show(error_dialog_type); } +void ChromeAutofillClient::ShowAutofillProgressDialog( + base::OnceClosure cancel_callback) { + DCHECK(autofill_progress_dialog_controller_); + autofill_progress_dialog_controller_->ShowDialog(std::move(cancel_callback)); +} + +void ChromeAutofillClient::CloseAutofillProgressDialog( + bool show_confirmation_before_closing) { + DCHECK(autofill_progress_dialog_controller_); + autofill_progress_dialog_controller_->DismissDialog( + show_confirmation_before_closing); +} + bool ChromeAutofillClient::IsAutofillAssistantShowing() { auto* assistant_runtime_manager = autofill_assistant::RuntimeManager::GetForWebContents(web_contents()); @@ -899,7 +912,10 @@ GetPersonalDataManager()->app_locale())), unmask_controller_( user_prefs::UserPrefs::Get(web_contents->GetBrowserContext())), - autofill_error_dialog_controller_(web_contents) { + autofill_error_dialog_controller_(web_contents), + autofill_progress_dialog_controller_( + std::make_unique<AutofillProgressDialogControllerImpl>( + web_contents)) { // TODO(crbug.com/928595): Replace the closure with a callback to the // renderer that indicates if log messages should be sent from the // renderer.
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index 0ec3d0119..52cc68d 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -18,6 +18,7 @@ #include "chrome/browser/autofill/autofill_gstatic_reader.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/autofill/payments/autofill_error_dialog_controller_impl.h" +#include "chrome/browser/ui/autofill/payments/autofill_progress_dialog_controller_impl.h" #include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/logging/log_manager.h" #include "components/autofill/core/browser/payments/legal_message_line.h" @@ -161,6 +162,9 @@ const std::u16string& cvc, const gfx::Image& card_image) override; void ShowVirtualCardErrorDialog(bool is_permanent_error) override; + void ShowAutofillProgressDialog(base::OnceClosure cancel_callback) override; + void CloseAutofillProgressDialog( + bool show_confirmation_before_closing) override; bool IsAutofillAssistantShowing() override; bool IsAutocompleteEnabled() override; void PropagateAutofillPredictions( @@ -220,6 +224,8 @@ #endif CardUnmaskPromptControllerImpl unmask_controller_; AutofillErrorDialogControllerImpl autofill_error_dialog_controller_; + std::unique_ptr<AutofillProgressDialogControllerImpl> + autofill_progress_dialog_controller_; WEB_CONTENTS_USER_DATA_KEY_DECL(); };
diff --git a/chrome/browser/ui/autofill/payments/autofill_progress_dialog_controller_impl.cc b/chrome/browser/ui/autofill/payments/autofill_progress_dialog_controller_impl.cc index 18a1421..378bfeee1 100644 --- a/chrome/browser/ui/autofill/payments/autofill_progress_dialog_controller_impl.cc +++ b/chrome/browser/ui/autofill/payments/autofill_progress_dialog_controller_impl.cc
@@ -15,23 +15,45 @@ : web_contents_(web_contents) {} AutofillProgressDialogControllerImpl::~AutofillProgressDialogControllerImpl() { - Dismiss(); + if (autofill_progress_dialog_view_) { + autofill_progress_dialog_view_->Dismiss( + /*show_confirmation_before_closing=*/false); + autofill_progress_dialog_view_ = nullptr; + } } -void AutofillProgressDialogControllerImpl::ShowDialog() { +void AutofillProgressDialogControllerImpl::ShowDialog( + base::OnceClosure cancel_callback) { DCHECK(!autofill_progress_dialog_view_); + cancel_callback_ = std::move(cancel_callback); autofill_progress_dialog_view_ = AutofillProgressDialogView::CreateAndShow(this); } -void AutofillProgressDialogControllerImpl::ShowConfirmation() { - DCHECK(autofill_progress_dialog_view_); - autofill_progress_dialog_view_->ShowConfirmation(); +void AutofillProgressDialogControllerImpl::DismissDialog( + bool show_confirmation_before_closing) { + if (!autofill_progress_dialog_view_) + return; + + autofill_progress_dialog_view_->Dismiss(show_confirmation_before_closing); + autofill_progress_dialog_view_ = nullptr; } void AutofillProgressDialogControllerImpl::OnDismissed() { - autofill_progress_dialog_view_ = nullptr; + // If the |autofill_progress_dialog_view_| is not a nullptr. It means the + // dismissal was triggered by the user cancelling the flow. Thus we should + // invoke the |cancel_callback_|. + if (autofill_progress_dialog_view_) { + autofill_progress_dialog_view_ = nullptr; + std::move(cancel_callback_).Run(); + // TODO(crbug.com/1243475): Add metrics. + return; + } + + // Otherwise it was triggered by the backend components. The + // |cancel_callback_| will not be invoked but be reset. + cancel_callback_.Reset(); } const std::u16string AutofillProgressDialogControllerImpl::GetTitle() { @@ -59,9 +81,4 @@ return web_contents_; } -void AutofillProgressDialogControllerImpl::Dismiss() { - if (autofill_progress_dialog_view_) - autofill_progress_dialog_view_->Dismiss(); -} - } // namespace autofill
diff --git a/chrome/browser/ui/autofill/payments/autofill_progress_dialog_controller_impl.h b/chrome/browser/ui/autofill/payments/autofill_progress_dialog_controller_impl.h index 1d39ff3..4f471d7 100644 --- a/chrome/browser/ui/autofill/payments/autofill_progress_dialog_controller_impl.h +++ b/chrome/browser/ui/autofill/payments/autofill_progress_dialog_controller_impl.h
@@ -29,8 +29,8 @@ ~AutofillProgressDialogControllerImpl() override; - void ShowDialog(); - void ShowConfirmation(); + void ShowDialog(base::OnceClosure cancel_callback); + void DismissDialog(bool show_confirmation_before_closing); // AutofillProgressDialogController. void OnDismissed() override; @@ -46,12 +46,13 @@ } private: - // Dismiss the progress bar dialog if showing. - void Dismiss(); - content::WebContents* web_contents_; + // View that displays the error dialog. AutofillProgressDialogView* autofill_progress_dialog_view_ = nullptr; + + // Callback function invoked when the cancel button is clicked. + base::OnceClosure cancel_callback_; }; } // namespace autofill
diff --git a/chrome/browser/ui/autofill/payments/autofill_progress_dialog_view.h b/chrome/browser/ui/autofill/payments/autofill_progress_dialog_view.h index 8d9df405..fb2dd36 100644 --- a/chrome/browser/ui/autofill/payments/autofill_progress_dialog_view.h +++ b/chrome/browser/ui/autofill/payments/autofill_progress_dialog_view.h
@@ -16,10 +16,7 @@ virtual ~AutofillProgressDialogView() = default; // Called by the controller to dismiss the dialog. - virtual void Dismiss() = 0; - - // Called by the controller to show the confirmation view and message. - virtual void ShowConfirmation() = 0; + virtual void Dismiss(bool show_confirmation_before_closing) = 0; // Factory function for creating and showing the view. static AutofillProgressDialogView* CreateAndShow(
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index b746f90..68088c50 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -1101,8 +1101,8 @@ // Hosted app browser commands. const bool enable_copy_url = is_web_app_or_custom_tab || - base::FeatureList::IsEnabled(sharing_hub::kSharingHubDesktopOmnibox) || - base::FeatureList::IsEnabled(sharing_hub::kSharingHubDesktopAppMenu); + sharing_hub::SharingHubOmniboxEnabled(browser_->profile()) || + sharing_hub::SharingHubAppMenuEnabled(browser_->profile()); command_updater_.UpdateCommandEnabled(IDC_COPY_URL, enable_copy_url); command_updater_.UpdateCommandEnabled(IDC_OPEN_IN_CHROME, is_web_app_or_custom_tab);
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index c3627779..c335077 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -854,7 +854,7 @@ AddItemWithStringId(IDC_PRINT, IDS_PRINT); - if (!base::FeatureList::IsEnabled(sharing_hub::kSharingHubDesktopAppMenu) || + if (!sharing_hub::SharingHubAppMenuEnabled(browser()->profile()) || browser_->profile()->IsIncognitoProfile() || browser_->profile()->IsGuestSession()) { if (media_router::MediaRouterEnabled(browser()->profile()))
diff --git a/chrome/browser/ui/user_education/tutorial/tutorial.cc b/chrome/browser/ui/user_education/tutorial/tutorial.cc index 894ce64..62d8265 100644 --- a/chrome/browser/ui/user_education/tutorial/tutorial.cc +++ b/chrome/browser/ui/user_education/tutorial/tutorial.cc
@@ -109,10 +109,16 @@ tutorial_service->HideCurrentBubbleIfShowing(); + base::RepeatingClosure abort_callback = base::BindRepeating( + [](TutorialService* tutorial_service) { + tutorial_service->AbortTutorial(); + }, + base::Unretained(tutorial_service)); + std::unique_ptr<TutorialBubble> bubble = bubble_factory_registry->CreateBubbleForTrackedElement( element, title_text_, body_text_, arrow_, progress_, - is_last_step_); + std::move(abort_callback), is_last_step_); tutorial_service->SetCurrentBubble(std::move(bubble)); }, base::Unretained(tutorial_service),
diff --git a/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory.cc b/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory.cc index 67c22af..6e8bd0df 100644 --- a/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory.cc +++ b/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory.h" +#include "base/callback_forward.h" #include "chrome/browser/ui/user_education/tutorial/tutorial_bubble.h" #include "chrome/browser/ui/user_education/tutorial/tutorial_description.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -16,9 +17,10 @@ absl::optional<std::u16string> body_text, TutorialDescription::Step::Arrow arrow, absl::optional<std::pair<int, int>> progress, + base::RepeatingClosure abort_callback, bool is_last_step) { if (!CanBuildBubbleForTrackedElement(element)) return nullptr; return CreateBubble(element, title_text, body_text, arrow, progress, - is_last_step); + abort_callback, is_last_step); }
diff --git a/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory.h b/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory.h index a0ceec8..8871aaf 100644 --- a/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory.h +++ b/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_USER_EDUCATION_TUTORIAL_TUTORIAL_BUBBLE_FACTORY_H_ #define CHROME_BROWSER_UI_USER_EDUCATION_TUTORIAL_TUTORIAL_BUBBLE_FACTORY_H_ +#include "base/callback_forward.h" #include "chrome/browser/ui/user_education/tutorial/tutorial_bubble.h" #include "chrome/browser/ui/user_education/tutorial/tutorial_description.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -26,7 +27,8 @@ absl::optional<std::u16string> body_text, TutorialDescription::Step::Arrow arrow, absl::optional<std::pair<int, int>> progress, - bool is_last_step); + base::RepeatingClosure abort_callback, + bool is_last_step = false); private: // Called by the Tutorial to show the bubble. @@ -36,7 +38,8 @@ absl::optional<std::u16string> body_text, TutorialDescription::Step::Arrow arrow, absl::optional<std::pair<int, int>> progress, - bool is_last_step) = 0; + base::RepeatingClosure abort_callback, + bool is_last_step = false) = 0; // Returns true iff the bubble owner can show a bubble for the TrackedElement. virtual bool CanBuildBubbleForTrackedElement(ui::TrackedElement* element) = 0;
diff --git a/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory_registry.cc b/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory_registry.cc index c67cde1..4f123c4 100644 --- a/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory_registry.cc +++ b/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory_registry.cc
@@ -25,11 +25,13 @@ absl::optional<std::u16string> body_text, TutorialDescription::Step::Arrow arrow, absl::optional<std::pair<int, int>> progress, + base::RepeatingClosure abort_callback, bool is_last_step) { for (const auto& bubble_factory : bubble_factories_) { std::unique_ptr<TutorialBubble> bubble = bubble_factory->CreateBubbleIfElementIsValid( - element, title_text, body_text, arrow, progress, is_last_step); + element, title_text, body_text, arrow, progress, abort_callback, + is_last_step); if (bubble) return bubble; }
diff --git a/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory_registry.h b/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory_registry.h index 70f9485..358acca 100644 --- a/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory_registry.h +++ b/chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory_registry.h
@@ -35,7 +35,8 @@ absl::optional<std::u16string> body_text, TutorialDescription::Step::Arrow arrow, absl::optional<std::pair<int, int>> progress, - bool is_last_step); + base::RepeatingClosure abort_callback, + bool is_last_step = false); private: // the list of registered bubble factories
diff --git a/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views.cc b/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views.cc index bfd4ee91..30256c8 100644 --- a/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views.cc +++ b/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views.cc
@@ -17,6 +17,12 @@ namespace autofill { +namespace { +// The delay before dismissing the dialog after the progress throber shows the +// checkmark. This delay is for users to identify the status change. +constexpr int kDelayBeforeDismissingDialogInSeconds = 1; +} // namespace + AutofillProgressDialogViews::AutofillProgressDialogViews( AutofillProgressDialogController* controller) : controller_(controller) { @@ -61,22 +67,23 @@ return dialog_view; } -void AutofillProgressDialogViews::Dismiss() { - if (controller_) { - controller_->OnDismissed(); - controller_ = nullptr; +void AutofillProgressDialogViews::Dismiss( + bool show_confirmation_before_closing) { + // If |show_confirmation_before_closing| is true, show the confirmation and + // close the widget with a delay. + if (show_confirmation_before_closing) { + label_->SetText(controller_->GetConfirmationMessage()); + progress_throbber_->SetChecked(true); + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&AutofillProgressDialogViews::CloseWidget, + weak_ptr_factory_.GetWeakPtr()), + base::Seconds(kDelayBeforeDismissingDialogInSeconds)); + return; } - GetWidget()->CloseWithReason(views::Widget::ClosedReason::kUnspecified); -} -void AutofillProgressDialogViews::ShowConfirmation() { - label_->SetText(controller_->GetConfirmationMessage()); - progress_throbber_->SetChecked(true); - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&AutofillProgressDialogViews::Dismiss, - weak_ptr_factory_.GetWeakPtr()), - base::Seconds(1)); + // Otherwise close the widget directly. + CloseWidget(); } void AutofillProgressDialogViews::AddedToWidget() { @@ -98,4 +105,12 @@ return controller_->GetTitle(); } +void AutofillProgressDialogViews::CloseWidget() { + if (controller_) { + controller_->OnDismissed(); + controller_ = nullptr; + } + GetWidget()->CloseWithReason(views::Widget::ClosedReason::kUnspecified); +} + } // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views.h b/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views.h index 91c7308..89a3259c 100644 --- a/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views.h +++ b/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views.h
@@ -27,8 +27,7 @@ ~AutofillProgressDialogViews() override; // AutofillProgressDialogView: - void Dismiss() override; - void ShowConfirmation() override; + void Dismiss(bool show_confirmation_before_closing) override; // DialogDelegate: void AddedToWidget() override; @@ -36,6 +35,9 @@ std::u16string GetWindowTitle() const override; private: + // Close the widget of this view, and notify controller. + void CloseWidget(); + AutofillProgressDialogController* controller_ = nullptr; views::Label* label_ = nullptr; views::Throbber* progress_throbber_ = nullptr;
diff --git a/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views_browsertest.cc b/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views_browsertest.cc index 3b1824c..bbf1635 100644 --- a/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views_browsertest.cc +++ b/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views_browsertest.cc
@@ -28,7 +28,9 @@ browser()->tab_strip_model()->GetActiveWebContents()); } - void ShowUi(const std::string& name) override { controller()->ShowDialog(); } + void ShowUi(const std::string& name) override { + controller()->ShowDialog(base::DoNothing()); + } AutofillProgressDialogViews* GetDialogViews() { DCHECK(controller());
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index bd32df2..879e349 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -344,8 +344,7 @@ params.types_enabled.push_back(PageActionIconType::kSharingHub); } #else - if (base::FeatureList::IsEnabled(sharing_hub::kSharingHubDesktopOmnibox) && - !is_popup_mode_) + if (sharing_hub::SharingHubOmniboxEnabled(profile_) && !is_popup_mode_) params.types_enabled.push_back(PageActionIconType::kSharingHub); #endif }
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.cc b/chrome/browser/ui/views/select_file_dialog_extension.cc index bdfa062..576d28f 100644 --- a/chrome/browser/ui/views/select_file_dialog_extension.cc +++ b/chrome/browser/ui/views/select_file_dialog_extension.cc
@@ -10,7 +10,7 @@ #include <utility> #include "ash/constants/ash_features.h" -#include "ash/public/cpp/capture_mode/capture_mode_api.h" +#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/tablet_mode.h" #include "base/bind.h" #include "base/callback.h" @@ -48,6 +48,7 @@ #include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/native_app_window.h" #include "extensions/browser/extension_system.h" +#include "ui/aura/window.h" #include "ui/base/base_window.h" #include "ui/gfx/color_palette.h" #include "ui/shell_dialogs/select_file_policy.h" @@ -442,8 +443,21 @@ // The web contents to associate the dialog with. content::WebContents* web_contents = nullptr; + // The folder selection dialog created for capture mode should never be + // parented to a browser window (if one exists). https://crbug.com/1258842. + const bool is_for_capture_mode = + owner.window && + owner.window->GetId() == + ash::kShellWindowId_CaptureModeFolderSelectionDialogOwner; + + const bool skip_finding_browser = is_for_capture_mode || + owner.android_task_id.has_value() || + owner.lacros_window_id.has_value(); + + can_resize_ = !ash::TabletMode::IsInTabletMode() && !is_for_capture_mode; + // Obtain BaseWindow and WebContents if the owner window is browser. - if (!owner.android_task_id.has_value() && !owner.lacros_window_id.has_value()) + if (!skip_finding_browser) FindRuntimeContext(owner.window, &base_window, &web_contents); if (web_contents) @@ -475,11 +489,6 @@ gfx::NativeWindow parent_window = base_window ? base_window->GetNativeWindow() : owner.window; -#if BUILDFLAG(IS_CHROMEOS_ASH) - can_resize_ = - !ash::TabletMode::IsInTabletMode() && !ash::IsCaptureModeSessionActive(); -#endif - if (ash::features::IsFileManagerSwaEnabled()) { // SystemFilesAppDialogDelegate is a self-deleting class that calls the // delete operator once the dialog for which it was created has been closed.
diff --git a/chrome/browser/ui/views/toolbar/app_menu.cc b/chrome/browser/ui/views/toolbar/app_menu.cc index 4a0cf37..3e71f202 100644 --- a/chrome/browser/ui/views/toolbar/app_menu.cc +++ b/chrome/browser/ui/views/toolbar/app_menu.cc
@@ -984,11 +984,8 @@ if (command_id == IDC_MORE_TOOLS_MENU) return true; - if (command_id == IDC_SHARING_HUB_MENU) { - DCHECK( - base::FeatureList::IsEnabled(sharing_hub::kSharingHubDesktopAppMenu)); + if (command_id == IDC_SHARING_HUB_MENU) return true; - } // The items representing the cut menu (cut/copy/paste), zoom menu // (increment/decrement/reset) and extension toolbar view are always enabled.
diff --git a/chrome/browser/ui/views/user_education/feature_promo_bubble_view.h b/chrome/browser/ui/views/user_education/feature_promo_bubble_view.h index 028babc..709e4e9 100644 --- a/chrome/browser/ui/views/user_education/feature_promo_bubble_view.h +++ b/chrome/browser/ui/views/user_education/feature_promo_bubble_view.h
@@ -89,9 +89,11 @@ absl::optional<base::TimeDelta> timeout_after_interaction; // Used to call feature specific logic on dismiss. + // (TODO) dpenning: move to using a OnceClosure. absl::optional<base::RepeatingClosure> dismiss_callback; // Used to call feature specific logic on timeout. + // (TODO) dpenning: move to using a OnceClosure. base::RepeatingClosure timeout_callback; }; @@ -138,6 +140,8 @@ base::TimeDelta timeout_after_interaction_; base::OneShotTimer auto_close_timer_; + + // (TODO) dpenning: move to using a OnceClosure. base::RepeatingClosure timeout_callback_; };
diff --git a/chrome/browser/ui/views/user_education/tutorial_bubble_factory_views.cc b/chrome/browser/ui/views/user_education/tutorial_bubble_factory_views.cc index 59147d6..b55f7b9 100644 --- a/chrome/browser/ui/views/user_education/tutorial_bubble_factory_views.cc +++ b/chrome/browser/ui/views/user_education/tutorial_bubble_factory_views.cc
@@ -46,6 +46,7 @@ absl::optional<std::u16string> body_text, TutorialDescription::Step::Arrow arrow, absl::optional<std::pair<int, int>> progress, + base::RepeatingClosure abort_callback, bool is_last_step) { if (!element->IsA<views::TrackedElementViews>()) return nullptr; @@ -98,6 +99,11 @@ params.timeout_after_interaction = is_last_step ? kDelayWithInteraction : kDelayZero; + if (abort_callback) { + params.has_close_button = true; + params.dismiss_callback = abort_callback; + } + return std::make_unique<TutorialBubbleViews>( owner_impl->ShowBubble(std::move(params), base::BindOnce([] {}))); }
diff --git a/chrome/browser/ui/views/user_education/tutorial_bubble_factory_views.h b/chrome/browser/ui/views/user_education/tutorial_bubble_factory_views.h index a929281..dbdb7b0f 100644 --- a/chrome/browser/ui/views/user_education/tutorial_bubble_factory_views.h +++ b/chrome/browser/ui/views/user_education/tutorial_bubble_factory_views.h
@@ -30,7 +30,8 @@ absl::optional<std::u16string> body_text, TutorialDescription::Step::Arrow arrow, absl::optional<std::pair<int, int>> progress, - bool is_last_step) override; + base::RepeatingClosure abort_callback, + bool is_last_step = false) override; bool CanBuildBubbleForTrackedElement(ui::TrackedElement* element) override; };
diff --git a/chrome/browser/ui/webui/extensions/extensions_internals_source.cc b/chrome/browser/ui/webui/extensions/extensions_internals_source.cc index c57ea396..836be23 100644 --- a/chrome/browser/ui/webui/extensions/extensions_internals_source.cc +++ b/chrome/browser/ui/webui/extensions/extensions_internals_source.cc
@@ -160,10 +160,6 @@ } if (disable_reasons & extensions::disable_reason::DISABLE_BLOCKED_BY_POLICY) disable_reasons_value.Append("DISABLE_BLOCKED_BY_POLICY"); - if (disable_reasons & - extensions::disable_reason::DISABLE_REMOTELY_FOR_MALWARE) { - disable_reasons_value.Append("DISABLE_REMOTELY_FOR_MALWARE"); - } return disable_reasons_value; } // The JSON we generate looks like this:
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc index 5863f43..777be39 100644 --- a/chrome/browser/ui/webui/settings/about_handler.cc +++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -479,9 +479,10 @@ } std::u16string channel; - bool is_powerwash_allowed; - if (!args->GetString(0, &channel) || - !args->GetBoolean(1, &is_powerwash_allowed)) { + bool is_powerwash_allowed = false; + if (args->GetString(0, &channel) && args->GetList()[1].is_bool()) { + is_powerwash_allowed = args->GetList()[1].GetBool(); + } else { LOG(ERROR) << "Can't parse SetChannel() args"; return; }
diff --git a/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc b/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc index 3efe0ec..64d4778 100644 --- a/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc +++ b/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc
@@ -204,7 +204,8 @@ void ChromeCleanupHandler::HandleStartScanning(const base::ListValue* args) { CHECK_EQ(1U, args->GetList().size()); bool allow_logs_upload = false; - args->GetBoolean(0, &allow_logs_upload); + if (args->GetList()[0].is_bool()) + allow_logs_upload = args->GetList()[0].GetBool(); // If this operation is not allowed the UI should be disabled. CHECK(controller_->IsAllowedByPolicy()); @@ -230,7 +231,8 @@ void ChromeCleanupHandler::HandleStartCleanup(const base::ListValue* args) { CHECK_EQ(1U, args->GetList().size()); bool allow_logs_upload = false; - args->GetBoolean(0, &allow_logs_upload); + if (args->GetList()[0].is_bool()) + allow_logs_upload = args->GetList()[0].GetBool(); // The state is propagated to all open tabs and should be consistent. DCHECK_EQ(controller_->logs_enabled(profile_), allow_logs_upload); @@ -251,7 +253,8 @@ const base::ListValue* args) { CHECK_EQ(1U, args->GetList().size()); bool details_section_visible = false; - args->GetBoolean(0, &details_section_visible); + if (args->GetList()[0].is_bool()) + details_section_visible = args->GetList()[0].GetBool(); if (details_section_visible) { base::RecordAction(
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc index 552d6cb..9f1bce8 100644 --- a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
@@ -98,16 +98,18 @@ void AccessibilityHandler::HandleSetStartupSoundEnabled( const base::ListValue* args) { DCHECK_EQ(1U, args->GetList().size()); - bool enabled; - args->GetBoolean(0, &enabled); + bool enabled = false; + if (args->GetList()[0].is_bool()) + enabled = args->GetList()[0].GetBool(); AccessibilityManager::Get()->SetStartupSoundEnabled(enabled); } void AccessibilityHandler::HandleRecordSelectedShowShelfNavigationButtonsValue( const base::ListValue* args) { DCHECK_EQ(1U, args->GetList().size()); - bool enabled; - args->GetBoolean(0, &enabled); + bool enabled = false; + if (args->GetList()[0].is_bool()) + enabled = args->GetList()[0].GetBool(); a11y_nav_buttons_toggle_metrics_reporter_timer_.Start( FROM_HERE, base::Seconds(10),
diff --git a/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc b/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc index ddaa8ca..8c4a8bb 100644 --- a/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc
@@ -108,7 +108,8 @@ void AndroidAppsHandler::ShowAndroidAppsSettings(const base::ListValue* args) { CHECK_EQ(1U, args->GetList().size()); bool activated_from_keyboard = false; - args->GetBoolean(0, &activated_from_keyboard); + if (args->GetList()[0].is_bool()) + activated_from_keyboard = args->GetList()[0].GetBool(); int flags = activated_from_keyboard ? ui::EF_NONE : ui::EF_LEFT_MOUSE_BUTTON; app_service_proxy_->Launch(
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc index 9543bdf..62a907c0 100644 --- a/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc
@@ -138,7 +138,8 @@ void StylusHandler::HandleSetPreferredNoteTakingAppEnabledOnLockScreen( const base::ListValue* args) { bool enabled = false; - CHECK(args->GetBoolean(0, &enabled)); + CHECK(args->GetList()[0].is_bool()); + enabled = args->GetList()[0].GetBool(); NoteTakingHelper::Get()->SetPreferredAppEnabledOnLockScreen( Profile::FromWebUI(web_ui()), enabled);
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc index 7c084ad..214076d 100644 --- a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc
@@ -351,7 +351,8 @@ void MultideviceHandler::HandleSetSmartLockSignInEnabled( const base::ListValue* args) { bool enabled = false; - CHECK(args->GetBoolean(0, &enabled)); + if (args->GetList()[0].is_bool()) + enabled = args->GetList()[0].GetBool(); std::string auth_token; bool auth_token_present = args->GetString(1, &auth_token);
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index c649d95d8..5d3936c 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -613,7 +613,8 @@ void PeopleHandler::HandleSignout(const base::ListValue* args) { bool delete_profile = false; - args->GetBoolean(0, &delete_profile); + if (args->GetList()[0].is_bool()) + delete_profile = args->GetList()[0].GetBool(); base::FilePath profile_path = profile_->GetPath(); if (!signin_util::IsUserSignoutAllowedForProfile(profile_)) {
diff --git a/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc b/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc index 9515ab3..80c2efe 100644 --- a/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc +++ b/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc
@@ -190,7 +190,8 @@ void ProtocolHandlersHandler::HandleSetHandlersEnabled( const base::ListValue* args) { bool enabled = true; - CHECK(args->GetBoolean(0, &enabled)); + CHECK(args->GetList()[0].is_bool()); + enabled = args->GetList()[0].GetBool(); if (enabled) GetProtocolHandlerRegistry()->Enable(); else
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.cc b/chrome/browser/ui/webui/settings/reset_settings_handler.cc index 6449021c..72f8d4e 100644 --- a/chrome/browser/ui/webui/settings/reset_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
@@ -138,7 +138,8 @@ std::string callback_id; CHECK(args->GetString(0, &callback_id)); bool send_settings = false; - CHECK(args->GetBoolean(1, &send_settings)); + CHECK(args->GetList()[1].is_bool()); + send_settings = args->GetList()[1].GetBool(); std::string request_origin_string; CHECK(args->GetString(2, &request_origin_string)); reset_report::ChromeResetReport::ResetRequestOrigin request_origin =
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc index d6518df..8223325 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -1127,8 +1127,8 @@ CHECK(args->GetString(1, &secondary_pattern_string)); std::string type; CHECK(args->GetString(2, &type)); - bool incognito; - CHECK(args->GetBoolean(3, &incognito)); + CHECK(args->GetList()[3].is_bool()); + bool incognito = args->GetList()[3].GetBool(); ContentSettingsType content_type = site_settings::ContentSettingsTypeFromGroupName(type); @@ -1193,8 +1193,8 @@ CHECK(args->GetString(2, &type)); std::string value; CHECK(args->GetString(3, &value)); - bool incognito; - CHECK(args->GetBoolean(4, &incognito)); + CHECK(args->GetList()[4].is_bool()); + bool incognito = args->GetList()[4].GetBool(); ContentSettingsType content_type = site_settings::ContentSettingsTypeFromGroupName(type); @@ -1458,8 +1458,8 @@ return; CHECK_EQ(1U, args->GetList().size()); - bool value; - CHECK(args->GetBoolean(0, &value)); + CHECK(args->GetList()[0].is_bool()); + bool value = args->GetList()[0].GetBool(); profile_->GetPrefs()->SetBoolean(prefs::kBlockAutoplayEnabled, value); }
diff --git a/chrome/browser/ui/webui/webapks/webapks_handler.cc b/chrome/browser/ui/webui/webapks/webapks_handler.cc index 248c458..bb2ca76 100644 --- a/chrome/browser/ui/webui/webapks/webapks_handler.cc +++ b/chrome/browser/ui/webui/webapks/webapks_handler.cc
@@ -11,7 +11,7 @@ #include "chrome/browser/android/shortcut_helper.h" #include "content/public/browser/web_ui.h" #include "third_party/blink/public/common/manifest/manifest_util.h" -#include "ui/android/color_helpers.h" +#include "ui/android/color_utils_android.h" #include "ui/gfx/color_utils.h" WebApksHandler::WebApksHandler()
diff --git a/chrome/browser/web_applications/web_app_constants.h b/chrome/browser/web_applications/web_app_constants.h index 6f1764a2..11c5be6 100644 --- a/chrome/browser/web_applications/web_app_constants.h +++ b/chrome/browser/web_applications/web_app_constants.h
@@ -286,9 +286,15 @@ // A result how `WebAppIconDownloader` processed the list of icon urls. enum class IconsDownloadedResult { - // Icon downloading requests fulfilled. + // At least one (or all if `WebAppIconDownloader::FailAllIfAnyFail()` + // was called) icon urls were downloaded into the given `icons_map`. kCompleted, - // All icon downloading requests cancelled. + // There was an error downloading the icons, and `icons_map` is empty. + // Errors can include: + // * All icon downloads failed. + // * At least one icon download failed and + // `WebAppIconDownloader::FailAllIfAnyFail()` was called. + // * Unexpected navigations or state changes on the `web_contents`. kCancelled, };
diff --git a/chrome/browser/web_applications/web_app_icon_downloader.cc b/chrome/browser/web_applications/web_app_icon_downloader.cc index 5c9a3eb..10b8ded 100644 --- a/chrome/browser/web_applications/web_app_icon_downloader.cc +++ b/chrome/browser/web_applications/web_app_icon_downloader.cc
@@ -109,7 +109,7 @@ const GURL& image_url, const std::vector<SkBitmap>& bitmaps, const std::vector<gfx::Size>& original_bitmap_sizes) { - // Request may have been canceled by DidFinishNavigation(). + // Request may have been canceled by PrimaryPageChanged(). if (in_progress_requests_.erase(id) == 0) return; @@ -144,7 +144,6 @@ CompleteCallback(); } -// content::WebContentsObserver overrides: void WebAppIconDownloader::PrimaryPageChanged(content::Page& page) { CancelDownloads(); }
diff --git a/chrome/browser/web_applications/web_app_icon_downloader.h b/chrome/browser/web_applications/web_app_icon_downloader.h index cdf3479e..3bf69ebf 100644 --- a/chrome/browser/web_applications/web_app_icon_downloader.h +++ b/chrome/browser/web_applications/web_app_icon_downloader.h
@@ -86,7 +86,7 @@ const std::vector<SkBitmap>& bitmaps, const std::vector<gfx::Size>& original_bitmap_sizes); - // content::WebContentsObserver overrides: + // content::WebContentsObserver: void PrimaryPageChanged(content::Page& page) override; void DidUpdateFaviconURL( content::RenderFrameHost* rfh,
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 24e33fa..1875f07 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1634050758-81ac571898085b700004c0e280809306718f9da2.profdata +chrome-win32-main-1634072245-4c09bdcbc793607463f7ca39634458b6e4988617.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 0bd63ad..103b759 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1634050758-7b5caff70f9b52b0f1ba9a90b5545e65e5dac729.profdata +chrome-win64-main-1634072245-1b1c585a799cb124650c63f35c2823e95a980cc8.profdata
diff --git a/chrome/common/extensions/api/cryptotoken_private.idl b/chrome/common/extensions/api/cryptotoken_private.idl index 1fa079c..3b61724 100644 --- a/chrome/common/extensions/api/cryptotoken_private.idl +++ b/chrome/common/extensions/api/cryptotoken_private.idl
@@ -19,9 +19,12 @@ DOMString appId; // The origin of the caller. DOMString origin; - // Identifies the tab in which the registration is occuring so that any + // Identifies the tab in which the request is occuring so that any // permissions prompt is correctly located. long tabId; + // Identifies the frame in which the frame is occuring. Required + // but ignored for `canAppIdGetAttestation`. + long frameId; }; interface Functions {
diff --git a/chrome/renderer/extensions/extension_hooks_delegate.cc b/chrome/renderer/extensions/extension_hooks_delegate.cc index 4063e16..520d643 100644 --- a/chrome/renderer/extensions/extension_hooks_delegate.cc +++ b/chrome/renderer/extensions/extension_hooks_delegate.cc
@@ -228,8 +228,10 @@ } v8::Local<v8::Value> v8_message = arguments[1]; + std::unique_ptr<Message> message = messaging_util::MessageFromV8( - script_context->v8_context(), v8_message, &error); + script_context->v8_context(), v8_message, + messaging_util::GetSerializationFormat(*script_context), &error); if (!message) { RequestResult result(RequestResult::INVALID_INVOCATION); result.error = std::move(error);
diff --git a/chrome/renderer/extensions/extension_hooks_delegate_unittest.cc b/chrome/renderer/extensions/extension_hooks_delegate_unittest.cc index fa3a666c..ab27f50 100644 --- a/chrome/renderer/extensions/extension_hooks_delegate_unittest.cc +++ b/chrome/renderer/extensions/extension_hooks_delegate_unittest.cc
@@ -7,6 +7,7 @@ #include "base/strings/stringprintf.h" #include "content/public/common/child_process_host.h" #include "extensions/common/api/messaging/messaging_endpoint.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/extension_builder.h" #include "extensions/common/extension_messages.h" #include "extensions/common/value_builder.h" @@ -178,7 +179,7 @@ const std::string kChannel = "chrome.extension.sendRequest"; base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id(other_context_id, 0, false); + const PortId port_id(other_context_id, 0, false, SerializationFormat::kJson); ExtensionMsg_TabConnectionInfo tab_connection_info; tab_connection_info.frame_id = 0; @@ -207,8 +208,9 @@ // Post the message to the receiver. Since the receiver doesn't respond, the // channel should remain open. - messaging_service()->DeliverMessage(script_context_set(), port_id, - Message("\"message\"", false), nullptr); + messaging_service()->DeliverMessage( + script_context_set(), port_id, + Message("\"message\"", SerializationFormat::kJson, false), nullptr); ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender()); EXPECT_TRUE( messaging_service()->HasPortForTesting(script_context(), port_id));
diff --git a/chrome/renderer/extensions/tabs_hooks_delegate.cc b/chrome/renderer/extensions/tabs_hooks_delegate.cc index c2b3bfd..3bcf0615 100644 --- a/chrome/renderer/extensions/tabs_hooks_delegate.cc +++ b/chrome/renderer/extensions/tabs_hooks_delegate.cc
@@ -84,8 +84,10 @@ int tab_id = messaging_util::ExtractIntegerId(arguments[0]); v8::Local<v8::Value> v8_message = arguments[1]; std::string error; + std::unique_ptr<Message> message = messaging_util::MessageFromV8( - script_context->v8_context(), v8_message, &error); + script_context->v8_context(), v8_message, + messaging_util::GetSerializationFormat(*script_context), &error); if (!message) { RequestResult result(RequestResult::INVALID_INVOCATION); result.error = std::move(error); @@ -119,8 +121,10 @@ v8::Local<v8::Value> v8_message = arguments[1]; DCHECK(!v8_message.IsEmpty()); std::string error; + std::unique_ptr<Message> message = messaging_util::MessageFromV8( - script_context->v8_context(), v8_message, &error); + script_context->v8_context(), v8_message, + messaging_util::GetSerializationFormat(*script_context), &error); if (!message) { RequestResult result(RequestResult::INVALID_INVOCATION); result.error = std::move(error); @@ -154,7 +158,8 @@ gin::Handle<GinPort> port = messaging_service_->Connect( script_context, MessageTarget::ForTab(tab_id, options.frame_id), - options.channel_name); + options.channel_name, + messaging_util::GetSerializationFormat(*script_context)); DCHECK(!port.IsEmpty()); RequestResult result(RequestResult::HANDLED);
diff --git a/chrome/services/sharing/nearby/nearby_connections_unittest.cc b/chrome/services/sharing/nearby/nearby_connections_unittest.cc index ef9b8cb..f491c3ca 100644 --- a/chrome/services/sharing/nearby/nearby_connections_unittest.cc +++ b/chrome/services/sharing/nearby/nearby_connections_unittest.cc
@@ -1000,8 +1000,7 @@ initiated_run_loop.Quit(); }); - ClientProxy* client_proxy = - StartAdvertising(fake_connection_life_cycle_listener, endpoint_data); + StartAdvertising(fake_connection_life_cycle_listener, endpoint_data); initiated_run_loop.Run(); base::RunLoop accepted_run_loop; @@ -1012,8 +1011,7 @@ }); FakePayloadListener fake_payload_listener; - client_proxy = - AcceptConnection(fake_payload_listener, endpoint_data.remote_endpoint_id); + AcceptConnection(fake_payload_listener, endpoint_data.remote_endpoint_id); accepted_run_loop.Run(); }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/webapps/WebApkIntentDataProviderBuilder.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/webapps/WebApkIntentDataProviderBuilder.java index d5056df..0b179ae 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/webapps/WebApkIntentDataProviderBuilder.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/webapps/WebApkIntentDataProviderBuilder.java
@@ -9,11 +9,11 @@ import org.chromium.blink.mojom.DisplayMode; import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider; -import org.chromium.chrome.browser.browserservices.intents.WebappConstants; import org.chromium.chrome.browser.webapps.WebApkIntentDataProviderFactory; import org.chromium.components.webapps.ShortcutSource; import org.chromium.components.webapps.WebApkDistributor; import org.chromium.device.mojom.ScreenOrientationLockType; +import org.chromium.ui.util.ColorUtils; import java.util.ArrayList; import java.util.HashMap; @@ -54,8 +54,7 @@ public BrowserServicesIntentDataProvider build() { return WebApkIntentDataProviderFactory.create(new Intent(), mUrl, mScope, null, null, null, null, mDisplayMode, ScreenOrientationLockType.DEFAULT, ShortcutSource.UNKNOWN, - WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING, - WebappConstants.MANIFEST_COLOR_INVALID_OR_MISSING, Color.WHITE, + ColorUtils.INVALID_COLOR, ColorUtils.INVALID_COLOR, Color.WHITE, false /* isPrimaryIconMaskable */, false /* isSplashIconMaskable */, mWebApkPackageName, /* shellApkVersion */ 1, mManifestUrl, mUrl, WebApkDistributor.BROWSER,
diff --git a/chrome/test/base/testing_profile_manager.cc b/chrome/test/base/testing_profile_manager.cc index 7ce2420c..de4379c 100644 --- a/chrome/test/base/testing_profile_manager.cc +++ b/chrome/test/base/testing_profile_manager.cc
@@ -204,6 +204,17 @@ void TestingProfileManager::DeleteAllTestingProfiles() { DCHECK(called_set_up_); + + ProfileAttributesStorage& storage = + profile_manager_->GetProfileAttributesStorage(); + for (auto& name_profile_pair : testing_profiles_) { + TestingProfile* profile = name_profile_pair.second; + if (profile->IsGuestSession() || profile->IsSystemProfile()) { + // Guest and System profiles aren't added to Storage. + continue; + } + storage.RemoveProfile(profile->GetPath()); + } profile_manager_->profiles_info_.clear(); }
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 8f81e4c71..a3bb9bc5 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -11094,6 +11094,12 @@ "ReportUploadFrequency": { "reason_for_missing_test": "Maps into CrosSettings" }, + "ReportDeviceNetworkTelemetryCollectionRateMs": { + "reason_for_missing_test": "Maps into CrosSettings" + }, + "ReportDeviceNetworkTelemetryEventCheckingRateMs": { + "reason_for_missing_test": "Maps into CrosSettings" + }, "DeviceAllowNewUsers": { "reason_for_missing_test": "Maps into CrosSettings" },
diff --git a/chrome/test/data/updater/Keystone.ticketstore b/chrome/test/data/updater/Keystone.ticketstore new file mode 100644 index 0000000..ceab3f7 --- /dev/null +++ b/chrome/test/data/updater/Keystone.ticketstore Binary files differ
diff --git a/chrome/test/data/webrtc/webrtc_getdisplaymedia_test.html b/chrome/test/data/webrtc/webrtc_getdisplaymedia_test.html index 66787c32..ea2ee12 100644 --- a/chrome/test/data/webrtc/webrtc_getdisplaymedia_test.html +++ b/chrome/test/data/webrtc/webrtc_getdisplaymedia_test.html
@@ -9,14 +9,17 @@ 'use strict'; var settings; var video_track; - var has_audio_track = false; + var audio_track; + var stored_media_stream; function handleSuccess(stream) { - has_audio_track = stream.getAudioTracks().length == 1; settings = stream.getVideoTracks()[0].getSettings(); var video = document.querySelector('video'); video.srcObject = stream; video_track = stream.getVideoTracks()[0]; + if (stream.getAudioTracks().length > 0) { + audio_track = stream.getAudioTracks()[0]; + } video.play(); returnToTest("capture-success"); } @@ -38,7 +41,28 @@ } function hasAudioTrack() { - returnToTest(has_audio_track ? "true" : "false"); + returnToTest(`${!!audio_track}`); + } + + function getVideoTrackType() { + if (!video_track) { + returnToTest("error-no-video-track"); + } + returnToTest(video_track.constructor.name); + } + + function getVideoCloneTrackType() { + if (!video_track) { + returnToTest("error-no-video-track-to-clone"); + } + returnToTest(video_track.clone().constructor.name); + } + + function getAudioTrackType() { + if (!audio_track) { + returnToTest("error-no-audio-track"); + } + returnToTest(audio_track.constructor.name); } function getDisplaySurfaceSetting() { @@ -87,10 +111,6 @@ returnToTest("ended"); } } - - // function readLastResultFromEmbedded() { - // // Blocks until the result is reported by the embedded page. - // } </script> </head> <body>
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.js index db564d6..6b8b741 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.js +++ b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.js
@@ -309,6 +309,33 @@ assertEquals(']', actualAccelerator.key_display); }); + test('RemoveAccelerator', async () => { + await flushTasks(); + + // Open dialog for first accelerator in View Desk subsection. + await openDialogForAcceleratorInSubsection_(/*View Desk*/ 1); + let editDialog = page.shadowRoot.querySelector('#editDialog'); + assertTrue(!!editDialog); + + // Grab the first accelerator from Virtual Desks subsection. + let acceleratorList = editDialog.shadowRoot.querySelector('cr-dialog') + .querySelectorAll('accelerator-edit-view'); + assertEquals(1, acceleratorList.length); + const editView = acceleratorList[0]; + + // Click on remove button. + editView.shadowRoot.querySelector('#deleteButton').click(); + + await flushTasks(); + + // Requery the accelerator elements. + acceleratorList = editDialog.shadowRoot.querySelector('cr-dialog') + .querySelectorAll('accelerator-edit-view'); + + // Expect that the accelerator has now been removed. + assertEquals(0, acceleratorList.length); + }); + suite('FakeMojoProviderTest', () => { test('SettingGettingTestProvider', () => { // TODO(zentaro): Replace with fake when built.
diff --git a/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_base_page_test.js b/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_base_page_test.js index b8d32dd9..657b033 100644 --- a/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_base_page_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_base_page_test.js
@@ -49,12 +49,19 @@ flush(); } - test('Title is shown', function() { + test('Title and loading indicator are shown', function() { const title = bluetoothBasePage.shadowRoot.querySelector('#title'); assertTrue(!!title); assertEquals( bluetoothBasePage.i18n('bluetoothPairNewDevice'), title.textContent.trim()); + + const getProgress = () => + bluetoothBasePage.shadowRoot.querySelector('paper-progress'); + assertFalse(!!getProgress()); + bluetoothBasePage.showScanProgress = true; + flush(); + assertTrue(!!getProgress()); }); test('Button states', function() {
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn index 2f2761f..63953b1 100644 --- a/chrome/updater/BUILD.gn +++ b/chrome/updater/BUILD.gn
@@ -224,6 +224,7 @@ "//chrome/updater/win:app_install_controller", "//chrome/updater/win/ui", ] + sources += [ "activity_impl_win.cc", "app/app_install_win.cc", @@ -235,6 +236,7 @@ "app/server/win/server.h", "app/server/win/service_main.cc", "app/server/win/service_main.h", + "app/server/win/wrl_classes.cc", "device_management/dm_storage_win.cc", "lib_util_win.cc", "policy/win/group_policy_manager.cc", @@ -273,7 +275,6 @@ "win/win_constants.h", "win/win_util.cc", "win/win_util.h", - "win/wrl_module.h", ] deps += [ "//chrome/installer/util:with_no_strings", @@ -548,6 +549,9 @@ if (is_mac) { sources += [ + "mac/keystone/ks_tickets.h", + "mac/keystone/ks_tickets.mm", + "mac/keystone/ks_tickets_unittest.mm", "mac/keystone/ksadmin_unittest.cc", "mac/net/network_unittest.cc", "mac/scoped_xpc_service_mock.h", @@ -573,6 +577,7 @@ ] data = [ + "//chrome/test/data/updater/Keystone.ticketstore", "//chrome/test/data/updater/updater_setup_test_dmg.dmg", "//chrome/test/data/updater/updater_qualification_app_dmg.crx", ]
diff --git a/chrome/updater/app/server/win/server.cc b/chrome/updater/app/server/win/server.cc index c663f36..3c93976 100644 --- a/chrome/updater/app/server/win/server.cc +++ b/chrome/updater/app/server/win/server.cc
@@ -4,10 +4,11 @@ #include "chrome/updater/app/server/win/server.h" -#include <wrl/implements.h> +#include <wrl/module.h> #include <algorithm> #include <memory> +#include <string> #include <utility> #include "base/bind.h" @@ -17,6 +18,8 @@ #include "base/files/file_path.h" #include "base/logging.h" #include "base/memory/ref_counted.h" +#include "base/strings/strcat.h" +#include "base/strings/utf_string_conversions.h" #include "base/system/sys_info.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" @@ -36,7 +39,6 @@ #include "chrome/updater/win/setup/setup_util.h" #include "chrome/updater/win/setup/uninstall.h" #include "chrome/updater/win/win_constants.h" -#include "chrome/updater/win/wrl_module.h" #include "components/prefs/pref_service.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -47,6 +49,18 @@ return base::CommandLine::ForCurrentProcess()->HasSwitch(kComServiceSwitch); } +std::wstring GetCOMGroup(const std::wstring& prefix, UpdaterScope scope) { + return base::StrCat({prefix, base::ASCIIToWide(UpdaterScopeToString(scope))}); +} + +std::wstring COMGroup(UpdaterScope scope) { + return GetCOMGroup(L"Active", scope); +} + +std::wstring COMGroupInternal(UpdaterScope scope) { + return GetCOMGroup(L"Internal", scope); +} + } // namespace // Returns a leaky singleton of the App instance. @@ -84,99 +98,26 @@ } HRESULT ComServerApp::RegisterClassObjects() { - Microsoft::WRL::ComPtr<IUnknown> factory; - unsigned int flags = Microsoft::WRL::ModuleType::OutOfProc; - - HRESULT hr = Microsoft::WRL::Details::CreateClassFactory< - Microsoft::WRL::SimpleClassFactory<UpdaterImpl>>( - &flags, nullptr, __uuidof(IClassFactory), &factory); - if (FAILED(hr)) { - LOG(ERROR) << "Factory creation for UpdaterImpl failed; hr: " << hr; - return hr; - } - - Microsoft::WRL::ComPtr<IClassFactory> class_factory_updater; - hr = factory.As(&class_factory_updater); - if (FAILED(hr)) { - LOG(ERROR) << "IClassFactory object creation failed; hr: " << hr; - return hr; - } - factory.Reset(); - - hr = Microsoft::WRL::Details::CreateClassFactory< - Microsoft::WRL::SimpleClassFactory<LegacyOnDemandImpl>>( - &flags, nullptr, __uuidof(IClassFactory), &factory); - if (FAILED(hr)) { - LOG(ERROR) << "Factory creation for LegacyOnDemandImpl failed; hr: " << hr; - return hr; - } - - Microsoft::WRL::ComPtr<IClassFactory> class_factory_legacy_ondemand; - hr = factory.As(&class_factory_legacy_ondemand); - if (FAILED(hr)) { - LOG(ERROR) << "IClassFactory object creation failed; hr: " << hr; - return hr; - } - - // The pointer in this array is unowned. Do not release it. - IClassFactory* class_factories[] = {class_factory_updater.Get(), - class_factory_legacy_ondemand.Get()}; - std::vector<CLSID> class_ids = GetActiveServers(updater_scope()); - std::vector<DWORD> cookies(class_ids.size()); - hr = Microsoft::WRL::Module<Microsoft::WRL::OutOfProc>::GetModule() - .RegisterCOMObject(nullptr, &class_ids[0], class_factories, - &cookies[0], class_ids.size()); - if (FAILED(hr)) { - LOG(ERROR) << "RegisterCOMObject failed; hr: " << hr; - return hr; - } - - cookies.swap(cookies_); - return hr; + // Register COM class objects that are under either the ActiveSystem or the + // ActiveUser group. + // See wrl_classes.cc for details on the COM classes within the group. + return Microsoft::WRL::Module<Microsoft::WRL::OutOfProc>::GetModule() + .RegisterObjects(COMGroup(updater_scope()).c_str()); } HRESULT ComServerApp::RegisterInternalClassObjects() { - Microsoft::WRL::ComPtr<IUnknown> factory; - unsigned int flags = Microsoft::WRL::ModuleType::OutOfProc; - - HRESULT hr = Microsoft::WRL::Details::CreateClassFactory< - Microsoft::WRL::SimpleClassFactory<UpdaterInternalImpl>>( - &flags, nullptr, __uuidof(IClassFactory), &factory); - if (FAILED(hr)) { - LOG(ERROR) << "Factory creation for UpdaterInternalImpl failed; hr: " << hr; - return hr; - } - - Microsoft::WRL::ComPtr<IClassFactory> class_factory_updater_internal; - hr = factory.As(&class_factory_updater_internal); - if (FAILED(hr)) { - LOG(ERROR) << "IClassFactory object creation failed; hr: " << hr; - return hr; - } - factory.Reset(); - - // The pointer in this array is unowned. Do not release it. - IClassFactory* class_factories[] = {class_factory_updater_internal.Get()}; - std::vector<CLSID> class_ids = GetSideBySideServers(updater_scope()); - std::vector<DWORD> cookies(class_ids.size()); - hr = Microsoft::WRL::Module<Microsoft::WRL::OutOfProc>::GetModule() - .RegisterCOMObject(nullptr, &class_ids[0], class_factories, - &cookies[0], class_ids.size()); - if (FAILED(hr)) { - LOG(ERROR) << "RegisterCOMObject failed; hr: " << hr; - return hr; - } - - cookies.swap(cookies_); - return hr; + // Register COM class objects that are under either the InternalSystem or the + // InternalUser group. + // See wrl_classes.cc for details on the COM classes within the group. + return Microsoft::WRL::Module<Microsoft::WRL::OutOfProc>::GetModule() + .RegisterObjects(COMGroupInternal(updater_scope()).c_str()); } void ComServerApp::UnregisterClassObjects() { - auto& module = Microsoft::WRL::Module<Microsoft::WRL::OutOfProc>::GetModule(); const HRESULT hr = - module.UnregisterCOMObject(nullptr, cookies_.data(), cookies_.size()); - if (FAILED(hr)) - LOG(ERROR) << "UnregisterCOMObject failed; hr: " << hr; + Microsoft::WRL::Module<Microsoft::WRL::OutOfProc>::GetModule() + .UnregisterObjects(); + LOG_IF(ERROR, FAILED(hr)) << "UnregisterObjects failed; hr: " << hr; } void ComServerApp::CreateWRLModule() {
diff --git a/chrome/updater/app/server/win/server.h b/chrome/updater/app/server/win/server.h index fc78fba0..689b796 100644 --- a/chrome/updater/app/server/win/server.h +++ b/chrome/updater/app/server/win/server.h
@@ -7,8 +7,6 @@ #include <windows.h> -#include <vector> - #include "base/callback_forward.h" #include "base/check.h" #include "base/memory/scoped_refptr.h" @@ -94,9 +92,6 @@ // Handles COM setup and registration. void Start(base::OnceCallback<HRESULT()> register_callback); - // Identifier of registered class objects used for unregistration. - std::vector<DWORD> cookies_; - // While this object lives, COM can be used by all threads in the program. base::win::ScopedCOMInitializer com_initializer_;
diff --git a/chrome/updater/app/server/win/service_main.cc b/chrome/updater/app/server/win/service_main.cc index e2c2ffd..6cd814e 100644 --- a/chrome/updater/app/server/win/service_main.cc +++ b/chrome/updater/app/server/win/service_main.cc
@@ -6,6 +6,7 @@ #include <atlsecurity.h> #include <sddl.h> +#include <wrl/module.h> #include <string> #include <type_traits> @@ -21,7 +22,6 @@ #include "chrome/updater/constants.h" #include "chrome/updater/win/win_constants.h" #include "chrome/updater/win/win_util.h" -#include "chrome/updater/win/wrl_module.h" namespace updater {
diff --git a/chrome/updater/app/server/win/wrl_classes.cc b/chrome/updater/app/server/win/wrl_classes.cc new file mode 100644 index 0000000..334dfb8 --- /dev/null +++ b/chrome/updater/app/server/win/wrl_classes.cc
@@ -0,0 +1,60 @@ +// Copyright 2021 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 <wrl/module.h> + +#include "chrome/updater/app/server/win/com_classes.h" +#include "chrome/updater/app/server/win/com_classes_legacy.h" + +namespace updater { + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-braces" +#pragma clang diagnostic ignored "-Wc++98-compat-extra-semi" + +// CoCreatableClassWithFactoryEx takes three parameters, `className`, `factory`, +// and `serverName`: +// * `className` identifies the COM class from the IDL file, and not the +// corresponding C++ implementation class. +// * `factory` identifies the class factory that creates the COM object, and is +// typically Microsoft::WRL::SimpleClassFactory<>. +// * `serverName` is used below to group COM classes that need to be +// registered/unregistered together in a single process by using +// Microsoft::WRL::Module::RegisterObjects and +// Microsoft::WRL::Module::UnregisterObjects, respectively. +// +// Below, we are registering the following groups of COM objects: +// * ActiveSystem +// * ActiveUser +// * InternalSystem +// * InternalUser +CoCreatableClassWithFactoryEx(UpdaterSystemClass, + Microsoft::WRL::SimpleClassFactory<UpdaterImpl>, + ActiveSystem); +CoCreatableClassWithFactoryEx( + GoogleUpdate3WebSystemClass, + Microsoft::WRL::SimpleClassFactory<LegacyOnDemandImpl>, + ActiveSystem); + +CoCreatableClassWithFactoryEx(UpdaterUserClass, + Microsoft::WRL::SimpleClassFactory<UpdaterImpl>, + ActiveUser); +CoCreatableClassWithFactoryEx( + GoogleUpdate3WebUserClass, + Microsoft::WRL::SimpleClassFactory<LegacyOnDemandImpl>, + ActiveUser); + +CoCreatableClassWithFactoryEx( + UpdaterInternalSystemClass, + Microsoft::WRL::SimpleClassFactory<UpdaterInternalImpl>, + InternalSystem); + +CoCreatableClassWithFactoryEx( + UpdaterInternalUserClass, + Microsoft::WRL::SimpleClassFactory<UpdaterInternalImpl>, + InternalUser); + +#pragma clang diagnostic pop + +} // namespace updater
diff --git a/chrome/updater/mac/BUILD.gn b/chrome/updater/mac/BUILD.gn index 2ddd6b91..f8db594 100644 --- a/chrome/updater/mac/BUILD.gn +++ b/chrome/updater/mac/BUILD.gn
@@ -131,6 +131,8 @@ executable("ksadmin") { output_name = "ksadmin" sources = [ + "keystone/ks_tickets.h", + "keystone/ks_tickets.mm", "keystone/ksadmin.h", "keystone/ksadmin.mm", "keystone/ksadmin_main.cc",
diff --git a/chrome/updater/mac/keystone/ks_tickets.h b/chrome/updater/mac/keystone/ks_tickets.h new file mode 100644 index 0000000..a46d72a --- /dev/null +++ b/chrome/updater/mac/keystone/ks_tickets.h
@@ -0,0 +1,20 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_UPDATER_MAC_KEYSTONE_KS_TICKETS_H_ +#define CHROME_UPDATER_MAC_KEYSTONE_KS_TICKETS_H_ + +#import <Foundation/Foundation.h> + +@class KSPathExistenceChecker; + +// KSTicketStore holds a class method for reading an NSDictionary of NSString +// to KSTickets. +@interface KSTicketStore : NSObject + ++ (nullable NSDictionary*)readStoreWithPath:(nonnull NSString*)path; + +@end + +#endif // CHROME_UPDATER_MAC_KEYSTONE_KS_TICKETS_H_
diff --git a/chrome/updater/mac/keystone/ks_tickets.mm b/chrome/updater/mac/keystone/ks_tickets.mm new file mode 100644 index 0000000..42f75e1c --- /dev/null +++ b/chrome/updater/mac/keystone/ks_tickets.mm
@@ -0,0 +1,286 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "chrome/updater/mac/keystone/ks_tickets.h" + +#import <Foundation/Foundation.h> + +#include "base/logging.h" +#include "base/notreached.h" +#include "base/strings/sys_string_conversions.h" + +@interface KSPathExistenceChecker : NSObject <NSSecureCoding> { + @private + NSString* path_; +} +@end + +@interface KSTicket : NSObject <NSSecureCoding> +@end + +@implementation KSTicketStore + ++ (nullable NSDictionary*)readStoreWithPath:(nonnull NSString*)path { + if (![[NSFileManager defaultManager] fileExistsAtPath:path]) { + VLOG(0) << "Ticket store does not exist at " + << base::SysNSStringToUTF8(path); + return [NSDictionary dictionary]; + } + NSError* readError = nil; + NSData* storeData = [NSData dataWithContentsOfFile:path + options:0 // Use normal IO + error:&readError]; + if (!storeData) { + VLOG(0) << "Failed to decode ticket store at " + << base::SysNSStringToUTF8(path) << ": " << readError; + return nil; + } + if (![storeData length]) + return [NSDictionary dictionary]; + NSDictionary* store = nil; + @try { // Unarchiver can throw + NSKeyedUnarchiver* unpacker = + [[NSKeyedUnarchiver alloc] initForReadingWithData:storeData]; + unpacker.requiresSecureCoding = YES; + NSSet* classes = + [NSSet setWithObjects:[NSDictionary class], [KSTicket class], + [KSPathExistenceChecker class], [NSArray class], + [NSURL class], nil]; + store = [unpacker decodeObjectOfClasses:classes + forKey:NSKeyedArchiveRootObjectKey]; + } @catch (id e) { + VLOG(0) << base::SysNSStringToUTF8( + [NSString stringWithFormat:@"Ticket exception %@", e]); + return nil; + } + if (!store || ![store isKindOfClass:[NSDictionary class]]) { + VLOG(0) << "Ticket store is not a dictionary."; + return nil; + } + return store; +} + +@end + +@implementation KSPathExistenceChecker + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (void)dealloc { + [path_ release]; + [super dealloc]; +} + +- (id)initWithCoder:(NSCoder*)coder { + if ((self = [super init])) { + @try { + path_ = [[coder decodeObjectOfClass:[NSString class] + forKey:@"path"] retain]; + } @catch (id e) { + VLOG(0) << base::SysNSStringToUTF8( + [NSString stringWithFormat:@"Coder exception %@", e]); + return nil; + } + } + return self; +} + +- (void)encodeWithCoder:(NSCoder*)coder { + NOTREACHED() << "KSPathExistenceChecker::encodeWithCoder not implemented."; +} + +- (NSString*)description { + // Formatting must stay the same in ksadmin output. + return [NSString + stringWithFormat:@"<%@:0x222222222222 path=%@>", [self class], path_]; +} + +@end + +NSString* const kKSTicketCohortKey = @"Cohort"; +NSString* const kKSTicketCohortHintKey = @"CohortHint"; +NSString* const kKSTicketCohortNameKey = @"CohortName"; + +@implementation KSTicket { + @private + NSString* productID_; + NSString* version_; + KSPathExistenceChecker* existenceChecker_; + NSURL* serverURL_; + NSDate* creationDate_; + NSString* serverType_; + NSString* tag_; + NSString* tagPath_; + NSString* tagKey_; + NSString* brandPath_; + NSString* brandKey_; + NSString* versionPath_; + NSString* versionKey_; + NSString* cohort_; + NSString* cohortHint_; + NSString* cohortName_; + int32_t ticketVersion_; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +// Tries to obtain the server URL which may be NSURL or NSString object. +// Verifies the read objects and guarantees that the returned object is NSURL. +// The method may throw. +- (NSURL*)decodeServerURL:(NSCoder*)decoder { + id serverURL = [decoder decodeObjectOfClasses:[NSSet setWithArray:@[ + [NSString class], + [NSURL class], + ]] + forKey:@"server_url"]; + if (!serverURL) + return nil; + if ([serverURL isKindOfClass:[NSString class]]) { + return [NSURL URLWithString:serverURL]; // May throw + } + return (NSURL*)serverURL; +} + +- (id)initWithCoder:(NSCoder*)coder { + if ((self = [super init])) { + @try { + productID_ = [[coder decodeObjectOfClass:[NSString class] + forKey:@"product_id"] retain]; + version_ = [[coder decodeObjectOfClass:[NSString class] + forKey:@"version"] retain]; + existenceChecker_ = + [[coder decodeObjectOfClass:[KSPathExistenceChecker class] + forKey:@"existence_checker"] retain]; + serverURL_ = [[self decodeServerURL:coder] retain]; + creationDate_ = [[coder decodeObjectOfClass:[NSDate class] + forKey:@"creation_date"] retain]; + serverType_ = [[coder decodeObjectOfClass:[NSString class] + forKey:@"serverType"] retain]; + tag_ = [[coder decodeObjectOfClass:[NSString class] + forKey:@"tag"] retain]; + tagPath_ = [[coder decodeObjectOfClass:[NSString class] + forKey:@"tagPath"] retain]; + tagKey_ = [[coder decodeObjectOfClass:[NSString class] + forKey:@"tagKey"] retain]; + brandPath_ = [[coder decodeObjectOfClass:[NSString class] + forKey:@"brandPath"] retain]; + brandKey_ = [[coder decodeObjectOfClass:[NSString class] + forKey:@"brandKey"] retain]; + versionPath_ = [[coder decodeObjectOfClass:[NSString class] + forKey:@"versionPath"] retain]; + versionKey_ = [[coder decodeObjectOfClass:[NSString class] + forKey:@"versionKey"] retain]; + cohort_ = [[coder decodeObjectOfClass:[NSString class] + forKey:kKSTicketCohortKey] retain]; + cohortHint_ = [[coder decodeObjectOfClass:[NSString class] + forKey:kKSTicketCohortHintKey] retain]; + cohortName_ = [[coder decodeObjectOfClass:[NSString class] + forKey:kKSTicketCohortNameKey] retain]; + ticketVersion_ = [coder decodeInt32ForKey:@"ticketVersion"]; + } @catch (id e) { + VLOG(0) << base::SysNSStringToUTF8( + [NSString stringWithFormat:@"Coder exception %@", e]); + return nil; + } + } + return self; +} + +- (void)dealloc { + [productID_ release]; + [version_ release]; + [existenceChecker_ release]; + [serverURL_ release]; + [creationDate_ release]; + [serverType_ release]; + [tag_ release]; + [tagPath_ release]; + [tagKey_ release]; + [brandPath_ release]; + [brandKey_ release]; + [versionPath_ release]; + [versionKey_ release]; + [cohort_ release]; + [cohortHint_ release]; + [cohortName_ release]; + + [super dealloc]; +} + +- (void)encodeWithCoder:(NSCoder*)coder { + NOTREACHED() << "KSTicket::encodeWithCoder not implemented."; +} + +- (NSUInteger)hash { + return [productID_ hash] + [version_ hash] + [existenceChecker_ hash] + + [serverURL_ hash] + [creationDate_ hash]; +} + +- (NSString*)description { + // Keep the description stable. Clients depend on the output formatting + // as "fieldname=value" without any additional quoting. We cannot use + // KSDescription() here because of these legacy formatting restrictions. In + // particular, ksadmin output must not be substantially changed. + NSString* serverTypeString = @""; + if (serverType_) { + serverTypeString = + [NSString stringWithFormat:@"\n\tserverType=%@", serverType_]; + } + NSString* tagString = @""; + if (tag_) { + tagString = [NSString stringWithFormat:@"\n\ttag=%@", tag_]; + } + NSString* tagPathString = @""; + if (tagPath_ && tagKey_) { + tagPathString = [NSString + stringWithFormat:@"\n\ttagPath=%@\n\ttagKey=%@", tagPath_, tagKey_]; + } + NSString* brandPathString = @""; + if (brandPath_ && brandKey_) { + brandPathString = + [NSString stringWithFormat:@"\n\tbrandPath=%@\n\tbrandKey=%@", + brandPath_, brandKey_]; + } + NSString* versionPathString = @""; + if (versionPath_ && versionKey_) { + versionPathString = + [NSString stringWithFormat:@"\n\tversionPath=%@\n\tversionKey=%@", + versionPath_, versionKey_]; + } + NSString* cohortString = @""; + if ([cohort_ length]) { + cohortString = [NSString stringWithFormat:@"\n\tcohort=%@", cohort_]; + if ([cohortName_ length]) { + cohortString = [cohortString + stringByAppendingFormat:@"\n\tcohortName=%@", cohortName_]; + } + } + NSString* cohortHintString = @""; + if ([cohortHint_ length]) { + cohortHintString = + [NSString stringWithFormat:@"\n\tcohortHint=%@", cohortHint_]; + } + NSString* ticketVersionString = + [NSString stringWithFormat:@"\n\tticketVersion=%d", ticketVersion_]; + // Dates used to be parsed and stored as GMT and printed in GMT. That + // changed in 10.7 to be GMT with timezone information, so use a custom + // description string that matches our old output. + NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; + NSString* gmtDate = [dateFormatter stringFromDate:creationDate_]; + return [NSString + stringWithFormat:@"<%@:0x222222222222\n\tproductID=%@\n\tversion=%@\n\t" + @"xc=%@%@\n\turl=%@\n\tcreationDate=%@%@%@%@%@%@%@%@\n>", + [self class], productID_, version_, existenceChecker_, + serverTypeString, serverURL_, gmtDate, tagString, + tagPathString, brandPathString, versionPathString, + cohortString, cohortHintString, ticketVersionString]; +} + +@end
diff --git a/chrome/updater/mac/keystone/ks_tickets_unittest.mm b/chrome/updater/mac/keystone/ks_tickets_unittest.mm new file mode 100644 index 0000000..9753f0b --- /dev/null +++ b/chrome/updater/mac/keystone/ks_tickets_unittest.mm
@@ -0,0 +1,120 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "chrome/updater/mac/keystone/ks_tickets.h" + +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "base/strings/sys_string_conversions.h" +#include "chrome/common/chrome_paths.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace updater { + +TEST(KSTicketsTest, Decode) { + @autoreleasepool { + base::FilePath test_data_path; + ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_path)); + NSDictionary* store = [KSTicketStore + readStoreWithPath:base::SysUTF8ToNSString( + test_data_path + .Append(FILE_PATH_LITERAL("updater")) + .Append( + FILE_PATH_LITERAL("Keystone.ticketstore")) + .AsUTF8Unsafe())]; + + ASSERT_TRUE(store); + EXPECT_EQ([store count], 5ul); + EXPECT_EQ( + base::SysNSStringToUTF8( + [[store objectForKey:@"com.google.chrome.canary"] description]), + "<KSTicket:0x222222222222\n" + "\tproductID=com.google.Chrome.canary\n" + "\tversion=96.0.4662.0\n" + "\txc=<KSPathExistenceChecker:0x222222222222 " + "path=/Applications/Google Chrome Canary.app>\n" + "\tserverType=Omaha\n" + "\turl=https://tools.google.com/service/update2\n" + "\tcreationDate=2020-11-16 20:11:41\n" + "\ttag=canary\n" + "\ttagPath=/Applications/Google Chrome Canary.app/Contents/Info.plist\n" + "\ttagKey=KSChannelID\n" + "\tversionPath=" + "/Applications/Google Chrome Canary.app/Contents/Info.plist\n" + "\tversionKey=KSVersion\n" + "\tcohort=1:0:\n" + "\tcohortName=Canary\n" + "\tticketVersion=1\n" + ">"); + EXPECT_EQ( + base::SysNSStringToUTF8([[store + objectForKey:@"com.google.chrome_remote_desktop"] description]), + "<KSTicket:0x222222222222\n" + "\tproductID=com.google.chrome_remote_desktop\n" + "\tversion=94.0.4606.27\n" + "\txc=<KSPathExistenceChecker:0x222222222222 " + "path=/Library/LaunchAgents/org.chromium.chromoting.plist>\n" + "\tserverType=Omaha\n" + "\turl=https://tools.google.com/service/update2\n" + "\tcreationDate=2020-12-14 20:31:58\n" + "\tcohort=1:10ql:\n" + "\tcohortName=Stable\n" + "\tticketVersion=1\n" + ">"); + + EXPECT_EQ(base::SysNSStringToUTF8([[store + objectForKey:@"com.google.secureconnect"] description]), + "<KSTicket:0x222222222222\n" + "\tproductID=com.google.SecureConnect\n" + "\tversion=2.1.8\n" + "\txc=<KSPathExistenceChecker:0x222222222222 " + "path=/Library/Application Support/Google/Endpoint " + "Verification/ApiHelper>\n" + "\tserverType=Omaha\n" + "\turl=https://tools.google.com/service/update2\n" + "\tcreationDate=2019-12-16 17:25:15\n" + "\tcohort=1::\n" + "\tticketVersion=1\n" + ">"); + + EXPECT_EQ( + base::SysNSStringToUTF8( + [[store objectForKey:@"com.google.chrome"] description]), + "<KSTicket:0x222222222222\n" + "\tproductID=com.google.Chrome\n" + "\tversion=94.0.4606.71\n" + "\txc=<KSPathExistenceChecker:0x222222222222 " + "path=/Applications/Google Chrome.app>\n" + "\tserverType=Omaha\n" + "\turl=https://tools.google.com/service/update2\n" + "\tcreationDate=2019-12-19 17:15:37\n" + "\ttagPath=/Applications/Google Chrome.app/Contents/Info.plist\n" + "\ttagKey=KSChannelID\n" + "\tbrandPath=/Library/Google/Google Chrome Brand.plist\n" + "\tbrandKey=KSBrandID\n" + "\tversionPath=/Applications/Google Chrome.app/Contents/Info.plist\n" + "\tversionKey=KSVersion\n" + "\tcohort=1:1y5:\n" + "\tcohortName=Stable\n" + "\tticketVersion=1\n" + ">"); + + EXPECT_EQ(base::SysNSStringToUTF8( + [[store objectForKey:@"com.google.keystone"] description]), + "<KSTicket:0x222222222222\n" + "\tproductID=com.google.Keystone\n" + "\tversion=1.3.16.180\n" + "\txc=<KSPathExistenceChecker:0x222222222222 " + "path=/Library/Google/GoogleSoftwareUpdate/" + "GoogleSoftwareUpdate.bundle>\n" + "\turl=https://tools.google.com/service/update2\n" + "\tcreationDate=2019-12-16 17:18:45\n" + "\tcohort=1:0:\n" + "\tcohortName=Everyone\n" + "\tticketVersion=1\n" + ">"); + } +} + +} // namespace updater
diff --git a/chrome/updater/mac/keystone/ksadmin.mm b/chrome/updater/mac/keystone/ksadmin.mm index 9749c21..d8de9ce 100644 --- a/chrome/updater/mac/keystone/ksadmin.mm +++ b/chrome/updater/mac/keystone/ksadmin.mm
@@ -20,11 +20,14 @@ #include "base/memory/scoped_refptr.h" #include "base/message_loop/message_pump_type.h" #include "base/strings/string_util.h" +#include "base/strings/sys_string_conversions.h" #include "base/task/single_thread_task_executor.h" #include "base/task/thread_pool.h" #include "base/task/thread_pool/thread_pool_instance.h" #include "base/threading/thread_restrictions.h" #include "chrome/updater/app/app.h" +#include "chrome/updater/mac/keystone/ks_tickets.h" +#include "chrome/updater/mac/mac_util.h" #include "chrome/updater/mac/update_service_proxy.h" #include "chrome/updater/registration_data.h" #include "chrome/updater/update_service.h" @@ -87,12 +90,36 @@ return result; } +bool HasSwitch(const std::string& arg, + const std::map<std::string, std::string>& switches) { + if (base::Contains(switches, arg)) + return true; + const static std::map<std::string, std::vector<std::string>> aliases = { + {kCommandDelete, {"d"}}, {kCommandInstall, {"i"}}, + {kCommandList, {"l"}}, {kCommandKsadminVersion, {"k"}}, + {kCommandPrintTag, {"G"}}, {kCommandPrintTickets, {"print", "p"}}, + {kCommandRegister, {"r"}}, {kCommandSystemStore, {"S"}}, + {kCommandUserInitiated, {"F"}}, {kCommandUserStore, {"U"}}, + }; + if (!base::Contains(aliases, arg)) + return false; + for (const auto& alias : aliases.at(arg)) { + if (base::Contains(switches, alias)) + return true; + } + return false; +} + +UpdaterScope Scope(const std::map<std::string, std::string>& switches) { + return HasSwitch(kCommandSystemStore, switches) ? UpdaterScope::kSystem + : UpdaterScope::kUser; +} + class KSAdminApp : public App { public: explicit KSAdminApp(const std::map<std::string, std::string>& switches) - : service_proxy_( - base::MakeRefCounted<UpdateServiceProxy>(GetUpdaterScope())), - switches_(switches) {} + : switches_(switches), + service_proxy_(base::MakeRefCounted<UpdateServiceProxy>(Scope())) {} private: ~KSAdminApp() override = default; @@ -107,11 +134,12 @@ void PrintVersion(); void PrintTickets(); - bool HasSwitch(const std::string& arg); - std::string SwitchValue(const std::string& arg); + UpdaterScope Scope() const; + bool HasSwitch(const std::string& arg) const; + std::string SwitchValue(const std::string& arg) const; - scoped_refptr<UpdateServiceProxy> service_proxy_; const std::map<std::string, std::string> switches_; + scoped_refptr<UpdateServiceProxy> service_proxy_; }; void KSAdminApp::PrintUsage(const std::string& error_message) { @@ -204,26 +232,11 @@ base::BindOnce(&KSAdminApp::Shutdown, this))); } -bool KSAdminApp::HasSwitch(const std::string& arg) { - if (base::Contains(switches_, arg)) - return true; - const static std::map<std::string, std::vector<std::string>> aliases = { - {kCommandDelete, {"d"}}, {kCommandInstall, {"i"}}, - {kCommandList, {"l"}}, {kCommandKsadminVersion, {"k"}}, - {kCommandPrintTag, {"G"}}, {kCommandPrintTickets, {"print", "p"}}, - {kCommandRegister, {"r"}}, {kCommandSystemStore, {"S"}}, - {kCommandUserInitiated, {"F"}}, {kCommandUserStore, {"U"}}, - }; - if (!base::Contains(aliases, arg)) - return false; - for (const auto& alias : aliases.at(arg)) { - if (base::Contains(switches_, alias)) - return true; - } - return false; +bool KSAdminApp::HasSwitch(const std::string& arg) const { + return updater::HasSwitch(arg, switches_); } -std::string KSAdminApp::SwitchValue(const std::string& arg) { +std::string KSAdminApp::SwitchValue(const std::string& arg) const { if (base::Contains(switches_, arg)) return switches_.at(arg); const static std::map<std::string, std::string> aliases = { @@ -239,6 +252,10 @@ return base::Contains(switches_, alias) ? switches_.at(alias) : ""; } +UpdaterScope KSAdminApp::Scope() const { + return updater::Scope(switches_); +} + void KSAdminApp::Delete() { // TODO(crbug.com/1250524): Implement. Shutdown(1); @@ -255,8 +272,26 @@ } void KSAdminApp::PrintTickets() { - // TODO(crbug.com/1250524): Implement. - Shutdown(1); + // TODO(crbug.com/1250524): Print tickets owned by Chromium Updater. If there + // are any, suppress printing any legacy tickets. + @autoreleasepool { + const NSDictionary* store = [KSTicketStore + readStoreWithPath:base::SysUTF8ToNSString( + GetKeystoneFolderPath(Scope()) + ->Append(FILE_PATH_LITERAL("TicketStore")) + .Append( + FILE_PATH_LITERAL("Keystone.ticketstore")) + .AsUTF8Unsafe())]; + if (store.count > 0) { + for (const id key in store) { + printf("%s\n", + base::SysNSStringToUTF8([store[key] description]).c_str()); + } + } else { + printf("No tickets\n"); + } + } + Shutdown(0); } void KSAdminApp::FirstTaskRun() { @@ -289,12 +324,11 @@ int KSAdminAppMain(int argc, char* argv[]) { base::AtExitManager exit_manager; base::CommandLine::Init(argc, argv); - // TODO(crbug.com/1250524): GetUpdaterScope() won't work: callers do not pass - // --system but rather --system-store. Check also other GetUpdaterScope calls - // in this code. - updater::InitLogging(GetUpdaterScope(), FILE_PATH_LITERAL("updater.log")); + std::map<std::string, std::string> command_line = + ParseCommandLine(argc, argv); + updater::InitLogging(Scope(command_line), FILE_PATH_LITERAL("updater.log")); base::SingleThreadTaskExecutor main_task_executor(base::MessagePumpType::UI); - return base::MakeRefCounted<KSAdminApp>(ParseCommandLine(argc, argv))->Run(); + return base::MakeRefCounted<KSAdminApp>(command_line)->Run(); } } // namespace updater
diff --git a/chrome/updater/service_factory_win.cc b/chrome/updater/service_factory_win.cc index 1ded800a..0d3920b 100644 --- a/chrome/updater/service_factory_win.cc +++ b/chrome/updater/service_factory_win.cc
@@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <wrl/module.h> + #include "base/logging.h" #include "base/memory/ref_counted.h" #include "chrome/updater/updater_scope.h" #include "chrome/updater/win/update_service_internal_proxy.h" #include "chrome/updater/win/update_service_proxy.h" -#include "chrome/updater/win/wrl_module.h" namespace updater { namespace {
diff --git a/chrome/updater/updater_scope.h b/chrome/updater/updater_scope.h index bbda4d0..84255c2b 100644 --- a/chrome/updater/updater_scope.h +++ b/chrome/updater/updater_scope.h
@@ -6,6 +6,7 @@ #define CHROME_UPDATER_UPDATER_SCOPE_H_ #include <ostream> +#include <string> namespace updater { @@ -18,15 +19,19 @@ kSystem = 2, }; -inline std::ostream& operator<<(std::ostream& os, UpdaterScope scope) { +inline std::string UpdaterScopeToString(UpdaterScope scope) { switch (scope) { case UpdaterScope::kUser: - return os << "User"; + return "User"; case UpdaterScope::kSystem: - return os << "System"; + return "System"; } } +inline std::ostream& operator<<(std::ostream& os, UpdaterScope scope) { + return os << UpdaterScopeToString(scope).c_str(); +} + // Returns the scope of the updater, which is either per-system or per-user. // The updater scope is determined from command line arguments of the process, // the presence and content of the --tag argument, and the integrity level
diff --git a/chrome/updater/win/wrl_module.h b/chrome/updater/win/wrl_module.h deleted file mode 100644 index a563076..0000000 --- a/chrome/updater/win/wrl_module.h +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_UPDATER_WIN_WRL_MODULE_H_ -#define CHROME_UPDATER_WIN_WRL_MODULE_H_ - -#if !defined(__WRL_CLASSIC_COM_STRICT__) -#error "WRL must not depend on WinRT." -#endif - -#include <wrl/module.h> - -#endif // CHROME_UPDATER_WIN_WRL_MODULE_H_
diff --git a/chromecast/base/chromecast_switches.cc b/chromecast/base/chromecast_switches.cc index 68b80b1..04c0e1c 100644 --- a/chromecast/base/chromecast_switches.cc +++ b/chromecast/base/chromecast_switches.cc
@@ -186,6 +186,9 @@ // Whether to enable the drawing of rounded window corners in the root window. const char kEnableRoundedWindowCorners[] = "enable-rounded-window-corners"; +// Whether in hospitality mode +const char kManagedMode[] = "managed-mode"; + // Endpoint that the mixer service listens on. This is a path for a UNIX domain // socket (default is /tmp/mixer-service). const char kMixerServiceEndpoint[] = "mixer-service-endpoint";
diff --git a/chromecast/base/chromecast_switches.h b/chromecast/base/chromecast_switches.h index d06ee62..7ccb5a2 100644 --- a/chromecast/base/chromecast_switches.h +++ b/chromecast/base/chromecast_switches.h
@@ -84,6 +84,7 @@ extern const char kBackGestureHorizontalThreshold[]; extern const char kEnableTopDragGesture[]; extern const char kEnableRoundedWindowCorners[]; +extern const char kManagedMode[]; // Background color used when Chromium hasn't rendered anything yet. extern const char kCastAppBackgroundColor[];
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index 52159fe..0c484130 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -584,6 +584,8 @@ "cast_web_contents.h", "cast_web_view.cc", "cast_web_view.h", + "gesture_router.cc", + "gesture_router.h", ] # Need to expose this so that internal public_configs are propagated. @@ -592,6 +594,7 @@ ":client", "//chromecast/browser/mojom", "//chromecast/common/mojom", + "//chromecast/mojo", "//content/public/browser", ] @@ -601,7 +604,9 @@ "//chromecast/graphics", "//chromecast/ui:back_gesture_router", "//chromecast/ui/mojom", + "//content/public/browser", "//content/public/common", + "//mojo/public/cpp/bindings", "//ui/events", "//url", ]
diff --git a/chromecast/browser/android/cast_content_window_android.cc b/chromecast/browser/android/cast_content_window_android.cc index d37e553..ec2f56e 100644 --- a/chromecast/browser/android/cast_content_window_android.cc +++ b/chromecast/browser/android/cast_content_window_android.cc
@@ -181,8 +181,8 @@ const base::android::JavaParamRef<jobject>& callback) { auto wrapper = std::make_unique<GestureConsumedCallbackWrapper>(env, callback); - if (delegate_) { - delegate_->ConsumeGesture( + if (gesture_router()) { + gesture_router()->ConsumeGesture( static_cast<GestureType>(gesture_type), base::BindOnce(&GestureConsumedCallbackWrapper::Invoke, std::move(wrapper)));
diff --git a/chromecast/browser/cast_content_gesture_handler.cc b/chromecast/browser/cast_content_gesture_handler.cc index 85b19b8..795a086 100644 --- a/chromecast/browser/cast_content_gesture_handler.cc +++ b/chromecast/browser/cast_content_gesture_handler.cc
@@ -15,7 +15,7 @@ } // namespace CastContentGestureHandler::CastContentGestureHandler( - base::WeakPtr<CastContentWindow::Delegate> delegate, + GestureRouter* delegate, bool enable_top_drag_gesture) : priority_(Priority::NONE), enable_top_drag_gesture_(enable_top_drag_gesture), @@ -26,8 +26,7 @@ DCHECK(delegate_); } -CastContentGestureHandler::CastContentGestureHandler( - base::WeakPtr<CastContentWindow::Delegate> delegate) +CastContentGestureHandler::CastContentGestureHandler(GestureRouter* delegate) : CastContentGestureHandler( delegate, GetSwitchValueBoolean(switches::kEnableTopDragGesture, false)) {}
diff --git a/chromecast/browser/cast_content_gesture_handler.h b/chromecast/browser/cast_content_gesture_handler.h index 2071c67d..c1308970 100644 --- a/chromecast/browser/cast_content_gesture_handler.h +++ b/chromecast/browser/cast_content_gesture_handler.h
@@ -8,7 +8,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/timer/elapsed_timer.h" -#include "chromecast/browser/cast_content_window.h" +#include "chromecast/browser/gesture_router.h" #include "chromecast/graphics/gestures/cast_gesture_handler.h" namespace chromecast { @@ -17,8 +17,9 @@ // CastContentWindow::Delegate. class CastContentGestureHandler : public CastGestureHandler { public: - explicit CastContentGestureHandler( - base::WeakPtr<CastContentWindow::Delegate> delegate); + explicit CastContentGestureHandler(GestureRouter* delegate); + CastContentGestureHandler(GestureRouter* delegate, + bool enable_top_drag_gesture); ~CastContentGestureHandler() override; // CastGestureHandler implementation: @@ -33,9 +34,6 @@ void SetPriority(Priority priority); private: - friend class CastContentGestureHandlerTest; - CastContentGestureHandler(base::WeakPtr<CastContentWindow::Delegate> delegate, - bool enable_top_drag_gesture); GestureType GestureForSwipeOrigin(CastSideSwipeOrigin swipe_origin); Priority priority_; @@ -44,7 +42,7 @@ // Number of pixels past swipe origin to consider as a back gesture. const int back_horizontal_threshold_; - base::WeakPtr<CastContentWindow::Delegate> const delegate_; + GestureRouter* const delegate_; base::ElapsedTimer current_swipe_time_; };
diff --git a/chromecast/browser/cast_content_gesture_handler_test.cc b/chromecast/browser/cast_content_gesture_handler_test.cc index 87ee316..20523211 100644 --- a/chromecast/browser/cast_content_gesture_handler_test.cc +++ b/chromecast/browser/cast_content_gesture_handler_test.cc
@@ -40,211 +40,200 @@ constexpr gfx::Point kOngoingRightGesturePoint1(400, 50); constexpr gfx::Point kRightGestureEndPoint(200, 60); +class MockGestureHandler : public mojom::GestureHandler { + public: + MockGestureHandler() = default; + ~MockGestureHandler() override = default; + + MOCK_METHOD(void, OnBackGesture, (OnBackGestureCallback), (override)); + MOCK_METHOD(void, OnBackGestureProgress, (const gfx::Point&), (override)); + MOCK_METHOD(void, OnTopDragGestureProgress, (const gfx::Point&), (override)); + MOCK_METHOD(void, OnTopDragGestureDone, (), (override)); + MOCK_METHOD(void, + OnRightDragGestureProgress, + (const gfx::Point&), + (override)); + MOCK_METHOD(void, OnRightDragGestureDone, (), (override)); + MOCK_METHOD(void, OnBackGestureCancel, (), (override)); + MOCK_METHOD(void, OnTapGesture, (), (override)); + MOCK_METHOD(void, OnTapDownGesture, (), (override)); +}; + } // namespace class CastContentGestureHandlerTest : public testing::Test { public: - CastContentGestureHandlerTest() - : delegate_(new testing::StrictMock<MockCastContentWindowDelegate>), - dispatcher_(delegate_->AsWeakPtr(), true) {} + CastContentGestureHandlerTest() {} + + void SetUp() final { + gesture_router_ = std::make_unique<GestureRouter>(); + dispatcher_ = std::make_unique<CastContentGestureHandler>( + gesture_router_.get(), true); + gesture_router_->SetHandler(&handler_); + } protected: - std::unique_ptr<testing::StrictMock<MockCastContentWindowDelegate>> delegate_; - CastContentGestureHandler dispatcher_; + std::unique_ptr<GestureRouter> gesture_router_; + std::unique_ptr<CastContentGestureHandler> dispatcher_; + MockGestureHandler handler_; }; // Verify the simple case of a left swipe with the right horizontal leads to // back. TEST_F(CastContentGestureHandlerTest, VerifySimpleBackSuccess) { - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::TOP_DRAG))) - .WillRepeatedly(Return(false)); - - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::GO_BACK))) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*delegate_, GestureProgress(Eq(GestureType::GO_BACK), - Eq(kOngoingBackGesturePoint1))); - EXPECT_CALL(*delegate_, ConsumeGesture(Eq(GestureType::GO_BACK), _)) - .WillRepeatedly( - [](auto, auto callback) { std::move(callback).Run(true); }); - dispatcher_.CanHandleSwipe(CastSideSwipeOrigin::LEFT); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::BEGIN, - CastSideSwipeOrigin::LEFT, kLeftSidePoint); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::CONTINUE, - CastSideSwipeOrigin::LEFT, - kOngoingBackGesturePoint1); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::END, - CastSideSwipeOrigin::LEFT, - kValidBackGestureEndPoint); + gesture_router_->SetCanTopDrag(false); + gesture_router_->SetCanGoBack(true); + EXPECT_CALL(handler_, OnBackGestureProgress(Eq(kOngoingBackGesturePoint1))); + EXPECT_CALL(handler_, OnBackGesture(_)); + ASSERT_TRUE(dispatcher_->CanHandleSwipe(CastSideSwipeOrigin::LEFT)); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::BEGIN, + CastSideSwipeOrigin::LEFT, kLeftSidePoint); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::CONTINUE, + CastSideSwipeOrigin::LEFT, + kOngoingBackGesturePoint1); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::END, + CastSideSwipeOrigin::LEFT, + kValidBackGestureEndPoint); } // Verify that if the finger is not lifted, that's not a back gesture. TEST_F(CastContentGestureHandlerTest, VerifyNoDispatchOnNoLift) { - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::TOP_DRAG))) - .WillRepeatedly(Return(false)); - - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::GO_BACK))) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*delegate_, ConsumeGesture(Eq(GestureType::GO_BACK), _)).Times(0); - EXPECT_CALL(*delegate_, GestureProgress(Eq(GestureType::GO_BACK), - Eq(kValidBackGestureEndPoint))); - EXPECT_CALL(*delegate_, - GestureProgress(Eq(GestureType::GO_BACK), Eq(kPastTheEndPoint1))); - dispatcher_.CanHandleSwipe(CastSideSwipeOrigin::LEFT); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::BEGIN, - CastSideSwipeOrigin::LEFT, kLeftSidePoint); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::CONTINUE, - CastSideSwipeOrigin::LEFT, - kValidBackGestureEndPoint); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::CONTINUE, - CastSideSwipeOrigin::LEFT, kPastTheEndPoint1); + gesture_router_->SetCanTopDrag(false); + gesture_router_->SetCanGoBack(true); + EXPECT_CALL(handler_, OnBackGestureProgress(Eq(kValidBackGestureEndPoint))); + EXPECT_CALL(handler_, OnBackGesture(_)).Times(0); + EXPECT_CALL(handler_, OnBackGestureProgress(Eq(kPastTheEndPoint1))); + ASSERT_TRUE(dispatcher_->CanHandleSwipe(CastSideSwipeOrigin::LEFT)); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::BEGIN, + CastSideSwipeOrigin::LEFT, kLeftSidePoint); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::CONTINUE, + CastSideSwipeOrigin::LEFT, + kValidBackGestureEndPoint); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::CONTINUE, + CastSideSwipeOrigin::LEFT, kPastTheEndPoint1); } // Verify that multiple 'continue' events still only lead to one back // invocation. TEST_F(CastContentGestureHandlerTest, VerifyOnlySingleDispatch) { - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::TOP_DRAG))) - .WillRepeatedly(Return(false)); + gesture_router_->SetCanTopDrag(false); + gesture_router_->SetCanGoBack(true); - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::GO_BACK))) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*delegate_, GestureProgress(Eq(GestureType::GO_BACK), - Eq(kValidBackGestureEndPoint))); - EXPECT_CALL(*delegate_, - GestureProgress(Eq(GestureType::GO_BACK), Eq(kPastTheEndPoint1))); - EXPECT_CALL(*delegate_, ConsumeGesture(Eq(GestureType::GO_BACK), _)) - .WillRepeatedly( - [](auto, auto callback) { std::move(callback).Run(true); }); - dispatcher_.CanHandleSwipe(CastSideSwipeOrigin::LEFT); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::BEGIN, - CastSideSwipeOrigin::LEFT, kLeftSidePoint); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::CONTINUE, - CastSideSwipeOrigin::LEFT, - kValidBackGestureEndPoint); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::CONTINUE, - CastSideSwipeOrigin::LEFT, kPastTheEndPoint1); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::END, - CastSideSwipeOrigin::LEFT, kPastTheEndPoint2); + EXPECT_CALL(handler_, OnBackGestureProgress(Eq(kValidBackGestureEndPoint))); + EXPECT_CALL(handler_, OnBackGestureProgress(Eq(kPastTheEndPoint1))); + EXPECT_CALL(handler_, OnBackGesture(_)); + ASSERT_TRUE(dispatcher_->CanHandleSwipe(CastSideSwipeOrigin::LEFT)); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::BEGIN, + CastSideSwipeOrigin::LEFT, kLeftSidePoint); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::CONTINUE, + CastSideSwipeOrigin::LEFT, + kValidBackGestureEndPoint); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::CONTINUE, + CastSideSwipeOrigin::LEFT, kPastTheEndPoint1); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::END, + CastSideSwipeOrigin::LEFT, kPastTheEndPoint2); } // Verify that if the delegate says it doesn't handle back that we won't try to // ask them to consume it. TEST_F(CastContentGestureHandlerTest, VerifyDelegateDoesNotConsumeUnwanted) { - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::TOP_DRAG))) - .WillRepeatedly(Return(false)); - - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::GO_BACK))) - .WillRepeatedly(Return(false)); - dispatcher_.CanHandleSwipe(CastSideSwipeOrigin::LEFT); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::BEGIN, - CastSideSwipeOrigin::LEFT, kLeftSidePoint); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::CONTINUE, - CastSideSwipeOrigin::LEFT, - kValidBackGestureEndPoint); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::END, - CastSideSwipeOrigin::LEFT, kPastTheEndPoint2); + gesture_router_->SetCanTopDrag(false); + gesture_router_->SetCanGoBack(false); + ASSERT_FALSE(dispatcher_->CanHandleSwipe(CastSideSwipeOrigin::LEFT)); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::BEGIN, + CastSideSwipeOrigin::LEFT, kLeftSidePoint); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::CONTINUE, + CastSideSwipeOrigin::LEFT, + kValidBackGestureEndPoint); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::END, + CastSideSwipeOrigin::LEFT, kPastTheEndPoint2); } // Verify that a not-left gesture doesn't lead to a swipe. TEST_F(CastContentGestureHandlerTest, VerifyNotLeftSwipeIsNotBack) { - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::TOP_DRAG))) - .WillRepeatedly(Return(false)); + gesture_router_->SetCanTopDrag(false); - dispatcher_.CanHandleSwipe(CastSideSwipeOrigin::TOP); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::BEGIN, - CastSideSwipeOrigin::TOP, kTopSidePoint); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::CONTINUE, - CastSideSwipeOrigin::TOP, - kOngoingTopGesturePoint2); + ASSERT_FALSE(dispatcher_->CanHandleSwipe(CastSideSwipeOrigin::TOP)); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::BEGIN, + CastSideSwipeOrigin::TOP, kTopSidePoint); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::CONTINUE, + CastSideSwipeOrigin::TOP, + kOngoingTopGesturePoint2); } // Verify that if the gesture doesn't go far enough horizontally that we will // not consider it a swipe. TEST_F(CastContentGestureHandlerTest, VerifyNotFarEnoughRightIsNotBack) { - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::TOP_DRAG))) - .WillRepeatedly(Return(false)); + gesture_router_->SetCanTopDrag(false); + gesture_router_->SetCanGoBack(true); - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::GO_BACK))) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*delegate_, GestureProgress(Eq(GestureType::GO_BACK), - Eq(kOngoingBackGesturePoint1))); - EXPECT_CALL(*delegate_, CancelGesture(Eq(GestureType::GO_BACK))); - dispatcher_.CanHandleSwipe(CastSideSwipeOrigin::LEFT); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::BEGIN, - CastSideSwipeOrigin::LEFT, kLeftSidePoint); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::CONTINUE, - CastSideSwipeOrigin::LEFT, - kOngoingBackGesturePoint1); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::END, - CastSideSwipeOrigin::LEFT, - kOngoingBackGesturePoint2); + EXPECT_CALL(handler_, OnBackGestureProgress(Eq(kOngoingBackGesturePoint1))); + EXPECT_CALL(handler_, OnBackGestureCancel()); + ASSERT_TRUE(dispatcher_->CanHandleSwipe(CastSideSwipeOrigin::LEFT)); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::BEGIN, + CastSideSwipeOrigin::LEFT, kLeftSidePoint); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::CONTINUE, + CastSideSwipeOrigin::LEFT, + kOngoingBackGesturePoint1); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::END, + CastSideSwipeOrigin::LEFT, + kOngoingBackGesturePoint2); } // Verify that if the gesture ends before going far enough, that's also not a // swipe. TEST_F(CastContentGestureHandlerTest, VerifyNotFarEnoughRightAndEndIsNotBack) { - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::TOP_DRAG))) - .WillRepeatedly(Return(false)); + gesture_router_->SetCanTopDrag(false); + gesture_router_->SetCanGoBack(true); - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::GO_BACK))) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*delegate_, GestureProgress(Eq(GestureType::GO_BACK), - Eq(kOngoingBackGesturePoint1))); - EXPECT_CALL(*delegate_, CancelGesture(Eq(GestureType::GO_BACK))); - dispatcher_.CanHandleSwipe(CastSideSwipeOrigin::LEFT); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::BEGIN, - CastSideSwipeOrigin::LEFT, kLeftSidePoint); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::CONTINUE, - CastSideSwipeOrigin::LEFT, - kOngoingBackGesturePoint1); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::END, - CastSideSwipeOrigin::LEFT, - kOngoingBackGesturePoint2); + EXPECT_CALL(handler_, OnBackGestureProgress(Eq(kOngoingBackGesturePoint1))); + EXPECT_CALL(handler_, OnBackGestureCancel()); + ASSERT_TRUE(dispatcher_->CanHandleSwipe(CastSideSwipeOrigin::LEFT)); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::BEGIN, + CastSideSwipeOrigin::LEFT, kLeftSidePoint); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::CONTINUE, + CastSideSwipeOrigin::LEFT, + kOngoingBackGesturePoint1); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::END, + CastSideSwipeOrigin::LEFT, + kOngoingBackGesturePoint2); } // Verify simple top-down drag. TEST_F(CastContentGestureHandlerTest, VerifySimpleTopSuccess) { - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::TOP_DRAG))) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::GO_BACK))) - .WillRepeatedly(Return(false)); + gesture_router_->SetCanTopDrag(true); + gesture_router_->SetCanGoBack(false); - EXPECT_CALL(*delegate_, GestureProgress(Eq(GestureType::TOP_DRAG), - Eq(kOngoingTopGesturePoint1))); - EXPECT_CALL(*delegate_, ConsumeGesture(Eq(GestureType::TOP_DRAG), _)) - .WillRepeatedly( - [](auto, auto callback) { std::move(callback).Run(true); }); - dispatcher_.CanHandleSwipe(CastSideSwipeOrigin::TOP); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::BEGIN, - CastSideSwipeOrigin::TOP, kTopSidePoint); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::CONTINUE, - CastSideSwipeOrigin::TOP, - kOngoingTopGesturePoint1); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::END, - CastSideSwipeOrigin::LEFT, kTopGestureEndPoint); + EXPECT_CALL(handler_, OnTopDragGestureProgress(Eq(kOngoingTopGesturePoint1))); + EXPECT_CALL(handler_, OnTopDragGestureDone()); + ASSERT_TRUE(dispatcher_->CanHandleSwipe(CastSideSwipeOrigin::TOP)); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::BEGIN, + CastSideSwipeOrigin::TOP, kTopSidePoint); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::CONTINUE, + CastSideSwipeOrigin::TOP, + kOngoingTopGesturePoint1); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::END, + CastSideSwipeOrigin::TOP, kTopGestureEndPoint); } // Verify simple right-to-left drag. TEST_F(CastContentGestureHandlerTest, VerifySimpleRightSuccess) { - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::RIGHT_DRAG))) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::GO_BACK))) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*delegate_, CanHandleGesture(Eq(GestureType::TOP_DRAG))) - .WillRepeatedly(Return(false)); + gesture_router_->SetCanRightDrag(true); + gesture_router_->SetCanTopDrag(false); + gesture_router_->SetCanGoBack(false); - EXPECT_CALL(*delegate_, GestureProgress(Eq(GestureType::RIGHT_DRAG), - Eq(kOngoingRightGesturePoint1))); - EXPECT_CALL(*delegate_, ConsumeGesture(Eq(GestureType::RIGHT_DRAG), _)) - .WillRepeatedly( - [](auto, auto callback) { std::move(callback).Run(true); }); - dispatcher_.CanHandleSwipe(CastSideSwipeOrigin::RIGHT); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::BEGIN, - CastSideSwipeOrigin::RIGHT, kRightSidePoint); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::CONTINUE, - CastSideSwipeOrigin::RIGHT, - kOngoingRightGesturePoint1); - dispatcher_.HandleSideSwipe(CastSideSwipeEvent::END, - CastSideSwipeOrigin::LEFT, kRightGestureEndPoint); + EXPECT_CALL(handler_, + OnRightDragGestureProgress(Eq(kOngoingRightGesturePoint1))); + EXPECT_CALL(handler_, OnRightDragGestureDone()); + ASSERT_TRUE(dispatcher_->CanHandleSwipe(CastSideSwipeOrigin::RIGHT)); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::BEGIN, + CastSideSwipeOrigin::RIGHT, kRightSidePoint); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::CONTINUE, + CastSideSwipeOrigin::RIGHT, + kOngoingRightGesturePoint1); + dispatcher_->HandleSideSwipe(CastSideSwipeEvent::END, + CastSideSwipeOrigin::RIGHT, + kRightGestureEndPoint); } } // namespace chromecast
diff --git a/chromecast/browser/cast_content_window.cc b/chromecast/browser/cast_content_window.cc index bff258e..c7a90734 100644 --- a/chromecast/browser/cast_content_window.cc +++ b/chromecast/browser/cast_content_window.cc
@@ -8,10 +8,24 @@ CastContentWindow::CastContentWindow(base::WeakPtr<Delegate> delegate, mojom::CastWebViewParamsPtr params) - : delegate_(delegate), params_(std::move(params)) {} + : delegate_(delegate), params_(std::move(params)) { + RegisterBackGestureRouter(gesture_router()); +} CastContentWindow::~CastContentWindow() = default; +void CastContentWindow::SetCastWebContents(CastWebContents* cast_web_contents) { + cast_web_contents_ = cast_web_contents; + // Must provide binder callbacks with WeakPtr since CastContentWindow + these + // interface implementations are destroyed before CastWebContents. + cast_web_contents_->local_interfaces()->AddBinder(base::BindRepeating( + &CastContentWindow::BindReceiver, weak_factory_.GetWeakPtr())); + cast_web_contents_->local_interfaces()->AddBinder(base::BindRepeating( + &CastContentWindow::BindActivityWindow, weak_factory_.GetWeakPtr())); + cast_web_contents_->local_interfaces()->AddBinder( + gesture_router()->GetBinder()); +} + void CastContentWindow::AddObserver(Observer* observer) { observer_list_.AddObserver(observer); } @@ -25,6 +39,19 @@ receiver_.Bind(std::move(receiver)); } +void CastContentWindow::BindActivityWindow( + mojo::PendingReceiver<mojom::ActivityWindow> receiver) { + activity_window_receiver_.Bind(std::move(receiver)); +} + +void CastContentWindow::Show() { + RequestVisibility(VisibilityPriority::STICKY_ACTIVITY); +} + +void CastContentWindow::Hide() { + RequestMoveOut(); +} + mojom::MediaControlUi* CastContentWindow::media_controls() { return nullptr; }
diff --git a/chromecast/browser/cast_content_window.h b/chromecast/browser/cast_content_window.h index 200a4d5..2b6974ef 100644 --- a/chromecast/browser/cast_content_window.h +++ b/chromecast/browser/cast_content_window.h
@@ -11,9 +11,11 @@ #include "base/observer_list.h" #include "base/observer_list_types.h" #include "chromecast/browser/cast_web_contents.h" +#include "chromecast/browser/gesture_router.h" #include "chromecast/browser/mojom/cast_content_window.mojom.h" #include "chromecast/browser/mojom/cast_web_service.mojom.h" #include "chromecast/browser/visibility_types.h" +#include "chromecast/common/mojom/activity_window.mojom.h" #include "chromecast/graphics/gestures/cast_gesture_handler.h" #include "chromecast/ui/back_gesture_router.h" #include "chromecast/ui/mojom/media_control_ui.mojom.h" @@ -27,32 +29,14 @@ // Class that represents the "window" a WebContents is displayed in cast_shell. // For Linux, this represents an Aura window. For Android, this is a Activity. // See CastContentWindowAura and CastContentWindowAndroid. -class CastContentWindow : public mojom::CastContentWindow { +class CastContentWindow : public mojom::CastContentWindow, + public mojom::ActivityWindow { public: class Delegate { public: // Notify window destruction. virtual void OnWindowDestroyed() {} - using GestureHandledCallback = base::OnceCallback<void(bool)>; - - // Check to see if the gesture can be handled by the delegate. This is - // called prior to ConsumeGesture(). - virtual bool CanHandleGesture(GestureType gesture_type) = 0; - - // Called while a system UI gesture is in progress. - virtual void GestureProgress(GestureType gesture_type, - const gfx::Point& touch_location) {} - - // Called when an in-progress system UI gesture is cancelled (for example - // when the finger is lifted before the completion of the gesture.) - virtual void CancelGesture(GestureType gesture_type) {} - - // Consume and handle a completed UI gesture. Invokes the callback with a - // boolean indicating whether the gesture was handled or not. - virtual void ConsumeGesture(GestureType gesture_type, - GestureHandledCallback handled_callback) = 0; - // Notify visibility change for this window. virtual void OnVisibilityChange(VisibilityType visibility_type) {} @@ -74,11 +58,10 @@ ~CastContentWindow() override; // |cast_web_contents| must outlive the CastContentWindow. - void SetCastWebContents(CastWebContents* cast_web_contents) { - cast_web_contents_ = cast_web_contents; - } + void SetCastWebContents(CastWebContents* cast_web_contents); CastWebContents* cast_web_contents() { return cast_web_contents_; } + GestureRouter* gesture_router() { return &gesture_router_; } // mojom::CastContentWindow implementation: void CreateWindow(mojom::ZOrder z_order, @@ -90,6 +73,10 @@ void SetActivityContext(base::Value activity_context) override = 0; void SetHostContext(base::Value host_context) override = 0; + // mojom::ActivityWindow implementation: + void Show() override; + void Hide() override; + // Notify the window that its visibility type has changed. This should only // ever be called by the window manager. // TODO(seantopping): Make this private to the window manager. @@ -114,6 +101,9 @@ void BindReceiver(mojo::PendingReceiver<mojom::CastContentWindow> receiver); protected: + void BindActivityWindow( + mojo::PendingReceiver<mojom::ActivityWindow> receiver); + // Camel case due to conflict with WebContentsObserver::web_contents(). content::WebContents* WebContents() { return cast_web_contents() ? cast_web_contents()->web_contents() : nullptr; @@ -123,8 +113,11 @@ base::WeakPtr<Delegate> delegate_; mojom::CastWebViewParamsPtr params_; + GestureRouter gesture_router_; mojo::Receiver<mojom::CastContentWindow> receiver_{this}; + mojo::Receiver<mojom::ActivityWindow> activity_window_receiver_{this}; base::ObserverList<Observer> observer_list_; + base::WeakPtrFactory<CastContentWindow> weak_factory_{this}; }; } // namespace chromecast
diff --git a/chromecast/browser/cast_content_window_aura.cc b/chromecast/browser/cast_content_window_aura.cc index f69bef18d..8efd130 100644 --- a/chromecast/browser/cast_content_window_aura.cc +++ b/chromecast/browser/cast_content_window_aura.cc
@@ -93,7 +93,7 @@ : CastContentWindow(delegate, std::move(params)), window_manager_(window_manager), gesture_dispatcher_( - std::make_unique<CastContentGestureHandler>(delegate_)), + std::make_unique<CastContentGestureHandler>(gesture_router())), window_(nullptr), has_screen_access_(false), resize_window_when_navigation_starts_(true) {}
diff --git a/chromecast/browser/cast_web_contents.h b/chromecast/browser/cast_web_contents.h index c79b720..3a0e0a8 100644 --- a/chromecast/browser/cast_web_contents.h +++ b/chromecast/browser/cast_web_contents.h
@@ -18,6 +18,7 @@ #include "chromecast/browser/mojom/cast_web_contents.mojom.h" #include "chromecast/browser/web_types.h" #include "chromecast/common/mojom/feature_manager.mojom.h" +#include "chromecast/mojo/interface_bundle.h" #include "content/public/common/media_playback_renderer_type.mojom.h" #include "mojo/public/cpp/bindings/generic_pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -255,6 +256,9 @@ // registry or any registered InterfaceProvider. virtual bool TryBindReceiver(mojo::GenericPendingReceiver& receiver) = 0; + // Locally-registered interfaces which are exposed to render frames. + virtual InterfaceBundle* local_interfaces() = 0; + // Used for owner to pass its |InterfaceProvider| pointers to CastWebContents. // It is owner's responsibility to make sure each |InterfaceProvider| pointer // has distinct mojo interface set.
diff --git a/chromecast/browser/cast_web_contents_impl.cc b/chromecast/browser/cast_web_contents_impl.cc index 833aca76..7486d64b 100644 --- a/chromecast/browser/cast_web_contents_impl.cc +++ b/chromecast/browser/cast_web_contents_impl.cc
@@ -444,6 +444,11 @@ bool CastWebContentsImpl::TryBindReceiver( mojo::GenericPendingReceiver& receiver) { + // First try binding local interfaces. + if (local_interfaces_.TryBindReceiver(receiver)) { + return true; + } + const std::string interface_name = *receiver.interface_name(); mojo::ScopedMessagePipeHandle interface_pipe = receiver.PassPipe(); @@ -468,6 +473,10 @@ return true; } +InterfaceBundle* CastWebContentsImpl::local_interfaces() { + return &local_interfaces_; +} + void CastWebContentsImpl::RegisterInterfaceProvider( const InterfaceSet& interface_set, service_manager::InterfaceProvider* interface_provider) {
diff --git a/chromecast/browser/cast_web_contents_impl.h b/chromecast/browser/cast_web_contents_impl.h index 4b9dbe5..032dbe0 100644 --- a/chromecast/browser/cast_web_contents_impl.h +++ b/chromecast/browser/cast_web_contents_impl.h
@@ -86,6 +86,7 @@ const InterfaceSet& interface_set, service_manager::InterfaceProvider* interface_provider) override; bool TryBindReceiver(mojo::GenericPendingReceiver& receiver) override; + InterfaceBundle* local_interfaces() override; void BlockMediaLoading(bool blocked) override; void BlockMediaStarting(bool blocked) override; void EnableBackgroundVideoPlayback(bool enabled) override; @@ -219,6 +220,7 @@ base::ObserverList<CastWebContentsObserver>::Unchecked observer_list_; + InterfaceBundle local_interfaces_; RemoteInterfaces remote_interfaces_; const scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/chromecast/browser/gesture_router.cc b/chromecast/browser/gesture_router.cc new file mode 100644 index 0000000..67f10e5 --- /dev/null +++ b/chromecast/browser/gesture_router.cc
@@ -0,0 +1,238 @@ +// Copyright 2021 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 "chromecast/browser/gesture_router.h" + +#include <utility> + +#include "base/bind.h" +#include "base/callback.h" +#include "chromecast/base/chromecast_switches.h" + +namespace chromecast { + +GestureRouter::GestureRouter() + : gesture_source_receiver_(this), + handler_(nullptr), + can_go_back_(false), + can_top_drag_(false), + can_right_drag_(false), + managed_mode_(GetSwitchValueBoolean(switches::kManagedMode, false)), + weak_factory_(this) {} + +GestureRouter::~GestureRouter() = default; + +bool GestureRouter::CanHandleGesture(GestureType gesture_type) { + switch (gesture_type) { + case GestureType::GO_BACK: + return CanGoBack(); + case GestureType::TAP: + return true; + case GestureType::TAP_DOWN: + return true; + case GestureType::TOP_DRAG: + return CanTopDrag(); + case GestureType::RIGHT_DRAG: + return CanRightDrag(); + default: + return false; + } +} + +void GestureRouter::GestureProgress(GestureType gesture_type, + const gfx::Point& touch_location) { + switch (gesture_type) { + case GestureType::GO_BACK: + if (!CanGoBack()) + return; + SendBackGestureProgress(touch_location); + break; + case GestureType::TOP_DRAG: + if (!CanTopDrag()) + return; + SendTopDragGestureProgress(touch_location); + break; + case GestureType::RIGHT_DRAG: + if (!CanRightDrag()) + return; + SendRightDragGestureProgress(touch_location); + break; + default: + return; + } +} + +void GestureRouter::CancelGesture(GestureType gesture_type) { + switch (gesture_type) { + case GestureType::GO_BACK: + if (!CanGoBack()) + return; + SendBackGestureCancel(); + break; + default: + return; + } +} + +void GestureRouter::ConsumeGesture(GestureType gesture_type, + GestureHandledCallback handled_callback) { + switch (gesture_type) { + case GestureType::NO_GESTURE: + std::move(handled_callback).Run(false); + break; + case GestureType::GO_BACK: + if (!CanGoBack()) { + std::move(handled_callback).Run(false); + return; + } + SendBackGesture(std::move(handled_callback)); + break; + case GestureType::TAP: + SendTapGesture(); + std::move(handled_callback).Run(true); + break; + case GestureType::TAP_DOWN: + SendTapDownGesture(); + std::move(handled_callback).Run(true); + break; + case GestureType::TOP_DRAG: + SendTopDragGestureDone(); + std::move(handled_callback).Run(true); + break; + case GestureType::RIGHT_DRAG: + SendRightDragGestureDone(); + std::move(handled_callback).Run(true); + break; + default: + std::move(handled_callback).Run(false); + } +} + +void GestureRouter::SetConsumeGestureCallback(ConsumerCallback callback) { + consumer_callback_ = callback; +} + +void GestureRouter::SetHandler(mojom::GestureHandler* handler) { + handler_ = handler; +} + +void GestureRouter::Subscribe( + mojo::PendingRemote<mojom::GestureHandler> pending_handler_remote) { + if (handler_remote_.is_bound()) { + handler_remote_.reset(); + } + handler_remote_.Bind(std::move(pending_handler_remote)); + SetHandler(handler_remote_.get()); +} + +void GestureRouter::SetCanGoBack(bool can_go_back) { + can_go_back_ = can_go_back; + if (delegate_) + delegate_->SetCanGoBack(can_go_back_); +} + +bool GestureRouter::CanGoBack() const { + return can_go_back_ && (consumer_callback_ || handler_); +} + +void GestureRouter::SendBackGesture( + base::OnceCallback<void(bool)> was_handled_callback) { + if (consumer_callback_) { + consumer_callback_.Run(GestureType::GO_BACK, + std::move(was_handled_callback)); + return; + } + if (!handler_) + return; + handler_->OnBackGesture(std::move(was_handled_callback)); +} + +void GestureRouter::SendBackGestureProgress(const gfx::Point& touch_location) { + if (!handler_) + return; + handler_->OnBackGestureProgress(touch_location); +} + +void GestureRouter::SendBackGestureCancel() { + if (!handler_) + return; + handler_->OnBackGestureCancel(); +} + +void GestureRouter::SetCanTopDrag(bool can_top_drag) { + can_top_drag_ = can_top_drag; +} + +bool GestureRouter::CanTopDrag() const { + return handler_ && can_top_drag_ && !managed_mode_; +} + +void GestureRouter::SendTopDragGestureDone() { + if (!handler_) + return; + handler_->OnTopDragGestureDone(); +} + +void GestureRouter::SendTopDragGestureProgress( + const gfx::Point& touch_location) { + if (!handler_) + return; + handler_->OnTopDragGestureProgress(touch_location); +} + +void GestureRouter::SetCanRightDrag(bool can_right_drag) { + can_right_drag_ = can_right_drag; +} + +bool GestureRouter::CanRightDrag() const { + return handler_ && can_right_drag_; +} + +void GestureRouter::SendRightDragGestureDone() { + if (!handler_) + return; + handler_->OnRightDragGestureDone(); +} + +void GestureRouter::SendRightDragGestureProgress( + const gfx::Point& touch_location) { + if (!handler_) + return; + handler_->OnRightDragGestureProgress(touch_location); +} + +void GestureRouter::SendTapGesture() { + if (!handler_) + return; + handler_->OnTapGesture(); +} + +void GestureRouter::SendTapDownGesture() { + if (!handler_) + return; + handler_->OnTapDownGesture(); +} + +void GestureRouter::SetBackGestureDelegate(Delegate* delegate) { + delegate_ = delegate; + if (delegate_) + delegate_->SetCanGoBack(can_go_back_); +} + +base::RepeatingCallback<void(mojo::PendingReceiver<mojom::GestureSource>)> +GestureRouter::GetBinder() { + return base::BindRepeating(&GestureRouter::BindGestureSource, + weak_factory_.GetWeakPtr()); +} + +void GestureRouter::BindGestureSource( + mojo::PendingReceiver<mojom::GestureSource> request) { + if (gesture_source_receiver_.is_bound()) { + LOG(WARNING) << "Gesture router is being re-bound."; + gesture_source_receiver_.reset(); + } + gesture_source_receiver_.Bind(std::move(request)); +} + +} // namespace chromecast
diff --git a/chromecast/browser/gesture_router.h b/chromecast/browser/gesture_router.h new file mode 100644 index 0000000..b0a4999 --- /dev/null +++ b/chromecast/browser/gesture_router.h
@@ -0,0 +1,110 @@ +// Copyright 2021 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 CHROMECAST_BROWSER_GESTURE_ROUTER_H_ +#define CHROMECAST_BROWSER_GESTURE_ROUTER_H_ + +#include "base/callback_forward.h" +#include "base/memory/weak_ptr.h" +#include "chromecast/browser/visibility_types.h" +#include "chromecast/common/mojom/gesture.mojom.h" +#include "chromecast/ui/back_gesture_router.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" + +namespace chromecast { + +// This class exposes Cast UI gesture hooks to JavaScript. The page notifies +// its ability to handle specific gestures, which allows this class to perform +// necessary routing. +class GestureRouter : private mojom::GestureSource, public BackGestureRouter { + public: + GestureRouter(); + GestureRouter(const GestureRouter&) = delete; + GestureRouter& operator=(const GestureRouter&) = delete; + ~GestureRouter() override; + + using GestureHandledCallback = base::OnceCallback<void(bool)>; + + using ConsumerCallback = + base::RepeatingCallback<void(GestureType, GestureHandledCallback)>; + + // Check to see if the gesture can be handled by JS. This is called prior to + // ConsumeGesture(). + bool CanHandleGesture(GestureType gesture_type); + + // Called while a system UI gesture is in progress. + void GestureProgress(GestureType gesture_type, + const gfx::Point& touch_location); + + // Called when an in-progress system UI gesture is cancelled (for example + // when the finger is lifted before the completion of the gesture.) + void CancelGesture(GestureType gesture_type); + + // Consume and handle a completed UI gesture. Invokes the callback with a + // boolean indicating whether the gesture was handled or not. + void ConsumeGesture(GestureType gesture_type, + GestureHandledCallback handled_callback); + + // Registers an in-process gesture consumer. If set, this supersedes the + // mojo handler path. This can be called multiple times, overriding a + // previously registered callback. + void SetConsumeGestureCallback(ConsumerCallback callback); + + // mojom::GestureSource implementation: + void Subscribe(mojo::PendingRemote<mojom::GestureHandler> + pending_handler_remote) override; + void SetCanGoBack(bool can_go_back) override; + void SetCanTopDrag(bool can_top_drag) override; + void SetCanRightDrag(bool can_right_drag) override; + + bool CanGoBack() const; + void SendBackGesture(base::OnceCallback<void(bool)> was_handled_callback); + void SendBackGestureProgress(const gfx::Point& touch_location); + void SendBackGestureCancel(); + bool CanTopDrag() const; + void SendTopDragGestureProgress(const gfx::Point& touch_location); + void SendTopDragGestureDone(); + bool CanRightDrag() const; + void SendRightDragGestureProgress(const gfx::Point& touch_location); + void SendRightDragGestureDone(); + void SendTapGesture(); + void SendTapDownGesture(); + + // BackGestureRouter overrides: + void SetBackGestureDelegate(Delegate* delegate) override; + + base::RepeatingCallback<void(mojo::PendingReceiver<mojom::GestureSource>)> + GetBinder(); + + private: + friend class CastContentGestureHandlerTest; + friend class CastContentWindowEmbeddedTest; + + // Helper method for unit tests. Instead of having to register an async + // subscriber, tests can use SetHandler() to register a mock instead. This + // can be called multiple times. + void SetHandler(mojom::GestureHandler* handler); + + void BindGestureSource(mojo::PendingReceiver<mojom::GestureSource> request); + + mojo::Receiver<mojom::GestureSource> gesture_source_receiver_; + mojo::Remote<mojom::GestureHandler> handler_remote_; + mojom::GestureHandler* handler_; + + bool can_go_back_; + bool can_top_drag_; + bool can_right_drag_; + bool managed_mode_; // If in managed mode, disable top drag. + Delegate* delegate_ = nullptr; + + ConsumerCallback consumer_callback_; + + base::WeakPtrFactory<GestureRouter> weak_factory_; +}; + +} // namespace chromecast + +#endif // CHROMECAST_BROWSER_GESTURE_ROUTER_H_
diff --git a/chromecast/browser/service/cast_service_simple.cc b/chromecast/browser/service/cast_service_simple.cc index 2a08934..276915f7 100644 --- a/chromecast/browser/service/cast_service_simple.cc +++ b/chromecast/browser/service/cast_service_simple.cc
@@ -90,16 +90,6 @@ void CastServiceSimple::OnWindowDestroyed() {} -bool CastServiceSimple::CanHandleGesture(GestureType gesture_type) { - return false; -} - -void CastServiceSimple::ConsumeGesture( - GestureType gesture_type, - GestureHandledCallback handled_callback) { - std::move(handled_callback).Run(false); -} - void CastServiceSimple::OnVisibilityChange(VisibilityType visibility_type) {} } // namespace shell
diff --git a/chromecast/browser/service/cast_service_simple.h b/chromecast/browser/service/cast_service_simple.h index c1d70bd..f3d64aef 100644 --- a/chromecast/browser/service/cast_service_simple.h +++ b/chromecast/browser/service/cast_service_simple.h
@@ -45,9 +45,6 @@ // CastContentWindow::Delegate implementation: void OnWindowDestroyed() override; - bool CanHandleGesture(GestureType gesture_type) override; - void ConsumeGesture(GestureType gesture_type, - GestureHandledCallback handled_callback) override; void OnVisibilityChange(VisibilityType visibility_type) override; private:
diff --git a/chromecast/browser/test/cast_browser_test.cc b/chromecast/browser/test/cast_browser_test.cc index e9cb887..a3c70465 100644 --- a/chromecast/browser/test/cast_browser_test.cc +++ b/chromecast/browser/test/cast_browser_test.cc
@@ -90,14 +90,5 @@ void CastBrowserTest::OnVisibilityChange(VisibilityType visibility_type) {} -bool CastBrowserTest::CanHandleGesture(GestureType gesture_type) { - return false; -} - -void CastBrowserTest::ConsumeGesture(GestureType gesture_type, - GestureHandledCallback handled_callback) { - std::move(handled_callback).Run(false); -} - } // namespace shell } // namespace chromecast
diff --git a/chromecast/browser/test/cast_browser_test.h b/chromecast/browser/test/cast_browser_test.h index 3e494c85..5fc8f367 100644 --- a/chromecast/browser/test/cast_browser_test.h +++ b/chromecast/browser/test/cast_browser_test.h
@@ -53,9 +53,6 @@ // CastWebView::Delegate implementation: void OnWindowDestroyed() override; void OnVisibilityChange(VisibilityType visibility_type) override; - bool CanHandleGesture(GestureType gesture_type) override; - void ConsumeGesture(GestureType gesture_type, - GestureHandledCallback handled_callback) override; std::unique_ptr<CastWebViewFactory> web_view_factory_; std::unique_ptr<CastWebService> web_service_;
diff --git a/chromecast/browser/test/mock_cast_content_window_delegate.h b/chromecast/browser/test/mock_cast_content_window_delegate.h index 4c0b157..ce5b1f988 100644 --- a/chromecast/browser/test/mock_cast_content_window_delegate.h +++ b/chromecast/browser/test/mock_cast_content_window_delegate.h
@@ -18,14 +18,8 @@ MockCastContentWindowDelegate(); ~MockCastContentWindowDelegate() override; - MOCK_METHOD1(CanHandleGesture, bool(GestureType gesture_type)); - MOCK_METHOD2(ConsumeGesture, - void(GestureType gesture_type, - GestureHandledCallback handled_callback)); - MOCK_METHOD1(CancelGesture, void(GestureType gesture_type)); - MOCK_METHOD2(GestureProgress, - void(GestureType gesture_type, - const gfx::Point& touch_location)); + MOCK_METHOD(void, OnWindowDestroyed, (), (override)); + MOCK_METHOD(void, OnVisibilityChange, (VisibilityType), (override)); }; } // namespace chromecast
diff --git a/chromecast/browser/test/mock_cast_web_view.h b/chromecast/browser/test/mock_cast_web_view.h index e998db15..4563d69 100644 --- a/chromecast/browser/test/mock_cast_web_view.h +++ b/chromecast/browser/test/mock_cast_web_view.h
@@ -64,6 +64,7 @@ (override)); MOCK_METHOD(void, SetEnabledForRemoteDebugging, (bool), (override)); MOCK_METHOD(void, GetMainFramePid, (GetMainFramePidCallback), (override)); + MOCK_METHOD(InterfaceBundle*, local_interfaces, (), (override)); MOCK_METHOD(void, RegisterInterfaceProvider, (const InterfaceSet&, service_manager::InterfaceProvider*),
diff --git a/chromecast/browser/webview/cast_content_window_embedded.cc b/chromecast/browser/webview/cast_content_window_embedded.cc index 9f72bcf..a5c179a 100644 --- a/chromecast/browser/webview/cast_content_window_embedded.cc +++ b/chromecast/browser/webview/cast_content_window_embedded.cc
@@ -163,8 +163,8 @@ if (request.navigation && request.navigation.value() == CastWindowEmbedder::NavigationType::GO_BACK) { - if (delegate_ && delegate_->CanHandleGesture(GestureType::GO_BACK)) { - delegate_->ConsumeGesture( + if (gesture_router()->CanHandleGesture(GestureType::GO_BACK)) { + gesture_router()->ConsumeGesture( GestureType::GO_BACK, base::BindOnce(&CastContentWindowEmbedded::ConsumeGestureCompleted, base::Unretained(this))); @@ -201,17 +201,18 @@ } if (request.back_gesture_progress_event) { - if (delegate_ && delegate_->CanHandleGesture(GestureType::GO_BACK)) - delegate_->GestureProgress( + if (gesture_router()->CanHandleGesture(GestureType::GO_BACK)) { + gesture_router()->GestureProgress( GestureType::GO_BACK, gfx::Point(request.back_gesture_progress_event.value().x, request.back_gesture_progress_event.value().y)); + } return; } if (request.back_gesture_cancel_event) { - if (delegate_ && delegate_->CanHandleGesture(GestureType::GO_BACK)) - delegate_->CancelGesture(GestureType::GO_BACK); + if (gesture_router()->CanHandleGesture(GestureType::GO_BACK)) + gesture_router()->CancelGesture(GestureType::GO_BACK); return; } }
diff --git a/chromecast/browser/webview/cast_content_window_embedded_unittest.cc b/chromecast/browser/webview/cast_content_window_embedded_unittest.cc index 95014353..dee0064 100644 --- a/chromecast/browser/webview/cast_content_window_embedded_unittest.cc +++ b/chromecast/browser/webview/cast_content_window_embedded_unittest.cc
@@ -125,18 +125,17 @@ .Times(1) .WillOnce(Return(fake_window_id /* window_id */)); - EXPECT_CALL(*mock_cast_content_window_delegate_, - CanHandleGesture(GestureType::GO_BACK)) - .Times(1) - .WillOnce(Return(true)); + cast_content_window_embedded_ = std::make_unique<CastContentWindowEmbedded>( + mock_cast_content_window_delegate_->AsWeakPtr(), GenerateParams(), + cast_window_embedder_.get(), false /* force_720p_resolution */); - // Delegate of the CastContentWindow indicts that it has handled the event. - EXPECT_CALL(*mock_cast_content_window_delegate_, ConsumeGesture(_, _)) - .Times(1) - .WillOnce([](GestureType gesture_type, - base::OnceCallback<void(bool)> consume_gesture_completed) { - std::move(consume_gesture_completed).Run(true); - }); + cast_content_window_embedded_->gesture_router()->SetCanGoBack(true); + cast_content_window_embedded_->gesture_router()->SetConsumeGestureCallback( + base::BindRepeating( + [](GestureType gesture_type, + base::OnceCallback<void(bool)> consume_gesture_completed) { + std::move(consume_gesture_completed).Run(true); + })); // CastWindowEmbedder shall receive the ack of event handling EXPECT_CALL( @@ -145,10 +144,6 @@ fake_window_id, _, true, CastWindowEmbedder::NavigationType::GO_BACK)) .Times(1); - cast_content_window_embedded_ = std::make_unique<CastContentWindowEmbedded>( - mock_cast_content_window_delegate_->AsWeakPtr(), GenerateParams(), - cast_window_embedder_.get(), false /* force_720p_resolution */); - CastWindowEmbedder::EmbedderWindowEvent window_event; window_event.window_id = 1; window_event.navigation = CastWindowEmbedder::NavigationType::GO_BACK; @@ -167,19 +162,20 @@ .Times(1) .WillOnce(Return(fake_window_id /* window_id */)); - EXPECT_CALL(*mock_cast_content_window_delegate_, - CanHandleGesture(GestureType::GO_BACK)) - .Times(1) - .WillOnce(Return(true)); + cast_content_window_embedded_ = std::make_unique<CastContentWindowEmbedded>( + mock_cast_content_window_delegate_->AsWeakPtr(), GenerateParams(), + cast_window_embedder_.get(), false /* force_720p_resolution */); + + cast_content_window_embedded_->gesture_router()->SetCanGoBack(true); // Delegate of the CastContentWindow indicts that it dit not handle the // event. - EXPECT_CALL(*mock_cast_content_window_delegate_, ConsumeGesture(_, _)) - .Times(1) - .WillOnce([](GestureType gesture_type, - base::OnceCallback<void(bool)> consume_gesture_completed) { - std::move(consume_gesture_completed).Run(false /* handled */); - }); + cast_content_window_embedded_->gesture_router()->SetConsumeGestureCallback( + base::BindRepeating( + [](GestureType gesture_type, + base::OnceCallback<void(bool)> consume_gesture_completed) { + std::move(consume_gesture_completed).Run(false); + })); // CastWindowEmbedder shall receive the ack of event handling EXPECT_CALL(*cast_window_embedder_, @@ -188,10 +184,6 @@ CastWindowEmbedder::NavigationType::GO_BACK)) .Times(1); - cast_content_window_embedded_ = std::make_unique<CastContentWindowEmbedded>( - mock_cast_content_window_delegate_->AsWeakPtr(), GenerateParams(), - cast_window_embedder_.get(), false /* force_720p_resolution */); - CastWindowEmbedder::EmbedderWindowEvent window_event; window_event.window_id = 1; window_event.navigation = CastWindowEmbedder::NavigationType::GO_BACK; @@ -210,15 +202,11 @@ .Times(1) .WillOnce(Return(fake_window_id /* window_id */)); - EXPECT_CALL(*mock_cast_content_window_delegate_, - CanHandleGesture(GestureType::GO_BACK)) - .Times(1) - .WillOnce(Return(false)); + cast_content_window_embedded_ = std::make_unique<CastContentWindowEmbedded>( + mock_cast_content_window_delegate_->AsWeakPtr(), GenerateParams(), + cast_window_embedder_.get(), false /* force_720p_resolution */); - // Delegate of the CastContentWindow indicts that it dit not handled the - // event. - EXPECT_CALL(*mock_cast_content_window_delegate_, ConsumeGesture(_, _)) - .Times(0); + cast_content_window_embedded_->gesture_router()->SetCanGoBack(false); // CastWindowEmbedder shall receive the ack of event handling EXPECT_CALL(*cast_window_embedder_, @@ -227,10 +215,6 @@ CastWindowEmbedder::NavigationType::GO_BACK)) .Times(1); - cast_content_window_embedded_ = std::make_unique<CastContentWindowEmbedded>( - mock_cast_content_window_delegate_->AsWeakPtr(), GenerateParams(), - cast_window_embedder_.get(), false /* force_720p_resolution */); - CastWindowEmbedder::EmbedderWindowEvent window_event; window_event.window_id = 1; window_event.navigation = CastWindowEmbedder::NavigationType::GO_BACK;
diff --git a/chromecast/cast_core/runtime_application_base.cc b/chromecast/cast_core/runtime_application_base.cc index 7c2d08e..8f6d425 100644 --- a/chromecast/cast_core/runtime_application_base.cc +++ b/chromecast/cast_core/runtime_application_base.cc
@@ -158,10 +158,6 @@ return web_service_->CreateWebViewInternal(create_params, std::move(params)); } -bool RuntimeApplicationBase::CanHandleGesture(GestureType gesture_type) { - return false; -} - void RuntimeApplicationBase::StopApplication() { is_application_stopped_ = true; @@ -194,10 +190,4 @@ set_cast_session_id(std::string()); } -void RuntimeApplicationBase::ConsumeGesture( - GestureType gesture_type, - GestureHandledCallback handled_callback) { - std::move(handled_callback).Run(false); -} - } // namespace chromecast
diff --git a/chromecast/cast_core/runtime_application_base.h b/chromecast/cast_core/runtime_application_base.h index 6fb5c8e..56dde1b 100644 --- a/chromecast/cast_core/runtime_application_base.h +++ b/chromecast/cast_core/runtime_application_base.h
@@ -80,11 +80,6 @@ // Called following Launch() on |task_runner_|. void FinishLaunch(std::string core_application_service_endpoint); - // CastWebView::Delegate implementation: - bool CanHandleGesture(GestureType gesture_type) override; - void ConsumeGesture(GestureType gesture_type, - GestureHandledCallback handled_callback) override; - // RuntimeMessagePortApplicationServiceDelegate implementation: void PostMessage(const cast::web::Message& request, cast::web::MessagePortStatus* response,
diff --git a/chromecast/common/feature_constants.cc b/chromecast/common/feature_constants.cc index b4ff4883..b4a8e17 100644 --- a/chromecast/common/feature_constants.cc +++ b/chromecast/common/feature_constants.cc
@@ -10,6 +10,17 @@ const char kEnableTrackControlAppRendererFeatureUse[] = "track_control_renderer_feature_use"; const char kEnablePlayready[] = "playready"; +const char kEnableDevMode[] = "dev_mode"; +const char kDevModeOrigin[] = "dev_mode_origin"; +const char kEnableAccessibilityControls[] = "accessibility_controls"; +const char kEnableSystemGestures[] = "system_gestures"; +const char kEnableWindowControls[] = "enable_window_controls"; +const char kEnableSettingsUiMojo[] = "enable_settings_ui_mojo"; +const char kDisableBackgroundTabTimerThrottle[] = + "disable_background_tab_timer_throttle"; +const char kDisableBackgroundSuspend[] = "disable_background_suspend"; +const char kEnableAssistantMessagePipe[] = "enable_assistant_message_pipe"; +const char kEnableDemoStandaloneMode[] = "enable_demo_standalone_mode"; const char kKeyAppId[] = "app_id"; const char kKeyAllowInsecureContent[] = "allow_insecure_content";
diff --git a/chromecast/common/feature_constants.h b/chromecast/common/feature_constants.h index 2b821574..1e667c9d 100644 --- a/chromecast/common/feature_constants.h +++ b/chromecast/common/feature_constants.h
@@ -20,6 +20,37 @@ // Insecure content is allowed for the app. extern const char kKeyAllowInsecureContent[]; +// If dev mode is enabled, kDevModeOrigin will be set with origin url +extern const char kEnableDevMode[]; +extern const char kDevModeOrigin[]; + +// Permit changes to accessibility control settings? +// (color inversion, high contrast text, etc.) +extern const char kEnableAccessibilityControls[]; + +// Permit subscription to platform system gesture events? +extern const char kEnableSystemGestures[]; + +// Enables window APIs for the webpage (show/hide, etc.) +extern const char kEnableWindowControls[]; + +// Enable mojo connection for the settings UI. +extern const char kEnableSettingsUiMojo[]; + +// Disable blink background tab timer throttling for making sure application in +// in mini tile mode runs smoothly. +extern const char kDisableBackgroundTabTimerThrottle[]; + +// Sets RenderFrameMediaPlaybackOptions::kIsBackgroundMediaSuspendEnabled to +// false. +extern const char kDisableBackgroundSuspend[]; + +// Enable sending/receiving messages to/from libassistant +extern const char kEnableAssistantMessagePipe[]; + +// Enable a standalone demo app to control privileged features. +extern const char kEnableDemoStandaloneMode[]; + } // namespace feature } // namespace chromecast
diff --git a/chromecast/mojo/interface_bundle.h b/chromecast/mojo/interface_bundle.h index 94a2fec4..20afa1f 100644 --- a/chromecast/mojo/interface_bundle.h +++ b/chromecast/mojo/interface_bundle.h
@@ -12,6 +12,7 @@ #include "base/sequence_checker.h" #include "chromecast/mojo/binder_factory.h" #include "chromecast/mojo/mojom/remote_interfaces.mojom.h" +#include "mojo/public/cpp/bindings/generic_pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote.h" @@ -123,6 +124,17 @@ void AddClient( mojo::PendingReceiver<mojom::RemoteInterfaces> receiver) override; + // Attempt to bind a generic receiver. Succeeds if there is an available + // implementation or binder callback registered. + bool TryBindReceiver(mojo::GenericPendingReceiver& receiver) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (local_interfaces_.HasInterface(*receiver.interface_name())) { + local_interfaces_.Bind(*receiver.interface_name(), receiver.PassPipe()); + return true; + } + return false; + } + private: // For interfaces that are provided as a local pointer without any binding // logic, we can use MultiBinderFactory to expose a binding surface.
diff --git a/chromecast/renderer/BUILD.gn b/chromecast/renderer/BUILD.gn index 41454ad..07344599 100644 --- a/chromecast/renderer/BUILD.gn +++ b/chromecast/renderer/BUILD.gn
@@ -36,16 +36,26 @@ sources = [ "activity_filtering_websocket_handshake_throttle.cc", "activity_filtering_websocket_handshake_throttle.h", + "assistant_bindings.cc", + "assistant_bindings.h", + "cast_accessibility_bindings.cc", + "cast_accessibility_bindings.h", "cast_activity_url_filter_manager.cc", "cast_activity_url_filter_manager.h", "cast_content_renderer_client.cc", "cast_content_renderer_client.h", "cast_content_settings_client.cc", "cast_content_settings_client.h", + "cast_demo_bindings.cc", + "cast_demo_bindings.h", "cast_url_loader_throttle_provider.cc", "cast_url_loader_throttle_provider.h", "cast_websocket_handshake_throttle_provider.cc", "cast_websocket_handshake_throttle_provider.h", + "cast_window_manager_bindings.cc", + "cast_window_manager_bindings.h", + "feature_manager.cc", + "feature_manager.h", "feature_manager_on_associated_interface.cc", "feature_manager_on_associated_interface.h", "identification_settings_manager_renderer.cc", @@ -57,10 +67,13 @@ "native_bindings_helper.h", "queryable_data_store.cc", "queryable_data_store.h", + "settings_ui_bindings.cc", + "settings_ui_bindings.h", ] public_deps = [ "//chromecast:chromecast_buildflags", + "//chromecast/browser/mojom", "//chromecast/common/mojom", "//content/public/renderer", "//media",
diff --git a/chromecast/renderer/DEPS b/chromecast/renderer/DEPS index 8610ff45..592c935 100644 --- a/chromecast/renderer/DEPS +++ b/chromecast/renderer/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+chromecast/browser/mojom", "+chromecast/common", "+chromecast/crash", "+chromecast/media",
diff --git a/chromecast/renderer/assistant_bindings.cc b/chromecast/renderer/assistant_bindings.cc new file mode 100644 index 0000000..55484f70 --- /dev/null +++ b/chromecast/renderer/assistant_bindings.cc
@@ -0,0 +1,169 @@ +// Copyright 2021 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 "chromecast/renderer/assistant_bindings.h" + +#include "base/check.h" +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/logging.h" +#include "base/stl_util.h" +#include "base/time/time.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_thread.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/web/blink.h" +#include "third_party/blink/public/web/web_local_frame.h" + +namespace chromecast { +namespace shell { + +namespace { + +const int kMaxMessageQueueSize = 50; +static const int64_t kDelayBetweenReconnectionInMillis = 100; + +const char kSetAssistantMessageHandlerMethodName[] = + "setAssistantMessageHandler"; +const char kSendAssistantRequestMethodName[] = "sendAssistantRequest"; + +} // namespace + +AssistantBindings::AssistantBindings(content::RenderFrame* frame, + const base::Value& feature_config) + : CastBinding(frame), + feature_config_(feature_config.Clone()), + message_client_binding_(this), + weak_factory_(this) { + weak_this_ = weak_factory_.GetWeakPtr(); +} + +AssistantBindings::~AssistantBindings() {} + +void AssistantBindings::OnMessage(base::Value message) { + if (assistant_message_handler_.IsEmpty()) { + return; + } + + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::MicrotasksScope microtasks_scope( + isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::HandleScope handle_scope(isolate); + blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame(); + v8::Local<v8::Context> context = web_frame->MainWorldScriptContext(); + v8::Context::Scope context_scope(context); + + v8::Local<v8::Function> handler = v8::Local<v8::Function>::New( + isolate, std::move(assistant_message_handler_)); + + std::string json; + base::JSONWriter::Write(message, &json); + v8::Local<v8::Value> message_val = + gin::Converter<std::string>::ToV8(isolate, json); + + v8::Local<v8::Value> argv[] = {message_val}; + web_frame->CallFunctionEvenIfScriptDisabled(handler, context->Global(), + base::size(argv), argv); + + assistant_message_handler_ = + v8::UniquePersistent<v8::Function>(isolate, handler); +} + +void AssistantBindings::Install(v8::Local<v8::Object> cast_platform, + v8::Isolate* isolate) { + DVLOG(1) << "Installing AssistantBindings"; + + InstallBinding(isolate, cast_platform, kSetAssistantMessageHandlerMethodName, + &AssistantBindings::SetAssistantMessageHandler, + base::Unretained(this)); + InstallBinding(isolate, cast_platform, kSendAssistantRequestMethodName, + &AssistantBindings::SendAssistantRequest, + base::Unretained(this)); +} + +void AssistantBindings::SetAssistantMessageHandler( + v8::Local<v8::Function> assistant_message_handler) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + assistant_message_handler_ = + v8::UniquePersistent<v8::Function>(isolate, assistant_message_handler); + ReconnectMessagePipe(); +} + +void AssistantBindings::SendAssistantRequest(const std::string& request) { + if (assistant_message_handler_.IsEmpty()) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + isolate->ThrowException( + v8::String::NewFromUtf8(isolate, + "Error: assistant message handler is not set.", + v8::NewStringType::kInternalized) + .ToLocalChecked()); + return; + } + if (!message_pipe_.is_bound()) { + if (v8_to_assistant_queue_.size() < kMaxMessageQueueSize) { + v8_to_assistant_queue_.push_back(request); + } else { + LOG(WARNING) << "Messages sending to assistant overflow, will drop " + "upcoming messages"; + } + return; + } + + v8_to_assistant_queue_.push_back(request); + FlushV8ToAssistantQueue(); +} + +void AssistantBindings::ReconnectMessagePipe() { + if (message_client_binding_.is_bound()) + message_client_binding_.reset(); + if (message_pipe_.is_bound()) + message_pipe_.reset(); + LOG(INFO) << "Creating message pipe"; + base::Value* app_id = + feature_config_.FindKeyOfType("app_id", base::Value::Type::STRING); + DCHECK(app_id) << "Couldn't get app_id from feature config"; + GetMojoInterface()->CreateMessagePipe( + app_id->GetString(), message_client_binding_.BindNewPipeAndPassRemote(), + message_pipe_.BindNewPipeAndPassReceiver()); + + reconnect_assistant_timer_.Stop(); +} + +void AssistantBindings::OnAssistantConnectionError() { + LOG(WARNING) << "Disconnected from assistant. Will reconnect every " + << kDelayBetweenReconnectionInMillis << " milliseconds"; + assistant_.reset(); + reconnect_assistant_timer_.Start( + FROM_HERE, + base::TimeDelta::FromMilliseconds(kDelayBetweenReconnectionInMillis), + this, &AssistantBindings::ReconnectMessagePipe); +} + +void AssistantBindings::FlushV8ToAssistantQueue() { + DCHECK(message_pipe_.is_bound()); + + for (auto& request : v8_to_assistant_queue_) { + auto value = base::JSONReader::Read(request); + if (!value) { + LOG(ERROR) << "Unable to parse Assistant message JSON."; + continue; + } + message_pipe_->SendMessage(std::move(*value)); + } + v8_to_assistant_queue_.clear(); +} + +const mojo::Remote<chromecast::mojom::AssistantMessageService>& +AssistantBindings::GetMojoInterface() { + if (!assistant_.is_bound()) { + render_frame()->GetBrowserInterfaceBroker()->GetInterface( + assistant_.BindNewPipeAndPassReceiver()); + assistant_.set_disconnect_handler(base::BindOnce( + &AssistantBindings::OnAssistantConnectionError, weak_this_)); + } + return assistant_; +} + +} // namespace shell +} // namespace chromecast
diff --git a/chromecast/renderer/assistant_bindings.h b/chromecast/renderer/assistant_bindings.h new file mode 100644 index 0000000..d243d92 --- /dev/null +++ b/chromecast/renderer/assistant_bindings.h
@@ -0,0 +1,74 @@ +// Copyright 2021 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 CHROMECAST_RENDERER_ASSISTANT_BINDINGS_H_ +#define CHROMECAST_RENDERER_ASSISTANT_BINDINGS_H_ + +#include <string> +#include <vector> + +#include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" +#include "chromecast/common/mojom/assistant_messenger.mojom.h" +#include "chromecast/renderer/native_bindings_helper.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" + +namespace chromecast { +namespace shell { + +// When enabled, these bindings can be used to open a message channel with the +// Assistant. These bindings are only enabled for a small set of first-party +// apps. +class AssistantBindings : public CastBinding, + public chromecast::mojom::AssistantMessageClient { + public: + AssistantBindings(content::RenderFrame* frame, + const base::Value& feature_config); + ~AssistantBindings() override; + AssistantBindings(const AssistantBindings&) = delete; + AssistantBindings& operator=(const AssistantBindings&) = delete; + + private: + friend class ::chromecast::CastBinding; + + // chromecast::mojom::AssistantMessageClient implementation: + void OnMessage(base::Value message) override; + + // CastBinding implementation: + void Install(v8::Local<v8::Object> cast_platform, + v8::Isolate* isolate) override; + + // Binding methods + void SetAssistantMessageHandler( + v8::Local<v8::Function> assistant_message_handler); + void SendAssistantRequest(const std::string& request); + + void ReconnectMessagePipe(); + void OnAssistantConnectionError(); + + void FlushV8ToAssistantQueue(); + + const mojo::Remote<chromecast::mojom::AssistantMessageService>& + GetMojoInterface(); + + base::RepeatingTimer reconnect_assistant_timer_; + mojo::Remote<chromecast::mojom::AssistantMessageService> assistant_; + base::Value feature_config_; + + mojo::Receiver<chromecast::mojom::AssistantMessageClient> + message_client_binding_; + mojo::Remote<chromecast::mojom::AssistantMessagePipe> message_pipe_; + std::vector<std::string> v8_to_assistant_queue_; + + v8::UniquePersistent<v8::Function> assistant_message_handler_; + + base::WeakPtr<AssistantBindings> weak_this_; + base::WeakPtrFactory<AssistantBindings> weak_factory_; +}; + +} // namespace shell +} // namespace chromecast + +#endif // CHROMECAST_RENDERER_ASSISTANT_BINDINGS_H_
diff --git a/chromecast/renderer/cast_accessibility_bindings.cc b/chromecast/renderer/cast_accessibility_bindings.cc new file mode 100644 index 0000000..cbe9791 --- /dev/null +++ b/chromecast/renderer/cast_accessibility_bindings.cc
@@ -0,0 +1,243 @@ +// Copyright 2021 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 "chromecast/renderer/cast_accessibility_bindings.h" + +#include <vector> + +#include "base/bind.h" +#include "base/logging.h" +#include "chromecast/common/feature_constants.h" +#include "chromecast/renderer/feature_manager.h" +#include "content/public/renderer/render_frame.h" +#include "gin/data_object_builder.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/web/blink.h" +#include "third_party/blink/public/web/web_local_frame.h" + +namespace chromecast { +namespace shell { + +namespace { + +constexpr char kBindingsObjectName[] = "accessibility"; +constexpr char kSetColorInversionName[] = "setColorInversion"; +constexpr char kSetScreenReaderName[] = "setScreenReader"; +constexpr char kSetMagnificationGestureName[] = "setMagnificationGesture"; +constexpr char kGetAccessibilitySettings[] = "getAccessibilitySettings"; +constexpr char kIsColorInversionEnabled[] = "isColorInversionEnabled"; +constexpr char kIsScreenReaderEnabled[] = "isScreenReaderEnabled"; +constexpr char kIsMagnificationGestureEnabled[] = + "isMagnificationGestureEnabled"; +constexpr char kScreenReaderSettingChangedHandler[] = + "setScreenReaderSettingChangedHandler"; +constexpr char kColorInversionSettingChangedHandler[] = + "setColorInversionSettingChangedHandler"; +constexpr char kMagnificationGestureSettingChangedHandler[] = + "setMagnificationGestureSettingChangedHandler"; + +void OnAccessibilityServiceConnectionError() { + LOG(ERROR) << "Connection error talking to accessibility manager."; +} + +} // namespace + +CastAccessibilityBindings::CastAccessibilityBindings( + content::RenderFrame* render_frame, + const FeatureManager* feature_manager) + : CastBinding(render_frame), feature_manager_(feature_manager) { + registry_.AddInterface(base::BindRepeating( + &CastAccessibilityBindings::OnCastAccessibilityClientRequest, + base::Unretained(this))); +} + +CastAccessibilityBindings::~CastAccessibilityBindings() {} + +void CastAccessibilityBindings::OnInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle* interface_pipe) { + registry_.TryBindInterface(interface_name, interface_pipe); +} + +void CastAccessibilityBindings::Install(v8::Local<v8::Object> cast_platform, + v8::Isolate* isolate) { + v8::Local<v8::Object> AccessibilityObject = + EnsureObjectExists(isolate, cast_platform, kBindingsObjectName); + + if (feature_manager_->FeatureEnabled(feature::kEnableAccessibilityControls)) { + InstallBinding(isolate, AccessibilityObject, kSetColorInversionName, + &CastAccessibilityBindings::SetColorInversion, + base::Unretained(this)); + InstallBinding(isolate, AccessibilityObject, kSetScreenReaderName, + &CastAccessibilityBindings::SetScreenReader, + base::Unretained(this)); + InstallBinding(isolate, AccessibilityObject, kSetMagnificationGestureName, + &CastAccessibilityBindings::SetMagnificationGesture, + base::Unretained(this)); + } + // Getters and callback are always available. + InstallBinding(isolate, AccessibilityObject, kGetAccessibilitySettings, + &CastAccessibilityBindings::GetAccessibilitySettings, + base::Unretained(this)); + InstallBinding( + isolate, AccessibilityObject, kScreenReaderSettingChangedHandler, + &CastAccessibilityBindings::SetScreenReaderSettingChangedHandler, + base::Unretained(this)); + InstallBinding( + isolate, AccessibilityObject, kColorInversionSettingChangedHandler, + &CastAccessibilityBindings::SetColorInversionSettingChangedHandler, + base::Unretained(this)); + InstallBinding( + isolate, AccessibilityObject, kMagnificationGestureSettingChangedHandler, + &CastAccessibilityBindings::SetMagnificationGestureSettingChangedHandler, + base::Unretained(this)); +} + +void CastAccessibilityBindings::SetColorInversion(bool enable) { + if (!BindAccessibility()) + return; + accessibility_service_->SetColorInversion(enable); +} + +void CastAccessibilityBindings::SetScreenReader(bool enable) { + if (!BindAccessibility()) + return; + accessibility_service_->SetScreenReader(enable); +} + +void CastAccessibilityBindings::SetMagnificationGesture(bool enable) { + if (!BindAccessibility()) + return; + accessibility_service_->SetMagnificationGestureEnabled(enable); +} + +v8::Local<v8::Value> CastAccessibilityBindings::GetAccessibilitySettings() { + DVLOG(2) << __FUNCTION__; + v8::Isolate* isolate = blink::MainThreadIsolate(); + + if (!BindAccessibility()) + return gin::ConvertToV8(isolate, false); + + v8::Local<v8::Promise::Resolver> resolver = + v8::Promise::Resolver::New(isolate->GetCurrentContext()).ToLocalChecked(); + + PersistedResolver unique_resolver = + v8::Global<v8::Promise::Resolver>(isolate, resolver); + PersistedContext context(isolate, isolate->GetCurrentContext()); + + accessibility_service_->GetAccessibilitySettings(base::BindOnce( + &CastAccessibilityBindings::OnGetAccessibilitySettings, + base::Unretained(this), std::move(unique_resolver), std::move(context))); + return resolver->GetPromise(); +} + +void CastAccessibilityBindings::SetScreenReaderSettingChangedHandler( + v8::Local<v8::Function> handler) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + screen_reader_setting_changed_handler_ = + v8::UniquePersistent<v8::Function>(isolate, handler); +} + +void CastAccessibilityBindings::SetColorInversionSettingChangedHandler( + v8::Local<v8::Function> handler) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + color_inversion_setting_changed_handler_ = + v8::UniquePersistent<v8::Function>(isolate, handler); +} + +void CastAccessibilityBindings::SetMagnificationGestureSettingChangedHandler( + v8::Local<v8::Function> handler) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + magnification_gesture_setting_changed_handler_ = + v8::UniquePersistent<v8::Function>(isolate, handler); +} + +bool CastAccessibilityBindings::BindAccessibility() { + if (!accessibility_service_) { + render_frame()->GetBrowserInterfaceBroker()->GetInterface( + accessibility_service_.BindNewPipeAndPassReceiver()); + if (!accessibility_service_) { + LOG(ERROR) + << "Couldn't establish connection to cast window manager service"; + return false; + } + accessibility_service_.set_disconnect_handler( + base::BindRepeating(&OnAccessibilityServiceConnectionError)); + } + return true; +} + +void CastAccessibilityBindings::OnGetAccessibilitySettings( + PersistedResolver resolver, + PersistedContext original_context, + mojom::AccessibilitySettingsPtr settings) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::MicrotasksScope microtasks_scope( + isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Context> context = original_context.Get(isolate); + v8::Context::Scope context_scope(context); + + v8::Local<v8::Object> obj = + gin::DataObjectBuilder(isolate) + .Set(kIsColorInversionEnabled, settings->color_inversion_enabled) + .Set(kIsScreenReaderEnabled, settings->screen_reader_enabled) + .Set(kIsMagnificationGestureEnabled, + settings->magnification_gesture_enabled) + .Build(); + + resolver.Get(isolate)->Resolve(context, obj).ToChecked(); +} + +void CastAccessibilityBindings::AccessibilitySettingChanged( + v8::UniquePersistent<v8::Function>* handler_function, + bool new_value) { + if (handler_function->IsEmpty()) { + return; + } + + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame(); + v8::Local<v8::Context> context = web_frame->MainWorldScriptContext(); + v8::Context::Scope context_scope(context); + v8::Local<v8::Function> handler = + v8::Local<v8::Function>::New(isolate, std::move(*handler_function)); + + v8::Local<v8::Boolean> arg = v8::Boolean::New(isolate, new_value); + + std::vector<v8::Local<v8::Value>> args{arg}; + + v8::MaybeLocal<v8::Value> maybe_result = + handler->Call(context, context->Global(), args.size(), args.data()); + + *handler_function = v8::UniquePersistent<v8::Function>(isolate, handler); + + v8::Local<v8::Value> result; + ignore_result(maybe_result.ToLocal(&result)); +} + +void CastAccessibilityBindings::ScreenReaderSettingChanged(bool new_value) { + AccessibilitySettingChanged(&screen_reader_setting_changed_handler_, + new_value); +} + +void CastAccessibilityBindings::ColorInversionSettingChanged(bool new_value) { + AccessibilitySettingChanged(&color_inversion_setting_changed_handler_, + new_value); +} + +void CastAccessibilityBindings::MagnificationGestureSettingChanged( + bool new_value) { + AccessibilitySettingChanged(&magnification_gesture_setting_changed_handler_, + new_value); +} + +void CastAccessibilityBindings::OnCastAccessibilityClientRequest( + mojo::PendingReceiver<shell::mojom::CastAccessibilityClient> request) { + bindings_.Add(this, std::move(request)); +} + +} // namespace shell +} // namespace chromecast
diff --git a/chromecast/renderer/cast_accessibility_bindings.h b/chromecast/renderer/cast_accessibility_bindings.h new file mode 100644 index 0000000..ecace20 --- /dev/null +++ b/chromecast/renderer/cast_accessibility_bindings.h
@@ -0,0 +1,100 @@ +// Copyright 2021 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 CHROMECAST_RENDERER_CAST_ACCESSIBILITY_BINDINGS_H_ +#define CHROMECAST_RENDERER_CAST_ACCESSIBILITY_BINDINGS_H_ + +#include "base/memory/ptr_util.h" +#include "chromecast/common/mojom/accessibility.mojom.h" +#include "chromecast/renderer/native_bindings_helper.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#include "v8/include/v8.h" + +namespace chromecast { + +class FeatureManager; + +namespace shell { + +// Renderer side implementation of JS available bindings for accessibility +// related functions. +class CastAccessibilityBindings : public CastBinding, + public mojom::CastAccessibilityClient { + public: + CastAccessibilityBindings(content::RenderFrame* render_frame, + const FeatureManager* feature_manager); + ~CastAccessibilityBindings() override; + CastAccessibilityBindings(const CastAccessibilityBindings&) = delete; + CastAccessibilityBindings& operator=(const CastAccessibilityBindings&) = + delete; + + private: + // content::RenderFrameObserver implementation: + void OnInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle* interface_pipe) override; + + // Typedefs for v8 objects that need to run between tasks. + // v8::Global has move semantics, it does not imply unique ownership over an + // v8 object. You can create multiple v8::Globals from the same v8::Local. + using PersistedContext = v8::Global<v8::Context>; + using PersistedResolver = v8::Global<v8::Promise::Resolver>; + + // CastBinding implementation: + void Install(v8::Local<v8::Object> cast_platform, + v8::Isolate* isolate) override; + + // Bind incoming accessibility requests with this implementation. + void OnCastAccessibilityClientRequest( + mojo::PendingReceiver<shell::mojom::CastAccessibilityClient> request); + + void OnConnectionError(); + bool BindAccessibility(); + + void SetColorInversion(bool enable); + void SetScreenReader(bool enable); + void SetMagnificationGesture(bool enable); + + v8::Local<v8::Value> GetAccessibilitySettings(); + + void SetScreenReaderSettingChangedHandler(v8::Local<v8::Function> handler); + void SetColorInversionSettingChangedHandler(v8::Local<v8::Function> handler); + void SetMagnificationGestureSettingChangedHandler( + v8::Local<v8::Function> handler); + + void OnGetAccessibilitySettings(PersistedResolver resolver, + PersistedContext original_context, + mojom::AccessibilitySettingsPtr settings); + + void AccessibilitySettingChanged( + v8::UniquePersistent<v8::Function>* handler_function, + bool new_value); + + // mojom::CastAccessibilityClient implementation + void ScreenReaderSettingChanged(bool new_value) override; + void ColorInversionSettingChanged(bool new_value) override; + void MagnificationGestureSettingChanged(bool new_value) override; + + mojo::Remote<mojom::CastAccessibilityService> accessibility_service_; + + const FeatureManager* feature_manager_; + + v8::UniquePersistent<v8::Function> screen_reader_setting_changed_handler_; + v8::UniquePersistent<v8::Function> color_inversion_setting_changed_handler_; + v8::UniquePersistent<v8::Function> + magnification_gesture_setting_changed_handler_; + + service_manager::BinderRegistry registry_; + + mojo::ReceiverSet<shell::mojom::CastAccessibilityClient> bindings_; +}; + +} // namespace shell +} // namespace chromecast + +#endif // CHROMECAST_RENDERER_CAST_ACCESSIBILITY_BINDINGS_H_
diff --git a/chromecast/renderer/cast_demo_bindings.cc b/chromecast/renderer/cast_demo_bindings.cc new file mode 100644 index 0000000..76d44c0 --- /dev/null +++ b/chromecast/renderer/cast_demo_bindings.cc
@@ -0,0 +1,373 @@ +// Copyright 2021 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 "chromecast/renderer/cast_demo_bindings.h" + +#include "base/check.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/v8_value_converter.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/web/blink.h" +#include "third_party/blink/public/web/web_local_frame.h" + +namespace chromecast { +namespace shell { + +namespace { +const int64_t kDelayBetweenReconnectionInMillis = 100; + +const char kDemoObjectName[] = "demo"; + +const char kRecordEventName[] = "recordEvent"; +const char kSetRetailerName[] = "setRetailer"; +const char kSetStoreIdName[] = "setStoreId"; +const char kGetRetailerName[] = "getRetailer"; +const char kGetStoreIdName[] = "getStoreId"; +const char kSetDefaultVolumeName[] = "setDefaultVolume"; +const char kGetDefaultVolumeName[] = "getDefaultVolume"; +const char kApplyDefaultVolumeName[] = "applyDefaultVolume"; +const char kSetWifiConnectionName[] = "setWifiConnection"; +const char kGetAvailableWifiNetworksName[] = "getAvailableWifiNetworks"; +const char kGetWifiConnectionStateName[] = "getWifiConnectionState"; +const char kRegisterVolumeChangeHandlerName[] = "registerVolumeChangeHandler"; +const char kPersistLocalStorageName[] = "persistLocalStorage"; + +const char kSetVolumeName[] = "setVolume"; +} // namespace + +CastDemoBindings::CastDemoBindings(content::RenderFrame* render_frame) + : CastBinding(render_frame), binding_(this), weak_factory_(this) {} + +CastDemoBindings::~CastDemoBindings() {} + +void CastDemoBindings::Install(v8::Local<v8::Object> cast_platform, + v8::Isolate* isolate) { + v8::Local<v8::Object> demo_object = + EnsureObjectExists(isolate, cast_platform, kDemoObjectName); + + InstallBinding(isolate, demo_object, kRecordEventName, + &CastDemoBindings::RecordEvent, base::Unretained(this)); + InstallBinding(isolate, demo_object, kSetRetailerName, + &CastDemoBindings::SetRetailerName, base::Unretained(this)); + InstallBinding(isolate, demo_object, kSetStoreIdName, + &CastDemoBindings::SetStoreId, base::Unretained(this)); + InstallBinding(isolate, demo_object, kGetRetailerName, + &CastDemoBindings::GetRetailerName, base::Unretained(this)); + InstallBinding(isolate, demo_object, kGetStoreIdName, + &CastDemoBindings::GetStoreId, base::Unretained(this)); + InstallBinding(isolate, demo_object, kSetDefaultVolumeName, + &CastDemoBindings::SetDefaultVolumeLevel, + base::Unretained(this)); + InstallBinding(isolate, demo_object, kGetDefaultVolumeName, + &CastDemoBindings::GetDefaultVolumeLevel, + base::Unretained(this)); + InstallBinding(isolate, demo_object, kApplyDefaultVolumeName, + &CastDemoBindings::ApplyDefaultVolume, base::Unretained(this)); + InstallBinding(isolate, demo_object, kSetWifiConnectionName, + &CastDemoBindings::SetWifiCredentials, base::Unretained(this)); + InstallBinding(isolate, demo_object, kGetAvailableWifiNetworksName, + &CastDemoBindings::GetAvailableWifiNetworks, + base::Unretained(this)); + InstallBinding(isolate, demo_object, kGetWifiConnectionStateName, + &CastDemoBindings::GetConnectionStatus, + base::Unretained(this)); + InstallBinding(isolate, demo_object, kRegisterVolumeChangeHandlerName, + &CastDemoBindings::SetVolumeChangeHandler, + base::Unretained(this)); + InstallBinding(isolate, demo_object, kPersistLocalStorageName, + &CastDemoBindings::PersistLocalStorage, + base::Unretained(this)); + + InstallBinding(isolate, demo_object, kSetVolumeName, + &CastDemoBindings::SetVolume, base::Unretained(this)); +} + +void CastDemoBindings::RecordEvent(const std::string& event_name, + v8::Local<v8::Value> v8_data) { + v8::Isolate* v8_isolate = blink::MainThreadIsolate(); + v8::HandleScope v8_handle_scope(v8_isolate); + blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame(); + v8::Local<v8::Context> v8_context = web_frame->MainWorldScriptContext(); + v8::Context::Scope v8_context_scope(v8_context); + + std::unique_ptr<content::V8ValueConverter> v8_converter = + content::V8ValueConverter::Create(); + v8_converter->SetDateAllowed(true); + v8_converter->SetRegExpAllowed(true); + std::unique_ptr<base::Value> data_ptr = + v8_converter->FromV8Value(v8_data, v8_context); + + base::Value data; + if (data_ptr) { + data = base::Value::FromUniquePtrValue(std::move(data_ptr)); + } + GetCastDemo()->RecordEvent(event_name, std::move(data)); +} + +void CastDemoBindings::SetRetailerName(const std::string& retailer_name) { + GetCastDemo()->SetRetailerName(retailer_name); +} + +void CastDemoBindings::SetStoreId(const std::string& store_id) { + GetCastDemo()->SetStoreId(store_id); +} + +v8::Local<v8::Value> CastDemoBindings::GetRetailerName() { + v8::Isolate* isolate = blink::MainThreadIsolate(); + auto context = isolate->GetCurrentContext(); + v8::Local<v8::Promise::Resolver> resolver = + v8::Promise::Resolver::New(context).ToLocalChecked(); + v8::Global<v8::Promise::Resolver> unique_resolver = + v8::Global<v8::Promise::Resolver>(isolate, resolver); + v8::Global<v8::Context> persisted_context = + v8::Global<v8::Context>(isolate, context); + + GetCastDemo()->GetRetailerName(base::BindOnce( + &CastDemoBindings::OnGetRetailerName, base::Unretained(this), + std::move(unique_resolver), std::move(persisted_context))); + return resolver->GetPromise(); +} + +void CastDemoBindings::OnGetRetailerName( + v8::Global<v8::Promise::Resolver> resolver, + v8::Global<v8::Context> original_context, + const std::string& retailer_name) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::MicrotasksScope microtasks_scope( + isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Context> context = original_context.Get(isolate); + v8::Context::Scope context_scope(context); + + resolver.Get(isolate) + ->Resolve(context, gin::ConvertToV8(isolate, retailer_name)) + .ToChecked(); +} + +v8::Local<v8::Value> CastDemoBindings::GetStoreId() { + v8::Isolate* isolate = blink::MainThreadIsolate(); + auto context = isolate->GetCurrentContext(); + v8::Local<v8::Promise::Resolver> resolver = + v8::Promise::Resolver::New(context).ToLocalChecked(); + v8::Global<v8::Promise::Resolver> unique_resolver = + v8::Global<v8::Promise::Resolver>(isolate, resolver); + v8::Global<v8::Context> persisted_context = + v8::Global<v8::Context>(isolate, context); + + GetCastDemo()->GetStoreId( + base::BindOnce(&CastDemoBindings::OnGetStoreId, base::Unretained(this), + std::move(unique_resolver), std::move(persisted_context))); + return resolver->GetPromise(); +} + +void CastDemoBindings::OnGetStoreId(v8::Global<v8::Promise::Resolver> resolver, + v8::Global<v8::Context> original_context, + const std::string& store_id) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::MicrotasksScope microtasks_scope( + isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Context> context = original_context.Get(isolate); + v8::Context::Scope context_scope(context); + + resolver.Get(isolate) + ->Resolve(context, gin::ConvertToV8(isolate, store_id)) + .ToChecked(); +} + +void CastDemoBindings::SetVolume(float level) { + // This method is deprecated. Provide a workable implementation to support + // development using old content. + SetDefaultVolumeLevel(level); + ApplyDefaultVolume(); +} + +void CastDemoBindings::SetDefaultVolumeLevel(float level) { + GetCastDemo()->SetDefaultVolumeLevel(level); +} + +v8::Local<v8::Value> CastDemoBindings::GetDefaultVolumeLevel() { + v8::Isolate* isolate = blink::MainThreadIsolate(); + auto context = isolate->GetCurrentContext(); + v8::Local<v8::Promise::Resolver> resolver = + v8::Promise::Resolver::New(context).ToLocalChecked(); + v8::Global<v8::Promise::Resolver> unique_resolver = + v8::Global<v8::Promise::Resolver>(isolate, resolver); + v8::Global<v8::Context> persisted_context = + v8::Global<v8::Context>(isolate, context); + + GetCastDemo()->GetDefaultVolumeLevel(base::BindOnce( + &CastDemoBindings::OnGetDefaultVolumeLevel, base::Unretained(this), + std::move(unique_resolver), std::move(persisted_context))); + return resolver->GetPromise(); +} + +void CastDemoBindings::OnGetDefaultVolumeLevel( + v8::Global<v8::Promise::Resolver> resolver, + v8::Global<v8::Context> original_context, + float level) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::MicrotasksScope microtasks_scope( + isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Context> context = original_context.Get(isolate); + v8::Context::Scope context_scope(context); + + resolver.Get(isolate) + ->Resolve(context, gin::ConvertToV8(isolate, level)) + .ToChecked(); +} + +void CastDemoBindings::ApplyDefaultVolume() { + GetCastDemo()->ApplyDefaultVolume(); +} + +void CastDemoBindings::SetWifiCredentials(const std::string& ssid, + const std::string& psk) { + GetCastDemo()->SetWifiCredentials(ssid, psk); +} + +v8::Local<v8::Value> CastDemoBindings::GetAvailableWifiNetworks() { + v8::Isolate* isolate = blink::MainThreadIsolate(); + auto context = isolate->GetCurrentContext(); + v8::Local<v8::Promise::Resolver> resolver = + v8::Promise::Resolver::New(context).ToLocalChecked(); + v8::Global<v8::Promise::Resolver> unique_resolver = + v8::Global<v8::Promise::Resolver>(isolate, resolver); + v8::Global<v8::Context> persisted_context = + v8::Global<v8::Context>(isolate, context); + + GetCastDemo()->GetAvailableWifiNetworks(base::BindOnce( + &CastDemoBindings::OnGetAvailableWifiNetworks, base::Unretained(this), + std::move(unique_resolver), std::move(persisted_context))); + return resolver->GetPromise(); +} + +void CastDemoBindings::OnGetAvailableWifiNetworks( + v8::Global<v8::Promise::Resolver> resolver, + v8::Global<v8::Context> original_context, + base::Value network_list) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::MicrotasksScope microtasks_scope( + isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Context> context = original_context.Get(isolate); + v8::Context::Scope context_scope(context); + + std::unique_ptr<content::V8ValueConverter> v8_converter = + content::V8ValueConverter::Create(); + v8::Local<v8::Value> v8_value = + v8_converter->ToV8Value(&network_list, context); + + resolver.Get(isolate) + ->Resolve(context, gin::ConvertToV8(isolate, v8_value)) + .ToChecked(); +} + +v8::Local<v8::Value> CastDemoBindings::GetConnectionStatus() { + v8::Isolate* isolate = blink::MainThreadIsolate(); + auto context = isolate->GetCurrentContext(); + v8::Local<v8::Promise::Resolver> resolver = + v8::Promise::Resolver::New(context).ToLocalChecked(); + v8::Global<v8::Promise::Resolver> unique_resolver = + v8::Global<v8::Promise::Resolver>(isolate, resolver); + v8::Global<v8::Context> persisted_context = + v8::Global<v8::Context>(isolate, context); + + GetCastDemo()->GetConnectionStatus(base::BindOnce( + &CastDemoBindings::OnGetConnectionStatus, base::Unretained(this), + std::move(unique_resolver), std::move(persisted_context))); + return resolver->GetPromise(); +} + +void CastDemoBindings::OnGetConnectionStatus( + v8::Global<v8::Promise::Resolver> resolver, + v8::Global<v8::Context> original_context, + base::Value status) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::MicrotasksScope microtasks_scope( + isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Context> context = original_context.Get(isolate); + v8::Context::Scope context_scope(context); + + std::unique_ptr<content::V8ValueConverter> v8_converter = + content::V8ValueConverter::Create(); + v8::Local<v8::Value> v8_value = v8_converter->ToV8Value(&status, context); + + resolver.Get(isolate) + ->Resolve(context, gin::ConvertToV8(isolate, v8_value)) + .ToChecked(); +} + +void CastDemoBindings::SetVolumeChangeHandler( + v8::Local<v8::Function> volume_change_handler) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + volume_change_handler_ = + v8::UniquePersistent<v8::Function>(isolate, volume_change_handler); +} + +void CastDemoBindings::VolumeChanged(float level) { + if (volume_change_handler_.IsEmpty()) { + return; + } + + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame(); + v8::Local<v8::Context> context = web_frame->MainWorldScriptContext(); + v8::Context::Scope context_scope(context); + v8::Local<v8::Function> handler = + v8::Local<v8::Function>::New(isolate, std::move(volume_change_handler_)); + + std::vector<v8::Local<v8::Value>> args{gin::ConvertToV8(isolate, level)}; + + v8::MaybeLocal<v8::Value> maybe_result = + handler->Call(context, context->Global(), args.size(), args.data()); + + volume_change_handler_ = v8::UniquePersistent<v8::Function>(isolate, handler); + + v8::Local<v8::Value> result; + ignore_result(maybe_result.ToLocal(&result)); +} + +void CastDemoBindings::PersistLocalStorage() { + GetCastDemo()->PersistLocalStorage(); +} + +void CastDemoBindings::ReconnectMojo() { + render_frame()->GetBrowserInterfaceBroker()->GetInterface( + cast_demo_.BindNewPipeAndPassReceiver()); + DCHECK(cast_demo_.is_bound()); + cast_demo_.set_disconnect_handler(base::BindOnce( + &CastDemoBindings::OnMojoConnectionError, base::Unretained(this))); + + if (binding_.is_bound()) { + binding_.reset(); + } + + mojo::PendingRemote<mojom::CastDemoVolumeChangeObserver> pending_remote; + binding_.Bind(pending_remote.InitWithNewPipeAndPassReceiver()); + cast_demo_->AddVolumeChangeObserver(std::move(pending_remote)); +} + +void CastDemoBindings::OnMojoConnectionError() { + LOG(WARNING) << "Disconnected from Demo Mojo. Will retry every " + << kDelayBetweenReconnectionInMillis << " milliseconds."; + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&CastDemoBindings::ReconnectMojo, + weak_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(kDelayBetweenReconnectionInMillis)); +} + +const mojo::Remote<mojom::CastDemo>& CastDemoBindings::GetCastDemo() { + if (!cast_demo_.is_bound()) { + ReconnectMojo(); + } + return cast_demo_; +} + +} // namespace shell +} // namespace chromecast
diff --git a/chromecast/renderer/cast_demo_bindings.h b/chromecast/renderer/cast_demo_bindings.h new file mode 100644 index 0000000..2306bfe --- /dev/null +++ b/chromecast/renderer/cast_demo_bindings.h
@@ -0,0 +1,97 @@ +// Copyright 2021 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 CHROMECAST_RENDERER_CAST_DEMO_BINDINGS_H_ +#define CHROMECAST_RENDERER_CAST_DEMO_BINDINGS_H_ + +#include <string> + +#include "base/memory/weak_ptr.h" +#include "chromecast/common/mojom/cast_demo.mojom.h" +#include "chromecast/renderer/native_bindings_helper.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "v8/include/v8.h" + +namespace chromecast { +namespace shell { + +// Enabled only when the device is in demonstration mode. This is only enabled +// for the demonstration JS app. +class CastDemoBindings : public CastBinding, + public mojom::CastDemoVolumeChangeObserver { + public: + explicit CastDemoBindings(content::RenderFrame* render_frame); + CastDemoBindings(const CastDemoBindings&) = delete; + CastDemoBindings& operator=(const CastDemoBindings&) = delete; + + private: + friend class CastBinding; + + ~CastDemoBindings() override; + + // CastBinding implementation: + void Install(v8::Local<v8::Object> cast_platform, + v8::Isolate* isolate) override; + + // Methods to be called from v8: (See mojom for details) + void RecordEvent(const std::string& event_name, v8::Local<v8::Value> data); + void SetRetailerName(const std::string& retailer_name); + void SetStoreId(const std::string& store_id); + v8::Local<v8::Value> GetRetailerName(); + v8::Local<v8::Value> GetStoreId(); + void SetDefaultVolumeLevel(float level); + v8::Local<v8::Value> GetDefaultVolumeLevel(); + void ApplyDefaultVolume(); + void SetWifiCredentials(const std::string& ssid, const std::string& psk); + v8::Local<v8::Value> GetAvailableWifiNetworks(); + v8::Local<v8::Value> GetConnectionStatus(); + void SetVolumeChangeHandler(v8::Local<v8::Function> volume_change_handler); + void PersistLocalStorage(); + + // Deprecated + void SetVolume(float level); + + // Methods to return values to v8: + void OnGetRetailerName(v8::Global<v8::Promise::Resolver> resolver, + v8::Global<v8::Context> original_context, + const std::string& retailer_name); + void OnGetStoreId(v8::Global<v8::Promise::Resolver> resolver, + v8::Global<v8::Context> original_context, + const std::string& store_id); + void OnGetDefaultVolumeLevel(v8::Global<v8::Promise::Resolver> resolver, + v8::Global<v8::Context> original_context, + float level); + void OnGetAvailableWifiNetworks(v8::Global<v8::Promise::Resolver> resolver, + v8::Global<v8::Context> original_context, + base::Value network_list); + void OnGetConnectionStatus(v8::Global<v8::Promise::Resolver> resolver, + v8::Global<v8::Context> original_context, + base::Value status); + + // mojom::CastDemoVolumeChangeObserver implementation: + void VolumeChanged(float level) override; + + void ReconnectMojo(); + void OnMojoConnectionError(); + + // Returns a reference to |cast_demo_|, and binds it to a mojo pipe if + // necessary. + const mojo::Remote<mojom::CastDemo>& GetCastDemo(); + + // The pointer to the remote mojom::CastDemo interface. Do not access this + // member directly; instead, use GetCastDemo(). + mojo::Remote<mojom::CastDemo> cast_demo_; + + mojo::Receiver<mojom::CastDemoVolumeChangeObserver> binding_; + + v8::UniquePersistent<v8::Function> volume_change_handler_; + + base::WeakPtrFactory<CastDemoBindings> weak_factory_; +}; + +} // namespace shell +} // namespace chromecast + +#endif // CHROMECAST_RENDERER_CAST_DEMO_BINDINGS_H_
diff --git a/chromecast/renderer/cast_window_manager_bindings.cc b/chromecast/renderer/cast_window_manager_bindings.cc new file mode 100644 index 0000000..897f8b5 --- /dev/null +++ b/chromecast/renderer/cast_window_manager_bindings.cc
@@ -0,0 +1,340 @@ +// Copyright 2021 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 "chromecast/renderer/cast_window_manager_bindings.h" + +#include <vector> + +#include "base/check.h" +#include "build/build_config.h" +#include "chromecast/base/cast_features.h" +#include "chromecast/common/feature_constants.h" +#include "chromecast/common/mojom/gesture.mojom.h" +#include "chromecast/renderer/feature_manager.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_view.h" +#include "gin/data_object_builder.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/web/blink.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_view.h" + +namespace chromecast { +namespace shell { + +namespace { + +const char kBindingsObjectName[] = "windowManager"; +const char kOnBackGestureName[] = "onBackGesture"; +const char kOnBackGestureProgressName[] = "onBackGestureProgress"; +const char kOnBackGestureCancelName[] = "onBackGestureCancel"; +const char kOnTopDragGestureDoneName[] = "onTopDragGestureDone"; +const char kOnTopDragGestureProgressName[] = "onTopDragGestureProgress"; +const char kOnRightDragGestureDoneName[] = "onRightDragGestureDone"; +const char kOnRightDragGestureProgressName[] = "onRightDragGestureProgress"; +const char kOnTapGestureName[] = "onTapGesture"; +const char kOnTapDownGestureName[] = "onTapDownGesture"; +const char kCanGoBackName[] = "canGoBack"; +const char kCanTopDragName[] = "canTopDrag"; +const char kCanRightDragName[] = "canRightDrag"; +const char kMinimize[] = "minimize"; +const char kMaximize[] = "maximize"; + +#if !defined(OS_ANDROID) +const char kDisplayControlsName[] = "displayControls"; +#endif + +void OnGestureSourceDisconnectionError() { + LOG(ERROR) << "Connection error talking to system gesture source."; +} + +void OnWindowDisconnect() { + LOG(ERROR) << "Connection error talking to platform activity."; +} + +} // namespace + +CastWindowManagerBindings::CastWindowManagerBindings( + content::RenderFrame* render_frame, + const FeatureManager* feature_manager) + : CastBinding(render_frame), + feature_manager_(feature_manager), + handler_receiver_(this) { + DCHECK(feature_manager_); +} + +CastWindowManagerBindings::~CastWindowManagerBindings() {} + +void CastWindowManagerBindings::Install(v8::Local<v8::Object> cast_platform, + v8::Isolate* isolate) { + if (feature_manager_->FeatureEnabled(feature::kEnableSystemGestures)) { + v8::Local<v8::Object> windowManagerObject = + EnsureObjectExists(isolate, cast_platform, kBindingsObjectName); + + // On back bindings. + InstallBinding(isolate, windowManagerObject, kCanGoBackName, + &CastWindowManagerBindings::SetCanGoBack, + base::Unretained(this)); + InstallBinding(isolate, windowManagerObject, kOnBackGestureName, + &CastWindowManagerBindings::SetV8Callback, + base::Unretained(this), &on_back_gesture_callback_); + InstallBinding(isolate, windowManagerObject, kOnBackGestureProgressName, + &CastWindowManagerBindings::SetV8Callback, + base::Unretained(this), &on_back_gesture_progress_callback_); + InstallBinding(isolate, windowManagerObject, kOnBackGestureCancelName, + &CastWindowManagerBindings::SetV8Callback, + base::Unretained(this), &on_back_gesture_cancel_callback_); + + // Top drag bindings. + InstallBinding(isolate, windowManagerObject, kCanTopDragName, + &CastWindowManagerBindings::SetCanTopDrag, + base::Unretained(this)); + InstallBinding(isolate, windowManagerObject, kOnTopDragGestureDoneName, + &CastWindowManagerBindings::SetV8Callback, + base::Unretained(this), &on_top_drag_gesture_done_callback_); + InstallBinding(isolate, windowManagerObject, kOnTopDragGestureProgressName, + &CastWindowManagerBindings::SetV8Callback, + base::Unretained(this), + &on_top_drag_gesture_progress_callback_); + + // Right drag bindings. + InstallBinding(isolate, windowManagerObject, kCanRightDragName, + &CastWindowManagerBindings::SetCanRightDrag, + base::Unretained(this)); + InstallBinding(isolate, windowManagerObject, kOnRightDragGestureDoneName, + &CastWindowManagerBindings::SetV8Callback, + base::Unretained(this), + &on_right_drag_gesture_done_callback_); + InstallBinding( + isolate, windowManagerObject, kOnRightDragGestureProgressName, + &CastWindowManagerBindings::SetV8Callback, base::Unretained(this), + &on_right_drag_gesture_progress_callback_); + + // 'Tap' bindings. + InstallBinding(isolate, windowManagerObject, kOnTapGestureName, + &CastWindowManagerBindings::SetV8Callback, + base::Unretained(this), &on_tap_gesture_callback_); + InstallBinding(isolate, windowManagerObject, kOnTapDownGestureName, + &CastWindowManagerBindings::SetV8Callback, + base::Unretained(this), &on_tap_down_gesture_callback_); + } + if (feature_manager_->FeatureEnabled(feature::kEnableWindowControls)) { + v8::Local<v8::Object> windowManagerObject = + EnsureObjectExists(isolate, cast_platform, kBindingsObjectName); + + InstallBinding(isolate, windowManagerObject, kMaximize, + &CastWindowManagerBindings::Show, base::Unretained(this)); + InstallBinding(isolate, windowManagerObject, kMinimize, + &CastWindowManagerBindings::Hide, base::Unretained(this)); + } +} + +v8::Local<v8::Value> CastWindowManagerBindings::SetV8Callback( + v8::UniquePersistent<v8::Function>* callback_function, + v8::Local<v8::Function> callback) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + + *callback_function = v8::UniquePersistent<v8::Function>(isolate, callback); + + return v8::Undefined(isolate); +} + +void CastWindowManagerBindings::Show() { + BindWindow(); + window_->Show(); +} + +void CastWindowManagerBindings::Hide() { + BindWindow(); + window_->Hide(); +} + +void CastWindowManagerBindings::SetCanGoBack(bool can_go_back) { + BindGestureSource(); + gesture_source_->SetCanGoBack(can_go_back); +} + +void CastWindowManagerBindings::SetCanTopDrag(bool can_top_drag) { + BindGestureSource(); + gesture_source_->SetCanTopDrag(can_top_drag); +} + +void CastWindowManagerBindings::SetCanRightDrag(bool can_right_drag) { + BindGestureSource(); + gesture_source_->SetCanRightDrag(can_right_drag); +} + +void CastWindowManagerBindings::OnTouchInputSupportSet( + PersistedResolver resolver, + PersistedContext original_context, + bool resolve_promise, + bool display_controls) { + DVLOG(2) << __FUNCTION__; + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::MicrotasksScope microtasks_scope( + isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Context> context = original_context.Get(isolate); + v8::Context::Scope context_scope(context); + + if (resolve_promise) { + resolver.Get(isolate) + ->Resolve(context, + +#if !defined(OS_ANDROID) + gin::DataObjectBuilder(isolate) + .Set(kDisplayControlsName, display_controls) + .Build() +#else + v8::Undefined(isolate) +#endif + ) + .ToChecked(); + } else { + resolver.Get(isolate)->Reject(context, v8::Undefined(isolate)).ToChecked(); + } +} + +void CastWindowManagerBindings::BindGestureSource() { + if (gesture_source_.is_bound() && gesture_source_.is_connected()) + return; + gesture_source_.reset(); + render_frame()->GetBrowserInterfaceBroker()->GetInterface( + gesture_source_.BindNewPipeAndPassReceiver()); + gesture_source_.set_disconnect_handler( + base::BindRepeating(&OnGestureSourceDisconnectionError)); + handler_receiver_.reset(); + gesture_source_->Subscribe(handler_receiver_.BindNewPipeAndPassRemote()); +} + +void CastWindowManagerBindings::BindWindow() { + if (window_.is_bound() && window_.is_connected()) + return; + window_.reset(); + render_frame()->GetBrowserInterfaceBroker()->GetInterface( + window_.BindNewPipeAndPassReceiver()); + window_.set_disconnect_handler(base::BindRepeating(&OnWindowDisconnect)); +} + +void CastWindowManagerBindings::InvokeV8Callback( + v8::UniquePersistent<v8::Function>* callback_function) { + if (callback_function->IsEmpty()) { + return; + } + + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame(); + v8::Local<v8::Context> context = web_frame->MainWorldScriptContext(); + v8::Context::Scope context_scope(context); + v8::Local<v8::Function> handler = + v8::Local<v8::Function>::New(isolate, std::move(*callback_function)); + + v8::MaybeLocal<v8::Value> maybe_result = + handler->Call(context, context->Global(), 0, nullptr); + + *callback_function = v8::UniquePersistent<v8::Function>(isolate, handler); + + v8::Local<v8::Value> result; + ignore_result(maybe_result.ToLocal(&result)); +} + +void CastWindowManagerBindings::InvokeV8Callback( + v8::UniquePersistent<v8::Function>* callback_function, + const gfx::Point& touch_location) { + if (callback_function->IsEmpty()) { + return; + } + + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame(); + v8::Local<v8::Context> context = web_frame->MainWorldScriptContext(); + v8::Context::Scope context_scope(context); + v8::Local<v8::Function> handler = + v8::Local<v8::Function>::New(isolate, std::move(*callback_function)); + + v8::Local<v8::Number> touch_x = v8::Integer::New(isolate, touch_location.x()); + v8::Local<v8::Number> touch_y = v8::Integer::New(isolate, touch_location.y()); + + std::vector<v8::Local<v8::Value>> args{touch_x, touch_y}; + + v8::MaybeLocal<v8::Value> maybe_result = + handler->Call(context, context->Global(), args.size(), args.data()); + + *callback_function = v8::UniquePersistent<v8::Function>(isolate, handler); + + v8::Local<v8::Value> result; + ignore_result(maybe_result.ToLocal(&result)); +} + +void CastWindowManagerBindings::OnBackGesture( + ::chromecast::mojom::GestureHandler::OnBackGestureCallback callback) { + // Note: Can't use InvokeV8Callback here because of the OnBackGestureCallback + // argument. So we have this boilerplate here until we can get rid of the + // unused callback argument. + if (on_back_gesture_callback_.IsEmpty()) { + std::move(callback).Run(false); + return; + } + + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame(); + v8::Local<v8::Context> context = web_frame->MainWorldScriptContext(); + v8::Context::Scope context_scope(context); + v8::Local<v8::Function> handler = v8::Local<v8::Function>::New( + isolate, std::move(on_back_gesture_callback_)); + auto result = handler->Call(context, context->Global(), 0, nullptr); + + on_back_gesture_callback_ = + v8::UniquePersistent<v8::Function>(isolate, handler); + if (result.IsEmpty()) { + LOG(ERROR) << "No value from callback execution; "; + std::move(callback).Run(false); + return; + } + + auto callback_return_value = result.ToLocalChecked(); + bool return_boolean = callback_return_value->BooleanValue(isolate); + std::move(callback).Run(return_boolean); +} + +void CastWindowManagerBindings::OnBackGestureProgress( + const gfx::Point& touch_location) { + InvokeV8Callback(&on_back_gesture_progress_callback_, touch_location); +} + +void CastWindowManagerBindings::OnBackGestureCancel() { + InvokeV8Callback(&on_back_gesture_cancel_callback_); +} + +void CastWindowManagerBindings::OnTopDragGestureDone() { + InvokeV8Callback(&on_top_drag_gesture_done_callback_); +} + +void CastWindowManagerBindings::OnTopDragGestureProgress( + const gfx::Point& touch_location) { + InvokeV8Callback(&on_top_drag_gesture_progress_callback_, touch_location); +} + +void CastWindowManagerBindings::OnRightDragGestureDone() { + InvokeV8Callback(&on_right_drag_gesture_done_callback_); +} + +void CastWindowManagerBindings::OnRightDragGestureProgress( + const gfx::Point& touch_location) { + InvokeV8Callback(&on_right_drag_gesture_progress_callback_, touch_location); +} + +void CastWindowManagerBindings::OnTapGesture() { + InvokeV8Callback(&on_tap_gesture_callback_); +} + +void CastWindowManagerBindings::OnTapDownGesture() { + InvokeV8Callback(&on_tap_down_gesture_callback_); +} + +} // namespace shell +} // namespace chromecast
diff --git a/chromecast/renderer/cast_window_manager_bindings.h b/chromecast/renderer/cast_window_manager_bindings.h new file mode 100644 index 0000000..dfb4731 --- /dev/null +++ b/chromecast/renderer/cast_window_manager_bindings.h
@@ -0,0 +1,108 @@ +// Copyright 2021 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 CHROMECAST_RENDERER_CAST_WINDOW_MANAGER_BINDINGS_H_ +#define CHROMECAST_RENDERER_CAST_WINDOW_MANAGER_BINDINGS_H_ + +#include "base/memory/ptr_util.h" +#include "chromecast/browser/mojom/cast_content_window.mojom.h" +#include "chromecast/common/mojom/activity_window.mojom.h" +#include "chromecast/common/mojom/gesture.mojom.h" +#include "chromecast/renderer/native_bindings_helper.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "v8/include/v8.h" + +namespace chromecast { + +class FeatureManager; + +namespace shell { + +// Renderer side implementation of cast system gesture. +// Implements the mojo service which receives notification of gesture events, +// and also sets up the JS callback bindings to application code. +class CastWindowManagerBindings : public CastBinding, + public ::chromecast::mojom::GestureHandler { + public: + CastWindowManagerBindings(content::RenderFrame* render_frame, + const FeatureManager* feature_manager); + CastWindowManagerBindings(const CastWindowManagerBindings&) = delete; + CastWindowManagerBindings& operator=(const CastWindowManagerBindings&) = + delete; + + // ::chromecast::mojom::GestureHandler implementation: + void OnBackGesture(OnBackGestureCallback callback) override; + void OnBackGestureProgress(const gfx::Point& touch_location) override; + void OnBackGestureCancel() override; + void OnTopDragGestureProgress(const gfx::Point& touch_location) override; + void OnTopDragGestureDone() override; + void OnRightDragGestureProgress(const gfx::Point& touch_location) override; + void OnRightDragGestureDone() override; + void OnTapGesture() override; + void OnTapDownGesture() override; + + private: + friend class CastBinding; + + ~CastWindowManagerBindings() override; + + // Typedefs for v8 objects that need to run between tasks. + // v8::Global has move semantics, it does not imply unique ownership over an + // v8 object. You can create multiple v8::Globals from the same v8::Local. + using PersistedContext = v8::Global<v8::Context>; + using PersistedResolver = v8::Global<v8::Promise::Resolver>; + + v8::Local<v8::Value> SetV8Callback( + v8::UniquePersistent<v8::Function>* callback_function, + v8::Local<v8::Function> callback); + void InvokeV8Callback(v8::UniquePersistent<v8::Function>* callback_function); + void InvokeV8Callback(v8::UniquePersistent<v8::Function>* callback_function, + const gfx::Point& touch_location); + + // CastBinding implementation: + void Install(v8::Local<v8::Object> cast_platform, + v8::Isolate* isolate) override; + + void BindGestureSource(); + void BindWindow(); + + void Show(); + void Hide(); + void SetCanGoBack(bool can_go_back); + void SetCanTopDrag(bool can_top_drag); + void SetCanRightDrag(bool can_right_drag); + + void OnTouchInputSupportSet(PersistedResolver resolver, + PersistedContext original_context, + bool resolve_promise, + bool display_controls); + + const FeatureManager* feature_manager_; + + mojo::Remote<::chromecast::mojom::GestureSource> gesture_source_; + mojo::Remote<::chromecast::mojom::ActivityWindow> window_; + + // Receiver handle bound to self. + mojo::Receiver<::chromecast::mojom::GestureHandler> handler_receiver_; + + v8::UniquePersistent<v8::Function> on_back_gesture_callback_; + v8::UniquePersistent<v8::Function> on_back_gesture_progress_callback_; + v8::UniquePersistent<v8::Function> on_back_gesture_cancel_callback_; + + v8::UniquePersistent<v8::Function> on_top_drag_gesture_done_callback_; + v8::UniquePersistent<v8::Function> on_top_drag_gesture_progress_callback_; + + v8::UniquePersistent<v8::Function> on_right_drag_gesture_done_callback_; + v8::UniquePersistent<v8::Function> on_right_drag_gesture_progress_callback_; + + v8::UniquePersistent<v8::Function> on_tap_gesture_callback_; + + v8::UniquePersistent<v8::Function> on_tap_down_gesture_callback_; +}; + +} // namespace shell +} // namespace chromecast + +#endif // CHROMECAST_RENDERER_CAST_WINDOW_MANAGER_BINDINGS_H_
diff --git a/chromecast/renderer/extensions/extension_hooks_delegate.cc b/chromecast/renderer/extensions/extension_hooks_delegate.cc index d9cdb57..3e7b878 100644 --- a/chromecast/renderer/extensions/extension_hooks_delegate.cc +++ b/chromecast/renderer/extensions/extension_hooks_delegate.cc
@@ -218,7 +218,8 @@ v8::Local<v8::Value> v8_message = arguments[1]; std::unique_ptr<Message> message = messaging_util::MessageFromV8( - script_context->v8_context(), v8_message, &error); + script_context->v8_context(), v8_message, + messaging_util::GetSerializationFormat(*script_context), &error); if (!message) { RequestResult result(RequestResult::INVALID_INVOCATION); result.error = std::move(error);
diff --git a/chromecast/renderer/extensions/tabs_hooks_delegate.cc b/chromecast/renderer/extensions/tabs_hooks_delegate.cc index c8e7663..ffcbbeab 100644 --- a/chromecast/renderer/extensions/tabs_hooks_delegate.cc +++ b/chromecast/renderer/extensions/tabs_hooks_delegate.cc
@@ -89,7 +89,8 @@ v8::Local<v8::Value> v8_message = arguments[1]; std::string error; std::unique_ptr<Message> message = messaging_util::MessageFromV8( - script_context->v8_context(), v8_message, &error); + script_context->v8_context(), v8_message, + messaging_util::GetSerializationFormat(*script_context), &error); if (!message) { RequestResult result(RequestResult::INVALID_INVOCATION); result.error = std::move(error); @@ -124,7 +125,8 @@ DCHECK(!v8_message.IsEmpty()); std::string error; std::unique_ptr<Message> message = messaging_util::MessageFromV8( - script_context->v8_context(), v8_message, &error); + script_context->v8_context(), v8_message, + messaging_util::GetSerializationFormat(*script_context), &error); if (!message) { RequestResult result(RequestResult::INVALID_INVOCATION); result.error = std::move(error); @@ -158,7 +160,8 @@ gin::Handle<GinPort> port = messaging_service_->Connect( script_context, MessageTarget::ForTab(tab_id, options.frame_id), - options.channel_name); + options.channel_name, + messaging_util::GetSerializationFormat(*script_context)); DCHECK(!port.IsEmpty()); RequestResult result(RequestResult::HANDLED);
diff --git a/chromecast/renderer/feature_manager.cc b/chromecast/renderer/feature_manager.cc new file mode 100644 index 0000000..734847b --- /dev/null +++ b/chromecast/renderer/feature_manager.cc
@@ -0,0 +1,185 @@ +// Copyright 2021 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 "chromecast/renderer/feature_manager.h" + +#include <iostream> +#include <map> +#include <string> +#include <vector> + +#include "base/check.h" +#include "base/logging.h" +#include "base/values.h" +#include "chromecast/base/cast_features.h" +#include "chromecast/common/feature_constants.h" +#include "chromecast/renderer/assistant_bindings.h" +#include "chromecast/renderer/cast_accessibility_bindings.h" +#include "chromecast/renderer/cast_demo_bindings.h" +#include "chromecast/renderer/cast_window_manager_bindings.h" +#include "chromecast/renderer/settings_ui_bindings.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_frame_media_playback_options.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" +#include "third_party/blink/public/platform/web_runtime_features.h" +#include "third_party/blink/public/platform/web_security_origin.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_security_policy.h" + +namespace chromecast { + +FeatureManager::FeatureManager(content::RenderFrame* render_frame) + : content::RenderFrameObserver(render_frame), + configured_(false), + can_install_bindings_(false), + dev_origin_(GURL::EmptyGURL()), + secure_origin_set_(false) { + registry_.AddInterface(base::BindRepeating( + &FeatureManager::OnFeatureManagerRequest, base::Unretained(this))); +} + +FeatureManager::~FeatureManager() {} + +void FeatureManager::OnInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle* interface_pipe) { + registry_.TryBindInterface(interface_name, interface_pipe); +} + +void FeatureManager::OnDestruct() { + delete this; +} + +void FeatureManager::DidClearWindowObject() { + can_install_bindings_ = true; + if (!configured_) + return; + + EnableBindings(); +} + +void FeatureManager::ConfigureFeatures( + std::vector<chromecast::shell::mojom::FeaturePtr> features) { + if (configured_) + return; + configured_ = true; + for (auto& feature : features) { + // If we want to add enabled/disabled status to FeaturePtr, we can overlap + // previous setting via [] operator + features_map_[feature->name] = std::move(feature); + } + + ConfigureFeaturesInternal(); + + if (!can_install_bindings_) + return; + EnableBindings(); +} + +void FeatureManager::ConfigureFeaturesInternal() { + if (FeatureEnabled(feature::kEnableDevMode)) { + base::Value& dev_mode_config = + (features_map_.find(feature::kEnableDevMode)->second)->config; + base::Value* dev_mode_origin = + dev_mode_config.FindKey(feature::kDevModeOrigin); + DCHECK(dev_mode_origin); + dev_origin_ = GURL(dev_mode_origin->GetString()); + DCHECK(dev_origin_.is_valid()); + } + + if (FeatureEnabled(feature::kDisableBackgroundSuspend)) { + auto options = render_frame()->GetRenderFrameMediaPlaybackOptions(); + options.is_background_suspend_enabled = false; + render_frame()->SetRenderFrameMediaPlaybackOptions(options); + } + + // Call feature-specific functions. + SetupAdditionalSecureOrigin(); + + // Disable timer throttling for background tabs before the frame is painted. + if (FeatureEnabled(feature::kDisableBackgroundTabTimerThrottle)) { + blink::WebRuntimeFeatures::EnableTimerThrottlingForBackgroundTabs(false); + } + if (FeatureEnabled(feature::kEnableSettingsUiMojo)) { + v8_bindings_.insert(new shell::SettingsUiBindings(render_frame())); + } + + // Window manager bindings will install themselves depending on the specific + // feature flags enabled, so we pass the feature manager through to let it + // decide. + v8_bindings_.insert( + new shell::CastWindowManagerBindings(render_frame(), this)); + // Accessibility bindings will install themselves depending on the specific + // feature flags enabled, so we pass the feature manager through to let it + // decide. + v8_bindings_.insert( + new shell::CastAccessibilityBindings(render_frame(), this)); + + if (FeatureEnabled(feature::kEnableDemoStandaloneMode)) { + v8_bindings_.insert(new shell::CastDemoBindings(render_frame())); + } + + if (FeatureEnabled(feature::kEnableAssistantMessagePipe)) { + auto& feature = GetFeature(feature::kEnableAssistantMessagePipe); + v8_bindings_.insert( + new shell::AssistantBindings(render_frame(), feature->config)); + } +} + +void FeatureManager::EnableBindings() { + LOG(INFO) << "Enabling bindings: " << *this; + for (auto* binding : v8_bindings_) { + binding->TryInstall(); + } +} + +void FeatureManager::OnFeatureManagerRequest( + mojo::PendingReceiver<shell::mojom::FeatureManager> request) { + bindings_.Add(this, std::move(request)); +} + +bool FeatureManager::FeatureEnabled(const std::string& feature) const { + return features_map_.find(feature) != features_map_.end(); +} + +const chromecast::shell::mojom::FeaturePtr& FeatureManager::GetFeature( + const std::string& feature) const { + auto itor = features_map_.find(feature); + DCHECK(itor != features_map_.end()); + return itor->second; +} + +void FeatureManager::SetupAdditionalSecureOrigin() { + if (!dev_origin_.is_valid()) { + return; + } + + // Secure origin should be only set once, otherwise it will cause CHECK + // failure when race between origin safelist changing and thread creation + // happens (b/63583734). + if (secure_origin_set_) { + return; + } + + secure_origin_set_ = true; + + LOG(INFO) << "Treat origin " << dev_origin_ << " as secure origin"; + + blink::WebSecurityPolicy::AddSchemeToSecureContextSafelist( + blink::WebString::FromASCII(dev_origin_.scheme())); + + network::SecureOriginAllowlist::GetInstance().SetAuxiliaryAllowlist( + dev_origin_.spec(), nullptr); +} + +std::ostream& operator<<(std::ostream& os, const FeatureManager& features) { + for (auto& feature : features.features_map_) { + os << feature.first << " "; + } + return os; +} + +} // namespace chromecast
diff --git a/chromecast/renderer/feature_manager.h b/chromecast/renderer/feature_manager.h new file mode 100644 index 0000000..fb05dd3a --- /dev/null +++ b/chromecast/renderer/feature_manager.h
@@ -0,0 +1,94 @@ +// Copyright 2021 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 CHROMECAST_RENDERER_FEATURE_MANAGER_H_ +#define CHROMECAST_RENDERER_FEATURE_MANAGER_H_ + +#include <iosfwd> +#include <map> +#include <string> +#include <vector> + +#include "base/containers/flat_set.h" +#include "base/values.h" +#include "chromecast/common/mojom/feature_manager.mojom.h" +#include "chromecast/renderer/native_bindings_helper.h" +#include "content/public/renderer/render_frame_observer.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#include "url/gurl.h" + +namespace chromecast { + +// Receives messages from the browser process to enable/disable Cast +// application-facing features. Features usually have an associated V8 binding +// which exposes a platform capability to the app. +class FeatureManager : public content::RenderFrameObserver, + public shell::mojom::FeatureManager { + public: + explicit FeatureManager(content::RenderFrame* render_frame); + FeatureManager(const FeatureManager&) = delete; + FeatureManager& operator=(const FeatureManager&) = delete; + ~FeatureManager() override; + + const GURL& dev_origin() const { return dev_origin_; } + bool configured() const { return configured_; } + + bool FeatureEnabled(const std::string& feature) const; + + const chromecast::shell::mojom::FeaturePtr& GetFeature( + const std::string& feature) const; + + friend std::ostream& operator<<(std::ostream& os, + const FeatureManager& features); + + protected: + // Allows a derived class to add its own features at the end of + // mojom::FeatureManager::ConfigureFeatures(). + virtual void ConfigureFeaturesInternal(); + + // Map for storing enabled features, name -> FeaturePtr. + using FeaturesMap = + std::map<std::string, chromecast::shell::mojom::FeaturePtr>; + FeaturesMap features_map_; + + base::flat_set<CastBinding*> v8_bindings_; + + private: + // content::RenderFrameObserver implementation: + void OnInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle* interface_pipe) override; + void DidClearWindowObject() override; + void OnDestruct() override; + + // shell::mojom::FeatureManager implementation + void ConfigureFeatures( + std::vector<chromecast::shell::mojom::FeaturePtr> features) override; + + // Bind the incoming request with this implementation + void OnFeatureManagerRequest( + mojo::PendingReceiver<shell::mojom::FeatureManager> request); + + void EnableBindings(); + void SetupAdditionalSecureOrigin(); + + // Flag for when the configuration message is received from the browser. + bool configured_; + bool can_install_bindings_; + + // Origin enabled for development + GURL dev_origin_; + bool secure_origin_set_; + + service_manager::BinderRegistry registry_; + + mojo::ReceiverSet<shell::mojom::FeatureManager> bindings_; +}; + +} // namespace chromecast + +#endif // CHROMECAST_RENDERER_FEATURE_MANAGER_H_
diff --git a/chromecast/renderer/settings_ui_bindings.cc b/chromecast/renderer/settings_ui_bindings.cc new file mode 100644 index 0000000..740aaca --- /dev/null +++ b/chromecast/renderer/settings_ui_bindings.cc
@@ -0,0 +1,171 @@ +// Copyright 2021 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 "chromecast/renderer/settings_ui_bindings.h" + +#include <vector> + +#include "base/bind.h" +#include "base/check.h" +#include "base/location.h" +#include "content/public/renderer/render_frame.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/web/blink.h" +#include "third_party/blink/public/web/web_local_frame.h" + +namespace chromecast { +namespace shell { + +namespace { + +const int64_t kDelayBetweenReconnectionInMillis = 100; + +const char kSettingsUiName[] = "settings_ui"; +const char kSetSideSwipeHandler[] = "setSideSwipeHandler"; +const char kSetPlatformInfoHandler[] = "setPlatformInfoHandler"; +const char kRequestVisible[] = "requestVisible"; + +} // namespace + +SettingsUiBindings::SettingsUiBindings(content::RenderFrame* frame) + : CastBinding(frame), binding_(this), weak_factory_(this) { + ReconnectMojo(); +} + +SettingsUiBindings::~SettingsUiBindings() {} + +void SettingsUiBindings::HandleSideSwipe( + chromecast::mojom::SideSwipeEvent event, + chromecast::mojom::SideSwipeOrigin origin, + const gfx::Point& touch_location) { + if (side_swipe_handler_.IsEmpty()) { + return; + } + + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::MicrotasksScope microtasks_scope( + isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::HandleScope handle_scope(isolate); + blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame(); + v8::Local<v8::Context> context = web_frame->MainWorldScriptContext(); + v8::Context::Scope context_scope(context); + v8::Local<v8::Function> handler = + v8::Local<v8::Function>::New(isolate, std::move(side_swipe_handler_)); + + v8::Local<v8::Number> touch_event = + v8::Integer::New(isolate, static_cast<int>(event)); + v8::Local<v8::Number> touch_origin = + v8::Integer::New(isolate, static_cast<int>(origin)); + v8::Local<v8::Number> touch_x = v8::Integer::New(isolate, touch_location.x()); + v8::Local<v8::Number> touch_y = v8::Integer::New(isolate, touch_location.y()); + + std::vector<v8::Local<v8::Value>> args{touch_event, touch_origin, touch_x, + touch_y}; + + v8::MaybeLocal<v8::Value> maybe_result = + handler->Call(context, context->Global(), args.size(), args.data()); + + side_swipe_handler_ = v8::UniquePersistent<v8::Function>(isolate, handler); + + v8::Local<v8::Value> result; + ignore_result(maybe_result.ToLocal(&result)); +} + +void SettingsUiBindings::SendPlatformInfo( + const std::string& platform_info_json) { + if (platform_info_handler_.IsEmpty()) { + pending_platform_info_json_ = platform_info_json; + return; + } + + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::MicrotasksScope microtasks_scope( + isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::HandleScope handle_scope(isolate); + blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame(); + v8::Local<v8::Context> context = web_frame->MainWorldScriptContext(); + v8::Context::Scope context_scope(context); + v8::Local<v8::Function> handler = + v8::Local<v8::Function>::New(isolate, std::move(platform_info_handler_)); + + v8::Local<v8::String> platform_info = + v8::String::NewFromUtf8(isolate, platform_info_json.data(), + v8::NewStringType::kInternalized) + .ToLocalChecked(); + + std::vector<v8::Local<v8::Value>> args{platform_info}; + + v8::MaybeLocal<v8::Value> maybe_result = + handler->Call(context, context->Global(), args.size(), args.data()); + + platform_info_handler_ = v8::UniquePersistent<v8::Function>(isolate, handler); + + v8::Local<v8::Value> result; + ignore_result(maybe_result.ToLocal(&result)); +} + +void SettingsUiBindings::Install(v8::Local<v8::Object> cast_platform, + v8::Isolate* isolate) { + v8::Local<v8::Object> settings_ui = + EnsureObjectExists(isolate, cast_platform, kSettingsUiName); + + InstallBinding(isolate, settings_ui, kSetSideSwipeHandler, + &SettingsUiBindings::SetSideSwipeHandler, + base::Unretained(this)); + InstallBinding(isolate, settings_ui, kSetPlatformInfoHandler, + &SettingsUiBindings::SetPlatformInfoHandler, + base::Unretained(this)); + InstallBinding(isolate, settings_ui, kRequestVisible, + &SettingsUiBindings::RequestVisible, base::Unretained(this)); +} + +void SettingsUiBindings::SetSideSwipeHandler( + v8::Local<v8::Function> side_swipe_handler) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + side_swipe_handler_ = + v8::UniquePersistent<v8::Function>(isolate, side_swipe_handler); +} + +void SettingsUiBindings::SetPlatformInfoHandler( + v8::Local<v8::Function> platform_info_handler) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + platform_info_handler_ = + v8::UniquePersistent<v8::Function>(isolate, platform_info_handler); + if (!pending_platform_info_json_.empty()) { + SendPlatformInfo(pending_platform_info_json_); + pending_platform_info_json_.clear(); + } +} + +void SettingsUiBindings::RequestVisible(bool visible) { + if (settings_platform_ptr_) { + settings_platform_ptr_->RequestVisible(visible); + } +} + +void SettingsUiBindings::ReconnectMojo() { + if (binding_.is_bound()) + binding_.reset(); + if (settings_platform_ptr_.is_bound()) + settings_platform_ptr_.reset(); + + render_frame()->GetBrowserInterfaceBroker()->GetInterface( + settings_platform_ptr_.BindNewPipeAndPassReceiver()); + settings_platform_ptr_.set_disconnect_handler(base::BindOnce( + &SettingsUiBindings::OnMojoConnectionError, weak_factory_.GetWeakPtr())); + settings_platform_ptr_->Connect(binding_.BindNewPipeAndPassRemote()); + mojo_reconnect_timer_.Stop(); +} + +void SettingsUiBindings::OnMojoConnectionError() { + LOG(WARNING) << "Disconnected from settings UI MOJO. Will reconnect every " + << kDelayBetweenReconnectionInMillis << " milliseconds."; + mojo_reconnect_timer_.Start( + FROM_HERE, + base::TimeDelta::FromMilliseconds(kDelayBetweenReconnectionInMillis), + this, &SettingsUiBindings::ReconnectMojo); +} + +} // namespace shell +} // namespace chromecast
diff --git a/chromecast/renderer/settings_ui_bindings.h b/chromecast/renderer/settings_ui_bindings.h new file mode 100644 index 0000000..b5b75d9d --- /dev/null +++ b/chromecast/renderer/settings_ui_bindings.h
@@ -0,0 +1,69 @@ +// Copyright 2021 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 CHROMECAST_RENDERER_SETTINGS_UI_BINDINGS_H_ +#define CHROMECAST_RENDERER_SETTINGS_UI_BINDINGS_H_ + +#include <string> + +#include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" +#include "chromecast/common/mojom/settings_ui.mojom.h" +#include "chromecast/renderer/native_bindings_helper.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "v8/include/v8.h" + +namespace chromecast { +namespace shell { + +// Exposed to the platform settings UI app on display assistants. Handles +// certain swipe events to show/hide the settings menu. This also receives +// platform information periodically to update the device properties in the +// settings UI. +class SettingsUiBindings : public CastBinding, + public chromecast::mojom::SettingsClient { + public: + explicit SettingsUiBindings(content::RenderFrame* frame); + ~SettingsUiBindings() override; + SettingsUiBindings(const SettingsUiBindings&) = delete; + SettingsUiBindings& operator=(const SettingsUiBindings&) = delete; + + private: + friend class ::chromecast::CastBinding; + + // mojom::SettingsClient implementation: + void HandleSideSwipe(chromecast::mojom::SideSwipeEvent event, + chromecast::mojom::SideSwipeOrigin origin, + const gfx::Point& touch_location) override; + void SendPlatformInfo(const std::string& platform_info_json) override; + + // CastBinding implementation: + void Install(v8::Local<v8::Object> cast_platform, + v8::Isolate* isolate) override; + + // Binding methods + void SetSideSwipeHandler(v8::Local<v8::Function> side_swipe_handler); + void SetPlatformInfoHandler(v8::Local<v8::Function> platform_info_handler); + void RequestVisible(bool visible); + + void ReconnectMojo(); + void OnMojoConnectionError(); + + std::string pending_platform_info_json_; + + v8::UniquePersistent<v8::Function> side_swipe_handler_; + v8::UniquePersistent<v8::Function> platform_info_handler_; + + mojo::Remote<chromecast::mojom::SettingsPlatform> settings_platform_ptr_; + mojo::Receiver<chromecast::mojom::SettingsClient> binding_; + base::RepeatingTimer mojo_reconnect_timer_; + + base::WeakPtrFactory<SettingsUiBindings> weak_factory_; +}; + +} // namespace shell +} // namespace chromecast + +#endif // CHROMECAST_RENDERER_SETTINGS_UI_BINDINGS_H_
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 5500cf9..604e047 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -1065,13 +1065,13 @@ Can't resolve DNS from Android apps </message> <message name="IDS_NETWORK_DIAGNOSTICS_NO_IP_ADDRESS_TEXT" desc="The text shown when a network's IP Address is missing."> - Unable to obtain IP address + IP address is unavailable </message> <message name="IDS_NETWORK_DIAGNOSTICS_VISIT_SETTINGS_TO_CONFIGURE_LINK_TEXT" desc="Help text that directs users to settings to configure their network."> - Visit settings to configure + To set up, go to Settings </message> <message name="IDS_NETWORK_DIAGNOSTICS_MISSING_NAME_SERVERS_TEXT" desc="The text shown when no name servers are configured."> - No name servers are configured + DNS isn't set up </message> <message name="IDS_DIAGNOSTICS_NETWORK_SIGNAL_STRENGTH_WEAK" desc="Label used to describe the signal strength of a network connection when the signal is weak."> Weak (<ph name="SIGNAL_STRENGTH">$1<ex>(20)</ex></ph>)
diff --git a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_MISSING_NAME_SERVERS_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_MISSING_NAME_SERVERS_TEXT.png.sha1 index e88da440..0072e72 100644 --- a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_MISSING_NAME_SERVERS_TEXT.png.sha1 +++ b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_MISSING_NAME_SERVERS_TEXT.png.sha1
@@ -1 +1 @@ -73746946099c4c974852e63234501effa4f798f1 \ No newline at end of file +2f4cd218cecf2d8eb157f7bd3351bf17ebc14542 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_NO_IP_ADDRESS_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_NO_IP_ADDRESS_TEXT.png.sha1 index 6a08a142..235cdd08 100644 --- a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_NO_IP_ADDRESS_TEXT.png.sha1 +++ b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_NO_IP_ADDRESS_TEXT.png.sha1
@@ -1 +1 @@ -56b002c1ffe8572c90dc532fd18de231a2823ae5 \ No newline at end of file +d4521a2b262d7345cf7c470069a9dc378f5918ef \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VISIT_SETTINGS_TO_CONFIGURE_LINK_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VISIT_SETTINGS_TO_CONFIGURE_LINK_TEXT.png.sha1 index 6a08a142..235cdd08 100644 --- a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VISIT_SETTINGS_TO_CONFIGURE_LINK_TEXT.png.sha1 +++ b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VISIT_SETTINGS_TO_CONFIGURE_LINK_TEXT.png.sha1
@@ -1 +1 @@ -56b002c1ffe8572c90dc532fd18de231a2823ae5 \ No newline at end of file +d4521a2b262d7345cf7c470069a9dc378f5918ef \ No newline at end of file
diff --git a/chromeos/components/eche_app_ui/BUILD.gn b/chromeos/components/eche_app_ui/BUILD.gn index 03e52027..16e1b22 100644 --- a/chromeos/components/eche_app_ui/BUILD.gn +++ b/chromeos/components/eche_app_ui/BUILD.gn
@@ -32,6 +32,8 @@ "eche_notification_click_handler.h", "eche_notification_generator.cc", "eche_notification_generator.h", + "eche_presence_manager.cc", + "eche_presence_manager.h", "eche_recent_app_click_handler.cc", "eche_recent_app_click_handler.h", "eche_signaler.cc", @@ -67,7 +69,8 @@ "//chromeos/resources:eche_bundle_resources", "//chromeos/services/device_sync/public/cpp:cpp", "//chromeos/services/multidevice_setup/public/cpp:cpp", - "//chromeos/services/secure_channel/public/cpp/client:client", + "//chromeos/services/secure_channel/public/cpp/client", + "//chromeos/services/secure_channel/public/cpp/shared", "//components/prefs", "//content/public/browser", "//mojo/public/js:resources",
diff --git a/chromeos/components/eche_app_ui/eche_app_manager.cc b/chromeos/components/eche_app_ui/eche_app_manager.cc index 3b1bc3d..96803be 100644 --- a/chromeos/components/eche_app_ui/eche_app_manager.cc +++ b/chromeos/components/eche_app_ui/eche_app_manager.cc
@@ -8,6 +8,7 @@ #include "base/system/sys_info.h" #include "chromeos/components/eche_app_ui/eche_message_receiver.h" #include "chromeos/components/eche_app_ui/eche_notification_generator.h" +#include "chromeos/components/eche_app_ui/eche_presence_manager.h" #include "chromeos/components/eche_app_ui/eche_signaler.h" #include "chromeos/components/eche_app_ui/eche_uid_provider.h" #include "chromeos/components/eche_app_ui/launch_app_helper.h" @@ -32,6 +33,8 @@ device_sync::DeviceSyncClient* device_sync_client, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, secure_channel::SecureChannelClient* secure_channel_client, + std::unique_ptr<secure_channel::PresenceMonitorClient> + presence_monitor_client, LaunchAppHelper::LaunchEcheAppFunction launch_eche_app_function, LaunchAppHelper::CloseEcheAppFunction close_eche_app_function, LaunchAppHelper::LaunchNotificationFunction launch_notification_function) @@ -64,6 +67,12 @@ connection_manager_.get())), signaler_(std::make_unique<EcheSignaler>(eche_connector_.get(), connection_manager_.get())), + eche_presence_manager_(std::make_unique<EchePresenceManager>( + feature_status_provider_.get(), + device_sync_client, + multidevice_setup_client, + std::move(presence_monitor_client), + eche_connector_.get())), uid_(std::make_unique<EcheUidProvider>(pref_service)), eche_recent_app_click_handler_( std::make_unique<EcheRecentAppClickHandler>( @@ -105,16 +114,17 @@ // NOTE: These should be destroyed in the opposite order of how these objects // are initialized in the constructor. void EcheAppManager::Shutdown() { + system_info_provider_.reset(); + message_receiver_.reset(); notification_generator_.reset(); eche_recent_app_click_handler_.reset(); uid_.reset(); - system_info_provider_.reset(); + eche_presence_manager_.reset(); signaler_.reset(); eche_connector_.reset(); eche_notification_click_handler_.reset(); launch_app_helper_.reset(); feature_status_provider_.reset(); - message_receiver_.reset(); connection_manager_.reset(); }
diff --git a/chromeos/components/eche_app_ui/eche_app_manager.h b/chromeos/components/eche_app_ui/eche_app_manager.h index 28d7312..0895615 100644 --- a/chromeos/components/eche_app_ui/eche_app_manager.h +++ b/chromeos/components/eche_app_ui/eche_app_manager.h
@@ -6,6 +6,7 @@ #define CHROMEOS_COMPONENTS_ECHE_APP_UI_ECHE_APP_MANAGER_H_ #include <stdint.h> +#include <memory> #include "chromeos/components/eche_app_ui/eche_connector.h" #include "chromeos/components/eche_app_ui/eche_feature_status_provider.h" @@ -15,6 +16,7 @@ #include "chromeos/components/eche_app_ui/mojom/eche_app.mojom.h" #include "chromeos/components/phonehub/phone_hub_manager.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" +#include "chromeos/services/secure_channel/public/cpp/client/presence_monitor_client_impl.h" #include "components/keyed_service/core/keyed_service.h" #include "mojo/public/cpp/bindings/remote.h" @@ -37,12 +39,13 @@ namespace eche_app { -class SystemInfo; -class EcheSignaler; -class SystemInfoProvider; -class EcheUidProvider; -class EcheNotificationGenerator; class EcheMessageReceiver; +class EcheNotificationGenerator; +class EchePresenceManager; +class EcheSignaler; +class EcheUidProvider; +class SystemInfo; +class SystemInfoProvider; // Implements the core logic of the EcheApp and exposes interfaces via its // public API. Implemented as a KeyedService since it depends on other @@ -55,6 +58,8 @@ device_sync::DeviceSyncClient*, multidevice_setup::MultiDeviceSetupClient*, secure_channel::SecureChannelClient*, + std::unique_ptr<secure_channel::PresenceMonitorClient> + presence_monitor_client, LaunchAppHelper::LaunchEcheAppFunction, LaunchAppHelper::CloseEcheAppFunction, LaunchAppHelper::LaunchNotificationFunction); @@ -86,6 +91,7 @@ eche_notification_click_handler_; std::unique_ptr<EcheConnector> eche_connector_; std::unique_ptr<EcheSignaler> signaler_; + std::unique_ptr<EchePresenceManager> eche_presence_manager_; std::unique_ptr<EcheUidProvider> uid_; std::unique_ptr<EcheRecentAppClickHandler> eche_recent_app_click_handler_; std::unique_ptr<EcheNotificationGenerator> notification_generator_;
diff --git a/chromeos/components/eche_app_ui/eche_connector.cc b/chromeos/components/eche_app_ui/eche_connector.cc index 51099673..aa2aff72 100644 --- a/chromeos/components/eche_app_ui/eche_connector.cc +++ b/chromeos/components/eche_app_ui/eche_connector.cc
@@ -10,7 +10,6 @@ #include "chromeos/components/multidevice/software_feature.h" #include "chromeos/components/multidevice/software_feature_state.h" #include "chromeos/components/phonehub/phone_hub_manager.h" -#include "chromeos/services/device_sync/public/cpp/device_sync_client.h" #include "chromeos/services/secure_channel/public/cpp/client/connection_manager.h" namespace chromeos { @@ -84,12 +83,12 @@ const FeatureStatus feature_status = eche_feature_status_provider_->GetStatus(); if (feature_status == FeatureStatus::kConnected && !queue_.empty()) { + PA_LOG(INFO) << "Flushing message queue"; FlushQueue(); } } void EcheConnector::FlushQueue() { - PA_LOG(INFO) << "Flushing message queue"; const int size = queue_.size(); for (int i = 0; i < size; i++) { connection_manager_->SendMessage(queue_.front());
diff --git a/chromeos/components/eche_app_ui/eche_presence_manager.cc b/chromeos/components/eche_app_ui/eche_presence_manager.cc new file mode 100644 index 0000000..57f31cd --- /dev/null +++ b/chromeos/components/eche_app_ui/eche_presence_manager.cc
@@ -0,0 +1,146 @@ +// Copyright 2021 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 "chromeos/components/eche_app_ui/eche_presence_manager.h" + +#include "chromeos/components/eche_app_ui/eche_connector.h" +#include "chromeos/components/eche_app_ui/proto/exo_messages.pb.h" +#include "chromeos/components/multidevice/logging/logging.h" +#include "chromeos/components/multidevice/remote_device_ref.h" +#include "chromeos/services/device_sync/public/cpp/device_sync_client.h" +#include "chromeos/services/secure_channel/public/cpp/client/presence_monitor_client.h" + +namespace chromeos { +namespace eche_app { + +namespace { + +// How often to check whether the last seen time is below the maximum age. +constexpr base::TimeDelta kTimerInterval = base::Seconds(30); +// The maximum age of the last seen time before the connection must be +// terminated. +constexpr base::TimeDelta kMaximumLastSeenAge = base::Minutes(5); + +} // namespace + +EchePresenceManager::EchePresenceManager( + EcheFeatureStatusProvider* eche_feature_status_provider, + device_sync::DeviceSyncClient* device_sync_client, + multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, + std::unique_ptr<secure_channel::PresenceMonitorClient> + presence_monitor_client, + EcheConnector* eche_connector) + : eche_feature_status_provider_(eche_feature_status_provider), + device_sync_client_(device_sync_client), + multidevice_setup_client_(multidevice_setup_client), + presence_monitor_client_(std::move(presence_monitor_client)), + eche_connector_(eche_connector) { + eche_feature_status_provider_->AddObserver(this); + presence_monitor_client_->SetPresenceMonitorCallbacks( + base::BindRepeating(&EchePresenceManager::OnReady, + weak_ptr_factory_.GetWeakPtr()), + base::BindRepeating(&EchePresenceManager::OnDeviceSeen, + weak_ptr_factory_.GetWeakPtr())); +} + +EchePresenceManager::~EchePresenceManager() { + eche_feature_status_provider_->RemoveObserver(this); +} + +void EchePresenceManager::OnFeatureStatusChanged() { + UpdateMonitoringStatus(); +} + +void EchePresenceManager::OnReady() { + UpdateMonitoringStatus(); +} + +void EchePresenceManager::UpdateMonitoringStatus() { + const FeatureStatus feature_status = + eche_feature_status_provider_->GetStatus(); + switch (feature_status) { + case FeatureStatus::kIneligible: + ABSL_FALLTHROUGH_INTENDED; + case FeatureStatus::kDisabled: + ABSL_FALLTHROUGH_INTENDED; + case FeatureStatus::kDependentFeature: + ABSL_FALLTHROUGH_INTENDED; + case FeatureStatus::kDependentFeaturePending: + ABSL_FALLTHROUGH_INTENDED; + case FeatureStatus::kDisconnected: + ABSL_FALLTHROUGH_INTENDED; + case FeatureStatus::kConnecting: + StopMonitoring(); + break; + + case FeatureStatus::kConnected: + StartMonitoring(); + break; + } +} + +void EchePresenceManager::StartMonitoring() { + if (is_monitoring_) { + return; + } + + const absl::optional<multidevice::RemoteDeviceRef> remote_device_ref = + multidevice_setup_client_->GetHostStatus().second; + const absl::optional<multidevice::RemoteDeviceRef> local_device_ref = + device_sync_client_->GetLocalDeviceMetadata(); + if (!remote_device_ref || !local_device_ref) { + return; + } + + // Before we start monitoring we don't know when the device was last seen, so + // set it to something far out of the expected time window to start. This will + // be properly set once we see the first advertisement, and if one is not seen + // before the first check, will return that the devices are out of proximity. + device_last_seen_time_ = base::TimeTicks::UnixEpoch(); + is_monitoring_ = true; + + if (timer_.IsRunning()) { + timer_.Reset(); + } else { + timer_.Start(FROM_HERE, kTimerInterval, + base::BindRepeating(&EchePresenceManager::OnTimerExpired, + weak_ptr_factory_.GetWeakPtr())); + } + + presence_monitor_client_->StartMonitoring(remote_device_ref.value(), + local_device_ref.value()); +} + +void EchePresenceManager::StopMonitoring() { + if (!is_monitoring_) { + return; + } + + timer_.Stop(); + presence_monitor_client_->StopMonitoring(); + is_monitoring_ = false; +} + +void EchePresenceManager::OnTimerExpired() { + if ((base::TimeTicks::Now() - device_last_seen_time_) > kMaximumLastSeenAge) { + PA_LOG(INFO) << "Proximity has not been maintained; stopping monitoring"; + StopMonitoring(); + } else { + PA_LOG(INFO) << "Proximity has been maintained; sending ping"; + proto::ProximityPing ping; + proto::ExoMessage message; + *message.mutable_proximity_ping() = std::move(ping); + eche_connector_->SendMessage(message.SerializeAsString()); + } +} + +void EchePresenceManager::OnDeviceSeen() { + // It is the responsibility of the scanner to ensure outdated advertisements + // are not forwarded through, so we will treat all received advertisements as + // valid. + device_last_seen_time_ = base::TimeTicks::Now(); +} + +} // namespace eche_app +} // namespace chromeos
diff --git a/chromeos/components/eche_app_ui/eche_presence_manager.h b/chromeos/components/eche_app_ui/eche_presence_manager.h new file mode 100644 index 0000000..4935e88da --- /dev/null +++ b/chromeos/components/eche_app_ui/eche_presence_manager.h
@@ -0,0 +1,83 @@ +// Copyright 2021 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 CHROMEOS_COMPONENTS_ECHE_APP_UI_ECHE_PRESENCE_MANAGER_H_ +#define CHROMEOS_COMPONENTS_ECHE_APP_UI_ECHE_PRESENCE_MANAGER_H_ + +#include <memory> + +#include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" +#include "chromeos/components/eche_app_ui/eche_feature_status_provider.h" +#include "chromeos/components/eche_app_ui/feature_status_provider.h" + +namespace chromeos { + +namespace device_sync { + +class DeviceSyncClient; + +} // namespace device_sync + +namespace multidevice_setup { + +class MultiDeviceSetupClient; + +} // namespace multidevice_setup + +namespace secure_channel { + +class PresenceMonitorClient; + +} // namespace secure_channel + +namespace eche_app { + +class EcheConnector; + +// Control presence monitoring and the sending of keepalives. +class EchePresenceManager : public FeatureStatusProvider::Observer { + public: + EchePresenceManager( + EcheFeatureStatusProvider* eche_feature_status_provider, + device_sync::DeviceSyncClient* device_sync_client, + multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, + std::unique_ptr<secure_channel::PresenceMonitorClient> + presence_monitor_client, + EcheConnector* eche_connector); + ~EchePresenceManager() override; + + EchePresenceManager(const EchePresenceManager&) = delete; + EchePresenceManager& operator=(const EchePresenceManager&) = delete; + + private: + // FeatureStatusProvider::Observer: + void OnFeatureStatusChanged() override; + + void OnReady(); + void OnDeviceSeen(); + + void UpdateMonitoringStatus(); + void StartMonitoring(); + void StopMonitoring(); + void OnTimerExpired(); + + EcheFeatureStatusProvider* eche_feature_status_provider_; + device_sync::DeviceSyncClient* device_sync_client_; + multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client_; + std::unique_ptr<secure_channel::PresenceMonitorClient> + presence_monitor_client_; + EcheConnector* eche_connector_; + base::RepeatingTimer timer_; + + bool is_monitoring_ = false; + base::TimeTicks device_last_seen_time_; + + base::WeakPtrFactory<EchePresenceManager> weak_ptr_factory_{this}; +}; + +} // namespace eche_app +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_ECHE_APP_UI_ECHE_PRESENCE_MANAGER_H_
diff --git a/chromeos/components/multidevice/remote_device_ref.h b/chromeos/components/multidevice/remote_device_ref.h index d943418..65047f36 100644 --- a/chromeos/components/multidevice/remote_device_ref.h +++ b/chromeos/components/multidevice/remote_device_ref.h
@@ -23,6 +23,7 @@ } // namespace multidevice_setup namespace secure_channel { +class PresenceMonitorClientImpl; class SecureChannelClientImpl; } // namespace secure_channel @@ -92,6 +93,7 @@ private: friend class multidevice_setup::MultiDeviceSetupImpl; friend class secure_channel::SecureChannelClientImpl; + friend class secure_channel::PresenceMonitorClientImpl; friend class RemoteDeviceCache; friend class RemoteDeviceRefBuilder; friend class RemoteDeviceRefTest;
diff --git a/chromeos/services/bluetooth_config/OWNERS b/chromeos/services/bluetooth_config/OWNERS index 5189b388..33cd4c86 100644 --- a/chromeos/services/bluetooth_config/OWNERS +++ b/chromeos/services/bluetooth_config/OWNERS
@@ -1 +1,2 @@ -khorimoto@chromium.org +gordonseto@google.com +khorimoto@chromium.org \ No newline at end of file
diff --git a/chromeos/services/libassistant/conversation_controller.cc b/chromeos/services/libassistant/conversation_controller.cc index d24f753..8bb637a 100644 --- a/chromeos/services/libassistant/conversation_controller.cc +++ b/chromeos/services/libassistant/conversation_controller.cc
@@ -11,9 +11,11 @@ #include "base/thread_annotations.h" #include "base/threading/sequenced_task_runner_handle.h" #include "chromeos/assistant/internal/internal_util.h" +#include "chromeos/assistant/internal/proto/shared/proto/v2/internal_options.pb.h" #include "chromeos/services/assistant/public/cpp/features.h" #include "chromeos/services/libassistant/grpc/assistant_client.h" #include "chromeos/services/libassistant/public/mojom/conversation_controller.mojom.h" +#include "chromeos/services/libassistant/util.h" #include "chromeos/strings/grit/chromeos_strings.h" #include "libassistant/shared/internal_api/assistant_manager_delegate.h" #include "libassistant/shared/internal_api/assistant_manager_internal.h" @@ -257,15 +259,13 @@ void ConversationController::OnAssistantClientRunning( AssistantClient* assistant_client) { // Only when Libassistant is running we can start sending queries. - assistant_manager_ = assistant_client->assistant_manager(); - assistant_manager_internal_ = assistant_client->assistant_manager_internal(); + assistant_client_ = assistant_client; requests_are_allowed_ = true; } void ConversationController::OnDestroyingAssistantClient( AssistantClient* assistant_client) { - assistant_manager_ = nullptr; - assistant_manager_internal_ = nullptr; + assistant_client_ = nullptr; } void ConversationController::SendTextQuery(const std::string& query, @@ -275,28 +275,27 @@ DCHECK(requests_are_allowed_) << "Should not receive requests before Libassistant is running"; - if (!assistant_manager_internal_) + if (!assistant_client_) return; MaybeStopPreviousInteraction(); // Configs |VoicelessOptions|. - assistant_client::VoicelessOptions options; - options.is_user_initiated = true; + ::assistant::api::VoicelessOptions options; + options.set_is_user_initiated(true); if (!allow_tts) { - options.modality = - assistant_client::VoicelessOptions::Modality::TYPING_MODALITY; + options.set_modality(::assistant::api::VoicelessOptions::TYPING_MODALITY); } // Remember the interaction metadata, and pass the generated conversation id // to LibAssistant. - options.conversation_turn_id = - assistant_manager_delegate_->AddPendingTextInteraction(query, source); + options.set_conversation_turn_id( + assistant_manager_delegate_->AddPendingTextInteraction(query, source)); // Builds text interaction. - std::string interaction = assistant::CreateTextQueryInteraction(query); + auto interaction = CreateTextQueryInteraction(query); - assistant_manager_internal_->SendVoicelessInteraction( - interaction, /*description=*/"text_query", options, [](auto) {}); + assistant_client_->SendVoicelessInteraction( + interaction, /*description=*/"text_query", options, base::DoNothing()); } void ConversationController::StartVoiceInteraction() { @@ -304,21 +303,21 @@ DCHECK(requests_are_allowed_) << "Should not receive requests before Libassistant is running"; - if (!assistant_manager_) { + if (!assistant_client_) { VLOG(1) << "Starting voice interaction without assistant manager."; return; } MaybeStopPreviousInteraction(); - assistant_manager_->StartAssistantInteraction(); + assistant_client_->StartVoiceInteraction(); } void ConversationController::StartEditReminderInteraction( const std::string& client_id) { DCHECK(requests_are_allowed_) << "Should not receive requests before Libassistant is running"; - if (!assistant_manager_internal_) + if (!assistant_client_) return; // Cancels any ongoing StopInteraction posted by StopActiveInteraction() @@ -328,9 +327,12 @@ // See b/182948180. MaybeStopPreviousInteraction(); - SendVoicelessInteraction(assistant::CreateEditReminderInteraction(client_id), - /*description=*/std::string(), - /*is_user_initiated=*/true); + ::assistant::api::VoicelessOptions options; + options.set_is_user_initiated(true); + + assistant_client_->SendVoicelessInteraction( + CreateEditReminderInteraction(client_id), + /*description=*/std::string(), options, base::DoNothing()); } void ConversationController::StartScreenContextInteraction( @@ -338,7 +340,7 @@ const std::vector<uint8_t>& screenshot) { DCHECK(requests_are_allowed_) << "Should not receive requests before Libassistant is running"; - if (!assistant_manager_internal_) + if (!assistant_client_) return; MaybeStopPreviousInteraction(); @@ -364,11 +366,11 @@ context_protos.emplace_back( chromeos::assistant::CreateContextProto(screenshot, /*is_first_query=*/true)); - assistant_manager_internal_->SendScreenContextRequest(context_protos); + assistant_client_->SendScreenContextRequest(context_protos); } void ConversationController::StopActiveInteraction(bool cancel_conversation) { - if (!assistant_manager_internal_) { + if (!assistant_client_) { VLOG(1) << "Stopping interaction without assistant manager."; return; } @@ -378,12 +380,11 @@ // stability as Libassistant might misbehave when it's forcefully stopped. auto stop_callback = [](base::WeakPtr<ConversationController> weak_this, bool cancel_conversation) { - if (!weak_this || !weak_this->assistant_manager_internal_) { + if (!weak_this || !weak_this->assistant_client_) { return; } VLOG(1) << "Stopping Assistant interaction."; - weak_this->assistant_manager_internal_->StopAssistantInteractionInternal( - cancel_conversation); + weak_this->assistant_client_->StopAssistantInteraction(cancel_conversation); }; stop_interaction_closure_ = @@ -400,55 +401,59 @@ int32_t action_index) { DCHECK(requests_are_allowed_) << "Should not receive requests before Libassistant is running"; - if (!assistant_manager_internal_) + if (!assistant_client_) return; - const std::string request_interaction = - assistant::SerializeNotificationRequestInteraction( - notification.server_id, notification.consistency_token, - notification.opaque_token, action_index); + auto request_interaction = CreateNotificationRequestInteraction( + notification.server_id, notification.consistency_token, + notification.opaque_token, action_index); - SendVoicelessInteraction(request_interaction, - /*description=*/"RequestNotification", - /*is_user_initiated=*/true); + ::assistant::api::VoicelessOptions options; + options.set_is_user_initiated(true); + + assistant_client_->SendVoicelessInteraction( + request_interaction, + /*description=*/"RequestNotification", options, base::DoNothing()); } void ConversationController::DismissNotification( AssistantNotification notification) { DCHECK(requests_are_allowed_) << "Should not receive requests before Libassistant is running"; - if (!assistant_manager_internal_) + if (!assistant_client_) return; - const std::string dismissed_interaction = - assistant::SerializeNotificationDismissedInteraction( - notification.server_id, notification.consistency_token, - notification.opaque_token, {notification.grouping_key}); + auto dismissed_interaction = CreateNotificationDismissedInteraction( + notification.server_id, notification.consistency_token, + notification.opaque_token, {notification.grouping_key}); - assistant_client::VoicelessOptions options; - options.obfuscated_gaia_id = notification.obfuscated_gaia_id; + ::assistant::api::VoicelessOptions options; + options.set_obfuscated_gaia_id(notification.obfuscated_gaia_id); - assistant_manager_internal_->SendVoicelessInteraction( + assistant_client_->SendVoicelessInteraction( dismissed_interaction, /*description=*/"DismissNotification", options, - [](auto) {}); + base::DoNothing()); } void ConversationController::SendAssistantFeedback( const AssistantFeedback& feedback) { DCHECK(requests_are_allowed_) << "Should not receive requests before Libassistant is running"; - if (!assistant_manager_internal_) + if (!assistant_client_) return; std::string raw_image_data(feedback.screenshot_png.begin(), feedback.screenshot_png.end()); - const std::string interaction = assistant::CreateSendFeedbackInteraction( - feedback.assistant_debug_info_allowed, feedback.description, - raw_image_data); + auto interaction = + CreateSendFeedbackInteraction(feedback.assistant_debug_info_allowed, + feedback.description, raw_image_data); - SendVoicelessInteraction(interaction, - /*description=*/"send feedback with details", - /*is_user_initiated=*/false); + ::assistant::api::VoicelessOptions options; + options.set_is_user_initiated(false); + + assistant_client_->SendVoicelessInteraction( + interaction, /*description=*/"send feedback with details", options, + base::DoNothing()); } void ConversationController::AddRemoteObserver( @@ -516,15 +521,14 @@ // Note that we will always set |provider_found| to true since the preceding // OnVerifyAndroidApp() should already confirm that the requested provider is // available on the device. - std::string interaction_proto = - assistant::CreateOpenProviderResponseInteraction( - interaction.interaction_id, /*provider_found=*/true); - assistant_client::VoicelessOptions options; - options.obfuscated_gaia_id = interaction.user_id; + auto interaction_proto = CreateOpenProviderResponseInteraction( + interaction.interaction_id, /*provider_found=*/true); + ::assistant::api::VoicelessOptions options; + options.set_obfuscated_gaia_id(interaction.user_id); - assistant_manager_internal_->SendVoicelessInteraction( + assistant_client_->SendVoicelessInteraction( interaction_proto, /*description=*/"open_provider_response", options, - [](auto) {}); + base::DoNothing()); } // Called from Libassistant thread. @@ -582,16 +586,5 @@ stop_interaction_closure_->callback().Run(); } -void ConversationController::SendVoicelessInteraction( - const std::string& interaction, - const std::string& description, - bool is_user_initiated) { - assistant_client::VoicelessOptions voiceless_options; - voiceless_options.is_user_initiated = is_user_initiated; - - assistant_manager_internal_->SendVoicelessInteraction( - interaction, description, voiceless_options, [](auto) {}); -} - } // namespace libassistant } // namespace chromeos
diff --git a/chromeos/services/libassistant/conversation_controller.h b/chromeos/services/libassistant/conversation_controller.h index 51f5ac0..80843e52 100644 --- a/chromeos/services/libassistant/conversation_controller.h +++ b/chromeos/services/libassistant/conversation_controller.h
@@ -21,11 +21,6 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote_set.h" -namespace assistant_client { -class AssistantManager; -class AssistantManagerInternal; -} // namespace assistant_client - namespace chromeos { namespace assistant { namespace action { @@ -35,6 +30,8 @@ namespace libassistant { +class AssistantClient; + class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) ConversationController : public mojom::ConversationController, public AssistantClientObserver, @@ -117,19 +114,17 @@ void MaybeStopPreviousInteraction(); - void SendVoicelessInteraction(const std::string& interaction, - const std::string& description, - bool is_user_initiated); - mojo::Receiver<mojom::ConversationController> receiver_; mojo::RemoteSet<mojom::ConversationObserver> observers_; mojo::RemoteSet<mojom::AuthenticationStateObserver> authentication_state_observers_; mojo::Remote<mojom::NotificationDelegate> notification_delegate_; - assistant_client::AssistantManager* assistant_manager_ = nullptr; - assistant_client::AssistantManagerInternal* assistant_manager_internal_ = - nullptr; + // Owned by ServiceController. + // Set in `OnAssistantClientCreated()` and unset in + // `OnDestroyingAssistantClient()`. + AssistantClient* assistant_client_ = nullptr; + // False until libassistant is running for the first time. // Any request that comes in before that is an error and will be DCHECK'ed. bool requests_are_allowed_ = false;
diff --git a/chromeos/services/libassistant/conversation_controller_unittest.cc b/chromeos/services/libassistant/conversation_controller_unittest.cc index f8349d527..6fcc419 100644 --- a/chromeos/services/libassistant/conversation_controller_unittest.cc +++ b/chromeos/services/libassistant/conversation_controller_unittest.cc
@@ -5,8 +5,6 @@ #include "chromeos/services/libassistant/conversation_controller.h" #include "base/run_loop.h" #include "base/test/task_environment.h" -#include "chromeos/assistant/internal/test_support/fake_assistant_manager.h" -#include "chromeos/assistant/internal/test_support/fake_assistant_manager_internal.h" #include "chromeos/assistant/test_support/expect_utils.h" #include "chromeos/services/libassistant/test_support/fake_assistant_client.h" #include "testing/gmock/include/gmock/gmock.h" @@ -17,79 +15,54 @@ namespace { -class AssistantManagerInternalMock - : public assistant::FakeAssistantManagerInternal { +class AssistantClientMock : public FakeAssistantClient { public: - AssistantManagerInternalMock() = default; - AssistantManagerInternalMock(const AssistantManagerInternalMock&) = delete; - AssistantManagerInternalMock& operator=(const AssistantManagerInternalMock&) = - delete; - ~AssistantManagerInternalMock() override = default; + AssistantClientMock( + std::unique_ptr<assistant::FakeAssistantManager> assistant_manager, + assistant::FakeAssistantManagerInternal* assistant_manager_internal) + : FakeAssistantClient(std::move(assistant_manager), + assistant_manager_internal) {} + ~AssistantClientMock() override = default; - // assistant::FakeAssistantManagerInternal implementation: - MOCK_METHOD(void, - StopAssistantInteractionInternal, - (bool cancel_conversation)); + // AssistantClient: + MOCK_METHOD(void, StartVoiceInteraction, ()); + MOCK_METHOD(void, StopAssistantInteraction, (bool cancel_conversation)); MOCK_METHOD(void, SendVoicelessInteraction, - (const std::string&, - const std::string&, - const assistant_client::VoicelessOptions& options, - assistant_client::SuccessCallbackInternal on_done)); -}; - -class AssistantManagerMock : public assistant::FakeAssistantManager { - public: - AssistantManagerMock() = default; - AssistantManagerMock(const AssistantManagerMock&) = delete; - AssistantManagerMock& operator=(const AssistantManagerMock&) = delete; - ~AssistantManagerMock() override = default; - - // assistant::FakeAssistantManager implementation: - MOCK_METHOD(void, StartAssistantInteraction, ()); + (const ::assistant::api::Interaction& interaction, + const std::string& description, + const ::assistant::api::VoicelessOptions& options, + base::OnceCallback<void(bool)> on_done)); }; } // namespace class ConversationControllerTest : public ::testing::Test { public: - ConversationControllerTest() { - auto fake_assistant_manager = std::make_unique<AssistantManagerMock>(); - assistant_client_ = std::make_unique<FakeAssistantClient>( - std::move(fake_assistant_manager), &assistant_manager_internal_); - } + ConversationControllerTest() = default; ConversationControllerTest(const ConversationControllerTest&) = delete; ConversationControllerTest& operator=(const ConversationControllerTest&) = delete; ~ConversationControllerTest() override = default; void StartLibassistant() { - controller_.OnAssistantClientRunning(assistant_client_.get()); + controller_.OnAssistantClientRunning(&assistant_client_); } ConversationController& controller() { return controller_; } - AssistantManagerMock& assistant_manager_mock() { - return *(reinterpret_cast<AssistantManagerMock*>( - assistant_client_->assistant_manager())); - } - - AssistantManagerInternalMock& assistant_manager_internal_mock() { - return *(reinterpret_cast<AssistantManagerInternalMock*>( - assistant_client_->assistant_manager_internal())); - } + AssistantClientMock& assistant_client_mock() { return assistant_client_; } private: base::test::SingleThreadTaskEnvironment environment_; ConversationController controller_; - AssistantManagerInternalMock assistant_manager_internal_; - std::unique_ptr<FakeAssistantClient> assistant_client_; + AssistantClientMock assistant_client_{nullptr, nullptr}; }; TEST_F(ConversationControllerTest, ShouldStartVoiceInteraction) { StartLibassistant(); - EXPECT_CALL(assistant_manager_mock(), StartAssistantInteraction()); + EXPECT_CALL(assistant_client_mock(), StartVoiceInteraction()); controller().StartVoiceInteraction(); } @@ -97,32 +70,26 @@ TEST_F(ConversationControllerTest, ShouldStopInteractionAfterDelay) { StartLibassistant(); - EXPECT_CALL(assistant_manager_internal_mock(), - StopAssistantInteractionInternal) - .Times(0); + EXPECT_CALL(assistant_client_mock(), StopAssistantInteraction).Times(0); controller().StopActiveInteraction(true); - testing::Mock::VerifyAndClearExpectations(&assistant_manager_internal_mock()); + testing::Mock::VerifyAndClearExpectations(&assistant_client_mock()); - WAIT_FOR_CALL(assistant_manager_internal_mock(), - StopAssistantInteractionInternal); + WAIT_FOR_CALL(assistant_client_mock(), StopAssistantInteraction); } TEST_F(ConversationControllerTest, ShouldStopInteractionImmediatelyBeforeNewVoiceInteraction) { StartLibassistant(); - EXPECT_CALL(assistant_manager_internal_mock(), - StopAssistantInteractionInternal) - .Times(0); + EXPECT_CALL(assistant_client_mock(), StopAssistantInteraction).Times(0); controller().StopActiveInteraction(true); - testing::Mock::VerifyAndClearExpectations(&assistant_manager_internal_mock()); + testing::Mock::VerifyAndClearExpectations(&assistant_client_mock()); - ::testing::Expectation stop = EXPECT_CALL(assistant_manager_internal_mock(), - StopAssistantInteractionInternal) - .Times(1); - EXPECT_CALL(assistant_manager_mock(), StartAssistantInteraction) + ::testing::Expectation stop = + EXPECT_CALL(assistant_client_mock(), StopAssistantInteraction).Times(1); + EXPECT_CALL(assistant_client_mock(), StartVoiceInteraction) .Times(1) .After(stop); controller().StartVoiceInteraction(); @@ -132,17 +99,14 @@ ShouldStopInteractionImmediatelyBeforeNewEditReminderInteraction) { StartLibassistant(); - EXPECT_CALL(assistant_manager_internal_mock(), - StopAssistantInteractionInternal) - .Times(0); + EXPECT_CALL(assistant_client_mock(), StopAssistantInteraction).Times(0); controller().StopActiveInteraction(true); - testing::Mock::VerifyAndClearExpectations(&assistant_manager_internal_mock()); + testing::Mock::VerifyAndClearExpectations(&assistant_client_mock()); - ::testing::Expectation stop = EXPECT_CALL(assistant_manager_internal_mock(), - StopAssistantInteractionInternal) - .Times(1); - EXPECT_CALL(assistant_manager_internal_mock(), SendVoicelessInteraction) + ::testing::Expectation stop = + EXPECT_CALL(assistant_client_mock(), StopAssistantInteraction).Times(1); + EXPECT_CALL(assistant_client_mock(), SendVoicelessInteraction) .Times(1) .After(stop); controller().StartEditReminderInteraction("client-id");
diff --git a/chromeos/services/libassistant/grpc/assistant_client.h b/chromeos/services/libassistant/grpc/assistant_client.h index acfc75b..6b8fa6f6 100644 --- a/chromeos/services/libassistant/grpc/assistant_client.h +++ b/chromeos/services/libassistant/grpc/assistant_client.h
@@ -105,11 +105,6 @@ virtual void AddExperimentIds(const std::vector<std::string>& exp_ids) = 0; - virtual void SendVoicelessInteraction( - const ::assistant::api::Interaction& interaction, - const std::string& description, - const ::assistant::api::VoicelessOptions& options, - base::OnceCallback<void(bool)> on_done) = 0; // Speaker Id Enrollment methods. virtual void AddSpeakerIdEnrollmentEventObserver( @@ -142,8 +137,17 @@ GrpcServicesObserver<OnDeviceStateEventRequest>* observer) = 0; // Conversation methods. + virtual void SendVoicelessInteraction( + const ::assistant::api::Interaction& interaction, + const std::string& description, + const ::assistant::api::VoicelessOptions& options, + base::OnceCallback<void(bool)> on_done) = 0; virtual void RegisterActionModule( assistant_client::ActionModule* action_module) = 0; + virtual void SendScreenContextRequest( + const std::vector<std::string>& context_protos) = 0; + virtual void StartVoiceInteraction() = 0; + virtual void StopAssistantInteraction(bool cancel_conversation) = 0; // Settings-related functionality during bootup: virtual void SetAuthenticationInfo(const AuthTokens& tokens) = 0;
diff --git a/chromeos/services/libassistant/grpc/assistant_client_v1.cc b/chromeos/services/libassistant/grpc/assistant_client_v1.cc index 7f7090ad..c82ef0d 100644 --- a/chromeos/services/libassistant/grpc/assistant_client_v1.cc +++ b/chromeos/services/libassistant/grpc/assistant_client_v1.cc
@@ -266,7 +266,7 @@ } AssistantClientV1::~AssistantClientV1() { - // Some listeners (e.g. MediaManagerListener) require that they outlive + // Some listeners (e.g. MediaManagerListener) require that they outlive // `assistant_manager_`. Reset `assistant_manager_` in the parent class first // before any listener in this class gets destructed. ResetAssistantManager(); @@ -295,20 +295,6 @@ assistant_manager_internal()->AddExtraExperimentIds(exp_ids); } -void AssistantClientV1::SendVoicelessInteraction( - const ::assistant::api::Interaction& interaction, - const std::string& description, - const ::assistant::api::VoicelessOptions& options, - base::OnceCallback<void(bool)> on_done) { - assistant_client::VoicelessOptions voiceless_options; - PopulateVoicelessOptionsFromProto(options, &voiceless_options); - assistant_manager_internal()->SendVoicelessInteraction( - interaction.SerializeAsString(), description, voiceless_options, - [callback = std::move(on_done)](bool result) mutable { - std::move(callback).Run(result); - }); -} - void AssistantClientV1::AddSpeakerIdEnrollmentEventObserver( GrpcServicesObserver<OnSpeakerIdEnrollmentEventRequest>* observer) { speaker_event_observer_list_.AddObserver(observer); @@ -389,11 +375,39 @@ device_state_event_observer_list_.AddObserver(observer); } +void AssistantClientV1::SendVoicelessInteraction( + const ::assistant::api::Interaction& interaction, + const std::string& description, + const ::assistant::api::VoicelessOptions& options, + base::OnceCallback<void(bool)> on_done) { + assistant_client::VoicelessOptions voiceless_options; + PopulateVoicelessOptionsFromProto(options, &voiceless_options); + assistant_manager_internal()->SendVoicelessInteraction( + interaction.SerializeAsString(), description, voiceless_options, + [callback = std::move(on_done)](bool result) mutable { + std::move(callback).Run(result); + }); +} + void AssistantClientV1::RegisterActionModule( assistant_client::ActionModule* action_module) { assistant_manager_internal()->RegisterActionModule(action_module); } +void AssistantClientV1::SendScreenContextRequest( + const std::vector<std::string>& context_protos) { + assistant_manager_internal()->SendScreenContextRequest(context_protos); +} + +void AssistantClientV1::StartVoiceInteraction() { + assistant_manager()->StartAssistantInteraction(); +} + +void AssistantClientV1::StopAssistantInteraction(bool cancel_conversation) { + assistant_manager_internal()->StopAssistantInteractionInternal( + cancel_conversation); +} + void AssistantClientV1::SetAuthenticationInfo(const AuthTokens& tokens) { assistant_manager()->SetAuthTokens(tokens); }
diff --git a/chromeos/services/libassistant/grpc/assistant_client_v1.h b/chromeos/services/libassistant/grpc/assistant_client_v1.h index fcf587c4..7e1963d7 100644 --- a/chromeos/services/libassistant/grpc/assistant_client_v1.h +++ b/chromeos/services/libassistant/grpc/assistant_client_v1.h
@@ -33,11 +33,6 @@ assistant_client::ChromeOSApiDelegate* delegate) override; bool StartGrpcServices() override; void AddExperimentIds(const std::vector<std::string>& exp_ids) override; - void SendVoicelessInteraction( - const ::assistant::api::Interaction& interaction, - const std::string& description, - const ::assistant::api::VoicelessOptions& options, - base::OnceCallback<void(bool)> on_done) override; void AddSpeakerIdEnrollmentEventObserver( GrpcServicesObserver<OnSpeakerIdEnrollmentEventRequest>* observer) override; @@ -60,8 +55,17 @@ void SetExternalPlaybackState(const MediaStatus& status_proto) override; void AddDeviceStateEventObserver( GrpcServicesObserver<OnDeviceStateEventRequest>* observer) override; + void SendVoicelessInteraction( + const ::assistant::api::Interaction& interaction, + const std::string& description, + const ::assistant::api::VoicelessOptions& options, + base::OnceCallback<void(bool)> on_done) override; void RegisterActionModule( assistant_client::ActionModule* action_module) override; + void SendScreenContextRequest( + const std::vector<std::string>& context_protos) override; + void StartVoiceInteraction() override; + void StopAssistantInteraction(bool cancel_conversation) override; void SetAuthenticationInfo(const AuthTokens& tokens) override; void SetInternalOptions(const std::string& locale, bool spoken_feedback_enabled) override;
diff --git a/chromeos/services/libassistant/test_support/fake_assistant_client.cc b/chromeos/services/libassistant/test_support/fake_assistant_client.cc index b27a4b5f..3c7e773c 100644 --- a/chromeos/services/libassistant/test_support/fake_assistant_client.cc +++ b/chromeos/services/libassistant/test_support/fake_assistant_client.cc
@@ -34,12 +34,6 @@ void FakeAssistantClient::AddExperimentIds( const std::vector<std::string>& exp_ids) {} -void FakeAssistantClient::SendVoicelessInteraction( - const ::assistant::api::Interaction& interaction, - const std::string& description, - const ::assistant::api::VoicelessOptions& options, - base::OnceCallback<void(bool)> on_done) {} - void FakeAssistantClient::AddSpeakerIdEnrollmentEventObserver( GrpcServicesObserver<OnSpeakerIdEnrollmentEventRequest>* observer) {} @@ -74,9 +68,22 @@ void FakeAssistantClient::AddDeviceStateEventObserver( GrpcServicesObserver<OnDeviceStateEventRequest>* observer) {} +void FakeAssistantClient::SendVoicelessInteraction( + const ::assistant::api::Interaction& interaction, + const std::string& description, + const ::assistant::api::VoicelessOptions& options, + base::OnceCallback<void(bool)> on_done) {} + void FakeAssistantClient::RegisterActionModule( assistant_client::ActionModule* action_module) {} +void FakeAssistantClient::SendScreenContextRequest( + const std::vector<std::string>& context_protos) {} + +void FakeAssistantClient::StartVoiceInteraction() {} + +void FakeAssistantClient::StopAssistantInteraction(bool cancel_conversation) {} + void FakeAssistantClient::SetInternalOptions(const std::string& locale, bool spoken_feedback_enabled) {}
diff --git a/chromeos/services/libassistant/test_support/fake_assistant_client.h b/chromeos/services/libassistant/test_support/fake_assistant_client.h index b683d32..77452816 100644 --- a/chromeos/services/libassistant/test_support/fake_assistant_client.h +++ b/chromeos/services/libassistant/test_support/fake_assistant_client.h
@@ -34,11 +34,6 @@ assistant_client::ChromeOSApiDelegate* delegate) override; bool StartGrpcServices() override; void AddExperimentIds(const std::vector<std::string>& exp_ids) override; - void SendVoicelessInteraction( - const ::assistant::api::Interaction& interaction, - const std::string& description, - const ::assistant::api::VoicelessOptions& options, - base::OnceCallback<void(bool)> on_done) override; void AddSpeakerIdEnrollmentEventObserver( GrpcServicesObserver<OnSpeakerIdEnrollmentEventRequest>* observer) override; @@ -61,8 +56,17 @@ void SetExternalPlaybackState(const MediaStatus& status_proto) override; void AddDeviceStateEventObserver( GrpcServicesObserver<OnDeviceStateEventRequest>* observer) override; + void SendVoicelessInteraction( + const ::assistant::api::Interaction& interaction, + const std::string& description, + const ::assistant::api::VoicelessOptions& options, + base::OnceCallback<void(bool)> on_done) override; void RegisterActionModule( assistant_client::ActionModule* action_module) override; + void SendScreenContextRequest( + const std::vector<std::string>& context_protos) override; + void StartVoiceInteraction() override; + void StopAssistantInteraction(bool cancel_conversation) override; void SetInternalOptions(const std::string& locale, bool spoken_feedback_enabled) override; void SetAuthenticationInfo(const AuthTokens& tokens) override;
diff --git a/chromeos/services/libassistant/util.cc b/chromeos/services/libassistant/util.cc index 1f840ef7..fcdfb3f 100644 --- a/chromeos/services/libassistant/util.cc +++ b/chromeos/services/libassistant/util.cc
@@ -349,5 +349,76 @@ .Proto(); } +Interaction CreateNotificationRequestInteraction( + const std::string& notification_id, + const std::string& consistent_token, + const std::string& opaque_token, + const int action_index) { + auto request_param = assistant::CreateNotificationRequestParam( + notification_id, consistent_token, opaque_token, action_index); + + return V1InteractionBuilder() + .SetClientInputName(assistant::kClientInputRequestNotification) + .AddClientInputParams(assistant::kNotificationRequestParamsKey, + request_param) + .Proto(); +} + +Interaction CreateNotificationDismissedInteraction( + const std::string& notification_id, + const std::string& consistent_token, + const std::string& opaque_token, + const std::vector<std::string>& grouping_keys) { + auto dismiss_param = assistant::CreateNotificationDismissedParam( + notification_id, consistent_token, opaque_token, grouping_keys); + + return V1InteractionBuilder() + .SetClientInputName(assistant::kClientInputDismissNotification) + .AddClientInputParams(assistant::kNotificationDismissParamsKey, + dismiss_param) + .Proto(); +} + +Interaction CreateEditReminderInteraction(const std::string& reminder_id) { + auto intent_input = assistant::CreateEditReminderParam(reminder_id); + + return V1InteractionBuilder() + .SetClientInputName(assistant::kClientInputEditReminder) + .AddClientInputParams(assistant::kEditReminderParamsKey, intent_input) + .Proto(); +} + +Interaction CreateOpenProviderResponseInteraction(const int interaction_id, + const bool provider_found) { + return V1InteractionBuilder() + .SetInResponseTo(interaction_id) + .SetStatusCodeFromEntityFound(provider_found) + .Proto(); +} + +Interaction CreateSendFeedbackInteraction( + bool assistant_debug_info_allowed, + const std::string& feedback_description, + const std::string& screenshot_png) { + auto feedback_arg = assistant::CreateFeedbackParam( + assistant_debug_info_allowed, feedback_description, screenshot_png); + + return V1InteractionBuilder() + .SetClientInputName(assistant::kClientInputText) + .AddClientInputParams( + assistant::kTextParamsKey, + assistant::CreateTextParam(assistant::kFeedbackText)) + .AddClientInputParams(assistant::kFeedbackParamsKey, feedback_arg) + .Proto(); +} + +Interaction CreateTextQueryInteraction(const std::string& query) { + return V1InteractionBuilder() + .SetClientInputName(assistant::kClientInputText) + .AddClientInputParams(assistant::kTextParamsKey, + assistant::CreateTextParam(query)) + .Proto(); +} + } // namespace libassistant } // namespace chromeos
diff --git a/chromeos/services/libassistant/util.h b/chromeos/services/libassistant/util.h index ce795004..61ab09c 100644 --- a/chromeos/services/libassistant/util.h +++ b/chromeos/services/libassistant/util.h
@@ -45,6 +45,35 @@ int interaction_id, const std::vector<chromeos::assistant::DeviceSetting>& device_settings); +// `action_index` is the index of the actions and buttons. +::assistant::api::Interaction CreateNotificationRequestInteraction( + const std::string& notification_id, + const std::string& consistent_token, + const std::string& opaque_token, + const int action_index); + +// `grouping_keys` are the keys to group multiple notifications together. +::assistant::api::Interaction CreateNotificationDismissedInteraction( + const std::string& notification_id, + const std::string& consistent_token, + const std::string& opaque_token, + const std::vector<std::string>& grouping_keys); + +::assistant::api::Interaction CreateEditReminderInteraction( + const std::string& reminder_id); + +::assistant::api::Interaction CreateOpenProviderResponseInteraction( + const int interaction_id, + const bool provider_found); + +::assistant::api::Interaction CreateSendFeedbackInteraction( + bool assistant_debug_info_allowed, + const std::string& feedback_description, + const std::string& screenshot_png = std::string()); + +::assistant::api::Interaction CreateTextQueryInteraction( + const std::string& query); + } // namespace libassistant } // namespace chromeos
diff --git a/chromeos/services/secure_channel/BUILD.gn b/chromeos/services/secure_channel/BUILD.gn index 85cf6e8b8..ca8faab 100644 --- a/chromeos/services/secure_channel/BUILD.gn +++ b/chromeos/services/secure_channel/BUILD.gn
@@ -134,6 +134,10 @@ "pending_connection_request_delegate.h", "pending_nearby_initiator_connection_request.cc", "pending_nearby_initiator_connection_request.h", + "presence_monitor_delegate.cc", + "presence_monitor_delegate.h", + "presence_monitor_impl.cc", + "presence_monitor_impl.h", "raw_eid_generator.h", "raw_eid_generator_impl.cc", "raw_eid_generator_impl.h",
diff --git a/chromeos/services/secure_channel/presence_monitor_delegate.cc b/chromeos/services/secure_channel/presence_monitor_delegate.cc new file mode 100644 index 0000000..fe802ea --- /dev/null +++ b/chromeos/services/secure_channel/presence_monitor_delegate.cc
@@ -0,0 +1,74 @@ +// Copyright 2021 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 "chromeos/services/secure_channel/presence_monitor_delegate.h" + +#include "chromeos/components/multidevice/logging/logging.h" +#include "chromeos/components/multidevice/remote_device_cache.h" +#include "chromeos/services/secure_channel/ble_scanner_impl.h" +#include "chromeos/services/secure_channel/ble_synchronizer.h" +#include "chromeos/services/secure_channel/bluetooth_helper_impl.h" +#include "chromeos/services/secure_channel/connection_role.h" +#include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h" +#include "device/bluetooth/bluetooth_adapter.h" + +namespace chromeos { +namespace secure_channel { + +PresenceMonitorDelegate::PresenceMonitorDelegate( + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, + PresenceMonitor::DeviceSeenCallback device_seen_callback) + : bluetooth_adapter_(bluetooth_adapter), + device_seen_callback_(std::move(device_seen_callback)), + remote_device_cache_(multidevice::RemoteDeviceCache::Factory::Create()), + bluetooth_helper_( + BluetoothHelperImpl::Factory::Create(remote_device_cache_.get())), + ble_synchronizer_(BleSynchronizer::Factory::Create(bluetooth_adapter_)), + ble_scanner_(BleScannerImpl::Factory::Create(bluetooth_helper_.get(), + ble_synchronizer_.get(), + bluetooth_adapter_)) { + ble_scanner_->AddObserver(this); +} + +PresenceMonitorDelegate::~PresenceMonitorDelegate() { + ble_scanner_->RemoveObserver(this); +} + +void PresenceMonitorDelegate::StartMonitoring( + const multidevice::RemoteDevice& remote_device, + const multidevice::RemoteDevice& local_device) { + PA_LOG(INFO) << "Starting monitoring proximity"; + remote_device_id_ = remote_device.GetDeviceId(); + local_device_id_ = local_device.GetDeviceId(); + + remote_device_cache_->SetRemoteDevices({remote_device, local_device}); + + ble_scanner_->AddScanRequest(ConnectionAttemptDetails( + remote_device_id_, local_device_id_, + ConnectionMedium::kBluetoothLowEnergy, ConnectionRole::kListenerRole)); +} + +void PresenceMonitorDelegate::StopMonitoring() { + PA_LOG(INFO) << "Stopping monitoring proximity"; + ble_scanner_->RemoveScanRequest(ConnectionAttemptDetails( + remote_device_id_, local_device_id_, + ConnectionMedium::kBluetoothLowEnergy, ConnectionRole::kListenerRole)); + remote_device_id_.clear(); + local_device_id_.clear(); +} + +void PresenceMonitorDelegate::OnReceivedAdvertisement( + multidevice::RemoteDeviceRef remote_device_ref, + device::BluetoothDevice* bluetooth_device, + ConnectionMedium connection_medium, + ConnectionRole connection_role, + const std::vector<uint8_t>& eid) { + // It is the responsibility of the scanner to ensure outdated advertisements + // are not forwarded through, so we will treat all received advertisements as + // valid. + device_seen_callback_.Run(); +} + +} // namespace secure_channel +} // namespace chromeos
diff --git a/chromeos/services/secure_channel/presence_monitor_delegate.h b/chromeos/services/secure_channel/presence_monitor_delegate.h new file mode 100644 index 0000000..5389ee4 --- /dev/null +++ b/chromeos/services/secure_channel/presence_monitor_delegate.h
@@ -0,0 +1,65 @@ +// Copyright 2021 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 CHROMEOS_SERVICES_SECURE_CHANNEL_PRESENCE_MONITOR_DELEGATE_H_ +#define CHROMEOS_SERVICES_SECURE_CHANNEL_PRESENCE_MONITOR_DELEGATE_H_ + +#include "chromeos/services/secure_channel/ble_scanner.h" +#include "chromeos/services/secure_channel/public/cpp/shared/presence_monitor.h" + +namespace device { +class BluetoothAdapter; +class BluetoothDevice; +} // namespace device + +namespace chromeos { + +namespace multidevice { +class RemoteDeviceCache; +class RemoteDeviceRef; +} // namespace multidevice + +namespace secure_channel { + +class BleSynchronizerBase; +class BluetoothHelper; + +// Monitors device proximity while a secure channel is active. +class PresenceMonitorDelegate : public BleScanner::Observer { + public: + PresenceMonitorDelegate( + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, + PresenceMonitor::DeviceSeenCallback device_seen_callback); + ~PresenceMonitorDelegate() override; + + PresenceMonitorDelegate(const PresenceMonitorDelegate&) = delete; + PresenceMonitorDelegate& operator=(const PresenceMonitorDelegate&) = delete; + + void StartMonitoring(const multidevice::RemoteDevice& remote_device, + const multidevice::RemoteDevice& local_device); + void StopMonitoring(); + + private: + // BleScanner::Observer: + void OnReceivedAdvertisement(multidevice::RemoteDeviceRef remote_device, + device::BluetoothDevice* bluetooth_device, + ConnectionMedium connection_medium, + ConnectionRole connection_role, + const std::vector<uint8_t>& eid) override; + + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_; + PresenceMonitor::DeviceSeenCallback device_seen_callback_; + std::unique_ptr<multidevice::RemoteDeviceCache> remote_device_cache_; + std::unique_ptr<BluetoothHelper> bluetooth_helper_; + std::unique_ptr<BleSynchronizerBase> ble_synchronizer_; + std::unique_ptr<BleScanner> ble_scanner_; + + std::string remote_device_id_; + std::string local_device_id_; +}; + +} // namespace secure_channel + +} // namespace chromeos +#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_PRESENCE_MONITOR_DELEGATE_H_
diff --git a/chromeos/services/secure_channel/presence_monitor_impl.cc b/chromeos/services/secure_channel/presence_monitor_impl.cc new file mode 100644 index 0000000..c61d9fe --- /dev/null +++ b/chromeos/services/secure_channel/presence_monitor_impl.cc
@@ -0,0 +1,52 @@ +// Copyright 2021 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 "chromeos/services/secure_channel/presence_monitor_impl.h" + +#include "chromeos/components/multidevice/logging/logging.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" + +namespace chromeos { +namespace secure_channel { + +PresenceMonitorImpl::PresenceMonitorImpl() = default; + +PresenceMonitorImpl::~PresenceMonitorImpl() = default; + +void PresenceMonitorImpl::SetPresenceMonitorCallbacks( + ReadyCallback ready_callback, + DeviceSeenCallback device_seen_callback) { + if (!presence_monitor_delegate_) { + device::BluetoothAdapterFactory::Get()->GetAdapter(base::BindOnce( + &PresenceMonitorImpl::OnAdapterReceived, weak_ptr_factory_.GetWeakPtr(), + std::move(ready_callback), std::move(device_seen_callback))); + } +} + +void PresenceMonitorImpl::StartMonitoring( + const multidevice::RemoteDevice& remote_device, + const multidevice::RemoteDevice& local_device) { + if (presence_monitor_delegate_) { + presence_monitor_delegate_->StartMonitoring(remote_device, local_device); + } +} + +void PresenceMonitorImpl::StopMonitoring() { + if (presence_monitor_delegate_) { + presence_monitor_delegate_->StopMonitoring(); + } +} + +void PresenceMonitorImpl::OnAdapterReceived( + PresenceMonitor::ReadyCallback ready_callback, + PresenceMonitor::DeviceSeenCallback device_seen_callback, + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) { + presence_monitor_delegate_ = std::make_unique<PresenceMonitorDelegate>( + std::move(bluetooth_adapter), std::move(device_seen_callback)); + ready_callback.Run(); +} + +} // namespace secure_channel +} // namespace chromeos
diff --git a/chromeos/services/secure_channel/presence_monitor_impl.h b/chromeos/services/secure_channel/presence_monitor_impl.h new file mode 100644 index 0000000..ee64db2 --- /dev/null +++ b/chromeos/services/secure_channel/presence_monitor_impl.h
@@ -0,0 +1,57 @@ +// Copyright 2021 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 CHROMEOS_SERVICES_SECURE_CHANNEL_PRESENCE_MONITOR_IMPL_H_ +#define CHROMEOS_SERVICES_SECURE_CHANNEL_PRESENCE_MONITOR_IMPL_H_ + +#include "chromeos/services/secure_channel/presence_monitor_delegate.h" +#include "chromeos/services/secure_channel/public/cpp/shared/presence_monitor.h" + +namespace device { + +class BluetoothAdapter; + +} // namespace device + +namespace chromeos { + +namespace multidevice { + +struct RemoteDevice; + +} // namespace multidevice + +namespace secure_channel { + +// Monitors device proximity while a secure channel is active. +class PresenceMonitorImpl : public PresenceMonitor { + public: + PresenceMonitorImpl(); + ~PresenceMonitorImpl() override; + + PresenceMonitorImpl(const PresenceMonitorImpl&) = delete; + PresenceMonitorImpl& operator=(const PresenceMonitorImpl&) = delete; + + // PresenceMonitor: + void SetPresenceMonitorCallbacks( + PresenceMonitor::ReadyCallback ready_callback, + PresenceMonitor::DeviceSeenCallback device_seen_callback) override; + void StartMonitoring(const multidevice::RemoteDevice& remote_device, + const multidevice::RemoteDevice& local_device) override; + void StopMonitoring() override; + + private: + void OnAdapterReceived( + PresenceMonitor::ReadyCallback ready_callback, + PresenceMonitor::DeviceSeenCallback device_seen_callback, + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter); + + std::unique_ptr<PresenceMonitorDelegate> presence_monitor_delegate_; + + base::WeakPtrFactory<PresenceMonitorImpl> weak_ptr_factory_{this}; +}; + +} // namespace secure_channel +} // namespace chromeos +#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_PRESENCE_MONITOR_IMPL_H_
diff --git a/chromeos/services/secure_channel/public/cpp/client/BUILD.gn b/chromeos/services/secure_channel/public/cpp/client/BUILD.gn index ecd31c9b..ec1c7c8 100644 --- a/chromeos/services/secure_channel/public/cpp/client/BUILD.gn +++ b/chromeos/services/secure_channel/public/cpp/client/BUILD.gn
@@ -18,6 +18,9 @@ "connection_manager_impl.h", "nearby_connector.cc", "nearby_connector.h", + "presence_monitor_client.h", + "presence_monitor_client_impl.cc", + "presence_monitor_client_impl.h", "secure_channel_client.h", "secure_channel_client_impl.cc", "secure_channel_client_impl.h",
diff --git a/chromeos/services/secure_channel/public/cpp/client/presence_monitor_client.h b/chromeos/services/secure_channel/public/cpp/client/presence_monitor_client.h new file mode 100644 index 0000000..85af752 --- /dev/null +++ b/chromeos/services/secure_channel/public/cpp/client/presence_monitor_client.h
@@ -0,0 +1,46 @@ +// Copyright 2021 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 CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_PRESENCE_MONITOR_CLIENT_H_ +#define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_PRESENCE_MONITOR_CLIENT_H_ + +#include "chromeos/components/multidevice/remote_device_ref.h" +#include "chromeos/services/secure_channel/public/cpp/shared/presence_monitor.h" + +namespace chromeos { +namespace secure_channel { + +// Provides clients access to the PresenceMonitor API. +class PresenceMonitorClient { + public: + virtual ~PresenceMonitorClient() = default; + + virtual void SetPresenceMonitorCallbacks( + PresenceMonitor::ReadyCallback ready_callback, + PresenceMonitor::DeviceSeenCallback device_seen_callback) = 0; + virtual void StartMonitoring( + const multidevice::RemoteDeviceRef& remote_device_ref, + const multidevice::RemoteDeviceRef& local_device_ref) = 0; + virtual void StopMonitoring() = 0; + + protected: + PresenceMonitorClient() = default; + + private: + PresenceMonitorClient(const PresenceMonitorClient&) = delete; + PresenceMonitorClient& operator=(const PresenceMonitorClient&) = delete; +}; + +} // namespace secure_channel +} // namespace chromeos + +// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos +// source migration is finished. +namespace ash { +namespace secure_channel { +using ::chromeos::secure_channel::PresenceMonitorClient; +} +} // namespace ash + +#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_PRESENCE_MONITOR_CLIENT_H_
diff --git a/chromeos/services/secure_channel/public/cpp/client/presence_monitor_client_impl.cc b/chromeos/services/secure_channel/public/cpp/client/presence_monitor_client_impl.cc new file mode 100644 index 0000000..2751a558 --- /dev/null +++ b/chromeos/services/secure_channel/public/cpp/client/presence_monitor_client_impl.cc
@@ -0,0 +1,62 @@ +// Copyright 2021 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 "chromeos/services/secure_channel/public/cpp/client/presence_monitor_client_impl.h" + +#include "base/bind.h" +#include "base/memory/ptr_util.h" + +namespace chromeos { +namespace secure_channel { + +// static +PresenceMonitorClientImpl::Factory* + PresenceMonitorClientImpl::Factory::test_factory_ = nullptr; + +// static +std::unique_ptr<PresenceMonitorClient> +PresenceMonitorClientImpl::Factory::Create( + std::unique_ptr<PresenceMonitor> presence_monitor) { + if (test_factory_) { + return test_factory_->CreateInstance(std::move(presence_monitor)); + } + + return base::WrapUnique( + new PresenceMonitorClientImpl(std::move(presence_monitor))); +} + +// static +void PresenceMonitorClientImpl::Factory::SetFactoryForTesting( + Factory* test_factory) { + test_factory_ = test_factory; +} + +PresenceMonitorClientImpl::Factory::~Factory() = default; + +PresenceMonitorClientImpl::PresenceMonitorClientImpl( + std::unique_ptr<PresenceMonitor> presence_monitor) + : presence_monitor_(std::move(presence_monitor)) {} + +PresenceMonitorClientImpl::~PresenceMonitorClientImpl() = default; + +void PresenceMonitorClientImpl::SetPresenceMonitorCallbacks( + PresenceMonitor::ReadyCallback ready_callback, + PresenceMonitor::DeviceSeenCallback device_seen_callback) { + presence_monitor_->SetPresenceMonitorCallbacks( + std::move(ready_callback), std::move(device_seen_callback)); +} + +void PresenceMonitorClientImpl::StartMonitoring( + const multidevice::RemoteDeviceRef& remote_device, + const multidevice::RemoteDeviceRef& local_device) { + presence_monitor_->StartMonitoring(remote_device.GetRemoteDevice(), + local_device.GetRemoteDevice()); +} + +void PresenceMonitorClientImpl::StopMonitoring() { + presence_monitor_->StopMonitoring(); +} + +} // namespace secure_channel +} // namespace chromeos
diff --git a/chromeos/services/secure_channel/public/cpp/client/presence_monitor_client_impl.h b/chromeos/services/secure_channel/public/cpp/client/presence_monitor_client_impl.h new file mode 100644 index 0000000..ecb0deec --- /dev/null +++ b/chromeos/services/secure_channel/public/cpp/client/presence_monitor_client_impl.h
@@ -0,0 +1,62 @@ +// Copyright 2021 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 CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_PRESENCE_MONITOR_CLIENT_IMPL_H_ +#define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_PRESENCE_MONITOR_CLIENT_IMPL_H_ + +#include <memory> + +#include "chromeos/services/secure_channel/public/cpp/client/presence_monitor_client.h" +#include "chromeos/services/secure_channel/public/cpp/shared/presence_monitor.h" + +namespace chromeos { + +namespace multidevice { + +class RemoteDeviceRef; + +} // namespace multidevice + +namespace secure_channel { + +// Provides clients access to the PresenceMonitor API. +class PresenceMonitorClientImpl : public PresenceMonitorClient { + public: + class Factory { + public: + static std::unique_ptr<PresenceMonitorClient> Create( + std::unique_ptr<PresenceMonitor> presence_monitor); + static void SetFactoryForTesting(Factory* test_factory); + + protected: + virtual ~Factory(); + virtual std::unique_ptr<PresenceMonitorClient> CreateInstance( + std::unique_ptr<PresenceMonitor> presence_monitor) = 0; + + private: + static Factory* test_factory_; + }; + + ~PresenceMonitorClientImpl() override; + + private: + explicit PresenceMonitorClientImpl( + std::unique_ptr<PresenceMonitor> presence_monitor); + + // PresenceMonitorClient: + void SetPresenceMonitorCallbacks( + PresenceMonitor::ReadyCallback ready_callback, + PresenceMonitor::DeviceSeenCallback device_seen_callback) override; + void StartMonitoring( + const multidevice::RemoteDeviceRef& remote_device_ref, + const multidevice::RemoteDeviceRef& local_device_ref) override; + void StopMonitoring() override; + + std::unique_ptr<PresenceMonitor> presence_monitor_; +}; + +} // namespace secure_channel +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_PRESENCE_MONITOR_CLIENT_IMPL_H_
diff --git a/chromeos/services/secure_channel/public/cpp/shared/BUILD.gn b/chromeos/services/secure_channel/public/cpp/shared/BUILD.gn index 21aa4c4..d8b26ee 100644 --- a/chromeos/services/secure_channel/public/cpp/shared/BUILD.gn +++ b/chromeos/services/secure_channel/public/cpp/shared/BUILD.gn
@@ -8,6 +8,7 @@ "connection_medium.h", "connection_priority.cc", "connection_priority.h", + "presence_monitor.h", ] deps = [ "//base" ]
diff --git a/chromeos/services/secure_channel/public/cpp/shared/presence_monitor.h b/chromeos/services/secure_channel/public/cpp/shared/presence_monitor.h new file mode 100644 index 0000000..63c80ab25 --- /dev/null +++ b/chromeos/services/secure_channel/public/cpp/shared/presence_monitor.h
@@ -0,0 +1,43 @@ +// Copyright 2021 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 CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_SHARED_PRESENCE_MONITOR_H_ +#define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_SHARED_PRESENCE_MONITOR_H_ + +#include "base/callback.h" + +namespace chromeos { + +namespace multidevice { +struct RemoteDevice; +} // namespace multidevice + +namespace secure_channel { + +// Monitors device proximity while a secure channel is active. +class PresenceMonitor { + public: + using ReadyCallback = base::RepeatingCallback<void()>; + using DeviceSeenCallback = base::RepeatingCallback<void()>; + + virtual ~PresenceMonitor() = default; + + PresenceMonitor(const PresenceMonitor&) = delete; + PresenceMonitor& operator=(const PresenceMonitor&) = delete; + + virtual void SetPresenceMonitorCallbacks( + ReadyCallback ready_callback, + DeviceSeenCallback device_seen_callback) = 0; + virtual void StartMonitoring( + const multidevice::RemoteDevice& remote_device, + const multidevice::RemoteDevice& local_device) = 0; + virtual void StopMonitoring() = 0; + + protected: + PresenceMonitor() = default; +}; + +} // namespace secure_channel +} // namespace chromeos +#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_SHARED_PRESENCE_MONITOR_H_
diff --git a/chromeos/settings/cros_settings_names.cc b/chromeos/settings/cros_settings_names.cc index c8cebd7..cfc6d7ed 100644 --- a/chromeos/settings/cros_settings_names.cc +++ b/chromeos/settings/cros_settings_names.cc
@@ -254,6 +254,14 @@ const char kSystemLogUploadEnabled[] = "cros.device_status.system_log_upload_enabled"; +// How frequently the networks health telemetry are collected. +const char kReportDeviceNetworkTelemetryCollectionRateMs[] = + "cros.telemetry_reporting.report_network_telemetry_collection_rate_ms"; + +// How frequently the networks data are checked for events. +const char kReportDeviceNetworkTelemetryEventCheckingRateMs[] = + "cros.telemetry_reporting.report_network_telemetry_event_checking_rate_ms"; + // This policy should not appear in the protobuf ever but is used internally to // signal that we are running in a "safe-mode" for policy recovery. const char kPolicyMissingMitigationMode[] =
diff --git a/chromeos/settings/cros_settings_names.h b/chromeos/settings/cros_settings_names.h index 3f91560..64ebf3a 100644 --- a/chromeos/settings/cros_settings_names.h +++ b/chromeos/settings/cros_settings_names.h
@@ -132,6 +132,10 @@ COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kReportDevicePrintJobs[]; COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kReportDeviceLoginLogout[]; +COMPONENT_EXPORT(CHROMEOS_SETTINGS) +extern const char kReportDeviceNetworkTelemetryCollectionRateMs[]; +COMPONENT_EXPORT(CHROMEOS_SETTINGS) +extern const char kReportDeviceNetworkTelemetryEventCheckingRateMs[]; COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kHeartbeatEnabled[]; COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kHeartbeatFrequency[]; @@ -414,6 +418,8 @@ using ::chromeos::kReportDeviceNetworkConfiguration; using ::chromeos::kReportDeviceNetworkInterfaces; using ::chromeos::kReportDeviceNetworkStatus; +using ::chromeos::kReportDeviceNetworkTelemetryCollectionRateMs; +using ::chromeos::kReportDeviceNetworkTelemetryEventCheckingRateMs; using ::chromeos::kReportDevicePowerStatus; using ::chromeos::kReportDevicePrintJobs; using ::chromeos::kReportDeviceSecurityStatus;
diff --git a/components/autofill/core/browser/autofill_client.cc b/components/autofill/core/browser/autofill_client.cc index 8126fe6..2747e5f 100644 --- a/components/autofill/core/browser/autofill_client.cc +++ b/components/autofill/core/browser/autofill_client.cc
@@ -87,6 +87,18 @@ // ChromeAutofillClient (Chrome Desktop & Android) implements this. } +void AutofillClient::ShowAutofillProgressDialog( + base::OnceClosure cancel_callback) { + // This is overridden by platform subclasses. Currently only + // ChromeAutofillClient (Chrome Desktop & Android) implements this. +} + +void AutofillClient::CloseAutofillProgressDialog( + bool show_confirmation_before_closing) { + // This is overridden by platform subclasses. Currently only + // ChromeAutofillClient (Chrome Desktop & Android) implements this. +} + bool AutofillClient::IsAutofillAssistantShowing() { return false; }
diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h index dec2a6f..8fa66e20 100644 --- a/components/autofill/core/browser/autofill_client.h +++ b/components/autofill/core/browser/autofill_client.h
@@ -584,6 +584,12 @@ // error dialog with virtual card related messages. virtual void ShowVirtualCardErrorDialog(bool is_permanent_error); + // Show/dismiss the progress dialog which contains a throbber and a text + // message indicating that something is in progress. + virtual void ShowAutofillProgressDialog(base::OnceClosure cancel_callback); + virtual void CloseAutofillProgressDialog( + bool show_confirmation_before_closing); + // Returns true if the Autofill Assistant UI is currently being shown. virtual bool IsAutofillAssistantShowing();
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager.cc b/components/autofill/core/browser/payments/credit_card_access_manager.cc index ab01dfb..255960f 100644 --- a/components/autofill/core/browser/payments/credit_card_access_manager.cc +++ b/components/autofill/core/browser/payments/credit_card_access_manager.cc
@@ -914,7 +914,9 @@ void CreditCardAccessManager::FetchVirtualCard() { is_authentication_in_progress_ = true; - // TODO(crbug.com/1243475): Show pending dialog when the request is ongoing. + client_->ShowAutofillProgressDialog( + base::BindOnce(&CreditCardAccessManager::OnVirtualCardUnmaskCancelled, + weak_ptr_factory_.GetWeakPtr())); // Send a risk-based unmasking request to server to attempt to fetch the card. absl::optional<GURL> last_committed_url_origin = @@ -953,9 +955,12 @@ AutofillClient::PaymentsRpcResult result, payments::PaymentsClient::UnmaskResponseDetails& response_details) { virtual_card_unmask_response_details_ = response_details; - // TODO(crbug.com/1243475): Dismiss the pending dialog. if (result == AutofillClient::PaymentsRpcResult::kSuccess) { if (!response_details.real_pan.empty()) { + // Show confirmation on the progress dialog and then dismiss it. + client_->CloseAutofillProgressDialog( + /*show_confirmation_before_closing=*/true); + // If the real pan is not empty, then complete card information has been // fetched from the server (this is ensured in Payments Client). Pass the // unmasked card to |accessor_| and end the session. @@ -976,6 +981,9 @@ // Otherwise further authentication is required to unmask the card. DCHECK(!response_details.context_token.empty()); + // Close the progress dialog without showing the confirmation. + client_->CloseAutofillProgressDialog( + /*show_confirmation_before_closing=*/false); GetAuthenticationType( IsFidoAuthEnabled(response_details.fido_request_options.has_value())); return; @@ -985,6 +993,9 @@ // dialog. If RPC result is kVcnRetrievalPermanentFailure we show VCN // permanent error dialog, and for all other cases we show VCN temporary // error dialog. + // Close the progress dialog without showing the confirmation. + client_->CloseAutofillProgressDialog( + /*show_confirmation_before_closing=*/false); accessor_->OnCreditCardFetched(CreditCardFetchResult::kTransientError); client_->ShowVirtualCardErrorDialog( result == @@ -1024,7 +1035,13 @@ OnDidGetAuthenticationType(selected_authentication_type); } +void CreditCardAccessManager::OnVirtualCardUnmaskCancelled() { + // TODO(crbug.com/1243475): Add metrics for user cancellation. + Reset(); +} + void CreditCardAccessManager::Reset() { + weak_ptr_factory_.InvalidateWeakPtrs(); unmask_auth_flow_type_ = UnmaskAuthFlowType::kNone; is_authentication_in_progress_ = false; preflight_call_timestamp_ = absl::nullopt;
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager.h b/components/autofill/core/browser/payments/credit_card_access_manager.h index 3faeeac..179e0813 100644 --- a/components/autofill/core/browser/payments/credit_card_access_manager.h +++ b/components/autofill/core/browser/payments/credit_card_access_manager.h
@@ -352,6 +352,10 @@ void OnUserAcceptedAuthenticationSelectionDialog( const CardUnmaskChallengeOption& selected_challenge_option); + // Callback function invoked when the user has cancelled the virtual card + // unmasking. + void OnVirtualCardUnmaskCancelled(); + // Reset all the member variables of |this| and restore initial states. void Reset();
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc index 07f004d..7faaecf 100644 --- a/components/exo/shell_surface_base.cc +++ b/components/exo/shell_surface_base.cc
@@ -1396,7 +1396,7 @@ if (root_surface()) { size = root_surface()->content_size(); if (client_submits_surfaces_in_pixel_coordinates()) { - int dsf = std::ceil(host_window()->layer()->device_scale_factor()); + float dsf = host_window()->layer()->device_scale_factor(); size = gfx::ScaleToRoundedSize(size, 1.0f / dsf); } }
diff --git a/components/exo/surface_tree_host.cc b/components/exo/surface_tree_host.cc index 430b7d9..e1dba1b9 100644 --- a/components/exo/surface_tree_host.cc +++ b/components/exo/surface_tree_host.cc
@@ -328,8 +328,8 @@ // synchronization. if (client_submits_surfaces_in_pixel_coordinates_) { gfx::Transform tr; - float s = ceil(host_window_->layer()->device_scale_factor()); - tr.Scale(1.0f / s, 1.0f / s); + float scale = host_window_->layer()->device_scale_factor(); + tr.Scale(1.0f / scale, 1.0f / scale); host_window_->SetTransform(tr); } const bool fills_bounds_opaquely =
diff --git a/components/leveldb_proto/internal/proto_leveldb_wrapper_metrics.h b/components/leveldb_proto/internal/proto_leveldb_wrapper_metrics.h index 2f8ae4f..1b55906b 100644 --- a/components/leveldb_proto/internal/proto_leveldb_wrapper_metrics.h +++ b/components/leveldb_proto/internal/proto_leveldb_wrapper_metrics.h
@@ -16,8 +16,9 @@ // Static metrics recording helper functions for ProtoLevelDBWrapper. // // When adding database clients that require UMA metrics recording, ensure that -// the client name is added as a suffix in histograms.xml for the appropriate -// ProtoDB.* metrics. +// the client name is added as a LevelDBClient variant in +// //tools/metrics/histograms/metadata/leveldb_proto/histograms.xml for the +// appropriate ProtoDB.* metrics. class ProtoLevelDBWrapperMetrics { public: static void RecordInit(const std::string& client, @@ -37,4 +38,4 @@ } // namespace leveldb_proto -#endif // COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_LEVELDB_WRAPPER_METRICS_H_ \ No newline at end of file +#endif // COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_LEVELDB_WRAPPER_METRICS_H_
diff --git a/components/leveldb_proto/public/shared_proto_database_client_list.cc b/components/leveldb_proto/public/shared_proto_database_client_list.cc index a125045..2dd09cd 100644 --- a/components/leveldb_proto/public/shared_proto_database_client_list.cc +++ b/components/leveldb_proto/public/shared_proto_database_client_list.cc
@@ -19,8 +19,9 @@ // static std::string SharedProtoDatabaseClientList::ProtoDbTypeToString( ProtoDbType db_type) { - // Please update the suffix LevelDBClients in histograms.xml to match the - // strings returned here. + // Please update the variant LevelDBClient in + // //tools/metrics/histograms/metadata/leveldb_proto/histograms.xml + // to match the strings returned here. switch (db_type) { case ProtoDbType::TEST_DATABASE0: return "TestDatabase0";
diff --git a/components/leveldb_proto/public/shared_proto_database_client_list.h b/components/leveldb_proto/public/shared_proto_database_client_list.h index 0e3a88f..dc7f30a 100644 --- a/components/leveldb_proto/public/shared_proto_database_client_list.h +++ b/components/leveldb_proto/public/shared_proto_database_client_list.h
@@ -18,8 +18,9 @@ // The enum values are used to index into the shared database. Do not rearrange // or reuse the integer values. Add new database types at the end of the enum, // and update the string mapping in ProtoDbTypeToString(). Also update the -// suffix LevelDBClients in histogram_suffixes_list.xml to match the strings for -// the types. +// variant LevelDBClient in +// //tools/metrics/histograms/metadata/leveldb_proto/histograms.xml to match the +// strings for the types. enum class ProtoDbType { TEST_DATABASE0 = 0, TEST_DATABASE1 = 1,
diff --git a/components/metrics/generate_expired_histograms_array.gni b/components/metrics/generate_expired_histograms_array.gni index 39b384af..deb6e74b 100644 --- a/components/metrics/generate_expired_histograms_array.gni +++ b/components/metrics/generate_expired_histograms_array.gni
@@ -89,6 +89,7 @@ "//tools/metrics/histograms/metadata/installer/histograms.xml", "//tools/metrics/histograms/metadata/interstitial/histograms.xml", "//tools/metrics/histograms/metadata/ios/histograms.xml", + "//tools/metrics/histograms/metadata/leveldb_proto/histograms.xml", "//tools/metrics/histograms/metadata/local/histograms.xml", "//tools/metrics/histograms/metadata/login/histograms.xml", "//tools/metrics/histograms/metadata/media/histograms.xml",
diff --git a/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc b/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc index 55241d4..e7aaa4e0 100644 --- a/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc +++ b/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc
@@ -35,6 +35,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/posix/eintr_wrapper.h" +#include "base/rand_util.h" #include "base/system/sys_info.h" #include "base/threading/thread.h" #include "base/time/time.h" @@ -598,6 +599,17 @@ sandbox::Syscall::InvalidCall(); } +BPF_TEST_C(NaClNonSfiSandboxTest, + random, + nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { + // Ensure that UrandomFD is valid. + int urandom_fd = base::GetUrandomFD(); + BPF_ASSERT_NE(-1, urandom_fd); + + // The test should pass if the base::Rand*() don't crash. + base::RandDouble(); +} + // The following tests check for several restrictions in tgkill(). A delegate is // needed to be able to call getpid() from inside the process that will be // sandboxed, but before the sandbox is installed.
diff --git a/components/nacl/loader/nonsfi/run_all_unittests.cc b/components/nacl/loader/nonsfi/run_all_unittests.cc index 09ea459..7da3e83 100644 --- a/components/nacl/loader/nonsfi/run_all_unittests.cc +++ b/components/nacl/loader/nonsfi/run_all_unittests.cc
@@ -4,6 +4,7 @@ #include "base/at_exit.h" #include "base/bind.h" +#include "base/rand_util.h" #include "base/test/launcher/unit_test_launcher.h" #include "testing/gtest/include/gtest/gtest.h" @@ -18,5 +19,10 @@ int main(int argc, char** argv) { base::AtExitManager at_exit; testing::InitGoogleTest(&argc, argv); + + // Force early initialisation of /dev/urandom FD as it can't be initialised + // from a sandbox. + base::GetUrandomFD(); + return base::LaunchUnitTests(argc, argv, base::BindOnce(&RunAllTestsImpl)); }
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto index 39f19b11..0607f58 100644 --- a/components/policy/proto/chrome_device_policy.proto +++ b/components/policy/proto/chrome_device_policy.proto
@@ -161,6 +161,12 @@ // This is a internal flag that will be used to control whether enable // granular device reporting is enabled optional bool enable_granular_reporting = 32 [default = true]; + + // Network telemetry policies. + optional int64 report_network_telemetry_collection_rate_ms = 33 + [default = 600000]; + optional int64 report_network_telemetry_event_checking_rate_ms = 34 + [default = 60000]; } message EphemeralUsersEnabledProto {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 03d4e3a..99b8b0aa 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -976,6 +976,8 @@ 'HeartbeatFrequency', 'LogUploadEnabled', 'DeviceMetricsReportingEnabled', + 'ReportDeviceNetworkTelemetryCollectionRateMs', + 'ReportDeviceNetworkTelemetryEventCheckingRateMs', ], }, { @@ -10439,6 +10441,48 @@ 'arc_support': 'This policy has no effect on the logging done by Android.', }, { + 'name': 'ReportDeviceNetworkTelemetryCollectionRateMs', + 'owners': ['anasr@google.com', 'cros-reporting-team@google.com'], + 'type': 'int', + 'schema': { 'type': 'integer', 'minimum': 60000 }, + 'future_on': ['chrome_os'], + 'supported_chrome_os_management': ['google_cloud'], + 'device_only': True, + 'features': { + 'dynamic_refresh': True, + }, + 'example_value': 600000, + 'default': 600000, + 'id': 914, + 'caption': '''Network telemetry collection rate in milliseconds.''', + 'tags': ['admin-sharing'], + 'desc': '''Rate at which network data is sampled and collected. The minimum allowed is 1 minute. + + If not set, the default rate of 10 minutes applies.''', + 'arc_support': 'This policy has no effect on the logging done by Android.', + }, + { + 'name': 'ReportDeviceNetworkTelemetryEventCheckingRateMs', + 'owners': ['anasr@google.com', 'cros-reporting-team@google.com'], + 'type': 'int', + 'schema': { 'type': 'integer', 'minimum': 60000 }, + 'future_on': ['chrome_os'], + 'supported_chrome_os_management': ['google_cloud'], + 'device_only': True, + 'features': { + 'dynamic_refresh': True, + }, + 'example_value': 60000, + 'default': 60000, + 'id': 915, + 'caption': '''Network events checking rate in milliseconds.''', + 'tags': ['admin-sharing'], + 'desc': '''Rate at which network data is polled and checked for events. The minimum allowed is 1 minute. + + If not set, the default rate of 1 minute applies.''', + 'arc_support': 'This policy has no effect on the logging done by Android.', + }, + { 'name': 'ReportDeviceUsers', 'owners': ['stepco@chromium.org', 'cros-reporting-team@google.com', 'lbaraz@chromium.org'], 'type': 'main', @@ -28759,6 +28803,8 @@ 'ReportDeviceSystemInfo': 'device_reporting.report_system_info', 'ReportDevicePrintJobs': 'device_reporting.report_print_jobs', 'ReportDeviceLoginLogout': 'device_reporting.report_login_logout', + 'ReportDeviceNetworkTelemetryCollectionRateMs': 'device_reporting.report_network_telemetry_collection_rate_ms', + 'ReportDeviceNetworkTelemetryEventCheckingRateMs': 'device_reporting.report_network_telemetry_event_checking_rate_ms', 'ReportUploadFrequency': 'device_reporting.device_status_frequency', 'DeviceLoginScreenPowerManagement': 'login_screen_power_management.login_screen_power_management', 'DeviceChromeVariations': 'device_chrome_variations_type.value', @@ -29332,6 +29378,6 @@ 'placeholders': [], 'deleted_policy_ids': [114, 115, 204, 205, 206, 412, 476, 544, 546, 562, 569, 578, 583, 585, 586, 587, 588, 589, 590, 591, 600, 668, 669, 872], 'deleted_atomic_policy_group_ids': [19], - 'highest_id_currently_used': 913, + 'highest_id_currently_used': 915, 'highest_atomic_group_id_currently_used': 41 }
diff --git a/components/reporting/storage/storage.cc b/components/reporting/storage/storage.cc index af3db57..edbbf00 100644 --- a/components/reporting/storage/storage.cc +++ b/components/reporting/storage/storage.cc
@@ -82,6 +82,7 @@ constexpr base::FilePath::CharType kEncryptionKeyFilePrefix[] = FILE_PATH_LITERAL("EncryptionKey."); const int32_t kEncryptionKeyMaxFileSize = 256; +const uint64_t kQueueSize = 2 * 1024LL * 1024LL; // Failed upload retry delay: if an upload fails and there are no more incoming // events, collected events will not get uploaded for an indefinite time (see @@ -97,33 +98,39 @@ QueueOptions(options) .set_subdirectory(kSecurityQueueSubdir) .set_file_prefix(kSecurityQueuePrefix) - .set_upload_retry_delay(kFailedUploadRetryDelay)), + .set_upload_retry_delay(kFailedUploadRetryDelay) + .set_max_single_file_size(kQueueSize)), std::make_pair(IMMEDIATE, QueueOptions(options) .set_subdirectory(kImmediateQueueSubdir) .set_file_prefix(kImmediateQueuePrefix) - .set_upload_retry_delay(kFailedUploadRetryDelay)), + .set_upload_retry_delay(kFailedUploadRetryDelay) + .set_max_single_file_size(kQueueSize)), std::make_pair(FAST_BATCH, QueueOptions(options) .set_subdirectory(kFastBatchQueueSubdir) .set_file_prefix(kFastBatchQueuePrefix) - .set_upload_period(kFastBatchUploadPeriod)), + .set_upload_period(kFastBatchUploadPeriod) + .set_max_single_file_size(kQueueSize)), std::make_pair(SLOW_BATCH, QueueOptions(options) .set_subdirectory(kSlowBatchQueueSubdir) .set_file_prefix(kSlowBatchQueuePrefix) - .set_upload_period(kSlowBatchUploadPeriod)), + .set_upload_period(kSlowBatchUploadPeriod) + .set_max_single_file_size(kQueueSize)), std::make_pair(BACKGROUND_BATCH, QueueOptions(options) .set_subdirectory(kBackgroundQueueSubdir) .set_file_prefix(kBackgroundQueuePrefix) - .set_upload_period(kBackgroundQueueUploadPeriod)), + .set_upload_period(kBackgroundQueueUploadPeriod) + .set_max_single_file_size(kQueueSize)), std::make_pair(MANUAL_BATCH, QueueOptions(options) .set_subdirectory(kManualQueueSubdir) .set_file_prefix(kManualQueuePrefix) .set_upload_period(kManualUploadPeriod) - .set_upload_retry_delay(kFailedUploadRetryDelay)), + .set_upload_retry_delay(kFailedUploadRetryDelay) + .set_max_single_file_size(kQueueSize)), }; }
diff --git a/components/reporting/storage/storage_configuration.cc b/components/reporting/storage/storage_configuration.cc index df4fc36b..8167ba4e 100644 --- a/components/reporting/storage/storage_configuration.cc +++ b/components/reporting/storage/storage_configuration.cc
@@ -12,4 +12,7 @@ default; StorageOptions::~StorageOptions() = default; +QueueOptions::QueueOptions(const StorageOptions& storage_options) + : storage_options_(storage_options) {} +QueueOptions::QueueOptions(const QueueOptions& options) = default; } // namespace reporting
diff --git a/components/reporting/storage/storage_configuration.h b/components/reporting/storage/storage_configuration.h index 2327b91..183598d0 100644 --- a/components/reporting/storage/storage_configuration.h +++ b/components/reporting/storage/storage_configuration.h
@@ -48,10 +48,6 @@ max_total_memory_size_ = max_total_memory_size; return *this; } - StorageOptions& set_single_file_size(uint64_t single_file_size) { - single_file_size_ = single_file_size; - return *this; - } const base::FilePath& directory() const { return directory_; } base::StringPiece signature_verification_public_key() const { return signature_verification_public_key_; @@ -59,7 +55,6 @@ size_t max_record_size() const { return max_record_size_; } uint64_t max_total_files_size() const { return max_total_files_size_; } uint64_t max_total_memory_size() const { return max_total_memory_size_; } - uint64_t single_file_size() const { return single_file_size_; } private: // Subdirectory of the location assigned for this Storage. @@ -77,12 +72,6 @@ // Maximum memory usage (reading buffers). uint64_t max_total_memory_size_ = 4 * 1024LL * 1024LL; // 4 MiB - - // Cut-off size of an individual file in all queues. - // When file exceeds this size, the new file is created - // for further records. Note that each file must have at least - // one record before it is closed, regardless of that record size. - uint64_t single_file_size_ = 1 * 1024LL * 1024LL; // 1 MiB }; // Single queue options class allowing to set parameters individually, e.g.: @@ -93,9 +82,8 @@ // storage_options must outlive QueueOptions. class QueueOptions { public: - explicit QueueOptions(const StorageOptions& storage_options) - : storage_options_(storage_options) {} - QueueOptions(const QueueOptions& options) = default; + explicit QueueOptions(const StorageOptions& storage_options); + QueueOptions(const QueueOptions& options); // QueueOptions& operator=(const QueueOptions& options) = default; QueueOptions& set_subdirectory( const base::FilePath::StringType& subdirectory) { @@ -114,6 +102,10 @@ upload_retry_delay_ = upload_retry_delay; return *this; } + QueueOptions& set_max_single_file_size(uint64_t max_single_file_size) { + max_single_file_size_ = max_single_file_size; + return *this; + } const base::FilePath& directory() const { return directory_; } const base::FilePath::StringType& file_prefix() const { return file_prefix_; } size_t max_record_size() const { return storage_options_.max_record_size(); } @@ -123,9 +115,7 @@ size_t max_total_memory_size() const { return storage_options_.max_total_memory_size(); } - uint64_t single_file_size() const { - return storage_options_.single_file_size(); - } + uint64_t max_single_file_size() const { return max_single_file_size_; } base::TimeDelta upload_period() const { return upload_period_; } base::TimeDelta upload_retry_delay() const { return upload_retry_delay_; } @@ -146,6 +136,11 @@ // Retry delay for a failed upload. If 0, not retried at all // (should only be set to 0 in periodic queues). base::TimeDelta upload_retry_delay_; + // Cut-off file size of an individual queue + // When file exceeds this size, the new file is created + // for further records. Note that each file must have at least + // one record before it is closed, regardless of that record size. + uint64_t max_single_file_size_ = 1 * 1024LL * 1024LL; // 1 MiB }; } // namespace reporting
diff --git a/components/reporting/storage/storage_queue.cc b/components/reporting/storage/storage_queue.cc index ad63bdb9..7b54c5b 100644 --- a/components/reporting/storage/storage_queue.cc +++ b/components/reporting/storage/storage_queue.cc
@@ -452,7 +452,7 @@ scoped_refptr<SingleFile> last_file = files_.rbegin()->second; if (last_file->size() > 0 && // Cannot have a file with no records. last_file->size() + size + sizeof(RecordHeader) + FRAME_SIZE > - options_.single_file_size()) { + options_.max_single_file_size()) { // The last file will become too large, asynchronously close it and add // new. last_file->Close();
diff --git a/components/reporting/storage/storage_queue_stress_test.cc b/components/reporting/storage/storage_queue_stress_test.cc index f9115022..822b6709 100644 --- a/components/reporting/storage/storage_queue_stress_test.cc +++ b/components/reporting/storage/storage_queue_stress_test.cc
@@ -130,8 +130,7 @@ {CompressionModule::kCompressReportingFeature}, {}); ASSERT_TRUE(location_.CreateUniqueTempDir()); - options_.set_directory(base::FilePath(location_.GetPath())) - .set_single_file_size(GetParam()); + options_.set_directory(base::FilePath(location_.GetPath())); } void TearDown() override { @@ -180,7 +179,8 @@ QueueOptions BuildStorageQueueOptionsImmediate() const { return QueueOptions(options_) .set_subdirectory(FILE_PATH_LITERAL("D1")) - .set_file_prefix(FILE_PATH_LITERAL("F0001")); + .set_file_prefix(FILE_PATH_LITERAL("F0001")) + .set_max_single_file_size(GetParam()); } QueueOptions BuildStorageQueueOptionsPeriodic(
diff --git a/components/reporting/storage/storage_queue_unittest.cc b/components/reporting/storage/storage_queue_unittest.cc index cfd1505..64f872ce 100644 --- a/components/reporting/storage/storage_queue_unittest.cc +++ b/components/reporting/storage/storage_queue_unittest.cc
@@ -462,8 +462,7 @@ protected: void SetUp() override { ASSERT_TRUE(location_.CreateUniqueTempDir()); - options_.set_directory(base::FilePath(location_.GetPath())) - .set_single_file_size(GetParam()); + options_.set_directory(base::FilePath(location_.GetPath())); EXPECT_CALL(set_mock_uploader_expectations_, Call(_, NotNull())) .WillRepeatedly(Invoke([](UploaderInterface::UploadReason reason, TestUploader* test_uploader) { @@ -528,7 +527,8 @@ return QueueOptions(options_) .set_subdirectory(FILE_PATH_LITERAL("D1")) .set_file_prefix(FILE_PATH_LITERAL("F0001")) - .set_upload_retry_delay(upload_retry_delay); + .set_upload_retry_delay(upload_retry_delay) + .set_max_single_file_size(GetParam()); } QueueOptions BuildStorageQueueOptionsPeriodic( @@ -860,7 +860,7 @@ // Set uploader expectations. Previous data is all lost. // The expected results depend on the test configuration. test::TestCallbackAutoWaiter waiter; - switch (options.single_file_size()) { + switch (options.max_single_file_size()) { case 1: // single record in file - deletion killed the first record EXPECT_CALL(set_mock_uploader_expectations_, Call(Eq(UploaderInterface::PERIODIC), NotNull()))
diff --git a/components/reporting/storage/storage_unittest.cc b/components/reporting/storage/storage_unittest.cc index b21f6d9..3c99bf9 100644 --- a/components/reporting/storage/storage_unittest.cc +++ b/components/reporting/storage/storage_unittest.cc
@@ -785,8 +785,7 @@ StorageOptions BuildTestStorageOptions() const { auto options = StorageOptions() - .set_directory(base::FilePath(location_.GetPath())) - .set_single_file_size(is_encryption_enabled()); + .set_directory(base::FilePath(location_.GetPath())); if (is_encryption_enabled()) { // Encryption enabled. options.set_signature_verification_public_key(std::string(
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc index 8071aab46..9a8b0d9 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc
@@ -532,6 +532,9 @@ // the current mainframe URL, because the mainframe URL has to be // committed before subframe navigation starts. token = cache_manager_->GetPageLoadToken(last_committed_url); + RecordBooleanWithAndWithoutSuffix( + "SafeBrowsing.PageLoadToken.RealTimeCheckHasToken", GetMetricSuffix(), + token.has_token_value()); // It's possible that the token is not found because the last committed // URL is not checked by real time URL check. Create a new page load token // in this case.
diff --git a/components/safe_browsing/core/browser/verdict_cache_manager.cc b/components/safe_browsing/core/browser/verdict_cache_manager.cc index 085864f..7a4bce6d 100644 --- a/components/safe_browsing/core/browser/verdict_cache_manager.cc +++ b/components/safe_browsing/core/browser/verdict_cache_manager.cc
@@ -605,7 +605,6 @@ ChromeUserPopulation::PageLoadToken VerdictCacheManager::GetPageLoadToken( const GURL& url) { std::string hostname = url.host(); - // TODO(crbug.com/1240403): Log the proportion of tokens that are not found. return base::Contains(page_load_token_map_, hostname) ? page_load_token_map_[hostname] : ChromeUserPopulation::PageLoadToken(); @@ -711,7 +710,8 @@ base::Time::FromJavaTime(token.token_time_msec()) > base::Minutes(kPageLoadTokenExpireMinute); }); - // TODO(crbug.com/1240403): Log the number of entries in page_load_token_map_; + base::UmaHistogramCounts10000("SafeBrowsing.PageLoadToken.TokenCount", + page_load_token_map_.size()); } // Overridden from history::HistoryServiceObserver.
diff --git a/components/services/app_service/BUILD.gn b/components/services/app_service/BUILD.gn index 651ebd1..c3c4428e 100644 --- a/components/services/app_service/BUILD.gn +++ b/components/services/app_service/BUILD.gn
@@ -4,8 +4,8 @@ source_set("lib") { sources = [ - "app_service_impl.cc", - "app_service_impl.h", + "app_service_mojom_impl.cc", + "app_service_mojom_impl.h", ] deps = [ @@ -24,7 +24,7 @@ source_set("unit_tests") { testonly = true - sources = [ "app_service_impl_unittest.cc" ] + sources = [ "app_service_mojom_impl_unittest.cc" ] deps = [ ":lib",
diff --git a/components/services/app_service/app_service_impl.cc b/components/services/app_service/app_service_mojom_impl.cc similarity index 80% rename from components/services/app_service/app_service_impl.cc rename to components/services/app_service/app_service_mojom_impl.cc index 023910b..1e36405 100644 --- a/components/services/app_service/app_service_impl.cc +++ b/components/services/app_service/app_service_mojom_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/services/app_service/app_service_impl.h" +#include "components/services/app_service/app_service_mojom_impl.h" #include <iterator> #include <utility> @@ -106,9 +106,10 @@ namespace apps { -AppServiceImpl::AppServiceImpl(const base::FilePath& profile_dir, - base::OnceClosure read_completed_for_testing, - base::OnceClosure write_completed_for_testing) +AppServiceMojomImpl::AppServiceMojomImpl( + const base::FilePath& profile_dir, + base::OnceClosure read_completed_for_testing, + base::OnceClosure write_completed_for_testing) : profile_dir_(profile_dir), should_write_preferred_apps_to_file_(false), writing_preferred_apps_(false), @@ -120,19 +121,19 @@ InitializePreferredApps(); } -AppServiceImpl::~AppServiceImpl() = default; +AppServiceMojomImpl::~AppServiceMojomImpl() = default; -void AppServiceImpl::BindReceiver( +void AppServiceMojomImpl::BindReceiver( mojo::PendingReceiver<apps::mojom::AppService> receiver) { receivers_.Add(this, std::move(receiver)); } -void AppServiceImpl::FlushMojoCallsForTesting() { +void AppServiceMojomImpl::FlushMojoCallsForTesting() { subscribers_.FlushForTesting(); receivers_.FlushForTesting(); } -void AppServiceImpl::RegisterPublisher( +void AppServiceMojomImpl::RegisterPublisher( mojo::PendingRemote<apps::mojom::Publisher> publisher_remote, apps::mojom::AppType app_type) { mojo::Remote<apps::mojom::Publisher> publisher(std::move(publisher_remote)); @@ -146,13 +147,13 @@ // Add the new publisher to the set. publisher.set_disconnect_handler( - base::BindOnce(&AppServiceImpl::OnPublisherDisconnected, + base::BindOnce(&AppServiceMojomImpl::OnPublisherDisconnected, base::Unretained(this), app_type)); auto result = publishers_.emplace(app_type, std::move(publisher)); CHECK(result.second); } -void AppServiceImpl::RegisterSubscriber( +void AppServiceMojomImpl::RegisterSubscriber( mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, apps::mojom::ConnectOptionsPtr opts) { // Connect the new subscriber with every registered publisher. @@ -173,13 +174,13 @@ subscribers_.Add(std::move(subscriber)); } -void AppServiceImpl::LoadIcon(apps::mojom::AppType app_type, - const std::string& app_id, - apps::mojom::IconKeyPtr icon_key, - apps::mojom::IconType icon_type, - int32_t size_hint_in_dip, - bool allow_placeholder_icon, - LoadIconCallback callback) { +void AppServiceMojomImpl::LoadIcon(apps::mojom::AppType app_type, + const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, + apps::mojom::IconType icon_type, + int32_t size_hint_in_dip, + bool allow_placeholder_icon, + LoadIconCallback callback) { auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { std::move(callback).Run(apps::mojom::IconValue::New()); @@ -190,11 +191,11 @@ std::move(callback)); } -void AppServiceImpl::Launch(apps::mojom::AppType app_type, - const std::string& app_id, - int32_t event_flags, - apps::mojom::LaunchSource launch_source, - apps::mojom::WindowInfoPtr window_info) { +void AppServiceMojomImpl::Launch(apps::mojom::AppType app_type, + const std::string& app_id, + int32_t event_flags, + apps::mojom::LaunchSource launch_source, + apps::mojom::WindowInfoPtr window_info) { auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { return; @@ -202,11 +203,12 @@ iter->second->Launch(app_id, event_flags, launch_source, std::move(window_info)); } -void AppServiceImpl::LaunchAppWithFiles(apps::mojom::AppType app_type, - const std::string& app_id, - int32_t event_flags, - apps::mojom::LaunchSource launch_source, - apps::mojom::FilePathsPtr file_paths) { +void AppServiceMojomImpl::LaunchAppWithFiles( + apps::mojom::AppType app_type, + const std::string& app_id, + int32_t event_flags, + apps::mojom::LaunchSource launch_source, + apps::mojom::FilePathsPtr file_paths) { CHECK(file_paths); auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { @@ -216,7 +218,7 @@ std::move(file_paths)); } -void AppServiceImpl::LaunchAppWithIntent( +void AppServiceMojomImpl::LaunchAppWithIntent( apps::mojom::AppType app_type, const std::string& app_id, int32_t event_flags, @@ -231,9 +233,9 @@ launch_source, std::move(window_info)); } -void AppServiceImpl::SetPermission(apps::mojom::AppType app_type, - const std::string& app_id, - apps::mojom::PermissionPtr permission) { +void AppServiceMojomImpl::SetPermission(apps::mojom::AppType app_type, + const std::string& app_id, + apps::mojom::PermissionPtr permission) { auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { return; @@ -241,11 +243,12 @@ iter->second->SetPermission(app_id, std::move(permission)); } -void AppServiceImpl::Uninstall(apps::mojom::AppType app_type, - const std::string& app_id, - apps::mojom::UninstallSource uninstall_source, - bool clear_site_data, - bool report_abuse) { +void AppServiceMojomImpl::Uninstall( + apps::mojom::AppType app_type, + const std::string& app_id, + apps::mojom::UninstallSource uninstall_source, + bool clear_site_data, + bool report_abuse) { auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { return; @@ -254,8 +257,8 @@ report_abuse); } -void AppServiceImpl::PauseApp(apps::mojom::AppType app_type, - const std::string& app_id) { +void AppServiceMojomImpl::PauseApp(apps::mojom::AppType app_type, + const std::string& app_id) { auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { return; @@ -263,8 +266,8 @@ iter->second->PauseApp(app_id); } -void AppServiceImpl::UnpauseApp(apps::mojom::AppType app_type, - const std::string& app_id) { +void AppServiceMojomImpl::UnpauseApp(apps::mojom::AppType app_type, + const std::string& app_id) { auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { return; @@ -272,8 +275,8 @@ iter->second->UnpauseApp(app_id); } -void AppServiceImpl::StopApp(apps::mojom::AppType app_type, - const std::string& app_id) { +void AppServiceMojomImpl::StopApp(apps::mojom::AppType app_type, + const std::string& app_id) { auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { return; @@ -281,11 +284,11 @@ iter->second->StopApp(app_id); } -void AppServiceImpl::GetMenuModel(apps::mojom::AppType app_type, - const std::string& app_id, - apps::mojom::MenuType menu_type, - int64_t display_id, - GetMenuModelCallback callback) { +void AppServiceMojomImpl::GetMenuModel(apps::mojom::AppType app_type, + const std::string& app_id, + apps::mojom::MenuType menu_type, + int64_t display_id, + GetMenuModelCallback callback) { auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { std::move(callback).Run(apps::mojom::MenuItems::New()); @@ -296,11 +299,12 @@ std::move(callback)); } -void AppServiceImpl::ExecuteContextMenuCommand(apps::mojom::AppType app_type, - const std::string& app_id, - int command_id, - const std::string& shortcut_id, - int64_t display_id) { +void AppServiceMojomImpl::ExecuteContextMenuCommand( + apps::mojom::AppType app_type, + const std::string& app_id, + int command_id, + const std::string& shortcut_id, + int64_t display_id) { auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { return; @@ -310,8 +314,8 @@ display_id); } -void AppServiceImpl::OpenNativeSettings(apps::mojom::AppType app_type, - const std::string& app_id) { +void AppServiceMojomImpl::OpenNativeSettings(apps::mojom::AppType app_type, + const std::string& app_id) { auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { return; @@ -319,11 +323,12 @@ iter->second->OpenNativeSettings(app_id); } -void AppServiceImpl::AddPreferredApp(apps::mojom::AppType app_type, - const std::string& app_id, - apps::mojom::IntentFilterPtr intent_filter, - apps::mojom::IntentPtr intent, - bool from_publisher) { +void AppServiceMojomImpl::AddPreferredApp( + apps::mojom::AppType app_type, + const std::string& app_id, + apps::mojom::IntentFilterPtr intent_filter, + apps::mojom::IntentPtr intent, + bool from_publisher) { // TODO(crbug.com/853604): Make sure the ARC preference init happens after // this. Might need to change the interface to call that after read completed. // Might also need to record the change before data read and make the update @@ -368,8 +373,8 @@ } } -void AppServiceImpl::RemovePreferredApp(apps::mojom::AppType app_type, - const std::string& app_id) { +void AppServiceMojomImpl::RemovePreferredApp(apps::mojom::AppType app_type, + const std::string& app_id) { // TODO(crbug.com/853604): Make sure the ARC preference init happens after // this. Might need to change the interface to call that after read completed. // Might also need to record the change before data read and make the update @@ -394,7 +399,7 @@ LogPreferredAppUpdateAction(PreferredAppsUpdateAction::kDeleteForAppId); } -void AppServiceImpl::RemovePreferredAppForFilter( +void AppServiceMojomImpl::RemovePreferredAppForFilter( apps::mojom::AppType app_type, const std::string& app_id, apps::mojom::IntentFilterPtr intent_filter) { @@ -418,7 +423,7 @@ LogPreferredAppUpdateAction(PreferredAppsUpdateAction::kDeleteForFilter); } -void AppServiceImpl::SetSupportedLinksPreference( +void AppServiceMojomImpl::SetSupportedLinksPreference( apps::mojom::AppType app_type, const std::string& app_id, std::vector<apps::mojom::IntentFilterPtr> all_link_filters) { @@ -493,7 +498,7 @@ } } -void AppServiceImpl::RemoveSupportedLinksPreference( +void AppServiceMojomImpl::RemoveSupportedLinksPreference( apps::mojom::AppType app_type, const std::string& app_id) { if (!preferred_apps_.IsInitialized()) { @@ -524,9 +529,9 @@ /*open_in_app=*/false); } -void AppServiceImpl::SetResizeLocked(apps::mojom::AppType app_type, - const std::string& app_id, - mojom::OptionalBool locked) { +void AppServiceMojomImpl::SetResizeLocked(apps::mojom::AppType app_type, + const std::string& app_id, + mojom::OptionalBool locked) { auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { return; @@ -534,9 +539,9 @@ iter->second->SetResizeLocked(app_id, locked); } -void AppServiceImpl::SetWindowMode(apps::mojom::AppType app_type, - const std::string& app_id, - apps::mojom::WindowMode window_mode) { +void AppServiceMojomImpl::SetWindowMode(apps::mojom::AppType app_type, + const std::string& app_id, + apps::mojom::WindowMode window_mode) { auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { return; @@ -544,19 +549,20 @@ iter->second->SetWindowMode(app_id, window_mode); } -PreferredAppsList& AppServiceImpl::GetPreferredAppsForTesting() { +PreferredAppsList& AppServiceMojomImpl::GetPreferredAppsForTesting() { return preferred_apps_; } -void AppServiceImpl::OnPublisherDisconnected(apps::mojom::AppType app_type) { +void AppServiceMojomImpl::OnPublisherDisconnected( + apps::mojom::AppType app_type) { publishers_.erase(app_type); } -void AppServiceImpl::InitializePreferredApps() { +void AppServiceMojomImpl::InitializePreferredApps() { ReadFromJSON(profile_dir_); } -void AppServiceImpl::WriteToJSON( +void AppServiceMojomImpl::WriteToJSON( const base::FilePath& profile_dir, const apps::PreferredAppsList& preferred_apps) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -580,11 +586,11 @@ FROM_HERE, base::BindOnce(&WriteDataBlocking, profile_dir.Append(kPreferredAppsDirname), json_string), - base::BindOnce(&AppServiceImpl::WriteCompleted, + base::BindOnce(&AppServiceMojomImpl::WriteCompleted, weak_ptr_factory_.GetWeakPtr())); } -void AppServiceImpl::WriteCompleted() { +void AppServiceMojomImpl::WriteCompleted() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); writing_preferred_apps_ = false; if (!should_write_preferred_apps_to_file_) { @@ -600,17 +606,17 @@ WriteToJSON(profile_dir_, preferred_apps_); } -void AppServiceImpl::ReadFromJSON(const base::FilePath& profile_dir) { +void AppServiceMojomImpl::ReadFromJSON(const base::FilePath& profile_dir) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); task_runner_->PostTaskAndReplyWithResult( FROM_HERE, base::BindOnce(&ReadDataBlocking, profile_dir.Append(kPreferredAppsDirname)), - base::BindOnce(&AppServiceImpl::ReadCompleted, + base::BindOnce(&AppServiceMojomImpl::ReadCompleted, weak_ptr_factory_.GetWeakPtr())); } -void AppServiceImpl::ReadCompleted(std::string preferred_apps_string) { +void AppServiceMojomImpl::ReadCompleted(std::string preferred_apps_string) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); bool preferred_apps_upgraded = false; if (preferred_apps_string.empty()) {
diff --git a/components/services/app_service/app_service_impl.h b/components/services/app_service/app_service_mojom_impl.h similarity index 92% rename from components/services/app_service/app_service_impl.h rename to components/services/app_service/app_service_mojom_impl.h index 336b135..e1e322ac 100644 --- a/components/services/app_service/app_service_impl.h +++ b/components/services/app_service/app_service_mojom_impl.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_SERVICES_APP_SERVICE_APP_SERVICE_IMPL_H_ -#define COMPONENTS_SERVICES_APP_SERVICE_APP_SERVICE_IMPL_H_ +#ifndef COMPONENTS_SERVICES_APP_SERVICE_APP_SERVICE_MOJOM_IMPL_H_ +#define COMPONENTS_SERVICES_APP_SERVICE_APP_SERVICE_MOJOM_IMPL_H_ #include <map> @@ -26,17 +26,17 @@ // The implementation of the apps::mojom::AppService Mojo interface. // // See components/services/app_service/README.md. -class AppServiceImpl : public apps::mojom::AppService { +class AppServiceMojomImpl : public apps::mojom::AppService { public: - AppServiceImpl( + AppServiceMojomImpl( const base::FilePath& profile_dir, base::OnceClosure read_completed_for_testing = base::OnceClosure(), base::OnceClosure write_completed_for_testing = base::OnceClosure()); - AppServiceImpl(const AppServiceImpl&) = delete; - AppServiceImpl& operator=(const AppServiceImpl&) = delete; + AppServiceMojomImpl(const AppServiceMojomImpl&) = delete; + AppServiceMojomImpl& operator=(const AppServiceMojomImpl&) = delete; - ~AppServiceImpl() override; + ~AppServiceMojomImpl() override; void BindReceiver(mojo::PendingReceiver<apps::mojom::AppService> receiver); @@ -172,9 +172,9 @@ base::OnceClosure write_completed_for_testing_; - base::WeakPtrFactory<AppServiceImpl> weak_ptr_factory_{this}; + base::WeakPtrFactory<AppServiceMojomImpl> weak_ptr_factory_{this}; }; } // namespace apps -#endif // COMPONENTS_SERVICES_APP_SERVICE_APP_SERVICE_IMPL_H_ +#endif // COMPONENTS_SERVICES_APP_SERVICE_APP_SERVICE_MOJOM_IMPL_H_
diff --git a/components/services/app_service/app_service_impl_unittest.cc b/components/services/app_service/app_service_mojom_impl_unittest.cc similarity index 96% rename from components/services/app_service/app_service_impl_unittest.cc rename to components/services/app_service/app_service_mojom_impl_unittest.cc index d0fd0eec..d5028586 100644 --- a/components/services/app_service/app_service_impl_unittest.cc +++ b/components/services/app_service/app_service_mojom_impl_unittest.cc
@@ -11,7 +11,7 @@ #include "base/callback.h" #include "base/files/scoped_temp_dir.h" #include "base/run_loop.h" -#include "components/services/app_service/app_service_impl.h" +#include "components/services/app_service/app_service_mojom_impl.h" #include "components/services/app_service/public/cpp/app_capability_access_cache.h" #include "components/services/app_service/public/cpp/intent_filter_util.h" #include "components/services/app_service/public/cpp/intent_test_util.h" @@ -33,7 +33,7 @@ class FakePublisher : public apps::PublisherBase { public: - FakePublisher(AppServiceImpl* impl, + FakePublisher(AppServiceMojomImpl* impl, apps::mojom::AppType app_type, std::vector<std::string> initial_app_ids) : app_type_(app_type), known_app_ids_(std::move(initial_app_ids)) { @@ -74,7 +74,8 @@ subscribers_, app_id, accessing_camera, accessing_microphone); } - void UninstallApps(std::vector<std::string> app_ids, AppServiceImpl* impl) { + void UninstallApps(std::vector<std::string> app_ids, + AppServiceMojomImpl* impl) { for (auto& subscriber : subscribers_) { CallOnApps(subscriber.get(), app_ids, /*uninstall=*/true); } @@ -170,7 +171,7 @@ class FakeSubscriber : public apps::mojom::Subscriber { public: - explicit FakeSubscriber(AppServiceImpl* impl) { + explicit FakeSubscriber(AppServiceMojomImpl* impl) { mojo::PendingRemote<apps::mojom::Subscriber> remote; receivers_.Add(this, remote.InitWithNewPipeAndPassReceiver()); impl->RegisterSubscriber(std::move(remote), nullptr); @@ -250,17 +251,17 @@ apps::PreferredAppsList preferred_apps_; }; -class AppServiceImplTest : public testing::Test { +class AppServiceMojomImplTest : public testing::Test { protected: content::BrowserTaskEnvironment task_environment_; base::ScopedTempDir temp_dir_; }; -TEST_F(AppServiceImplTest, PubSub) { +TEST_F(AppServiceMojomImplTest, PubSub) { const int size_hint_in_dip = 64; ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - AppServiceImpl impl(temp_dir_.GetPath()); + AppServiceMojomImpl impl(temp_dir_.GetPath()); // Start with one subscriber. FakeSubscriber sub0(&impl); @@ -388,10 +389,10 @@ } } -TEST_F(AppServiceImplTest, PreferredApps) { +TEST_F(AppServiceMojomImplTest, PreferredApps) { // Test Initialize. ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - AppServiceImpl impl(temp_dir_.GetPath()); + AppServiceMojomImpl impl(temp_dir_.GetPath()); impl.GetPreferredAppsForTesting().Init(); const char kAppId1[] = "abcdefg"; @@ -491,7 +492,7 @@ sub1.PreferredApps().FindPreferredAppForUrl(another_filter_url)); } -TEST_F(AppServiceImplTest, PreferredAppsPersistency) { +TEST_F(AppServiceMojomImplTest, PreferredAppsPersistency) { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); const char kAppId1[] = "abcdefg"; @@ -500,9 +501,8 @@ { base::RunLoop run_loop_read; base::RunLoop run_loop_write; - AppServiceImpl impl(temp_dir_.GetPath(), - run_loop_read.QuitClosure(), - run_loop_write.QuitClosure()); + AppServiceMojomImpl impl(temp_dir_.GetPath(), run_loop_read.QuitClosure(), + run_loop_write.QuitClosure()); impl.FlushMojoCallsForTesting(); run_loop_read.Run(); impl.AddPreferredApp(apps::mojom::AppType::kUnknown, kAppId1, @@ -515,8 +515,7 @@ // Create a new impl to initialize preferred apps from the disk. { base::RunLoop run_loop_read; - AppServiceImpl impl(temp_dir_.GetPath(), - run_loop_read.QuitClosure()); + AppServiceMojomImpl impl(temp_dir_.GetPath(), run_loop_read.QuitClosure()); impl.FlushMojoCallsForTesting(); run_loop_read.Run(); EXPECT_EQ(kAppId1, impl.GetPreferredAppsForTesting().FindPreferredAppForUrl( @@ -524,10 +523,10 @@ } } -TEST_F(AppServiceImplTest, PreferredAppsSetSupportedLinks) { +TEST_F(AppServiceMojomImplTest, PreferredAppsSetSupportedLinks) { // Test Initialize. ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - AppServiceImpl impl(temp_dir_.GetPath()); + AppServiceMojomImpl impl(temp_dir_.GetPath()); impl.GetPreferredAppsForTesting().Init(); const char kAppId1[] = "abcdefg"; @@ -613,10 +612,10 @@ } // Test that app with overlapped supported links works properly. -TEST_F(AppServiceImplTest, PreferredAppsOverlap) { +TEST_F(AppServiceMojomImplTest, PreferredAppsOverlap) { // Test Initialize. ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - AppServiceImpl impl(temp_dir_.GetPath()); + AppServiceMojomImpl impl(temp_dir_.GetPath()); impl.GetPreferredAppsForTesting().Init(); const char kAppId1[] = "abcdefg"; @@ -708,10 +707,10 @@ } // Test that duplicated entry will not be added. -TEST_F(AppServiceImplTest, PreferredAppsDuplicated) { +TEST_F(AppServiceMojomImplTest, PreferredAppsDuplicated) { // Test Initialize. ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - AppServiceImpl impl(temp_dir_.GetPath()); + AppServiceMojomImpl impl(temp_dir_.GetPath()); impl.GetPreferredAppsForTesting().Init(); const char kAppId1[] = "abcdefg"; @@ -746,10 +745,10 @@ } // Test that duplicated entry will not be added for supported links. -TEST_F(AppServiceImplTest, PreferredAppsDuplicatedSupportedLink) { +TEST_F(AppServiceMojomImplTest, PreferredAppsDuplicatedSupportedLink) { // Test Initialize. ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - AppServiceImpl impl(temp_dir_.GetPath()); + AppServiceMojomImpl impl(temp_dir_.GetPath()); impl.GetPreferredAppsForTesting().Init(); const char kAppId1[] = "abcdefg";
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc index 253f336..bfaa0c3 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
@@ -366,11 +366,12 @@ navigation_handle->HasCommitted()); blink::mojom::FilterListResult latest_filter_list_result = EnsureFrameAdEvidence(navigation_handle).latest_filter_list_result(); - // TODO(1061899): Calculate this without using the WebContents. bool is_same_domain_to_main_frame = net::registry_controlled_domains::SameDomainOrHost( navigation_handle->GetURL(), - navigation_handle->GetWebContents()->GetLastCommittedURL(), + navigation_handle->GetRenderFrameHost() + ->GetOutermostMainFrame() + ->GetLastCommittedURL(), net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); bool is_restricted_navigation = latest_filter_list_result ==
diff --git a/components/thin_webview/internal/compositor_view_impl.cc b/components/thin_webview/internal/compositor_view_impl.cc index 71b35de4..08ce986 100644 --- a/components/thin_webview/internal/compositor_view_impl.cc +++ b/components/thin_webview/internal/compositor_view_impl.cc
@@ -13,7 +13,7 @@ #include "components/thin_webview/internal/jni_headers/CompositorViewImpl_jni.h" #include "content/public/browser/android/compositor.h" #include "third_party/skia/include/core/SkColor.h" -#include "ui/android/color_helpers.h" +#include "ui/android/color_utils_android.h" #include "ui/android/window_android.h" using base::android::JavaParamRef;
diff --git a/components/update_client/update_client_errors.h b/components/update_client/update_client_errors.h index 61d70b2..58d6736f 100644 --- a/components/update_client/update_client_errors.h +++ b/components/update_client/update_client_errors.h
@@ -85,6 +85,8 @@ CLEAN_INSTALL_DIR_FAILED = 15, INSTALL_VERIFICATION_FAILED = 16, MISSING_INSTALL_PARAMS = 17, + // If LaunchProcess is attempted on unsupported non-desktop skus e.g. xbox + LAUNCH_PROCESS_FAILED = 18, CUSTOM_ERROR_BASE = 100, // Specific installer errors go above this value. };
diff --git a/components/webapps/browser/android/webapk/webapk_proto_builder.cc b/components/webapps/browser/android/webapk/webapk_proto_builder.cc index efaf223..269a6d1 100644 --- a/components/webapps/browser/android/webapk/webapk_proto_builder.cc +++ b/components/webapps/browser/android/webapk/webapk_proto_builder.cc
@@ -19,7 +19,7 @@ #include "third_party/blink/public/common/manifest/manifest_util.h" #include "third_party/blink/public/mojom/manifest/manifest.mojom.h" #include "third_party/skia/include/core/SkBitmap.h" -#include "ui/android/color_helpers.h" +#include "ui/android/color_utils_android.h" #include "ui/gfx/codec/png_codec.h" namespace webapps {
diff --git a/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/content/browser/accessibility/accessibility_tree_formatter_blink.cc index baf409b..2ec96e9 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_blink.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -721,11 +721,12 @@ attr_index <= static_cast<int32_t>(ax::mojom::FloatAttribute::kMaxValue); ++attr_index) { auto attr = static_cast<ax::mojom::FloatAttribute>(attr_index); - double float_value; - if (!dict.GetDouble(ui::ToString(attr), &float_value)) + absl::optional<double> float_value = + dict.FindDoublePath(ui::ToString(attr)); + if (!float_value) continue; WriteAttribute( - false, base::StringPrintf("%s=%.2f", ui::ToString(attr), float_value), + false, base::StringPrintf("%s=%.2f", ui::ToString(attr), *float_value), &line); }
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index 211baf25..86c272d8 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -1674,6 +1674,29 @@ return RenderFrameHost::FrameIterationAction::kStop; })); } + + EXPECT_EQ(nullptr, rfh_a->GetParentOrOuterDocument()); + EXPECT_EQ(rfh_a, rfh_b->GetParentOrOuterDocument()); + EXPECT_EQ(rfh_b, rfh_c->GetParentOrOuterDocument()); + EXPECT_EQ(rfh_a, rfh_d->GetParentOrOuterDocument()); + EXPECT_EQ(nullptr, rfh_e->GetParentOrOuterDocument()); + // The outermost document of a bfcached page is the bfcached main + // RenderFrameHost, not the primary main RenderFrameHost. + EXPECT_EQ(rfh_a, rfh_a->GetOutermostMainFrame()); + EXPECT_EQ(rfh_a, rfh_b->GetOutermostMainFrame()); + EXPECT_EQ(rfh_a, rfh_c->GetOutermostMainFrame()); + EXPECT_EQ(rfh_a, rfh_d->GetOutermostMainFrame()); + EXPECT_EQ(rfh_e, rfh_e->GetOutermostMainFrame()); + EXPECT_EQ(nullptr, rfh_a->GetParentOrOuterDocumentOrEmbedder()); + EXPECT_EQ(rfh_a, rfh_b->GetParentOrOuterDocumentOrEmbedder()); + EXPECT_EQ(rfh_b, rfh_c->GetParentOrOuterDocumentOrEmbedder()); + EXPECT_EQ(rfh_a, rfh_d->GetParentOrOuterDocumentOrEmbedder()); + EXPECT_EQ(nullptr, rfh_e->GetParentOrOuterDocumentOrEmbedder()); + EXPECT_EQ(rfh_a, rfh_a->GetOutermostMainFrameOrEmbedder()); + EXPECT_EQ(rfh_a, rfh_b->GetOutermostMainFrameOrEmbedder()); + EXPECT_EQ(rfh_a, rfh_c->GetOutermostMainFrameOrEmbedder()); + EXPECT_EQ(rfh_a, rfh_d->GetOutermostMainFrameOrEmbedder()); + EXPECT_EQ(rfh_e, rfh_e->GetOutermostMainFrameOrEmbedder()); } // Tests that |RenderFrameHostImpl::ForEachRenderFrameHostIncludingSpeculative|
diff --git a/content/browser/cache_storage/cache_storage_dispatcher_host.cc b/content/browser/cache_storage/cache_storage_dispatcher_host.cc index 73c78c0..a0a41be 100644 --- a/content/browser/cache_storage/cache_storage_dispatcher_host.cc +++ b/content/browser/cache_storage/cache_storage_dispatcher_host.cc
@@ -208,9 +208,12 @@ content::CacheStorageCache::InitState::Initialized : false; + bool range_request = + request->headers.contains(std::string(net::HttpRequestHeaders::kRange)); + auto cb = base::BindOnce( [](base::WeakPtr<CacheImpl> self, base::TimeTicks start_time, - bool ignore_search, bool in_related_fetch_event, + bool ignore_search, bool in_related_fetch_event, bool range_request, bool cache_initialized, int64_t trace_id, blink::mojom::CacheStorageCache::MatchCallback callback, blink::mojom::CacheStorageError error, @@ -270,7 +273,7 @@ CacheStorageTracedValue(response)); blink::mojom::MatchResultPtr result; - if (in_related_fetch_event) { + if (in_related_fetch_event && !range_request) { result = EagerlyReadResponseBody(std::move(response)); } else { result = @@ -279,8 +282,8 @@ std::move(callback).Run(std::move(result)); }, weak_factory_.GetWeakPtr(), base::TimeTicks::Now(), - match_options->ignore_search, in_related_fetch_event, cache_initialized, - trace_id, std::move(callback)); + match_options->ignore_search, in_related_fetch_event, range_request, + cache_initialized, trace_id, std::move(callback)); if (!cache) { std::move(cb).Run(CacheStorageError::kErrorNotFound, nullptr);
diff --git a/content/browser/fenced_frame/fenced_frame_browsertest.cc b/content/browser/fenced_frame/fenced_frame_browsertest.cc index dc27469..fda6fa7 100644 --- a/content/browser/fenced_frame/fenced_frame_browsertest.cc +++ b/content/browser/fenced_frame/fenced_frame_browsertest.cc
@@ -78,6 +78,11 @@ EXPECT_EQ(nullptr, inner_fenced_frame_rfh->GetParent()); EXPECT_EQ(inner_fenced_frame_rfh->GetParentOrOuterDocument(), primary_rfh.get()); + EXPECT_EQ(inner_fenced_frame_rfh->GetOutermostMainFrame(), primary_rfh.get()); + EXPECT_EQ(inner_fenced_frame_rfh->GetParentOrOuterDocumentOrEmbedder(), + primary_rfh.get()); + EXPECT_EQ(inner_fenced_frame_rfh->GetOutermostMainFrameOrEmbedder(), + primary_rfh.get()); // Test `RenderFrameHostImpl::IsInPrimaryMainFrame`. EXPECT_TRUE(primary_rfh->IsInPrimaryMainFrame());
diff --git a/content/browser/prerender/prerender_browsertest.cc b/content/browser/prerender/prerender_browsertest.cc index c3515c63..48a96f4 100644 --- a/content/browser/prerender/prerender_browsertest.cc +++ b/content/browser/prerender/prerender_browsertest.cc
@@ -1603,6 +1603,34 @@ testing::UnorderedElementsAre(initiator_render_frame_host, prerendered_render_frame_host, rfh_sub_1, rfh_sub_2, rfh_sub_1_1)); + + EXPECT_EQ(nullptr, initiator_render_frame_host->GetParentOrOuterDocument()); + EXPECT_EQ(nullptr, prerendered_render_frame_host->GetParentOrOuterDocument()); + EXPECT_EQ(prerendered_render_frame_host, + rfh_sub_1->GetParentOrOuterDocument()); + EXPECT_EQ(rfh_sub_1, rfh_sub_1_1->GetParentOrOuterDocument()); + EXPECT_EQ(prerendered_render_frame_host, + rfh_sub_2->GetParentOrOuterDocument()); + EXPECT_EQ(initiator_render_frame_host, + initiator_render_frame_host->GetOutermostMainFrame()); + EXPECT_EQ(initiator_render_frame_host, + initiator_render_frame_host->GetOutermostMainFrameOrEmbedder()); + // The outermost document of a prerendered page is the prerendered main + // RenderFrameHost, not the primary main RenderFrameHost. + EXPECT_EQ(prerendered_render_frame_host, + prerendered_render_frame_host->GetOutermostMainFrame()); + EXPECT_EQ(prerendered_render_frame_host, rfh_sub_1->GetOutermostMainFrame()); + EXPECT_EQ(prerendered_render_frame_host, + rfh_sub_1_1->GetOutermostMainFrame()); + EXPECT_EQ(prerendered_render_frame_host, rfh_sub_2->GetOutermostMainFrame()); + EXPECT_EQ(prerendered_render_frame_host, + prerendered_render_frame_host->GetOutermostMainFrameOrEmbedder()); + EXPECT_EQ(prerendered_render_frame_host, + rfh_sub_1->GetOutermostMainFrameOrEmbedder()); + EXPECT_EQ(prerendered_render_frame_host, + rfh_sub_1_1->GetOutermostMainFrameOrEmbedder()); + EXPECT_EQ(prerendered_render_frame_host, + rfh_sub_2->GetOutermostMainFrameOrEmbedder()); } // Tests that a prerendering page cannot change the visible URL of the
diff --git a/content/browser/renderer_host/cross_process_frame_connector.cc b/content/browser/renderer_host/cross_process_frame_connector.cc index de006fd..53b91df 100644 --- a/content/browser/renderer_host/cross_process_frame_connector.cc +++ b/content/browser/renderer_host/cross_process_frame_connector.cc
@@ -46,7 +46,7 @@ // be on the correct display. All subsequent updates to |screen_infos_| // ultimately come from the root, so it makes sense to do it here as well. screen_infos_ = current_child_frame_host() - ->GetOutermostMainFrame() + ->GetOutermostMainFrameOrEmbedder() ->GetRenderWidgetHost() ->GetScreenInfos(); } @@ -454,7 +454,7 @@ return nullptr; RenderFrameHostImpl* root = - current_child_frame_host()->GetOutermostMainFrame(); + current_child_frame_host()->GetOutermostMainFrameOrEmbedder(); return static_cast<RenderWidgetHostViewBase*>(root->GetView()); }
diff --git a/content/browser/renderer_host/frame_tree.cc b/content/browser/renderer_host/frame_tree.cc index ca95742..5faf43ff 100644 --- a/content/browser/renderer_host/frame_tree.cc +++ b/content/browser/renderer_host/frame_tree.cc
@@ -625,7 +625,10 @@ // The accessibility tree data for the root of the frame tree keeps // track of the focused frame too, so update that every time the // focused frame changes. - root()->current_frame_host()->GetOutermostMainFrame()->UpdateAXTreeData(); + root() + ->current_frame_host() + ->GetOutermostMainFrameOrEmbedder() + ->UpdateAXTreeData(); } scoped_refptr<RenderViewHostImpl> FrameTree::CreateRenderViewHost(
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc index 6b124c3..7170533f 100644 --- a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc +++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
@@ -48,13 +48,12 @@ base::DictionaryValue* root; if (!value->GetAsDictionary(&root)) return false; - double x, y; - if (!root->GetDouble("x", &x)) + absl::optional<double> x = root->FindDoubleKey("x"); + absl::optional<double> y = root->FindDoubleKey("y"); + if (!x || !y) return false; - if (!root->GetDouble("y", &y)) - return false; - point->set_x(x); - point->set_y(y); + point->set_x(*x); + point->set_y(*y); return true; }
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index a2c0654f..2198d47e 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -8685,6 +8685,17 @@ return !GetParent() && GetPage().IsPrimary(); } +RenderFrameHostImpl* RenderFrameHostImpl::GetOutermostMainFrame() { + RenderFrameHostImpl* current = this; + while (true) { + RenderFrameHostImpl* parent_or_outer_doc = + current->GetParentOrOuterDocument(); + if (!parent_or_outer_doc) + return current; + current = parent_or_outer_doc; + }; +} + bool RenderFrameHostImpl::CanAccessFilesOfPageState( const blink::PageState& state) { return ChildProcessSecurityPolicyImpl::GetInstance()->CanReadAllFiles( @@ -12055,7 +12066,7 @@ return nullptr; } -RenderFrameHostImpl* RenderFrameHostImpl::GetOutermostMainFrame() { +RenderFrameHostImpl* RenderFrameHostImpl::GetOutermostMainFrameOrEmbedder() { RenderFrameHostImpl* current = this; while (true) { RenderFrameHostImpl* parent = current->GetParentOrOuterDocumentOrEmbedder(); @@ -12430,8 +12441,9 @@ // The accessibility tree for the outermost root frame contains references // to the focused frame via its AXTreeID, so ensure that we update that. - if (GetOutermostMainFrame() != this) - GetOutermostMainFrame()->UpdateAXTreeData(); + RenderFrameHostImpl* outermost = GetOutermostMainFrameOrEmbedder(); + if (outermost != this) + outermost->UpdateAXTreeData(); } bool RenderFrameHostImpl::DocumentUsedWebOTP() {
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index 6212c8d..a96eadb6 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -329,6 +329,7 @@ RenderFrameHostImpl* GetMainFrame() override; PageImpl& GetPage() override; bool IsInPrimaryMainFrame() override; + RenderFrameHostImpl* GetOutermostMainFrame() override; bool IsFencedFrameRoot() override; void ForEachRenderFrameHost(FrameIterationCallback on_frame) override; void ForEachRenderFrameHost( @@ -1878,8 +1879,14 @@ return media_device_id_salt_base_; } - // Returns the global root RenderFrameHostImpl in the outermost WebContents. - RenderFrameHostImpl* GetOutermostMainFrame(); + // Returns the topmost ancestor RenderFrameHost. This includes any parents (in + // the case of subframes), any outer documents (e.g. fenced frame owners), and + // any GuestViews. See also GetOutermostMainFrame which does not escape + // GuestViews and GetParentOrOuterDocumentOrEmbedder for more details. + // Note that this may be different from getting the WebContents' primary main + // frame. For example, if `this` is in a bfcached or prerendered page, this + // will return the cached/prerendered page's main RenderFrameHost. + RenderFrameHostImpl* GetOutermostMainFrameOrEmbedder(); void set_inner_tree_main_frame_tree_node_id(int id) { inner_tree_main_frame_tree_node_id_ = id;
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc index 85ea3cf7..524ca1eb 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -5549,6 +5549,19 @@ })); EXPECT_THAT(visited_frames, testing::ElementsAre(rfh_a, rfh_b, rfh_d)); } + + EXPECT_EQ(nullptr, rfh_a->GetParentOrOuterDocument()); + EXPECT_EQ(rfh_a, rfh_b->GetParentOrOuterDocument()); + EXPECT_EQ(rfh_b, rfh_c->GetParentOrOuterDocument()); + EXPECT_EQ(rfh_a, rfh_d->GetParentOrOuterDocument()); + EXPECT_EQ(rfh_a, rfh_a->GetOutermostMainFrame()); + EXPECT_EQ(rfh_a, rfh_b->GetOutermostMainFrame()); + EXPECT_EQ(rfh_a, rfh_c->GetOutermostMainFrame()); + EXPECT_EQ(rfh_a, rfh_d->GetOutermostMainFrame()); + EXPECT_EQ(rfh_a, rfh_a->GetOutermostMainFrameOrEmbedder()); + EXPECT_EQ(rfh_a, rfh_b->GetOutermostMainFrameOrEmbedder()); + EXPECT_EQ(rfh_a, rfh_c->GetOutermostMainFrameOrEmbedder()); + EXPECT_EQ(rfh_a, rfh_d->GetOutermostMainFrameOrEmbedder()); } // Tests that RenderFrameHost::ForEachRenderFrameHost does not expose @@ -5817,8 +5830,12 @@ EXPECT_THAT(CollectAllRenderFrameHosts(rfh_a), testing::ElementsAre(rfh_a, rfh_b)); EXPECT_EQ(nullptr, rfh_b->GetParent()); + // Note that since this is a generic test inner WebContents, whether it's + // considered an outer document or embedder is just an implementation detail. EXPECT_EQ(nullptr, rfh_b->GetParentOrOuterDocument()); + EXPECT_EQ(rfh_b, rfh_b->GetOutermostMainFrame()); EXPECT_EQ(rfh_a, rfh_b->GetParentOrOuterDocumentOrEmbedder()); + EXPECT_EQ(rfh_a, rfh_b->GetOutermostMainFrameOrEmbedder()); } IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
diff --git a/content/browser/service_worker/service_worker_version_browsertest.cc b/content/browser/service_worker/service_worker_version_browsertest.cc index 3537c2308..57708e2 100644 --- a/content/browser/service_worker/service_worker_version_browsertest.cc +++ b/content/browser/service_worker/service_worker_version_browsertest.cc
@@ -393,11 +393,20 @@ const std::string& path, ServiceWorkerFetchDispatcher::FetchEventResult* result, blink::mojom::FetchAPIResponsePtr* response) { + FetchOnRegisteredWorker(path, "", result, response); + } + + void FetchOnRegisteredWorker( + const std::string& path, + const std::string& range_header, + ServiceWorkerFetchDispatcher::FetchEventResult* result, + blink::mojom::FetchAPIResponsePtr* response) { bool prepare_result = false; FetchResult fetch_result; fetch_result.status = blink::ServiceWorkerStatusCode::kErrorFailed; base::RunLoop fetch_run_loop; - Fetch(fetch_run_loop.QuitClosure(), path, &prepare_result, &fetch_result); + Fetch(fetch_run_loop.QuitClosure(), path, range_header, &prepare_result, + &fetch_result); fetch_run_loop.Run(); ASSERT_TRUE(prepare_result); *result = fetch_result.result; @@ -622,6 +631,7 @@ void Fetch(base::OnceClosure done, const std::string& path, + const std::string& range_header, bool* prepare_result, FetchResult* result) { ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -635,6 +645,9 @@ auto request = blink::mojom::FetchAPIRequest::New(); request->url = url; request->method = "GET"; + if (!range_header.empty()) { + request->headers[net::HttpRequestHeaders::kRange] = range_header; + } fetch_dispatcher_ = std::make_unique<ServiceWorkerFetchDispatcher>( std::move(request), destination, std::string() /* client_id */, version_, std::move(prepare_callback), std::move(fetch_callback), @@ -1497,7 +1510,14 @@ class CacheStorageEagerReadingTest : public ServiceWorkerVersionBrowserTest { public: void SetupServiceWorkerAndDoFetch( - std::string fetch_url, + const std::string& fetch_url, + blink::mojom::FetchAPIResponsePtr* response_out) { + SetupServiceWorkerAndDoFetch(fetch_url, "", response_out); + } + + void SetupServiceWorkerAndDoFetch( + const std::string& fetch_url, + const std::string& range_header, blink::mojom::FetchAPIResponsePtr* response_out) { StartServerAndNavigateToSetup(); ASSERT_EQ(Install("/service_worker/cached_fetch_event.js"), @@ -1505,7 +1525,7 @@ ASSERT_EQ(Activate(), blink::ServiceWorkerStatusCode::kOk); ServiceWorkerFetchDispatcher::FetchEventResult result; - FetchOnRegisteredWorker(fetch_url, &result, response_out); + FetchOnRegisteredWorker(fetch_url, range_header, &result, response_out); } void ExpectNormalCacheResponse(blink::mojom::FetchAPIResponsePtr response) { @@ -1569,4 +1589,12 @@ ExpectNormalCacheResponse(std::move(response)); } +IN_PROC_BROWSER_TEST_F(CacheStorageEagerReadingTest, + CacheMatchInRelatedFetchEventWithRangeRequest) { + blink::mojom::FetchAPIResponsePtr response; + SetupServiceWorkerAndDoFetch(kCacheMatchURL, "bytes=0-8", &response); + EXPECT_TRUE(response); + ExpectNormalCacheResponse(std::move(response)); +} + } // namespace content
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc index 403e4c98..6e94cbe 100644 --- a/content/browser/site_per_process_hit_test_browsertest.cc +++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -650,13 +650,12 @@ base::DictionaryValue* root; if (!value->GetAsDictionary(&root)) return false; - double x, y; - if (!root->GetDouble("x", &x)) + absl::optional<double> x = root->FindDoubleKey("x"); + absl::optional<double> y = root->FindDoubleKey("y"); + if (!x || !y) return false; - if (!root->GetDouble("y", &y)) - return false; - point->set_x(x); - point->set_y(y); + point->set_x(*x); + point->set_y(*y); return true; }
diff --git a/content/public/browser/idle_manager.h b/content/public/browser/idle_manager.h index fd5b7dff..ee36970 100644 --- a/content/public/browser/idle_manager.h +++ b/content/public/browser/idle_manager.h
@@ -15,26 +15,10 @@ namespace content { -class IdleTimeProvider; - // Provides an interface for handling mojo connections from the renderer, // keeping track of clients that are monitoring the user's idle state. class IdleManager { public: - // Provides an interface for calculating a user's idle time and screen state. - class IdleTimeProvider { - public: - IdleTimeProvider() = default; - virtual ~IdleTimeProvider() = default; - - IdleTimeProvider(const IdleTimeProvider&) = delete; - IdleTimeProvider& operator=(const IdleTimeProvider&) = delete; - - // See ui/base/idle/idle.h for the semantics of these methods. - virtual base::TimeDelta CalculateIdleTime() = 0; - virtual bool CheckIdleStateIsLocked() = 0; - }; - IdleManager() = default; virtual ~IdleManager() = default;
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index a11af1d36..179302b 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -286,6 +286,17 @@ // the primary main frame. virtual bool IsInPrimaryMainFrame() = 0; + // Returns the topmost ancestor RenderFrameHost of this RenderFrameHost. This + // includes any parents (in the case of subframes) and any outer documents + // (e.g. fenced frame owners), but does not traverse out of GuestViews. + // This can be used instead of GetMainFrame in cases where we want to escape + // inner pages. See also GetParentOrOuterDocument for more details on the + // distinction of "parents" and "outer documents." + // Note that this may be different from getting the WebContents' primary main + // frame. For example, if `this` is in a bfcached or prerendered page, this + // will return the cached/prerendered page's main RenderFrameHost. + virtual RenderFrameHost* GetOutermostMainFrame() = 0; + // Fenced frames (meta-bug https://crbug.com/1111084): // Returns true if this document is the root of a fenced frame tree. //
diff --git a/content/renderer/skia_benchmarking_extension.cc b/content/renderer/skia_benchmarking_extension.cc index e100ed8..120c2f9 100644 --- a/content/renderer/skia_benchmarking_extension.cc +++ b/content/renderer/skia_benchmarking_extension.cc
@@ -186,7 +186,7 @@ const base::DictionaryValue* params_dict = nullptr; if (params_value.get() && params_value->GetAsDictionary(¶ms_dict)) { - params_dict->GetDouble("scale", &scale); + scale = params_dict->FindDoubleKey("scale").value_or(scale); params_dict->GetInteger("stop", &stop_index); const base::Value* clip_value = nullptr;
diff --git a/content/test/data/accessibility/html/input-search-expected-blink.txt b/content/test/data/accessibility/html/input-search-expected-blink.txt index 051c7b8..6756c6e 100644 --- a/content/test/data/accessibility/html/input-search-expected-blink.txt +++ b/content/test/data/accessibility/html/input-search-expected-blink.txt
@@ -2,9 +2,6 @@ ++genericContainer ignored ++++genericContainer ++++++searchBox value='Search terms' -++++++++genericContainer ignored -++++++++++genericContainer ignored -++++++++++++genericContainer -++++++++++++++staticText name='Search terms' -++++++++++++++++inlineTextBox name='Search terms' -++++++++++genericContainer ignored \ No newline at end of file +++++++++genericContainer +++++++++++staticText name='Search terms' +++++++++++++inlineTextBox name='Search terms'
diff --git a/content/test/data/accessibility/html/input-types-expected-blink.txt b/content/test/data/accessibility/html/input-types-expected-blink.txt index 1e7143b..9497946 100644 --- a/content/test/data/accessibility/html/input-types-expected-blink.txt +++ b/content/test/data/accessibility/html/input-types-expected-blink.txt
@@ -65,10 +65,7 @@ ++++++++staticText name='Search: ' ++++++++++inlineTextBox name='Search: ' ++++++++searchBox editable name='Search:' -++++++++++genericContainer ignored -++++++++++++genericContainer ignored -++++++++++++++genericContainer editable -++++++++++++genericContainer ignored +++++++++++genericContainer editable ++++++labelText ++++++++staticText name='Submit: ' ++++++++++inlineTextBox name='Submit: '
diff --git a/content/test/data/accessibility/html/input-types-with-placeholder-expected-blink.txt b/content/test/data/accessibility/html/input-types-with-placeholder-expected-blink.txt index 63b620a1..2ef1299 100644 --- a/content/test/data/accessibility/html/input-types-with-placeholder-expected-blink.txt +++ b/content/test/data/accessibility/html/input-types-with-placeholder-expected-blink.txt
@@ -22,11 +22,7 @@ ++++++++staticText name='Search: ' ++++++++++inlineTextBox name='Search: ' ++++++++searchBox editable name='Search:' placeholder='search' -++++++++++genericContainer ignored -++++++++++genericContainer ignored -++++++++++++genericContainer ignored -++++++++++++++genericContainer editable -++++++++++++genericContainer ignored +++++++++++genericContainer editable ++++++labelText ++++++++staticText name='Tel: ' ++++++++++inlineTextBox name='Tel: ' @@ -44,4 +40,4 @@ ++++++++++inlineTextBox name='Url: ' ++++++++textField editable name='Url:' placeholder='https://www.example.com' ++++++++++genericContainer ignored -++++++++++genericContainer editable \ No newline at end of file +++++++++++genericContainer editable
diff --git a/content/test/data/accessibility/html/input-types-with-value-and-placeholder-expected-blink.txt b/content/test/data/accessibility/html/input-types-with-value-and-placeholder-expected-blink.txt index 0b32733..7e1ab2a4 100644 --- a/content/test/data/accessibility/html/input-types-with-value-and-placeholder-expected-blink.txt +++ b/content/test/data/accessibility/html/input-types-with-value-and-placeholder-expected-blink.txt
@@ -30,12 +30,9 @@ ++++++++++inlineTextBox name='Search: ' ++++++++searchBox editable name='Search:' placeholder='placeholder' value='search' ++++++++++genericContainer ignored invisible -++++++++++genericContainer ignored -++++++++++++genericContainer ignored -++++++++++++++genericContainer editable -++++++++++++++++staticText editable name='search' -++++++++++++++++++inlineTextBox editable name='search' -++++++++++++genericContainer ignored +++++++++++genericContainer editable +++++++++++++staticText editable name='search' +++++++++++++++inlineTextBox editable name='search' ++++++labelText ++++++++staticText name='Tel: ' ++++++++++inlineTextBox name='Tel: ' @@ -59,4 +56,4 @@ ++++++++++genericContainer ignored invisible ++++++++++genericContainer editable ++++++++++++staticText editable name='https://www.example.com' -++++++++++++++inlineTextBox editable name='https://www.example.com' \ No newline at end of file +++++++++++++++inlineTextBox editable name='https://www.example.com'
diff --git a/content/test/data/accessibility/html/input-types-with-value-expected-blink.txt b/content/test/data/accessibility/html/input-types-with-value-expected-blink.txt index 4718483..115a019 100644 --- a/content/test/data/accessibility/html/input-types-with-value-expected-blink.txt +++ b/content/test/data/accessibility/html/input-types-with-value-expected-blink.txt
@@ -26,12 +26,9 @@ ++++++++staticText name='Search: ' ++++++++++inlineTextBox name='Search: ' ++++++++searchBox editable name='Search:' value='search' -++++++++++genericContainer ignored -++++++++++++genericContainer ignored -++++++++++++++genericContainer editable -++++++++++++++++staticText editable name='search' -++++++++++++++++++inlineTextBox editable name='search' -++++++++++++genericContainer ignored +++++++++++genericContainer editable +++++++++++++staticText editable name='search' +++++++++++++++inlineTextBox editable name='search' ++++++labelText ++++++++staticText name='Tel: ' ++++++++++inlineTextBox name='Tel: '
diff --git a/content/test/data/service_worker/cached_fetch_event.js b/content/test/data/service_worker/cached_fetch_event.js index 890e51f..3f44d7f 100644 --- a/content/test/data/service_worker/cached_fetch_event.js +++ b/content/test/data/service_worker/cached_fetch_event.js
@@ -15,6 +15,6 @@ self.addEventListener('fetch', evt => { evt.respondWith(async function() { const c = await caches.open(name); - return c.match(resource); + return c.match(new Request(resource, { headers: evt.request.headers })); }()); });
diff --git a/content/test/gpu/unexpected_pass_finder.py b/content/test/gpu/unexpected_pass_finder.py index 7e94185f..c13df5a 100755 --- a/content/test/gpu/unexpected_pass_finder.py +++ b/content/test/gpu/unexpected_pass_finder.py
@@ -206,9 +206,9 @@ stale_message = '' if args.remove_stale_expectations: stale_expectations = [] - for _, expectation_map in stale.items(): + for expectation_file, expectation_map in stale.items(): stale_expectations.extend(expectation_map.keys()) - stale_expectations.extend(unused_expectations) + stale_expectations.extend(unused_expectations.get(expectation_file, [])) affected_urls |= expectations_instance.RemoveExpectationsFromFile( stale_expectations, args.expectation_file) stale_message += ('Stale expectations removed from %s. Stale comments, '
diff --git a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc index 0706ac67..237ed89 100644 --- a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc +++ b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
@@ -88,8 +88,7 @@ UnloadedExtensionReason reason) { if (reason == UnloadedExtensionReason::DISABLE) { static constexpr int kReleaseAllocationDisableReasons = - disable_reason::DISABLE_BLOCKED_BY_POLICY | - disable_reason::DISABLE_REMOTELY_FOR_MALWARE; + disable_reason::DISABLE_BLOCKED_BY_POLICY; // Release allocation on reload of an unpacked extension and treat it as a // new install since the extension directory's contents may have changed.
diff --git a/extensions/browser/disable_reason.h b/extensions/browser/disable_reason.h index 1c62515..622b56d 100644 --- a/extensions/browser/disable_reason.h +++ b/extensions/browser/disable_reason.h
@@ -45,8 +45,9 @@ // Blocked due to management policy. DISABLE_BLOCKED_BY_POLICY = 1 << 16, // DISABLE_BLOCKED_MATURE = 1 << 17, // Deprecated. - // Remotely disabled due to malware. - DISABLE_REMOTELY_FOR_MALWARE = 1 << 18, + // TODO(crbug.com/1193695): Replaced by kPrefOmahaBlocklistState. Remove this + // entirely once clients are migrated over, around M99. + DEPRECATED_DISABLE_REMOTELY_FOR_MALWARE = 1 << 18, DISABLE_REINSTALL = 1 << 19, // Disabled by Safe Browsing extension allowlist enforcement. DISABLE_NOT_ALLOWLISTED = 1 << 20,
diff --git a/extensions/browser/extension_prefs.cc b/extensions/browser/extension_prefs.cc index 83efb76..e92591e 100644 --- a/extensions/browser/extension_prefs.cc +++ b/extensions/browser/extension_prefs.cc
@@ -2697,6 +2697,19 @@ legacy_pref_cleared = true; } + if (HasDisableReason( + extension_id, + disable_reason::DEPRECATED_DISABLE_REMOTELY_FOR_MALWARE)) { + // Migrate the old value. + blocklist_prefs::AddOmahaBlocklistState( + extension_id, BitMapBlocklistState::BLOCKLISTED_MALWARE, this); + // Clear the legacy pref. + RemoveDisableReason( + extension_id, + disable_reason::DEPRECATED_DISABLE_REMOTELY_FOR_MALWARE); + legacy_pref_cleared = true; + } + if (legacy_pref_cleared) DeleteExtensionPrefsIfPrefEmpty(extension_id); }
diff --git a/extensions/common/api/messaging/message.h b/extensions/common/api/messaging/message.h index c3ff586..8c6cc97 100644 --- a/extensions/common/api/messaging/message.h +++ b/extensions/common/api/messaging/message.h
@@ -5,26 +5,32 @@ #ifndef EXTENSIONS_COMMON_API_MESSAGING_MESSAGE_H_ #define EXTENSIONS_COMMON_API_MESSAGING_MESSAGE_H_ +#include "extensions/common/api/messaging/serialization_format.h" + namespace extensions { // A message consists of both the data itself as well as a user gesture state. struct Message { std::string data; + SerializationFormat format = SerializationFormat::kJson; bool user_gesture = false; bool from_privileged_context = false; Message() = default; Message(const std::string& data, + SerializationFormat format, bool user_gesture, bool from_privileged_context = false) : data(data), + format(format), user_gesture(user_gesture), from_privileged_context(from_privileged_context) {} bool operator==(const Message& other) const { // Skipping the equality check for |from_privileged_context| here // because this field is used only for histograms. - return data == other.data && user_gesture == other.user_gesture; + return data == other.data && user_gesture == other.user_gesture && + format == other.format; } };
diff --git a/extensions/common/api/messaging/port_id.cc b/extensions/common/api/messaging/port_id.cc index 105ff9f..df7f6435 100644 --- a/extensions/common/api/messaging/port_id.cc +++ b/extensions/common/api/messaging/port_id.cc
@@ -11,8 +11,12 @@ PortId::PortId() {} PortId::PortId(const base::UnguessableToken& context_id, int port_number, - bool is_opener) - : context_id(context_id), port_number(port_number), is_opener(is_opener) {} + bool is_opener, + SerializationFormat format) + : context_id(context_id), + port_number(port_number), + is_opener(is_opener), + serialization_format(format) {} PortId::~PortId() {} PortId::PortId(PortId&& other) = default; PortId::PortId(const PortId& other) = default; @@ -20,12 +24,14 @@ bool PortId::operator==(const PortId& other) const { return context_id == other.context_id && port_number == other.port_number && - is_opener == other.is_opener; + is_opener == other.is_opener && + serialization_format == other.serialization_format; } bool PortId::operator<(const PortId& other) const { - return std::tie(context_id, port_number, is_opener) < - std::tie(other.context_id, other.port_number, other.is_opener); + return std::tie(context_id, port_number, is_opener, serialization_format) < + std::tie(other.context_id, other.port_number, other.is_opener, + other.serialization_format); } } // namespace extensions
diff --git a/extensions/common/api/messaging/port_id.h b/extensions/common/api/messaging/port_id.h index e44aa1f..1856efa 100644 --- a/extensions/common/api/messaging/port_id.h +++ b/extensions/common/api/messaging/port_id.h
@@ -8,6 +8,7 @@ #include <utility> #include "base/unguessable_token.h" +#include "extensions/common/api/messaging/serialization_format.h" namespace extensions { @@ -26,6 +27,8 @@ // port with the number '1' in each. // - is_opener: Whether or not this port id is for the opener port (false // indicating it is the receiver port). +// Additionally, this also holds `serialization_format` which is the +// preferred SerializationFormat to be used for messages sent by this port. // A few more notes: // - There should only be a single existent opener port. That is, in all the // contexts, there should only be one with a given context_id, port_number, @@ -41,16 +44,21 @@ // this means that multiple contexts could have the same id. However, GUIDs // are sufficiently random as to be globally unique in practice (the chance // of a duplicate is about the same as the sun exploding right now). +// - The `serialization_format` for a port may sometimes differ from that of the +// Messages sent on the port. For example this can happen if a message can't +// be structure cloned in which case we fallback to JSON. struct PortId { // See class comments for the description of these fields. base::UnguessableToken context_id; int port_number = 0; bool is_opener = false; + SerializationFormat serialization_format = SerializationFormat::kJson; PortId(); PortId(const base::UnguessableToken& context_id, int port_number, - bool is_opener); + bool is_opener, + SerializationFormat format); ~PortId(); PortId(PortId&& other); PortId(const PortId& other); @@ -64,7 +72,7 @@ // receiver port returns the ID of the opener, and a call on the opener port // returns the ID of all receivers. PortId GetOppositePortId() const { - return PortId(context_id, port_number, !is_opener); + return PortId(context_id, port_number, !is_opener, serialization_format); } bool operator==(const PortId& other) const;
diff --git a/extensions/common/api/messaging/serialization_format.h b/extensions/common/api/messaging/serialization_format.h new file mode 100644 index 0000000..69eb17f --- /dev/null +++ b/extensions/common/api/messaging/serialization_format.h
@@ -0,0 +1,18 @@ +// Copyright 2021 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 EXTENSIONS_COMMON_API_MESSAGING_SERIALIZATION_FORMAT_H_ +#define EXTENSIONS_COMMON_API_MESSAGING_SERIALIZATION_FORMAT_H_ + +namespace extensions { + +enum class SerializationFormat { + kStructuredCloned, + kJson, + kLast = kJson, +}; + +} // namespace extensions + +#endif // EXTENSIONS_COMMON_API_MESSAGING_SERIALIZATION_FORMAT_H_
diff --git a/extensions/common/extension_features.cc b/extensions/common/extension_features.cc index 69ebb98..d18fe4d 100644 --- a/extensions/common/extension_features.cc +++ b/extensions/common/extension_features.cc
@@ -82,4 +82,11 @@ // crbug.com/1173354. const base::Feature kAllowWasmInMV3{"AllowWasmInMV3", base::FEATURE_DISABLED_BY_DEFAULT}; + +// When enabled, causes Manifest V3 (and greater) extensions to use structured +// cloning (instead of JSON serialization) for extension messaging, except when +// communicating with native messaging hosts. +const base::Feature kStructuredCloningForMV3Messaging{ + "StructuredCloningForMV3Messaging", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace extensions_features
diff --git a/extensions/common/extension_features.h b/extensions/common/extension_features.h index 9abf282..b2975d0 100644 --- a/extensions/common/extension_features.h +++ b/extensions/common/extension_features.h
@@ -32,6 +32,8 @@ extern const base::Feature kAllowWasmInMV3; +extern const base::Feature kStructuredCloningForMV3Messaging; + } // namespace extensions_features #endif // EXTENSIONS_COMMON_EXTENSION_FEATURES_H_
diff --git a/extensions/common/extension_messages.h b/extensions/common/extension_messages.h index 0ac92f3..5ca3dd9 100644 --- a/extensions/common/extension_messages.h +++ b/extensions/common/extension_messages.h
@@ -25,6 +25,7 @@ #include "extensions/common/api/messaging/messaging_endpoint.h" #include "extensions/common/api/messaging/port_context.h" #include "extensions/common/api/messaging/port_id.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/common_param_traits.h" #include "extensions/common/constants.h" #include "extensions/common/draggable_region.h" @@ -66,6 +67,9 @@ IPC_ENUM_TRAITS_MAX_VALUE(extensions::MessagingEndpoint::Type, extensions::MessagingEndpoint::Type::kLast) +IPC_ENUM_TRAITS_MAX_VALUE(extensions::SerializationFormat, + extensions::SerializationFormat::kLast) + // Parameters structure for ExtensionHostMsg_AddAPIActionToActivityLog and // ExtensionHostMsg_AddEventToActivityLog. IPC_STRUCT_BEGIN(ExtensionHostMsg_APIActionOrEvent_Params) @@ -255,6 +259,7 @@ IPC_STRUCT_TRAITS_BEGIN(extensions::Message) IPC_STRUCT_TRAITS_MEMBER(data) + IPC_STRUCT_TRAITS_MEMBER(format) IPC_STRUCT_TRAITS_MEMBER(user_gesture) IPC_STRUCT_TRAITS_END() @@ -262,6 +267,7 @@ IPC_STRUCT_TRAITS_MEMBER(context_id) IPC_STRUCT_TRAITS_MEMBER(port_number) IPC_STRUCT_TRAITS_MEMBER(is_opener) + IPC_STRUCT_TRAITS_MEMBER(serialization_format) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(extensions::EventFilteringInfo)
diff --git a/extensions/renderer/bindings/api_binding_hooks.cc b/extensions/renderer/bindings/api_binding_hooks.cc index 2fa599a..b6c9406 100644 --- a/extensions/renderer/bindings/api_binding_hooks.cc +++ b/extensions/renderer/bindings/api_binding_hooks.cc
@@ -377,21 +377,6 @@ return GetJSHookInterfaceObject(api_name_, context, true); } -v8::Local<v8::Function> APIBindingHooks::GetCustomJSCallback( - const std::string& name, - v8::Local<v8::Context> context) { - v8::Local<v8::Object> hooks = - GetJSHookInterfaceObject(api_name_, context, false); - if (hooks.IsEmpty()) - return v8::Local<v8::Function>(); - JSHookInterface* hook_interface = nullptr; - gin::Converter<JSHookInterface*>::FromV8(context->GetIsolate(), hooks, - &hook_interface); - CHECK(hook_interface); - - return hook_interface->GetCustomCallback(name, context->GetIsolate()); -} - bool APIBindingHooks::CreateCustomEvent(v8::Local<v8::Context> context, const std::string& event_name, v8::Local<v8::Value>* event_out) {
diff --git a/extensions/renderer/bindings/api_binding_hooks.h b/extensions/renderer/bindings/api_binding_hooks.h index f0f35c2..d2dd8933 100644 --- a/extensions/renderer/bindings/api_binding_hooks.h +++ b/extensions/renderer/bindings/api_binding_hooks.h
@@ -68,10 +68,6 @@ // Returns a JS interface that can be used to register hooks. v8::Local<v8::Object> GetJSHookInterface(v8::Local<v8::Context> context); - // Gets the custom-set JS callback for the given method, if one exists. - v8::Local<v8::Function> GetCustomJSCallback(const std::string& method_name, - v8::Local<v8::Context> context); - // Creates a new JS event for the given |event_name|, if a custom event is // provided. Returns true if an event was created. bool CreateCustomEvent(v8::Local<v8::Context> context,
diff --git a/extensions/renderer/gin_port.cc b/extensions/renderer/gin_port.cc index a7dd9a0..bf9aa0a 100644 --- a/extensions/renderer/gin_port.cc +++ b/extensions/renderer/gin_port.cc
@@ -157,8 +157,8 @@ } std::string error; - std::unique_ptr<Message> message = - messaging_util::MessageFromV8(context, v8_message, &error); + std::unique_ptr<Message> message = messaging_util::MessageFromV8( + context, v8_message, port_id_.serialization_format, &error); // NOTE(devlin): JS-based bindings just log to the console here and return, // rather than throwing an error. But it really seems like it should be an // error. Let's see how this goes.
diff --git a/extensions/renderer/gin_port.h b/extensions/renderer/gin_port.h index 77a4af1..30a7cdc 100644 --- a/extensions/renderer/gin_port.h +++ b/extensions/renderer/gin_port.h
@@ -132,14 +132,14 @@ State state_ = kActive; // The associated port id. - PortId port_id_; + const PortId port_id_; // The routing id associated with the port's context's render frame. // TODO(devlin/lazyboy): This won't work with service workers. - int routing_id_; + const int routing_id_; // The port's name. - std::string name_; + const std::string name_; // The associated APIEventHandler. Guaranteed to outlive this object. APIEventHandler* const event_handler_;
diff --git a/extensions/renderer/gin_port_unittest.cc b/extensions/renderer/gin_port_unittest.cc index 161ee88..8ea5d376 100644 --- a/extensions/renderer/gin_port_unittest.cc +++ b/extensions/renderer/gin_port_unittest.cc
@@ -12,6 +12,7 @@ #include "content/public/common/content_features.h" #include "extensions/common/api/messaging/message.h" #include "extensions/common/api/messaging/port_id.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/renderer/bindings/api_binding_test.h" #include "extensions/renderer/bindings/api_binding_test_util.h" #include "extensions/renderer/bindings/api_event_handler.h" @@ -115,7 +116,8 @@ v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = MainContext(); - PortId port_id(base::UnguessableToken::Create(), 0, true); + PortId port_id(base::UnguessableToken::Create(), 0, true, + SerializationFormat::kJson); gin::Handle<GinPort> port = CreatePort(context, port_id); v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>(); @@ -129,7 +131,8 @@ v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = MainContext(); - PortId port_id(base::UnguessableToken::Create(), 0, true); + PortId port_id(base::UnguessableToken::Create(), 0, true, + SerializationFormat::kJson); gin::Handle<GinPort> port = CreatePort(context, port_id); v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>(); @@ -150,7 +153,8 @@ v8::Local<v8::Value> args[] = {port_obj}; RunFunctionOnGlobal(test_function, context, base::size(args), args); - port->DispatchOnMessage(context, Message(R"({"foo":42})", false)); + port->DispatchOnMessage( + context, Message(R"({"foo":42})", SerializationFormat::kJson, false)); EXPECT_EQ("true", GetStringPropertyFromObject(context->Global(), context, "messageValid")); @@ -163,7 +167,8 @@ v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = MainContext(); - PortId port_id(base::UnguessableToken::Create(), 0, true); + PortId port_id(base::UnguessableToken::Create(), 0, true, + SerializationFormat::kJson); gin::Handle<GinPort> port = CreatePort(context, port_id); v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>(); @@ -200,7 +205,9 @@ // Simple message; should succeed. const char kFunction[] = "(function(port) { port.postMessage({data: [42]}); })"; - test_post_message(kFunction, port_id, Message(R"({"data":[42]})", false)); + test_post_message( + kFunction, port_id, + Message(R"({"data":[42]})", SerializationFormat::kJson, false)); // TODO(mustaq): We need a test with Message.user_gesture == true. } @@ -208,7 +215,8 @@ { // Simple non-object message; should succeed. const char kFunction[] = "(function(port) { port.postMessage('hello'); })"; - test_post_message(kFunction, port_id, Message(R"("hello")", false)); + test_post_message(kFunction, port_id, + Message(R"("hello")", SerializationFormat::kJson, false)); } { @@ -216,14 +224,17 @@ // stringify result "undefined"); should succeed. const char kFunction[] = "(function(port) { port.postMessage('undefined'); })"; - test_post_message(kFunction, port_id, Message(R"("undefined")", false)); + test_post_message( + kFunction, port_id, + Message(R"("undefined")", SerializationFormat::kJson, false)); } { // We change undefined to null; see comment in gin_port.cc. const char kFunction[] = "(function(port) { port.postMessage(undefined); })"; - test_post_message(kFunction, port_id, Message("null", false)); + test_post_message(kFunction, port_id, + Message("null", SerializationFormat::kJson, false)); } { @@ -261,7 +272,8 @@ v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = MainContext(); - PortId port_id(base::UnguessableToken::Create(), 0, true); + PortId port_id(base::UnguessableToken::Create(), 0, true, + SerializationFormat::kJson); gin::Handle<GinPort> port = CreatePort(context, port_id); v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>(); @@ -289,7 +301,8 @@ v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = MainContext(); - PortId port_id(base::UnguessableToken::Create(), 0, true); + PortId port_id(base::UnguessableToken::Create(), 0, true, + SerializationFormat::kJson); gin::Handle<GinPort> port = CreatePort(context, port_id); v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>(); @@ -310,7 +323,8 @@ v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = MainContext(); - PortId port_id(base::UnguessableToken::Create(), 0, true); + PortId port_id(base::UnguessableToken::Create(), 0, true, + SerializationFormat::kJson); gin::Handle<GinPort> port = CreatePort(context, port_id); v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>(); @@ -336,7 +350,8 @@ v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = MainContext(); - PortId port_id(base::UnguessableToken::Create(), 0, true); + PortId port_id(base::UnguessableToken::Create(), 0, true, + SerializationFormat::kJson); gin::Handle<GinPort> port = CreatePort(context, port_id); v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>(); @@ -368,7 +383,8 @@ v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = MainContext(); - PortId port_id(base::UnguessableToken::Create(), 0, true); + PortId port_id(base::UnguessableToken::Create(), 0, true, + SerializationFormat::kJson); { gin::Handle<GinPort> port = CreatePort(context, port_id); @@ -393,7 +409,8 @@ v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = MainContext(); - PortId port_id(base::UnguessableToken::Create(), 0, true); + PortId port_id(base::UnguessableToken::Create(), 0, true, + SerializationFormat::kJson); gin::Handle<GinPort> port = CreatePort(context, port_id); v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>(); @@ -435,7 +452,8 @@ v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = MainContext(); - PortId port_id(base::UnguessableToken::Create(), 0, true); + PortId port_id(base::UnguessableToken::Create(), 0, true, + SerializationFormat::kJson); gin::Handle<GinPort> port = CreatePort(context, port_id); v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>();
diff --git a/extensions/renderer/messaging_util.cc b/extensions/renderer/messaging_util.cc index a812649a..d85957d 100644 --- a/extensions/renderer/messaging_util.cc +++ b/extensions/renderer/messaging_util.cc
@@ -12,7 +12,9 @@ #include "base/strings/stringprintf.h" #include "components/crx_file/id_util.h" #include "extensions/common/api/messaging/message.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/extension.h" +#include "extensions/common/extension_features.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_handlers/background_info.h" #include "extensions/renderer/get_script_context.h" @@ -79,7 +81,8 @@ bool has_unrestricted_user_activation = web_frame && web_frame->HasTransientUserActivation() && !web_frame->LastActivationWasRestricted(); - return std::make_unique<Message>(message, has_unrestricted_user_activation, + return std::make_unique<Message>(message, SerializationFormat::kJson, + has_unrestricted_user_activation, privileged_context); } @@ -100,7 +103,9 @@ std::unique_ptr<Message> MessageFromV8(v8::Local<v8::Context> context, v8::Local<v8::Value> value, + SerializationFormat format, std::string* error_out) { + // TODO(crbug.com/248548): Incorporate `format` while serializing the message. DCHECK(!value.IsEmpty()); v8::Isolate* isolate = context->GetIsolate(); v8::Context::Scope context_scope(context); @@ -141,6 +146,9 @@ v8::Local<v8::Value> MessageToV8(v8::Local<v8::Context> context, const Message& message) { + // TODO(crbug.com/248548): Incorporate `message.format` while deserializing + // the message. + v8::Isolate* isolate = context->GetIsolate(); v8::Context::Scope context_scope(context); @@ -164,6 +172,19 @@ return 0; } +SerializationFormat GetSerializationFormat( + const ScriptContext& script_context) { + if (!base::FeatureList::IsEnabled( + extensions_features::kStructuredCloningForMV3Messaging)) { + return SerializationFormat::kJson; + } + + const Extension* extension = script_context.extension(); + return extension && extension->manifest_version() >= 3 + ? SerializationFormat::kStructuredCloned + : SerializationFormat::kJson; +} + MessageOptions ParseMessageOptions(v8::Local<v8::Context> context, v8::Local<v8::Object> v8_options, int flags) {
diff --git a/extensions/renderer/messaging_util.h b/extensions/renderer/messaging_util.h index 3ef6669..007b3a8 100644 --- a/extensions/renderer/messaging_util.h +++ b/extensions/renderer/messaging_util.h
@@ -16,6 +16,7 @@ } namespace extensions { +enum class SerializationFormat; class ScriptContext; struct Message; @@ -40,6 +41,7 @@ // will populate |error_out|. std::unique_ptr<Message> MessageFromV8(v8::Local<v8::Context> context, v8::Local<v8::Value> value, + SerializationFormat format, std::string* error); // Converts a message to a v8 value. This is expected not to fail, since it @@ -52,6 +54,11 @@ // |value| is either an int32 or -0. int ExtractIntegerId(v8::Local<v8::Value> value); +// Returns the preferred serialization format for the given `context`. Note +// extension native messaging clients shouldn't call this as they should always +// use JSON. +SerializationFormat GetSerializationFormat(const ScriptContext& context); + // Flags for ParseMessageOptions(). enum ParseOptionsFlags { NO_FLAGS = 0,
diff --git a/extensions/renderer/messaging_util_unittest.cc b/extensions/renderer/messaging_util_unittest.cc index eee132e9..73b2132d 100644 --- a/extensions/renderer/messaging_util_unittest.cc +++ b/extensions/renderer/messaging_util_unittest.cc
@@ -9,6 +9,7 @@ #include "base/cxx17_backports.h" #include "base/strings/stringprintf.h" #include "extensions/common/api/messaging/message.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/extension_builder.h" #include "extensions/renderer/bindings/api_binding_test.h" #include "extensions/renderer/bindings/api_binding_test_util.h" @@ -31,8 +32,8 @@ v8::Local<v8::Value> long_message = V8ValueFromScriptSource(context, "'a'.repeat(1024 *1024 * 65)"); std::string error; - std::unique_ptr<Message> message = - messaging_util::MessageFromV8(context, long_message, &error); + std::unique_ptr<Message> message = messaging_util::MessageFromV8( + context, long_message, SerializationFormat::kJson, &error); EXPECT_FALSE(message); EXPECT_EQ(kMessageTooLongError, error); }
diff --git a/extensions/renderer/native_renderer_messaging_service.cc b/extensions/renderer/native_renderer_messaging_service.cc index b79c49844..ec20ebb 100644 --- a/extensions/renderer/native_renderer_messaging_service.cc +++ b/extensions/renderer/native_renderer_messaging_service.cc
@@ -164,7 +164,8 @@ gin::Handle<GinPort> NativeRendererMessagingService::Connect( ScriptContext* script_context, const MessageTarget& target, - const std::string& channel_name) { + const std::string& channel_name, + SerializationFormat format) { if (!ScriptContextIsValid(script_context)) return gin::Handle<GinPort>(); @@ -174,9 +175,10 @@ return gin::Handle<GinPort>(); bool is_opener = true; - gin::Handle<GinPort> port = CreatePort( - script_context, channel_name, - PortId(script_context->context_id(), data->next_port_id++, is_opener)); + gin::Handle<GinPort> port = + CreatePort(script_context, channel_name, + PortId(script_context->context_id(), data->next_port_id++, + is_opener, format)); bindings_system_->GetIPCMessageSender()->SendOpenMessageChannel( script_context, port->port_id(), target, channel_name); @@ -196,7 +198,16 @@ script_context->v8_context(), kCreateIfMissing); bool is_opener = true; - PortId port_id(script_context->context_id(), data->next_port_id++, is_opener); + + // TODO(crbug.com/248548): Instead of inferring the SerializationFormat from + // Message, it'd be better to have the clients pass it directly. This is + // because, in case of `kStructuredCloned` to `kJson` fallback, the format for + // the ports will also be `kJson`. This is inconsistent with what we do for + // ports for long-lived channels where the port's `SerializationFormat` is + // always the same as that passed by messaging clients and is independent of + // any fallback behavior. + PortId port_id(script_context->context_id(), data->next_port_id++, is_opener, + message.format); one_time_message_handler_.SendMessage( script_context, port_id, target, method_name, message, response_callback);
diff --git a/extensions/renderer/native_renderer_messaging_service.h b/extensions/renderer/native_renderer_messaging_service.h index cfdbee8..ec09c0d 100644 --- a/extensions/renderer/native_renderer_messaging_service.h +++ b/extensions/renderer/native_renderer_messaging_service.h
@@ -22,6 +22,7 @@ } namespace extensions { +enum class SerializationFormat; class NativeExtensionBindingsSystem; class ScriptContextSetIterable; struct Message; @@ -109,7 +110,8 @@ // Creates and opens a new message port in the specified context. gin::Handle<GinPort> Connect(ScriptContext* script_context, const MessageTarget& target, - const std::string& name); + const std::string& name, + SerializationFormat format); // Sends a one-time message, as is used by runtime.sendMessage. void SendOneTimeMessage(ScriptContext* script_context,
diff --git a/extensions/renderer/native_renderer_messaging_service_unittest.cc b/extensions/renderer/native_renderer_messaging_service_unittest.cc index 831f326..c9f7517 100644 --- a/extensions/renderer/native_renderer_messaging_service_unittest.cc +++ b/extensions/renderer/native_renderer_messaging_service_unittest.cc
@@ -12,6 +12,7 @@ #include "components/crx_file/id_util.h" #include "content/public/common/child_process_host.h" #include "extensions/common/api/messaging/messaging_endpoint.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" #include "extensions/common/extension_messages.h" @@ -80,7 +81,7 @@ v8::HandleScope handle_scope(isolate()); base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id(other_context_id, 0, false); + const PortId port_id(other_context_id, 0, false, SerializationFormat::kJson); EXPECT_FALSE( messaging_service()->HasPortForTesting(script_context(), port_id)); @@ -105,7 +106,7 @@ v8::Local<v8::Context> context = MainContext(); base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id(other_context_id, 0, false); + const PortId port_id(other_context_id, 0, false, SerializationFormat::kJson); EXPECT_FALSE( messaging_service()->HasPortForTesting(script_context(), port_id)); @@ -164,8 +165,8 @@ v8::Local<v8::Context> context = MainContext(); base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id1(other_context_id, 0, false); - const PortId port_id2(other_context_id, 1, false); + const PortId port_id1(other_context_id, 0, false, SerializationFormat::kJson); + const PortId port_id2(other_context_id, 1, false, SerializationFormat::kJson); gin::Handle<GinPort> port1 = messaging_service()->CreatePortForTesting( script_context(), "channel1", port_id1); @@ -205,8 +206,9 @@ GetStringPropertyFromObject(global, context, kPort2Message)); const char kMessageString[] = R"({"data":"hello"})"; - messaging_service()->DeliverMessage(script_context_set(), port_id1, - Message(kMessageString, false), nullptr); + messaging_service()->DeliverMessage( + script_context_set(), port_id1, + Message(kMessageString, SerializationFormat::kJson, false), nullptr); // Only port1 should have been notified of the message (ports only receive // messages directed to themselves). @@ -221,8 +223,8 @@ v8::Local<v8::Context> context = MainContext(); base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id1(other_context_id, 0, false); - const PortId port_id2(other_context_id, 1, false); + const PortId port_id1(other_context_id, 0, false, SerializationFormat::kJson); + const PortId port_id2(other_context_id, 1, false, SerializationFormat::kJson); gin::Handle<GinPort> port1 = messaging_service()->CreatePortForTesting( script_context(), "channel1", port_id1); @@ -274,7 +276,7 @@ v8::Local<v8::Context> context = MainContext(); base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id(other_context_id, 0, false); + const PortId port_id(other_context_id, 0, false, SerializationFormat::kJson); gin::Handle<GinPort> port = messaging_service()->CreatePortForTesting( script_context(), "channel", port_id); @@ -288,9 +290,10 @@ FunctionFromString(context, kDispatchMessage); v8::Local<v8::Value> args[] = {port_object}; - EXPECT_CALL( - *ipc_message_sender(), - SendPostMessageToPort(port_id, Message(R"({"data":"hello"})", false))); + EXPECT_CALL(*ipc_message_sender(), + SendPostMessageToPort( + port_id, Message(R"({"data":"hello"})", + SerializationFormat::kJson, false))); RunFunctionOnGlobal(post_message, context, base::size(args), args); ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender()); } @@ -300,7 +303,7 @@ v8::Local<v8::Context> context = MainContext(); base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id(other_context_id, 0, false); + const PortId port_id(other_context_id, 0, false, SerializationFormat::kJson); gin::Handle<GinPort> port = messaging_service()->CreatePortForTesting( script_context(), "channel", port_id); @@ -324,13 +327,14 @@ v8::HandleScope handle_scope(isolate()); const std::string kChannel = "channel"; - PortId expected_port_id(script_context()->context_id(), 0, true); + PortId expected_port_id(script_context()->context_id(), 0, true, + SerializationFormat::kJson); MessageTarget target(MessageTarget::ForExtension(extension()->id())); EXPECT_CALL(*ipc_message_sender(), SendOpenMessageChannel(script_context(), expected_port_id, target, kChannel)); - gin::Handle<GinPort> new_port = - messaging_service()->Connect(script_context(), target, "channel"); + gin::Handle<GinPort> new_port = messaging_service()->Connect( + script_context(), target, "channel", SerializationFormat::kJson); ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender()); ASSERT_FALSE(new_port.IsEmpty()); @@ -347,7 +351,8 @@ v8::Local<v8::Context> context = MainContext(); const std::string kChannel = "chrome.runtime.sendMessage"; - PortId port_id(script_context()->context_id(), 0, true); + PortId port_id(script_context()->context_id(), 0, true, + SerializationFormat::kJson); const char kEchoArgs[] = "(function() { this.replyArgs = Array.from(arguments); })"; v8::Local<v8::Function> response_callback = @@ -355,7 +360,7 @@ // Send a message and expect a reply. A new port should be created, and should // remain open (waiting for the response). - const Message message("\"hi\"", false); + const Message message("\"hi\"", SerializationFormat::kJson, false); MessageTarget target(MessageTarget::ForExtension(extension()->id())); EXPECT_CALL( *ipc_message_sender(), @@ -371,8 +376,9 @@ // port should be closed. EXPECT_CALL(*ipc_message_sender(), SendCloseMessagePort(MSG_ROUTING_NONE, port_id, true)); - messaging_service()->DeliverMessage(script_context_set(), port_id, - Message("\"reply\"", false), nullptr); + messaging_service()->DeliverMessage( + script_context_set(), port_id, + Message("\"reply\"", SerializationFormat::kJson, false), nullptr); ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender()); EXPECT_EQ("[\"reply\"]", GetStringPropertyFromObject(context->Global(), context, "replyArgs")); @@ -401,7 +407,7 @@ const std::string kChannel = "chrome.runtime.sendMessage"; base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id(other_context_id, 0, false); + const PortId port_id(other_context_id, 0, false, SerializationFormat::kJson); ExtensionMsg_TabConnectionInfo tab_connection_info; tab_connection_info.frame_id = 0; @@ -430,13 +436,15 @@ // Post the message to the receiver. The receiver should respond, and the // port should close. - EXPECT_CALL( - *ipc_message_sender(), - SendPostMessageToPort(port_id, Message(R"({"data":"hi"})", false))); + EXPECT_CALL(*ipc_message_sender(), + SendPostMessageToPort( + port_id, Message(R"({"data":"hi"})", + SerializationFormat::kJson, false))); EXPECT_CALL(*ipc_message_sender(), SendCloseMessagePort(MSG_ROUTING_NONE, port_id, true)); - messaging_service()->DeliverMessage(script_context_set(), port_id, - Message("\"message\"", false), nullptr); + messaging_service()->DeliverMessage( + script_context_set(), port_id, + Message("\"message\"", SerializationFormat::kJson, false), nullptr); ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender()); EXPECT_FALSE( messaging_service()->HasPortForTesting(script_context(), port_id)); @@ -466,9 +474,10 @@ base::UnguessableToken other_context_id = base::UnguessableToken::Create(); int next_port_id = 0; - const PortId on_message_port_id(other_context_id, ++next_port_id, false); + const PortId on_message_port_id(other_context_id, ++next_port_id, false, + SerializationFormat::kJson); const PortId on_message_external_port_id(other_context_id, ++next_port_id, - false); + false, SerializationFormat::kJson); auto open_port = [this](const PortId& port_id, const ExtensionId& source_id) { ExtensionMsg_TabConnectionInfo tab_connection_info; @@ -503,8 +512,9 @@ crx_file::id_util::GenerateId("different"); open_port(on_message_external_port_id, other_extension); - messaging_service()->DeliverMessage(script_context_set(), on_message_port_id, - Message("\"onMessage\"", false), nullptr); + messaging_service()->DeliverMessage( + script_context_set(), on_message_port_id, + Message("\"onMessage\"", SerializationFormat::kJson, false), nullptr); EXPECT_EQ("\"onMessage\"", GetStringPropertyFromObject(context->Global(), context, "onMessageReceived")); @@ -514,7 +524,8 @@ messaging_service()->DeliverMessage( script_context_set(), on_message_external_port_id, - Message("\"onMessageExternal\"", false), nullptr); + Message("\"onMessageExternal\"", SerializationFormat::kJson, false), + nullptr); EXPECT_EQ("\"onMessage\"", GetStringPropertyFromObject(context->Global(), context, "onMessageReceived"));
diff --git a/extensions/renderer/one_time_message_handler.cc b/extensions/renderer/one_time_message_handler.cc index 7bd539b7..0099b03 100644 --- a/extensions/renderer/one_time_message_handler.cc +++ b/extensions/renderer/one_time_message_handler.cc
@@ -283,11 +283,12 @@ OneTimeReceiver& port = iter->second; // This port is a receiver, so we invoke the onMessage event and provide a - // callback through which the port can respond. The port stays open until - // we receive a response. + // callback through which the port can respond. The port stays open until we + // receive a response. // TODO(devlin): With chrome.runtime.sendMessage, we actually require that a // listener return `true` if they intend to respond asynchronously; otherwise // we close the port. + auto callback = std::make_unique<OneTimeMessageCallback>( base::BindOnce(&OneTimeMessageHandler::OnOneTimeMessageResponse, weak_factory_.GetWeakPtr(), target_port_id)); @@ -471,8 +472,8 @@ value = v8::Undefined(isolate); std::string error; - std::unique_ptr<Message> message = - messaging_util::MessageFromV8(context, value, &error); + std::unique_ptr<Message> message = messaging_util::MessageFromV8( + context, value, port_id.serialization_format, &error); if (!message) { arguments->ThrowTypeError(error); return;
diff --git a/extensions/renderer/one_time_message_handler_unittest.cc b/extensions/renderer/one_time_message_handler_unittest.cc index 22ba5a5..1448081 100644 --- a/extensions/renderer/one_time_message_handler_unittest.cc +++ b/extensions/renderer/one_time_message_handler_unittest.cc
@@ -12,6 +12,7 @@ #include "base/strings/stringprintf.h" #include "extensions/common/api/messaging/message.h" #include "extensions/common/api/messaging/port_id.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" #include "extensions/renderer/bindings/api_binding_test_util.h" @@ -92,8 +93,9 @@ // Tests sending a message without expecting a reply, as in // chrome.runtime.sendMessage({foo: 'bar'}); TEST_F(OneTimeMessageHandlerTest, SendMessageAndDontExpectReply) { - const PortId port_id(script_context()->context_id(), 0, true); - const Message message("\"Hello\"", false); + const PortId port_id(script_context()->context_id(), 0, true, + SerializationFormat::kJson); + const Message message("\"Hello\"", SerializationFormat::kJson, false); // We should open a message port, send a message, and then close it // immediately. @@ -116,8 +118,9 @@ // Tests sending a message and expecting a reply, as in // chrome.runtime.sendMessage({foo: 'bar'}, function(reply) { ... }); TEST_F(OneTimeMessageHandlerTest, SendMessageAndExpectReply) { - const PortId port_id(script_context()->context_id(), 0, true); - const Message message("\"Hello\"", false); + const PortId port_id(script_context()->context_id(), 0, true, + SerializationFormat::kJson); + const Message message("\"Hello\"", SerializationFormat::kJson, false); v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = MainContext(); @@ -152,7 +155,7 @@ // Deliver the reply; the message port should close. EXPECT_CALL(*ipc_message_sender(), SendCloseMessagePort(MSG_ROUTING_NONE, port_id, true)); - const Message reply("\"Hi\"", false); + const Message reply("\"Hi\"", SerializationFormat::kJson, false); message_handler()->DeliverMessage(script_context(), reply, port_id); ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender()); EXPECT_FALSE(message_handler()->HasPort(script_context(), port_id)); @@ -166,8 +169,9 @@ // Tests disconnecting an opener (initiator of a sendMessage() call); this can // happen when no receiving end exists (i.e., no listener to runtime.onMessage). TEST_F(OneTimeMessageHandlerTest, DisconnectOpener) { - const PortId port_id(script_context()->context_id(), 0, true); - const Message message("\"Hello\"", false); + const PortId port_id(script_context()->context_id(), 0, true, + SerializationFormat::kJson); + const Message message("\"Hello\"", SerializationFormat::kJson, false); v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = MainContext(); @@ -221,7 +225,7 @@ EXPECT_EQ("undefined", GetGlobalProperty(context, "eventSender")); base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id(other_context_id, 0, false); + const PortId port_id(other_context_id, 0, false, SerializationFormat::kJson); EXPECT_FALSE(message_handler()->HasPort(script_context(), port_id)); v8::Local<v8::Object> sender = gin::DataObjectBuilder(isolate()) @@ -234,7 +238,7 @@ EXPECT_EQ("undefined", GetGlobalProperty(context, "eventMessage")); EXPECT_EQ("undefined", GetGlobalProperty(context, "eventSender")); - const Message message("\"Hi\"", false); + const Message message("\"Hi\"", SerializationFormat::kJson, false); message_handler()->DeliverMessage(script_context(), message, port_id); EXPECT_EQ("\"Hi\"", GetGlobalProperty(context, "eventMessage")); @@ -267,7 +271,7 @@ RunFunctionOnGlobal(add_listener, context, 0, nullptr); base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id(other_context_id, 0, false); + const PortId port_id(other_context_id, 0, false, SerializationFormat::kJson); EXPECT_FALSE(message_handler()->HasPort(script_context(), port_id)); v8::Local<v8::Object> sender = v8::Object::New(isolate()); @@ -275,13 +279,14 @@ messaging_util::kOnMessageEvent); EXPECT_TRUE(message_handler()->HasPort(script_context(), port_id)); - const Message message("\"Hi\"", false); + const Message message("\"Hi\"", SerializationFormat::kJson, false); // When the listener replies, we should post the reply to the message port and // close the channel. - EXPECT_CALL( - *ipc_message_sender(), - SendPostMessageToPort(port_id, Message(R"({"data":"hey"})", false))); + EXPECT_CALL(*ipc_message_sender(), + SendPostMessageToPort( + port_id, Message(R"({"data":"hey"})", + SerializationFormat::kJson, false))); EXPECT_CALL(*ipc_message_sender(), SendCloseMessagePort(MSG_ROUTING_NONE, port_id, true)); message_handler()->DeliverMessage(script_context(), message, port_id); @@ -308,12 +313,12 @@ RunFunctionOnGlobal(add_listener, context, 0, nullptr); base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id(other_context_id, 0, false); + const PortId port_id(other_context_id, 0, false, SerializationFormat::kJson); v8::Local<v8::Object> sender = v8::Object::New(isolate()); message_handler()->AddReceiver(script_context(), port_id, sender, messaging_util::kOnMessageEvent); - const Message message("\"Hi\"", false); + const Message message("\"Hi\"", SerializationFormat::kJson, false); message_handler()->DeliverMessage(script_context(), message, port_id); @@ -325,8 +330,10 @@ v8::Local<v8::Value> reply_arg = V8ValueFromScriptSource(context, "'hi'"); v8::Local<v8::Value> args[] = {reply_arg}; - EXPECT_CALL(*ipc_message_sender(), - SendPostMessageToPort(port_id, Message("\"hi\"", false))); + EXPECT_CALL( + *ipc_message_sender(), + SendPostMessageToPort( + port_id, Message("\"hi\"", SerializationFormat::kJson, false))); EXPECT_CALL(*ipc_message_sender(), SendCloseMessagePort(MSG_ROUTING_NONE, port_id, true)); RunFunction(reply.As<v8::Function>(), context, base::size(args), args); @@ -356,7 +363,8 @@ RunFunctionOnGlobal(add_listener, context, 0, nullptr); base::UnguessableToken sender_context_id = base::UnguessableToken::Create(); - const PortId original_port_id(sender_context_id, 0, false); + const PortId original_port_id(sender_context_id, 0, false, + SerializationFormat::kJson); v8::Local<v8::Object> sender = v8::Object::New(isolate()); message_handler()->AddReceiver(script_context(), original_port_id, sender, @@ -365,9 +373,10 @@ // On delivering the message, we expect the listener to open a new message // channel by using sendMessage(). The original message channel will be // closed. - const PortId listener_created_port_id(script_context()->context_id(), 0, - true); - const Message listener_sent_message("\"foo\"", false); + const PortId listener_created_port_id(script_context()->context_id(), 0, true, + SerializationFormat::kJson); + const Message listener_sent_message("\"foo\"", SerializationFormat::kJson, + false); MessageTarget target(MessageTarget::ForExtension(extension()->id())); EXPECT_CALL( *ipc_message_sender(), @@ -379,7 +388,7 @@ EXPECT_CALL(*ipc_message_sender(), SendCloseMessagePort(MSG_ROUTING_NONE, original_port_id, false)); - const Message message("\"Hi\"", false); + const Message message("\"Hi\"", SerializationFormat::kJson, false); message_handler()->DeliverMessage(script_context(), message, original_port_id); ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender()); @@ -403,8 +412,9 @@ // Running the function should send one message ('foo'), which will wait for // a reply. - const PortId original_port_id(script_context()->context_id(), 0, true); - const Message original_message("\"foo\"", false); + const PortId original_port_id(script_context()->context_id(), 0, true, + SerializationFormat::kJson); + const Message original_message("\"foo\"", SerializationFormat::kJson, false); MessageTarget target(MessageTarget::ForExtension(extension()->id())); EXPECT_CALL(*ipc_message_sender(), SendOpenMessageChannel(script_context(), original_port_id, target, @@ -416,15 +426,18 @@ // Upon delivering the reply to the sender, it should send a second message // ('bar'). The original message channel should be closed. - const PortId new_port_id(script_context()->context_id(), 1, true); + const PortId new_port_id(script_context()->context_id(), 1, true, + SerializationFormat::kJson); EXPECT_CALL(*ipc_message_sender(), SendOpenMessageChannel(script_context(), new_port_id, target, messaging_util::kSendMessageChannel)); - EXPECT_CALL(*ipc_message_sender(), - SendPostMessageToPort(new_port_id, Message("\"bar\"", false))); + EXPECT_CALL( + *ipc_message_sender(), + SendPostMessageToPort( + new_port_id, Message("\"bar\"", SerializationFormat::kJson, false))); EXPECT_CALL(*ipc_message_sender(), SendCloseMessagePort(MSG_ROUTING_NONE, original_port_id, true)); - const Message reply("\"reply\"", false); + const Message reply("\"reply\"", SerializationFormat::kJson, false); message_handler()->DeliverMessage(script_context(), reply, original_port_id); ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender()); } @@ -445,12 +458,12 @@ RunFunctionOnGlobal(add_listener, context, 0, nullptr); base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id(other_context_id, 0, false); + const PortId port_id(other_context_id, 0, false, SerializationFormat::kJson); v8::Local<v8::Object> sender = v8::Object::New(isolate()); message_handler()->AddReceiver(script_context(), port_id, sender, messaging_util::kOnMessageEvent); - const Message message("\"Hi\"", false); + const Message message("\"Hi\"", SerializationFormat::kJson, false); EXPECT_CALL(*ipc_message_sender(), SendCloseMessagePort(MSG_ROUTING_NONE, port_id, false)); @@ -489,7 +502,7 @@ "function(message, reply, sender) { throw new Error('hi!'); }"); base::UnguessableToken other_context_id = base::UnguessableToken::Create(); - const PortId port_id(other_context_id, 0, false); + const PortId port_id(other_context_id, 0, false, SerializationFormat::kJson); v8::Local<v8::Object> sender = v8::Object::New(isolate()); message_handler()->AddReceiver(script_context(), port_id, sender, @@ -500,7 +513,7 @@ // Dispatch the message. Since none of these listeners return `true`, the port // should close. - const Message message("\"Hi\"", false); + const Message message("\"Hi\"", SerializationFormat::kJson, false); EXPECT_CALL(*ipc_message_sender(), SendCloseMessagePort(MSG_ROUTING_NONE, port_id, false)); message_handler()->DeliverMessage(script_context(), message, port_id);
diff --git a/extensions/renderer/runtime_hooks_delegate.cc b/extensions/renderer/runtime_hooks_delegate.cc index b75d29e..da108c6 100644 --- a/extensions/renderer/runtime_hooks_delegate.cc +++ b/extensions/renderer/runtime_hooks_delegate.cc
@@ -11,6 +11,7 @@ #include "content/public/renderer/render_frame.h" #include "content/public/renderer/v8_value_converter.h" #include "extensions/common/api/messaging/message.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" #include "extensions/common/manifest.h" @@ -223,8 +224,9 @@ v8::Local<v8::Context> v8_context = script_context->v8_context(); v8::Local<v8::Value> v8_message = arguments[1]; - std::unique_ptr<Message> message = - messaging_util::MessageFromV8(v8_context, v8_message, &error); + std::unique_ptr<Message> message = messaging_util::MessageFromV8( + v8_context, v8_message, + messaging_util::GetSerializationFormat(*script_context), &error); if (!message) { RequestResult result(RequestResult::INVALID_INVOCATION); result.error = std::move(error); @@ -258,8 +260,12 @@ v8::Local<v8::Value> v8_message = arguments[1]; DCHECK(!v8_message.IsEmpty()); std::string error; - std::unique_ptr<Message> message = messaging_util::MessageFromV8( - script_context->v8_context(), v8_message, &error); + + // Native messaging always uses JSON since a native host doesn't understand + // structured cloning serialization. + std::unique_ptr<Message> message = + messaging_util::MessageFromV8(script_context->v8_context(), v8_message, + SerializationFormat::kJson, &error); if (!message) { RequestResult result(RequestResult::INVALID_INVOCATION); result.error = std::move(error); @@ -301,7 +307,8 @@ gin::Handle<GinPort> port = messaging_service_->Connect( script_context, MessageTarget::ForExtension(target_id), - options.channel_name); + options.channel_name, + messaging_util::GetSerializationFormat(*script_context)); DCHECK(!port.IsEmpty()); RequestResult result(RequestResult::HANDLED); @@ -317,9 +324,13 @@ std::string application_name = gin::V8ToString(script_context->isolate(), arguments[0]); + + // Native messaging always uses JSON since a native host doesn't understand + // structured cloning serialization. + auto format = SerializationFormat::kJson; gin::Handle<GinPort> port = messaging_service_->Connect( script_context, MessageTarget::ForNativeApp(application_name), - std::string()); + std::string(), format); RequestResult result(RequestResult::HANDLED); result.return_value = port.ToV8();
diff --git a/extensions/renderer/runtime_hooks_delegate_unittest.cc b/extensions/renderer/runtime_hooks_delegate_unittest.cc index 66780e9..3ab4e84f 100644 --- a/extensions/renderer/runtime_hooks_delegate_unittest.cc +++ b/extensions/renderer/runtime_hooks_delegate_unittest.cc
@@ -9,6 +9,7 @@ #include "base/strings/stringprintf.h" #include "components/crx_file/id_util.h" #include "content/public/common/child_process_host.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" #include "extensions/common/extension_messages.h" @@ -367,7 +368,8 @@ constexpr char kAddPortTemplate[] = "(function() { return chrome.runtime.connectNative(%s); })"; PortId expected_port_id(script_context()->context_id(), - next_context_port_id++, true); + next_context_port_id++, true, + SerializationFormat::kJson); MessageTarget expected_target( MessageTarget::ForNativeApp(expected_app_name)); EXPECT_CALL(*ipc_message_sender(), @@ -415,13 +417,14 @@ "(function() { chrome.runtime.sendNativeMessage(%s); })"; PortId expected_port_id(script_context()->context_id(), - next_context_port_id++, true); + next_context_port_id++, true, + SerializationFormat::kJson); MessageTarget expected_target( MessageTarget::ForNativeApp(expected_application_name)); EXPECT_CALL(*ipc_message_sender(), SendOpenMessageChannel(script_context(), expected_port_id, expected_target, kEmptyExpectedChannel)); - Message message(expected_message, false); + Message message(expected_message, SerializationFormat::kJson, false); EXPECT_CALL(*ipc_message_sender(), SendPostMessageToPort(expected_port_id, message)); // Note: we don't close native message ports immediately. See comment in
diff --git a/extensions/renderer/send_message_tester.cc b/extensions/renderer/send_message_tester.cc index 1732ea4..0a943e5 100644 --- a/extensions/renderer/send_message_tester.cc +++ b/extensions/renderer/send_message_tester.cc
@@ -5,6 +5,7 @@ #include "extensions/renderer/send_message_tester.h" #include "base/strings/stringprintf.h" +#include "extensions/common/api/messaging/serialization_format.h" #include "extensions/renderer/bindings/api_binding_test_util.h" #include "extensions/renderer/messaging_util.h" #include "extensions/renderer/native_extension_bindings_system_test_base.h" @@ -54,7 +55,8 @@ constexpr char kAddPortTemplate[] = "(function() { return chrome.%s.connect(%s); })"; - PortId expected_port_id(script_context_->context_id(), next_port_id_++, true); + PortId expected_port_id(script_context_->context_id(), next_port_id_++, true, + SerializationFormat::kJson); EXPECT_CALL(*ipc_sender_, SendOpenMessageChannel(script_context_, expected_port_id, expected_target, expected_channel)); @@ -91,12 +93,13 @@ break; } - PortId expected_port_id(script_context_->context_id(), next_port_id_++, true); + PortId expected_port_id(script_context_->context_id(), next_port_id_++, true, + SerializationFormat::kJson); EXPECT_CALL(*ipc_sender_, SendOpenMessageChannel(script_context_, expected_port_id, expected_target, expected_channel)); - Message message(expected_message, false); + Message message(expected_message, SerializationFormat::kJson, false); EXPECT_CALL(*ipc_sender_, SendPostMessageToPort(expected_port_id, message)); if (expected_port_status == CLOSED) {
diff --git a/infra/archive_config/win32-archive-rel.json b/infra/archive_config/win32-archive-rel.json new file mode 100644 index 0000000..92212f2 --- /dev/null +++ b/infra/archive_config/win32-archive-rel.json
@@ -0,0 +1,158 @@ +{ + "archive_datas": [ + { + "files": [ + "chrome.exe", + "chrome.dll", + "chrome_100_percent.pak", + "chrome_200_percent.pak", + "chrome_elf.dll", + "chrome_proxy.exe", + "chrome_pwa_launcher.exe", + "D3DCompiler_47.dll", + "elevation_service.exe", + "eventlog_provider.dll", + "First Run", + "icudtl.dat", + "interactive_ui_tests.exe", + "libEGL.dll", + "libGLESv2.dll", + "MEIPreload\\manifest.json", + "MEIPreload\\preloaded_data.pb", + "mojo_core.dll", + "nacl64.exe", + "nacl_irt_x86_32.nexe", + "nacl_irt_x86_64.nexe", + "notification_helper.exe", + "resources.pak", + "swiftshader\\libEGL.dll", + "swiftshader\\libGLESv2.dll", + "v8_context_snapshot.bin", + "vk_swiftshader.dll", + "vk_swiftshader_icd.json", + "vulkan-1.dll" + ], + "file_globs": ["*.manifest"], + "dirs": ["locales"], + "gcs_bucket": "chromium-browser-snapshots", + "gcs_path": "experimental/Win/{%position%}/chrome-win.zip", + "archive_type": "ARCHIVE_TYPE_ZIP" + }, + { + "files": [ + "chrome.dll.pdb", + "chrome.exe.pdb", + "chrome_elf.dll.pdb", + "chrome_proxy.exe.pdb", + "chrome_pwa_launcher.exe.pdb", + "elevation_service.exe.pdb", + "eventlog_provider.dll.pdb", + "gaia1_0.dll.pdb", + "gcapi_dll.dll.pdb", + "gcp_setup.exe.pdb", + "libEGL.dll.pdb", + "libGLESv2.dll.pdb", + "mini_installer.exe.pdb", + "mojo_core.dll.pdb", + "nacl64.exe.pdb", + "notification_helper.exe.pdb", + "setup.exe.pdb", + "swiftshader\\libEGL.dll.pdb", + "swiftshader\\libGLESv2.dll.pdb", + "vk_swiftshader.dll.pdb", + "vulkan-1.dll.pdb" + ], + "gcs_bucket": "chromium-browser-snapshots", + "gcs_path": "experimental/Win/{%position%}/chrome-win32-syms.zip", + "archive_type": "ARCHIVE_TYPE_ZIP" + }, + { + "files": [ + "chromedriver.exe.pdb" + ], + "gcs_bucket": "chromium-browser-snapshots", + "gcs_path": "experimental/Win/{%position%}/chromedriver_win32-syms.zip", + "archive_type": "ARCHIVE_TYPE_ZIP" + }, + { + "files": [ + "chromedriver.exe" + ], + "gcs_bucket": "chromium-browser-snapshots", + "gcs_path": "experimental/Win/{%position%}/chromedriver_win32.zip", + "archive_type": "ARCHIVE_TYPE_ZIP" + }, + { + "files": [ + "blink_deprecated_test_plugin.dll", + "blink_test_plugin.dll", + "content_shell.exe", + "content_shell.pak", + "icudtl.dat", + "v8_context_snapshot.bin" + ], + "dirs": ["resources"], + "gcs_bucket": "chromium-browser-snapshots", + "gcs_path": "experimental/Win/{%position%}/content-shell.zip", + "archive_type": "ARCHIVE_TYPE_ZIP" + }, + { + "dirs": ["gen\\third_party\\devtools-frontend\\src\\front_end"], + "gcs_bucket": "chromium-browser-snapshots", + "gcs_path": "experimental/Win/{%position%}/devtools-frontend.zip", + "archive_type": "ARCHIVE_TYPE_ZIP" + }, + { + "files": [ + "gcapi.h", + "gcapi_dll.dll", + "gcapi_dll.dll.lib" + ], + "gcs_bucket": "chromium-browser-snapshots", + "gcs_path": "experimental/Win/{%position%}/gcapi.zip", + "archive_type": "ARCHIVE_TYPE_ZIP" + }, + { + "files": [ + "actions.xml", + "histograms.xml", + "ukm.xml" + ], + "gcs_bucket": "chromium-browser-snapshots", + "gcs_path": "experimental/Win/{%position%}/metrics-metadata.zip", + "archive_type": "ARCHIVE_TYPE_ZIP" + }, + { + "files": [ + "mini_installer.exe" + ], + "gcs_bucket": "chromium-browser-snapshots", + "gcs_path": "experimental/Win/{%position%}", + "archive_type": "ARCHIVE_TYPE_FILES" + }, + { + "dirs": ["pnacl"], + "gcs_bucket": "chromium-browser-snapshots", + "gcs_path": "experimental/Win/{%position%}/pnacl.zip", + "archive_type": "ARCHIVE_TYPE_ZIP" + }, + { + "files": [ + "remoting-me2me-host-win.zip" + ], + "gcs_bucket": "chromium-browser-snapshots", + "gcs_path": "experimental/Win/{%position%}", + "archive_type": "ARCHIVE_TYPE_FILES" + }, + { + "files": [ + "updater.exe", + "UpdaterSetup.exe" + ], + "dirs": ["UpdaterSigning"], + "gcs_bucket": "chromium-browser-snapshots", + "gcs_path": "experimental/Win/{%position%}/updater.zip", + "archive_type": "ARCHIVE_TYPE_ZIP" + } + ] +} \ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/UBSan vptr Release \050reclient shadow\051/properties.textpb" "b/infra/config/generated/builders/ci/UBSan vptr Release \050reclient shadow\051/properties.textpb" new file mode 100644 index 0000000..989e5cbf --- /dev/null +++ "b/infra/config/generated/builders/ci/UBSan vptr Release \050reclient shadow\051/properties.textpb"
@@ -0,0 +1,20 @@ +{ + "$build/reclient": { + "instance": "rbe-chromium-trusted", + "jobs": 250, + "metrics_project": "chromium-reclient-metrics" + }, + "$kitchen": { + "devshell": true, + "emulate_gce": true, + "git_auth": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "recipe": "chromium" +} \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/win32-archive-rel/properties.textpb b/infra/config/generated/builders/ci/win32-archive-rel/properties.textpb index d85f8fe78..e5d1a1d 100644 --- a/infra/config/generated/builders/ci/win32-archive-rel/properties.textpb +++ b/infra/config/generated/builders/ci/win32-archive-rel/properties.textpb
@@ -1,4 +1,12 @@ { + "$build/archive": { + "source_side_spec_path": [ + "src", + "infra", + "archive_config", + "win32-archive-rel.json" + ] + }, "$build/goma": { "enable_ats": true, "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/try/linux-headless-shell-rel/properties.textpb b/infra/config/generated/builders/try/linux-headless-shell-rel/properties.textpb new file mode 100644 index 0000000..8f6e9de --- /dev/null +++ b/infra/config/generated/builders/try/linux-headless-shell-rel/properties.textpb
@@ -0,0 +1,20 @@ +{ + "$build/goma": { + "enable_ats": true, + "rpc_extra_params": "?prod", + "server_host": "goma.chromium.org", + "use_luci_auth": true + }, + "$kitchen": { + "devshell": true, + "git_auth": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "recipe": "chromium_trybot" +} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/win10-rel-orchestrator/properties.textpb b/infra/config/generated/builders/try/win10-rel-orchestrator/properties.textpb index 6f28b25..d41a371 100644 --- a/infra/config/generated/builders/try/win10-rel-orchestrator/properties.textpb +++ b/infra/config/generated/builders/try/win10-rel-orchestrator/properties.textpb
@@ -1,6 +1,6 @@ { "$build/chromium_orchestrator": { - "compilator": "win10-rel-compilator", + "compilator": "win10_chromium_x64_rel_ng-compilator", "compilator_watcher_git_revision": "d5bee0e7798a40c3c6261c3dbc14becf1fbb693f" }, "$build/code_coverage": {
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index 3a0281b..47e2b8e0 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -1229,6 +1229,10 @@ includable_only: true } builders { + name: "chromium/try/linux-headless-shell-rel" + includable_only: true + } + builders { name: "chromium/try/linux-inverse-fieldtrials-fyi-rel" includable_only: true } @@ -1837,6 +1841,10 @@ location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { + name: "chromium/try/win10_chromium_x64_rel_ng-compilator" + includable_only: true + } + builders { name: "chromium/try/win10_chromium_x64_rel_ng_exp" includable_only: true }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index a81191c..f60853f 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -21927,6 +21927,91 @@ } } builders { + name: "UBSan vptr Release (reclient shadow)" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/main" + cmd: "luciexe" + } + properties: + '{' + ' "$build/reclient": {' + ' "instance": "rbe-chromium-trusted",' + ' "jobs": 250,' + ' "metrics_project": "chromium-reclient-metrics"' + ' },' + ' "$kitchen": {' + ' "devshell": true,' + ' "emulate_gce": true,' + ' "git_auth": true' + ' },' + ' "$recipe_engine/resultdb/test_presentation": {' + ' "column_keys": [],' + ' "grouping_keys": [' + ' "status",' + ' "v.test_suite"' + ' ]' + ' },' + ' "builder_group": "chromium.fyi",' + ' "recipe": "chromium"' + '}' + execution_timeout_secs: 36000 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "chromium.chromium_tests.use_gitiles_trigger" + value: 100 + } + experiments { + key: "chromium.chromium_tests.use_rdb_results" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "VR Linux" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -47026,6 +47111,14 @@ } properties: '{' + ' "$build/archive": {' + ' "source_side_spec_path": [' + ' "src",' + ' "infra",' + ' "archive_config",' + ' "win32-archive-rel.json"' + ' ]' + ' },' ' "$build/goma": {' ' "enable_ats": true,' ' "rpc_extra_params": "?prod",' @@ -70229,6 +70322,98 @@ } } builders { + name: "linux-headless-shell-rel" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/main" + cmd: "luciexe" + } + properties: + '{' + ' "$build/goma": {' + ' "enable_ats": true,' + ' "rpc_extra_params": "?prod",' + ' "server_host": "goma.chromium.org",' + ' "use_luci_auth": true' + ' },' + ' "$kitchen": {' + ' "devshell": true,' + ' "git_auth": true' + ' },' + ' "$recipe_engine/resultdb/test_presentation": {' + ' "column_keys": [],' + ' "grouping_keys": [' + ' "status",' + ' "v.test_suite"' + ' ]' + ' },' + ' "builder_group": "tryserver.chromium.linux",' + ' "recipe": "chromium_trybot"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium.chromium_tests.use_rdb_results" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "linux-inverse-fieldtrials-fyi-rel" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -80782,7 +80967,7 @@ properties: '{' ' "$build/chromium_orchestrator": {' - ' "compilator": "win10-rel-compilator",' + ' "compilator": "win10_chromium_x64_rel_ng-compilator",' ' "compilator_watcher_git_revision": "d5bee0e7798a40c3c6261c3dbc14becf1fbb693f"' ' },' ' "$build/code_coverage": {' @@ -81342,6 +81527,109 @@ } } builders { + name: "win10_chromium_x64_rel_ng-compilator" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "cores:32" + dimensions: "cpu:x86-64" + dimensions: "os:Windows-10" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:1" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/main" + cmd: "luciexe" + } + properties: + '{' + ' "$build/code_coverage": {' + ' "coverage_test_types": [' + ' "unit",' + ' "overall"' + ' ],' + ' "use_clang_coverage": true' + ' },' + ' "$build/goma": {' + ' "enable_ats": false,' + ' "jobs": 300,' + ' "rpc_extra_params": "?prod",' + ' "server_host": "goma.chromium.org",' + ' "use_luci_auth": true' + ' },' + ' "$kitchen": {' + ' "devshell": true,' + ' "git_auth": true' + ' },' + ' "$recipe_engine/resultdb/test_presentation": {' + ' "column_keys": [],' + ' "grouping_keys": [' + ' "status",' + ' "v.test_suite"' + ' ]' + ' },' + ' "builder_group": "tryserver.chromium.win",' + ' "orchestrator": {' + ' "builder_group": "tryserver.chromium.win",' + ' "builder_name": "win10_chromium_x64_rel_ng"' + ' },' + ' "recipe": "chromium/compilator"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium.chromium_tests.use_rdb_results" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "win10_chromium_x64_rel_ng_exp" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index b4776df..45f3ebd 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -6616,6 +6616,11 @@ short_name: "rel" } builders { + name: "buildbucket/luci.chromium.ci/UBSan vptr Release (reclient shadow)" + category: "linux UBSan" + short_name: "vpt" + } + builders { name: "buildbucket/luci.chromium.ci/ASAN Debug (reclient)" category: "linux asan" short_name: "dbg" @@ -14750,6 +14755,9 @@ name: "buildbucket/luci.chromium.try/linux-gcc-rel" } builders { + name: "buildbucket/luci.chromium.try/linux-headless-shell-rel" + } + builders { name: "buildbucket/luci.chromium.try/linux-inverse-fieldtrials-fyi-rel" } builders { @@ -15113,6 +15121,9 @@ name: "buildbucket/luci.chromium.try/win10_chromium_x64_rel_ng" } builders { + name: "buildbucket/luci.chromium.try/win10_chromium_x64_rel_ng-compilator" + } + builders { name: "buildbucket/luci.chromium.try/win10_chromium_x64_rel_ng_exp" } builders { @@ -15775,6 +15786,9 @@ name: "buildbucket/luci.chromium.try/linux-gcc-rel" } builders { + name: "buildbucket/luci.chromium.try/linux-headless-shell-rel" + } + builders { name: "buildbucket/luci.chromium.try/linux-inverse-fieldtrials-fyi-rel" } builders { @@ -16225,6 +16239,9 @@ name: "buildbucket/luci.chromium.try/win10_chromium_x64_rel_ng" } builders { + name: "buildbucket/luci.chromium.try/win10_chromium_x64_rel_ng-compilator" + } + builders { name: "buildbucket/luci.chromium.try/win10_chromium_x64_rel_ng_exp" } builders {
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg index 28afa9b..c0d88904 100644 --- a/infra/config/generated/luci/luci-scheduler.cfg +++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -3324,6 +3324,20 @@ } } job { + id: "UBSan vptr Release (reclient shadow)" + realm: "ci" + acl_sets: "ci" + triggering_policy { + kind: GREEDY_BATCHING + max_concurrent_invocations: 4 + } + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "UBSan vptr Release (reclient shadow)" + } +} +job { id: "VR Linux" realm: "ci" acl_sets: "ci" @@ -7445,6 +7459,7 @@ triggers: "UBSan Release" triggers: "UBSan Release (reclient)" triggers: "UBSan vptr Release" + triggers: "UBSan vptr Release (reclient shadow)" triggers: "VR Linux" triggers: "VR Linux (reclient)" triggers: "WebKit Linux ASAN"
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index c651d024..77b154c 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -1884,6 +1884,17 @@ cores = 32, main_console_view = "main", os = os.WINDOWS_DEFAULT, + properties = { + # The format of these properties is defined at archive/properties.proto + "$build/archive": { + "source_side_spec_path": [ + "src", + "infra", + "archive_config", + "win32-archive-rel.json", + ], + }, + }, ) ci.chromium_builder( @@ -4387,6 +4398,22 @@ ) ci.fyi_builder( + name = "UBSan vptr Release (reclient shadow)", + console_view_entry = consoles.console_view_entry( + category = "linux UBSan", + short_name = "vpt", + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 4, + ), + goma_backend = None, + reclient_jobs = 250, + reclient_instance = rbe_instance.DEFAULT, + configure_kitchen = True, + kitchen_emulate_gce = True, +) + +ci.fyi_builder( name = "VR Linux (reclient)", console_view_entry = consoles.console_view_entry( category = "linux",
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index 4a0e03d..c142701 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -1261,6 +1261,10 @@ ) try_.chromium_linux_builder( + name = "linux-headless-shell-rel", +) + +try_.chromium_linux_builder( name = "linux-inverse-fieldtrials-fyi-rel", ) @@ -1974,7 +1978,7 @@ coverage_test_types = ["unit", "overall"], properties = { "$build/chromium_orchestrator": { - "compilator": "win10-rel-compilator", + "compilator": "win10_chromium_x64_rel_ng-compilator", "compilator_watcher_git_revision": compilator_watcher_git_revision, }, }, @@ -2003,6 +2007,24 @@ ) try_.chromium_win_builder( + name = "win10_chromium_x64_rel_ng-compilator", + builderless = None, + os = os.WINDOWS_10, + cores = 32, + ssd = True, + goma_jobs = goma.jobs.J300, + executable = "recipe:chromium/compilator", + use_clang_coverage = True, + coverage_test_types = ["unit", "overall"], + properties = { + "orchestrator": { + "builder_name": "win10_chromium_x64_rel_ng", + "builder_group": "tryserver.chromium.win", + }, + }, +) + +try_.chromium_win_builder( name = "win10_chromium_x64_rel_ng_exp", builderless = False, os = os.WINDOWS_ANY,
diff --git a/ios/chrome/browser/ui/settings/bandwidth_management_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/bandwidth_management_table_view_controller_unittest.mm index d45a8989..445567bd 100644 --- a/ios/chrome/browser/ui/settings/bandwidth_management_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/bandwidth_management_table_view_controller_unittest.mm
@@ -23,7 +23,6 @@ #include "ios/chrome/test/ios_chrome_scoped_testing_local_state.h" #include "ios/chrome/test/testing_application_context.h" #include "ios/web/public/test/web_task_environment.h" -#include "net/log/test_net_log.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" @@ -66,7 +65,6 @@ } web::WebTaskEnvironment task_environment_; - net::RecordingTestNetLog net_log_; IOSChromeScopedTestingLocalState local_state_; std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
diff --git a/ios/chrome/browser/ui/settings/password/password_details/add_password_mediator.mm b/ios/chrome/browser/ui/settings/password/password_details/add_password_mediator.mm index 9c1237a..8c68b17 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/add_password_mediator.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/add_password_mediator.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/ui/settings/password/password_details/add_password_mediator.h" #include "base/bind.h" +#include "base/ranges/algorithm.h" #include "base/strings/sys_string_conversions.h" #include "base/task/cancelable_task_tracker.h" #include "base/task/post_task.h" @@ -24,26 +25,28 @@ #error "This file requires ARC support." #endif +using base::SysNSStringToUTF8; using base::SysNSStringToUTF16; using base::SysUTF8ToNSString; namespace { -// Checks for existing credentials with the same website and username. +// Checks for existing credentials with the same url and username. bool CheckForDuplicates( - NSString* website, + GURL url, NSString* username, const password_manager::SavedPasswordsPresenter::SavedPasswordsView& credentials) { - GURL gurl = net::GURLWithNSURL([NSURL URLWithString:website]); std::string signon_realm = password_manager::GetSignonRealm( - password_manager_util::StripAuthAndParams(gurl)); + password_manager_util::StripAuthAndParams(url)); std::u16string username_value = SysNSStringToUTF16(username); - for (const auto& form : credentials) { - if (form.signon_realm == signon_realm && - form.username_value == username_value) { - return true; - } - } + auto have_equal_username_and_realm = + [&signon_realm, + &username_value](const password_manager::PasswordForm& form) { + return signon_realm == form.signon_realm && + username_value == form.username_value; + }; + if (base::ranges::any_of(credentials, have_equal_username_and_realm)) + return true; return false; } } @@ -68,6 +71,9 @@ @property(nonatomic, assign) scoped_refptr<base::SequencedTaskRunner> sequencedTaskRunner; +// Stores the url entered in the website field. +@property(nonatomic, assign) GURL URL; + @end @implementation AddPasswordMediator @@ -106,14 +112,12 @@ - (void)passwordDetailsViewController: (PasswordDetailsTableViewController*)viewController - didAddPasswordDetailsWithSite:(NSString*)website - username:(NSString*)username + didAddPasswordDetails:(NSString*)username password:(NSString*)password { password_manager::PasswordForm passwordForm; - GURL gurl = net::GURLWithNSURL([NSURL URLWithString:website]); - DCHECK(gurl.is_valid()); + DCHECK([self isURLValid]); - passwordForm.url = password_manager_util::StripAuthAndParams(gurl); + passwordForm.url = self.URL; passwordForm.signon_realm = password_manager::GetSignonRealm(passwordForm.url); passwordForm.username_value = SysNSStringToUTF16(username); @@ -126,24 +130,29 @@ [self.delegate dismissPasswordDetailsTableViewController]; } -- (void)checkForDuplicatesWithSite:(NSString*)website - username:(NSString*)username { +- (void)checkForDuplicates:(NSString*)username { _validationTaskTracker->TryCancelAll(); + if (![self isURLValid]) { + return; + } + __weak __typeof(self) weakSelf = self; _validationTaskTracker->PostTaskAndReplyWithResult( _sequencedTaskRunner.get(), FROM_HERE, - base::BindOnce(&CheckForDuplicates, website, username, + base::BindOnce(&CheckForDuplicates, self.URL, username, _manager->GetAllCredentials()), base::BindOnce(^(bool duplicateFound) { [weakSelf.consumer onDuplicateCheckCompletion:duplicateFound]; })); } -- (void)showExistingCredentialWithSite:(NSString*)website - username:(NSString*)username { - GURL gurl = net::GURLWithNSURL([NSURL URLWithString:website]); +- (void)showExistingCredential:(NSString*)username { + if (![self isURLValid]) { + return; + } + std::string signon_realm = password_manager::GetSignonRealm( - password_manager_util::StripAuthAndParams(gurl)); + password_manager_util::StripAuthAndParams(self.URL)); std::u16string username_value = SysNSStringToUTF16(username); for (const auto& form : _manager->GetAllCredentials()) { if (form.signon_realm == signon_realm && @@ -159,6 +168,15 @@ [self.delegate dismissPasswordDetailsTableViewController]; } +- (void)setWebsiteURL:(NSString*)website { + self.URL = password_manager_util::ConstructGURLWithScheme( + SysNSStringToUTF8(website)); +} + +- (BOOL)isURLValid { + return self.URL.is_valid() && self.URL.SchemeIsHTTPOrHTTPS(); +} + - (BOOL)isUsernameReused:(NSString*)newUsername { return NO; }
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm index 23da21d..0c6676c 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
@@ -90,19 +90,16 @@ - (void)passwordDetailsViewController: (PasswordDetailsTableViewController*)viewController - didAddPasswordDetailsWithSite:(NSString*)website - username:(NSString*)username + didAddPasswordDetails:(NSString*)username password:(NSString*)password { NOTREACHED(); } -- (void)checkForDuplicatesWithSite:(NSString*)website - username:(NSString*)username { +- (void)checkForDuplicates:(NSString*)username { NOTREACHED(); } -- (void)showExistingCredentialWithSite:(NSString*)website - username:(NSString*)username { +- (void)showExistingCredential:(NSString*)username { NOTREACHED(); } @@ -110,6 +107,14 @@ NOTREACHED(); } +- (void)setWebsiteURL:(NSString*)website { + NOTREACHED(); +} + +- (BOOL)isURLValid { + return YES; +} + - (BOOL)isUsernameReused:(NSString*)newUsername { // It is more efficient to check set of the usernames for the same origin // instead of delegating this to the |_manager|.
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 711265a..2d8c563d 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
@@ -635,7 +635,7 @@ - (void)onDuplicateCheckCompletion:(BOOL)duplicateFound { self.navigationItem.rightBarButtonItem.enabled = - !duplicateFound && self.shouldEnableSave; + !duplicateFound && self.shouldEnableSave && [self.delegate isURLValid]; if (duplicateFound == self.isDuplicatedCredential) { return; } @@ -691,18 +691,21 @@ } - (void)tableViewItemDidChange:(TableViewTextEditItem*)tableViewItem { - // TODO(crbug.com/1226006): Add validations for the site. - if (self.credentialType == CredentialTypeNew) { - [self.delegate - checkForDuplicatesWithSite:self.websiteTextItem.textFieldValue - username:self.usernameTextItem.textFieldValue]; + if (tableViewItem == self.websiteTextItem && + self.credentialType == CredentialTypeNew) { + [self.delegate setWebsiteURL:self.websiteTextItem.textFieldValue]; } self.shouldEnableSave = [self checkIfValidSite] & [self checkIfValidUsername] & [self checkIfValidPassword]; self.navigationItem.rightBarButtonItem.enabled = - !self.isDuplicatedCredential && self.shouldEnableSave; + !self.isDuplicatedCredential && self.shouldEnableSave && + [self.delegate isURLValid]; + + if (self.credentialType == CredentialTypeNew) { + [self.delegate checkForDuplicates:self.usernameTextItem.textFieldValue]; + } } - (void)tableViewItemDidEndEditing:(TableViewTextEditItem*)tableViewItem { @@ -728,8 +731,7 @@ - (void)didTapSaveButton:(id)sender { [self.delegate passwordDetailsViewController:self - didAddPasswordDetailsWithSite:self.websiteTextItem.textFieldValue - username:self.usernameTextItem.textFieldValue + didAddPasswordDetails:self.usernameTextItem.textFieldValue password:self.passwordTextItem.textFieldValue]; } @@ -954,10 +956,8 @@ } [strongSelf.delegate - showExistingCredentialWithSite:strongSelf.websiteTextItem - .textFieldValue - username:strongSelf.usernameTextItem - .textFieldValue]; + showExistingCredential:strongSelf.usernameTextItem + .textFieldValue]; }; // TODO(crbug.com/1226006): Use i18n string.
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_delegate.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_delegate.h index 203358a..89dc0103 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_delegate.h +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_delegate.h
@@ -18,23 +18,26 @@ // Called when user finished adding a new password credential. - (void)passwordDetailsViewController: (PasswordDetailsTableViewController*)viewController - didAddPasswordDetailsWithSite:(NSString*)website - username:(NSString*)username + didAddPasswordDetails:(NSString*)username password:(NSString*)password; // Called on every keystroke to check whether duplicates exist before adding a // new credential. -- (void)checkForDuplicatesWithSite:(NSString*)website - username:(NSString*)username; +- (void)checkForDuplicates:(NSString*)username; // Called when an existing credential is to be displayed in the add credential // flow. -- (void)showExistingCredentialWithSite:(NSString*)website - username:(NSString*)username; +- (void)showExistingCredential:(NSString*)username; // Called when the user cancels the add password view. - (void)didCancelAddPasswordDetails; +// Called every time the text in the website field is updated. +- (void)setWebsiteURL:(NSString*)website; + +// Returns whether the website URL has http(s) scheme and is valid or not. +- (BOOL)isURLValid; + // Checks if the username is reused for the same domain. - (BOOL)isUsernameReused:(NSString*)newUsername;
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_unittest.mm index fff39f0..4c2adbb 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_unittest.mm
@@ -101,22 +101,26 @@ - (void)passwordDetailsViewController: (PasswordDetailsTableViewController*)viewController - didAddPasswordDetailsWithSite:(NSString*)website - username:(NSString*)username + didAddPasswordDetails:(NSString*)username password:(NSString*)password { } -- (void)checkForDuplicatesWithSite:(NSString*)website - username:(NSString*)username { +- (void)checkForDuplicates:(NSString*)username { } -- (void)showExistingCredentialWithSite:(NSString*)website - username:(NSString*)username { +- (void)showExistingCredential:(NSString*)username { } - (void)didCancelAddPasswordDetails { } +- (void)setWebsiteURL:(NSString*)website { +} + +- (BOOL)isURLValid { + return YES; +} + @end @interface FakeSnackbarImplementation : NSObject <SnackbarCommands>
diff --git a/ios/google_internal/frameworks/LSApplicationQuerySchemes.plist.sha1 b/ios/google_internal/frameworks/LSApplicationQuerySchemes.plist.sha1 index 8b348fc..7ef68ca4 100644 --- a/ios/google_internal/frameworks/LSApplicationQuerySchemes.plist.sha1 +++ b/ios/google_internal/frameworks/LSApplicationQuerySchemes.plist.sha1
@@ -1 +1 @@ -bc4db87578a140fcdb8bf7dbf8002805cd34501e \ No newline at end of file +5a871452dc8ef97d86fd171571e3995b950fbadd \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index 4e0071f..208938b 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -7153d40778308782401995fb334fe4eeb7e23333 \ No newline at end of file +7339a4100a10ddb3163cf593bb2959cf74cb8fdb \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index cf34afe..8bd95447 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -b4bfd9873bf419a037f758d8e220893bd0248fa1 \ No newline at end of file +f6ab320b8c1124872aaad26ead05a4a761d8cc76 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index dd21299..fd14bb1 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -fc7aac0a6837934e5daadf9a159fbc1cfd182bb8 \ No newline at end of file +c7669b52f19b45417f3fc0f3b3b0279ce59d3678 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index d7a4289..af0d5f1 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -f71759f0f4f631fbac419326d00f94237fb497ae \ No newline at end of file +8cc9e970531ee5229be7fd093111f73d575326ee \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 index 204688b..f303762 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -d7c926231dd1c7df0efabf50592cd064bc0eff2b \ No newline at end of file +887bac2596570a24df058ddd72da35c6fe36d6b0 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 index c682dfd..1f691ee2 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -b71455454d69c64663cd6bd4b58f01e9e9700c61 \ No newline at end of file +a0eecee6bb16e4b568c81b4069cdb0ab83016944 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index fbd34441..580a7fc 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -93760ff578e7e222929bf36f4cfbf6f1dc76b051 \ No newline at end of file +9b4ff184392a474da3cb81114c2f04a303660f44 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index 540db00..148fbae 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -a169d6873358267cc43e626f597b856686ec33fd \ No newline at end of file +48ce863422aa17d2bd0a2276692b01e013653631 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index 96325b60..30e6d01 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -dc00f722b9937dbe0cce9c4aa8bc2d06de9fc945 \ No newline at end of file +87f0dd0f3af960fd0ec285c4e20c409d43227610 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index 8692d779..8184ad76 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -2c12ec88e6ab8efddc2d0ff8784a65a8b3691e83 \ No newline at end of file +be12838eceb30a1fe382ba56db04e5c29427e570 \ No newline at end of file
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index 100b11e..ccce2dd7 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -618,16 +618,6 @@ assert_no_deps = ios_assert_no_deps } -js_compile_bundle("main_frame_web_bundle") { - visibility = [ ":js_resources" ] - closure_entry_point = "__crWeb.mainFrameWebBundle" - - sources = [ - "web_state/js/resources/main_frame_web_bundle.js", - "web_state/js/resources/navigation.js", - ] -} - js_compile_bundle("all_frames_web_bundle") { visibility = [ ":js_resources" ] closure_entry_point = "__crWeb.allFramesWebBundle" @@ -668,10 +658,7 @@ } js_compile_checked("js_resources") { - public_deps = [ - ":all_frames_web_bundle", - ":main_frame_web_bundle", - ] + public_deps = [ ":all_frames_web_bundle" ] js_modules = [ "//ios/web/web_state/js/resources/base.js",
diff --git a/ios/web/js_messaging/BUILD.gn b/ios/web/js_messaging/BUILD.gn index 1d0802a4..c0160371 100644 --- a/ios/web/js_messaging/BUILD.gn +++ b/ios/web/js_messaging/BUILD.gn
@@ -102,6 +102,7 @@ "//ios/web/js_features/context_menu", "//ios/web/js_features/scroll_helper", "//ios/web/js_features/window_error", + "//ios/web/navigation:navigation_feature", "//ios/web/navigation:session_restore_feature", "//ios/web/public", "//ios/web/public/js_messaging",
diff --git a/ios/web/js_messaging/java_script_feature_util_impl.mm b/ios/web/js_messaging/java_script_feature_util_impl.mm index dc112e84..721f457e 100644 --- a/ios/web/js_messaging/java_script_feature_util_impl.mm +++ b/ios/web/js_messaging/java_script_feature_util_impl.mm
@@ -17,6 +17,7 @@ #import "ios/web/js_features/window_error/window_error_java_script_feature.h" #import "ios/web/js_messaging/script_command_java_script_feature.h" #import "ios/web/js_messaging/web_frames_manager_java_script_feature.h" +#import "ios/web/navigation/navigation_java_script_feature.h" #import "ios/web/navigation/session_restore_java_script_feature.h" #include "ios/web/public/js_messaging/java_script_feature.h" #import "ios/web/public/web_client.h" @@ -112,6 +113,7 @@ GetFaviconJavaScriptFeature(), GetScrollHelperJavaScriptFeature(), GetWindowErrorJavaScriptFeature(), + NavigationJavaScriptFeature::GetInstance(), ScriptCommandJavaScriptFeature::GetInstance(), SessionRestoreJavaScriptFeature::FromBrowserState(browser_state), TextFragmentsJavaScriptFeature::GetInstance(),
diff --git a/ios/web/js_messaging/page_script_util.mm b/ios/web/js_messaging/page_script_util.mm index f7e55d5..39764987 100644 --- a/ios/web/js_messaging/page_script_util.mm +++ b/ios/web/js_messaging/page_script_util.mm
@@ -53,12 +53,7 @@ GetWebClient()->GetDocumentStartScriptForMainFrame(browser_state); DCHECK(embedder_page_script); - NSString* web_bundle = GetPageScript(@"main_frame_web_bundle"); - DCHECK(web_bundle); - - NSString* script = - [NSString stringWithFormat:@"%@; %@", web_bundle, embedder_page_script]; - return MakeScriptInjectableOnce(@"start_main_frame", script); + return MakeScriptInjectableOnce(@"start_main_frame", embedder_page_script); } NSString* GetDocumentStartScriptForAllFrames(BrowserState* browser_state) {
diff --git a/ios/web/js_messaging/resources/window_id.js b/ios/web/js_messaging/resources/window_id.js index 563a48a..35ebced 100644 --- a/ios/web/js_messaging/resources/window_id.js +++ b/ios/web/js_messaging/resources/window_id.js
@@ -13,4 +13,8 @@ // Send messages queued since message.js injection. __gCrWeb.message.invokeQueues(); + +const event = new Event('__gCrWebWindowIdInjected'); +window.dispatchEvent(event); + }());
diff --git a/ios/web/navigation/BUILD.gn b/ios/web/navigation/BUILD.gn index be659082..3a02462 100644 --- a/ios/web/navigation/BUILD.gn +++ b/ios/web/navigation/BUILD.gn
@@ -5,6 +5,7 @@ import("//build/buildflag_header.gni") import("//ios/build/config.gni") import("//ios/features.gni") +import("//ios/web/js_compile.gni") buildflag_header("block_universal_links_buildflags") { header = "block_universal_links_buildflags.h" @@ -103,6 +104,36 @@ configs += [ "//build/config/compiler:enable_arc" ] } +source_set("navigation_feature") { + deps = [ + ":navigation_js", + ":navigation_listeners_js", + "//base", + "//ios/web/public/js_messaging", + "//ios/web/web_state:web_state_impl_header", + "//ios/web/web_state/ui:web_controller_header", + ] + sources = [ + "navigation_java_script_feature.h", + "navigation_java_script_feature.mm", + ] + configs += [ "//build/config/compiler:enable_arc" ] +} + +js_compile_bundle("navigation_js") { + visibility = [ ":navigation_feature" ] + closure_entry_point = "__crWeb.navigation" + + sources = [ "resources/navigation.js" ] +} + +js_compile_bundle("navigation_listeners_js") { + visibility = [ ":navigation_feature" ] + closure_entry_point = "__crWeb.navigationListeners" + + sources = [ "resources/navigation_listeners.js" ] +} + source_set("session_restore_feature") { deps = [ "//base",
diff --git a/ios/web/navigation/crw_js_navigation_handler.h b/ios/web/navigation/crw_js_navigation_handler.h index edb68b7..4e00936 100644 --- a/ios/web/navigation/crw_js_navigation_handler.h +++ b/ios/web/navigation/crw_js_navigation_handler.h
@@ -8,35 +8,42 @@ #import <WebKit/WebKit.h> #import "ios/web/web_state/ui/crw_web_view_handler.h" -#import "ios/web/web_state/ui/crw_web_view_handler_delegate.h" #include "url/gurl.h" -@class CRWJSNavigationHandler; +namespace base { +class Value; +} // namespace base -@protocol CRWJSNavigationHandlerDelegate <CRWWebViewHandlerDelegate> - -// Returns the current URL of web view. -- (GURL)currentURLForJSNavigationHandler: - (CRWJSNavigationHandler*)navigationHandler; - -// Finds all the scrollviews in the view hierarchy and makes sure they do not -// interfere with scroll to top when tapping the statusbar. -- (void)JSNavigationHandlerOptOutScrollsToTopForSubviews: - (CRWJSNavigationHandler*)navigationHandler; - -@end +namespace web { +class UserInteractionState; +class WebStateImpl; +} // namespace web // Handles JS messages related to navigation(e.g. window.history.forward). @interface CRWJSNavigationHandler : CRWWebViewHandler -- (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithDelegate:(id<CRWJSNavigationHandlerDelegate>)delegate - NS_DESIGNATED_INITIALIZER; - // Whether the web page is currently performing window.history.pushState or // window.history.replaceState. @property(nonatomic, assign) BOOL changingHistoryState; +// Handles a navigation will change state message for the current webpage. +- (void)handleNavigationWillChangeState; + +// Handles a navigation did push state message for the current webpage. +- (void)handleNavigationDidPushStateMessage:(base::Value*)message + webState:(web::WebStateImpl*)webStateImpl + hasUserGesture:(BOOL)hasUserGesture + userInteractionState: + (web::UserInteractionState*)userInteractionState + currentURL:(GURL)currentURL; + +// Handles a navigation did replace state message for the current webpage. +- (void)handleNavigationDidReplaceStateMessage:(base::Value*)message + webState:(web::WebStateImpl*)webStateImpl + hasUserGesture:(BOOL)hasUserGesture + userInteractionState: + (web::UserInteractionState*)userInteractionState + currentURL:(GURL)currentURL; @end #endif // IOS_WEB_NAVIGATION_CRW_JS_NAVIGATION_HANDLER_H_
diff --git a/ios/web/navigation/crw_js_navigation_handler.mm b/ios/web/navigation/crw_js_navigation_handler.mm index cdd3ab01..be4353fd 100644 --- a/ios/web/navigation/crw_js_navigation_handler.mm +++ b/ios/web/navigation/crw_js_navigation_handler.mm
@@ -11,7 +11,6 @@ #import "ios/web/navigation/navigation_context_impl.h" #import "ios/web/navigation/navigation_item_impl.h" #import "ios/web/navigation/navigation_manager_impl.h" -#include "ios/web/public/js_messaging/web_frame.h" #import "ios/web/web_state/user_interaction_state.h" #import "ios/web/web_state/web_state_impl.h" #import "net/base/mac/url_conversions.h" @@ -21,7 +20,6 @@ #endif namespace { -const char kCommandPrefix[] = "navigation"; // URLs that are fed into WKWebView as history push/replace get escaped, // potentially changing their format. Code that attempts to determine whether a @@ -36,130 +34,55 @@ } // namespace -@interface CRWJSNavigationHandler () { - // Subscription for JS message. - base::CallbackListSubscription _subscription; -} - -@property(nonatomic, weak) id<CRWJSNavigationHandlerDelegate> delegate; - -// Returns WebStateImpl from self.delegate. -@property(nonatomic, readonly, assign) web::WebStateImpl* webStateImpl; -// Returns NavigationManagerImpl from self.webStateImpl. -@property(nonatomic, readonly, assign) - web::NavigationManagerImpl* navigationManagerImpl; -// Returns UserInteractionState from self.delegate. -@property(nonatomic, readonly, assign) - web::UserInteractionState* userInteractionState; -// Returns WKWebView from self.delegate. -@property(nonatomic, readonly, weak) WKWebView* webView; -// Returns current URL from self.delegate. -@property(nonatomic, readonly, assign) GURL currentURL; - -@end - @implementation CRWJSNavigationHandler #pragma mark - Public -- (instancetype)initWithDelegate:(id<CRWJSNavigationHandlerDelegate>)delegate { - if (self = [super init]) { - _delegate = delegate; - - __weak CRWJSNavigationHandler* weakSelf = self; - auto navigationStateCallback = ^(const base::Value& message, const GURL&, - bool /* user_is_interacting */, - web::WebFrame* senderFrame) { - if (!senderFrame->IsMainFrame()) - return; - - const std::string* command = message.FindStringKey("command"); - if (!command) - return; - - if (*command == "navigation.hashchange") { - [weakSelf handleNavigationHashChangeInFrame:senderFrame]; - } else if (*command == "navigation.willChangeState") { - [weakSelf handleNavigationWillChangeStateInFrame:senderFrame]; - } else if (*command == "navigation.didPushState") { - [weakSelf handleNavigationDidPushStateMessage:message - inFrame:senderFrame]; - } else if (*command == "navigation.didReplaceState") { - [weakSelf handleNavigationDidReplaceStateMessage:message - inFrame:senderFrame]; - } - }; - - _subscription = self.webStateImpl->AddScriptCommandCallback( - base::BindRepeating(navigationStateCallback), kCommandPrefix); - } - return self; -} - -#pragma mark - Private - -- (web::WebStateImpl*)webStateImpl { - return [self.delegate webStateImplForWebViewHandler:self]; -} - -- (web::NavigationManagerImpl*)navigationManagerImpl { - return &(self.webStateImpl->GetNavigationManagerImpl()); -} - -- (web::UserInteractionState*)userInteractionState { - return [self.delegate userInteractionStateForWebViewHandler:self]; -} - -- (WKWebView*)webView { - return [self.delegate webViewForWebViewHandler:self]; -} - -- (GURL)currentURL { - return [self.delegate currentURLForJSNavigationHandler:self]; -} - -// Handles the navigation.hashchange event emitted from |senderFrame|. -- (void)handleNavigationHashChangeInFrame:(web::WebFrame*)senderFrame { - self.navigationManagerImpl->GetCurrentItemImpl()->SetIsCreatedFromHashChange( - true); -} - -// Handles the navigation.willChangeState message sent from |senderFrame|. -- (void)handleNavigationWillChangeStateInFrame:(web::WebFrame*)senderFrame { +- (void)handleNavigationWillChangeState { self.changingHistoryState = YES; } -// Handles the navigation.didChangeState message sent from |senderFrame|. -- (void)handleNavigationDidPushStateMessage:(const base::Value&)message - inFrame:(web::WebFrame*)senderFrame { +- (void)handleNavigationDidPushStateMessage:(base::Value*)message + webState:(web::WebStateImpl*)webStateImpl + hasUserGesture:(BOOL)hasUserGesture + userInteractionState: + (web::UserInteractionState*)userInteractionState + currentURL:(GURL)currentURL { + if (!webStateImpl || webStateImpl->IsBeingDestroyed()) { + // Ignore messages received after WebState is being destroyed. + return; + } + DCHECK(self.changingHistoryState); self.changingHistoryState = NO; + const web::NavigationManagerImpl& navigationManagerImpl = + webStateImpl->GetNavigationManagerImpl(); + // If there is a pending entry, a new navigation has been registered but // hasn't begun loading. Since the pushState message is coming from the // previous page, ignore it and allow the previously registered navigation to // continue. This can ocur if a pushState is issued from an anchor tag // onClick event, as the click would have already been registered. - if (self.navigationManagerImpl->GetPendingItem()) { + if (navigationManagerImpl.GetPendingItem()) { return; } - const std::string* pageURL = message.FindStringKey("pageUrl"); - const std::string* baseURL = message.FindStringKey("baseUrl"); + const std::string* pageURL = message->FindStringKey("pageUrl"); + const std::string* baseURL = message->FindStringKey("baseUrl"); if (!pageURL || !baseURL) { DLOG(WARNING) << "JS message parameter not found: pageUrl or baseUrl"; return; } GURL pushURL = web::history_state_util::GetHistoryStateChangeUrl( - self.currentURL, GURL(*baseURL), *pageURL); + currentURL, GURL(*baseURL), *pageURL); // UIWebView seems to choke on unicode characters that haven't been // escaped; escape the URL now so the expected load URL is correct. pushURL = URLEscapedForHistory(pushURL); if (!pushURL.is_valid()) return; - web::NavigationItemImpl* navItem = - self.navigationManagerImpl->GetCurrentItemImpl(); + web::NavigationItemImpl* navItem = navigationManagerImpl.GetCurrentItemImpl(); // PushState happened before first navigation entry or called when the // navigation entry does not contain a valid URL. if (!navItem || !navItem->GetURL().is_valid()) @@ -171,17 +94,17 @@ // just before the pushState. return; } - const std::string* stateObjectJSON = message.FindStringKey("stateObject"); + const std::string* stateObjectJSON = message->FindStringKey("stateObject"); if (!stateObjectJSON) { DLOG(WARNING) << "JS message parameter not found: stateObject"; return; } NSString* stateObject = base::SysUTF8ToNSString(*stateObjectJSON); - int currentIndex = self.navigationManagerImpl->GetIndexOfItem(navItem); + int currentIndex = navigationManagerImpl.GetIndexOfItem(navItem); if (currentIndex > 0) { web::NavigationItem* previousItem = - self.navigationManagerImpl->GetItemAtIndex(currentIndex - 1); + navigationManagerImpl.GetItemAtIndex(currentIndex - 1); web::UserAgentType userAgent = previousItem->GetUserAgentType(); if (userAgent != web::UserAgentType::NONE) { navItem->SetUserAgentType(userAgent); @@ -192,42 +115,51 @@ // input and should not be added to the history stack. // TODO(crbug.com/549301): Improve transition detection. ui::PageTransition transition = - self.userInteractionState->UserInteractionRegisteredSincePageLoaded() + userInteractionState->UserInteractionRegisteredSincePageLoaded() ? ui::PAGE_TRANSITION_LINK : ui::PAGE_TRANSITION_CLIENT_REDIRECT; [self pushStateWithPageURL:pushURL stateObject:stateObject transition:transition - hasUserGesture:self.userInteractionState->IsUserInteracting( - self.webView)]; - [self.delegate webViewHandlerUpdateSSLStatusForCurrentNavigationItem:self]; + hasUserGesture:hasUserGesture + userInteractionState:userInteractionState + webState:webStateImpl]; } -// Handles the navigation.didReplaceState message sent from |senderFrame|. -- (void)handleNavigationDidReplaceStateMessage:(const base::Value&)message - inFrame:(web::WebFrame*)senderFrame { +- (void)handleNavigationDidReplaceStateMessage:(base::Value*)message + webState:(web::WebStateImpl*)webStateImpl + hasUserGesture:(BOOL)hasUserGesture + userInteractionState: + (web::UserInteractionState*)userInteractionState + currentURL:(GURL)currentURL { + if (!webStateImpl || webStateImpl->IsBeingDestroyed()) { + // Ignore messages received after WebState is being destroyed. + return; + } + DCHECK(self.changingHistoryState); self.changingHistoryState = NO; - const std::string* pageURL = message.FindStringKey("pageUrl"); - const std::string* baseURL = message.FindStringKey("baseUrl"); + const std::string* pageURL = message->FindStringKey("pageUrl"); + const std::string* baseURL = message->FindStringKey("baseUrl"); if (!pageURL || !baseURL) { DLOG(WARNING) << "JS message parameter not found: pageUrl or baseUrl"; return; } GURL replaceURL = web::history_state_util::GetHistoryStateChangeUrl( - self.currentURL, GURL(*baseURL), *pageURL); + currentURL, GURL(*baseURL), *pageURL); // UIWebView seems to choke on unicode characters that haven't been // escaped; escape the URL now so the expected load URL is correct. replaceURL = URLEscapedForHistory(replaceURL); if (!replaceURL.is_valid()) return; - web::NavigationItemImpl* navItem = - self.navigationManagerImpl->GetCurrentItemImpl(); + const web::NavigationManagerImpl& navigationManagerImpl = + webStateImpl->GetNavigationManagerImpl(); + web::NavigationItemImpl* navItem = navigationManagerImpl.GetCurrentItemImpl(); // ReplaceState happened before first navigation entry or called right // after window.open when the url is empty/not valid. - if (!navItem || (self.navigationManagerImpl->GetItemCount() <= 1 && + if (!navItem || (navigationManagerImpl.GetItemCount() <= 1 && navItem->GetURL().is_empty())) return; if (!web::history_state_util::IsHistoryStateChangeValid(navItem->GetURL(), @@ -237,7 +169,7 @@ // new URL is loaded just before the replaceState. return; } - const std::string* stateObjectJSON = message.FindStringKey("stateObject"); + const std::string* stateObjectJSON = message->FindStringKey("stateObject"); if (!stateObjectJSON) { DLOG(WARNING) << "JS message parameter not found: stateObject"; return; @@ -245,10 +177,12 @@ NSString* stateObject = base::SysUTF8ToNSString(*stateObjectJSON); [self replaceStateWithPageURL:replaceURL stateObject:stateObject - hasUserGesture:self.userInteractionState->IsUserInteracting( - self.webView)]; + hasUserGesture:hasUserGesture + webState:webStateImpl]; } +#pragma mark - Private + // Adds a new NavigationItem with the given URL and state object to the // history stack. A state object is a serialized generic JavaScript object // that contains details of the UI's state for a given NavigationItem/URL. @@ -257,33 +191,37 @@ - (void)pushStateWithPageURL:(const GURL&)pageURL stateObject:(NSString*)stateObject transition:(ui::PageTransition)transition - hasUserGesture:(BOOL)hasUserGesture { + hasUserGesture:(BOOL)hasUserGesture + userInteractionState:(web::UserInteractionState*)userInteractionState + webState:(web::WebStateImpl*)webStateImpl { std::unique_ptr<web::NavigationContextImpl> context = web::NavigationContextImpl::CreateNavigationContext( - self.webStateImpl, pageURL, hasUserGesture, transition, + webStateImpl, pageURL, hasUserGesture, transition, /*is_renderer_initiated=*/true); context->SetIsSameDocument(true); - self.webStateImpl->OnNavigationStarted(context.get()); + webStateImpl->OnNavigationStarted(context.get()); context->SetHasCommitted(true); - self.webStateImpl->OnNavigationFinished(context.get()); - self.userInteractionState->SetUserInteractionRegisteredSincePageLoaded(false); + webStateImpl->OnNavigationFinished(context.get()); + userInteractionState->SetUserInteractionRegisteredSincePageLoaded(false); } // Assigns the given URL and state object to the current NavigationItem. - (void)replaceStateWithPageURL:(const GURL&)pageURL stateObject:(NSString*)stateObject - hasUserGesture:(BOOL)hasUserGesture { + hasUserGesture:(BOOL)hasUserGesture + webState:(web::WebStateImpl*)webStateImpl { std::unique_ptr<web::NavigationContextImpl> context = web::NavigationContextImpl::CreateNavigationContext( - self.webStateImpl, pageURL, hasUserGesture, + webStateImpl, pageURL, hasUserGesture, ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT, /*is_renderer_initiated=*/true); context->SetIsSameDocument(true); - self.webStateImpl->OnNavigationStarted(context.get()); - self.navigationManagerImpl->UpdateCurrentItemForReplaceState(pageURL, - stateObject); + webStateImpl->OnNavigationStarted(context.get()); + web::NavigationManagerImpl& navigationManagerImpl = + webStateImpl->GetNavigationManagerImpl(); + navigationManagerImpl.UpdateCurrentItemForReplaceState(pageURL, stateObject); context->SetHasCommitted(true); - self.webStateImpl->OnNavigationFinished(context.get()); + webStateImpl->OnNavigationFinished(context.get()); } @end
diff --git a/ios/web/navigation/navigation_java_script_feature.h b/ios/web/navigation/navigation_java_script_feature.h new file mode 100644 index 0000000..5918cb1 --- /dev/null +++ b/ios/web/navigation/navigation_java_script_feature.h
@@ -0,0 +1,38 @@ +// Copyright 2021 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 IOS_WEB_NAVIGATION_NAVIGATION_JAVA_SCRIPT_FEATURE_H_ +#define IOS_WEB_NAVIGATION_NAVIGATION_JAVA_SCRIPT_FEATURE_H_ + +#include "base/no_destructor.h" +#import "ios/web/public/js_messaging/java_script_feature.h" + +namespace web { + +// A feature which receives messages about the main frame page navigation. +class NavigationJavaScriptFeature : public web::JavaScriptFeature { + public: + // This feature holds no state, so only a single static instance is ever + // needed. + static NavigationJavaScriptFeature* GetInstance(); + + private: + friend class base::NoDestructor<NavigationJavaScriptFeature>; + + NavigationJavaScriptFeature(); + ~NavigationJavaScriptFeature() override; + + NavigationJavaScriptFeature(const NavigationJavaScriptFeature&) = delete; + NavigationJavaScriptFeature& operator=(const NavigationJavaScriptFeature&) = + delete; + + // JavaScriptFeature: + absl::optional<std::string> GetScriptMessageHandlerName() const override; + void ScriptMessageReceived(web::WebState* web_state, + const web::ScriptMessage& message) override; +}; + +} // namespace web + +#endif // IOS_WEB_NAVIGATION_NAVIGATION_JAVA_SCRIPT_FEATURE_H_
diff --git a/ios/web/navigation/navigation_java_script_feature.mm b/ios/web/navigation/navigation_java_script_feature.mm new file mode 100644 index 0000000..e536da4e --- /dev/null +++ b/ios/web/navigation/navigation_java_script_feature.mm
@@ -0,0 +1,86 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/web/navigation/navigation_java_script_feature.h" +#import "ios/web/public/js_messaging/java_script_feature_util.h" +#import "ios/web/public/js_messaging/script_message.h" +#import "ios/web/web_state/ui/crw_web_controller.h" +#import "ios/web/web_state/web_state_impl.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace web { + +namespace { + +const char kScriptName[] = "navigation_js"; +const char kListenersScriptName[] = "navigation_listeners_js"; +const char kScriptHandlerName[] = "NavigationEventMessage"; + +} // namespace + +// static +NavigationJavaScriptFeature* NavigationJavaScriptFeature::GetInstance() { + static base::NoDestructor<NavigationJavaScriptFeature> instance; + return instance.get(); +} + +NavigationJavaScriptFeature::NavigationJavaScriptFeature() + : JavaScriptFeature( + ContentWorld::kPageContentWorld, + {FeatureScript::CreateWithFilename( + kScriptName, + FeatureScript::InjectionTime::kDocumentStart, + FeatureScript::TargetFrames::kMainFrame, + FeatureScript::ReinjectionBehavior::kInjectOncePerWindow), + FeatureScript::CreateWithFilename( + kListenersScriptName, + FeatureScript::InjectionTime::kDocumentStart, + FeatureScript::TargetFrames::kMainFrame, + FeatureScript::ReinjectionBehavior:: + kReinjectOnDocumentRecreation)}, + {web::java_script_features::GetCommonJavaScriptFeature(), + web::java_script_features::GetMessageJavaScriptFeature()}) {} + +NavigationJavaScriptFeature::~NavigationJavaScriptFeature() = default; + +absl::optional<std::string> +NavigationJavaScriptFeature::GetScriptMessageHandlerName() const { + return kScriptHandlerName; +} + +void NavigationJavaScriptFeature::ScriptMessageReceived( + web::WebState* web_state, + const web::ScriptMessage& message) { + if (!message.body() || !message.body()->is_dict()) { + // Ignore malformed responses. + return; + } + + if (!message.is_main_frame()) { + return; + } + + const std::string* command = message.body()->FindStringKey("command"); + if (!command) { + return; + } + + CRWWebController* web_controller = + static_cast<WebStateImpl*>(web_state)->GetWebController(); + + if (*command == "hashchange") { + [web_controller handleNavigationHashChange]; + } else if (*command == "willChangeState") { + [web_controller handleNavigationWillChangeState]; + } else if (*command == "didPushState") { + [web_controller handleNavigationDidPushStateMessage:message.body()]; + } else if (*command == "didReplaceState") { + [web_controller handleNavigationDidReplaceStateMessage:message.body()]; + } +} + +} // namespace web
diff --git a/ios/web/web_state/js/resources/navigation.js b/ios/web/navigation/resources/navigation.js similarity index 64% rename from ios/web/web_state/js/resources/navigation.js rename to ios/web/navigation/resources/navigation.js index 2a712b6..860e3022 100644 --- a/ios/web/web_state/js/resources/navigation.js +++ b/ios/web/navigation/resources/navigation.js
@@ -8,7 +8,7 @@ goog.provide('__crWeb.navigation'); -/** Beginning of anonymouse object */ +/** Beginning of anonymous object */ (function() { /** @@ -25,9 +25,35 @@ // https://heycam.github.io/webidl/#datacloneerror this.name = 'DataCloneError'; this.code = 25; - this.message = "Cyclic structures are not supported."; + this.message = 'Cyclic structures are not supported.'; } +// Stores queued messages until they can be sent to the "NavigationEventMessage" +// handler. +var queuedMessages = []; + +// Attempts to send any queued messages. Messages will be only be removed once +// they have been sent. +function sendQueuedMessages() { + while (queuedMessages.length > 0) { + try { + __gCrWeb.common.sendWebKitMessage( + 'NavigationEventMessage', queuedMessages[0]); + queuedMessages.shift(); + } catch (e) { + // 'NavigationEventMessage' message handler is not currently registered. + // Send the message later when possible. + break; + } + } +}; + +// Queues the |message| and triggers the queue to be sent. +function queueNavigationEventMessage(message) { + queuedMessages.push(message); + sendQueuedMessages(); +}; + /** * Intercepts window.history methods so native code can differentiate between * same-document navigation that are state navigations vs. hash navigations. @@ -37,7 +63,7 @@ * called for same-document navigation. */ window.history.pushState = function(stateObject, pageTitle, pageUrl) { - __gCrWeb.message.invokeOnHost({'command': 'navigation.willChangeState'}); + queueNavigationEventMessage({'command': 'willChangeState'}); // JSONStringify throws an exception when given a cyclical object. This // internal implementation detail should not be exposed to callers of @@ -52,8 +78,8 @@ } pageUrl = pageUrl || window.location.href; originalWindowHistoryPushState.call(history, stateObject, pageTitle, pageUrl); - __gCrWeb.message.invokeOnHost({ - 'command': 'navigation.didPushState', + queueNavigationEventMessage({ + 'command': 'didPushState', 'stateObject': serializedState, 'baseUrl': document.baseURI, 'pageUrl': pageUrl.toString() @@ -61,12 +87,12 @@ }; window.history.replaceState = function(stateObject, pageTitle, pageUrl) { - __gCrWeb.message.invokeOnHost({'command': 'navigation.willChangeState'}); + queueNavigationEventMessage({'command': 'willChangeState'}); - // JSONStringify throws an exception when given a cyclical object. This - // internal implementation detail should not be exposed to callers of - // replaceState. Instead, throw a standard exception when stringification - // fails. + // JSONStringify throws an exception when given a cyclical object. This + // internal implementation detail should not be exposed to callers of + // replaceState. Instead, throw a standard exception when stringification + // fails. try { // Calling stringify() on undefined causes a JSON parse error. var serializedState = typeof (stateObject) == 'undefined' ? @@ -78,20 +104,20 @@ pageUrl = pageUrl || window.location.href; originalWindowHistoryReplaceState.call( history, stateObject, pageTitle, pageUrl); - __gCrWeb.message.invokeOnHost({ - 'command': 'navigation.didReplaceState', + queueNavigationEventMessage({ + 'command': 'didReplaceState', 'stateObject': serializedState, 'baseUrl': document.baseURI, 'pageUrl': pageUrl.toString() }); }; -window.addEventListener('hashchange', function(evt) { - __gCrWeb.message.invokeOnHost({'command': 'navigation.hashchange'}); +window.addEventListener('__gCrWebWindowIdInjected', function() { + sendQueuedMessages(); }); /** Flush the message queue. */ if (__gCrWeb.message) { __gCrWeb.message.invokeQueues(); } -}()); // End of anonymouse object +}()); // End of anonymous object
diff --git a/ios/web/navigation/resources/navigation_listeners.js b/ios/web/navigation/resources/navigation_listeners.js new file mode 100644 index 0000000..a684bbe --- /dev/null +++ b/ios/web/navigation/resources/navigation_listeners.js
@@ -0,0 +1,18 @@ +// Copyright 2021 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. + +/** + * @fileoverview Navigation listener to report hash change. + */ + +goog.provide('__crWeb.navigationListeners'); + +/** Beginning of anonymous object */ +(function() { + +window.addEventListener('hashchange', function(evt) { + __gCrWeb.common.sendWebKitMessage( + 'NavigationEventMessage', {'command': 'hashchange'}); +}); +}()); // End of anonymous object
diff --git a/ios/web/web_state/js/resources/main_frame_web_bundle.js b/ios/web/web_state/js/resources/main_frame_web_bundle.js deleted file mode 100644 index 7825ced7..0000000 --- a/ios/web/web_state/js/resources/main_frame_web_bundle.js +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2015 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. - -// Set of scripts required by web layer backed up by WKWebView. -goog.provide('__crWeb.mainFrameWebBundle'); - -// Requires __crWeb.form provided by __crWeb.allFramesWebBundle. - -// DEPRECATED -// Do NOT add new features here, but rather add them using an instance of -// JavaScriptFeature. Please see the documentation at -// //ios/web/public/js_messaging/README.md -goog.require('__crWeb.navigation');
diff --git a/ios/web/web_state/ui/crw_web_controller.h b/ios/web/web_state/ui/crw_web_controller.h index 18e6bc90..494015e7 100644 --- a/ios/web/web_state/ui/crw_web_controller.h +++ b/ios/web/web_state/ui/crw_web_controller.h
@@ -11,6 +11,10 @@ #import "ios/web/web_state/ui/crw_touch_tracking_recognizer.h" #import "ios/web/web_state/ui/crw_web_view_navigation_proxy.h" +namespace base { +class Value; +} // namespace base + namespace web { enum class NavigationInitiationType; @@ -194,6 +198,20 @@ // TODO(crbug.com/905939): Remove WindowID. - (void)injectWindowID; +#pragma mark Navigation Message Handlers + +// Handles a navigation hash change message for the current webpage. +- (void)handleNavigationHashChange; + +// Handles a navigation will change message for the current webpage. +- (void)handleNavigationWillChangeState; + +// Handles a navigation did push state message for the current webpage. +- (void)handleNavigationDidPushStateMessage:(base::Value*)message; + +// Handles a navigation did replace state message for the current webpage. +- (void)handleNavigationDidReplaceStateMessage:(base::Value*)message; + #pragma mark CRWJSInjectionEvaluator // Do not use these executeJavaScript functions directly, prefer
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index a4cb924..241e80f 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -97,7 +97,6 @@ CRWWebControllerContainerViewDelegate, CRWWebViewNavigationObserverDelegate, CRWWebRequestControllerDelegate, - CRWJSNavigationHandlerDelegate, CRWWebViewScrollViewProxyObserver, CRWWKNavigationHandlerDelegate, CRWWKUIHandlerDelegate, @@ -150,7 +149,7 @@ @property(nonatomic, readonly, strong) CRWWKNavigationHandler* navigationHandler; @property(nonatomic, readonly, strong) - CRWJSNavigationHandler* JSNavigationHandler; + CRWJSNavigationHandler* jsNavigationHandler; // The WKUIDelegate handler class. @property(nonatomic, readonly, strong) CRWWKUIHandler* UIHandler; @@ -307,8 +306,7 @@ _navigationHandler = [[CRWWKNavigationHandler alloc] initWithDelegate:self]; - _JSNavigationHandler = - [[CRWJSNavigationHandler alloc] initWithDelegate:self]; + _jsNavigationHandler = [[CRWJSNavigationHandler alloc] init]; _UIHandler = [[CRWWKUIHandler alloc] init]; _UIHandler.delegate = self; @@ -543,7 +541,7 @@ _SSLStatusUpdater = nil; [self.navigationHandler close]; [self.UIHandler close]; - [self.JSNavigationHandler close]; + [self.jsNavigationHandler close]; [self.requestController close]; self.swipeRecognizerProvider = nil; [self.requestController close]; @@ -895,6 +893,34 @@ return nil; } +- (void)handleNavigationHashChange { + self.navigationManagerImpl->GetCurrentItemImpl()->SetIsCreatedFromHashChange( + true); +} + +- (void)handleNavigationWillChangeState { + [self.jsNavigationHandler handleNavigationWillChangeState]; +} + +- (void)handleNavigationDidPushStateMessage:(base::Value*)message { + [self.jsNavigationHandler + handleNavigationDidPushStateMessage:message + webState:_webStateImpl + hasUserGesture:self.isUserInteracting + userInteractionState:&_userInteractionState + currentURL:self.currentURL]; + [self updateSSLStatusForCurrentNavigationItem]; +} + +- (void)handleNavigationDidReplaceStateMessage:(base::Value*)message { + [self.jsNavigationHandler + handleNavigationDidReplaceStateMessage:message + webState:_webStateImpl + hasUserGesture:self.isUserInteracting + userInteractionState:&_userInteractionState + currentURL:self.currentURL]; +} + #pragma mark - JavaScript - (void)injectWindowID { @@ -1810,7 +1836,7 @@ // |newNavigationContext| only exists if this method has to create a new // context object. std::unique_ptr<web::NavigationContextImpl> newNavigationContext; - if (!self.JSNavigationHandler.changingHistoryState) { + if (!self.jsNavigationHandler.changingHistoryState) { if ([self.navigationHandler contextForPendingMainFrameNavigationWithURL:newURL]) { // NavigationManager::LoadURLWithParams() was called with URL that has @@ -1831,7 +1857,7 @@ [self setDocumentURL:newURL context:newNavigationContext.get()]; - if (!self.JSNavigationHandler.changingHistoryState) { + if (!self.jsNavigationHandler.changingHistoryState) { // Pass either newly created context (if it exists) or context that already // existed before. web::NavigationContextImpl* navigationContext = newNavigationContext.get(); @@ -1950,23 +1976,6 @@ return nil; } -#pragma mark - CRWJSNavigationHandlerDelegate - -- (GURL)currentURLForJSNavigationHandler: - (CRWJSNavigationHandler*)navigationHandler { - return self.currentURL; -} - -- (void)JSNavigationHandlerUpdateSSLStatusForCurrentNavigationItem: - (CRWJSNavigationHandler*)navigationHandler { - [self updateSSLStatusForCurrentNavigationItem]; -} - -- (void)JSNavigationHandlerOptOutScrollsToTopForSubviews: - (CRWJSNavigationHandler*)navigationHandler { - return [self optOutScrollsToTopForSubviews]; -} - #pragma mark - UIDropInteractionDelegate - (BOOL)dropInteraction:(UIDropInteraction*)interaction
diff --git a/media/gpu/v4l2/test/v4l2_stateless_decoder.cc b/media/gpu/v4l2/test/v4l2_stateless_decoder.cc index f50619a..1feaf99 100644 --- a/media/gpu/v4l2/test/v4l2_stateless_decoder.cc +++ b/media/gpu/v4l2/test/v4l2_stateless_decoder.cc
@@ -128,5 +128,14 @@ if (!dec->Initialize()) LOG(FATAL) << "Initialization for decoding failed."; + for (int i = 0; i < n_frames || n_frames == 0; i++) { + LOG(INFO) << "Frame " << i << "..."; + const Vp9Decoder::Result res = dec->DecodeNextFrame(); + if (res == Vp9Decoder::kEOStream) { + LOG(INFO) << "End of stream."; + break; + } + } + return EXIT_SUCCESS; }
diff --git a/media/gpu/v4l2/test/vp9_decoder.cc b/media/gpu/v4l2/test/vp9_decoder.cc index bc49144..0979511 100644 --- a/media/gpu/v4l2/test/vp9_decoder.cc +++ b/media/gpu/v4l2/test/vp9_decoder.cc
@@ -125,15 +125,13 @@ return true; } -Vp9Parser::Result Vp9Decoder::ReadNextFrame(Vp9FrameHeader* vp9_frame_header, +Vp9Parser::Result Vp9Decoder::ReadNextFrame(Vp9FrameHeader& vp9_frame_header, gfx::Size& size) { - DCHECK(vp9_frame_header); - // TODO(jchinlee): reexamine this loop for cleanup. while (true) { std::unique_ptr<DecryptConfig> null_config; Vp9Parser::Result res = - vp9_parser_->ParseNextFrame(vp9_frame_header, &size, &null_config); + vp9_parser_->ParseNextFrame(&vp9_frame_header, &size, &null_config); if (res == Vp9Parser::kEOStream) { IvfFrameHeader ivf_frame_header{}; const uint8_t* ivf_frame_data; @@ -150,5 +148,26 @@ } } +Vp9Decoder::Result Vp9Decoder::DecodeNextFrame() { + gfx::Size size; + Vp9FrameHeader frame_hdr{}; + + const Vp9Parser::Result parser_res = ReadNextFrame(frame_hdr, size); + switch (parser_res) { + case Vp9Parser::kInvalidStream: + LOG_ASSERT(false) << "Failed to parse frame"; + return Vp9Decoder::kError; + case Vp9Parser::kAwaitingRefresh: + LOG_ASSERT(false) << "Unsupported parser return value"; + return Vp9Decoder::kError; + case Vp9Parser::kEOStream: + return Vp9Decoder::kEOStream; + case Vp9Parser::kOk: + return Vp9Decoder::kOk; + } + NOTREACHED(); + return Vp9Decoder::kError; +} + } // namespace v4l2_test } // namespace media
diff --git a/media/gpu/v4l2/test/vp9_decoder.h b/media/gpu/v4l2/test/vp9_decoder.h index 60269e3..884bdfe 100644 --- a/media/gpu/v4l2/test/vp9_decoder.h +++ b/media/gpu/v4l2/test/vp9_decoder.h
@@ -20,6 +20,13 @@ // A Vp9Decoder decodes VP9-encoded IVF streams using v4l2 ioctl calls. class Vp9Decoder { public: + // Result of decoding the current frame. + enum Result { + kOk, + kError, + kEOStream, + }; + Vp9Decoder(const Vp9Decoder&) = delete; Vp9Decoder& operator=(const Vp9Decoder&) = delete; ~Vp9Decoder(); @@ -34,6 +41,9 @@ // https://www.kernel.org/doc/html/v5.10/userspace-api/media/v4l/dev-stateless-decoder.html#initialization bool Initialize(); + // Parses next frame from IVF stream and decodes the frame. + Vp9Decoder::Result DecodeNextFrame(); + private: Vp9Decoder(std::unique_ptr<IvfParser> ivf_parser, std::unique_ptr<V4L2IoctlShim> v4l2_ioctl, @@ -42,7 +52,7 @@ // Reads next frame from IVF stream and its size into |vp9_frame_header| // and |size| respectively. - Vp9Parser::Result ReadNextFrame(Vp9FrameHeader* vp9_frame_header, + Vp9Parser::Result ReadNextFrame(Vp9FrameHeader& vp9_frame_header, gfx::Size& size); // Parser for the IVF stream to decode.
diff --git a/net/cert/multi_log_ct_verifier_unittest.cc b/net/cert/multi_log_ct_verifier_unittest.cc index a26fbcd..bf944c2 100644 --- a/net/cert/multi_log_ct_verifier_unittest.cc +++ b/net/cert/multi_log_ct_verifier_unittest.cc
@@ -70,8 +70,9 @@ ASSERT_TRUE(embedded_sct_chain_.get()); } - bool CheckForEmbeddedSCTInNetLog(const RecordingTestNetLog& net_log) { - auto entries = net_log.GetEntries(); + bool CheckForEmbeddedSCTInNetLog( + const RecordingNetLogObserver& net_log_observer) { + auto entries = net_log_observer.GetEntries(); if (entries.size() != 2) return false; @@ -118,15 +119,15 @@ // |kLogDescription|. bool CheckPrecertificateVerification(scoped_refptr<X509Certificate> chain) { SignedCertificateTimestampAndStatusList scts; - RecordingTestNetLog test_net_log; + RecordingNetLogObserver net_log_observer(NetLogCaptureMode::kDefault); NetLogWithSource net_log = NetLogWithSource::Make( - &test_net_log, NetLogSourceType::SSL_CONNECT_JOB); + NetLog::Get(), NetLogSourceType::SSL_CONNECT_JOB); verifier_->Verify(kHostname, chain.get(), base::StringPiece(), base::StringPiece(), &scts, net_log); return ct::CheckForSingleVerifiedSCTInResult(scts, kLogDescription) && ct::CheckForSCTOrigin( scts, ct::SignedCertificateTimestamp::SCT_EMBEDDED) && - CheckForEmbeddedSCTInNetLog(test_net_log); + CheckForEmbeddedSCTInNetLog(net_log_observer); } // Histogram-related helper methods
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc index de6187a..bdb8e0c 100644 --- a/net/cookies/cookie_monster_unittest.cc +++ b/net/cookies/cookie_monster_unittest.cc
@@ -369,7 +369,7 @@ const int more_than_enough_cookies = domain_max_cookies + 10; // Add a bunch of cookies on a single host, should purge them. { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); for (int i = 0; i < more_than_enough_cookies; ++i) { std::string cookie = base::StringPrintf("a%03d=b", i); EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), cookie)); @@ -390,7 +390,7 @@ // between them. We shouldn't go above kDomainMaxCookies for both together. GURL url_google_specific(http_www_foo_.Format("http://www.gmail.%D")); { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); for (int i = 0; i < more_than_enough_cookies; ++i) { std::string cookie_general = base::StringPrintf("a%03d=b", i); EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), cookie_general)); @@ -426,7 +426,7 @@ // Test histogram for the number of registrable domains affected by domain // purge. { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); GURL url; for (int domain_num = 0; domain_num < 3; ++domain_num) { url = GURL(base::StringPrintf("http://domain%d.test", domain_num)); @@ -612,7 +612,7 @@ std::unique_ptr<CookieMonster> cm; if (alt_host_entries == nullptr) { - cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); } else { // When generating all of these cookies on alternate hosts, they need to // be all older than the max "safe" date for GC, which is currently 30 @@ -657,7 +657,7 @@ DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies - CookieMonster::kDomainPurgeCookies); - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); // Key: // Round 1 => LN; round 2 => LS; round 3 => MN. // Round 4 => HN; round 5 => MS; round 6 => HS @@ -723,7 +723,7 @@ DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies - CookieMonster::kDomainPurgeCookies); - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); // Key: // Round 1 => LN; round 2 => LS; round 3 => MN. // Round 4 => HN; round 5 => MS; round 6 => HS @@ -783,7 +783,7 @@ DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies - CookieMonster::kDomainPurgeCookies); - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); // Key: // Round 1 => LN; round 2 => LS; round 3 => MN. // Round 4 => HN; round 5 => MS; round 6 => HS @@ -905,7 +905,7 @@ void TestPartitionedCookiesGarbageCollectionHelper() { DCHECK_EQ(10u, CookieMonster::kPerPartitionDomainMaxCookies); int max_cookies = CookieMonster::kPerPartitionDomainMaxCookies; - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); auto cookie_partition_key = CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com")); @@ -927,7 +927,7 @@ // Function for creating a CM with a number of cookies in it, // no store (and hence no ability to affect access time). CookieMonster* CreateMonsterForGC(int num_cookies) { - CookieMonster* cm(new CookieMonster(nullptr, &net_log_)); + CookieMonster* cm(new CookieMonster(nullptr, net::NetLog::Get())); base::Time creation_time = base::Time::Now(); for (int i = 0; i < num_cookies; i++) { std::unique_ptr<CanonicalCookie> cc( @@ -961,7 +961,7 @@ return false; } - RecordingTestNetLog net_log_; + RecordingNetLogObserver net_log_; }; using CookieMonsterTest = CookieMonsterTestBase<CookieMonsterTestTraits>; @@ -994,8 +994,8 @@ DeferredCookieTaskTest() { persistent_store_ = base::MakeRefCounted<MockPersistentCookieStore>(); persistent_store_->set_store_load_commands(true); - cookie_monster_ = - std::make_unique<CookieMonster>(persistent_store_.get(), &net_log_); + cookie_monster_ = std::make_unique<CookieMonster>(persistent_store_.get(), + net::NetLog::Get()); } // Defines a cookie to be returned from PersistentCookieStore::Load @@ -1410,7 +1410,8 @@ TEST_F(CookieMonsterTest, TestCookieDeleteAll) { scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); CookieOptions options = CookieOptions::MakeAllInclusive(); EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), kValidCookieLine)); @@ -1453,7 +1454,7 @@ } TEST_F(CookieMonsterTest, TestCookieDeleteAllCreatedInTimeRangeTimestamps) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); Time now = Time::Now(); @@ -1541,7 +1542,7 @@ TEST_F(CookieMonsterTest, TestCookieDeleteAllCreatedInTimeRangeTimestampsWithInfo) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); Time now = Time::Now(); @@ -1629,7 +1630,7 @@ } TEST_F(CookieMonsterTest, TestCookieDeleteMatchingCookies) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); Time now = Time::Now(); // Nothing has been added so nothing should be deleted. @@ -1704,7 +1705,7 @@ TEST_F(CookieMonsterTest, TestLastAccess) { std::unique_ptr<CookieMonster> cm( - new CookieMonster(nullptr, kLastAccessThreshold, &net_log_)); + new CookieMonster(nullptr, kLastAccessThreshold, net::NetLog::Get())); EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "A=B")); const Time last_access_date(GetFirstCookieAccessDate(cm.get())); @@ -1762,9 +1763,10 @@ } TEST_F(CookieMonsterTest, SetCookieableSchemes) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); - std::unique_ptr<CookieMonster> cm_foo(new CookieMonster(nullptr, &net_log_)); + std::unique_ptr<CookieMonster> cm_foo( + new CookieMonster(nullptr, net::NetLog::Get())); // Only cm_foo should allow foo:// cookies. std::vector<std::string> schemes; @@ -1826,7 +1828,7 @@ TEST_F(CookieMonsterTest, GetAllCookiesForURL) { std::unique_ptr<CookieMonster> cm( - new CookieMonster(nullptr, kLastAccessThreshold, &net_log_)); + new CookieMonster(nullptr, kLastAccessThreshold, net::NetLog::Get())); // Create an httponly cookie. CookieOptions options = CookieOptions::MakeAllInclusive(); @@ -1943,7 +1945,7 @@ TEST_F(CookieMonsterTest, GetExcludedCookiesForURL) { std::unique_ptr<CookieMonster> cm( - new CookieMonster(nullptr, kLastAccessThreshold, &net_log_)); + new CookieMonster(nullptr, kLastAccessThreshold, net::NetLog::Get())); // Create an httponly cookie. CookieOptions options = CookieOptions::MakeAllInclusive(); @@ -2016,7 +2018,7 @@ } TEST_F(CookieMonsterTest, GetAllCookiesForURLPathMatching) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); CookieOptions options = CookieOptions::MakeAllInclusive(); @@ -2055,7 +2057,7 @@ } TEST_F(CookieMonsterTest, GetExcludedCookiesForURLPathMatching) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); CookieOptions options = CookieOptions::MakeAllInclusive(); @@ -2091,7 +2093,7 @@ } TEST_F(CookieMonsterTest, CookieSorting) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); base::Time system_time = base::Time::Now(); for (const char* cookie_line : @@ -2118,7 +2120,7 @@ } TEST_F(CookieMonsterTest, InheritCreationDate) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); base::Time the_not_so_distant_past(base::Time::Now() - base::Seconds(1000)); EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(), @@ -2149,7 +2151,7 @@ // Check that GetAllCookiesForURL() does not return expired cookies and deletes // them. TEST_F(CookieMonsterTest, DeleteExpiredCookiesOnGet) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "A=B;")); @@ -2246,7 +2248,8 @@ // Inject our initial cookies into the mock PersistentCookieStore. store->SetLoadExpectation(true, std::move(initial_cookies)); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); // Verify that duplicates were not imported for path "/". // (If this had failed, GetCookies() would have also returned X=1, X=2, X=4). @@ -2291,7 +2294,8 @@ initial_cookies.push_back(std::move(cc)); scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); store->SetLoadExpectation(true, std::move(initial_cookies)); @@ -2343,7 +2347,8 @@ // Inject our initial cookies into the mock PersistentCookieStore. store->SetLoadExpectation(true, std::move(initial_cookies)); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); CookieList list(GetAllCookies(cm.get())); EXPECT_EQ(2U, list.size()); @@ -2400,7 +2405,8 @@ // Inject our initial cookies into the mock PersistentCookieStore. store->SetLoadExpectation(true, std::move(initial_cookies)); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); CookieList list(GetAllCookies(cm.get())); EXPECT_EQ(2U, list.size()); @@ -2413,7 +2419,7 @@ } TEST_F(CookieMonsterTest, PredicateSeesAllCookies) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); const base::Time now = PopulateCmForPredicateCheck(cm.get()); // We test that we can see all cookies with |delete_info|. This includes @@ -2441,7 +2447,7 @@ // Mainly a test of GetEffectiveDomain, or more specifically, of the // expected behavior of GetEffectiveDomain within the CookieMonster. TEST_F(CookieMonsterTest, GetKey) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); // This test is really only interesting if GetKey() actually does something. EXPECT_EQ("foo.com", cm->GetKey("www.foo.com")); @@ -2488,7 +2494,7 @@ // Create new cookies and flush them to the store. { std::unique_ptr<CookieMonster> cmout( - new CookieMonster(store.get(), &net_log_)); + new CookieMonster(store.get(), net::NetLog::Get())); for (const auto& cookie : input_info) { EXPECT_TRUE(SetCanonicalCookie( cmout.get(), @@ -2508,7 +2514,7 @@ // Create a new cookie monster and make sure that everything is correct { std::unique_ptr<CookieMonster> cmin( - new CookieMonster(store.get(), &net_log_)); + new CookieMonster(store.get(), net::NetLog::Get())); CookieList cookies(GetAllCookies(cmin.get())); ASSERT_EQ(2u, cookies.size()); // Ordering is path length, then creation time. So second cookie @@ -2542,7 +2548,7 @@ base::MakeRefCounted<MockPersistentCookieStore>(); { - CookieMonster cmout(store.get(), &net_log_); + CookieMonster cmout(store.get(), net::NetLog::Get()); GURL url("http://www.example.com/"); EXPECT_TRUE( SetCookieWithCreationTime(&cmout, url, "A=1; max-age=600", current)); @@ -2564,7 +2570,7 @@ // Now read them in. Should get two cookies, not one. { - CookieMonster cmin(store2.get(), &net_log_); + CookieMonster cmin(store2.get(), net::NetLog::Get()); CookieList cookies(GetAllCookies(&cmin)); ASSERT_EQ(2u, cookies.size()); } @@ -2573,7 +2579,7 @@ TEST_F(CookieMonsterTest, CookieListOrdering) { // Put a random set of cookies into a monster and make sure // they're returned in the right order. - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); EXPECT_TRUE( SetCookie(cm.get(), GURL("http://d.c.b.a.foo.com/aa/x.html"), "c=1")); @@ -2712,7 +2718,8 @@ scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); store->set_store_load_commands(true); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); auto cookie = CanonicalCookie::Create( kUrl, "a=b", base::Time::Now(), absl::nullopt /* server_time */, @@ -2761,7 +2768,8 @@ scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); store->set_store_load_commands(true); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); ResultSavingCookieCallback<uint32_t> delete_callback; cm->DeleteAllAsync(delete_callback.MakeCallback()); @@ -2800,7 +2808,8 @@ scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); store->set_store_load_commands(true); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); GetAllCookiesCallback get_cookies_callback1; cm->GetAllCookiesAsync(get_cookies_callback1.MakeCallback()); @@ -2850,7 +2859,8 @@ scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); store->set_store_load_commands(true); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); // Get all cookies task that queues a task to set a cookie when executed. auto cookie = CanonicalCookie::Create( @@ -2894,7 +2904,7 @@ TEST_F(CookieMonsterTest, FlushStore) { auto counter = base::MakeRefCounted<CallbackCounter>(); auto store = base::MakeRefCounted<FlushablePersistentStore>(); - auto cm = std::make_unique<CookieMonster>(store, &net_log_); + auto cm = std::make_unique<CookieMonster>(store, net::NetLog::Get()); ASSERT_EQ(0, store->flush_count()); ASSERT_EQ(0, counter->callback_count()); @@ -2929,7 +2939,7 @@ ASSERT_EQ(2, counter->callback_count()); // If there's no backing store, FlushStore() is always a safe no-op. - cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); GetAllCookies(cm.get()); // Force init. cm->FlushStore(base::DoNothing()); base::RunLoop().RunUntilIdle(); @@ -2944,7 +2954,7 @@ TEST_F(CookieMonsterTest, SetAllCookies) { scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore()); - auto cm = std::make_unique<CookieMonster>(store.get(), &net_log_); + auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get()); cm->SetPersistSessionCookies(true); EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "U=V; path=/")); @@ -3014,7 +3024,7 @@ // Check that DeleteAll does flush (as a quick check that flush_count() works). TEST_F(CookieMonsterTest, DeleteAll) { scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore()); - auto cm = std::make_unique<CookieMonster>(store.get(), &net_log_); + auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get()); cm->SetPersistSessionCookies(true); EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "X=Y; path=/")); @@ -3041,7 +3051,7 @@ } TEST_F(CookieMonsterTest, HistogramCheck) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); // Should match call in InitializeHistograms, but doesn't really matter // since the histogram should have been initialized by the CM construction @@ -3086,7 +3096,8 @@ // CookieStore if the "persist session cookies" option is on. TEST_F(CookieMonsterTest, PersistSessionCookies) { scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); cm->SetPersistSessionCookies(true); // All cookies set with SetCookie are session cookies. @@ -3123,7 +3134,8 @@ // Test the commands sent to the persistent cookie store. TEST_F(CookieMonsterTest, PersisentCookieStorageTest) { scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); // Add a cookie. EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), @@ -3218,7 +3230,8 @@ // Inject our initial cookies into the mock PersistentCookieStore. store->SetLoadExpectation(true, std::move(initial_cookies)); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); EXPECT_EQ( "foo=bar; hello=world", @@ -3231,7 +3244,8 @@ const std::string cookie_source_histogram = "Cookie.CookieSourceScheme"; scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); histograms.ExpectTotalCount(cookie_source_histogram, 0); @@ -3317,7 +3331,7 @@ absl::nullopt /* cookie_partition_key */)); store->SetLoadExpectation(true /* return_value */, std::move(initial_cookies)); - auto cm = std::make_unique<CookieMonster>(store.get(), &net_log_); + auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get()); { base::HistogramTester histogram_tester; // Access the cookies to trigger loading from the persistent store. @@ -3462,7 +3476,8 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) { scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); // Set a secure, httponly cookie from a secure origin auto preexisting_cookie = CanonicalCookie::Create( @@ -3568,7 +3583,8 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus_PartitionedCookies) { scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); // Test adding two cookies with the same name, domain, and path but different // partition keys. @@ -3611,7 +3627,8 @@ // multiple reasons (Secure and HttpOnly). TEST_F(CookieMonsterTest, SkipDontOverwriteForMultipleReasons) { scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); // Set a secure, httponly cookie from a secure origin auto preexisting_cookie = CanonicalCookie::Create( @@ -3649,7 +3666,8 @@ // cookie should not be set. TEST_F(CookieMonsterTest, DontDeleteEquivalentCookieIfSetIsRejected) { scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); auto preexisting_cookie = CanonicalCookie::Create( http_www_foo_.url(), "cookie=foo", base::Time::Now(), @@ -3675,7 +3693,7 @@ } TEST_F(CookieMonsterTest, SetSecureCookies) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); GURL http_url("http://www.foo.com"); GURL http_superdomain_url("http://foo.com"); @@ -3842,7 +3860,7 @@ } TEST_F(CookieMonsterTest, SetSamePartyCookies) { - CookieMonster cm(nullptr, &net_log_); + CookieMonster cm(nullptr, net::NetLog::Get()); GURL http_url("http://www.foo.com"); GURL http_superdomain_url("http://foo.com"); GURL https_url("https://www.foo.com"); @@ -3899,7 +3917,7 @@ // Check domain-match criterion: If either cookie domain matches the other, // don't set the insecure cookie. TEST_F(CookieMonsterTest, LeaveSecureCookiesAlone_DomainMatch) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); // These domains will domain-match each other. const char* kRegistrableDomain = "foo.com"; @@ -4070,7 +4088,7 @@ // Check path-match criterion: If the new cookie is for the same path or a // subdirectory of the preexisting cookie's path, don't set the new cookie. TEST_F(CookieMonsterTest, LeaveSecureCookiesAlone_PathMatch) { - auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_); + auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get()); // A path that is later in this list will path-match all the paths before it. const char* kPaths[] = {"/", "/1", "/1/2", "/1/2/3"}; @@ -4887,7 +4905,8 @@ const char kHistogramName[] = "Cookie.DomainSet"; scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); histograms.ExpectTotalCount(kHistogramName, 0); @@ -4915,7 +4934,8 @@ const char kHistogramNameLocal[] = "Cookie.Port.Read.Localhost"; scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); histograms.ExpectTotalCount(kHistogramName, 0); @@ -4968,7 +4988,8 @@ const char kHistogramNameLocal[] = "Cookie.Port.Set.Localhost"; scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); histograms.ExpectTotalCount(kHistogramName, 0); @@ -5022,7 +5043,8 @@ "Cookie.Port.ReadDiffersFromSet.DomainSet"; scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); histograms.ExpectTotalCount(kHistogramName, 0); @@ -5121,7 +5143,8 @@ const char kHistogramName[] = "Cookie.CookieSourceSchemeName"; scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore); - std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); + std::unique_ptr<CookieMonster> cm( + new CookieMonster(store.get(), net::NetLog::Get())); histograms.ExpectTotalCount(kHistogramName, 0);
diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc index df6b1e4..30fe99a 100644 --- a/net/dns/dns_transaction_unittest.cc +++ b/net/dns/dns_transaction_unittest.cc
@@ -47,7 +47,6 @@ #include "net/log/net_log.h" #include "net/log/net_log_capture_mode.h" #include "net/log/net_log_with_source.h" -#include "net/log/test_net_log.h" #include "net/proxy_resolution/proxy_config_service_fixed.h" #include "net/socket/socket_test_util.h" #include "net/test/gtest_util.h" @@ -338,8 +337,9 @@ ResolveContext* context) { std::unique_ptr<DnsTransaction> transaction = factory->CreateTransaction( hostname, qtype, CompletionCallback(), - NetLogWithSource::Make(&net_log_, net::NetLogSourceType::NONE), secure, - factory->GetSecureDnsModeForTest(), context, true /* fast_timeout */); + NetLogWithSource::Make(net::NetLog::Get(), net::NetLogSourceType::NONE), + secure, factory->GetSecureDnsModeForTest(), context, + true /* fast_timeout */); transaction->SetRequestPriority(DEFAULT_PRIORITY); EXPECT_EQ(qtype, transaction->GetType()); StartTransaction(std::move(transaction)); @@ -401,7 +401,6 @@ bool has_completed() const { return completed_; } const DnsResponse* response() const { return response_; } - NetLog* net_log() { return &net_log_; } // Runs until the completion callback is called. Transaction must have already // been started or this will never complete. @@ -420,7 +419,6 @@ bool cancel_in_callback_ = false; base::RunLoop transaction_complete_run_loop_; bool completed_ = false; - TestNetLog net_log_; }; // Callback that allows a test to modify HttpResponseinfo @@ -2590,7 +2588,7 @@ false /* enqueue_transaction_id */); TransactionHelper helper0(kT0RecordCount); CountingObserver observer; - helper0.net_log()->AddObserver(&observer, NetLogCaptureMode::kEverything); + NetLog::Get()->AddObserver(&observer, NetLogCaptureMode::kEverything); helper0.StartTransaction(transaction_factory_.get(), kT0HostName, kT0Qtype, true /* secure */, resolve_context_.get()); helper0.RunUntilComplete();
diff --git a/net/dns/host_resolver_manager_fuzzer.cc b/net/dns/host_resolver_manager_fuzzer.cc index 7c0ed59..cc17b8cb 100644 --- a/net/dns/host_resolver_manager_fuzzer.cc +++ b/net/dns/host_resolver_manager_fuzzer.cc
@@ -25,6 +25,7 @@ #include "net/dns/host_resolver.h" #include "net/dns/public/dns_query_type.h" #include "net/dns/public/host_resolver_source.h" +#include "net/log/net_log.h" #include "net/log/net_log_with_source.h" #include "net/log/test_net_log.h" #include "net/net_buildflags.h" @@ -236,7 +237,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { { FuzzedDataProvider data_provider(data, size); - net::RecordingTestNetLog net_log; + // Including an observer; even though the recorded results aren't currently + // used, it'll ensure the netlogging code is fuzzed as well. + net::RecordingNetLogObserver net_log_observer; net::HostResolver::ManagerOptions options; options.max_concurrent_resolves = @@ -244,8 +247,8 @@ options.insecure_dns_client_enabled = data_provider.ConsumeBool(); bool enable_caching = data_provider.ConsumeBool(); std::unique_ptr<net::ContextHostResolver> host_resolver = - net::CreateFuzzedContextHostResolver(options, &net_log, &data_provider, - enable_caching); + net::CreateFuzzedContextHostResolver(options, net::NetLog::Get(), + &data_provider, enable_caching); std::vector<std::unique_ptr<DnsRequest>> dns_requests; bool done = false;
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc index 5890ed4..e4e7350 100644 --- a/net/dns/host_resolver_manager_unittest.cc +++ b/net/dns/host_resolver_manager_unittest.cc
@@ -2497,15 +2497,15 @@ nullptr /* net_log */); // Verify that two consecutive calls return the same value. - RecordingTestNetLog test_net_log; + RecordingNetLogObserver net_log_observer; NetLogWithSource net_log = - NetLogWithSource::Make(&test_net_log, NetLogSourceType::NONE); + NetLogWithSource::Make(net::NetLog::Get(), NetLogSourceType::NONE); bool result1 = IsIPv6Reachable(net_log); bool result2 = IsIPv6Reachable(net_log); EXPECT_EQ(result1, result2); // Filter reachability check events and verify that there are two of them. - auto probe_event_list = test_net_log.GetEntriesWithType( + auto probe_event_list = net_log_observer.GetEntriesWithType( NetLogEventType::HOST_RESOLVER_MANAGER_IPV6_REACHABILITY_CHECK); ASSERT_EQ(2U, probe_event_list.size());
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 1d0d919..bff22d0 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -911,10 +911,9 @@ request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog log; MockHostResolver* resolver = new MockHostResolver(); resolver->rules()->AddSimulatedTimeoutFailure("www.example.org"); - session_deps_.net_log = &log; + session_deps_.net_log = net::NetLog::Get(); session_deps_.host_resolver.reset(resolver); std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); @@ -1886,8 +1885,7 @@ request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); // Written data for successfully sending both requests. @@ -1987,8 +1985,7 @@ request.upload_data_stream = &upload_data_stream; } - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); SSLSocketDataProvider ssl1(ASYNC, OK); @@ -2464,8 +2461,7 @@ request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); const char* request_data = @@ -2888,8 +2884,7 @@ request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog log; - session_deps_.net_log = &log; + session_deps_.net_log = net::NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); @@ -2994,9 +2989,8 @@ request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog log; MockHostResolver* resolver = new MockHostResolver(); - session_deps_.net_log = &log; + session_deps_.net_log = net::NetLog::Get(); session_deps_.host_resolver.reset(resolver); std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); @@ -3108,8 +3102,7 @@ request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog log; - session_deps_.net_log = &log; + session_deps_.net_log = net::NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); @@ -3228,8 +3221,7 @@ request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog log; - session_deps_.net_log = &log; + session_deps_.net_log = net::NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); MockWrite data_writes[] = { @@ -6392,14 +6384,13 @@ request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog log; // Configure against https proxy server "proxy:70". session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateFixed( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); MockHostResolver* resolver = new MockHostResolver(); resolver->rules()->AddSimulatedTimeoutFailure("proxy"); - session_deps_.net_log = &log; + session_deps_.net_log = net::NetLog::Get(); session_deps_.host_resolver.reset(resolver); std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); @@ -11259,8 +11250,7 @@ session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateFixedFromPacResult( "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); HttpRequestInfo request; request.method = "GET"; @@ -11324,8 +11314,7 @@ session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateFixedFromPacResult( "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); const base::TimeDelta kTimeIncrement = base::Seconds(4); session_deps_.host_resolver->set_ondemand_mode(true); @@ -11392,8 +11381,7 @@ session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateFixedFromPacResult( "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); HttpRequestInfo request; request.method = "GET"; @@ -11440,8 +11428,7 @@ session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateFixedFromAutoDetectedPacResult( "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); HttpRequestInfo request; request.load_flags = LOAD_MAIN_FRAME_DEPRECATED; @@ -11488,8 +11475,7 @@ session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateFixed( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); const base::TimeDelta kTimeIncrement = base::Seconds(4); session_deps_.host_resolver->set_ondemand_mode(true); @@ -12310,8 +12296,7 @@ session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateFixedFromPacResult( "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); @@ -12367,8 +12352,7 @@ session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateFixedFromPacResult( "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); @@ -12429,8 +12413,7 @@ session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateFixed( "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); @@ -12485,8 +12468,7 @@ session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateFixedFromPacResult( "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); @@ -12554,8 +12536,7 @@ session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateFixedFromPacResult( "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); @@ -14711,14 +14692,12 @@ auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>( &capturing_proxy_resolver); - RecordingTestNetLog net_log; - session_deps_.proxy_resolution_service = std::make_unique<ConfiguredProxyResolutionService>( std::move(proxy_config_service), std::move(proxy_resolver_factory), - &net_log, /*quick_check_enabled=*/true); + net::NetLog::Get(), /*quick_check_enabled=*/true); - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); // Configure alternative service with a hostname that is not bypassed by the // proxy. @@ -14798,8 +14777,7 @@ std::make_unique<CapturingProxyResolverFactory>( &capturing_proxy_resolver), nullptr, /*quick_check_enabled=*/true); - RecordingTestNetLog net_log; - session_deps_.net_log = &net_log; + session_deps_.net_log = net::NetLog::Get(); HttpRequestInfo request; request.method = "GET"; @@ -18067,8 +18045,7 @@ session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateFixedFromPacResult( "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); - RecordingTestNetLog log; - session_deps_.net_log = &log; + session_deps_.net_log = net::NetLog::Get(); SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy ssl1.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
diff --git a/net/http/http_proxy_client_socket_fuzzer.cc b/net/http/http_proxy_client_socket_fuzzer.cc index 12d2fd8f6..9a7b0e6 100644 --- a/net/http/http_proxy_client_socket_fuzzer.cc +++ b/net/http/http_proxy_client_socket_fuzzer.cc
@@ -24,6 +24,7 @@ #include "net/http/http_auth_handler_digest.h" #include "net/http/http_auth_handler_factory.h" #include "net/http/http_auth_scheme.h" +#include "net/log/net_log.h" #include "net/log/test_net_log.h" #include "net/socket/fuzzed_socket.h" #include "net/socket/next_proto.h" @@ -35,14 +36,14 @@ // |data| is used to create a FuzzedSocket to fuzz reads and writes, see that // class for details. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - // Use a test NetLog, to exercise logging code. - net::RecordingTestNetLog test_net_log; - FuzzedDataProvider data_provider(data, size); + // Including an observer; even though the recorded results aren't currently + // used, it'll ensure the netlogging code is fuzzed as well. + net::RecordingNetLogObserver net_log_observer; net::TestCompletionCallback callback; std::unique_ptr<net::FuzzedSocket> fuzzed_socket( - new net::FuzzedSocket(&data_provider, &test_net_log)); + new net::FuzzedSocket(&data_provider, net::NetLog::Get())); CHECK_EQ(net::OK, fuzzed_socket->Connect(callback.callback())); // Create auth handler supporting basic and digest schemes. Other schemes can
diff --git a/net/log/file_net_log_observer_unittest.cc b/net/log/file_net_log_observer_unittest.cc index 611266e2d..4785a058 100644 --- a/net/log/file_net_log_observer_unittest.cc +++ b/net/log/file_net_log_observer_unittest.cc
@@ -23,13 +23,13 @@ #include "base/values.h" #include "build/build_config.h" #include "net/base/test_completion_callback.h" +#include "net/log/net_log.h" #include "net/log/net_log_entry.h" #include "net/log/net_log_event_type.h" #include "net/log/net_log_source.h" #include "net/log/net_log_source_type.h" #include "net/log/net_log_util.h" #include "net/log/net_log_values.h" -#include "net/log/test_net_log.h" #include "net/test/test_with_task_environment.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" @@ -246,7 +246,7 @@ std::move(constants)); } - logger_->StartObserving(&net_log_); + logger_->StartObserving(NetLog::Get()); } void CreateAndStartObservingPreExisting( @@ -268,7 +268,7 @@ std::move(file), NetLogCaptureMode::kDefault, std::move(constants)); } - logger_->StartObserving(&net_log_); + logger_->StartObserving(NetLog::Get()); } bool LogFileExists() { @@ -280,7 +280,6 @@ } protected: - TestNetLog net_log_; std::unique_ptr<FileNetLogObserver> logger_; base::ScopedTempDir temp_dir_; base::ScopedTempDir scratch_dir_; // used for bounded + preexisting @@ -308,7 +307,7 @@ logger_ = FileNetLogObserver::CreateBoundedForTests( log_path_, total_file_size, num_files, NetLogCaptureMode::kDefault, std::move(constants)); - logger_->StartObserving(&net_log_); + logger_->StartObserving(NetLog::Get()); } // Returns the path for an internally directory created for bounded logs (this @@ -332,7 +331,6 @@ protected: - TestNetLog net_log_; std::unique_ptr<FileNetLogObserver> logger_; base::FilePath log_path_; @@ -495,7 +493,7 @@ else logger_ = FileNetLogObserver::CreateUnboundedPreExisting( std::move(file), NetLogCaptureMode::kDefault, nullptr); - logger_->StartObserving(&net_log_); + logger_->StartObserving(NetLog::Get()); // Send dummy event. AddEntries(logger_.get(), 1, kDummyEventSize); @@ -975,7 +973,7 @@ logger_ = FileNetLogObserver::CreateBoundedPreExisting( scratch_dir.GetPath(), std::move(file), kLargeFileSize, NetLogCaptureMode::kDefault, nullptr); - logger_->StartObserving(&net_log_); + logger_->StartObserving(NetLog::Get()); base::ThreadPoolInstance::Get()->FlushForTesting(); EXPECT_TRUE(base::PathExists(log_path_)); @@ -1046,7 +1044,7 @@ for (size_t i = 0; i < kNumThreads; ++i) { threads[i]->task_runner()->PostTask( FROM_HERE, - base::BindOnce(&AddEntriesViaNetLog, base::Unretained(&net_log_), + base::BindOnce(&AddEntriesViaNetLog, base::Unretained(NetLog::Get()), kNumEventsAddedPerThread)); } @@ -1082,7 +1080,7 @@ for (size_t i = 0; i < kNumThreads; ++i) { threads[i]->task_runner()->PostTask( FROM_HERE, - base::BindOnce(&AddEntriesViaNetLog, base::Unretained(&net_log_), + base::BindOnce(&AddEntriesViaNetLog, base::Unretained(NetLog::Get()), kNumEventsAddedPerThread)); }
diff --git a/net/log/net_log_unittest.cc b/net/log/net_log_unittest.cc index 6bab0011..c5a9f16 100644 --- a/net/log/net_log_unittest.cc +++ b/net/log/net_log_unittest.cc
@@ -39,25 +39,25 @@ TEST(NetLogTest, BasicGlobalEvents) { base::test::TaskEnvironment task_environment{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; - RecordingTestNetLog net_log; - auto entries = net_log.GetEntries(); + RecordingNetLogObserver net_log_observer; + auto entries = net_log_observer.GetEntries(); EXPECT_EQ(0u, entries.size()); task_environment.FastForwardBy(base::Seconds(1234)); base::TimeTicks ticks0 = base::TimeTicks::Now(); - net_log.AddGlobalEntry(NetLogEventType::CANCELLED); + NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED); task_environment.FastForwardBy(base::Seconds(5678)); base::TimeTicks ticks1 = base::TimeTicks::Now(); EXPECT_LE(ticks0, ticks1); - net_log.AddGlobalEntry(NetLogEventType::FAILED); + NetLog::Get()->AddGlobalEntry(NetLogEventType::FAILED); task_environment.FastForwardBy(base::Seconds(91011)); EXPECT_LE(ticks1, base::TimeTicks::Now()); - entries = net_log.GetEntries(); + entries = net_log_observer.GetEntries(); ASSERT_EQ(2u, entries.size()); EXPECT_EQ(NetLogEventType::CANCELLED, entries[0].type); @@ -81,15 +81,15 @@ TEST(NetLogTest, BasicEventsWithSource) { base::test::TaskEnvironment task_environment{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; - RecordingTestNetLog net_log; - auto entries = net_log.GetEntries(); + RecordingNetLogObserver net_log_observer; + auto entries = net_log_observer.GetEntries(); EXPECT_EQ(0u, entries.size()); task_environment.FastForwardBy(base::Seconds(9876)); base::TimeTicks source0_start_ticks = base::TimeTicks::Now(); NetLogWithSource source0 = - NetLogWithSource::Make(&net_log, NetLogSourceType::URL_REQUEST); + NetLogWithSource::Make(NetLog::Get(), NetLogSourceType::URL_REQUEST); task_environment.FastForwardBy(base::Seconds(1)); base::TimeTicks source0_event0_ticks = base::TimeTicks::Now(); source0.BeginEvent(NetLogEventType::REQUEST_ALIVE); @@ -98,7 +98,7 @@ base::TimeTicks source1_start_ticks = base::TimeTicks::Now(); NetLogWithSource source1 = - NetLogWithSource::Make(&net_log, NetLogSourceType::SOCKET); + NetLogWithSource::Make(NetLog::Get(), NetLogSourceType::SOCKET); task_environment.FastForwardBy(base::Seconds(1)); base::TimeTicks source1_event0_ticks = base::TimeTicks::Now(); source1.BeginEvent(NetLogEventType::SOCKET_ALIVE); @@ -112,7 +112,7 @@ task_environment.FastForwardBy(base::Seconds(123)); - entries = net_log.GetEntries(); + entries = net_log_observer.GetEntries(); ASSERT_EQ(4u, entries.size()); EXPECT_EQ(NetLogEventType::REQUEST_ALIVE, entries[0].type); @@ -157,18 +157,17 @@ NetLogCaptureMode::kEverything, }; - RecordingTestNetLog net_log; + RecordingNetLogObserver net_log_observer; for (NetLogCaptureMode mode : kModes) { - net_log.SetObserverCaptureMode(mode); - EXPECT_EQ(mode, net_log.GetObserver()->capture_mode()); + net_log_observer.SetObserverCaptureMode(mode); - net_log.AddGlobalEntry(NetLogEventType::SOCKET_ALIVE, - [&](NetLogCaptureMode capture_mode) { - return NetCaptureModeParams(capture_mode); - }); + NetLog::Get()->AddGlobalEntry(NetLogEventType::SOCKET_ALIVE, + [&](NetLogCaptureMode capture_mode) { + return NetCaptureModeParams(capture_mode); + }); - auto entries = net_log.GetEntries(); + auto entries = net_log_observer.GetEntries(); ASSERT_EQ(1u, entries.size()); EXPECT_EQ(NetLogEventType::SOCKET_ALIVE, entries[0].type); @@ -181,7 +180,7 @@ ASSERT_EQ(CaptureModeToInt(mode), GetIntegerValueFromParams(entries[0], "capture_mode")); - net_log.Clear(); + net_log_observer.Clear(); } } @@ -336,18 +335,15 @@ // Makes sure that events on multiple threads are dispatched to all observers. TEST(NetLogTest, NetLogEventThreads) { - TestNetLog net_log; - - // Attach some observers. Since they're created after |net_log|, they'll - // safely detach themselves on destruction. + // Attach some observers. They'll safely detach themselves on destruction. CountingObserver observers[3]; for (size_t i = 0; i < base::size(observers); ++i) { - net_log.AddObserver(&observers[i], NetLogCaptureMode::kEverything); + NetLog::Get()->AddObserver(&observers[i], NetLogCaptureMode::kEverything); } // Run a bunch of threads to completion, each of which will emit events to // |net_log|. - RunTestThreads<AddEventsTestThread>(&net_log); + RunTestThreads<AddEventsTestThread>(NetLog::Get()); // Check that each observer saw the emitted events. const int kTotalEvents = kThreads * kEvents; @@ -357,70 +353,69 @@ // Test adding and removing a single observer. TEST(NetLogTest, NetLogAddRemoveObserver) { - TestNetLog net_log; CountingObserver observer; - AddEvent(&net_log); + AddEvent(NetLog::Get()); EXPECT_EQ(0, observer.count()); EXPECT_EQ(NULL, observer.net_log()); - EXPECT_FALSE(net_log.IsCapturing()); + EXPECT_FALSE(NetLog::Get()->IsCapturing()); // Add the observer and add an event. - net_log.AddObserver(&observer, NetLogCaptureMode::kIncludeSensitive); - EXPECT_TRUE(net_log.IsCapturing()); - EXPECT_EQ(&net_log, observer.net_log()); + NetLog::Get()->AddObserver(&observer, NetLogCaptureMode::kIncludeSensitive); + EXPECT_TRUE(NetLog::Get()->IsCapturing()); + EXPECT_EQ(NetLog::Get(), observer.net_log()); EXPECT_EQ(NetLogCaptureMode::kIncludeSensitive, observer.capture_mode()); - EXPECT_TRUE(net_log.IsCapturing()); + EXPECT_TRUE(NetLog::Get()->IsCapturing()); - AddEvent(&net_log); + AddEvent(NetLog::Get()); EXPECT_EQ(1, observer.count()); - AddEvent(&net_log); + AddEvent(NetLog::Get()); EXPECT_EQ(2, observer.count()); // Remove observer and add an event. - net_log.RemoveObserver(&observer); + NetLog::Get()->RemoveObserver(&observer); EXPECT_EQ(NULL, observer.net_log()); - EXPECT_FALSE(net_log.IsCapturing()); + EXPECT_FALSE(NetLog::Get()->IsCapturing()); - AddEvent(&net_log); + AddEvent(NetLog::Get()); EXPECT_EQ(2, observer.count()); // Add the observer a final time, this time with a different capture mdoe, and // add an event. - net_log.AddObserver(&observer, NetLogCaptureMode::kEverything); - EXPECT_EQ(&net_log, observer.net_log()); + NetLog::Get()->AddObserver(&observer, NetLogCaptureMode::kEverything); + EXPECT_EQ(NetLog::Get(), observer.net_log()); EXPECT_EQ(NetLogCaptureMode::kEverything, observer.capture_mode()); - EXPECT_TRUE(net_log.IsCapturing()); + EXPECT_TRUE(NetLog::Get()->IsCapturing()); - AddEvent(&net_log); + AddEvent(NetLog::Get()); EXPECT_EQ(3, observer.count()); } // Test adding and removing two observers at different log levels. TEST(NetLogTest, NetLogTwoObservers) { - TestNetLog net_log; LoggingObserver observer[2]; // Add first observer. - net_log.AddObserver(&observer[0], NetLogCaptureMode::kIncludeSensitive); - EXPECT_EQ(&net_log, observer[0].net_log()); + NetLog::Get()->AddObserver(&observer[0], + NetLogCaptureMode::kIncludeSensitive); + EXPECT_EQ(NetLog::Get(), observer[0].net_log()); EXPECT_EQ(NULL, observer[1].net_log()); EXPECT_EQ(NetLogCaptureMode::kIncludeSensitive, observer[0].capture_mode()); - EXPECT_TRUE(net_log.IsCapturing()); + EXPECT_TRUE(NetLog::Get()->IsCapturing()); // Add second observer observer. - net_log.AddObserver(&observer[1], NetLogCaptureMode::kEverything); - EXPECT_EQ(&net_log, observer[0].net_log()); - EXPECT_EQ(&net_log, observer[1].net_log()); + NetLog::Get()->AddObserver(&observer[1], NetLogCaptureMode::kEverything); + EXPECT_EQ(NetLog::Get(), observer[0].net_log()); + EXPECT_EQ(NetLog::Get(), observer[1].net_log()); EXPECT_EQ(NetLogCaptureMode::kIncludeSensitive, observer[0].capture_mode()); EXPECT_EQ(NetLogCaptureMode::kEverything, observer[1].capture_mode()); - EXPECT_TRUE(net_log.IsCapturing()); + EXPECT_TRUE(NetLog::Get()->IsCapturing()); // Add event and make sure both observers receive it at their respective log // levels. absl::optional<int> param; - AddEvent(&net_log); + AddEvent(NetLog::Get()); ASSERT_EQ(1U, observer[0].GetNumValues()); param = observer[0].GetValue(0)->FindIntKey("params"); ASSERT_TRUE(param); @@ -431,25 +426,25 @@ EXPECT_EQ(CaptureModeToInt(observer[1].capture_mode()), param.value()); // Remove second observer. - net_log.RemoveObserver(&observer[1]); - EXPECT_EQ(&net_log, observer[0].net_log()); + NetLog::Get()->RemoveObserver(&observer[1]); + EXPECT_EQ(NetLog::Get(), observer[0].net_log()); EXPECT_EQ(NULL, observer[1].net_log()); EXPECT_EQ(NetLogCaptureMode::kIncludeSensitive, observer[0].capture_mode()); - EXPECT_TRUE(net_log.IsCapturing()); + EXPECT_TRUE(NetLog::Get()->IsCapturing()); // Add event and make sure only second observer gets it. - AddEvent(&net_log); + AddEvent(NetLog::Get()); EXPECT_EQ(2U, observer[0].GetNumValues()); EXPECT_EQ(1U, observer[1].GetNumValues()); // Remove first observer. - net_log.RemoveObserver(&observer[0]); + NetLog::Get()->RemoveObserver(&observer[0]); EXPECT_EQ(NULL, observer[0].net_log()); EXPECT_EQ(NULL, observer[1].net_log()); - EXPECT_FALSE(net_log.IsCapturing()); + EXPECT_FALSE(NetLog::Get()->IsCapturing()); // Add event and make sure neither observer gets it. - AddEvent(&net_log); + AddEvent(NetLog::Get()); EXPECT_EQ(2U, observer[0].GetNumValues()); EXPECT_EQ(1U, observer[1].GetNumValues()); } @@ -457,11 +452,9 @@ // Makes sure that adding and removing observers simultaneously on different // threads works. TEST(NetLogTest, NetLogAddRemoveObserverThreads) { - TestNetLog net_log; - // Run a bunch of threads to completion, each of which will repeatedly add // and remove an observer, and set its logging level. - RunTestThreads<AddRemoveObserverTestThread>(&net_log); + RunTestThreads<AddRemoveObserverTestThread>(NetLog::Get()); } // Tests that serializing a NetLogEntry with empty parameters omits a value for
diff --git a/net/log/net_log_util_unittest.cc b/net/log/net_log_util_unittest.cc index 35d3f9a..7492acd 100644 --- a/net/log/net_log_util_unittest.cc +++ b/net/log/net_log_util_unittest.cc
@@ -94,8 +94,7 @@ // Using same context for each iteration makes sure deleted requests don't // appear in the list, or result in crashes. TestURLRequestContext context(true); - TestNetLog net_log; - context.set_net_log(&net_log); + context.set_net_log(NetLog::Get()); context.Init(); TestDelegate delegate; for (size_t num_requests = 0; num_requests < 5; ++num_requests) { @@ -107,9 +106,9 @@ } std::set<URLRequestContext*> contexts; contexts.insert(&context); - RecordingTestNetLog test_net_log; - CreateNetLogEntriesForActiveObjects(contexts, test_net_log.GetObserver()); - auto entry_list = test_net_log.GetEntries(); + RecordingNetLogObserver net_log_observer; + CreateNetLogEntriesForActiveObjects(contexts, &net_log_observer); + auto entry_list = net_log_observer.GetEntries(); ASSERT_EQ(num_requests, entry_list.size()); for (size_t i = 0; i < num_requests; ++i) { @@ -125,23 +124,21 @@ TestDelegate delegate; for (size_t num_requests = 0; num_requests < 5; ++num_requests) { - TestNetLog net_log; std::vector<std::unique_ptr<TestURLRequestContext>> contexts; std::vector<std::unique_ptr<URLRequest>> requests; std::set<URLRequestContext*> context_set; for (size_t i = 0; i < num_requests; ++i) { contexts.push_back(std::make_unique<TestURLRequestContext>(true)); - contexts[i]->set_net_log(&net_log); + contexts[i]->set_net_log(NetLog::Get()); contexts[i]->Init(); context_set.insert(contexts[i].get()); requests.push_back( contexts[i]->CreateRequest(GURL("about:hats"), DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); } - RecordingTestNetLog test_net_log; - CreateNetLogEntriesForActiveObjects(context_set, - test_net_log.GetObserver()); - auto entry_list = test_net_log.GetEntries(); + RecordingNetLogObserver net_log_observer; + CreateNetLogEntriesForActiveObjects(context_set, &net_log_observer); + auto entry_list = net_log_observer.GetEntries(); ASSERT_EQ(num_requests, entry_list.size()); for (size_t i = 0; i < num_requests; ++i) {
diff --git a/net/log/trace_net_log_observer_unittest.cc b/net/log/trace_net_log_observer_unittest.cc index 5cb1837..e517ce5 100644 --- a/net/log/trace_net_log_observer_unittest.cc +++ b/net/log/trace_net_log_observer_unittest.cc
@@ -21,6 +21,7 @@ #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_impl.h" #include "base/values.h" +#include "net/log/net_log.h" #include "net/log/net_log_event_type.h" #include "net/log/net_log_source_type.h" #include "net/log/net_log_with_source.h" @@ -39,6 +40,7 @@ struct TraceEntryInfo { std::string category; + // The netlog source id formatted as a hexadecimal string. std::string id; std::string phase; std::string name; @@ -179,7 +181,7 @@ size_t trace_events_size() const { return trace_events_->GetList().size(); } - RecordingTestNetLog* net_log() { return &net_log_; } + RecordingNetLogObserver* net_log_observer() { return &net_log_observer_; } TraceNetLogObserver* trace_net_log_observer() const { return trace_net_log_observer_.get(); @@ -189,13 +191,13 @@ std::unique_ptr<base::Value> trace_events_; base::trace_event::TraceResultBuffer trace_buffer_; base::trace_event::TraceResultBuffer::SimpleOutput json_output_; - RecordingTestNetLog net_log_; + RecordingNetLogObserver net_log_observer_; std::unique_ptr<TraceNetLogObserver> trace_net_log_observer_; }; TEST_F(TraceNetLogObserverTest, TracingNotEnabled) { - trace_net_log_observer()->WatchForTraceStart(net_log()); - net_log()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); + trace_net_log_observer()->WatchForTraceStart(NetLog::Get()); + NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); EndTraceAndFlush(); trace_net_log_observer()->StopWatchForTraceStart(); @@ -206,14 +208,14 @@ // This test will result in a deadlock if EnabledStateObserver instead // of AsyncEnabledStateObserver is used. Regression test for crbug.com/760817. TEST_F(TraceNetLogObserverTest, TracingDisabledDuringOnAddEntry) { - trace_net_log_observer()->WatchForTraceStart(net_log()); + trace_net_log_observer()->WatchForTraceStart(NetLog::Get()); TraceLog* trace_log = TraceLog::GetInstance(); trace_log->SetTraceBufferForTesting(base::WrapUnique( base::trace_event::TraceBuffer::CreateTraceBufferVectorOfSize(1))); EnableTraceLogWithNetLog(); // TraceLog will disable itself when an event makes the TraceBuffer full. while (!trace_log->BufferIsFull()) { - net_log()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); + NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); } base::RunLoop().RunUntilIdle(); @@ -225,18 +227,18 @@ } TEST_F(TraceNetLogObserverTest, TraceEventCaptured) { - auto entries = net_log()->GetEntries(); + auto entries = net_log_observer()->GetEntries(); EXPECT_TRUE(entries.empty()); - trace_net_log_observer()->WatchForTraceStart(net_log()); + trace_net_log_observer()->WatchForTraceStart(NetLog::Get()); EnableTraceLogWithNetLog(); NetLogWithSource net_log_with_source = - NetLogWithSource::Make(net_log(), net::NetLogSourceType::NONE); - net_log()->AddGlobalEntry(NetLogEventType::CANCELLED); + NetLogWithSource::Make(NetLog::Get(), net::NetLogSourceType::NONE); + NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED); net_log_with_source.BeginEvent(NetLogEventType::URL_REQUEST_START_JOB); net_log_with_source.EndEvent(NetLogEventType::REQUEST_ALIVE); - entries = net_log()->GetEntries(); + entries = net_log_observer()->GetEntries(); EXPECT_EQ(3u, entries.size()); EndTraceAndFlush(); trace_net_log_observer()->StopWatchForTraceStart(); @@ -254,7 +256,7 @@ TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(*item2); TraceEntryInfo actual_item3 = GetTraceEntryInfoFromValue(*item3); EXPECT_EQ(kNetLogTracingCategory, actual_item1.category); - EXPECT_EQ(base::StringPrintf("0x%d", entries[0].source.id), actual_item1.id); + EXPECT_EQ(base::StringPrintf("0x%x", entries[0].source.id), actual_item1.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT), actual_item1.phase); EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::CANCELLED), @@ -263,7 +265,7 @@ actual_item1.source_type); EXPECT_EQ(kNetLogTracingCategory, actual_item2.category); - EXPECT_EQ(base::StringPrintf("0x%d", entries[1].source.id), actual_item2.id); + EXPECT_EQ(base::StringPrintf("0x%x", entries[1].source.id), actual_item2.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN), actual_item2.phase); EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::URL_REQUEST_START_JOB), @@ -272,7 +274,7 @@ actual_item2.source_type); EXPECT_EQ(kNetLogTracingCategory, actual_item3.category); - EXPECT_EQ(base::StringPrintf("0x%d", entries[2].source.id), actual_item3.id); + EXPECT_EQ(base::StringPrintf("0x%x", entries[2].source.id), actual_item3.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_END), actual_item3.phase); EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::REQUEST_ALIVE), @@ -282,18 +284,18 @@ } TEST_F(TraceNetLogObserverTest, EnableAndDisableTracing) { - trace_net_log_observer()->WatchForTraceStart(net_log()); + trace_net_log_observer()->WatchForTraceStart(NetLog::Get()); EnableTraceLogWithNetLog(); - net_log()->AddGlobalEntry(NetLogEventType::CANCELLED); + NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED); DisableTraceLog(); - net_log()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); + NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); EnableTraceLogWithNetLog(); - net_log()->AddGlobalEntry(NetLogEventType::URL_REQUEST_START_JOB); + NetLog::Get()->AddGlobalEntry(NetLogEventType::URL_REQUEST_START_JOB); EndTraceAndFlush(); trace_net_log_observer()->StopWatchForTraceStart(); - auto entries = net_log()->GetEntries(); + auto entries = net_log_observer()->GetEntries(); EXPECT_EQ(3u, entries.size()); EXPECT_EQ(2u, trace_events_size()); const base::Value* item1 = &trace_events()->GetList()[0]; @@ -304,7 +306,7 @@ TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1); TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(*item2); EXPECT_EQ(kNetLogTracingCategory, actual_item1.category); - EXPECT_EQ(base::StringPrintf("0x%d", entries[0].source.id), actual_item1.id); + EXPECT_EQ(base::StringPrintf("0x%x", entries[0].source.id), actual_item1.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT), actual_item1.phase); EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::CANCELLED), @@ -313,7 +315,7 @@ actual_item1.source_type); EXPECT_EQ(kNetLogTracingCategory, actual_item2.category); - EXPECT_EQ(base::StringPrintf("0x%d", entries[2].source.id), actual_item2.id); + EXPECT_EQ(base::StringPrintf("0x%x", entries[2].source.id), actual_item2.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT), actual_item2.phase); EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::URL_REQUEST_START_JOB), @@ -323,16 +325,16 @@ } TEST_F(TraceNetLogObserverTest, DestroyObserverWhileTracing) { - trace_net_log_observer()->WatchForTraceStart(net_log()); + trace_net_log_observer()->WatchForTraceStart(NetLog::Get()); EnableTraceLogWithNetLog(); - net_log()->AddGlobalEntry(NetLogEventType::CANCELLED); + NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED); trace_net_log_observer()->StopWatchForTraceStart(); set_trace_net_log_observer(nullptr); - net_log()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); + NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); EndTraceAndFlush(); - auto entries = net_log()->GetEntries(); + auto entries = net_log_observer()->GetEntries(); EXPECT_EQ(2u, entries.size()); EXPECT_EQ(1u, trace_events_size()); @@ -341,7 +343,7 @@ TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1); EXPECT_EQ(kNetLogTracingCategory, actual_item1.category); - EXPECT_EQ(base::StringPrintf("0x%d", entries[0].source.id), actual_item1.id); + EXPECT_EQ(base::StringPrintf("0x%x", entries[0].source.id), actual_item1.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT), actual_item1.phase); EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::CANCELLED), @@ -351,16 +353,16 @@ } TEST_F(TraceNetLogObserverTest, DestroyObserverWhileNotTracing) { - trace_net_log_observer()->WatchForTraceStart(net_log()); - net_log()->AddGlobalEntry(NetLogEventType::CANCELLED); + trace_net_log_observer()->WatchForTraceStart(NetLog::Get()); + NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED); trace_net_log_observer()->StopWatchForTraceStart(); set_trace_net_log_observer(nullptr); - net_log()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); - net_log()->AddGlobalEntry(NetLogEventType::URL_REQUEST_START_JOB); + NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); + NetLog::Get()->AddGlobalEntry(NetLogEventType::URL_REQUEST_START_JOB); EndTraceAndFlush(); - auto entries = net_log()->GetEntries(); + auto entries = net_log_observer()->GetEntries(); EXPECT_EQ(3u, entries.size()); EXPECT_EQ(0u, trace_events_size()); } @@ -369,15 +371,15 @@ set_trace_net_log_observer(nullptr); EnableTraceLogWithNetLog(); set_trace_net_log_observer(new TraceNetLogObserver()); - trace_net_log_observer()->WatchForTraceStart(net_log()); - net_log()->AddGlobalEntry(NetLogEventType::CANCELLED); + trace_net_log_observer()->WatchForTraceStart(NetLog::Get()); + NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED); trace_net_log_observer()->StopWatchForTraceStart(); - net_log()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); - net_log()->AddGlobalEntry(NetLogEventType::URL_REQUEST_START_JOB); + NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); + NetLog::Get()->AddGlobalEntry(NetLogEventType::URL_REQUEST_START_JOB); EndTraceAndFlush(); - auto entries = net_log()->GetEntries(); + auto entries = net_log_observer()->GetEntries(); EXPECT_EQ(3u, entries.size()); EXPECT_EQ(1u, trace_events_size()); } @@ -389,31 +391,31 @@ EnableTraceLogWithoutNetLog(); set_trace_net_log_observer(new TraceNetLogObserver()); - trace_net_log_observer()->WatchForTraceStart(net_log()); - net_log()->AddGlobalEntry(NetLogEventType::CANCELLED); + trace_net_log_observer()->WatchForTraceStart(NetLog::Get()); + NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED); trace_net_log_observer()->StopWatchForTraceStart(); - net_log()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); - net_log()->AddGlobalEntry(NetLogEventType::URL_REQUEST_START_JOB); + NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); + NetLog::Get()->AddGlobalEntry(NetLogEventType::URL_REQUEST_START_JOB); EndTraceAndFlush(); - auto entries = net_log()->GetEntries(); + auto entries = net_log_observer()->GetEntries(); EXPECT_EQ(3u, entries.size()); EXPECT_EQ(0u, trace_events_size()); } TEST_F(TraceNetLogObserverTest, EventsWithAndWithoutParameters) { - trace_net_log_observer()->WatchForTraceStart(net_log()); + trace_net_log_observer()->WatchForTraceStart(NetLog::Get()); EnableTraceLogWithNetLog(); - net_log()->AddGlobalEntryWithStringParams(NetLogEventType::CANCELLED, "foo", - "bar"); - net_log()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); + NetLog::Get()->AddGlobalEntryWithStringParams(NetLogEventType::CANCELLED, + "foo", "bar"); + NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE); EndTraceAndFlush(); trace_net_log_observer()->StopWatchForTraceStart(); - auto entries = net_log()->GetEntries(); + auto entries = net_log_observer()->GetEntries(); EXPECT_EQ(2u, entries.size()); EXPECT_EQ(2u, trace_events_size()); const base::Value* item1 = &trace_events()->GetList()[0]; @@ -423,8 +425,9 @@ TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1); TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(*item2); + EXPECT_EQ(kNetLogTracingCategory, actual_item1.category); - EXPECT_EQ(base::StringPrintf("0x%d", entries[0].source.id), actual_item1.id); + EXPECT_EQ(base::StringPrintf("0x%x", entries[0].source.id), actual_item1.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT), actual_item1.phase); EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::CANCELLED), @@ -433,7 +436,7 @@ actual_item1.source_type); EXPECT_EQ(kNetLogTracingCategory, actual_item2.category); - EXPECT_EQ(base::StringPrintf("0x%d", entries[1].source.id), actual_item2.id); + EXPECT_EQ(base::StringPrintf("0x%x", entries[1].source.id), actual_item2.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT), actual_item2.phase); EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::REQUEST_ALIVE), @@ -453,16 +456,15 @@ TEST(TraceNetLogObserverCategoryTest, DisabledCategory) { base::test::TaskEnvironment task_environment; TraceNetLogObserver observer; - TestNetLog net_log; - observer.WatchForTraceStart(&net_log); + observer.WatchForTraceStart(NetLog::Get()); - EXPECT_FALSE(net_log.IsCapturing()); + EXPECT_FALSE(NetLog::Get()->IsCapturing()); EnableTraceLogWithoutNetLog(); - EXPECT_FALSE(net_log.IsCapturing()); + EXPECT_FALSE(NetLog::Get()->IsCapturing()); observer.StopWatchForTraceStart(); - EXPECT_FALSE(net_log.IsCapturing()); + EXPECT_FALSE(NetLog::Get()->IsCapturing()); DisableTraceLog(); } @@ -470,16 +472,15 @@ TEST(TraceNetLogObserverCategoryTest, EnabledCategory) { base::test::TaskEnvironment task_environment; TraceNetLogObserver observer; - TestNetLog net_log; - observer.WatchForTraceStart(&net_log); + observer.WatchForTraceStart(NetLog::Get()); - EXPECT_FALSE(net_log.IsCapturing()); + EXPECT_FALSE(NetLog::Get()->IsCapturing()); EnableTraceLogWithNetLog(); - EXPECT_TRUE(net_log.IsCapturing()); + EXPECT_TRUE(NetLog::Get()->IsCapturing()); observer.StopWatchForTraceStart(); - EXPECT_FALSE(net_log.IsCapturing()); + EXPECT_FALSE(NetLog::Get()->IsCapturing()); DisableTraceLog(); }
diff --git a/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc b/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc index 08e02858..732de85 100644 --- a/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc +++ b/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc
@@ -27,6 +27,7 @@ #include "net/base/proxy_server.h" #include "net/base/proxy_string_util.h" #include "net/base/test_completion_callback.h" +#include "net/log/net_log.h" #include "net/log/net_log_event_type.h" #include "net/log/net_log_with_source.h" #include "net/log/test_net_log.h" @@ -3010,10 +3011,11 @@ MockAsyncProxyResolverFactory* factory = new MockAsyncProxyResolverFactory(true); - RecordingTestNetLog log; + RecordingNetLogObserver observer; ConfiguredProxyResolutionService service(base::WrapUnique(config_service), - base::WrapUnique(factory), &log, + base::WrapUnique(factory), + net::NetLog::Get(), /*quick_check_enabled=*/true); MockPacFileFetcher* fetcher = new MockPacFileFetcher; @@ -3110,7 +3112,7 @@ // Check that the expected events were output to the log stream. In particular // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial // setup), and NOT a second time when the IP address changed. - auto entries = log.GetEntries(); + auto entries = observer.GetEntries(); EXPECT_TRUE(LogContainsEntryWithType(entries, 0, NetLogEventType::PROXY_CONFIG_CHANGED));
diff --git a/net/proxy_resolution/pac_file_decider_unittest.cc b/net/proxy_resolution/pac_file_decider_unittest.cc index c809cc60..00efda1db 100644 --- a/net/proxy_resolution/pac_file_decider_unittest.cc +++ b/net/proxy_resolution/pac_file_decider_unittest.cc
@@ -21,6 +21,7 @@ #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" #include "net/dns/mock_host_resolver.h" +#include "net/log/net_log.h" #include "net/log/net_log_event_type.h" #include "net/log/test_net_log.h" #include "net/log/test_net_log_util.h" @@ -205,8 +206,8 @@ Rules::Rule rule = rules.AddSuccessRule("http://custom/proxy.pac"); TestCompletionCallback callback; - RecordingTestNetLog log; - PacFileDecider decider(&fetcher, &dhcp_fetcher, &log); + RecordingNetLogObserver observer; + PacFileDecider decider(&fetcher, &dhcp_fetcher, net::NetLog::Get()); EXPECT_THAT(decider.Start(ProxyConfigWithAnnotation( config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), @@ -215,7 +216,7 @@ EXPECT_FALSE(decider.script_data().from_auto_detect); // Check the NetLog was filled correctly. - auto entries = log.GetEntries(); + auto entries = observer.GetEntries(); EXPECT_EQ(4u, entries.size()); EXPECT_TRUE( @@ -243,8 +244,8 @@ rules.AddFailDownloadRule("http://custom/proxy.pac"); TestCompletionCallback callback; - RecordingTestNetLog log; - PacFileDecider decider(&fetcher, &dhcp_fetcher, &log); + RecordingNetLogObserver observer; + PacFileDecider decider(&fetcher, &dhcp_fetcher, net::NetLog::Get()); EXPECT_THAT(decider.Start(ProxyConfigWithAnnotation( config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), @@ -252,7 +253,7 @@ EXPECT_FALSE(decider.script_data().data); // Check the NetLog was filled correctly. - auto entries = log.GetEntries(); + auto entries = observer.GetEntries(); EXPECT_EQ(4u, entries.size()); EXPECT_TRUE( @@ -544,9 +545,9 @@ Rules::Rule rule = rules.AddSuccessRule("http://custom/proxy.pac"); TestCompletionCallback callback; - RecordingTestNetLog log; + RecordingNetLogObserver observer; - PacFileDecider decider(&fetcher, &dhcp_fetcher, &log); + PacFileDecider decider(&fetcher, &dhcp_fetcher, net::NetLog::Get()); EXPECT_THAT(decider.Start(ProxyConfigWithAnnotation( config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), @@ -562,7 +563,7 @@ // Check the NetLog was filled correctly. // (Note that various states are repeated since both WPAD and custom // PAC scripts are tried). - auto entries = log.GetEntries(); + auto entries = observer.GetEntries(); EXPECT_EQ(10u, entries.size()); EXPECT_TRUE( @@ -655,8 +656,9 @@ rules.AddFailDownloadRule("http://custom/proxy.pac"); TestCompletionCallback callback; - RecordingTestNetLog log; - PacFileDecider decider(&fetcher, &dhcp_fetcher, &log); + + RecordingNetLogObserver observer; + PacFileDecider decider(&fetcher, &dhcp_fetcher, net::NetLog::Get()); EXPECT_THAT(decider.Start(ProxyConfigWithAnnotation( config, TRAFFIC_ANNOTATION_FOR_TESTS), base::Milliseconds(1), true, callback.callback()), @@ -666,7 +668,7 @@ EXPECT_FALSE(decider.script_data().data); // Check the NetLog was filled correctly. - auto entries = log.GetEntries(); + auto entries = observer.GetEntries(); EXPECT_EQ(6u, entries.size()); EXPECT_TRUE( @@ -697,8 +699,8 @@ rules.AddFailDownloadRule("http://custom/proxy.pac"); TestCompletionCallback callback; - RecordingTestNetLog log; - PacFileDecider decider(&fetcher, &dhcp_fetcher, &log); + RecordingNetLogObserver observer; + PacFileDecider decider(&fetcher, &dhcp_fetcher, net::NetLog::Get()); EXPECT_THAT(decider.Start(ProxyConfigWithAnnotation( config, TRAFFIC_ANNOTATION_FOR_TESTS), base::Seconds(-5), true, callback.callback()), @@ -706,7 +708,7 @@ EXPECT_FALSE(decider.script_data().data); // Check the NetLog was filled correctly. - auto entries = log.GetEntries(); + auto entries = observer.GetEntries(); EXPECT_EQ(4u, entries.size()); EXPECT_TRUE(
diff --git a/net/quic/dedicated_web_transport_http3_client_test.cc b/net/quic/dedicated_web_transport_http3_client_test.cc index daf6077..ff36421 100644 --- a/net/quic/dedicated_web_transport_http3_client_test.cc +++ b/net/quic/dedicated_web_transport_http3_client_test.cc
@@ -11,8 +11,6 @@ #include "net/base/schemeful_site.h" #include "net/cert/mock_cert_verifier.h" #include "net/dns/mock_host_resolver.h" -#include "net/log/test_net_log.h" -#include "net/log/test_net_log_util.h" #include "net/proxy_resolution/configured_proxy_resolution_service.h" #include "net/quic/crypto/proof_source_chromium.h" #include "net/test/test_data_directory.h" @@ -124,7 +122,7 @@ HostPortPair("test.example.com", 0)); builder.set_quic_context(std::move(quic_context)); - builder.set_net_log(&net_log_); + builder.set_net_log(NetLog::Get()); context_ = builder.Build(); // By default, quit on error instead of waiting for RunLoop() to time out. @@ -182,7 +180,6 @@ ::testing::NiceMock<MockVisitor> visitor_; std::unique_ptr<QuicSimpleServer> server_; std::unique_ptr<base::RunLoop> run_loop_; - RecordingTestNetLog net_log_; quic::test::QuicTestBackend backend_; int port_ = 0;
diff --git a/net/quic/quic_chromium_client_session_test.cc b/net/quic/quic_chromium_client_session_test.cc index fac8c17..bdf6673 100644 --- a/net/quic/quic_chromium_client_session_test.cc +++ b/net/quic/quic_chromium_client_session_test.cc
@@ -180,8 +180,8 @@ if (socket_data_) socket_factory_.AddSocketDataProvider(socket_data_.get()); std::unique_ptr<DatagramClientSocket> socket = - socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND, - &net_log_, NetLogSource()); + socket_factory_.CreateDatagramClientSocket( + DatagramSocket::DEFAULT_BIND, NetLog::Get(), NetLogSource()); socket->Connect(kIpEndPoint); QuicChromiumPacketWriter* writer = new net::QuicChromiumPacketWriter( socket.get(), base::ThreadTaskRunnerHandle::Get().get()); @@ -214,7 +214,7 @@ std::make_unique<quic::QuicClientPushPromiseIndex>(), &test_push_delegate_, base::DefaultTickClock::GetInstance(), base::ThreadTaskRunnerHandle::Get().get(), - /*socket_performance_watcher=*/nullptr, &net_log_); + /*socket_performance_watcher=*/nullptr, NetLog::Get()); if (connectivity_monitor_) { connectivity_monitor_->SetInitialDefaultNetwork(default_network_); session_->AddConnectivityObserver(connectivity_monitor_.get()); @@ -296,7 +296,6 @@ QuicFlagSaver flags_; // Save/restore all QUIC flag values. quic::QuicConfig config_; quic::QuicCryptoClientConfig crypto_config_; - RecordingTestNetLog net_log_; RecordingBoundTestNetLog bound_test_net_log_; MockClientSocketFactory socket_factory_; std::unique_ptr<MockRead> default_read_; @@ -469,7 +468,7 @@ NetLogWithSource session_net_log = session_->net_log(); EXPECT_EQ(NetLogSourceType::QUIC_SESSION, session_net_log.source().type); - EXPECT_EQ(&net_log_, session_net_log.net_log()); + EXPECT_EQ(NetLog::Get(), session_net_log.net_log()); std::unique_ptr<QuicChromiumClientSession::Handle> handle = session_->CreateHandle(destination_); @@ -1946,7 +1945,7 @@ // Create connected socket. std::unique_ptr<DatagramClientSocket> new_socket = socket_factory_.CreateDatagramClientSocket(DatagramSocket::RANDOM_BIND, - &net_log_, NetLogSource()); + NetLog::Get(), NetLogSource()); EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk()); // Create reader and writer. @@ -2055,8 +2054,8 @@ // Create connected socket. std::unique_ptr<DatagramClientSocket> new_socket = - socket_factory_.CreateDatagramClientSocket(DatagramSocket::RANDOM_BIND, - &net_log_, NetLogSource()); + socket_factory_.CreateDatagramClientSocket( + DatagramSocket::RANDOM_BIND, NetLog::Get(), NetLogSource()); EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk()); // Create reader and writer. @@ -2099,7 +2098,7 @@ // Create connected socket. std::unique_ptr<DatagramClientSocket> new_socket = socket_factory_.CreateDatagramClientSocket(DatagramSocket::RANDOM_BIND, - &net_log_, NetLogSource()); + NetLog::Get(), NetLogSource()); EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk()); // Create reader and writer. @@ -2189,7 +2188,7 @@ // Create connected socket. std::unique_ptr<DatagramClientSocket> new_socket = socket_factory_.CreateDatagramClientSocket(DatagramSocket::RANDOM_BIND, - &net_log_, NetLogSource()); + NetLog::Get(), NetLogSource()); EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk()); // Create reader and writer.
diff --git a/net/quic/quic_connectivity_probing_manager_test.cc b/net/quic/quic_connectivity_probing_manager_test.cc index 3189a1e..a39d726 100644 --- a/net/quic/quic_connectivity_probing_manager_test.cc +++ b/net/quic/quic_connectivity_probing_manager_test.cc
@@ -120,7 +120,7 @@ socket_factory_.AddSocketDataProvider(socket_data_.get()); // Create a connected socket for probing. socket_ = socket_factory_.CreateDatagramClientSocket( - DatagramSocket::DEFAULT_BIND, &net_log_, NetLogSource()); + DatagramSocket::DEFAULT_BIND, NetLog::Get(), NetLogSource()); EXPECT_THAT(socket_->Connect(kIpEndPoint), IsOk()); IPEndPoint self_address; socket_->GetLocalAddress(&self_address); @@ -157,7 +157,6 @@ quic::MockClock clock_; MockClientSocketFactory socket_factory_; - RecordingTestNetLog net_log_; RecordingBoundTestNetLog bound_test_net_log_; };
diff --git a/net/server/http_server_fuzzer.cc b/net/server/http_server_fuzzer.cc index 5ebebd8..00fefb1 100644 --- a/net/server/http_server_fuzzer.cc +++ b/net/server/http_server_fuzzer.cc
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "net/base/net_errors.h" +#include "net/log/net_log.h" #include "net/log/test_net_log.h" #include "net/server/http_server.h" #include "net/socket/fuzzed_server_socket.h" @@ -101,11 +102,14 @@ // // |data| is used to create a FuzzedServerSocket. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - net::RecordingTestNetLog test_net_log; + // Including an observer; even though the recorded results aren't currently + // used, it'll ensure the netlogging code is fuzzed as well. + net::RecordingNetLogObserver net_log_observer; FuzzedDataProvider data_provider(data, size); std::unique_ptr<net::ServerSocket> server_socket( - std::make_unique<net::FuzzedServerSocket>(&data_provider, &test_net_log)); + std::make_unique<net::FuzzedServerSocket>(&data_provider, + net::NetLog::Get())); CHECK_EQ(net::OK, server_socket->ListenWithAddressAndPort("127.0.0.1", 80, 5));
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc index d2fd3ee..83fb8a0 100644 --- a/net/socket/client_socket_pool_base_unittest.cc +++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -700,7 +700,7 @@ // It should be logged for the provided source and have the indicated reason. void ExpectSocketClosedWithReason(NetLogSource expected_source, const char* expected_reason) { - auto entries = net_log_.GetEntriesForSourceWithType( + auto entries = observer_.GetEntriesForSourceWithType( expected_source, NetLogEventType::SOCKET_POOL_CLOSING_SOCKET, NetLogEventPhase::NONE); ASSERT_EQ(1u, entries.size()); @@ -720,7 +720,6 @@ // synchronous completions are not registered by this count. size_t completion_count() const { return test_base_.completion_count(); } - RecordingTestNetLog net_log_; const CommonConnectJobParams common_connect_job_params_{ nullptr /* client_socket_factory */, nullptr /* host_resolver */, @@ -734,11 +733,12 @@ nullptr /* ssl_client_context */, nullptr /* socket_performance_watcher_factory */, nullptr /* network_quality_estimator */, - &net_log_, + NetLog::Get(), nullptr /* websocket_endpoint_lock_manager */}; bool connect_backup_jobs_enabled_; MockClientSocketFactory client_socket_factory_; TestConnectJobFactory* connect_job_factory_; + RecordingNetLogObserver observer_; // These parameters are never actually used to create a TransportConnectJob. scoped_refptr<ClientSocketPool::SocketParams> params_; std::unique_ptr<TransportClientSocketPool> pool_;
diff --git a/net/socket/connect_job_unittest.cc b/net/socket/connect_job_unittest.cc index 459c143..5a726bd0 100644 --- a/net/socket/connect_job_unittest.cc +++ b/net/socket/connect_job_unittest.cc
@@ -108,13 +108,13 @@ nullptr /* ssl_client_context */, nullptr /* socket_performance_watcher_factory */, nullptr /* network_quality_estimator */, - &net_log_, + NetLog::Get(), nullptr /* websocket_endpoint_lock_manager */) {} ~ConnectJobTest() override = default; protected: base::test::TaskEnvironment task_environment_; - RecordingTestNetLog net_log_; + RecordingNetLogObserver net_log_observer_; const CommonConnectJobParams common_connect_job_params_; TestConnectJobDelegate delegate_; }; @@ -185,7 +185,7 @@ // Have to delete the job for it to log the end event. job.reset(); - auto entries = net_log_.GetEntries(); + auto entries = net_log_observer_.GetEntries(); EXPECT_EQ(6u, entries.size()); EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::CONNECT_JOB));
diff --git a/net/socket/socks5_client_socket_fuzzer.cc b/net/socket/socks5_client_socket_fuzzer.cc index eb480d356..5ea5f3f9 100644 --- a/net/socket/socks5_client_socket_fuzzer.cc +++ b/net/socket/socks5_client_socket_fuzzer.cc
@@ -14,6 +14,7 @@ #include "net/base/address_list.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" +#include "net/log/net_log.h" #include "net/log/test_net_log.h" #include "net/socket/fuzzed_socket.h" #include "net/socket/socks5_client_socket.h" @@ -25,14 +26,15 @@ // |data| is used to create a FuzzedSocket to fuzz reads and writes, see that // class for details. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - // Use a test NetLog, to exercise logging code. - net::RecordingTestNetLog test_net_log; + // Including an observer; even though the recorded results aren't currently + // used, it'll ensure the netlogging code is fuzzed as well. + net::RecordingNetLogObserver net_log_observer; FuzzedDataProvider data_provider(data, size); net::TestCompletionCallback callback; std::unique_ptr<net::FuzzedSocket> fuzzed_socket( - new net::FuzzedSocket(&data_provider, &test_net_log)); + new net::FuzzedSocket(&data_provider, net::NetLog::Get())); CHECK_EQ(net::OK, fuzzed_socket->Connect(callback.callback())); net::SOCKS5ClientSocket socket(std::move(fuzzed_socket),
diff --git a/net/socket/socks5_client_socket_unittest.cc b/net/socket/socks5_client_socket_unittest.cc index e81ec66a..f85099a6 100644 --- a/net/socket/socks5_client_socket_unittest.cc +++ b/net/socket/socks5_client_socket_unittest.cc
@@ -63,7 +63,7 @@ protected: const uint16_t kNwPort; - RecordingTestNetLog net_log_; + RecordingNetLogObserver net_log_observer_; std::unique_ptr<SOCKS5ClientSocket> user_sock_; AddressList address_list_; // Filled in by BuildMockSocket() and owned by its return value @@ -134,7 +134,7 @@ MockRead(ASYNC, payload_read.data(), payload_read.size()) }; user_sock_ = - BuildMockSocket(data_reads, data_writes, "localhost", 80, &net_log_); + BuildMockSocket(data_reads, data_writes, "localhost", 80, NetLog::Get()); // At this state the TCP connection is completed but not the SOCKS handshake. EXPECT_TRUE(tcp_sock_->IsConnected()); @@ -144,7 +144,7 @@ EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(user_sock_->IsConnected()); - auto net_log_entries = net_log_.GetEntries(); + auto net_log_entries = net_log_observer_.GetEntries(); EXPECT_TRUE(LogContainsBeginEvent(net_log_entries, 0, NetLogEventType::SOCKS5_CONNECT)); @@ -153,7 +153,7 @@ EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(user_sock_->IsConnected()); - net_log_entries = net_log_.GetEntries(); + net_log_entries = net_log_observer_.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(net_log_entries, -1, NetLogEventType::SOCKS5_CONNECT)); @@ -261,11 +261,11 @@ MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength), MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength) }; user_sock_ = - BuildMockSocket(data_reads, data_writes, hostname, 80, &net_log_); + BuildMockSocket(data_reads, data_writes, hostname, 80, NetLog::Get()); int rv = user_sock_->Connect(callback_.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - auto net_log_entries = net_log_.GetEntries(); + auto net_log_entries = net_log_observer_.GetEntries(); EXPECT_TRUE(LogContainsBeginEvent(net_log_entries, 0, NetLogEventType::SOCKS5_CONNECT)); @@ -273,7 +273,7 @@ EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(user_sock_->IsConnected()); - net_log_entries = net_log_.GetEntries(); + net_log_entries = net_log_observer_.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(net_log_entries, -1, NetLogEventType::SOCKS5_CONNECT)); } @@ -290,17 +290,17 @@ MockRead(ASYNC, partial2, base::size(partial2)), MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength)}; user_sock_ = - BuildMockSocket(data_reads, data_writes, hostname, 80, &net_log_); + BuildMockSocket(data_reads, data_writes, hostname, 80, NetLog::Get()); int rv = user_sock_->Connect(callback_.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - auto net_log_entries = net_log_.GetEntries(); + auto net_log_entries = net_log_observer_.GetEntries(); EXPECT_TRUE(LogContainsBeginEvent(net_log_entries, 0, NetLogEventType::SOCKS5_CONNECT)); rv = callback_.WaitForResult(); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(user_sock_->IsConnected()); - net_log_entries = net_log_.GetEntries(); + net_log_entries = net_log_observer_.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(net_log_entries, -1, NetLogEventType::SOCKS5_CONNECT)); } @@ -317,16 +317,16 @@ MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength), MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength) }; user_sock_ = - BuildMockSocket(data_reads, data_writes, hostname, 80, &net_log_); + BuildMockSocket(data_reads, data_writes, hostname, 80, NetLog::Get()); int rv = user_sock_->Connect(callback_.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - auto net_log_entries = net_log_.GetEntries(); + auto net_log_entries = net_log_observer_.GetEntries(); EXPECT_TRUE(LogContainsBeginEvent(net_log_entries, 0, NetLogEventType::SOCKS5_CONNECT)); rv = callback_.WaitForResult(); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(user_sock_->IsConnected()); - net_log_entries = net_log_.GetEntries(); + net_log_entries = net_log_observer_.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(net_log_entries, -1, NetLogEventType::SOCKS5_CONNECT)); } @@ -345,16 +345,16 @@ }; user_sock_ = - BuildMockSocket(data_reads, data_writes, hostname, 80, &net_log_); + BuildMockSocket(data_reads, data_writes, hostname, 80, NetLog::Get()); int rv = user_sock_->Connect(callback_.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - auto net_log_entries = net_log_.GetEntries(); + auto net_log_entries = net_log_observer_.GetEntries(); EXPECT_TRUE(LogContainsBeginEvent(net_log_entries, 0, NetLogEventType::SOCKS5_CONNECT)); rv = callback_.WaitForResult(); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(user_sock_->IsConnected()); - net_log_entries = net_log_.GetEntries(); + net_log_entries = net_log_observer_.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(net_log_entries, -1, NetLogEventType::SOCKS5_CONNECT)); } @@ -362,10 +362,9 @@ TEST_F(SOCKS5ClientSocketTest, Tag) { StaticSocketDataProvider data; - RecordingTestNetLog log; MockTaggingStreamSocket* tagging_sock = new MockTaggingStreamSocket(std::unique_ptr<StreamSocket>( - new MockTCPClientSocket(address_list_, &log, &data))); + new MockTCPClientSocket(address_list_, NetLog::Get(), &data))); // |socket| takes ownership of |tagging_sock|, but keep a non-owning pointer // to it.
diff --git a/net/socket/socks_client_socket_fuzzer.cc b/net/socket/socks_client_socket_fuzzer.cc index 3bce834..d8e877a 100644 --- a/net/socket/socks_client_socket_fuzzer.cc +++ b/net/socket/socks_client_socket_fuzzer.cc
@@ -17,6 +17,7 @@ #include "net/dns/host_resolver.h" #include "net/dns/mock_host_resolver.h" #include "net/dns/public/secure_dns_policy.h" +#include "net/log/net_log.h" #include "net/log/test_net_log.h" #include "net/socket/fuzzed_socket.h" #include "net/socket/socks_client_socket.h" @@ -27,8 +28,9 @@ // |data| is used to create a FuzzedSocket to fuzz reads and writes, see that // class for details. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - // Use a test NetLog, to exercise logging code. - net::RecordingTestNetLog test_net_log; + // Including an observer; even though the recorded results aren't currently + // used, it'll ensure the netlogging code is fuzzed as well. + net::RecordingNetLogObserver net_log_observer; FuzzedDataProvider data_provider(data, size); @@ -53,7 +55,7 @@ net::TestCompletionCallback callback; std::unique_ptr<net::FuzzedSocket> fuzzed_socket( - new net::FuzzedSocket(&data_provider, &test_net_log)); + new net::FuzzedSocket(&data_provider, net::NetLog::Get())); CHECK_EQ(net::OK, fuzzed_socket->Connect(callback.callback())); net::SOCKSClientSocket socket(
diff --git a/net/socket/socks_client_socket_unittest.cc b/net/socket/socks_client_socket_unittest.cc index de50155..ace5905 100644 --- a/net/socket/socks_client_socket_unittest.cc +++ b/net/socket/socks_client_socket_unittest.cc
@@ -114,10 +114,10 @@ MockRead data_reads[] = { MockRead(ASYNC, kSOCKS4OkReply, kSOCKS4OkReplyLength), MockRead(ASYNC, payload_read.data(), payload_read.size())}; - RecordingTestNetLog log; + RecordingNetLogObserver log_observer; user_sock_ = BuildMockSocket(data_reads, data_writes, host_resolver_.get(), - "localhost", 80, &log); + "localhost", 80, NetLog::Get()); // At this state the TCP connection is completed but not the SOCKS // handshake. @@ -127,7 +127,7 @@ int rv = user_sock_->Connect(callback_.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - auto entries = log.GetEntries(); + auto entries = log_observer.GetEntries(); EXPECT_TRUE( LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKS_CONNECT)); EXPECT_FALSE(user_sock_->IsConnected()); @@ -135,7 +135,7 @@ rv = callback_.WaitForResult(); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(user_sock_->IsConnected()); - entries = log.GetEntries(); + entries = log_observer.GetEntries(); EXPECT_TRUE( LogContainsEndEvent(entries, -1, NetLogEventType::SOCKS_CONNECT)); @@ -233,15 +233,15 @@ kSOCKS4OkRequestLocalHostPort80Length)}; MockRead data_reads[] = { MockRead(SYNCHRONOUS, test.fail_reply, base::size(test.fail_reply))}; - RecordingTestNetLog log; + RecordingNetLogObserver log_observer; user_sock_ = BuildMockSocket(data_reads, data_writes, host_resolver_.get(), - "localhost", 80, &log); + "localhost", 80, NetLog::Get()); int rv = user_sock_->Connect(callback_.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - auto entries = log.GetEntries(); + auto entries = log_observer.GetEntries(); EXPECT_TRUE( LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKS_CONNECT)); @@ -249,7 +249,7 @@ EXPECT_EQ(test.fail_code, rv); EXPECT_FALSE(user_sock_->IsConnected()); EXPECT_TRUE(tcp_sock_->IsConnected()); - entries = log.GetEntries(); + entries = log_observer.GetEntries(); EXPECT_TRUE( LogContainsEndEvent(entries, -1, NetLogEventType::SOCKS_CONNECT)); } @@ -266,21 +266,21 @@ MockRead data_reads[] = { MockRead(ASYNC, kSOCKSPartialReply1, base::size(kSOCKSPartialReply1)), MockRead(ASYNC, kSOCKSPartialReply2, base::size(kSOCKSPartialReply2))}; - RecordingTestNetLog log; + RecordingNetLogObserver log_observer; user_sock_ = BuildMockSocket(data_reads, data_writes, host_resolver_.get(), - "localhost", 80, &log); + "localhost", 80, NetLog::Get()); int rv = user_sock_->Connect(callback_.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - auto entries = log.GetEntries(); + auto entries = log_observer.GetEntries(); EXPECT_TRUE( LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKS_CONNECT)); rv = callback_.WaitForResult(); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(user_sock_->IsConnected()); - entries = log.GetEntries(); + entries = log_observer.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SOCKS_CONNECT)); } @@ -300,21 +300,21 @@ }; MockRead data_reads[] = { MockRead(ASYNC, kSOCKS4OkReply, kSOCKS4OkReplyLength)}; - RecordingTestNetLog log; + RecordingNetLogObserver log_observer; user_sock_ = BuildMockSocket(data_reads, data_writes, host_resolver_.get(), - "localhost", 80, &log); + "localhost", 80, NetLog::Get()); int rv = user_sock_->Connect(callback_.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - auto entries = log.GetEntries(); + auto entries = log_observer.GetEntries(); EXPECT_TRUE( LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKS_CONNECT)); rv = callback_.WaitForResult(); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(user_sock_->IsConnected()); - entries = log.GetEntries(); + entries = log_observer.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SOCKS_CONNECT)); } @@ -327,21 +327,21 @@ MockRead(ASYNC, kSOCKS4OkReply, kSOCKS4OkReplyLength - 2), // close connection unexpectedly MockRead(SYNCHRONOUS, 0)}; - RecordingTestNetLog log; + RecordingNetLogObserver log_observer; user_sock_ = BuildMockSocket(data_reads, data_writes, host_resolver_.get(), - "localhost", 80, &log); + "localhost", 80, NetLog::Get()); int rv = user_sock_->Connect(callback_.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - auto entries = log.GetEntries(); + auto entries = log_observer.GetEntries(); EXPECT_TRUE( LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKS_CONNECT)); rv = callback_.WaitForResult(); EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED)); EXPECT_FALSE(user_sock_->IsConnected()); - entries = log.GetEntries(); + entries = log_observer.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SOCKS_CONNECT)); } @@ -352,14 +352,15 @@ host_resolver_->rules()->AddSimulatedTimeoutFailure(hostname); - RecordingTestNetLog log; + RecordingNetLogObserver log_observer; - user_sock_ = BuildMockSocket(base::span<MockRead>(), base::span<MockWrite>(), - host_resolver_.get(), hostname, 80, &log); + user_sock_ = + BuildMockSocket(base::span<MockRead>(), base::span<MockWrite>(), + host_resolver_.get(), hostname, 80, NetLog::Get()); int rv = user_sock_->Connect(callback_.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - auto entries = log.GetEntries(); + auto entries = log_observer.GetEntries(); EXPECT_TRUE( LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKS_CONNECT)); @@ -368,7 +369,7 @@ EXPECT_THAT(user_sock_->GetResolveErrorInfo().error, IsError(ERR_DNS_TIMED_OUT)); EXPECT_FALSE(user_sock_->IsConnected()); - entries = log.GetEntries(); + entries = log_observer.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SOCKS_CONNECT)); } @@ -428,10 +429,9 @@ TEST_F(SOCKSClientSocketTest, Tag) { StaticSocketDataProvider data; - RecordingTestNetLog log; MockTaggingStreamSocket* tagging_sock = new MockTaggingStreamSocket(std::unique_ptr<StreamSocket>( - new MockTCPClientSocket(address_list_, &log, &data))); + new MockTCPClientSocket(address_list_, NetLog::Get(), &data))); std::unique_ptr<ClientSocketHandle> connection(new ClientSocketHandle); // |connection| takes ownership of |tagging_sock|, but keep a @@ -454,10 +454,10 @@ for (auto secure_dns_policy : {SecureDnsPolicy::kAllow, SecureDnsPolicy::kDisable}) { StaticSocketDataProvider data; - RecordingTestNetLog log; MockHostResolver host_resolver; SOCKSClientSocket socket( - std::make_unique<MockTCPClientSocket>(address_list_, &log, &data), + std::make_unique<MockTCPClientSocket>(address_list_, NetLog::Get(), + &data), HostPortPair("localhost", 80), NetworkIsolationKey(), DEFAULT_PRIORITY, &host_resolver, secure_dns_policy, TRAFFIC_ANNOTATION_FOR_TESTS);
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index 675f010..9197611 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc
@@ -866,8 +866,8 @@ const SSLConfig& ssl_config, const HostPortPair& host_port_pair, int* result) { - std::unique_ptr<StreamSocket> transport( - new TCPClientSocket(addr_, nullptr, nullptr, &log_, NetLogSource())); + std::unique_ptr<StreamSocket> transport(new TCPClientSocket( + addr_, nullptr, nullptr, NetLog::Get(), NetLogSource())); int rv = callback_.GetResult(transport->Connect(callback_.callback())); if (rv != OK) { LOG(ERROR) << "Could not connect to SpawnedTestServer"; @@ -916,7 +916,7 @@ return result; } - RecordingTestNetLog log_; + RecordingNetLogObserver log_observer_; ClientSocketFactory* socket_factory_; std::unique_ptr<TestSSLConfigService> ssl_config_service_; std::unique_ptr<MockCertVerifier> cert_verifier_; @@ -1573,9 +1573,8 @@ StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig())); TestCompletionCallback callback; - RecordingTestNetLog log; - std::unique_ptr<StreamSocket> transport( - new TCPClientSocket(addr(), nullptr, nullptr, &log, NetLogSource())); + std::unique_ptr<StreamSocket> transport(new TCPClientSocket( + addr(), nullptr, nullptr, NetLog::Get(), NetLogSource())); int rv = callback.GetResult(transport->Connect(callback.callback())); EXPECT_THAT(rv, IsOk()); @@ -1586,13 +1585,13 @@ rv = sock->Connect(callback.callback()); - auto entries = log.GetEntries(); + auto entries = log_observer_.GetEntries(); EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLogEventType::SSL_CONNECT)); if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(sock->IsConnected()); - entries = log.GetEntries(); + entries = log_observer_.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SSL_CONNECT)); sock->Disconnect(); @@ -1623,7 +1622,7 @@ // test that the handshake has finished. This is because it may be // desirable to disconnect the socket before showing a user prompt, since // the user may take indefinitely long to respond. - auto entries = log_.GetEntries(); + auto entries = log_observer_.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SSL_CONNECT)); } @@ -1651,8 +1650,8 @@ ct_policy_enforcer_.get(), ssl_client_session_cache_.get(), nullptr); TestCompletionCallback callback; - auto transport = std::make_unique<TCPClientSocket>(addr(), nullptr, nullptr, - &log_, NetLogSource()); + auto transport = std::make_unique<TCPClientSocket>( + addr(), nullptr, nullptr, NetLog::Get(), NetLogSource()); int rv = callback.GetResult(transport->Connect(callback.callback())); ASSERT_THAT(rv, IsOk()); @@ -1686,7 +1685,7 @@ // test that the handshake has finished. This is because it may be // desirable to disconnect the socket before showing a user prompt, since // the user may take indefinitely long to respond. - auto entries = log_.GetEntries(); + auto entries = log_observer_.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SSL_CONNECT)); } @@ -1731,7 +1730,7 @@ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); EXPECT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED)); - auto entries = log_.GetEntries(); + auto entries = log_observer_.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SSL_CONNECT)); EXPECT_FALSE(sock_->IsConnected()); } @@ -2466,10 +2465,9 @@ StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig())); TestCompletionCallback callback; - RecordingTestNetLog log; - log.SetObserverCaptureMode(NetLogCaptureMode::kEverything); - std::unique_ptr<StreamSocket> transport( - new TCPClientSocket(addr(), nullptr, nullptr, &log, NetLogSource())); + log_observer_.SetObserverCaptureMode(NetLogCaptureMode::kEverything); + std::unique_ptr<StreamSocket> transport(new TCPClientSocket( + addr(), nullptr, nullptr, NetLog::Get(), NetLogSource())); int rv = callback.GetResult(transport->Connect(callback.callback())); EXPECT_THAT(rv, IsOk()); @@ -2490,7 +2488,7 @@ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS)); EXPECT_EQ(static_cast<int>(base::size(request_text) - 1), rv); - auto entries = log.GetEntries(); + auto entries = log_observer_.GetEntries(); size_t last_index = ExpectLogContainsSomewhereAfter( entries, 5, NetLogEventType::SSL_SOCKET_BYTES_SENT, NetLogEventPhase::NONE); @@ -2502,7 +2500,7 @@ if (rv <= 0) break; - entries = log.GetEntries(); + entries = log_observer_.GetEntries(); last_index = ExpectLogContainsSomewhereAfter( entries, last_index + 1, NetLogEventType::SSL_SOCKET_BYTES_RECEIVED, NetLogEventPhase::NONE); @@ -2766,7 +2764,7 @@ EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(sock_->IsConnected()); - auto entries = log_.GetEntries(); + auto entries = log_observer_.GetEntries(); EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SSL_CONNECT)); SSLInfo ssl_info; @@ -3199,8 +3197,8 @@ sock_.reset(); // Using a different HostPortPair uses a different session cache key. - std::unique_ptr<StreamSocket> transport( - new TCPClientSocket(addr(), nullptr, nullptr, &log_, NetLogSource())); + std::unique_ptr<StreamSocket> transport(new TCPClientSocket( + addr(), nullptr, nullptr, NetLog::Get(), NetLogSource())); TestCompletionCallback callback; ASSERT_THAT(callback.GetResult(transport->Connect(callback.callback())), IsOk()); @@ -3258,8 +3256,8 @@ for (int i = 0; i < 3; i++) { SCOPED_TRACE(i); - std::unique_ptr<StreamSocket> transport( - new TCPClientSocket(addr(), nullptr, nullptr, &log_, NetLogSource())); + std::unique_ptr<StreamSocket> transport(new TCPClientSocket( + addr(), nullptr, nullptr, NetLog::Get(), NetLogSource())); TestCompletionCallback callback; ASSERT_THAT(callback.GetResult(transport->Connect(callback.callback())), IsOk()); @@ -5522,9 +5520,8 @@ ASSERT_TRUE( StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, SSLServerConfig())); - RecordingTestNetLog log; - std::unique_ptr<StreamSocket> transport( - new TCPClientSocket(addr(), nullptr, nullptr, &log, NetLogSource())); + std::unique_ptr<StreamSocket> transport(new TCPClientSocket( + addr(), nullptr, nullptr, NetLog::Get(), NetLogSource())); MockTaggingStreamSocket* tagging_sock = new MockTaggingStreamSocket(std::move(transport)); @@ -6235,6 +6232,65 @@ 0); } +// Test that the server_name extension (SNI) is sent on DNS names, and not IP +// literals. +TEST_F(SSLClientSocketTest, ServerName) { + absl::optional<std::string> got_server_name; + bool ran_callback = false; + auto reset_callback_state = [&] { + got_server_name = absl::nullopt; + ran_callback = false; + }; + + // Start a server which records the server name. + SSLServerConfig server_config; + server_config.client_hello_callback_for_testing = + base::BindLambdaForTesting([&](const SSL_CLIENT_HELLO* client_hello) { + const char* server_name = + SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name); + if (server_name) { + got_server_name = server_name; + } else { + got_server_name = absl::nullopt; + } + ran_callback = true; + }); + ASSERT_TRUE( + StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config)); + + // The client should send the server_name extension for DNS names. + uint16_t port = host_port_pair().port(); + int rv; + ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost( + SSLConfig(), HostPortPair("example.com", port), &rv)); + ASSERT_THAT(rv, IsOk()); + EXPECT_TRUE(ran_callback); + EXPECT_EQ(got_server_name, "example.com"); + + // The client should not send the server_name extension for IPv4 and IPv6 + // literals. See https://crbug.com/500981. + reset_callback_state(); + ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost( + SSLConfig(), HostPortPair("1.2.3.4", port), &rv)); + ASSERT_THAT(rv, IsOk()); + EXPECT_TRUE(ran_callback); + EXPECT_EQ(got_server_name, absl::nullopt); + + reset_callback_state(); + ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost( + SSLConfig(), HostPortPair("::1", port), &rv)); + ASSERT_THAT(rv, IsOk()); + EXPECT_TRUE(ran_callback); + EXPECT_EQ(got_server_name, absl::nullopt); + + reset_callback_state(); + ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost( + SSLConfig(), HostPortPair("2001:db8::42", port), &rv)); + ASSERT_THAT(rv, IsOk()); + EXPECT_TRUE(ran_callback); + EXPECT_EQ(got_server_name, absl::nullopt); +} + class SSLClientSocketAlpsTest : public SSLClientSocketTest, public ::testing::WithParamInterface<std::tuple<bool, bool>> {
diff --git a/net/socket/transport_client_socket_pool_unittest.cc b/net/socket/transport_client_socket_pool_unittest.cc index 7782fd2..2560b3c 100644 --- a/net/socket/transport_client_socket_pool_unittest.cc +++ b/net/socket/transport_client_socket_pool_unittest.cc
@@ -35,8 +35,8 @@ #include "net/http/http_network_session.h" #include "net/http/http_proxy_connect_job.h" #include "net/http/transport_security_state.h" +#include "net/log/net_log.h" #include "net/log/net_log_with_source.h" -#include "net/log/test_net_log.h" #include "net/proxy_resolution/configured_proxy_resolution_service.h" #include "net/socket/client_socket_handle.h" #include "net/socket/connect_job.h" @@ -118,7 +118,7 @@ NetworkIsolationKey(), SecureDnsPolicy::kAllow), params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()), - client_socket_factory_(&net_log_) { + client_socket_factory_(NetLog::Get()) { std::unique_ptr<MockCertVerifier> cert_verifier = std::make_unique<MockCertVerifier>(); cert_verifier->set_default_result(OK); @@ -190,7 +190,6 @@ size_t completion_count() const { return test_base_.completion_count(); } bool connect_backup_jobs_enabled_; - RecordingTestNetLog net_log_; // |group_id_| and |params_| correspond to the same group. const ClientSocketPool::GroupId group_id_;
diff --git a/net/socket/transport_client_socket_unittest.cc b/net/socket/transport_client_socket_unittest.cc index eeb9d6d..ba922cb 100644 --- a/net/socket/transport_client_socket_unittest.cc +++ b/net/socket/transport_client_socket_unittest.cc
@@ -91,7 +91,7 @@ protected: base::RunLoop connect_loop_; uint16_t listen_port_; - RecordingTestNetLog net_log_; + RecordingNetLogObserver net_log_observer_; ClientSocketFactory* const socket_factory_; std::unique_ptr<StreamSocket> sock_; std::unique_ptr<StreamSocket> connected_sock_; @@ -119,7 +119,7 @@ AddressList addr = AddressList::CreateFromIPAddress( IPAddress::IPv4Localhost(), listen_port_); sock_ = socket_factory_->CreateTransportClientSocket( - addr, nullptr, nullptr, &net_log_, NetLogSource()); + addr, nullptr, nullptr, NetLog::Get(), NetLogSource()); } int TransportClientSocketTest::DrainClientSocket( @@ -236,7 +236,7 @@ // Wait for |listen_sock_| to accept a connection. connect_loop_.Run(); - auto net_log_entries = net_log_.GetEntries(); + auto net_log_entries = net_log_observer_.GetEntries(); EXPECT_TRUE( LogContainsBeginEvent(net_log_entries, 0, NetLogEventType::SOCKET_ALIVE)); EXPECT_TRUE( @@ -249,7 +249,7 @@ } EXPECT_TRUE(sock_->IsConnected()); - net_log_entries = net_log_.GetEntries(); + net_log_entries = net_log_observer_.GetEntries(); EXPECT_TRUE( LogContainsEndEvent(net_log_entries, -1, NetLogEventType::TCP_CONNECT));
diff --git a/net/socket/transport_connect_job_unittest.cc b/net/socket/transport_connect_job_unittest.cc index 67a7165a..4b82255d 100644 --- a/net/socket/transport_connect_job_unittest.cc +++ b/net/socket/transport_connect_job_unittest.cc
@@ -20,7 +20,7 @@ #include "net/base/test_completion_callback.h" #include "net/dns/mock_host_resolver.h" #include "net/dns/public/secure_dns_policy.h" -#include "net/log/test_net_log.h" +#include "net/log/net_log.h" #include "net/socket/connect_job_test_util.h" #include "net/socket/connection_attempts.h" #include "net/socket/stream_socket.h" @@ -41,7 +41,7 @@ public: TransportConnectJobTest() : WithTaskEnvironment(base::test::TaskEnvironment::TimeSource::MOCK_TIME), - client_socket_factory_(&net_log_), + client_socket_factory_(NetLog::Get()), common_connect_job_params_( &client_socket_factory_, &host_resolver_, @@ -55,7 +55,7 @@ nullptr /* ssl_client_context */, nullptr /* socket_performance_watcher_factory */, nullptr /* network_quality_estimator */, - &net_log_, + NetLog::Get(), nullptr /* websocket_endpoint_lock_manager */) {} ~TransportConnectJobTest() override {} @@ -68,7 +68,6 @@ } protected: - RecordingTestNetLog net_log_; MockHostResolver host_resolver_; MockTransportClientSocketFactory client_socket_factory_; const CommonConnectJobParams common_connect_job_params_;
diff --git a/net/socket/udp_socket_posix_unittest.cc b/net/socket/udp_socket_posix_unittest.cc index be20d83..6f61ed3 100644 --- a/net/socket/udp_socket_posix_unittest.cc +++ b/net/socket/udp_socket_posix_unittest.cc
@@ -5,8 +5,10 @@ #include "net/socket/udp_socket_posix.h" #include "base/bind.h" +#include "build/build_config.h" #include "net/base/completion_repeating_callback.h" #include "net/base/net_errors.h" +#include "net/log/net_log.h" #include "net/log/test_net_log.h" #include "net/log/test_net_log_util.h" #include "net/socket/datagram_socket.h" @@ -131,7 +133,7 @@ UDPSocketPosixTest() : TestWithTaskEnvironment( base::test::TaskEnvironment::TimeSource::MOCK_TIME), - socket_(DatagramSocket::DEFAULT_BIND, &client_log_, NetLogSource()), + socket_(DatagramSocket::DEFAULT_BIND, NetLog::Get(), NetLogSource()), callback_fired_(false) { write_callback_ = base::BindRepeating(&UDPSocketPosixTest::OnWriteComplete, weak_factory_.GetWeakPtr()); @@ -218,7 +220,7 @@ .WillOnce(Return(kNumMsgs)); } - RecordingTestNetLog client_log_; + RecordingNetLogObserver net_log_observer_; MockUDPSocketPosix socket_; DatagramBuffers buffers_; bool callback_fired_; @@ -344,7 +346,7 @@ socket_.DidSendBuffers(std::move(send_result)); EXPECT_EQ(0u, socket_.GetUnwrittenBuffers().size()); VerifyBuffersDequeued(); - auto client_entries = client_log_.GetEntries(); + auto client_entries = net_log_observer_.GetEntries(); EXPECT_EQ(4u, client_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE)); @@ -367,7 +369,7 @@ socket_.SetWriteCallback(write_callback_); socket_.DidSendBuffers(std::move(send_result)); EXPECT_EQ(0u, socket_.GetUnwrittenBuffers().size()); - auto client_entries = client_log_.GetEntries(); + auto client_entries = net_log_observer_.GetEntries(); EXPECT_EQ(4u, client_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE)); @@ -391,7 +393,7 @@ socket_.SetWriteCallback(write_callback_); socket_.DidSendBuffers(std::move(send_result)); EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size()); - auto client_entries = client_log_.GetEntries(); + auto client_entries = net_log_observer_.GetEntries(); EXPECT_EQ(2u, client_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE)); @@ -409,7 +411,7 @@ socket_.SetWriteCallback(write_callback_); socket_.DidSendBuffers(std::move(send_result)); EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size()); - auto client_entries = client_log_.GetEntries(); + auto client_entries = net_log_observer_.GetEntries(); EXPECT_EQ(2u, client_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE)); @@ -428,7 +430,7 @@ EXPECT_CALL(socket_, InternalWatchFileDescriptor()).WillOnce(Return(true)); socket_.DidSendBuffers(std::move(send_result)); EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size()); - auto client_entries = client_log_.GetEntries(); + auto client_entries = net_log_observer_.GetEntries(); EXPECT_EQ(2u, client_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE)); @@ -448,7 +450,7 @@ .WillOnce(InvokeWithoutArgs(WatcherSetInvalidHandle)); socket_.DidSendBuffers(std::move(send_result)); EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size()); - auto client_entries = client_log_.GetEntries(); + auto client_entries = net_log_observer_.GetEntries(); EXPECT_EQ(3u, client_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE)); @@ -471,7 +473,7 @@ socket_.DidSendBuffers(std::move(send_result)); buffers_ = socket_.GetUnwrittenBuffers(); EXPECT_EQ(2u, buffers_.size()); - auto client_entries = client_log_.GetEntries(); + auto client_entries = net_log_observer_.GetEntries(); EXPECT_EQ(2u, client_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE)); @@ -489,7 +491,7 @@ socket_.DidSendBuffers(std::move(send_result2)); EXPECT_EQ(0u, socket_.GetUnwrittenBuffers().size()); - client_entries = client_log_.GetEntries(); + client_entries = net_log_observer_.GetEntries(); EXPECT_EQ(4u, client_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE)); @@ -515,7 +517,7 @@ socket_.DidSendBuffers(std::move(send_result)); buffers_ = socket_.GetUnwrittenBuffers(); EXPECT_EQ(2u, buffers_.size()); - auto client_entries = client_log_.GetEntries(); + auto client_entries = net_log_observer_.GetEntries(); EXPECT_EQ(2u, client_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE)); @@ -533,7 +535,7 @@ socket_.DidSendBuffers(std::move(send_result2)); EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size()); - client_entries = client_log_.GetEntries(); + client_entries = net_log_observer_.GetEntries(); EXPECT_EQ(2u, client_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE)); @@ -552,7 +554,7 @@ ResetWriteCallback(); socket_.SetWriteCallback(write_callback_); socket_.DidSendBuffers(std::move(send_result)); - auto client_entries = client_log_.GetEntries(); + auto client_entries = net_log_observer_.GetEntries(); EXPECT_EQ(3u, client_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
diff --git a/net/socket/udp_socket_unittest.cc b/net/socket/udp_socket_unittest.cc index 6ce015f..5350e8396 100644 --- a/net/socket/udp_socket_unittest.cc +++ b/net/socket/udp_socket_unittest.cc
@@ -166,12 +166,11 @@ void UDPSocketTest::ConnectTest(bool use_nonblocking_io) { std::string simple_message("hello world!"); - + RecordingNetLogObserver net_log_observer; // Setup the server to listen. IPEndPoint server_address(IPAddress::IPv4Localhost(), 0 /* port */); - RecordingTestNetLog server_log; std::unique_ptr<UDPServerSocket> server( - new UDPServerSocket(&server_log, NetLogSource())); + new UDPServerSocket(NetLog::Get(), NetLogSource())); if (use_nonblocking_io) server->UseNonBlockingIO(); server->AllowAddressReuse(); @@ -180,9 +179,8 @@ ASSERT_THAT(server->GetLocalAddress(&server_address), IsOk()); // Setup the client. - RecordingTestNetLog client_log; - auto client = std::make_unique<UDPClientSocket>(DatagramSocket::DEFAULT_BIND, - &client_log, NetLogSource()); + auto client = std::make_unique<UDPClientSocket>( + DatagramSocket::DEFAULT_BIND, NetLog::Get(), NetLogSource()); if (use_nonblocking_io) client->UseNonBlockingIO(); @@ -221,12 +219,16 @@ EXPECT_EQ(simple_message.length(), static_cast<size_t>(read_result)); EXPECT_EQ(simple_message, std::string(buffer_->data(), read_result)); + NetLogSource server_net_log_source = server->NetLog().source(); + NetLogSource client_net_log_source = client->NetLog().source(); + // Delete sockets so they log their final events. server.reset(); client.reset(); // Check the server's log. - auto server_entries = server_log.GetEntries(); + auto server_entries = + net_log_observer.GetEntriesForSource(server_net_log_source); ASSERT_EQ(6u, server_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(server_entries, 0, NetLogEventType::SOCKET_ALIVE)); @@ -246,7 +248,8 @@ LogContainsEndEvent(server_entries, 5, NetLogEventType::SOCKET_ALIVE)); // Check the client's log. - auto client_entries = client_log.GetEntries(); + auto client_entries = + net_log_observer.GetEntriesForSource(client_net_log_source); EXPECT_EQ(7u, client_entries.size()); EXPECT_TRUE( LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE)); @@ -332,11 +335,10 @@ IPEndPoint listen_address; ASSERT_TRUE(CreateUDPAddress("0.0.0.0", 0 /* port */, &listen_address)); - RecordingTestNetLog server1_log, server2_log; std::unique_ptr<UDPServerSocket> server1( - new UDPServerSocket(&server1_log, NetLogSource())); + new UDPServerSocket(NetLog::Get(), NetLogSource())); std::unique_ptr<UDPServerSocket> server2( - new UDPServerSocket(&server2_log, NetLogSource())); + new UDPServerSocket(NetLog::Get(), NetLogSource())); server1->AllowAddressReuse(); server1->AllowBroadcast(); server2->AllowAddressReuse();
diff --git a/net/socket/websocket_transport_client_socket_pool_unittest.cc b/net/socket/websocket_transport_client_socket_pool_unittest.cc index 707eee65..0c4204c 100644 --- a/net/socket/websocket_transport_client_socket_pool_unittest.cc +++ b/net/socket/websocket_transport_client_socket_pool_unittest.cc
@@ -29,7 +29,7 @@ #include "net/base/test_completion_callback.h" #include "net/dns/mock_host_resolver.h" #include "net/dns/public/secure_dns_policy.h" -#include "net/log/test_net_log.h" +#include "net/log/net_log.h" #include "net/socket/client_socket_handle.h" #include "net/socket/connect_job.h" #include "net/socket/connect_job_test_util.h" @@ -79,7 +79,7 @@ SecureDnsPolicy::kAllow), params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()), host_resolver_(new MockHostResolver), - client_socket_factory_(&net_log_), + client_socket_factory_(NetLog::Get()), common_connect_job_params_( &client_socket_factory_, host_resolver_.get(), @@ -143,7 +143,6 @@ } size_t completion_count() const { return test_base_.completion_count(); } - RecordingTestNetLog net_log_; // |group_id_| and |params_| correspond to the same socket parameters. const ClientSocketPool::GroupId group_id_; scoped_refptr<ClientSocketPool::SocketParams> params_;
diff --git a/net/spdy/spdy_http_stream_unittest.cc b/net/spdy/spdy_http_stream_unittest.cc index 0248de38..4ce6a2b 100644 --- a/net/spdy/spdy_http_stream_unittest.cc +++ b/net/spdy/spdy_http_stream_unittest.cc
@@ -25,7 +25,6 @@ #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" #include "net/log/net_log_with_source.h" -#include "net/log/test_net_log.h" #include "net/socket/socket_tag.h" #include "net/socket/socket_test_util.h" #include "net/spdy/spdy_http_utils.h" @@ -139,7 +138,7 @@ NetworkIsolationKey(), SecureDnsPolicy::kAllow), ssl_(SYNCHRONOUS, OK) { - session_deps_.net_log = &net_log_; + session_deps_.net_log = NetLog::Get(); } ~SpdyHttpStreamTest() override = default; @@ -167,7 +166,6 @@ } SpdyTestUtil spdy_util_; - RecordingTestNetLog net_log_; SpdySessionDependencies session_deps_; const GURL url_; const HostPortPair host_port_pair_;
diff --git a/net/test/embedded_test_server/embedded_test_server_unittest.cc b/net/test/embedded_test_server/embedded_test_server_unittest.cc index 3ddc3500..ac39163 100644 --- a/net/test/embedded_test_server/embedded_test_server_unittest.cc +++ b/net/test/embedded_test_server/embedded_test_server_unittest.cc
@@ -24,7 +24,6 @@ #include "net/base/test_completion_callback.h" #include "net/http/http_response_headers.h" #include "net/log/net_log_source.h" -#include "net/log/test_net_log.h" #include "net/socket/client_socket_factory.h" #include "net/socket/stream_socket.h" #include "net/test/embedded_test_server/embedded_test_server_connection_listener.h" @@ -314,13 +313,12 @@ TEST_P(EmbeddedTestServerTest, ConnectionListenerAccept) { ASSERT_TRUE(server_->Start()); - RecordingTestNetLog net_log; net::AddressList address_list; EXPECT_TRUE(server_->GetAddressList(&address_list)); std::unique_ptr<StreamSocket> socket = ClientSocketFactory::GetDefaultFactory()->CreateTransportClientSocket( - address_list, nullptr, nullptr, &net_log, NetLogSource()); + address_list, nullptr, nullptr, NetLog::Get(), NetLogSource()); TestCompletionCallback callback; ASSERT_THAT(callback.GetResult(socket->Connect(callback.callback())), IsOk());
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc index 0113bd20..70417b6 100644 --- a/net/url_request/url_request_http_job_unittest.cc +++ b/net/url_request/url_request_http_job_unittest.cc
@@ -345,7 +345,7 @@ protected: URLRequestHttpJobTest() : context_(true) { context_.set_http_transaction_factory(&network_layer_); - context_.set_net_log(&net_log_); + context_.set_net_log(NetLog::Get()); context_.Init(); req_ = @@ -357,7 +357,7 @@ TestURLRequestContext context_; TestDelegate delegate_; - RecordingTestNetLog net_log_; + RecordingNetLogObserver net_log_observer_; std::unique_ptr<URLRequest> req_; }; @@ -1280,12 +1280,12 @@ url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS, is_for_websockets)); - net_log_.Clear(); + net_log_observer_.Clear(); r->Start(); d.RunUntilComplete(); if (test.upgrade_expected) { - auto entries = net_log_.GetEntriesWithType( + auto entries = net_log_observer_.GetEntriesWithType( net::NetLogEventType::URL_REQUEST_REDIRECT_JOB); int redirects = entries.size(); for (const auto& entry : entries) {
diff --git a/net/url_request/url_request_quic_unittest.cc b/net/url_request/url_request_quic_unittest.cc index 46f75a4..c69ca3ca 100644 --- a/net/url_request/url_request_quic_unittest.cc +++ b/net/url_request/url_request_quic_unittest.cc
@@ -26,7 +26,6 @@ #include "net/dns/mock_host_resolver.h" #include "net/http/transport_security_state.h" #include "net/log/net_log_event_type.h" -#include "net/log/test_net_log.h" #include "net/log/test_net_log_util.h" #include "net/quic/crypto/proof_source_chromium.h" #include "net/quic/quic_context.h" @@ -143,7 +142,7 @@ context_->set_host_resolver(host_resolver_.get()); context_->set_http_network_session_params(std::move(params)); context_->set_cert_verifier(&cert_verifier_); - context_->set_net_log(&net_log_); + context_->set_net_log(NetLog::Get()); transport_security_state_.SetExpectCTReporter(&expect_ct_reporter_); context_->set_transport_security_state(&transport_security_state_); } @@ -225,8 +224,6 @@ std::string(path); } - RecordingTestNetLog net_log_; - private: void StartQuicServer(quic::ParsedQuicVersion version) { // Set up in-memory cache.
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 72b600a..01f32f7a 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -15,6 +15,7 @@ #include "base/memory/ptr_util.h" #include "build/build_config.h" #include "net/dns/public/secure_dns_policy.h" +#include "net/log/net_log.h" #include "url/url_constants.h" #if defined(OS_WIN) @@ -672,7 +673,7 @@ : job_factory_(std::make_unique<URLRequestJobFactory>()), default_context_(std::make_unique<TestURLRequestContext>(true)) { default_context_->set_network_delegate(&default_network_delegate_); - default_context_->set_net_log(&net_log_); + default_context_->set_net_log(NetLog::Get()); } ~URLRequestTest() override { @@ -716,7 +717,7 @@ } protected: - RecordingTestNetLog net_log_; + RecordingNetLogObserver net_log_observer_; TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest. std::unique_ptr<URLRequestJobFactory> job_factory_; std::unique_ptr<TestURLRequestContext> default_context_; @@ -2092,7 +2093,7 @@ EXPECT_EQ(0, network_delegate.blocked_annotate_cookies_count()); EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); - auto entries = net_log_.GetEntries(); + auto entries = net_log_observer_.GetEntries(); for (const auto& entry : entries) { EXPECT_NE(entry.type, NetLogEventType::COOKIE_GET_BLOCKED_BY_NETWORK_DELEGATE); @@ -2116,7 +2117,7 @@ EXPECT_EQ(1, network_delegate.blocked_annotate_cookies_count()); EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); - auto entries = net_log_.GetEntries(); + auto entries = net_log_observer_.GetEntries(); ExpectLogContainsSomewhereAfter( entries, 0, NetLogEventType::COOKIE_GET_BLOCKED_BY_NETWORK_DELEGATE, NetLogEventPhase::NONE); @@ -2146,7 +2147,7 @@ EXPECT_EQ(0, network_delegate.blocked_annotate_cookies_count()); EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); - auto entries = net_log_.GetEntries(); + auto entries = net_log_observer_.GetEntries(); for (const auto& entry : entries) { EXPECT_NE(entry.type, NetLogEventType::COOKIE_SET_BLOCKED_BY_NETWORK_DELEGATE); @@ -2168,7 +2169,7 @@ EXPECT_EQ(0, network_delegate.blocked_annotate_cookies_count()); EXPECT_EQ(2, network_delegate.blocked_set_cookie_count()); - auto entries = net_log_.GetEntries(); + auto entries = net_log_observer_.GetEntries(); ExpectLogContainsSomewhereAfter( entries, 0, NetLogEventType::COOKIE_SET_BLOCKED_BY_NETWORK_DELEGATE, NetLogEventPhase::NONE); @@ -5170,7 +5171,7 @@ TestDelegate request_delegate; TestURLRequestContext context(true); context.set_network_delegate(nullptr); - context.set_net_log(&net_log_); + context.set_net_log(NetLog::Get()); context.Init(); { @@ -5192,7 +5193,7 @@ EXPECT_EQ(OK, request_delegate.request_status()); } - auto entries = net_log_.GetEntries(); + auto entries = net_log_observer_.GetEntries(); size_t log_position = ExpectLogContainsSomewhereAfter( entries, 0, NetLogEventType::DELEGATE_INFO, NetLogEventPhase::BEGIN); @@ -5211,7 +5212,7 @@ AsyncLoggingNetworkDelegate network_delegate; TestURLRequestContext context(true); context.set_network_delegate(&network_delegate); - context.set_net_log(&net_log_); + context.set_net_log(NetLog::Get()); context.Init(); { @@ -5233,7 +5234,7 @@ EXPECT_EQ(1, network_delegate.destroyed_requests()); size_t log_position = 0; - auto entries = net_log_.GetEntries(); + auto entries = net_log_observer_.GetEntries(); static const NetLogEventType kExpectedEvents[] = { NetLogEventType::NETWORK_DELEGATE_BEFORE_URL_REQUEST, NetLogEventType::NETWORK_DELEGATE_BEFORE_START_TRANSACTION, @@ -5265,7 +5266,7 @@ AsyncLoggingNetworkDelegate network_delegate; TestURLRequestContext context(true); context.set_network_delegate(&network_delegate); - context.set_net_log(&net_log_); + context.set_net_log(NetLog::Get()); context.Init(); { @@ -5287,7 +5288,7 @@ EXPECT_EQ(1, network_delegate.destroyed_requests()); size_t log_position = 0; - auto entries = net_log_.GetEntries(); + auto entries = net_log_observer_.GetEntries(); static const NetLogEventType kExpectedEvents[] = { NetLogEventType::NETWORK_DELEGATE_BEFORE_URL_REQUEST, NetLogEventType::NETWORK_DELEGATE_BEFORE_START_TRANSACTION, @@ -5338,7 +5339,7 @@ AsyncLoggingUrlRequestDelegate::NO_CANCEL); TestURLRequestContext context(true); context.set_network_delegate(nullptr); - context.set_net_log(&net_log_); + context.set_net_log(NetLog::Get()); context.Init(); { @@ -5358,7 +5359,7 @@ EXPECT_EQ(OK, request_delegate.request_status()); } - auto entries = net_log_.GetEntries(); + auto entries = net_log_observer_.GetEntries(); size_t log_position = 0; @@ -5395,7 +5396,7 @@ AsyncLoggingUrlRequestDelegate::NO_CANCEL); TestURLRequestContext context(true); context.set_network_delegate(nullptr); - context.set_net_log(&net_log_); + context.set_net_log(NetLog::Get()); context.Init(); { @@ -5410,7 +5411,7 @@ EXPECT_EQ(OK, request_delegate.request_status()); } - auto entries = net_log_.GetEntries(); + auto entries = net_log_observer_.GetEntries(); // Delegate info should only have been logged in OnReceivedRedirect and // OnResponseStarted. @@ -5449,10 +5450,10 @@ for (auto cancel_stage : kCancelStages) { AsyncLoggingUrlRequestDelegate request_delegate(cancel_stage); - RecordingTestNetLog net_log; + RecordingNetLogObserver net_log_observer; TestURLRequestContext context(true); context.set_network_delegate(nullptr); - context.set_net_log(&net_log); + context.set_net_log(NetLog::Get()); context.Init(); { @@ -5469,7 +5470,7 @@ base::RunLoop().RunUntilIdle(); } - auto entries = net_log.GetEntries(); + auto entries = net_log_observer.GetEntries(); // Delegate info is always logged in both OnReceivedRedirect and // OnResponseStarted. In the CANCEL_ON_RECEIVED_REDIRECT, the @@ -7717,10 +7718,10 @@ FilteringTestNetworkDelegate network_delegate; network_delegate.SetCookieFilter("not_stored_cookie"); network_delegate.set_block_annotate_cookies(); - RecordingTestNetLog net_log; + RecordingNetLogObserver net_log_observer; TestURLRequestContext context(true); context.set_network_delegate(&network_delegate); - context.set_net_log(&net_log); + context.set_net_log(net::NetLog::Get()); context.Init(); // Make sure cookies blocked from being stored are caught, and those that are // accepted are reported as well. @@ -7749,8 +7750,8 @@ EXPECT_TRUE( req->maybe_stored_cookies()[2].access_result.status.IsInclude()); EXPECT_EQ("path_cookie", req->maybe_stored_cookies()[2].cookie->Name()); - auto entries = - net_log.GetEntriesWithType(NetLogEventType::COOKIE_INCLUSION_STATUS); + auto entries = net_log_observer.GetEntriesWithType( + NetLogEventType::COOKIE_INCLUSION_STATUS); EXPECT_EQ(3u, entries.size()); EXPECT_EQ("{\"domain\":\"" + set_cookie_test_url.host() + "\",\"name\":\"not_stored_cookie\",\"operation\":\"store\"," @@ -7766,7 +7767,7 @@ "\",\"name\":\"path_cookie\",\"operation\":\"store\"," "\"path\":\"/set-cookie\",\"status\":\"INCLUDE, DO_NOT_WARN\"}", SerializeNetLogValueToJson(entries[2].params)); - net_log.Clear(); + net_log_observer.Clear(); } { TestDelegate d; @@ -7792,8 +7793,8 @@ req->maybe_sent_cookies()[1] .access_result.status.HasExactlyExclusionReasonsForTesting( {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES})); - auto entries = - net_log.GetEntriesWithType(NetLogEventType::COOKIE_INCLUSION_STATUS); + auto entries = net_log_observer.GetEntriesWithType( + NetLogEventType::COOKIE_INCLUSION_STATUS); EXPECT_EQ(2u, entries.size()); EXPECT_EQ("{\"domain\":\"" + set_cookie_test_url.host() + "\",\"name\":\"path_cookie\",\"operation\":\"send\",\"path\":" @@ -7805,13 +7806,13 @@ "\",\"name\":\"stored_cookie\",\"operation\":\"send\",\"path\":\"/" "\",\"status\":\"EXCLUDE_USER_PREFERENCES, DO_NOT_WARN\"}", SerializeNetLogValueToJson(entries[1].params)); - net_log.Clear(); + net_log_observer.Clear(); } { TestDelegate d; // Ensure that the log does not contain cookie names when not set to collect // sensitive data. - net_log.SetObserverCaptureMode(NetLogCaptureMode::kDefault); + net_log_observer.SetObserverCaptureMode(NetLogCaptureMode::kDefault); GURL test_url = test_server.GetURL("/echoheader?Cookie"); std::unique_ptr<URLRequest> req(context.CreateFirstPartyRequest( @@ -7819,8 +7820,8 @@ req->Start(); d.RunUntilComplete(); - auto entries = - net_log.GetEntriesWithType(NetLogEventType::COOKIE_INCLUSION_STATUS); + auto entries = net_log_observer.GetEntriesWithType( + NetLogEventType::COOKIE_INCLUSION_STATUS); EXPECT_EQ(2u, entries.size()); // Ensure that the potentially-sensitive |name|, |domain|, and |path| fields @@ -7834,8 +7835,9 @@ "DO_NOT_WARN\"}", SerializeNetLogValueToJson(entries[1].params)); - net_log.Clear(); - net_log.SetObserverCaptureMode(NetLogCaptureMode::kIncludeSensitive); + net_log_observer.Clear(); + net_log_observer.SetObserverCaptureMode( + NetLogCaptureMode::kIncludeSensitive); } network_delegate.unset_block_annotate_cookies(); @@ -7858,8 +7860,8 @@ {net::CookieInclusionStatus::EXCLUDE_NOT_ON_PATH})); EXPECT_EQ("stored_cookie", req->maybe_sent_cookies()[1].cookie.Name()); EXPECT_TRUE(req->maybe_sent_cookies()[1].access_result.status.IsInclude()); - auto entries = - net_log.GetEntriesWithType(NetLogEventType::COOKIE_INCLUSION_STATUS); + auto entries = net_log_observer.GetEntriesWithType( + NetLogEventType::COOKIE_INCLUSION_STATUS); EXPECT_EQ(2u, entries.size()); EXPECT_EQ( "{\"domain\":\"" + set_cookie_test_url.host() + @@ -7870,7 +7872,7 @@ "\",\"name\":\"stored_cookie\",\"operation\":\"send\"," "\"path\":\"/\",\"status\":\"INCLUDE, DO_NOT_WARN\"}", SerializeNetLogValueToJson(entries[1].params)); - net_log.Clear(); + net_log_observer.Clear(); } }
diff --git a/pdf/pdfium/pdfium_form_filler.cc b/pdf/pdfium/pdfium_form_filler.cc index 829962e..229cdf8 100644 --- a/pdf/pdfium/pdfium_form_filler.cc +++ b/pdf/pdfium/pdfium_form_filler.cc
@@ -30,9 +30,11 @@ int g_last_timer_id = 0; +#if defined(PDF_ENABLE_V8) std::string WideStringToString(FPDF_WIDESTRING wide_string) { return base::UTF16ToUTF8(reinterpret_cast<const char16_t*>(wide_string)); } +#endif } // namespace
diff --git a/pdf/pdfium/pdfium_form_filler_unittest.cc b/pdf/pdfium/pdfium_form_filler_unittest.cc index 24b6e9dc..c8f0df3 100644 --- a/pdf/pdfium/pdfium_form_filler_unittest.cc +++ b/pdf/pdfium/pdfium_form_filler_unittest.cc
@@ -4,6 +4,9 @@ #include "pdf/pdfium/pdfium_form_filler.h" +#include <vector> + +#include "base/cxx17_backports.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "gin/public/isolate_holder.h" @@ -23,7 +26,10 @@ namespace { +using ::testing::Contains; using ::testing::InSequence; +using ::testing::Not; +using ::testing::Return; class FormFillerTestClient : public TestClient { public: @@ -34,6 +40,7 @@ // Mock PDFEngine::Client methods. MOCK_METHOD(void, Beep, (), (override)); + MOCK_METHOD(std::string, GetURL, (), (override)); MOCK_METHOD(void, ScrollToX, (int), (override)); MOCK_METHOD(void, ScrollToY, (int), (override)); MOCK_METHOD(void, @@ -67,11 +74,18 @@ &engine->form_filler_, uri, modifiers); } +#if defined(PDF_ENABLE_V8) void TriggerBeep(PDFiumEngine* engine) { ASSERT_TRUE(engine); engine->form_filler_.Form_Beep(&engine->form_filler_, JSPLATFORM_BEEP_DEFAULT); } + + int TriggerGetFilePath(PDFiumEngine& engine, void* file_path, int length) { + return engine.form_filler_.Form_GetFilePath(&engine.form_filler_, file_path, + length); + } +#endif // defined(PDF_ENABLE_V8) }; TEST_F(FormFillerTest, DoURIActionWithKeyboardModifier) { @@ -175,17 +189,18 @@ } } -class FormFillerIsolateTest : public FormFillerTest { +#if defined(PDF_ENABLE_V8) +class FormFillerJavaScriptTest : public FormFillerTest { public: - FormFillerIsolateTest() { + FormFillerJavaScriptTest() { // Needed for setting up V8. InitializeSDK(/*enable_v8=*/true, FontMappingMode::kNoMapping); } - ~FormFillerIsolateTest() override { ShutdownSDK(); } + ~FormFillerJavaScriptTest() override { ShutdownSDK(); } }; -TEST_F(FormFillerIsolateTest, IsolateScoping) { +TEST_F(FormFillerJavaScriptTest, IsolateScoping) { // Enter the embedder's isolate so it can be captured when the // `PDFiumFormFiller` is created. v8::Isolate* embedder_isolate = blink::MainThreadIsolate(); @@ -211,4 +226,60 @@ EXPECT_EQ(v8::Isolate::TryGetCurrent(), pdfium_test_isolate); } +TEST_F(FormFillerJavaScriptTest, GetFilePath) { + constexpr char kTestPath[] = "https://www.example.com/path/to/the.pdf"; + constexpr int kTestPathSize = static_cast<int>(base::size(kTestPath)); + + FormFillerTestClient client; + EXPECT_CALL(client, GetURL).Times(2).WillRepeatedly(Return(kTestPath)); + PDFiumEngine engine(&client, PDFiumFormFiller::ScriptOption::kJavaScript); + + // TODO(dhoss): The return value should be `kTestPathSize`. + EXPECT_EQ(TriggerGetFilePath(engine, /*file_path=*/nullptr, /*length=*/0), + kTestPathSize - 1); + + std::vector<char> buffer(kTestPathSize, 'X'); + EXPECT_EQ(TriggerGetFilePath(engine, buffer.data(), buffer.size()), + kTestPathSize - 1); + + // TODO(dhoss): `buffer.data()` should be null terminated. + EXPECT_STRNE(buffer.data(), kTestPath); +} + +TEST_F(FormFillerJavaScriptTest, GetFilePathEmpty) { + FormFillerTestClient client; + EXPECT_CALL(client, GetURL).Times(2).WillRepeatedly(Return(std::string())); + PDFiumEngine engine(&client, PDFiumFormFiller::ScriptOption::kJavaScript); + + // TODO(dhoss): The return value should be 1. + EXPECT_EQ(TriggerGetFilePath(engine, /*file_path=*/nullptr, /*length=*/0), 0); + + char buffer[] = "buffer"; + EXPECT_EQ(TriggerGetFilePath(engine, buffer, /*length=*/1), 0); + + // TODO(dhoss): `buffer` should be "" (i.e., its first character should be a + // null terminator). + EXPECT_STRNE(buffer, ""); +} + +TEST_F(FormFillerJavaScriptTest, GetFilePathShortBuffer) { + constexpr char kTestPath[] = "https://www.example.com/path/to/the.pdf"; + constexpr int kTestPathSize = static_cast<int>(base::size(kTestPath)); + + FormFillerTestClient client; + EXPECT_CALL(client, GetURL).WillRepeatedly(Return(kTestPath)); + PDFiumEngine engine(&client, PDFiumFormFiller::ScriptOption::kJavaScript); + + std::vector<char> buffer(kTestPathSize - 1, 'X'); + + // TODO(dhoss): The return value should be `kTestPathSize`. + EXPECT_EQ(TriggerGetFilePath(engine, buffer.data(), buffer.size()), + kTestPathSize - 1); + + // TODO(dhoss): Nothing should be copied over. The buffer size is too small to + // contain a trailing null. + EXPECT_THAT(buffer, Not(Contains('X').Times(buffer.size()))); +} +#endif // defined(PDF_ENABLE_V8) + } // namespace chrome_pdf
diff --git a/services/device/generic_sensor/platform_sensor.cc b/services/device/generic_sensor/platform_sensor.cc index d0ccc94..b0eea1e 100644 --- a/services/device/generic_sensor/platform_sensor.cc +++ b/services/device/generic_sensor/platform_sensor.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/check.h" +#include "base/containers/cxx20_erase.h" #include "base/threading/sequenced_task_runner_handle.h" #include "services/device/generic_sensor/platform_sensor_provider.h" #include "services/device/generic_sensor/platform_sensor_util.h" @@ -72,23 +73,16 @@ return false; auto& config_list = client_entry->second; - auto config_entry = std::find(config_list.begin(), config_list.end(), config); - if (config_entry == config_list.end()) + if (base::Erase(config_list, config) == 0) return false; - config_list.erase(config_entry); - return UpdateSensorInternal(config_map_); } bool PlatformSensor::StopListening(Client* client) { DCHECK(client); - auto client_entry = config_map_.find(client); - if (client_entry == config_map_.end()) + if (config_map_.erase(client) == 0) return false; - - config_map_.erase(client_entry); - return UpdateSensorInternal(config_map_); }
diff --git a/services/network/proxy_resolver_factory_mojo_unittest.cc b/services/network/proxy_resolver_factory_mojo_unittest.cc index 6f900e1..9ba74aea 100644 --- a/services/network/proxy_resolver_factory_mojo_unittest.cc +++ b/services/network/proxy_resolver_factory_mojo_unittest.cc
@@ -24,6 +24,7 @@ #include "net/base/network_isolation_key.h" #include "net/base/test_completion_callback.h" #include "net/dns/mock_host_resolver.h" +#include "net/log/net_log.h" #include "net/log/net_log_event_type.h" #include "net/log/net_log_with_source.h" #include "net/log/test_net_log.h" @@ -517,7 +518,7 @@ factory_remote.InitWithNewPipeAndPassReceiver()); proxy_resolver_factory_mojo_ = std::make_unique<ProxyResolverFactoryMojo>( std::move(factory_remote), &host_resolver_, base::NullCallback(), - &net_log_); + net::NetLog::Get()); } std::unique_ptr<Request> MakeRequest( @@ -557,7 +558,7 @@ base::test::TaskEnvironment task_environment_; net::HangingHostResolver host_resolver_; - net::RecordingTestNetLog net_log_; + net::RecordingNetLogObserver net_log_observer_; std::unique_ptr<MockMojoProxyResolverFactory> mock_proxy_resolver_factory_; std::unique_ptr<net::ProxyResolverFactory> proxy_resolver_factory_mojo_; @@ -567,7 +568,7 @@ TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver) { CreateProxyResolver(); - CheckCapturedNetLogEntries(kScriptData, net_log_.GetEntries()); + CheckCapturedNetLogEntries(kScriptData, net_log_observer_.GetEntries()); } TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_Empty) { @@ -775,7 +776,7 @@ mock_proxy_resolver_.AddGetProxyAction(GetProxyForUrlAction::ReturnServers( url, ProxyServersFromPacString("DIRECT"))); CreateProxyResolver(); - net_log_.Clear(); + net_log_observer_.Clear(); std::unique_ptr<Request> request(MakeRequest(GURL(kExampleUrl))); EXPECT_THAT(request->Resolve(), IsError(net::ERR_IO_PENDING)); @@ -783,7 +784,7 @@ EXPECT_EQ("DIRECT", request->results().ToPacString()); - CheckCapturedNetLogEntries(url.spec(), net_log_.GetEntries()); + CheckCapturedNetLogEntries(url.spec(), net_log_observer_.GetEntries()); CheckCapturedNetLogEntries(url.spec(), request->net_log().GetEntries()); }
diff --git a/services/network/proxy_service_mojo_unittest.cc b/services/network/proxy_service_mojo_unittest.cc index 25b3bc9..6da977b 100644 --- a/services/network/proxy_service_mojo_unittest.cc +++ b/services/network/proxy_service_mojo_unittest.cc
@@ -20,6 +20,7 @@ #include "net/base/network_isolation_key.h" #include "net/base/test_completion_callback.h" #include "net/dns/mock_host_resolver.h" +#include "net/log/net_log.h" #include "net/log/net_log_event_type.h" #include "net/log/net_log_with_source.h" #include "net/log/test_net_log.h" @@ -127,8 +128,8 @@ TRAFFIC_ANNOTATION_FOR_TESTS)), base::WrapUnique(fetcher_), std::make_unique<net::DoNothingDhcpPacFileFetcher>(), - &mock_host_resolver_, &net_log_, true /* pac_quick_check_enabled */, - &network_delegate_); + &mock_host_resolver_, net::NetLog::Get(), + true /* pac_quick_check_enabled */, &network_delegate_); } base::test::TaskEnvironment task_environment_; @@ -137,7 +138,7 @@ net::MockHostResolver mock_host_resolver_; // Owned by |proxy_resolution_service_|. net::MockPacFileFetcher* fetcher_; - net::RecordingTestNetLog net_log_; + net::RecordingNetLogObserver net_log_observer_; std::unique_ptr<net::ConfiguredProxyResolutionService> proxy_resolution_service_; }; @@ -209,7 +210,7 @@ EXPECT_EQ(0u, mock_host_resolver_.num_resolve()); CheckCapturedNetLogEntries(test_net_log.GetEntries()); - CheckCapturedNetLogEntries(net_log_.GetEntries()); + CheckCapturedNetLogEntries(net_log_observer_.GetEntries()); } TEST_F(ProxyServiceMojoTest, ErrorOnInitialization) { @@ -234,7 +235,7 @@ EXPECT_EQ("DIRECT", info.ToPacString()); EXPECT_EQ(0u, mock_host_resolver_.num_resolve()); - CheckCapturedNetLogEntries(net_log_.GetEntries()); + CheckCapturedNetLogEntries(net_log_observer_.GetEntries()); } } // namespace network
diff --git a/services/network/trust_tokens/test/trust_token_test_util.cc b/services/network/trust_tokens/test/trust_token_test_util.cc index cb272ea..cff86a00 100644 --- a/services/network/trust_tokens/test/trust_token_test_util.cc +++ b/services/network/trust_tokens/test/trust_token_test_util.cc
@@ -13,8 +13,9 @@ namespace network { TestURLRequestMaker::TestURLRequestMaker() { - context_.set_net_log(&net_log_); + context_.set_net_log(net::NetLog::Get()); } + TestURLRequestMaker::~TestURLRequestMaker() = default; std::unique_ptr<net::URLRequest> TestURLRequestMaker::MakeURLRequest(
diff --git a/services/network/trust_tokens/test/trust_token_test_util.h b/services/network/trust_tokens/test/trust_token_test_util.h index 727f9056..cb696c4 100644 --- a/services/network/trust_tokens/test/trust_token_test_util.h +++ b/services/network/trust_tokens/test/trust_token_test_util.h
@@ -13,9 +13,6 @@ #include "base/json/json_string_value_serializer.h" #include "base/strings/string_piece.h" #include "base/test/task_environment.h" -#include "net/log/net_log.h" -#include "net/log/test_net_log.h" -#include "net/log/test_net_log_util.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_test_util.h" #include "services/network/public/mojom/trust_tokens.mojom.h" @@ -36,8 +33,6 @@ TestURLRequestMaker(); virtual ~TestURLRequestMaker(); - net::NetLog* net_log() const { return context_.net_log(); } - TestURLRequestMaker(const TestURLRequestMaker&) = delete; TestURLRequestMaker& operator=(const TestURLRequestMaker&) = delete; @@ -45,7 +40,6 @@ std::unique_ptr<net::URLRequest> MakeURLRequest(base::StringPiece spec); protected: - net::RecordingTestNetLog net_log_; net::TestDelegate delegate_; net::TestURLRequestContext context_; };
diff --git a/services/network/trust_tokens/trust_token_request_helper_factory_unittest.cc b/services/network/trust_tokens/trust_token_request_helper_factory_unittest.cc index e751480f..ea4868e 100644 --- a/services/network/trust_tokens/trust_token_request_helper_factory_unittest.cc +++ b/services/network/trust_tokens/trust_token_request_helper_factory_unittest.cc
@@ -67,7 +67,6 @@ const mojom::TrustTokenParams& suitable_signing_params() const { return *suitable_params_; } - const net::NetLog& net_log() const { return *maker_.net_log(); } std::unique_ptr<net::URLRequest> CreateSuitableRequest() { auto ret = maker_.MakeURLRequest("https://destination.example");
diff --git a/services/network/trust_tokens/trust_token_request_signing_helper_unittest.cc b/services/network/trust_tokens/trust_token_request_signing_helper_unittest.cc index 7bb8197..762b116f 100644 --- a/services/network/trust_tokens/trust_token_request_signing_helper_unittest.cc +++ b/services/network/trust_tokens/trust_token_request_signing_helper_unittest.cc
@@ -24,6 +24,7 @@ #include "components/cbor/writer.h" #include "net/base/request_priority.h" #include "net/http/structured_headers.h" +#include "net/log/net_log.h" #include "net/log/test_net_log.h" #include "net/log/test_net_log_util.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" @@ -693,11 +694,11 @@ // FailingSigner will fail to sign the request, so we should see the operation // fail. - net::RecordingTestNetLog net_log; + net::RecordingNetLogObserver net_log_observer; TrustTokenRequestSigningHelper helper( store.get(), std::move(params), std::make_unique<FailingSigner>(), std::make_unique<TrustTokenRequestCanonicalizer>(), - net::NetLogWithSource::Make(&net_log, + net::NetLogWithSource::Make(net::NetLog::Get(), net::NetLogSourceType::URL_REQUEST)); auto my_request = MakeURLRequest("https://destination.com/"); @@ -712,7 +713,7 @@ EXPECT_THAT(*my_request, Not(Header("Sec-Signature"))); EXPECT_THAT(*my_request, Header("Sec-Redemption-Record", IsEmpty())); EXPECT_TRUE(base::ranges::any_of( - net_log.GetEntriesWithType( + net_log_observer.GetEntriesWithType( net::NetLogEventType::TRUST_TOKEN_OPERATION_BEGIN_SIGNING), [](const net::NetLogEntry& entry) { absl::optional<std::string> key = net::GetOptionalStringValueFromParams(
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index 316b24c..ea4c59cb 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -961,6 +961,10 @@ return; } + // Set seen_raw_request_headers_ to false in order to make sure this redirect + // also calls the devtools observer. + seen_raw_request_headers_ = false; + // Removing headers can't make the set of pre-existing headers unsafe, but // adding headers can. if (!AreRequestHeadersSafe(modified_headers) || @@ -1135,7 +1139,7 @@ auto response = network::mojom::URLResponseHead::New(); PopulateResourceResponse(url_request_.get(), is_load_timing_enabled_, options_, response.get()); - + DispatchOnRawResponse(); ReportFlaggedResponseCookies(); const CrossOriginEmbedderPolicy kEmpty; @@ -1279,6 +1283,7 @@ response_ = network::mojom::URLResponseHead::New(); PopulateResourceResponse(url_request_.get(), is_load_timing_enabled_, options_, response_.get()); + DispatchOnRawResponse(); // Parse and remove the Trust Tokens response headers, if any are expected, // potentially failing the request if an error occurs. @@ -1945,7 +1950,10 @@ void URLLoader::SetRawRequestHeadersAndNotify( net::HttpRawRequestHeaders headers) { auto* devtools_observer = GetDevToolsObserver(); - if (devtools_observer && devtools_request_id()) { + // If we have seen_raw_request_headers_, then don't notify DevTools to prevent + // duplicate ExtraInfo events. + if (!seen_raw_request_headers_ && devtools_observer && + devtools_request_id()) { std::vector<network::mojom::HttpRawHeaderPairPtr> header_array; header_array.reserve(headers.headers().size()); @@ -1956,21 +1964,7 @@ pair->value = header.second; header_array.push_back(std::move(pair)); } - - mojom::ClientSecurityStatePtr client_security_state; - if (factory_params_->client_security_state) { - client_security_state = factory_params_->client_security_state->Clone(); - } else if (request_client_security_state_) { - client_security_state = request_client_security_state_->Clone(); - } - - net::LoadTimingInfo load_timing_info; - url_request_->GetLoadTimingInfo(&load_timing_info); - - devtools_observer->OnRawRequest( - devtools_request_id().value(), url_request_->maybe_sent_cookies(), - std::move(header_array), load_timing_info.request_start, - std::move(client_security_state)); + DispatchOnRawRequest(std::move(header_array)); } if (auto* cookie_observer = GetCookieAccessObserver()) { @@ -1992,9 +1986,89 @@ devtools_request_id())); } } +} - if (devtools_request_id()) - raw_request_headers_.Assign(std::move(headers)); +void URLLoader::DispatchOnRawRequest( + std::vector<network::mojom::HttpRawHeaderPairPtr> headers) { + auto* devtools_observer = GetDevToolsObserver(); + DCHECK(devtools_observer && devtools_request_id()); + + seen_raw_request_headers_ = true; + + mojom::ClientSecurityStatePtr client_security_state; + if (factory_params_->client_security_state) { + client_security_state = factory_params_->client_security_state->Clone(); + } else if (request_client_security_state_) { + client_security_state = request_client_security_state_->Clone(); + } + + net::LoadTimingInfo load_timing_info; + url_request_->GetLoadTimingInfo(&load_timing_info); + + devtools_observer->OnRawRequest( + devtools_request_id().value(), url_request_->maybe_sent_cookies(), + std::move(headers), load_timing_info.request_start, + std::move(client_security_state)); +} + +bool URLLoader::DispatchOnRawResponse() { + auto* devtools_observer = GetDevToolsObserver(); + if (!devtools_observer || !devtools_request_id() || + !url_request_->response_headers()) { + return false; + } + + std::vector<network::mojom::HttpRawHeaderPairPtr> header_array; + + // This is gated by enable_reporting_raw_headers_ to be backwards compatible + // with the old report_raw_headers behavior, where we wouldn't even send + // raw_response_headers_ to the trusted browser process based devtools + // instrumentation. This is observed in the case of HSTS redirects, where + // url_request_->response_headers has the HSTS redirect headers, like + // Non-Authoritative-Reason, but raw_response_headers_ has something else + // which doesn't include HSTS information. This is tested by + // DevToolsTest.TestRawHeadersWithRedirectAndHSTS. + // TODO(crbug.com/1234823): Remove enable_reporting_raw_headers_ + const net::HttpResponseHeaders* response_headers = + raw_response_headers_ && enable_reporting_raw_headers_ + ? raw_response_headers_.get() + : url_request_->response_headers(); + + size_t iterator = 0; + std::string name, value; + while (response_headers->EnumerateHeaderLines(&iterator, &name, &value)) { + network::mojom::HttpRawHeaderPairPtr pair = + network::mojom::HttpRawHeaderPair::New(); + pair->key = name; + pair->value = value; + header_array.push_back(std::move(pair)); + } + + // Only send the "raw" header text when the headers were actually send in + // text form (i.e. not QUIC or SPDY) + absl::optional<std::string> raw_response_headers; + + const net::HttpResponseInfo& response_info = url_request_->response_info(); + + if (!response_info.DidUseQuic() && !response_info.was_fetched_via_spdy) { + raw_response_headers = + absl::make_optional(net::HttpUtil::ConvertHeadersBackToHTTPResponse( + response_headers->raw_headers())); + } + + if (!seen_raw_request_headers_) { + // If we send OnRawResponse(), make sure we send OnRawRequest() event if + // we haven't had the callback from net, to make the client life easier. + DispatchOnRawRequest({}); + } + + devtools_observer->OnRawResponse( + devtools_request_id().value(), url_request_->maybe_stored_cookies(), + std::move(header_array), raw_response_headers, + IPEndPointToIPAddressSpace(response_info.remote_endpoint), + response_headers->response_code()); + + return true; } void URLLoader::SendUploadProgress(const net::UploadProgress& progress) { @@ -2159,54 +2233,6 @@ } void URLLoader::ReportFlaggedResponseCookies() { - auto* devtools_observer = GetDevToolsObserver(); - if (devtools_observer && devtools_request_id() && - url_request_->response_headers()) { - std::vector<network::mojom::HttpRawHeaderPairPtr> header_array; - - // This is gated by enable_reporting_raw_headers_ to be backwards compatible - // with the old report_raw_headers behavior, where we wouldn't even send - // raw_response_headers_ to the trusted browser process based devtools - // instrumentation. This is observed in the case of HSTS redirects, where - // url_request_->response_headers has the HSTS redirect headers, like - // Non-Authoritative-Reason, but raw_response_headers_ has something else - // which doesn't include HSTS information. This is tested by - // DevToolsTest.TestRawHeadersWithRedirectAndHSTS. - // TODO(crbug.com/1234823): Remove enable_reporting_raw_headers_ - const net::HttpResponseHeaders* response_headers = - raw_response_headers_ && enable_reporting_raw_headers_ - ? raw_response_headers_.get() - : url_request_->response_headers(); - - size_t iterator = 0; - std::string name, value; - while (response_headers->EnumerateHeaderLines(&iterator, &name, &value)) { - network::mojom::HttpRawHeaderPairPtr pair = - network::mojom::HttpRawHeaderPair::New(); - pair->key = name; - pair->value = value; - header_array.push_back(std::move(pair)); - } - - // Only send the "raw" header text when the headers were actually send in - // text form (i.e. not QUIC or SPDY) - absl::optional<std::string> raw_response_headers; - - const net::HttpResponseInfo& response_info = url_request_->response_info(); - - if (!response_info.DidUseQuic() && !response_info.was_fetched_via_spdy) { - raw_response_headers = - absl::make_optional(net::HttpUtil::ConvertHeadersBackToHTTPResponse( - response_headers->raw_headers())); - } - - devtools_observer->OnRawResponse( - devtools_request_id().value(), url_request_->maybe_stored_cookies(), - std::move(header_array), raw_response_headers, - IPEndPointToIPAddressSpace(response_info.remote_endpoint), - response_headers->response_code()); - } - if (auto* cookie_observer = GetCookieAccessObserver()) { std::vector<mojom::CookieOrLineWithAccessResultPtr> reported_cookies; for (const auto& cookie_line_and_access_result :
diff --git a/services/network/url_loader.h b/services/network/url_loader.h index 8cc5c3f..2da6bab0 100644 --- a/services/network/url_loader.h +++ b/services/network/url_loader.h
@@ -24,7 +24,6 @@ #include "mojo/public/cpp/system/simple_watcher.h" #include "net/base/load_states.h" #include "net/base/network_delegate.h" -#include "net/http/http_raw_request_headers.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_request.h" #include "services/network/keepalive_statistics_recorder.h" @@ -342,6 +341,9 @@ void SetRawResponseHeaders(scoped_refptr<const net::HttpResponseHeaders>); void NotifyEarlyResponse(scoped_refptr<const net::HttpResponseHeaders>); void SetRawRequestHeadersAndNotify(net::HttpRawRequestHeaders); + void DispatchOnRawRequest( + std::vector<network::mojom::HttpRawHeaderPairPtr> headers); + bool DispatchOnRawResponse(); void SendUploadProgress(const net::UploadProgress& progress); void OnUploadProgressACK(); void OnSSLCertificateErrorResponse(const net::SSLInfo& ssl_info, @@ -473,7 +475,7 @@ resource_scheduler_request_handle_; bool enable_reporting_raw_headers_ = false; - net::HttpRawRequestHeaders raw_request_headers_; + bool seen_raw_request_headers_ = false; scoped_refptr<const net::HttpResponseHeaders> raw_response_headers_; std::unique_ptr<UploadProgressTracker> upload_progress_tracker_;
diff --git a/services/network/web_transport_unittest.cc b/services/network/web_transport_unittest.cc index 4407ed87..efa20126 100644 --- a/services/network/web_transport_unittest.cc +++ b/services/network/web_transport_unittest.cc
@@ -296,7 +296,7 @@ network_context_.url_request_context()->set_cert_verifier(&cert_verifier_); network_context_.url_request_context()->set_host_resolver(&host_resolver_); - network_context_.url_request_context()->set_net_log(&net_log_); + network_context_.url_request_context()->set_net_log(net::NetLog::Get()); auto* quic_context = network_context_.url_request_context()->quic_context(); quic_context->params()->supported_versions.push_back(version_); quic_context->params()->origins_to_force_quic_on.insert( @@ -342,7 +342,7 @@ const url::Origin& origin() const { return origin_; } const NetworkContext& network_context() const { return network_context_; } NetworkContext& mutable_network_context() { return network_context_; } - net::RecordingTestNetLog& net_log() { return net_log_; } + net::RecordingNetLogObserver& net_log_observer() { return net_log_observer_; } void RunPendingTasks() { base::RunLoop run_loop; @@ -361,7 +361,7 @@ net::MockCertVerifier cert_verifier_; net::MockHostResolver host_resolver_; - net::RecordingTestNetLog net_log_; + net::RecordingNetLogObserver net_log_observer_; NetworkContext network_context_; @@ -574,8 +574,9 @@ EXPECT_TRUE(client.has_received_fin_for(incoming_stream_id)); EXPECT_FALSE(client.has_seen_mojo_connection_error()); - std::vector<net::NetLogEntry> resets_sent = net_log().GetEntriesWithType( - net::NetLogEventType::QUIC_SESSION_RST_STREAM_FRAME_SENT); + std::vector<net::NetLogEntry> resets_sent = + net_log_observer().GetEntriesWithType( + net::NetLogEventType::QUIC_SESSION_RST_STREAM_FRAME_SENT); EXPECT_EQ(0u, resets_sent.size()); }
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 0778bd5..a1fc6b5 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -32290,6 +32290,7 @@ "angle_unittests", "-v" ], + "ci_only": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -33536,6 +33537,7 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], + "ci_only": true, "merge": { "args": [ "--bucket", @@ -34839,6 +34841,7 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], + "ci_only": true, "merge": { "args": [ "--bucket",
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 22e26823..be3f445 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -508,6 +508,11 @@ "chromium_builder_asan" ] }, + "UBSan vptr Release (reclient shadow)": { + "additional_compile_targets": [ + "chromium_builder_asan" + ] + }, "VR Linux": { "additional_compile_targets": [ "vr_common_perftests"
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 4bc2b0bf..ea0c5c4 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -1449,8 +1449,7 @@ "performance_web_engine_test_suite": { "args": [ "../../content/test/gpu/run_telemetry_benchmark_fuchsia.py", - "--system-log-template", - "system_log", + "--per-test-logs-dir", ], "label": "//content/test:performance_web_engine_test_suite", "script": "//testing/scripts/run_performance_tests.py",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index e65bb233..69e4815 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -129,6 +129,12 @@ 'linux-lacros-tester-fyi-rel', 'linux-lacros-dbg-tests-fyi', ], + 'modifications': { + # https://crbug.com/1248257 + 'android-lollipop-arm-rel': { + 'ci_only': True, + }, + }, }, 'angle_white_box_tests': { 'modifications': { @@ -1655,6 +1661,10 @@ '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_11.gl_tests.filter', ], }, + # https://crbug.com/1248257 + 'android-lollipop-arm-rel': { + 'ci_only': True, + }, 'android-marshmallow-x86-rel': { 'args': [ '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.gl_tests.filter', @@ -3097,6 +3107,12 @@ 'remove_from': [ 'android-pie-x86-rel', ], + 'modifications': { + # https://crbug.com/1248257 + 'android-lollipop-arm-rel': { + 'ci_only': True, + }, + }, }, 'vr_pixeltests': { 'remove_from': [
diff --git a/testing/buildbot/tryserver.chromium.android.json b/testing/buildbot/tryserver.chromium.android.json index 20caee5..25ccea218d 100644 --- a/testing/buildbot/tryserver.chromium.android.json +++ b/testing/buildbot/tryserver.chromium.android.json
@@ -148,50 +148,6 @@ "test": "blink_unittests", "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/" } - ], - "isolated_scripts": [ - { - "args": [ - "--num-retries=3", - "--release", - "--android", - "--disable-breakpad", - "--additional-driver-flag=--use-gpu-in-tests" - ], - "isolate_name": "blink_web_tests", - "merge": { - "args": [ - "--verbose" - ], - "script": "//third_party/blink/tools/merge_web_test_results.py" - }, - "name": "blink_web_tests", - "resultdb": { - "enable": true - }, - "results_handler": "layout tests", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "device_os": "LMY48M", - "device_os_type": "userdebug", - "device_type": "hammerhead", - "os": "Android" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 - }, - "test_id_prefix": "ninja://:blink_web_tests/" - } ] } }
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index fa255027..5fbe4e5 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -2737,6 +2737,11 @@ 'chromium_builder_asan', ], }, + 'UBSan vptr Release (reclient shadow)': { + 'additional_compile_targets': [ + 'chromium_builder_asan', + ], + }, 'VR Linux': { 'mixins': [ 'has_native_resultdb_integration', @@ -6698,7 +6703,6 @@ ], 'test_suites': { 'gtest_tests': 'chromium_android_webkit_gtests', - 'isolated_scripts': 'chromium_webkit_isolated_scripts', }, 'os_type': 'android', },
diff --git a/testing/scripts/run_performance_tests.py b/testing/scripts/run_performance_tests.py index 5b85cb04..64d02f9 100755 --- a/testing/scripts/run_performance_tests.py +++ b/testing/scripts/run_performance_tests.py
@@ -461,13 +461,12 @@ return selection_args def _generate_syslog_args(self): - if self._options.system_log_template: + if self._options.per_test_logs_dir: isolated_out_dir = os.path.dirname( self._options.isolated_script_test_output) - return ['--system-log-file', os.path.join( + return ['--logs-dir', os.path.join( isolated_out_dir, - self.benchmark, - self._options.system_log_template)] + self.benchmark)] return [] @@ -609,9 +608,9 @@ ' to run in lieu of indexing into our benchmark bot maps', required=False) # crbug.com/1236245: This allows for per-benchmark device logs. - parser.add_argument('--system-log-template', - help='File name template for system logs for each ' - 'benchmark', required=False) + parser.add_argument('--per-test-logs-dir', + help='Require --logs-dir args for test', required=False, + default=False) # Some executions may have a different sharding scheme and/or set of tests. # These files must live in src/tools/perf/core/shard_maps parser.add_argument('--test-shard-map-filename', type=str, required=False)
diff --git a/testing/unexpected_passes_common/data_types.py b/testing/unexpected_passes_common/data_types.py index b3f6527e..959241af 100644 --- a/testing/unexpected_passes_common/data_types.py +++ b/testing/unexpected_passes_common/data_types.py
@@ -5,6 +5,7 @@ from __future__ import print_function +import collections import copy import fnmatch import logging @@ -432,28 +433,31 @@ empty dictionary, that test entry will also be removed. Returns: - A list containing any Expectations that were removed. + A dict from expectation file name (str) to set of unused expectations + (str) from that file. """ logging.info('Filtering out unused expectations') - unused_expectations = [] - for _, expectation, builder_map in self.IterBuilderStepMaps(): + unused = collections.defaultdict(list) + unused_count = 0 + for (expectation_file, expectation, + builder_map) in self.IterBuilderStepMaps(): if not builder_map: - unused_expectations.append(expectation) - for unused in unused_expectations: - for _, expectation_map in self.items(): - if unused in expectation_map: - del expectation_map[unused] - logging.debug('Found %d unused expectations', len(unused_expectations)) + unused[expectation_file].append(expectation) + unused_count += 1 + for expectation_file, expectations in unused.items(): + for e in expectations: + del self[expectation_file][e] + logging.debug('Found %d unused expectations', unused_count) - empty_tests = [] - for test_name, expectation_map in self.items(): + empty_files = [] + for expectation_file, expectation_map in self.items(): if not expectation_map: - empty_tests.append(test_name) - for empty in empty_tests: + empty_files.append(expectation_file) + for empty in empty_files: del self[empty] - logging.debug('Found %d empty tests: %s', len(empty_tests), empty_tests) + logging.debug('Found %d empty files: %s', len(empty_files), empty_files) - return unused_expectations + return unused class ExpectationBuilderMap(BaseTypedMap):
diff --git a/testing/unexpected_passes_common/data_types_unittest.py b/testing/unexpected_passes_common/data_types_unittest.py index caa9c0f7..2c76637 100755 --- a/testing/unexpected_passes_common/data_types_unittest.py +++ b/testing/unexpected_passes_common/data_types_unittest.py
@@ -1141,10 +1141,12 @@ }), }), }) + expected_unused = { + 'expectation_file': + [data_types.Expectation('foo/test', ['linux'], ['Failure'])] + } unused_expectations = expectation_map.FilterOutUnusedExpectations() - self.assertEqual( - unused_expectations, - [data_types.Expectation('foo/test', ['linux'], ['Failure'])]) + self.assertEqual(unused_expectations, expected_unused) self.assertEqual(expectation_map, expected_expectation_map) def testUnusedAndEmpty(self): @@ -1156,9 +1158,12 @@ data_types.BuilderStepMap(), }), }) + expected_unused = { + 'expectation_file': + [data_types.Expectation('foo/test', ['win'], ['Failure'])] + } unused_expectations = expectation_map.FilterOutUnusedExpectations() - self.assertEqual(unused_expectations, - [data_types.Expectation('foo/test', ['win'], ['Failure'])]) + self.assertEqual(unused_expectations, expected_unused) self.assertEqual(expectation_map, {})
diff --git a/testing/unexpected_passes_common/expectations.py b/testing/unexpected_passes_common/expectations.py index d106064..572cb7e 100644 --- a/testing/unexpected_passes_common/expectations.py +++ b/testing/unexpected_passes_common/expectations.py
@@ -41,6 +41,11 @@ for e in list_parser.expectations: if 'Skip' in e.raw_results: continue + # Expectations that only have a Pass expectation (usually used to + # override a broader, failing expectation) are not handled by the + # unexpected pass finder, so ignore those. + if e.raw_results == ['Pass']: + continue expectation = data_types.Expectation(e.test, e.tags, e.raw_results, e.reason) assert expectation not in expectations_for_file
diff --git a/testing/unexpected_passes_common/expectations_unittest.py b/testing/unexpected_passes_common/expectations_unittest.py index 4d2779f6..bd56d4c 100755 --- a/testing/unexpected_passes_common/expectations_unittest.py +++ b/testing/unexpected_passes_common/expectations_unittest.py
@@ -23,13 +23,14 @@ FAKE_EXPECTATION_FILE_CONTENTS = """\ # tags: [ win linux ] -# results: [ Failure RetryOnFailure Skip ] +# results: [ Failure RetryOnFailure Skip Pass ] crbug.com/1234 [ win ] foo/test [ Failure ] [ linux ] foo/test [ Failure ] crbug.com/2345 [ linux ] bar/* [ RetryOnFailure ] crbug.com/3456 [ linux ] some/bad/test [ Skip ] +crbug.com/4567 [ linux ] some/good/test [ Pass ] """ SECONDARY_FAKE_EXPECTATION_FILE_CONTENTS = """\ @@ -342,12 +343,13 @@ self.assertEqual(modified_urls, set(['crbug.com/1234', 'crbug.com/4567'])) expected_file_contents = """\ # tags: [ win linux ] -# results: [ Failure RetryOnFailure Skip ] +# results: [ Failure RetryOnFailure Skip Pass ] [ linux ] foo/test [ Failure ] crbug.com/2345 [ linux ] bar/* [ RetryOnFailure ] crbug.com/3456 [ linux ] some/bad/test [ Skip ] +crbug.com/4567 [ linux ] some/good/test [ Pass ] """ with open(self.filename) as f: self.assertEqual(f.read(), expected_file_contents)
diff --git a/testing/unexpected_passes_common/queries.py b/testing/unexpected_passes_common/queries.py index 46a9fd4..157c5b91 100644 --- a/testing/unexpected_passes_common/queries.py +++ b/testing/unexpected_passes_common/queries.py
@@ -17,6 +17,7 @@ import six from typ import expectations_parser +from typ import json_results from unexpected_passes_common import builders as builders_module from unexpected_passes_common import data_types from unexpected_passes_common import multiprocessing_utils @@ -271,22 +272,24 @@ def run_cmd_in_thread(inputs): cmd, query = inputs + query = query.encode('utf-8') with open(os.devnull, 'w') as devnull: - processes_lock.acquire() - # Starting many queries at once causes us to hit rate limits much more - # frequently, so stagger query starts to help avoid that. - time.sleep(QUERY_DELAY) - p = subprocess.Popen(cmd, - stdout=subprocess.PIPE, - stderr=devnull, - stdin=subprocess.PIPE) - processes.add(p) - processes_lock.release() + with processes_lock: + # Starting many queries at once causes us to hit rate limits much more + # frequently, so stagger query starts to help avoid that. + time.sleep(QUERY_DELAY) + p = subprocess.Popen(cmd, + stdout=subprocess.PIPE, + stderr=devnull, + stdin=subprocess.PIPE) + processes.add(p) # We pass in the query via stdin instead of including it on the # commandline because we can run into command length issues in large # query mode. stdout, _ = p.communicate(query) + if not isinstance(stdout, six.string_types): + stdout = stdout.decode('utf-8') if p.returncode: # When running many queries in parallel, it's possible to hit the # rate limit for the account if we're unlucky, so try again if we do. @@ -509,6 +512,10 @@ def _ConvertActualResultToExpectationFileFormat(actual_result): + # Web tests use ResultDB's ABORT value for both test timeouts and device + # failures, but Abort is not defined in typ. So, map it to timeout now. + if actual_result == 'ABORT': + actual_result = json_results.ResultType.Timeout # The result reported to ResultDB is in the format PASS/FAIL, while the # expected results in an expectation file are in the format Pass/Failure. return expectations_parser.RESULT_TAGS[actual_result]
diff --git a/testing/unexpected_passes_common/queries_unittest.py b/testing/unexpected_passes_common/queries_unittest.py index 9dd7223..12bb284 100755 --- a/testing/unexpected_passes_common/queries_unittest.py +++ b/testing/unexpected_passes_common/queries_unittest.py
@@ -34,6 +34,10 @@ with self.assertRaises(AssertionError): queries._StripPrefixFromBuildId('build-1-2') + def testConvertActualResultToExpectationFileFormatAbort(self): + self.assertEqual( + queries._ConvertActualResultToExpectationFileFormat('ABORT'), 'Timeout') + class QueryGeneratorUnittest(unittest.TestCase): def testSplitQueryGeneratorInitialSplit(self):
diff --git a/testing/unexpected_passes_common/result_output.py b/testing/unexpected_passes_common/result_output.py index 8d8d9c23..ba38a3e 100644 --- a/testing/unexpected_passes_common/result_output.py +++ b/testing/unexpected_passes_common/result_output.py
@@ -183,8 +183,8 @@ ummatched_results: Any unmatched results found while filling |test_expectation_map|, as returned by queries.FillExpectationMapFor[Ci|Try]Builders(). - unused_expectations: A list of any unmatched Expectations that were pulled - out of |test_expectation_map|. + unused_expectations: A dict from expectation file (str) to list of + unmatched Expectations that were pulled out of |test_expectation_map| output_format: A string denoting the format to output to. Valid values are "print" and "html". file_handle: An optional open file-like object to output to. If not @@ -199,7 +199,7 @@ active_str_dict = _ConvertTestExpectationMapToStringDict(active_dict) unmatched_results_str_dict = _ConvertUnmatchedResultsToStringDict( unmatched_results) - unused_expectations_str_list = _ConvertUnusedExpectationsToStringList( + unused_expectations_str_list = _ConvertUnusedExpectationsToStringDict( unused_expectations) if output_format == 'print': @@ -225,7 +225,9 @@ should_close_file = False if not file_handle: should_close_file = True - file_handle = tempfile.NamedTemporaryFile(delete=False, suffix='.html') + file_handle = tempfile.NamedTemporaryFile(delete=False, + suffix='.html', + mode='w') file_handle.write(HTML_HEADER) if stale_dict: @@ -441,23 +443,34 @@ return output_dict -def _ConvertUnusedExpectationsToStringList(unused_expectations): - """Converts |unused_expectations| to a list of strings for reporting. +def _ConvertUnusedExpectationsToStringDict(unused_expectations): + """Converts |unused_expectations| to a dict of strings for reporting. Args: - unused_expectations: A list of data_types.Expectation that didn't have any - matching results. + unused_expectations: A dict mapping expectation file (str) to lists of + data_types.Expectation who did not have any matching results. Returns: - A list of strings, each one corresponding to an element in - |unused_expectations|. Strings are in a format similar to what would be - present as a line in an expectation file. + A string dictionary representation of |unused_expectations| in the following + format: + { + expectation_file: [ + expectation1, + expectation2, + ], + } + The expectations are in a format similar to what would be present as a line + in an expectation file. """ - output_list = [] - for e in unused_expectations: - output_list.append('[ %s ] %s [ %s ]' % - (' '.join(e.tags), e.test, ' '.join(e.expected_results))) - return output_list + output_dict = {} + for expectation_file, expectations in unused_expectations.items(): + expectation_str_list = [] + for e in expectations: + expectation_str_list.append( + '[ %s ] %s [ %s ]' % + (' '.join(e.tags), e.test, ' '.join(e.expected_results))) + output_dict[expectation_file] = expectation_str_list + return output_dict def _FormatExpectation(expectation):
diff --git a/testing/unexpected_passes_common/result_output_unittest.py b/testing/unexpected_passes_common/result_output_unittest.py index 37755508..dc5f0f8 100755 --- a/testing/unexpected_passes_common/result_output_unittest.py +++ b/testing/unexpected_passes_common/result_output_unittest.py
@@ -11,6 +11,8 @@ import tempfile import unittest +import six + from pyfakefs import fake_filesystem_unittest from unexpected_passes_common import data_types @@ -140,7 +142,7 @@ }) # TODO(crbug.com/1198237): Remove the Python 2 version once we are fully # switched to Python 3. - if sys.version_info[0] == 2: + if six.PY2: expected_output = { 'expectation_file': { 'foo/test': { @@ -224,6 +226,54 @@ self.assertEqual(str_dict, expected_output) +class ConvertUnusedExpectationsToStringDictUnittest(unittest.TestCase): + def testEmptyDict(self): + """Tests that nothing blows up when given an empty dict.""" + self.assertEqual(result_output._ConvertUnusedExpectationsToStringDict({}), + {}) + + def testBasic(self): + """Basic functionality test.""" + unused = { + 'foo_file': [ + data_types.Expectation('foo/test', ['win', 'nvidia'], + ['Failure', 'Timeout']), + ], + 'bar_file': [ + data_types.Expectation('bar/test', ['win'], ['Failure']), + data_types.Expectation('bar/test2', ['win'], ['RetryOnFailure']) + ], + } + if six.PY2: + expected_output = { + 'foo_file': [ + '[ win nvidia ] foo/test [ Failure Timeout ]', + ], + 'bar_file': [ + '[ win ] bar/test [ Failure ]', + '[ win ] bar/test2 [ RetryOnFailure ]', + ], + } + else: + # Set ordering does not appear to be stable between test runs, as we can + # get either order of tags. So, generate them now instead of hard coding + # them. + tags = ' '.join(set(['win', 'nvidia'])) + results = ' '.join(set(['Failure', 'Timeout'])) + expected_output = { + 'foo_file': [ + '[ %s ] foo/test [ %s ]' % (tags, results), + ], + 'bar_file': [ + '[ win ] bar/test [ Failure ]', + '[ win ] bar/test2 [ RetryOnFailure ]', + ], + } + self.assertEqual( + result_output._ConvertUnusedExpectationsToStringDict(unused), + expected_output) + + class HtmlToFileUnittest(fake_filesystem_unittest.TestCase): def setUp(self): self.setUpPyfakefs() @@ -268,7 +318,7 @@ # pylint: disable=line-too-long # TODO(crbug.com/1198237): Remove the Python 2 version once we've fully # switched to Python 3. - if sys.version_info[0] == 2: + if six.PY2: expected_output = """\ <button type="button" class="collapsible_group">foo</button> <div class="content"> @@ -410,7 +460,7 @@ # TODO(crbug.com/1198237): Keep the Python 3 version once we are fully # switched. - if sys.version_info[0] == 2: + if six.PY2: expected_output = """\ foo "RetryOnFailure" expectation on "win intel" @@ -491,7 +541,7 @@ with self.assertRaises(RuntimeError): result_output.OutputResults(data_types.TestExpectationMap(), data_types.TestExpectationMap(), - data_types.TestExpectationMap(), {}, [], + data_types.TestExpectationMap(), {}, {}, 'asdf') def testOutputResultsSmoketest(self): @@ -535,16 +585,18 @@ 'build_id'), ], } - unmatched_expectations = [ - data_types.Expectation('foo', ['linux'], 'RetryOnFailure') - ] + unmatched_expectations = { + 'foo_file': [ + data_types.Expectation('foo', ['linux'], 'RetryOnFailure'), + ], + } stale, semi_stale, active = expectation_map.SplitByStaleness() - result_output.OutputResults(stale, semi_stale, active, {}, [], 'print', + result_output.OutputResults(stale, semi_stale, active, {}, {}, 'print', self._file_handle) result_output.OutputResults(stale, semi_stale, active, unmatched_results, - [], 'print', self._file_handle) + {}, 'print', self._file_handle) result_output.OutputResults(stale, semi_stale, active, {}, unmatched_expectations, 'print', self._file_handle) @@ -552,10 +604,10 @@ unmatched_expectations, 'print', self._file_handle) - result_output.OutputResults(stale, semi_stale, active, {}, [], 'html', + result_output.OutputResults(stale, semi_stale, active, {}, {}, 'html', self._file_handle) result_output.OutputResults(stale, semi_stale, active, unmatched_results, - [], 'html', self._file_handle) + {}, 'html', self._file_handle) result_output.OutputResults(stale, semi_stale, active, {}, unmatched_expectations, 'html', self._file_handle)
diff --git a/testing/unexpected_passes_common/unittest_utils.py b/testing/unexpected_passes_common/unittest_utils.py index f6600b6..0f8e26b7 100644 --- a/testing/unexpected_passes_common/unittest_utils.py +++ b/testing/unexpected_passes_common/unittest_utils.py
@@ -160,7 +160,7 @@ def _GetExpectationFileTagHeader(self): return """\ # tags: [ linux mac win ] -# results: [ Failure RetryOnFailure Skip ] +# results: [ Failure RetryOnFailure Skip Pass ] """
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index ecd534e..338ec13 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -3074,6 +3074,32 @@ ] } ], + "DnsHttpsSvcbSchemeUpgrade": [ + { + "platforms": [ + "windows", + "mac", + "linux", + "chromeos", + "chromeos_lacros", + "android" + ], + "experiments": [ + { + "name": "UseDnsHttpsSvcb", + "params": { + "UseDnsHttpsSvcbEnableInsecure": "true", + "UseDnsHttpsSvcbExtraTimeAbsolute": "500ms", + "UseDnsHttpsSvcbExtraTimePercent": "50", + "UseDnsHttpsSvcbHttpUpgrade": "true" + }, + "enable_features": [ + "UseDnsHttpsSvcb" + ] + } + ] + } + ], "DnsHttpssvc": [ { "platforms": [
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc index b0d5db6..c64289c4 100644 --- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc +++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
@@ -61,6 +61,8 @@ #include "third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h" #include "third_party/blink/renderer/platform/bindings/v8_private_property.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" @@ -225,8 +227,18 @@ Document* document = GetFrame()->GetDocument(); v8::Local<v8::Object> global_proxy = global_proxy_.NewLocal(isolate); - context = V8ContextSnapshot::CreateContextFromSnapshot( - isolate, World(), &extension_configuration, global_proxy, document); + { + DEFINE_STATIC_LOCAL( + CustomCountHistogram, main_frame_hist, + ("Blink.Binding.CreateV8ContextForMainFrame", 0, 10000000, 50)); + DEFINE_STATIC_LOCAL( + CustomCountHistogram, non_main_frame_hist, + ("Blink.Binding.CreateV8ContextForNonMainFrame", 0, 10000000, 50)); + ScopedUsHistogramTimer timer( + GetFrame()->IsMainFrame() ? main_frame_hist : non_main_frame_hist); + context = V8ContextSnapshot::CreateContextFromSnapshot( + isolate, World(), &extension_configuration, global_proxy, document); + } context_was_created_from_snapshot_ = !context.IsEmpty(); // Even if we enable V8 context snapshot feature, we may hit this branch
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni index b3b72cd0..3024d19 100644 --- a/third_party/blink/renderer/bindings/generated_in_core.gni +++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -424,6 +424,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_form_state_restore_mode.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fullscreen_navigation_ui.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fullscreen_navigation_ui.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_highlight_type.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_highlight_type.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_color_space.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_color_space.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_data_storage_format.cc",
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index 7d783e3..784009f 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -1491,6 +1491,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_uuid.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_broadcast_channel.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_broadcast_channel.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_browser_capture_media_stream_track.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_browser_capture_media_stream_track.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cache.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cache.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cache_storage.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni index 2737f423..66a5961 100644 --- a/third_party/blink/renderer/bindings/idl_in_modules.gni +++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -407,6 +407,7 @@ "//third_party/blink/renderer/modules/mediasource/url_media_source.idl", "//third_party/blink/renderer/modules/mediasource/video_playback_quality.idl", "//third_party/blink/renderer/modules/mediasource/video_track_source_buffer.idl", + "//third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.idl", "//third_party/blink/renderer/modules/mediastream/capture_handle.idl", "//third_party/blink/renderer/modules/mediastream/capture_handle_change_event.idl", "//third_party/blink/renderer/modules/mediastream/capture_handle_change_event_init.idl", @@ -416,8 +417,8 @@ "//third_party/blink/renderer/modules/mediastream/constrain_double_range.idl", "//third_party/blink/renderer/modules/mediastream/constrain_long_range.idl", "//third_party/blink/renderer/modules/mediastream/double_range.idl", - "//third_party/blink/renderer/modules/mediastream/input_device_info.idl", "//third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.idl", + "//third_party/blink/renderer/modules/mediastream/input_device_info.idl", "//third_party/blink/renderer/modules/mediastream/long_range.idl", "//third_party/blink/renderer/modules/mediastream/media_device_info.idl", "//third_party/blink/renderer/modules/mediastream/media_devices.idl",
diff --git a/third_party/blink/renderer/core/highlight/highlight.h b/third_party/blink/renderer/core/highlight/highlight.h index 035cba90..0c496f1 100644 --- a/third_party/blink/renderer/core/highlight/highlight.h +++ b/third_party/blink/renderer/core/highlight/highlight.h
@@ -38,6 +38,9 @@ const int32_t& priority() const { return priority_; } void setPriority(const int32_t&); + AtomicString type() const { return type_; } + void setType(const AtomicString& type) { type_ = type; } + bool Contains(AbstractRange*) const; class IterationSource final : public HighlightSetIterable::IterationSource { @@ -70,6 +73,7 @@ private: HeapLinkedHashSet<Member<AbstractRange>> highlight_ranges_; int32_t priority_ = 0; + AtomicString type_ = "highlight"; // Since a Highlight can be registered many times under different names in // many HighlightRegistries, we need to keep track of the number of times // it's present in each registry. If the Highlight is not registered anywhere,
diff --git a/third_party/blink/renderer/core/highlight/highlight.idl b/third_party/blink/renderer/core/highlight/highlight.idl index 931241a..2272698 100644 --- a/third_party/blink/renderer/core/highlight/highlight.idl +++ b/third_party/blink/renderer/core/highlight/highlight.idl
@@ -2,6 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +enum HighlightType { + "highlight", + "spelling-error", + "grammar-error" +}; + [ RuntimeEnabled = HighlightAPI, Exposed = Window @@ -9,4 +15,5 @@ constructor(AbstractRange... initRanges); setlike<AbstractRange>; attribute long priority; + attribute HighlightType type; };
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h index 4a93e01e..80457bf7 100644 --- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h +++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
@@ -24,6 +24,8 @@ // see NGExclusionSpace below. NGExclusionSpace was designed to be cheap // to construct and cheap to copy if empty. class CORE_EXPORT NGExclusionSpaceInternal final { + USING_FAST_MALLOC(NGExclusionSpaceInternal); + public: NGExclusionSpaceInternal(); NGExclusionSpaceInternal(const NGExclusionSpaceInternal&);
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_data.h b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_data.h index 8c37fa5..327b3fb 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_data.h +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_data.h
@@ -20,6 +20,9 @@ // This means that although splitting the sets by their track count would not // give the correct result. struct NGGridData { + USING_FAST_MALLOC(NGGridData); + + public: using RangeData = NGGridLayoutAlgorithmTrackCollection::Range; wtf_size_t row_start;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h index 1aac29f..f357ad5 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
@@ -28,6 +28,9 @@ // Data for SVG text in addition to NGFragmentItem. struct NGSvgFragmentData { + USING_FAST_MALLOC(NGSvgFragmentData); + + public: scoped_refptr<const ShapeResultView> shape_result; NGTextOffset text_offset; FloatRect rect;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h index 7507798b..5dc93824 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
@@ -589,6 +589,9 @@ bool ChildrenValid() const { return children_valid_; } struct OutOfFlowData { + USING_FAST_MALLOC(OutOfFlowData); + + public: Vector<NGPhysicalOutOfFlowPositionedNode> oof_positioned_descendants; };
diff --git a/third_party/blink/renderer/core/layout/ng/svg/resolved_text_layout_attributes_iterator.h b/third_party/blink/renderer/core/layout/ng/svg/resolved_text_layout_attributes_iterator.h index c210a40..28d0176 100644 --- a/third_party/blink/renderer/core/layout/ng/svg/resolved_text_layout_attributes_iterator.h +++ b/third_party/blink/renderer/core/layout/ng/svg/resolved_text_layout_attributes_iterator.h
@@ -30,6 +30,8 @@ // AdvanceTo(42) returns the NGSvgCharacterData at [2]. // AdvanceTo(43 or greater) returns the default NGSvgCharacterData. class ResolvedTextLayoutAttributesIterator final { + USING_FAST_MALLOC(ResolvedTextLayoutAttributesIterator); + public: explicit ResolvedTextLayoutAttributesIterator( const Vector<std::pair<unsigned, NGSvgCharacterData>>& resolved)
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_fragment_data.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_fragment_data.h index f89b5edb..5528864c 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_fragment_data.h +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_fragment_data.h
@@ -43,6 +43,9 @@ // Column/row location is used for collapsed border painting. // Only present if borders are collapsed. struct CollapsedBordersGeometry { + USING_FAST_MALLOC(CollapsedBordersGeometry); + + public: Vector<LayoutUnit> columns; // Column offsets from table grid border. Vector<LayoutUnit> rows; // Row offsets from table grid border.
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc index 4e8b7b06..f838a160 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc
@@ -31,10 +31,10 @@ // Returns true if text from beginning of |node| until |pos_offset| can be // considered empty. Otherwise, return false. bool IsFirstVisiblePosition(Node* node, unsigned pos_offset) { - auto range_start = Position::FirstPositionInNode(*node); - auto range_end = Position(node, pos_offset); + auto range_start = PositionInFlatTree::FirstPositionInNode(*node); + auto range_end = PositionInFlatTree(node, pos_offset); return node->getNodeType() == Node::kElementNode || pos_offset == 0 || - PlainText(EphemeralRange(range_start, range_end)) + PlainText(EphemeralRangeInFlatTree(range_start, range_end)) .StripWhiteSpace() .IsEmpty(); } @@ -42,11 +42,11 @@ // Returns true if text from |pos_offset| until end of |node| can be considered // empty. Otherwise, return false. bool IsLastVisiblePosition(Node* node, unsigned pos_offset) { - auto range_start = Position(node, pos_offset); - auto range_end = Position::LastPositionInNode(*node); + auto range_start = PositionInFlatTree(node, pos_offset); + auto range_end = PositionInFlatTree::LastPositionInNode(*node); return node->getNodeType() == Node::kElementNode || pos_offset == node->textContent().length() || - PlainText(EphemeralRange(range_start, range_end)) + PlainText(EphemeralRangeInFlatTree(range_start, range_end)) .StripWhiteSpace() .IsEmpty(); }
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc index 457528e..bf3b9b20 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/renderer/core/editing/ephemeral_range.h" #include "third_party/blink/renderer/core/editing/iterators/text_iterator.h" #include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/html/html_div_element.h" #include "third_party/blink/renderer/core/page/scrolling/text_fragment_handler.h" #include "third_party/blink/renderer/core/testing/scoped_fake_ukm_recorder.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" @@ -1220,6 +1221,32 @@ VerifySelector(start, end, "button-,paragraph,-text"); } +// Ensure generation works correctly when the range begins anchored to a shadow +// host. The shadow root has more children than the shadow host so this ensures +// we're using flat tree node traversals. +TEST_F(TextFragmentSelectorGeneratorTest, RangeBeginsOnShadowHost) { + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete(R"HTML( + <!DOCTYPE html> + <div id='host'></div> + the quick brown fox jumped over the lazy dog. + )HTML"); + + Element* host = GetDocument().getElementById("host"); + ShadowRoot& root = host->AttachShadowRootInternal(ShadowRootType::kOpen); + root.appendChild(MakeGarbageCollected<HTMLDivElement>(root.GetDocument())); + root.appendChild(MakeGarbageCollected<HTMLDivElement>(root.GetDocument())); + + Compositor().BeginFrame(); + + const auto& start = Position(host, PositionAnchorType::kAfterChildren); + const auto& end = Position(host->nextSibling(), 12); + ASSERT_EQ("the quick", PlainText(EphemeralRange(start, end))); + + VerifySelector(start, end, "the%20quick,-brown%20fox%20jumped"); +} + // Basic test case for |GetNextTextBlock|. TEST_F(TextFragmentSelectorGeneratorTest, GetPreviousTextBlock) { SimRequest request("https://example.com/test.html", "text/html");
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index af4d655..c5770b86 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -1939,7 +1939,8 @@ const LayoutObject* layout_object = fragment.GetLayoutObject(); bool skip_children = layout_object && - layout_object == hit_test.result->GetHitTestRequest().GetStopNode(); + (layout_object == hit_test.result->GetHitTestRequest().GetStopNode() || + layout_object->ChildPaintBlockedByDisplayLock()); if (!skip_children && box_fragment_.ShouldClipOverflowAlongEitherAxis()) { // PaintLayer::HitTestContentsForFragments checked the fragments' // foreground rect for intersection if a layer is self painting,
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index f0339f41..730534436 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -2556,16 +2556,21 @@ if (IsA<HTMLMediaElement>(owner)) return true; - // Do not include ignored descendants of an <input type="number"> because - // they interfere with AXPosition code that assumes a plain input field - // structure. Specifically, caret moved events will not be emitted for the - // final offset because the associated tree position for that offset is an - // ignored node. In some cases platform accessibility code will instead - // incorrectly emit a caret moved event for the AXPosition which follows the - // input. + // Do not include ignored descendants of an <input type="search"> or + // <input type="number"> because they interfere with AXPosition code that + // assumes a plain input field structure. Specifically, due to the ignored + // node at the end of textfield, end of editable text position will get + // adjusted to past text field or caret moved events will not be emitted for + // the final offset because the associated tree position. In some cases + // platform accessibility code will instead incorrectly emit a caret moved + // event for the AXPosition which follows the input. if (IsA<HTMLInputElement>(owner) && - DynamicTo<HTMLInputElement>(owner)->type() == input_type_names::kNumber) + (DynamicTo<HTMLInputElement>(owner)->type() == + input_type_names::kSearch || + DynamicTo<HTMLInputElement>(owner)->type() == + input_type_names::kNumber)) { return false; + } } Element* element = GetElement();
diff --git a/third_party/blink/renderer/modules/mediastream/BUILD.gn b/third_party/blink/renderer/modules/mediastream/BUILD.gn index 8f245e7..5b24736 100644 --- a/third_party/blink/renderer/modules/mediastream/BUILD.gn +++ b/third_party/blink/renderer/modules/mediastream/BUILD.gn
@@ -10,6 +10,8 @@ "apply_constraints_processor.h", "apply_constraints_request.cc", "apply_constraints_request.h", + "browser_capture_media_stream_track.cc", + "browser_capture_media_stream_track.h", "capture_handle_change_event.cc", "capture_handle_change_event.h", "dom_window_media_stream.h",
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc new file mode 100644 index 0000000..4f885813 --- /dev/null +++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
@@ -0,0 +1,74 @@ +// Copyright 2021 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 "third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h" + +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" + +namespace blink { + +BrowserCaptureMediaStreamTrack::BrowserCaptureMediaStreamTrack( + ExecutionContext* execution_context, + MediaStreamComponent* component, + base::OnceClosure callback, + const String& descriptor_id, + bool is_clone) + : BrowserCaptureMediaStreamTrack(execution_context, + component, + component->Source()->GetReadyState(), + std::move(callback), + descriptor_id, + is_clone) {} + +BrowserCaptureMediaStreamTrack::BrowserCaptureMediaStreamTrack( + ExecutionContext* execution_context, + MediaStreamComponent* component, + MediaStreamSource::ReadyState ready_state, + base::OnceClosure callback, + const String& descriptor_id, + bool is_clone) + : FocusableMediaStreamTrack(execution_context, + component, + ready_state, + std::move(callback), + descriptor_id, + is_clone) {} + +ScriptPromise BrowserCaptureMediaStreamTrack::cropTo( + ScriptState* script_state, + const String& crop_id, + ExceptionState& exception_state) { + // TODO(crbug.com/1247761): Implement. + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, "Not implemented.")); + return promise; +} + +BrowserCaptureMediaStreamTrack* BrowserCaptureMediaStreamTrack::clone( + ScriptState* script_state) { + // Instantiate the clone. + BrowserCaptureMediaStreamTrack* cloned_track = + MakeGarbageCollected<BrowserCaptureMediaStreamTrack>( + ExecutionContext::From(script_state), Component()->Clone(), + GetReadyState(), base::DoNothing(), descriptor_id(), + /*is_clone=*/true); + + // Copy state. + CloneInternal(cloned_track); + + return cloned_track; +} + +void BrowserCaptureMediaStreamTrack::CloneInternal( + BrowserCaptureMediaStreamTrack* cloned_track) { + // Clone parent classes' state. + FocusableMediaStreamTrack::CloneInternal(cloned_track); + + // TODO(crbug.com/1247761): Clone cropping-related state. +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h new file mode 100644 index 0000000..ad93ff0e --- /dev/null +++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h
@@ -0,0 +1,47 @@ +// Copyright 2021 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 THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_BROWSER_CAPTURE_MEDIA_STREAM_TRACK_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_BROWSER_CAPTURE_MEDIA_STREAM_TRACK_H_ + +#include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.h" + +namespace blink { + +class BrowserCaptureMediaStreamTrack final : public FocusableMediaStreamTrack { + DEFINE_WRAPPERTYPEINFO(); + + public: + BrowserCaptureMediaStreamTrack(ExecutionContext* execution_context, + MediaStreamComponent* component, + base::OnceClosure callback, + const String& descriptor_id, + bool is_clone = false); + + BrowserCaptureMediaStreamTrack(ExecutionContext* execution_context, + MediaStreamComponent* component, + MediaStreamSource::ReadyState ready_state, + base::OnceClosure callback, + const String& descriptor_id, + bool is_clone = false); + + ScriptPromise cropTo(ScriptState*, const String&, ExceptionState&); + + BrowserCaptureMediaStreamTrack* clone(ScriptState*) override; + + protected: + // Given a partially built MediaStreamTrack, finishes the job of making it + // into a clone of |this|. + // Useful for sub-classes (caveat below), as they need to clone both state + // from this class as well as of their own class. + // Caveat: This class is final, and has no sub-classes. We continue the + // pattern from the parent classes for clarity, and to make things easier + // if we do in the future sub-class further. + void CloneInternal(BrowserCaptureMediaStreamTrack*); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_BROWSER_CAPTURE_MEDIA_STREAM_TRACK_H_
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.idl b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.idl new file mode 100644 index 0000000..353b367 --- /dev/null +++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.idl
@@ -0,0 +1,22 @@ +// Copyright 2021 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. + +// https://eladalon1983.github.io/region-capture/ +// TODO(crbug.com/1247761): Link to more official spec once published. +[ + Exposed = Window, + RuntimeEnabled = RegionCapture +] +interface BrowserCaptureMediaStreamTrack : FocusableMediaStreamTrack { + // 1. If |cropTarget| is a non-empty string, start cropping the track + // to the coordinates of the element represented by |cropTarget|. + // Return a Promise that resolves once cropping has been fully initiated + // and the browser guarantees all subsequent frames produced on this track + // will be cropped. + // 2. If |cropTarget| is empty, stop cropping. + // Return a Promise that resolves when this instruction has been fully + // propagated and subsequent frames are guaranteed to be uncropped. + [CallWith = ScriptState, RaisesException, MeasureAs = RegionCapture] + Promise<void> cropTo(DOMString crop_id); +};
diff --git a/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.cc index 18b705f..ac08f83 100644 --- a/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.cc +++ b/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.cc
@@ -42,25 +42,6 @@ descriptor_id_(descriptor_id) { } -FocusableMediaStreamTrack* FocusableMediaStreamTrack::clone( - ScriptState* script_state) { - MediaStreamComponent* const cloned_component = Component()->Clone(); - FocusableMediaStreamTrack* cloned_track = - MakeGarbageCollected<FocusableMediaStreamTrack>( - ExecutionContext::From(script_state), cloned_component, - GetReadyState(), base::DoNothing(), descriptor_id_, - /*is_clone=*/true); - MediaStreamTrack::DidCloneMediaStreamTrack(Component(), cloned_component); - cloned_track->CloneImageCaptureFrom(*this); - -#if !defined(OS_ANDROID) - // Copied for completeness, but should never be read on clones. - cloned_track->focus_called_ = focus_called_; -#endif - - return cloned_track; -} - #if !defined(OS_ANDROID) void FocusableMediaStreamTrack::CloseFocusWindowOfOpportunity() { promise_settled_ = true; @@ -112,4 +93,32 @@ #endif } +FocusableMediaStreamTrack* FocusableMediaStreamTrack::clone( + ScriptState* script_state) { + // Instantiate the clone. + FocusableMediaStreamTrack* cloned_track = + MakeGarbageCollected<FocusableMediaStreamTrack>( + ExecutionContext::From(script_state), Component()->Clone(), + GetReadyState(), base::DoNothing(), descriptor_id_, + /*is_clone=*/true); + + // Copy state. + FocusableMediaStreamTrack::CloneInternal(cloned_track); + + return cloned_track; +} + +void FocusableMediaStreamTrack::CloneInternal( + FocusableMediaStreamTrack* cloned_track) { + // Clone parent classes' state. + MediaStreamTrack::CloneInternal(cloned_track); + + // Clone own state. +#if !defined(OS_ANDROID) + // Copied for completeness, but should never be read on clones. + cloned_track->focus_called_ = focus_called_; + cloned_track->promise_settled_ = promise_settled_; +#endif +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.h b/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.h index 061405ef..74e878b 100644 --- a/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.h +++ b/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.h
@@ -11,7 +11,7 @@ namespace blink { -class FocusableMediaStreamTrack final : public MediaStreamTrack { +class FocusableMediaStreamTrack : public MediaStreamTrack { DEFINE_WRAPPERTYPEINFO(); public: @@ -28,9 +28,6 @@ const String& descriptor_id, bool is_clone = false); - // Clones raise an error if focus() is called. - FocusableMediaStreamTrack* clone(ScriptState*) override; - #if !defined(OS_ANDROID) void CloseFocusWindowOfOpportunity() override; #endif @@ -39,6 +36,18 @@ V8CaptureStartFocusBehavior focus_behavior, ExceptionState& exception_state); + // Clones raise an error if focus() is called. + FocusableMediaStreamTrack* clone(ScriptState*) override; + + protected: + // Given a partially built FocusableMediaStreamTrack, finishes the job + // of making it into a clone of |this|. + // Useful for sub-classes, as they need to clone both state from + // this class as well as of their own class. + void CloneInternal(FocusableMediaStreamTrack*); + + const String& descriptor_id() const { return descriptor_id_; } + private: #if !defined(OS_ANDROID) // Clones may not be focus()-ed.
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream.cc b/third_party/blink/renderer/modules/mediastream/media_stream.cc index d62f75a..98c4494 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream.cc
@@ -28,6 +28,7 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/deprecation.h" +#include "third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h" #include "third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_track_event.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -39,44 +40,53 @@ namespace { -bool IsFocusable(const ExecutionContext* context, - const MediaStreamComponent* component) { - if (!context || !RuntimeEnabledFeatures::ConditionalFocusEnabled(context)) { - return false; - } - - if (!component) { - return false; - } - +// Returns the DisplayCaptureSurfaceType for display-capture tracks, +// absl::nullopt for non-display-capture tracks. +absl::optional<media::mojom::DisplayCaptureSurfaceType> GetDisplayCaptureType( + const MediaStreamComponent* component) { const MediaStreamTrackPlatform* const platform_track = component->GetPlatformTrack(); if (!platform_track) { - return false; + return absl::nullopt; } MediaStreamTrackPlatform::Settings settings; component->GetPlatformTrack()->GetSettings(settings); - - if (!settings.display_surface.has_value()) { - return false; - } - - const media::mojom::DisplayCaptureSurfaceType display_surface = - settings.display_surface.value(); - return display_surface == media::mojom::DisplayCaptureSurfaceType::BROWSER || - display_surface == media::mojom::DisplayCaptureSurfaceType::WINDOW; + return settings.display_surface; } MediaStreamTrack* MakeMediaStreamTrack(ExecutionContext* context, MediaStreamComponent* component, base::OnceClosure callback, const String& descriptor_id) { - return IsFocusable(context, component) - ? MakeGarbageCollected<FocusableMediaStreamTrack>( - context, component, std::move(callback), descriptor_id) - : MakeGarbageCollected<MediaStreamTrack>(context, component, - std::move(callback)); + DCHECK(context); + DCHECK(component); + + const absl::optional<media::mojom::DisplayCaptureSurfaceType> + display_surface_type = GetDisplayCaptureType(component); + const bool is_tab_capture = + (display_surface_type == + media::mojom::DisplayCaptureSurfaceType::BROWSER); + const bool is_window_capture = + (display_surface_type == media::mojom::DisplayCaptureSurfaceType::WINDOW); + + if (is_tab_capture && RuntimeEnabledFeatures::RegionCaptureEnabled(context)) { + // Note: + // * ConditionalFocus is `implied_by` RegionCapture. + // * BrowserCaptureMediaStreamTrack a subclass of FocusableMediaStreamTrack. + // Therefore, tab-capture with ConditionalFocus/RegionCapture active + // instantiates a track on which focus() is exposed - as intended. + DCHECK(RuntimeEnabledFeatures::ConditionalFocusEnabled(context)); + return MakeGarbageCollected<BrowserCaptureMediaStreamTrack>( + context, component, std::move(callback), descriptor_id); + } else if ((is_tab_capture || is_window_capture) && + RuntimeEnabledFeatures::ConditionalFocusEnabled(context)) { + return MakeGarbageCollected<FocusableMediaStreamTrack>( + context, component, std::move(callback), descriptor_id); + } else { + return MakeGarbageCollected<MediaStreamTrack>(context, component, + std::move(callback)); + } } } // namespace
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 f32ff46..0b973ca 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
@@ -199,6 +199,24 @@ native_track->SetEnabled(component->Enabled()); } +void DidCloneMediaStreamTrack(MediaStreamComponent* original, + MediaStreamComponent* clone) { + DCHECK(clone); + DCHECK(!clone->GetPlatformTrack()); + DCHECK(clone->Source()); + + switch (clone->Source()->GetType()) { + case MediaStreamSource::kTypeAudio: + // TODO(crbug.com/704136): Use per thread task runner. + MediaStreamUtils::CreateNativeAudioMediaStreamTrack( + clone, Thread::MainThread()->GetTaskRunner()); + break; + case MediaStreamSource::kTypeVideo: + CloneNativeVideoMediaStreamTrack(original, clone); + break; + } +} + } // namespace MediaStreamTrack::MediaStreamTrack(ExecutionContext* context, @@ -439,12 +457,15 @@ MediaStreamTrack* MediaStreamTrack::clone(ScriptState* script_state) { SendLogMessage(String::Format("%s()", __func__)); - MediaStreamComponent* cloned_component = Component()->Clone(); + + // Instantiate the clone. MediaStreamTrack* cloned_track = MakeGarbageCollected<MediaStreamTrack>( - ExecutionContext::From(script_state), cloned_component, ready_state_, + ExecutionContext::From(script_state), Component()->Clone(), ready_state_, base::DoNothing()); - DidCloneMediaStreamTrack(Component(), cloned_component); - cloned_track->CloneImageCaptureFrom(*this); + + // Copy state. + CloneInternal(cloned_track); + return cloned_track; } @@ -898,29 +919,17 @@ EventTargetWithInlineData::Trace(visitor); } -void MediaStreamTrack::DidCloneMediaStreamTrack(MediaStreamComponent* original, - MediaStreamComponent* clone) { - DCHECK(clone); - DCHECK(!clone->GetPlatformTrack()); - DCHECK(clone->Source()); +void MediaStreamTrack::CloneInternal(MediaStreamTrack* cloned_track) { + DCHECK(cloned_track); - switch (clone->Source()->GetType()) { - case MediaStreamSource::kTypeAudio: - // TODO(crbug.com/704136): Use per thread task runner. - MediaStreamUtils::CreateNativeAudioMediaStreamTrack( - clone, Thread::MainThread()->GetTaskRunner()); - break; - case MediaStreamSource::kTypeVideo: - CloneNativeVideoMediaStreamTrack(original, clone); - break; + DidCloneMediaStreamTrack(Component(), cloned_track->Component()); + + DCHECK(!cloned_track->image_capture_); + if (image_capture_) { + cloned_track->image_capture_ = image_capture_->Clone(); } } -void MediaStreamTrack::CloneImageCaptureFrom(const MediaStreamTrack& original) { - image_capture_ = - original.image_capture_ ? original.image_capture_->Clone() : nullptr; -} - void MediaStreamTrack::EnsureFeatureHandleForScheduler() { if (feature_handle_for_scheduler_) return;
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track.h b/third_party/blink/renderer/modules/mediastream/media_stream_track.h index 4a49daa4..54c82ee 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_track.h +++ b/third_party/blink/renderer/modules/mediastream/media_stream_track.h
@@ -138,11 +138,11 @@ void Trace(Visitor*) const override; protected: - static void DidCloneMediaStreamTrack(MediaStreamComponent* original, - MediaStreamComponent* clone); - - // Clones |image_capture_| from |original| into |this|. - void CloneImageCaptureFrom(const MediaStreamTrack& original); + // Given a partially built MediaStreamTrack, finishes the job of making it + // into a clone of |this|. + // Useful for sub-classes, as they need to clone both state from + // this class as well as of their own class. + void CloneInternal(MediaStreamTrack*); private: friend class CanvasCaptureMediaStreamTrack;
diff --git a/third_party/blink/renderer/modules/permissions/permission_status.cc b/third_party/blink/renderer/modules/permissions/permission_status.cc index 81bee19..9196d62 100644 --- a/third_party/blink/renderer/modules/permissions/permission_status.cc +++ b/third_party/blink/renderer/modules/permissions/permission_status.cc
@@ -77,6 +77,10 @@ return PermissionStatusToString(status_); } +String PermissionStatus::name() const { + return PermissionNameToString(descriptor_->name); +} + void PermissionStatus::StartListening() { DCHECK(!receiver_.is_bound()); mojo::PendingRemote<mojom::blink::PermissionObserver> observer;
diff --git a/third_party/blink/renderer/modules/permissions/permission_status.h b/third_party/blink/renderer/modules/permissions/permission_status.h index c911541..cd0c79b95 100644 --- a/third_party/blink/renderer/modules/permissions/permission_status.h +++ b/third_party/blink/renderer/modules/permissions/permission_status.h
@@ -61,6 +61,8 @@ String state() const; + String name() const; + DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange) void Trace(Visitor*) const override;
diff --git a/third_party/blink/renderer/modules/permissions/permission_status.idl b/third_party/blink/renderer/modules/permissions/permission_status.idl index 160fa54a..10ec901 100644 --- a/third_party/blink/renderer/modules/permissions/permission_status.idl +++ b/third_party/blink/renderer/modules/permissions/permission_status.idl
@@ -16,6 +16,7 @@ Exposed=(Window,Worker), RuntimeEnabled=Permissions ] interface PermissionStatus : EventTarget { + readonly attribute PermissionName name; readonly attribute PermissionState state; attribute EventHandler onchange; };
diff --git a/third_party/blink/renderer/modules/permissions/permission_utils.cc b/third_party/blink/renderer/modules/permissions/permission_utils.cc index 981d876..bd9b0e8a 100644 --- a/third_party/blink/renderer/modules/permissions/permission_utils.cc +++ b/third_party/blink/renderer/modules/permissions/permission_utils.cc
@@ -53,6 +53,59 @@ return "denied"; } +String PermissionNameToString(mojom::blink::PermissionName name) { + switch (name) { + case mojom::blink::PermissionName::GEOLOCATION: + return "geolocation"; + case mojom::blink::PermissionName::NOTIFICATIONS: + return "notifications"; + case mojom::blink::PermissionName::MIDI: + return "midi"; + case mojom::blink::PermissionName::PROTECTED_MEDIA_IDENTIFIER: + return "protected_media_identifier"; + case mojom::blink::PermissionName::DURABLE_STORAGE: + return "durable_storage"; + case mojom::blink::PermissionName::AUDIO_CAPTURE: + return "audio_capture"; + case mojom::blink::PermissionName::VIDEO_CAPTURE: + return "video_capture"; + case mojom::blink::PermissionName::BACKGROUND_SYNC: + return "background_sync"; + case mojom::blink::PermissionName::SENSORS: + return "sensors"; + case mojom::blink::PermissionName::ACCESSIBILITY_EVENTS: + return "accessibility_events"; + case mojom::blink::PermissionName::CLIPBOARD_READ: + return "clipboard_read"; + case mojom::blink::PermissionName::CLIPBOARD_WRITE: + return "clipboard_write"; + case mojom::blink::PermissionName::PAYMENT_HANDLER: + return "payment_handler"; + case mojom::blink::PermissionName::BACKGROUND_FETCH: + return "background_fetch"; + case mojom::blink::PermissionName::IDLE_DETECTION: + return "idle_detection"; + case mojom::blink::PermissionName::PERIODIC_BACKGROUND_SYNC: + return "periodic_background_sync"; + case mojom::blink::PermissionName::SCREEN_WAKE_LOCK: + return "screen_wake_lock"; + case mojom::blink::PermissionName::SYSTEM_WAKE_LOCK: + return "system_wake_lock"; + case mojom::blink::PermissionName::NFC: + return "nfc"; + case mojom::blink::PermissionName::STORAGE_ACCESS: + return "storage_access"; + case mojom::blink::PermissionName::WINDOW_PLACEMENT: + return "window_placement"; + case mojom::blink::PermissionName::FONT_ACCESS: + return "font_access"; + case mojom::blink::PermissionName::DISPLAY_CAPTURE: + return "display_capture"; + } + NOTREACHED(); + return "unknown"; +} + PermissionDescriptorPtr CreatePermissionDescriptor(PermissionName name) { auto descriptor = MojoPermissionDescriptor::New(); descriptor->name = name;
diff --git a/third_party/blink/renderer/modules/permissions/permission_utils.h b/third_party/blink/renderer/modules/permissions/permission_utils.h index 07f8e74..5aebc09 100644 --- a/third_party/blink/renderer/modules/permissions/permission_utils.h +++ b/third_party/blink/renderer/modules/permissions/permission_utils.h
@@ -23,6 +23,8 @@ String PermissionStatusToString(mojom::blink::PermissionStatus); +String PermissionNameToString(mojom::blink::PermissionName); + mojom::blink::PermissionDescriptorPtr CreatePermissionDescriptor( mojom::blink::PermissionName);
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc index cd6011c..10932ce 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -1001,6 +1001,18 @@ shared_image_usage_flags &= ~gpu::SHARED_IMAGE_USAGE_SCANOUT; } +#if defined(OS_MAC) + if ((shared_image_usage_flags & gpu::SHARED_IMAGE_USAGE_SCANOUT) && + is_accelerated && + adjusted_params.GetSkColorType() == kRGBA_8888_SkColorType) { + // GPU-accelerated scannout usage on Mac uses IOSurface. Must switch from + // RGBA_8888 to BGRA_8888 in that case. + adjusted_params = CanvasResourceParams(adjusted_params.ColorSpace(), + kBGRA_8888_SkColorType, + adjusted_params.GetSkAlphaType()); + } +#endif + auto provider = std::make_unique<CanvasResourceProviderSharedImage>( size, filter_quality, adjusted_params, context_provider_wrapper, is_origin_top_left, is_accelerated, skia_use_dawn,
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc index 4971786..50933a0 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" +#include "build/build_config.h" #include "components/viz/common/resources/release_callback.h" #include "components/viz/test/test_context_provider.h" #include "components/viz/test/test_gles2_interface.h" @@ -93,8 +94,12 @@ EXPECT_TRUE(provider->SupportsSingleBuffering()); EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it - // will internally force it to kRGBA8 + // will internally force it to RGBA8, or BGRA8 on MacOS +#if defined(OS_MAC) + EXPECT_EQ(provider->ColorParams().GetSkColorType(), kBGRA_8888_SkColorType); +#else EXPECT_EQ(provider->ColorParams().GetSkColorType(), kRGBA_8888_SkColorType); +#endif EXPECT_EQ(provider->ColorParams().GetSkAlphaType(), kColorParams.GetSkAlphaType()); @@ -182,8 +187,12 @@ EXPECT_FALSE(provider->SupportsSingleBuffering()); EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it - // will internally force it to kRGBA8 + // will internally force it to RGBA8, or BGRA8 on MacOS +#if defined(OS_MAC) + EXPECT_EQ(provider->ColorParams().GetSkColorType(), kBGRA_8888_SkColorType); +#else EXPECT_EQ(provider->ColorParams().GetSkColorType(), kRGBA_8888_SkColorType); +#endif EXPECT_EQ(provider->ColorParams().GetSkAlphaType(), kColorParams.GetSkAlphaType()); @@ -364,8 +373,12 @@ EXPECT_TRUE(provider->SupportsSingleBuffering()); EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it - // will internally force it to kRGBA8 + // will internally force it to RGBA8, or BGRA8 on MacOS +#if defined(OS_MAC) + EXPECT_EQ(provider->ColorParams().GetSkColorType(), kBGRA_8888_SkColorType); +#else EXPECT_EQ(provider->ColorParams().GetSkColorType(), kRGBA_8888_SkColorType); +#endif EXPECT_EQ(provider->ColorParams().GetSkAlphaType(), kColorParams.GetSkAlphaType());
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 227ebe54..904bd78 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -442,8 +442,8 @@ { name: "ConditionalFocus", origin_trial_feature_name: "ConditionalFocus", - depends_on: ["GetDisplayMedia"], status: {"Android": "", "default": "experimental"}, + implied_by: ["RegionCapture"], }, { name: "ConsolidatedMovementXY", @@ -1847,7 +1847,7 @@ }, { name: "RegionCapture", - status: "experimental", + status: {"Android": "", "default": "experimental"}, }, { name: "RemotePlayback",
diff --git a/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_finder.py b/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_finder.py index 522d86a9..66fcb0cd 100644 --- a/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_finder.py +++ b/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_finder.py
@@ -183,7 +183,8 @@ line = self._strip_comments(line) if not line: continue - is_glob = line[-1] == '*' and line[-2] != '\\' + is_glob = line[-1] == '*' and (len(line) == 1 + or line[-2] != '\\') if line[0] == '-': if is_glob: negative_globs.append(line)
diff --git a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/builders.py b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/builders.py index f7e47cf..0a20f1a 100644 --- a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/builders.py +++ b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/builders.py
@@ -26,8 +26,13 @@ } def GetFakeCiBuilders(self): + # Some of these are weird in that they're explicitly defined trybots + # instead of a mirror of a CI bot. return { # chromium.fyi + 'linux-blink-optional-highdpi-rel-dummy': { + 'linux-blink-optional-highdpi-rel', + }, 'linux-blink-rel-dummy': { 'linux-blink-rel', 'v8_linux_blink_rel', @@ -47,6 +52,9 @@ 'mac11.0-blink-rel-dummy': { 'mac11.0-blink-rel', }, + 'mac11.0.arm64-blink-rel-dummy': { + 'mac11.0.arm64-blink-rel', + }, 'WebKit Linux composite_after_paint Dummy Builder': { 'linux_layout_tests_composite_after_paint', }, @@ -59,9 +67,29 @@ 'win10.20h2-blink-rel-dummy': { 'win10.20h2-blink-rel', }, + # tryserver.chromium.linux + # Explicit trybot. + 'linux-blink-web-tests-force-accessibility-rel': { + 'linux-blink-web-tests-force-accessibility-rel', + }, + # Explicit trybot. + 'linux-layout-tests-edit-ng': { + 'linux-layout-tests-edit-ng', + }, } def GetNonChromiumBuilders(self): return { + 'devtools_frontend_linux_blink_light_rel', + 'devtools_frontend_linux_blink_rel', + 'DevTools Linux', 'DevTools Linux (chromium)', + # Could be used in the future, but has never run any builds. + 'linux-exp-code-coverage', + 'ToTMacOfficial', + 'V8 Blink Linux', + 'V8 Blink Linux Debug', + 'V8 Blink Linux Future', + 'V8 Blink Mac', + 'V8 Blink Win', }
diff --git a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/constants.py b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/constants.py new file mode 100644 index 0000000..d1b22ef --- /dev/null +++ b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/constants.py
@@ -0,0 +1,10 @@ +# Copyright 2021 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. +"""Constants for stale expectation removal.""" + +import os + +WEB_TEST_ROOT_DIR = os.path.realpath( + os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', + 'web_tests'))
diff --git a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/expectations.py b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/expectations.py index d6f726c..4bdbadb 100644 --- a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/expectations.py +++ b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/expectations.py
@@ -5,13 +5,12 @@ import os +from blinkpy.web_tests.stale_expectation_removal import constants + from unexpected_passes_common import expectations -WEB_TEST_ROOT_DIR = os.path.realpath( - os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', - 'web_tests')) - -MAIN_EXPECTATION_FILE = os.path.join(WEB_TEST_ROOT_DIR, 'TestExpectations') +MAIN_EXPECTATION_FILE = os.path.join(constants.WEB_TEST_ROOT_DIR, + 'TestExpectations') TOP_LEVEL_EXPECTATION_FILES = { 'ASANExpectations', @@ -20,6 +19,7 @@ # NeverFixTests omitted since they're never expected to be # unsuppressed. 'SlowTests', + 'TestExpectations', 'W3CImportExpectations', 'WPTOverrideExpectations', 'WebDriverExpectations', @@ -43,8 +43,8 @@ self._expectation_filepaths = [] for ef in self._GetTopLevelExpectationFiles(): self._expectation_filepaths.append( - os.path.join(WEB_TEST_ROOT_DIR, ef)) - flag_directory = os.path.join(WEB_TEST_ROOT_DIR, + os.path.join(constants.WEB_TEST_ROOT_DIR, ef)) + flag_directory = os.path.join(constants.WEB_TEST_ROOT_DIR, 'FlagExpectations') for ef in self._GetFlagSpecificExpectationFiles(): self._expectation_filepaths.append( @@ -58,7 +58,7 @@ def _GetFlagSpecificExpectationFiles(self): if self._flag_specific_expectation_files is None: self._flag_specific_expectation_files = set() - flag_directory = os.path.join(WEB_TEST_ROOT_DIR, + flag_directory = os.path.join(constants.WEB_TEST_ROOT_DIR, 'FlagExpectations') for ef in os.listdir(flag_directory): if ef != 'README.txt':
diff --git a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/queries.py b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/queries.py new file mode 100644 index 0000000..40bfefb --- /dev/null +++ b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/queries.py
@@ -0,0 +1,185 @@ +# Copyright 2021 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. +"""Web test-specific impl of the unexpected passes' queries module.""" + +import os +import posixpath + +from blinkpy.web_tests.stale_expectation_removal import constants + +from unexpected_passes_common import queries as queries_module + +# The target number of results/rows per query when running in large query mode. +# Higher values = longer individual query times and higher chances of running +# out of memory in BigQuery. Lower values = more parallelization overhead and +# more issues with rate limit errors. +TARGET_RESULTS_PER_QUERY = 20000 + +# This query gets us all results for tests that have had results with a +# Failure, Timeout, or Crash expectation in the past |@num_samples| builds on +# |@builder_name|. Whether these are CI or try results depends on whether +# |builder_type| is "ci" or "try". +BQ_QUERY_TEMPLATE = """\ +WITH + builds AS ( + SELECT + DISTINCT exported.id build_inv_id, + partition_time + FROM `chrome-luci-data.chromium.blink_web_tests_{builder_type}_test_results` tr + WHERE + exported.realm = "chromium:{builder_type}" + AND STRUCT("builder", @builder_name) IN UNNEST(variant) + ORDER BY partition_time DESC + LIMIT @num_builds + ), + results AS ( + SELECT + exported.id, + test_id, + status, + ( + SELECT value + FROM tr.tags + WHERE key = "step_name") as step_name, + ARRAY( + SELECT value + FROM tr.tags + WHERE key = "typ_tag") as typ_tags, + ARRAY( + SELECT value + FROM tr.tags + WHERE key = "raw_typ_expectation") as typ_expectations, + ARRAY( + SELECT value + FROM tr.tags + WHERE key = "web_tests_used_expectations_file") as expectation_files + FROM + `chrome-luci-data.chromium.blink_web_tests_{builder_type}_test_results` tr, + builds b + WHERE + exported.id = build_inv_id + AND status != "SKIP" + {test_filter_clause} + ) +SELECT * +FROM results +WHERE + "Failure" IN UNNEST(typ_expectations) + OR "Crash" IN UNNEST(typ_expectations) + OR "Timeout" IN UNNEST(typ_expectations) +""" + +# Very similar to above, but used to get the names of tests that are of +# interest for use as a filter. +TEST_FILTER_QUERY_TEMPLATE = """\ +WITH + builds AS ( + SELECT + DISTINCT exported.id build_inv_id, + partition_time + FROM + `chrome-luci-data.chromium.blink_web_tests_{builder_type}_test_results` tr + WHERE + exported.realm = "chromium:{builder_type}" + AND STRUCT("builder", @builder_name) IN UNNEST(variant) + ORDER BY partition_time DESC + LIMIT 50 + ), + results AS ( + SELECT + exported.id, + test_id, + ARRAY( + SELECT value + FROM tr.tags + WHERE key = "raw_typ_expectation") as typ_expectations + FROM + `chrome-luci-data.chromium.blink_web_tests_{builder_type}_test_results` tr, + builds b + WHERE + exported.id = build_inv_id + AND status != "SKIP" + ) +SELECT DISTINCT r.test_id +FROM results r +WHERE + "Failure" IN UNNEST(typ_expectations) + OR "Crash" IN UNNEST(typ_expectations) + OR "Timeout" IN UNNEST(typ_expectations) +""" + +KNOWN_TEST_ID_PREFIXES = [ + 'ninja://:blink_web_tests/', + 'ninja://:webgpu_blink_web_tests', +] + + +class WebTestBigQueryQuerier(queries_module.BigQueryQuerier): + def _GetRelevantExpectationFilesForQueryResult(self, query_result): + # Files in the query are either relative to the web tests directory or + # are an absolute path. The paths are always POSIX-style. We don't + # handle absolute paths since those typically point to temporary files + # which will not exist locally. + filepaths = [] + for f in query_result.get('expectation_files', []): + if posixpath.isabs(f): + continue + f = f.replace('/', os.sep) + f = os.path.join(constants.WEB_TEST_ROOT_DIR, f) + filepaths.append(f) + return filepaths + + def _ShouldSkipOverResult(self, _): + return False + + def _GetQueryGeneratorForBuilder(self, builder, builder_type): + # Look for all tests. + if not self._large_query_mode: + return WebTestFixedQueryGenerator(builder_type, '') + + query = TEST_FILTER_QUERY_TEMPLATE.format(builder_type=builder_type) + query_results = self._RunBigQueryCommandsForJsonOutput( + query, {'': { + 'builder_name': builder + }}) + test_ids = ['"%s"' % r['test_id'] for r in query_results] + + if not test_ids: + return None + + # Only consider specific test cases that were found to have active + # expectations in the above query. Also perform any initial query + # splitting. + target_num_ids = TARGET_RESULTS_PER_QUERY / self._num_samples + return WebTestSplitQueryGenerator(builder_type, test_ids, + target_num_ids) + + def _StripPrefixFromTestId(self, test_id): + # Web test IDs provided by ResultDB are the test name known by the test + # runner prefixed by one of the following: + # "ninja://:blink_web_tests/" + # "ninja://:webgpu_blink_web_tests/" + for prefix in KNOWN_TEST_ID_PREFIXES: + if test_id.startswith(prefix): + return test_id.replace(prefix, '') + raise RuntimeError('Unable to strip prefix from test ID %s' % test_id) + + +class WebTestFixedQueryGenerator(queries_module.FixedQueryGenerator): + def GetQueries(self): + return QueryGeneratorImpl(self.GetClauses(), self._builder_type) + + +class WebTestSplitQueryGenerator(queries_module.SplitQueryGenerator): + def GetQueries(self): + return QueryGeneratorImpl(self.GetClauses(), self._builder_type) + + +def QueryGeneratorImpl(test_filter_clauses, builder_type): + queries = [] + for tfc in test_filter_clauses: + queries.append( + BQ_QUERY_TEMPLATE.format(builder_type=builder_type, + test_filter_clause=tfc)) + return queries
diff --git a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/queries_unittest.py b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/queries_unittest.py new file mode 100755 index 0000000..124b64a --- /dev/null +++ b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/queries_unittest.py
@@ -0,0 +1,116 @@ +#!/usr/bin/env vpython3 +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import unittest +import six + +if six.PY3: + import unittest.mock as mock + +from blinkpy.web_tests.stale_expectation_removal import constants +from blinkpy.web_tests.stale_expectation_removal import queries +from blinkpy.web_tests.stale_expectation_removal import unittest_utils as wt_uu + + +class GetRelevantExpectationFilesForQueryResultUnittest(unittest.TestCase): + def testNoFiles(self): + """Tests that no reported expectation files are handled properly.""" + query_result = {} + querier = wt_uu.CreateGenericWebTestQuerier() + self.assertEqual( + querier._GetRelevantExpectationFilesForQueryResult(query_result), + []) + + def testAbsolutePath(self): + """Tests that absolute paths are ignored.""" + query_result = { + 'expectation_files': ['/posix/path', '/c:/windows/path'] + } + querier = wt_uu.CreateGenericWebTestQuerier() + self.assertEqual( + querier._GetRelevantExpectationFilesForQueryResult(query_result), + []) + + def testRelativePath(self): + """Tests that relative paths are properly reconstructed.""" + query_result = { + 'expectation_files': + ['TestExpectations', 'flag-specific/someflag'] + } + querier = wt_uu.CreateGenericWebTestQuerier() + expected_files = [ + os.path.join(constants.WEB_TEST_ROOT_DIR, 'TestExpectations'), + os.path.join(constants.WEB_TEST_ROOT_DIR, 'flag-specific', + 'someflag'), + ] + self.assertEqual( + querier._GetRelevantExpectationFilesForQueryResult(query_result), + expected_files) + + +@unittest.skipIf(six.PY2, 'Script and unittest are Python 3-only') +class GetQueryGeneratorForBuilderUnittest(unittest.TestCase): + def setUp(self): + self._query_patcher = mock.patch( + 'blinkpy.web_tests.stale_expectation_removal.queries.' + 'WebTestBigQueryQuerier._RunBigQueryCommandsForJsonOutput') + self._query_mock = self._query_patcher.start() + self.addCleanup(self._query_patcher.stop) + + def testNoLargeQueryMode(self): + """Tests that the expected clause is returned in normal mode.""" + querier = wt_uu.CreateGenericWebTestQuerier() + query_generator = querier._GetQueryGeneratorForBuilder('', '') + self.assertEqual(len(query_generator.GetClauses()), 1) + self.assertEqual(query_generator.GetClauses()[0], '') + self.assertIsInstance(query_generator, + queries.WebTestFixedQueryGenerator) + self._query_mock.assert_not_called() + + def testLargeQueryModeNoTests(self): + """Tests that a special value is returned if no tests are found.""" + querier = wt_uu.CreateGenericWebTestQuerier(large_query_mode=True) + self._query_mock.return_value = [] + query_generator = querier._GetQueryGeneratorForBuilder('', '') + self.assertIsNone(query_generator) + self._query_mock.assert_called_once() + + def testLargeQueryModeFoundTests(self): + """Tests that a clause containing found tests is returned.""" + querier = wt_uu.CreateGenericWebTestQuerier(large_query_mode=True) + self._query_mock.return_value = [ + { + 'test_id': 'foo_test', + }, + { + 'test_id': 'bar_test', + }, + ] + query_generator = querier._GetQueryGeneratorForBuilder('', '') + self.assertEqual(query_generator.GetClauses(), + ['AND test_id IN UNNEST(["foo_test", "bar_test"])']) + self.assertIsInstance(query_generator, + queries.WebTestSplitQueryGenerator) + + +class StripPrefixFromTestIdUnittest(unittest.TestCase): + def testUnknownPrefix(self): + """Tests that an error is raised if an unknown prefix is found.""" + querier = wt_uu.CreateGenericWebTestQuerier() + with self.assertRaises(RuntimeError): + querier._StripPrefixFromTestId('foobar') + + def testKnownPrefixes(self): + """Tests that all known prefixes are properly stripped.""" + querier = wt_uu.CreateGenericWebTestQuerier() + test_ids = [prefix + 'a' for prefix in queries.KNOWN_TEST_ID_PREFIXES] + for t in test_ids: + stripped = querier._StripPrefixFromTestId(t) + self.assertEqual(stripped, 'a') + + +if __name__ == '__main__': + unittest.main(verbosity=2)
diff --git a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/remove_stale_expectations.py b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/remove_stale_expectations.py index ac07e380..0c3a887b 100644 --- a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/remove_stale_expectations.py +++ b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/remove_stale_expectations.py
@@ -10,7 +10,9 @@ from blinkpy.web_tests.stale_expectation_removal import builders from blinkpy.web_tests.stale_expectation_removal import expectations +from blinkpy.web_tests.stale_expectation_removal import queries from unexpected_passes_common import builders as common_builders +from unexpected_passes_common import result_output def ParseArgs(): @@ -89,6 +91,23 @@ test_expectation_map = expectations_instance.CreateTestExpectationMap( expectations_instance.GetExpectationFilepaths(), None) ci_builders = builders_instance.GetCiBuilders(None) + + querier = queries.WebTestBigQueryQuerier(None, args.project, + args.num_samples, + args.large_query_mode) + # Unmatched results are mainly useful for script maintainers, as they don't + # provide any additional information for the purposes of finding + # unexpectedly passing tests or unused expectations. + unmatched = querier.FillExpectationMapForCiBuilders( + test_expectation_map, ci_builders) + try_builders = builders_instance.GetTryBuilders(ci_builders) + unmatched.update( + querier.FillExpectationMapForTryBuilders(test_expectation_map, + try_builders)) + unused_expectations = test_expectation_map.FilterOutUnusedExpectations() + stale, semi_stale, active = test_expectation_map.SplitByStaleness() + result_output.OutputResults(stale, semi_stale, active, unmatched, + unused_expectations, args.output_format) return 0
diff --git a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/unittest_utils.py b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/unittest_utils.py new file mode 100644 index 0000000..7527bac --- /dev/null +++ b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/unittest_utils.py
@@ -0,0 +1,12 @@ +# Copyright 2021 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. + +from blinkpy.web_tests.stale_expectation_removal import queries +from unexpected_passes_common import unittest_utils as uu + + +def CreateGenericWebTestQuerier(*args, **kwargs): + return uu.CreateGenericQuerier(cls=queries.WebTestBigQueryQuerier, + *args, + **kwargs)
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 0a07e2c..0c958156 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -420,6 +420,9 @@ crbug.com/1170337 [ Mac10.13 ] external/wpt/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.NaN.worker.html [ Timeout ] crbug.com/1170337 [ Mac10.13 ] external/wpt/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.zero.worker.html [ Skip Timeout ] +# Off by one pixel error on ref test +crbug.com/1259367 [ Mac ] printing/offscreencanvas-webgl-printing.html [ Failure ] + # Subpixel differences due to compositing on Mac10.14+. crbug.com/997202 [ Mac10.14 ] external/wpt/svg/extensibility/foreignObject/foreign-object-scale-scroll.html [ Failure ] crbug.com/997202 [ Mac10.15 ] external/wpt/svg/extensibility/foreignObject/foreign-object-scale-scroll.html [ Failure ] @@ -1713,8 +1716,6 @@ crbug.com/1234199 [ Mac ] external/wpt/html/semantics/embedded-content/the-object-element/object-events.html [ Skip ] crbug.com/1232504 [ Mac11.0 ] external/wpt/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/endTime.html [ Failure Timeout ] crbug.com/1232504 [ Mac11.0 ] external/wpt/html/semantics/embedded-content/media-elements/preserves-pitch.html [ Timeout ] -crbug.com/1240701 virtual/dialogfocus-old-behavior/external/wpt/html/semantics/interactive-elements/the-dialog-element/modal-dialog-display-contents.html [ Failure ] -crbug.com/1240701 external/wpt/html/semantics/interactive-elements/the-dialog-element/modal-dialog-display-contents.html [ Failure ] # XML nodes aren't match by .class selectors: crbug.com/649444 external/wpt/css/selectors/xml-class-selector.xml [ Failure ] @@ -7052,7 +7053,7 @@ crbug.com/1249176 [ Mac11-arm64 ] external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-014.html [ Failure Pass ] crbug.com/1249176 [ Mac11-arm64 ] virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Failure Pass ] crbug.com/1249176 [ Mac11-arm64 ] virtual/scalefactor200withoutzoom/external/wpt/largest-contentful-paint/multiple-redirects-TAO.html [ Failure Pass ] -crbug.com/1249176 [ Mac11-arm64 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/split.https.html [ Timeout Pass ] +crbug.com/1249176 [ Mac11-arm64 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/split.https.html [ Pass Timeout ] # mac-arm CI 10-01-2021 crbug.com/1249176 [ Mac11-arm64 ] editing/text-iterator/beforematch-async.html [ Failure ] @@ -7221,4 +7222,5 @@ crbug.com/1259133 [ Mac10.14 ] virtual/no-alloc-direct-call/external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.commit.html [ Failure Pass ] crbug.com/1259167 [ Mac ] virtual/threaded/external/wpt/scroll-animations/scroll-animation-inactive-timeline.html [ Failure Pass ] crbug.com/1259188 [ Mac10.14 ] virtual/gpu-rasterization/images/color-profile-animate.html [ Failure Pass ] -crbug.com/1259255 [ Win7 ] virtual/scroll-unification/fast/events/mouse-cursor-no-mousemove.html [ Failure Pass ] +crbug.com/1197465 [ Win7 ] virtual/scroll-unification/fast/events/mouse-cursor-no-mousemove.html [ Failure Pass ] +crbug.com/1259277 [ Debug Linux ] virtual/scroll-unification/fast/events/message-port-multi.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations b/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations index 1e759a8..59d5a73 100644 --- a/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations +++ b/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations
@@ -807,6 +807,7 @@ crbug.com/1050754 external/wpt/external/wpt/css/css-shapes/shape-outside/values/shape-margin-001.html [ Failure ] crbug.com/1050754 external/wpt/external/wpt/css/css-shapes/shape-outside/values/shape-outside-shape-arguments-000.html [ Failure ] crbug.com/1050754 external/wpt/external/wpt/css/cssom-view/scrollintoview.html [ Failure ] +crbug.com/1050754 external/wpt/external/wpt/editing/other/editable-state-and-focus-in-shadow-dom-in-designMode.tentative.html [ Timeout ] crbug.com/1050754 external/wpt/external/wpt/fetch/api/basic/status.h2.any.html [ Failure ] crbug.com/1050754 external/wpt/external/wpt/fetch/api/basic/status.h2.any.worker.html [ Failure ] crbug.com/1050754 external/wpt/external/wpt/fetch/api/headers/headers-normalize.any.sharedworker.html [ Failure ]
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 31e27a5..4464ce6d 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
@@ -639,6 +639,13 @@ ] }, "css-inline": { + "change-inline-change-abspos-crash.html": [ + "7752cc6592da6b017788157372329a5cb591d63e", + [ + null, + {} + ] + ], "inline-002-crash.html": [ "a10eee9907f3ca27b3265452aeb19e2b9710b55d", [ @@ -78036,6 +78043,73 @@ {} ] ], + "grid": { + "grid-container-fragmentation-001.html": [ + "0b954f2814850a23cf77a4f0595c7a49235e33f6", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "grid-container-fragmentation-002.html": [ + "aec5085991c0b0f4df95b7bf6b1e354f15be92e5", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "grid-container-fragmentation-003.html": [ + "659d9eaac5fe52785356d0e80bf37e18c2dd1e4b", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "grid-container-fragmentation-004.html": [ + "3e276060711faeb56d6576e4748b67c2334ae0d7", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "grid-container-fragmentation-005.html": [ + "a110275ff87dff4300a57322e4a0bc01f5eae20a", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ] + }, "ink-overflow-002.html": [ "8af605efea87b618007641729bd3b579fcb654eb", [ @@ -79115,6 +79189,19 @@ {} ] ], + "out-of-flow-in-multicolumn-075.html": [ + "34cf1ea74dda8a56c49a59ded805af83de84a75f", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "overflow-clip-000.html": [ "72b10f5cdd3092a042f1f90bff04e9428d61608e", [ @@ -229854,18 +229941,6 @@ "ffac42763f9f7221b78b6d685e49ce7854537b20", [] ], - "layer-basic-expected.txt": [ - "0cc2db7f0a0591080afbd6c80738c0d9c780385f", - [] - ], - "layer-import-expected.txt": [ - "1fc7e1b2e9146c0291d5797f452844a6f2ac4a61", - [] - ], - "layer-keyframes-override-expected.txt": [ - "1d5989fa0aa52c39c6d888fd58118f07007bd03d", - [] - ], "layer-stylesheet-sharing-ref.html": [ "fe004e5bda989248b67aad3b5c20f8a280447914", [] @@ -263914,7 +263989,7 @@ } }, "historical-expected.txt": [ - "4c0f1de272a71260bffdf9500383d81fafba50e2", + "4303f9b60573df10f4920ee4c83fea4795cb7433", [] ], "idlharness.window_exclude=Node-expected.txt": [ @@ -264657,7 +264732,7 @@ ], "include": { "editor-test-utils.js": [ - "3ca014a472fa45991e38d565a10fe9dc9afa6ff8", + "9ce5ff12226783a4147c2b344962c5a6def26727", [] ], "implementation.js": [ @@ -264702,6 +264777,10 @@ "e8a01d24d6815990f64169aff48b2977567bb3be", [] ], + "editable-state-and-focus-in-shadow-dom-in-designMode.tentative-expected.txt": [ + "3b6b947a443781c22448f24ddb3ea7865b2e8d48", + [] + ], "editing-around-select-element.tentative_delete-expected.txt": [ "6c018e9e1a8bcff1c72b6cd7b04b2c31938bfe92", [] @@ -294850,7 +294929,7 @@ [] ], "testharness.js": [ - "b4bed2b31fe327247cc505c456d3a7c38d2bd320", + "6fe5580ae7a1ab1a8439d8accfd74b8c92c3cf2b", [] ], "testharness.js.headers": [ @@ -341539,49 +341618,49 @@ ] ], "layer-basic.html": [ - "f92e142f91759049bae0f996866aff3cfb94c7ca", + "e214bffc25f5fc3b56480ec9c8704a80bf109c17", [ null, {} ] ], "layer-counter-style-override.html": [ - "7ffd3583da8b2d3d6eaee2b9f8defc8570d32081", + "1720898457b52344b270b28f435ebbaff5600923", [ null, {} ] ], "layer-font-face-override.html": [ - "8275b0815a241fdfcaac57aca4aba06b144afe8d", + "d35caca0129d16585f483b70d0fc746de189f29e", [ null, {} ] ], "layer-import.html": [ - "935659ac1a3eb7d3d015138e86b2d81238d111c9", + "0406f02927a87654b7636e01469488eb32e13e84", [ null, {} ] ], "layer-keyframes-override.html": [ - "f8963031826564d474bca1fcb818835d41d280b2", + "d0f4044f1e7f4610b7cf9f08f9012d9483c6f2dc", [ null, {} ] ], "layer-property-override.html": [ - "f0f8d833ac2e32225baa256a9afd3db5562f7a1a", + "9d3f9cb926a22b7c78d29c5510ab1ab56294bd78", [ null, {} ] ], "layer-scroll-timeline-override.html": [ - "9a50914e74448739b37f0b24193451e6a90995ef", + "59b8590b5f19277acc719600c99136aef2e532ca", [ null, {} @@ -341618,7 +341697,7 @@ ] }, "presentational-hints-cascade.html": [ - "729dc71666a903f9368f8cc24f4ad6836af24fdc", + "c3188fd0d7bcd7085094e285c62c3fd8f8e213d8", [ null, {} @@ -369443,7 +369522,7 @@ ] }, "historical.html": [ - "8a71e364e5ef30a0f9d9621d3eb018a34d42ae4c", + "7ef7e8032c7f46d66cb24db053949c38392fe288", [ null, {} @@ -372095,6 +372174,15 @@ } ] ], + "editable-state-and-focus-in-shadow-dom-in-designMode.tentative.html": [ + "88e6d291299c2fec70b91d5459c88ac855381f75", + [ + null, + { + "testdriver": true + } + ] + ], "editing-around-select-element.tentative.html": [ "9182216efd715112932755a1ecc56a6cb3c3adf3", [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-hit-test-contents-crash.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-hit-test-contents-crash.html new file mode 100644 index 0000000..737d2af --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-hit-test-contents-crash.html
@@ -0,0 +1,27 @@ +<!doctype html> +<link rel=author name="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel=assert content="Hit testing around hidden elements should not crash regardless of contents"> + +<style> +.box { width: 100px; height: 100px; border: 1px solid black; } +.hidden { content-visibility: hidden } +</style> + +<div id=container class="box hidden"> + content + <dialog id=dialog> + dialog + <div id=inner></div> + </dialog> +</div> +text + +<script> +function runTest() { + inner.getBoundingClientRect(); + document.elementFromPoint(20, 109); + document.elementFromPoint(20, 20); +} + +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-highlight-api/Highlight-type-attribute.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-highlight-api/Highlight-type-attribute.tentative.html new file mode 100644 index 0000000..97e3aaa3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-highlight-api/Highlight-type-attribute.tentative.html
@@ -0,0 +1,20 @@ +<!doctype html> +<title> Highlight type attribute tests </title> +<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + test(() => { + let customHighlight = new Highlight(); + assert_equals(customHighlight.type, "highlight", 'Highlight uses \"highlight\" as default type.'); + + customHighlight.type = "type-not-listed-in-HighlightType-enum"; + assert_equals(customHighlight.type, "highlight", 'Highlight type doesn\'t change after assigning an invalid value.'); + + customHighlight.type = "spelling-error"; + assert_equals(customHighlight.type, "spelling-error", 'Highlight type changes to the assigned value if it\'s part of the HighlightType enum (\"spelling-error\"").'); + + customHighlight.type = "grammar-error"; + assert_equals(customHighlight.type, "grammar-error", 'Highlight type changes to the assigned value if it\'s part of the HighlightType enum (\"grammar-error\").'); + }, 'Highlight has a mutable \'type\' attribute that is a HighlightType enum.'); +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/dom/historical-expected.txt b/third_party/blink/web_tests/external/wpt/dom/historical-expected.txt index 4c0f1de..4303f9b6 100644 --- a/third_party/blink/web_tests/external/wpt/dom/historical-expected.txt +++ b/third_party/blink/web_tests/external/wpt/dom/historical-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 76 tests; 72 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 77 tests; 72 PASS, 5 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Historical DOM features must be removed: DOMConfiguration PASS Historical DOM features must be removed: DOMCursor FAIL Historical DOM features must be removed: DOMError assert_equals: expected (undefined) undefined but got (function) function "function DOMError() { [native code] }" @@ -76,5 +76,6 @@ PASS Event should not have this constant: SELECT PASS Event should not have this constant: CHANGE PASS Event.prototype should not have this property: getPreventDefault +FAIL Event.prototype should not have this property: path Illegal invocation Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/dom/historical.html b/third_party/blink/web_tests/external/wpt/dom/historical.html index 8a71e36..7ef7e80 100644 --- a/third_party/blink/web_tests/external/wpt/dom/historical.html +++ b/third_party/blink/web_tests/external/wpt/dom/historical.html
@@ -190,6 +190,7 @@ var EventPrototypeRemoved = [ "getPreventDefault", + "path" ] EventPrototypeRemoved.forEach(name => { test(() => {
diff --git a/third_party/blink/web_tests/external/wpt/editing/include/editor-test-utils.js b/third_party/blink/web_tests/external/wpt/editing/include/editor-test-utils.js index 3ca014a..9ce5ff12 100644 --- a/third_party/blink/web_tests/external/wpt/editing/include/editor-test-utils.js +++ b/third_party/blink/web_tests/external/wpt/editing/include/editor-test-utils.js
@@ -73,6 +73,27 @@ return this.sendKey(kEnd, modifier); } + sendSelectAllShortcutKey() { + return this.sendKey( + "a", + (() => { + // Gecko for Linux defines only Alt-A as a shortcut key for select all, + // although in most environment, Ctrl-A works as so too, but it depends + // on the OS settings. + if ( + this.window.navigator.userAgent.includes("Linux") && + this.window.navigator.userAgent.includes("Gecko") && + !this.window.navigator.userAgent.includes("KHTML") + ) { + return this.kAlt; + } + return this.window.navigator.platform.includes("Mac") + ? this.kMeta + : this.kControl; + })() + ); + } + // Similar to `setupDiv` in editing/include/tests.js, this method sets // innerHTML value of this.editingHost, and sets multiple selection ranges // specified with the markers. @@ -142,7 +163,7 @@ return { marker: scanResult[0], container: textNode, - offset: scanResult.index + offset + offset: scanResult.index + offset, }; }; if (startContainer.nodeType === Node.TEXT_NODE) { @@ -181,7 +202,7 @@ return { marker: scanResult[0], container: textNode, - offset: scanResult.index + offset + offset: scanResult.index + offset, }; }; if (startContainer.nodeType === Node.TEXT_NODE) {
diff --git a/third_party/blink/web_tests/external/wpt/editing/other/editable-state-and-focus-in-shadow-dom-in-designMode.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/editing/other/editable-state-and-focus-in-shadow-dom-in-designMode.tentative-expected.txt new file mode 100644 index 0000000..3b6b947a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/editing/other/editable-state-and-focus-in-shadow-dom-in-designMode.tentative-expected.txt
@@ -0,0 +1,24 @@ +This is a testharness.js-based test. +PASS Waiting for load +FAIL Collapse selection into text in the open shadow DOM promise_test: Unhandled rejection with value: object "Error: we do not support keydown and keyup actions, please use test_driver.send_keys" +FAIL Collapse selection into text in <div contenteditable> in the open shadow DOM promise_test: Unhandled rejection with value: object "Error: we do not support keydown and keyup actions, please use test_driver.send_keys" +FAIL Set focus to <object> in the open shadow DOM promise_test: Unhandled rejection with value: object "Error: we do not support keydown and keyup actions, please use test_driver.send_keys" +FAIL Set focus to <p tabindex="0"> in the open shadow DOM promise_test: Unhandled rejection with value: object "Error: we do not support keydown and keyup actions, please use test_driver.send_keys" +FAIL SelectAll in the open shadow DOM promise_test: Unhandled rejection with value: object "Error: we do not support keydown and keyup actions, please use test_driver.send_keys" +FAIL SelectAll in the <div contenteditable> in the open shadow DOM promise_test: Unhandled rejection with value: object "Error: we do not support keydown and keyup actions, please use test_driver.send_keys" +FAIL Collapse selection into text in the closed shadow DOM promise_test: Unhandled rejection with value: object "Error: we do not support keydown and keyup actions, please use test_driver.send_keys" +FAIL Collapse selection into text in <div contenteditable> in the closed shadow DOM promise_test: Unhandled rejection with value: object "Error: we do not support keydown and keyup actions, please use test_driver.send_keys" +FAIL Set focus to <object> in the closed shadow DOM promise_test: Unhandled rejection with value: object "Error: we do not support keydown and keyup actions, please use test_driver.send_keys" +FAIL Set focus to <p tabindex="0"> in the closed shadow DOM promise_test: Unhandled rejection with value: object "Error: we do not support keydown and keyup actions, please use test_driver.send_keys" +FAIL SelectAll in the closed shadow DOM promise_test: Unhandled rejection with value: object "Error: we do not support keydown and keyup actions, please use test_driver.send_keys" +FAIL SelectAll in the <div contenteditable> in the closed shadow DOM promise_test: Unhandled rejection with value: object "Error: we do not support keydown and keyup actions, please use test_driver.send_keys" +PASS Focus after Collapse selection into text in the open shadow DOM +PASS Focus after Collapse selection into text in <div contenteditable> in the open shadow DOM +PASS Focus after Set focus to <object> in the open shadow DOM +PASS Focus after Set focus to <p tabindex="0"> in the open shadow DOM +PASS Focus after Collapse selection into text in the closed shadow DOM +PASS Focus after Collapse selection into text in <div contenteditable> in the closed shadow DOM +PASS Focus after Set focus to <object> in the closed shadow DOM +PASS Focus after Set focus to <p tabindex="0"> in the closed shadow DOM +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/editing/other/editable-state-and-focus-in-shadow-dom-in-designMode.tentative.html b/third_party/blink/web_tests/external/wpt/editing/other/editable-state-and-focus-in-shadow-dom-in-designMode.tentative.html new file mode 100644 index 0000000..88e6d2912 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/editing/other/editable-state-and-focus-in-shadow-dom-in-designMode.tentative.html
@@ -0,0 +1,252 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<title>Testing editable state and focus in shadow DOM in design mode</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<h3>open</h3> +<my-shadow data-mode="open"></my-shadow> +<h3>closed</h3> +<my-shadow data-mode="closed"></my-shadow> + +<script> +"use strict"; + +document.designMode = "on"; +const utils = new EditorTestUtils(document.body); + +class MyShadow extends HTMLElement { + #defaultInnerHTML = + "<style>:focus { outline: 3px red solid; }</style>" + + "<div>text" + + "<div contenteditable=\"\">editable</div>" + + "<object tabindex=\"0\">object</object>" + + "<p tabindex=\"0\">paragraph</p>" + + "</div>"; + #shadowRoot; + + constructor() { + super(); + this.#shadowRoot = this.attachShadow({mode: this.getAttribute("data-mode")}); + this.#shadowRoot.innerHTML = this.#defaultInnerHTML; + } + + reset() { + this.#shadowRoot.innerHTML = this.#defaultInnerHTML; + this.#shadowRoot.querySelector("div").getBoundingClientRect(); + } + + focusText() { + this.focus(); + const div = this.#shadowRoot.querySelector("div"); + getSelection().collapse(div.firstChild || div, 0); + } + + focusContentEditable() { + this.focus(); + const contenteditable = this.#shadowRoot.querySelector("div[contenteditable]"); + contenteditable.focus(); + getSelection().collapse(contenteditable.firstChild || contenteditable, 0); + } + + focusObject() { + this.focus(); + this.#shadowRoot.querySelector("object[tabindex]").focus(); + } + + focusParagraph() { + this.focus(); + const tabbableP = this.#shadowRoot.querySelector("p[tabindex]"); + tabbableP.focus(); + getSelection().collapse(tabbableP.firstChild || tabbableP, 0); + } + + getInnerHTML() { + return this.#shadowRoot.innerHTML; + } + + getDefaultInnerHTML() { + return this.#defaultInnerHTML; + } + + getFocusedElementName() { + return this.#shadowRoot.querySelector(":focus")?.tagName.toLocaleLowerCase() || ""; + } + + getSelectedRange() { + // XXX There is no standardized way to retrieve selected ranges in + // shadow trees, therefore, we use non-standardized API for now + // since the main purpose of this test is checking the behavior of + // selection changes in shadow trees, not checking the selection API. + const selection = + this.#shadowRoot.getSelection !== undefined + ? this.#shadowRoot.getSelection() + : getSelection(); + return selection.getRangeAt(0); + } +} + +customElements.define("my-shadow", MyShadow); + +function getRangeDescription(range) { + function getNodeDescription(node) { + if (!node) { + return "null"; + } + switch (node.nodeType) { + case Node.TEXT_NODE: + case Node.COMMENT_NODE: + case Node.CDATA_SECTION_NODE: + return `${node.nodeName} "${node.data}"`; + case Node.ELEMENT_NODE: + return `<${node.nodeName.toLowerCase()}>`; + default: + return `${node.nodeName}`; + } + } + if (range === null) { + return "null"; + } + if (range === undefined) { + return "undefined"; + } + return range.startContainer == range.endContainer && + range.startOffset == range.endOffset + ? `(${getNodeDescription(range.startContainer)}, ${range.startOffset})` + : `(${getNodeDescription(range.startContainer)}, ${ + range.startOffset + }) - (${getNodeDescription(range.endContainer)}, ${range.endOffset})`; +} + +promise_test(async () => { + await new Promise(resolve => addEventListener("load", resolve, {once: true})); + assert_true(true, "Load event is fired"); +}, "Waiting for load"); + +/** + * The expected result of this test is based on Blink and Gecko's behavior. + */ + +for (const mode of ["open", "closed"]) { + const host = document.querySelector(`my-shadow[data-mode=${mode}]`); + promise_test(async (t) => { + host.reset(); + host.focusText(); + test(() => { + assert_equals( + host.getFocusedElementName(), + "", + `No element should have focus after ${t.name}` + ); + }, `Focus after ${t.name}`); + await utils.sendKey("A"); + test(() => { + assert_equals( + host.getInnerHTML(), + host.getDefaultInnerHTML(), + `The shadow DOM shouldn't be modified after ${t.name}` + ); + }, `Typing "A" after ${t.name}`); + }, `Collapse selection into text in the ${mode} shadow DOM`); + + promise_test(async (t) => { + host.reset(); + host.focusContentEditable(); + test(() => { + assert_equals( + host.getFocusedElementName(), + "div", + `<div contenteditable> should have focus after ${t.name}` + ); + }, `Focus after ${t.name}`); + await utils.sendKey("A"); + test(() => { + assert_equals( + host.getInnerHTML(), + host.getDefaultInnerHTML().replace("<div contenteditable=\"\">", "<div contenteditable=\"\">A"), + `The shadow DOM shouldn't be modified after ${t.name}` + ); + }, `Typing "A" after ${t.name}`); + }, `Collapse selection into text in <div contenteditable> in the ${mode} shadow DOM`); + + promise_test(async (t) => { + host.reset(); + host.focusObject(); + test(() => { + assert_equals( + host.getFocusedElementName(), + "object", + `The <object> element should have focus after ${t.name}` + ); + }, `Focus after ${t.name}`); + await utils.sendKey("A"); + test(() => { + assert_equals( + host.getInnerHTML(), + host.getDefaultInnerHTML(), + `The shadow DOM shouldn't be modified after ${t.name}` + ); + }, `Typing "A" after ${t.name}`); + }, `Set focus to <object> in the ${mode} shadow DOM`); + + promise_test(async (t) => { + host.reset(); + host.focusParagraph(); + test(() => { + assert_equals( + host.getFocusedElementName(), + "p", + `The <p tabindex="0"> element should have focus after ${t.name}` + ); + }, `Focus after ${t.name}`); + await utils.sendKey("A"); + test(() => { + assert_equals( + host.getInnerHTML(), + host.getDefaultInnerHTML(), + `The shadow DOM shouldn't be modified after ${t.name}` + ); + }, `Typing "A" after ${t.name}`); + }, `Set focus to <p tabindex="0"> in the ${mode} shadow DOM`); + + promise_test(async (t) => { + host.reset(); + host.focusParagraph(); + await utils.sendSelectAllShortcutKey(); + assert_in_array( + getRangeDescription(host.getSelectedRange()), + [ + // Feel free to add reasonable select all result in the <my-shadow>. + "(#document-fragment, 0) - (#document-fragment, 2)", + "(#text \"text\", 0) - (#text \"paragraph\", 9)", + ], + `Only all children of the ${mode} shadow DOM should be selected` + ); + getSelection().collapse(document.body, 0); + }, `SelectAll in the ${mode} shadow DOM`); + + promise_test(async (t) => { + host.reset(); + host.focusContentEditable(); + await utils.sendSelectAllShortcutKey(); + assert_in_array( + getRangeDescription(host.getSelectedRange()), + [ + // Feel free to add reasonable select all result in the <div contenteditable>. + "(<div>, 0) - (<div>, 1)", + "(#text \"editable\", 0) - (#text \"editable\", 8)", + ] + ); + getSelection().collapse(document.body, 0); + }, `SelectAll in the <div contenteditable> in the ${mode} shadow DOM`); +} +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/getter-special-cases/cross-origin-isolated.sub.https.html b/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/getter-special-cases/cross-origin-isolated.sub.https.html index e10d3452..a521934 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/getter-special-cases/cross-origin-isolated.sub.https.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/getter-special-cases/cross-origin-isolated.sub.https.html
@@ -19,7 +19,7 @@ // Child frames of cross-origin isolated pages must also be cross-origin // isolated, and thus also origin-keyed. Make sure the implementation doesn't - // treat them specially in some wierd way, for the purposes of this + // treat them specially in some weird way, for the purposes of this // implication. testGetter(0, true, "child");
diff --git a/third_party/blink/web_tests/external/wpt/permissions/idlharness.any-expected.txt b/third_party/blink/web_tests/external/wpt/permissions/idlharness.any-expected.txt deleted file mode 100644 index 1da992c..0000000 --- a/third_party/blink/web_tests/external/wpt/permissions/idlharness.any-expected.txt +++ /dev/null
@@ -1,50 +0,0 @@ -This is a testharness.js-based test. -PASS idl_test setup -PASS idl_test validation -PASS Partial interface Navigator: original interface defined -PASS Partial interface Navigator: valid exposure set -PASS Partial interface Navigator: member names are unique -PASS Partial interface WorkerNavigator: original interface defined -PASS Partial interface WorkerNavigator: valid exposure set -PASS Partial interface WorkerNavigator: member names are unique -PASS Partial interface mixin NavigatorID: member names are unique -PASS Navigator includes NavigatorID: member names are unique -PASS Navigator includes NavigatorLanguage: member names are unique -PASS Navigator includes NavigatorOnLine: member names are unique -PASS Navigator includes NavigatorContentUtils: member names are unique -PASS Navigator includes NavigatorCookies: member names are unique -PASS Navigator includes NavigatorPlugins: member names are unique -PASS Navigator includes NavigatorConcurrentHardware: member names are unique -PASS WorkerNavigator includes NavigatorID: member names are unique -PASS WorkerNavigator includes NavigatorLanguage: member names are unique -PASS WorkerNavigator includes NavigatorOnLine: member names are unique -PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique -PASS Permissions interface: existence and properties of interface object -PASS Permissions interface object length -PASS Permissions interface object name -PASS Permissions interface: existence and properties of interface prototype object -PASS Permissions interface: existence and properties of interface prototype object's "constructor" property -PASS Permissions interface: existence and properties of interface prototype object's @@unscopables property -PASS Permissions interface: operation query(object) -PASS Permissions must be primary interface of navigator.permissions -PASS Stringification of navigator.permissions -PASS Permissions interface: navigator.permissions must inherit property "query(object)" with the proper type -PASS Permissions interface: calling query(object) on navigator.permissions with too few arguments must throw TypeError -PASS PermissionStatus interface: existence and properties of interface object -PASS PermissionStatus interface object length -PASS PermissionStatus interface object name -PASS PermissionStatus interface: existence and properties of interface prototype object -PASS PermissionStatus interface: existence and properties of interface prototype object's "constructor" property -PASS PermissionStatus interface: existence and properties of interface prototype object's @@unscopables property -PASS PermissionStatus interface: attribute state -FAIL PermissionStatus interface: attribute name assert_true: The prototype object must have a property "name" expected true got false -PASS PermissionStatus interface: attribute onchange -PASS PermissionStatus must be primary interface of permissionStatus -PASS Stringification of permissionStatus -PASS PermissionStatus interface: permissionStatus must inherit property "state" with the proper type -FAIL PermissionStatus interface: permissionStatus must inherit property "name" with the proper type assert_inherits: property "name" not found in prototype chain -PASS PermissionStatus interface: permissionStatus must inherit property "onchange" with the proper type -PASS Navigator interface: attribute permissions -PASS Navigator interface: navigator must inherit property "permissions" with the proper type -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/permissions/idlharness.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/permissions/idlharness.any.worker-expected.txt deleted file mode 100644 index 8fff624a..0000000 --- a/third_party/blink/web_tests/external/wpt/permissions/idlharness.any.worker-expected.txt +++ /dev/null
@@ -1,50 +0,0 @@ -This is a testharness.js-based test. -PASS idl_test setup -PASS idl_test validation -PASS Partial interface Navigator: original interface defined -PASS Partial interface Navigator: valid exposure set -PASS Partial interface Navigator: member names are unique -PASS Partial interface WorkerNavigator: original interface defined -PASS Partial interface WorkerNavigator: valid exposure set -PASS Partial interface WorkerNavigator: member names are unique -PASS Partial interface mixin NavigatorID: member names are unique -PASS Navigator includes NavigatorID: member names are unique -PASS Navigator includes NavigatorLanguage: member names are unique -PASS Navigator includes NavigatorOnLine: member names are unique -PASS Navigator includes NavigatorContentUtils: member names are unique -PASS Navigator includes NavigatorCookies: member names are unique -PASS Navigator includes NavigatorPlugins: member names are unique -PASS Navigator includes NavigatorConcurrentHardware: member names are unique -PASS WorkerNavigator includes NavigatorID: member names are unique -PASS WorkerNavigator includes NavigatorLanguage: member names are unique -PASS WorkerNavigator includes NavigatorOnLine: member names are unique -PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique -PASS Permissions interface: existence and properties of interface object -PASS Permissions interface object length -PASS Permissions interface object name -PASS Permissions interface: existence and properties of interface prototype object -PASS Permissions interface: existence and properties of interface prototype object's "constructor" property -PASS Permissions interface: existence and properties of interface prototype object's @@unscopables property -PASS Permissions interface: operation query(object) -PASS Permissions must be primary interface of navigator.permissions -PASS Stringification of navigator.permissions -PASS Permissions interface: navigator.permissions must inherit property "query(object)" with the proper type -PASS Permissions interface: calling query(object) on navigator.permissions with too few arguments must throw TypeError -PASS PermissionStatus interface: existence and properties of interface object -PASS PermissionStatus interface object length -PASS PermissionStatus interface object name -PASS PermissionStatus interface: existence and properties of interface prototype object -PASS PermissionStatus interface: existence and properties of interface prototype object's "constructor" property -PASS PermissionStatus interface: existence and properties of interface prototype object's @@unscopables property -PASS PermissionStatus interface: attribute state -FAIL PermissionStatus interface: attribute name assert_true: The prototype object must have a property "name" expected true got false -PASS PermissionStatus interface: attribute onchange -PASS PermissionStatus must be primary interface of permissionStatus -PASS Stringification of permissionStatus -PASS PermissionStatus interface: permissionStatus must inherit property "state" with the proper type -FAIL PermissionStatus interface: permissionStatus must inherit property "name" with the proper type assert_inherits: property "name" not found in prototype chain -PASS PermissionStatus interface: permissionStatus must inherit property "onchange" with the proper type -PASS WorkerNavigator interface: attribute permissions -PASS WorkerNavigator interface: navigator must inherit property "permissions" with the proper type -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/permissions/permissionsstatus-name-expected.txt b/third_party/blink/web_tests/external/wpt/permissions/permissionsstatus-name-expected.txt deleted file mode 100644 index 94dd7854..0000000 --- a/third_party/blink/web_tests/external/wpt/permissions/permissionsstatus-name-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Test PermissionStatus's name attribute. assert_equals: Name was geolocation expected (string) "geolocation" but got (undefined) undefined -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/resources/testharness.js b/third_party/blink/web_tests/external/wpt/resources/testharness.js index b4bed2b..6fe5580 100644 --- a/third_party/blink/web_tests/external/wpt/resources/testharness.js +++ b/third_party/blink/web_tests/external/wpt/resources/testharness.js
@@ -3414,7 +3414,12 @@ ["span", {"class":status_class(status)}, status ], - ] + ], + ["button", + {"onclick": "let evt = new Event('__test_restart'); " + + "let canceled = !window.dispatchEvent(evt);" + + "if (!canceled) { location.reload() }"}, + "Rerun"] ]]; if (harness_status.status === harness_status.ERROR) {
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-redirects-extrainfo-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-redirects-extrainfo-expected.txt new file mode 100644 index 0000000..7bcd4a71b --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-redirects-extrainfo-expected.txt
@@ -0,0 +1,27 @@ +Verifies that ExtraInfo events are emitted for each redirect in a chain in subsequent requests. + +requestWillBeSents: 2 + url: http://127.0.0.1:8000/inspector-protocol/resources/redirect2.php + url: http://127.0.0.1:8000/inspector-protocol/resources/final.html +responseReceiveds: 1 + url: http://127.0.0.1:8000/inspector-protocol/resources/final.html +requestWillBeSentExtraInfos: 2 + has headers: true + has headers: true +responseReceivedExtraInfos: 2 + has headers: true + has headers: true + +requestWillBeSents: 2 + url: http://127.0.0.1:8000/inspector-protocol/resources/redirect2.php + url: http://127.0.0.1:8000/inspector-protocol/resources/final.html +responseReceiveds: 1 + url: http://127.0.0.1:8000/inspector-protocol/resources/final.html +requestWillBeSentExtraInfos: 2 + has headers: true + has headers: false +responseReceivedExtraInfos: 2 + has headers: true + has headers: true + +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-redirects-extrainfo.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-redirects-extrainfo.js new file mode 100644 index 0000000..33be1fb --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-redirects-extrainfo.js
@@ -0,0 +1,112 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + 'Verifies that ExtraInfo events are emitted for each redirect in a chain in subsequent requests.\n'); + + await dp.Network.enable(); + + const requests = new Map(); + function pushEvent(name, event) { + if (!requests.has(event.params.requestId)) { + requests.set(event.params.requestId, {}); + } + const request = requests.get(event.params.requestId); + if (!request[name]) { + request[name] = []; + } + request[name].push(event); + } + + dp.Network.onRequestWillBeSent(event => { + pushEvent('requestWillBeSent', event); + }); + + const responseReceivedsPromise = new Promise(resolve => { + let responseReceivedCount = 0; + dp.Network.onResponseReceived(event => { + pushEvent('responseReceived', event); + responseReceivedCount++; + if (responseReceivedCount === 2) + resolve(); + }); + }); + + dp.Network.onRequestWillBeSentExtraInfo(event => { + pushEvent('requestWillBeSentExtraInfo', event); + }); + + const extraInfosPromise = new Promise(resolve => { + let extraInfoCount = 0; + dp.Network.onResponseReceivedExtraInfo(event => { + pushEvent('responseReceivedExtraInfo', event); + extraInfoCount++; + if (extraInfoCount === 4) + resolve(); + }); + }); + + + const path = '/inspector-protocol/resources/redirect2.php'; + session.evaluate(` + { + let xhr = new XMLHttpRequest(); + xhr.open('GET', '${path}'); + xhr.send(); + } + `); + session.evaluate(` + { + let xhr = new XMLHttpRequest(); + xhr.open('GET', '${path}'); + xhr.send(); + } + `); + + await responseReceivedsPromise; + await extraInfosPromise; + + for (const [requestId, request] of requests) { + const requestWillBeSents = request.requestWillBeSent; + if (requestWillBeSents) { + testRunner.log(`requestWillBeSents: ${requestWillBeSents.length}`); + for (let i = 0; i < requestWillBeSents.length; i++) { + const requestWillBeSent = requestWillBeSents[i]; + testRunner.log(` url: ${requestWillBeSent.params.request.url}`); + } + } else { + testRunner.log(`requestWilBeSents: none`); + } + + const responseReceiveds = request.responseReceived; + if (responseReceiveds) { + testRunner.log(`responseReceiveds: ${responseReceiveds.length}`); + for (let i = 0; i < responseReceiveds.length; i++) { + const responseReceived = responseReceiveds[i]; + testRunner.log(` url: ${responseReceived.params.response.url}`); + } + } else { + testRunner.log(`responseReceiveds: none`); + } + + const requestWillBeSentExtraInfos = request.requestWillBeSentExtraInfo; + if (requestWillBeSentExtraInfos) { + testRunner.log(`requestWillBeSentExtraInfos: ${requestWillBeSentExtraInfos.length}`); + for (let i = 0; i < requestWillBeSentExtraInfos.length; i++) { + const requestWillBeSentExtraInfo = requestWillBeSentExtraInfos[i]; + testRunner.log(` has headers: ${Object.keys(requestWillBeSentExtraInfo.params.headers).length > 0}`); + } + } + + const responseReceivedExtraInfos = request.responseReceivedExtraInfo; + if (responseReceivedExtraInfos) { + testRunner.log(`responseReceivedExtraInfos: ${responseReceivedExtraInfos.length}`); + for (let i = 0; i < responseReceivedExtraInfos.length; i++) { + const responseReceivedExtraInfo = responseReceivedExtraInfos[i]; + testRunner.log(` has headers: ${Object.keys(responseReceivedExtraInfo.params.headers).length > 0}`); + } + } + + testRunner.log(''); + } + + testRunner.completeTest(); +})
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 535dc051..bf92efe 100644 --- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1195,6 +1195,7 @@ method unregister interface PermissionStatus : EventTarget attribute @@toStringTag + getter name getter onchange getter state method constructor
diff --git a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 484ac31..07da2b38 100644 --- a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1067,6 +1067,7 @@ method unregister interface PermissionStatus : EventTarget attribute @@toStringTag + getter name getter onchange getter state method constructor
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt index 41d858a..9253b364 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -1065,6 +1065,7 @@ [Worker] method unregister [Worker] interface PermissionStatus : EventTarget [Worker] attribute @@toStringTag +[Worker] getter name [Worker] getter onchange [Worker] getter state [Worker] method constructor
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt index 986c961..9226a89 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -5374,6 +5374,7 @@ method constructor interface PermissionStatus : EventTarget attribute @@toStringTag + getter name getter onchange getter state method constructor
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt index c11908c9..d09cdf5 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -974,6 +974,7 @@ [Worker] method unregister [Worker] interface PermissionStatus : EventTarget [Worker] attribute @@toStringTag +[Worker] getter name [Worker] getter onchange [Worker] getter state [Worker] method constructor
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt index e0fd675..d415ba2 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -1234,6 +1234,7 @@ [Worker] method unregister [Worker] interface PermissionStatus : EventTarget [Worker] attribute @@toStringTag +[Worker] getter name [Worker] getter onchange [Worker] getter state [Worker] method constructor
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index 96920780..ce08ed4 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -672,6 +672,10 @@ method postMessage setter onmessage setter onmessageerror +interface BrowserCaptureMediaStreamTrack : FocusableMediaStreamTrack + attribute @@toStringTag + method constructor + method cropTo interface ByteLengthQueuingStrategy attribute @@toStringTag getter highWaterMark @@ -4525,6 +4529,7 @@ attribute @@toStringTag getter priority getter size + getter type method @@iterator method add method clear @@ -4536,6 +4541,7 @@ method keys method values setter priority + setter type interface HighlightRegistry attribute @@toStringTag getter size @@ -6381,6 +6387,7 @@ method constructor interface PermissionStatus : EventTarget attribute @@toStringTag + getter name getter onchange getter state method constructor
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt index 558e5af..ff68c1c 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -1096,6 +1096,7 @@ [Worker] method unregister [Worker] interface PermissionStatus : EventTarget [Worker] attribute @@toStringTag +[Worker] getter name [Worker] getter onchange [Worker] getter state [Worker] method constructor
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index a49239e8..91aa4ad4 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-11-0-118-ge294a95ca -Revision: e294a95ca85f4d1aa2cd1a6e00e572acd7f03871 +Version: VER-2-11-0-119-gede96b239 +Revision: ede96b239b90bf9c9d9a01f06005ae09fb4fa19b CPEPrefix: cpe:/a:freetype:freetype:2.10.4 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses"
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 1e4d273a..5e746fc8 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -311,6 +311,7 @@ 'TSAN Release (g-ip) (reclient)': 'tsan_disable_nacl_release_bot_reclient', 'TSAN Release (reclient)': 'tsan_disable_nacl_release_bot_reclient', 'UBSan Release (reclient)': 'ubsan_release_bot_reclient', + 'UBSan vptr Release (reclient shadow)': 'ubsan_vptr_release_bot_reclient', 'VR Linux': 'vr_release_bot', 'VR Linux (reclient)': 'vr_release_bot_reclient', 'Win 10 Fast Ring': 'release_trybot_minimal_symbols', @@ -960,6 +961,7 @@ 'linux-chromeos-js-code-coverage': 'chromeos_with_codecs_release_trybot_js_cpp_code_coverage', 'linux-chromeos-compile-dbg': 'chromeos_with_codecs_debug_bot', 'linux-chromeos-dbg': 'chromeos_with_codecs_debug_bot', + 'linux-lacros-dbg': 'lacros_on_linux_debug_bot', 'linux-lacros-rel': 'lacros_on_linux_release_trybot', 'linux-lacros-rel-rts': 'lacros_on_linux_release_trybot', 'linux-cfm-rel': 'linux_cfm_release_trybot', @@ -1040,6 +1042,7 @@ 'linux-extended-tracing-rel': 'release_trybot_extended_tracing', 'linux-inverse-fieldtrials-fyi-rel': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_invert_fieldtrials', 'linux-gcc-rel': 'release_bot_x86_minimal_symbols_no_clang_cxx11', + 'linux-headless-shell-rel': 'headless_shell_release_bot', 'linux-lacros-fyi-rel': 'lacros_on_linux_release_trybot', 'linux-lacros-version-skew-fyi': 'lacros_on_linux_release_not_build_ash_bot', 'linux-libfuzzer-asan-rel': 'libfuzzer_asan_release_trybot', @@ -3000,6 +3003,14 @@ 'ubsan_vptr', 'ubsan_no_recover_hack', 'release_bot', ], + 'ubsan_vptr_release_bot_reclient': [ + 'ubsan_vptr', 'release_bot_reclient', + ], + + 'ubsan_vptr_release_bot_reclient': [ + 'ubsan_vptr', 'ubsan_no_recover_hack', 'release_bot_reclient', + ], + 'v8_future_debug_bot': [ 'v8_future', 'debug_bot', ],
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json index 565d40d3..8da5b2350 100644 --- a/tools/mb/mb_config_expectations/chromium.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -419,6 +419,17 @@ "use_remoteexec": true } }, + "UBSan vptr Release (reclient shadow)": { + "gn_args": { + "dcheck_always_on": false, + "is_component_build": false, + "is_debug": false, + "is_ubsan_no_recover": true, + "is_ubsan_vptr": true, + "use_rbe": true, + "use_remoteexec": true + } + }, "VR Linux": { "gn_args": { "dcheck_always_on": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json index e8b3b8c..eb9d1d8bf 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
@@ -227,6 +227,17 @@ "use_goma": true } }, + "linux-lacros-dbg": { + "gn_args": { + "also_build_ash_chrome": true, + "chromeos_is_browser_only": true, + "is_component_build": true, + "is_debug": true, + "symbol_level": 1, + "target_os": "chromeos", + "use_goma": true + } + }, "linux-lacros-rel": { "gn_args": { "also_build_ash_chrome": true,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json index d4e910d..501aaaff 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
@@ -596,6 +596,19 @@ "use_goma": false } }, + "linux-headless-shell-rel": { + "args_file": "//build/args/headless.gn", + "gn_args": { + "dcheck_always_on": false, + "enable_ffmpeg_video_decoders": false, + "is_component_build": false, + "is_debug": false, + "media_use_ffmpeg": false, + "media_use_libvpx": false, + "proprietary_codecs": false, + "use_goma": true + } + }, "linux-inverse-fieldtrials-fyi-rel": { "gn_args": { "blink_enable_generated_code_formatting": false,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index afd4a01..9bf4933 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -26552,6 +26552,8 @@ <int value="911" label="PreconfiguredDeskTemplates"/> <int value="912" label="FastPairEnabled"/> <int value="913" label="SandboxExternalProtocol"/> + <int value="914" label="ReportDeviceNetworkTelemetryCollectionRateMs"/> + <int value="915" label="ReportDeviceNetworkTelemetryEventCheckingRateMs"/> </enum> <enum name="EnterprisePolicyDeviceIdValidity"> @@ -27317,7 +27319,7 @@ <int value="32768" label="CUSTODIAN_APPROVAL_REQUIRED"/> <int value="65536" label="BLOCKED_BY_POLICY"/> <int value="131072" label="DEPRECATED_BLOCKED_MATURE"/> - <int value="262144" label="DISABLE_REMOTELY_FOR_MALWARE"/> + <int value="262144" label="DEPRECATED_DISABLE_REMOTELY_FOR_MALWARE"/> <int value="524288" label="DISABLE_REINSTALL"/> <int value="1048576" label="DISABLE_NOT_ALLOWLISTED"/> </enum> @@ -56373,6 +56375,12 @@ <int value="7" label="Could not identify the source language"/> </enum> +<enum name="MerchantTrustBottomSheetOpenedSource"> + <int value="0" label="Unknown"/> + <int value="1" label="From message"/> + <int value="2" label="From page info"/> +</enum> + <enum name="MerchantTrustMessageClearReason"> <int value="0" label="Unknown"/> <int value="1" label="Navigate to same domain"/>
diff --git a/tools/metrics/histograms/histograms_index.txt b/tools/metrics/histograms/histograms_index.txt index c598890e..47cbd84 100644 --- a/tools/metrics/histograms/histograms_index.txt +++ b/tools/metrics/histograms/histograms_index.txt
@@ -56,6 +56,7 @@ tools/metrics/histograms/metadata/interstitial/histograms.xml tools/metrics/histograms/metadata/invalidation/histograms.xml tools/metrics/histograms/metadata/ios/histograms.xml +tools/metrics/histograms/metadata/leveldb_proto/histograms.xml tools/metrics/histograms/metadata/local/histograms.xml tools/metrics/histograms/metadata/login/histograms.xml tools/metrics/histograms/metadata/media/histograms.xml
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index e3628dd..6d5dec3 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -505,6 +505,10 @@ <summary> Measures time from {type} child process starts to right before main. Only recorded on Android N+. Zygote measurements are recorded on Q+. + + Zygote measurements capture the CPU time (thread time) spent to create the + app zygote process, before the zygote preload starts. For other processes it + measures the time (uptimeMillis) to create the child process service. </summary> <token key="type"> <variant name=".All" summary="all (excluding zygote)"/>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml index e59bbb14..973a1d4 100644 --- a/tools/metrics/histograms/metadata/blink/histograms.xml +++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -115,6 +115,42 @@ </summary> </histogram> +<histogram name="Blink.Binding.CreateV8ContextForMainFrame" + units="microseconds" expires_after="2022-02-01"> + <owner>sky@chromium.org</owner> + <owner>yukishiino@chromium.org</owner> + <summary> + Warning: this histogram was expired from ~4/2019 to ~10/2021. + + Time (in microseconds) spent to create a v8::Context instance during a page + loading in the main-frame window. + + Warning: This metric may include reports from clients with low-resolution + clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports + will cause this metric to have an abnormal distribution. When considering + revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the + solution. + </summary> +</histogram> + +<histogram name="Blink.Binding.CreateV8ContextForNonMainFrame" + units="microseconds" expires_after="2022-02-01"> + <owner>sky@chromium.org</owner> + <owner>yukishiino@chromium.org</owner> + <summary> + Warning: this histogram was expired from ~4/2019 to ~10/2021. + + Time spent (in microseconds) to create a v8::Context instance during a page + loading in a non-main-frame window, e.g. iframe. + + Warning: This metric may include reports from clients with low-resolution + clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports + will cause this metric to have an abnormal distribution. When considering + revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the + solution. + </summary> +</histogram> + <histogram name="Blink.Canvas.2DPrintingAsVector" enum="BooleanSuccess" expires_after="2022-01-31"> <owner>fserb@chromium.org</owner> @@ -961,9 +997,9 @@ </histogram> <histogram name="Blink.CSSPaintValue.PaintOffThread" - enum="BooleanCompositorCSSPaint" expires_after="2021-09-08"> + enum="BooleanCompositorCSSPaint" expires_after="2022-03-08"> <owner>xidachen@chromium.org</owner> - <owner>smcgruer@chromium.org</owner> + <owner>kevers@chromium.org</owner> <summary> Records if a CSS Paint is painted on the compositor thread or has fallen back to the main thread.
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml index 6450d30..34207bd 100644 --- a/tools/metrics/histograms/metadata/chromeos/histograms.xml +++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -1954,6 +1954,17 @@ </summary> </histogram> +<histogram name="ChromeOS.WebAPK.MinterResponseOrErrorCode" + enum="CombinedHttpResponseAndNetErrorCode" expires_after="2022-04-14"> + <owner>tsergeant@chromium.org</owner> + <owner>chromeos-apps-foundation-team@google.com</owner> + <summary> + HTTP response code or net error code for requests made to the WebAPK minter + service. Logged after a request to generate a WebAPK finishes, which happens + when a PWA which supports Web Share Target is installed or updated. + </summary> +</histogram> + <histogram name="ChromeOS.WebAPK.UnlinkedWebAPKCount" units="count" expires_after="2022-03-14"> <owner>tsergeant@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml index 171afcf..1508994 100644 --- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -7009,6 +7009,8 @@ </histogram_suffixes> <histogram_suffixes name="LevelDBClients" separator="."> +<!-- Obsolete. Use LevelDBClient variant in leveldb_proto/histograms.xml instead. --> + <suffix name="BudgetManager" label="Database for storing budget information for origins."/> <suffix name="CachedImageFetcherDatabase" @@ -7101,19 +7103,10 @@ label="Database for video tutorials (deprecated)."/> <suffix name="VideoTutorialsV2Database" label="Database for video tutorials."/> +<!-- The following two histograms are obsolete. --> + <affected-histogram name="LevelDB.ApproximateMemoryUse"/> - <affected-histogram name="LevelDB.ApproximateMemTableMemoryUse"/> <affected-histogram name="LevelDB.Open"/> - <affected-histogram name="ProtoDB.DestroySuccess"/> - <affected-histogram name="ProtoDB.GetErrorStatus"/> - <affected-histogram name="ProtoDB.GetFound"/> - <affected-histogram name="ProtoDB.GetSuccess"/> - <affected-histogram name="ProtoDB.InitStatus"/> - <affected-histogram name="ProtoDB.LoadEntriesSuccess"/> - <affected-histogram name="ProtoDB.LoadKeysAndEntriesSuccess"/> - <affected-histogram name="ProtoDB.LoadKeysSuccess"/> - <affected-histogram name="ProtoDB.UpdateErrorStatus"/> - <affected-histogram name="ProtoDB.UpdateSuccess"/> </histogram_suffixes> <histogram_suffixes name="LevelDBEnvBackupRestore" separator=""> @@ -10800,16 +10793,16 @@ </histogram_suffixes> <histogram_suffixes name="OptimizationGuide_OptimizationTargets" separator="."> - <suffix name="SegmentationChromeStartAndroid" label="Chrome Start Android"/> - <suffix name="SegmentationDummyFeature" label="Dummy feature"/> <suffix name="LanguageDetection" label="Language detection"/> <suffix name="ModelValidation" label="Model validation triggered via CLI"/> <suffix name="NotificationPermissions" label="Notification permissions"/> <suffix name="PageEntities" label="Page entities"/> <suffix name="PageTopics" label="Page topics"/> <suffix name="PainfulPageLoad" label="Painful page load"/> - <suffix name="SegmentationQueryTiles" label="Query tiles"/> + <suffix name="SegmentationChromeStartAndroid" label="Chrome Start Android"/> + <suffix name="SegmentationDummyFeature" label="Dummy feature"/> <suffix name="SegmentationNewTab" label="Segmentation: New tab page user"/> + <suffix name="SegmentationQueryTiles" label="Query tiles"/> <suffix name="SegmentationShare" label="Segmentation: Share user"/> <suffix name="SegmentationVoice" label="Segmentation: Voice user"/> <affected-histogram name="OptimizationGuide.IsPredictionModelValid"/> @@ -14782,6 +14775,7 @@ label="Records metrics for consumer real time URL lookup service."/> <suffix name="Enterprise" label="Records metrics for enterprise real time URL lookup service."/> + <affected-histogram name="SafeBrowsing.PageLoadToken.RealTimeCheckHasToken"/> <affected-histogram name="SafeBrowsing.RT.Backoff.State"/> <affected-histogram name="SafeBrowsing.RT.GetCache.Time"/> <affected-histogram name="SafeBrowsing.RT.GetCacheResult"/>
diff --git a/tools/metrics/histograms/metadata/leveldb_proto/OWNERS b/tools/metrics/histograms/metadata/leveldb_proto/OWNERS new file mode 100644 index 0000000..ade5e7b --- /dev/null +++ b/tools/metrics/histograms/metadata/leveldb_proto/OWNERS
@@ -0,0 +1,5 @@ +per-file OWNERS=file://tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS + +# Prefer sending CLs to the owners listed below. +# Use chromium-metrics-reviews@google.com as a backup. +nyquist@chromium.org
diff --git a/tools/metrics/histograms/metadata/leveldb_proto/histograms.xml b/tools/metrics/histograms/metadata/leveldb_proto/histograms.xml new file mode 100644 index 0000000..277eb94 --- /dev/null +++ b/tools/metrics/histograms/metadata/leveldb_proto/histograms.xml
@@ -0,0 +1,236 @@ +<!-- +Copyright 2021 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. +--> + +<!-- +This file is used to generate a comprehensive list of histograms related to +leveldb_proto along with a detailed description for each histogram. + +For best practices on writing histogram descriptions, see +https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md + +Please send CLs to chromium-metrics-reviews@google.com rather than to specific +individuals. These CLs will be automatically reassigned to a reviewer within +about 5 minutes. This approach helps the metrics team to load-balance incoming +reviews. Googlers can read more about this at go/gwsq-gerrit. +--> + +<histogram-configuration> + +<histograms> + +<variants name="LevelDBClient"> + <variant name="BudgetManager" + summary="Database for storing budget information for origins."/> + <variant name="CachedImageFetcherDatabase" + summary="Database for CachedImageFetcher metadata."/> + <variant name="CartDatabase" summary="Database for chrome cart."/> + <variant name="CommerceSubscriptionDatabase" + summary="Database for Chrome commerce subscriptions."/> + <variant name="CouponDatabase" summary="Database for coupons in Chrome."/> + <variant name="DomDistillerStore" summary="Databases for DomDistillerStore"> + <obsolete> + Deprecated since 2019-10. + </obsolete> + </variant> + <variant name="DownloadDB" summary="Databases for in-progress download."/> + <variant name="DownloadService" summary="Databases for download service."/> + <variant name="FeatureEngagementTrackerAvailabilityStore" + summary="Database for FeatureEngagementTracker feature availability."/> + <variant name="FeatureEngagementTrackerEventStore" + summary="Database for FeatureEngagementTracker events."/> + <variant name="FeedContentDatabase" + summary="Database for Feed content storage."/> + <variant name="FeedImageDatabase" summary="Databases for Feed Image Loader."> + <obsolete> + Deprecated since 11/18. + </obsolete> + </variant> + <variant name="FeedJournalDatabase" + summary="Database for Feed journal storage."/> + <variant name="FeedKeyValueDatabase" + summary="Database for key value cache used in feed rendering."/> + <variant name="FeedStorageDatabase" summary="Databases for Feed Storage."> + <obsolete> + Deprecated since 08/18. + </obsolete> + </variant> + <variant name="FeedStreamDatabase" + summary="Database for Feed v2 stream and content storage."/> + <variant name="GCMKeyStore" summary="Databases for GCMKeyStore"/> + <variant name="ImageManager" summary="Databases for ImageManager"/> + <variant name="MerchantTrustSignalDatabase" + summary="Database for Chrome merchant trust signals events."/> + <variant name="Metadata" summary="Metadata of shared databases"/> + <variant name="NearbySharePublicCertificateDatabase" + summary="Database for Nearby Share public certificates."/> + <variant name="NotificationSchedulerIcons" + summary="Notification scheduler icons database."/> + <variant name="NotificationSchedulerImpressions" + summary="Notification scheduler impression database."/> + <variant name="NotificationSchedulerNotifications" + summary="Notification scheduler notification database."/> + <variant name="NTPSnippetImages" + summary="Database for RemoteSuggestion images."/> + <variant name="NTPSnippets" + summary="Database for RemoteSuggestion snippets."/> + <variant name="OfflinePageMetadataStore" + summary="Databases for OfflinePageMetadataStore"/> + <variant name="PersistedStateDatabase" + summary="Database for NonCriticalPersistedTabData"/> + <variant name="PreviewsHintCacheStore" + summary="Databases for Previews Hints"/> + <variant name="PrintJobDatabase" summary="Database for print job metadata."/> + <variant name="SegmentInfoDatabase" + summary="Segmentation platform metadata database."/> + <variant name="SharedDb" summary="Shared database"/> + <variant name="ShareHistoryDatabase" + summary="Database for third-party share history."/> + <variant name="ShareRankingDatabase" + summary="Database for third-party share rankings."/> + <variant name="SignalDatabase" + summary="Segmentation platform signal database."/> + <variant name="SignalStorageConfigDatabase" + summary="Segmentation platform signal storage config."/> + <variant name="StrikeService" summary="Database for strike service."/> + <variant name="TabStateDatabase" + summary="Database for NonCriticalPersistedTabData"> + <obsolete> + Deprecated since 10/2020 in favor of PersistedStateDatabase + </obsolete> + </variant> + <variant name="UpboardingQueryTileStore" + summary="Database for Upboarding query tiles."/> + <variant name="UsageReportsBufferBackend" + summary="The result of the first attempt to open the usage reports + buffer backend database."/> + <variant name="UsageStatsSuspension" + summary="UsageStats database for Suspensions."/> + <variant name="UsageStatsTokenMapping" + summary="UsageStats database for TokenMappings."/> + <variant name="UsageStatsWebsiteEvent" + summary="UsageStats database for WebsiteEvents."/> + <variant name="VideoDecodeStatsDB" summary="Database for video decode stats"/> + <variant name="VideoTutorialsDatabase" + summary="Database for video tutorials (deprecated)."/> + <variant name="VideoTutorialsV2Database" + summary="Database for video tutorials."/> +</variants> + +<histogram name="LevelDB.ApproximateMemTableMemoryUse.{LevelDBClient}" + units="bytes" expires_after="2022-04-11"> + <owner>nyquist@chromium.org</owner> + <owner>salg@google.com</owner> + <owner>chrome-owp-storage@google.com</owner> + <summary> + The approximate MemTable memory use of a LevelDB in bytes. Recorded right + after initializing an on-disk database. + </summary> + <token key="LevelDBClient" variants="LevelDBClient"/> +</histogram> + +<histogram name="ProtoDB.DestroySuccess.{LevelDBClient}" enum="BooleanSuccess" + expires_after="2022-04-11"> + <owner>nyquist@chromium.org</owner> + <owner>ssid@chromium.org</owner> + <summary>Whether a ProtoDB Destroy call was successful or not.</summary> + <token key="LevelDBClient" variants="LevelDBClient"/> +</histogram> + +<histogram name="ProtoDB.GetErrorStatus.{LevelDBClient}" enum="LevelDBStatus" + expires_after="2022-04-11"> + <owner>nyquist@chromium.org</owner> + <owner>ssid@chromium.org</owner> + <summary> + The LevelDB Status returned from a failed ProtoDatabase Get call. + </summary> + <token key="LevelDBClient" variants="LevelDBClient"/> +</histogram> + +<histogram name="ProtoDB.GetFound.{LevelDBClient}" enum="Boolean" + expires_after="2022-04-11"> + <owner>nyquist@chromium.org</owner> + <owner>ssid@chromium.org</owner> + <summary>Whether a ProtoDB Get call found what was requested.</summary> + <token key="LevelDBClient" variants="LevelDBClient"/> +</histogram> + +<histogram name="ProtoDB.GetSuccess.{LevelDBClient}" enum="BooleanSuccess" + expires_after="2022-04-11"> + <owner>nyquist@chromium.org</owner> + <owner>ssid@chromium.org</owner> + <summary>Whether a ProtoDB Get call was successful or not.</summary> + <token key="LevelDBClient" variants="LevelDBClient"/> +</histogram> + +<histogram name="ProtoDB.InitStatus.{LevelDBClient}" enum="LevelDBStatus" + expires_after="2022-04-17"> + <owner>nyquist@chromium.org</owner> + <owner>ssid@chromium.org</owner> + <summary>The LevelDB Status from a ProtoDatabase Init call.</summary> + <token key="LevelDBClient" variants="LevelDBClient"/> +</histogram> + +<histogram name="ProtoDB.LoadEntriesSuccess.{LevelDBClient}" + enum="BooleanSuccess" expires_after="2022-04-11"> + <owner>nyquist@chromium.org</owner> + <owner>ssid@chromium.org</owner> + <summary>Whether a ProtoDB LoadEntries call was successful or not.</summary> + <token key="LevelDBClient" variants="LevelDBClient"/> +</histogram> + +<histogram name="ProtoDB.LoadKeysAndEntriesSuccess.{LevelDBClient}" + enum="BooleanSuccess" expires_after="2022-04-11"> + <owner>nyquist@chromium.org</owner> + <owner>ssid@chromium.org</owner> + <summary> + Whether a ProtoDB LoadKeysAndEntries call was successful or not. + </summary> + <token key="LevelDBClient" variants="LevelDBClient"/> +</histogram> + +<histogram name="ProtoDB.LoadKeysSuccess.{LevelDBClient}" enum="BooleanSuccess" + expires_after="2022-04-11"> + <owner>nyquist@chromium.org</owner> + <owner>ssid@chromium.org</owner> + <summary>Whether a ProtoDB LoadKeys call was successful or not.</summary> + <token key="LevelDBClient" variants="LevelDBClient"/> +</histogram> + +<histogram name="ProtoDB.SharedDbInitStatus" enum="ProtoDatabaseInitState" + expires_after="2022-04-17"> + <owner>ssid@chromium.org</owner> + <owner>salg@chromium.org</owner> + <summary> + Tracks the init state progress of a proto database. An enum value is + recorded for each state of progression through the initialization process. + Shows the number of users hitting each stage. The enum values starting with + success and failure indicate that the final output of initialization is a + success or failure. See + //components/leveldb_proto/internal/proto_init_state_description.md. + </summary> +</histogram> + +<histogram name="ProtoDB.UpdateErrorStatus.{LevelDBClient}" + enum="LevelDBStatus" expires_after="2022-04-11"> + <owner>nyquist@chromium.org</owner> + <owner>ssid@chromium.org</owner> + <summary> + The LevelDB Status returned from a failed Protodatabase UpdateEntries call. + </summary> + <token key="LevelDBClient" variants="LevelDBClient"/> +</histogram> + +<histogram name="ProtoDB.UpdateSuccess.{LevelDBClient}" enum="BooleanSuccess" + expires_after="2022-04-11"> + <owner>nyquist@chromium.org</owner> + <owner>ssid@chromium.org</owner> + <summary>Whether a ProtoDB UpdateEntries call was successful or not.</summary> + <token key="LevelDBClient" variants="LevelDBClient"/> +</histogram> + +</histograms> + +</histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/obsolete_histograms.xml b/tools/metrics/histograms/metadata/obsolete_histograms.xml index 35c9d498..dd22d40 100644 --- a/tools/metrics/histograms/metadata/obsolete_histograms.xml +++ b/tools/metrics/histograms/metadata/obsolete_histograms.xml
@@ -5849,42 +5849,6 @@ </summary> </histogram> -<histogram name="Blink.Binding.CreateV8ContextForMainFrame" - units="microseconds" expires_after="2019-04-16"> - <obsolete> - Removed as of 04/2019 with the removal of field trial experiment settings. - </obsolete> - <owner>peria@chromium.org</owner> - <summary> - Time spent to create a v8::Context instance during a page loading in the - main-frame window. - - Warning: This metric may include reports from clients with low-resolution - clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports - will cause this metric to have an abnormal distribution. When considering - revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the - solution. - </summary> -</histogram> - -<histogram name="Blink.Binding.CreateV8ContextForNonMainFrame" - units="microseconds" expires_after="2019-04-16"> - <obsolete> - Removed as of 04/2019 with the removal of field trial experiment settings. - </obsolete> - <owner>peria@chromium.org</owner> - <summary> - Time spent to create a v8::Context instance during a page loading in a - non-main-frame window, e.g. iframe. - - Warning: This metric may include reports from clients with low-resolution - clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports - will cause this metric to have an abnormal distribution. When considering - revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the - solution. - </summary> -</histogram> - <histogram name="Blink.Binding.InitializeMainLocalWindowProxy" units="microseconds" expires_after="M80"> <obsolete>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index 9a650f6..17de5e9 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -9453,17 +9453,6 @@ </summary> </histogram> -<histogram name="LevelDB.ApproximateMemTableMemoryUse" units="bytes" - expires_after="2021-08-24"> - <owner>nyquist@chromium.org</owner> - <owner>salg@google.com</owner> - <owner>chrome-owp-storage@google.com</owner> - <summary> - The approximate MemTable memory use of a LevelDB in bytes. Recorded right - after initializing an on-disk database. - </summary> -</histogram> - <histogram name="LevelDBEnv.DeleteTableBackupFile" enum="BooleanSuccess" expires_after="2022-08-01"> <owner>cmumford@chromium.org</owner> @@ -13575,95 +13564,6 @@ </summary> </histogram> -<histogram name="ProtoDB.DestroySuccess" enum="BooleanSuccess" - expires_after="2021-08-24"> - <owner>nyquist@chromium.org</owner> - <owner>ssid@chromium.org</owner> - <summary>Whether a ProtoDB Destroy call was successful or not.</summary> -</histogram> - -<histogram name="ProtoDB.GetErrorStatus" enum="LevelDBStatus" - expires_after="2021-08-24"> - <owner>nyquist@chromium.org</owner> - <owner>ssid@chromium.org</owner> - <summary> - The LevelDB Status returned from a failed ProtoDatabase Get call. - </summary> -</histogram> - -<histogram name="ProtoDB.GetFound" enum="Boolean" expires_after="2021-08-24"> - <owner>nyquist@chromium.org</owner> - <owner>ssid@chromium.org</owner> - <summary>Whether a ProtoDB Get call found what was requested.</summary> -</histogram> - -<histogram name="ProtoDB.GetSuccess" enum="BooleanSuccess" - expires_after="2021-08-24"> - <owner>nyquist@chromium.org</owner> - <owner>ssid@chromium.org</owner> - <summary>Whether a ProtoDB Get call was successful or not.</summary> -</histogram> - -<histogram name="ProtoDB.InitStatus" enum="LevelDBStatus" - expires_after="2022-04-17"> - <owner>nyquist@chromium.org</owner> - <owner>ssid@chromium.org</owner> - <summary>The LevelDB Status from a ProtoDatabase Init call.</summary> -</histogram> - -<histogram name="ProtoDB.LoadEntriesSuccess" enum="BooleanSuccess" - expires_after="2021-08-24"> - <owner>nyquist@chromium.org</owner> - <owner>ssid@chromium.org</owner> - <summary>Whether a ProtoDB LoadEntries call was successful or not.</summary> -</histogram> - -<histogram name="ProtoDB.LoadKeysAndEntriesSuccess" enum="BooleanSuccess" - expires_after="2021-08-24"> - <owner>nyquist@chromium.org</owner> - <owner>ssid@chromium.org</owner> - <summary> - Whether a ProtoDB LoadKeysAndEntries call was successful or not. - </summary> -</histogram> - -<histogram name="ProtoDB.LoadKeysSuccess" enum="BooleanSuccess" - expires_after="2021-08-24"> - <owner>nyquist@chromium.org</owner> - <owner>ssid@chromium.org</owner> - <summary>Whether a ProtoDB LoadKeys call was successful or not.</summary> -</histogram> - -<histogram name="ProtoDB.SharedDbInitStatus" enum="ProtoDatabaseInitState" - expires_after="2022-04-17"> - <owner>ssid@chromium.org</owner> - <owner>salg@chromium.org</owner> - <summary> - Tracks the init state progress of a proto database. An enum value is - recorded for each state of progression through the initialization process. - Shows the number of users hitting each stage. The enum values starting with - success and failure indicate that the final output of initialization is a - success or failure. See - //components/leveldb_proto/internal/proto_init_state_description.md. - </summary> -</histogram> - -<histogram name="ProtoDB.UpdateErrorStatus" enum="LevelDBStatus" - expires_after="2021-08-24"> - <owner>nyquist@chromium.org</owner> - <owner>ssid@chromium.org</owner> - <summary> - The LevelDB Status returned from a failed Protodatabase UpdateEntries call. - </summary> -</histogram> - -<histogram name="ProtoDB.UpdateSuccess" enum="BooleanSuccess" - expires_after="2021-08-24"> - <owner>nyquist@chromium.org</owner> - <owner>ssid@chromium.org</owner> - <summary>Whether a ProtoDB UpdateEntries call was successful or not.</summary> -</histogram> - <histogram name="ProxyOverriddenBubble.UserSelection" units="ExtensionBubbleAction" expires_after="2020-12-31"> <obsolete>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index 2164c64c7..d4bb5e6 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -1038,6 +1038,36 @@ </summary> </histogram> +<histogram name="SafeBrowsing.PageLoadToken.PasswordProtectionHasToken" + units="BooleanExists" expires_after="2022-10-08"> + <owner>xinghuilu@chromium.org</owner> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + Records whether a page load token is found before password protection + request is sent. Logged only when real time URL check is enabled. + </summary> +</histogram> + +<histogram name="SafeBrowsing.PageLoadToken.RealTimeCheckHasToken" + units="BooleanExists" expires_after="2022-10-08"> + <owner>xinghuilu@chromium.org</owner> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + Records whether a page load token is found before real time URL check + request is sent. Logged only when the check is on a subframe URL. + </summary> +</histogram> + +<histogram name="SafeBrowsing.PageLoadToken.TokenCount" units="entries" + expires_after="2022-10-08"> + <owner>xinghuilu@chromium.org</owner> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + Records the number of page load tokens stored in verdict cache manager. + Logged each time after a periodic clean up on expired tokens is performed. + </summary> +</histogram> + <histogram name="SafeBrowsing.PakIntegrity.{PakFile}" enum="BooleanSuccess" expires_after="2022-05-01"> <owner>rsesek@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/sharing/histograms.xml b/tools/metrics/histograms/metadata/sharing/histograms.xml index 96c56ab..26366f8 100644 --- a/tools/metrics/histograms/metadata/sharing/histograms.xml +++ b/tools/metrics/histograms/metadata/sharing/histograms.xml
@@ -584,21 +584,6 @@ </summary> </histogram> -<histogram name="Sharing.ShareTargetUpdate.Version" - units="FileTypePolicies Version" expires_after="M98"> - <owner>jeffreycohen@chromium.org</owner> - <owner>kristipark@chromium.org</owner> - <owner>src/chrome/browser/share/OWNERS</owner> - <summary> - Integer version number citing which version of the proto data chrome just - loaded. Latest version is in share_targets.asciipb. - - This is for the file types loaded from the component-update system. This - includes both those loaded from disk shortly after startup, and those - received over the network when the component version changes - </summary> -</histogram> - <histogram name="Sharing.SharingHubAndroid.Opened" enum="ShareOrigin" expires_after="2022-04-17"> <owner>sophey@chromium.org</owner> @@ -667,7 +652,7 @@ </histogram> <histogram name="Sharing.SharingHubAndroid.{DetailedContentType}.{ShareStatus}" - enum="LinkToggleState" expires_after="M98"> + enum="LinkToggleState" expires_after="M101"> <owner>sophey@chromium.org</owner> <owner>src/chrome/browser/share/OWNERS</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/stability/histograms.xml b/tools/metrics/histograms/metadata/stability/histograms.xml index 3383785..b9dd8f06 100644 --- a/tools/metrics/histograms/metadata/stability/histograms.xml +++ b/tools/metrics/histograms/metadata/stability/histograms.xml
@@ -653,7 +653,7 @@ </histogram> <histogram name="Stability.MobileSessionShutdownType" - enum="MobileSessionShutdownType" expires_after="2021-10-25"> + enum="MobileSessionShutdownType" expires_after="2022-05-01"> <owner>michaeldo@chromium.org</owner> <owner>olivierrobin@chromium.org</owner> <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 357aa4f..922cbdd3 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -10,7 +10,7 @@ }, "mac": { "hash": "c23e575ca7971342be4b254789513a3d9e75e19f", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/9709a3d80cc9e2ac3e6d808638334f7510ddc59a/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/mac/251c5dd034fdc7ce2578f2b5fd112e2fc0fa0e8e/trace_processor_shell" }, "linux_arm64": { "hash": "5074025a2898ec41a872e70a5719e417acb0a380",
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index d63d20f..6496d91a 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -13,7 +13,6 @@ output_name = "ui_android" sources = [ "animation_utils.h", - "color_helpers.h", "color_utils_android.cc", "color_utils_android.h", "delegated_frame_host_android.cc", @@ -519,7 +518,7 @@ # Clipboard unittests are run here for Android as gtests on Android are not # sharded. On other OSs these are run as part of interactive_ui_tests. "//ui/base/clipboard/clipboard_unittest.cc", - "color_helpers_unittest.cc", + "color_utils_android_unittest.cc", "overscroll_refresh_unittest.cc", "resources/resource_manager_impl_unittest.cc", "run_all_unittests.cc",
diff --git a/ui/android/color_helpers.h b/ui/android/color_helpers.h deleted file mode 100644 index c1f4fb6..0000000 --- a/ui/android/color_helpers.h +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_ANDROID_COLOR_HELPERS_H_ -#define UI_ANDROID_COLOR_HELPERS_H_ - -// TODO(pkotwicz): Replace color_helpers.h includes with color_utils_android.h -#include "ui/android/color_utils_android.h" - -#endif // UI_ANDROID_COLOR_HELPERS_H_
diff --git a/ui/android/color_helpers_unittest.cc b/ui/android/color_utils_android_unittest.cc similarity index 94% rename from ui/android/color_helpers_unittest.cc rename to ui/android/color_utils_android_unittest.cc index 5acf395..7c593d7 100644 --- a/ui/android/color_helpers_unittest.cc +++ b/ui/android/color_utils_android_unittest.cc
@@ -1,8 +1,8 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/android/color_helpers.h" +#include "ui/android/color_utils_android.h" #include <stdint.h>
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js index 974616d..2ece26a 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -2715,8 +2715,10 @@ CommandHandler.COMMANDS_['inspect-background'] = new class extends FilesCommand { execute(event, fileManager) { - chrome.fileManagerPrivate.openInspector( - chrome.fileManagerPrivate.InspectionType.BACKGROUND); + if (!window.isSWA) { + chrome.fileManagerPrivate.openInspector( + chrome.fileManagerPrivate.InspectionType.BACKGROUND); + } } };
diff --git a/ui/message_center/notification_list.cc b/ui/message_center/notification_list.cc index df78298..fccba33 100644 --- a/ui/message_center/notification_list.cc +++ b/ui/message_center/notification_list.cc
@@ -22,9 +22,8 @@ namespace { -bool ShouldShowNotificationAsPopup( - const Notification& notification, - const NotificationBlockers& blockers) { +bool ShouldShowNotificationAsPopup(const Notification& notification, + const NotificationBlockers& blockers) { for (auto* blocker : blockers) { if (!blocker->ShouldShowNotificationAsPopup(notification)) return false; @@ -62,9 +61,7 @@ } NotificationList::NotificationList(MessageCenter* message_center) - : message_center_(message_center), - quiet_mode_(false) { -} + : message_center_(message_center), quiet_mode_(false) {} NotificationList::~NotificationList() = default; @@ -145,6 +142,17 @@ return notifications; } +NotificationList::Notifications NotificationList::GetNotificationsByOriginUrl( + const GURL& source_url) const { + Notifications notifications; + for (const auto& tuple : notifications_) { + Notification* notification = tuple.first.get(); + if (notification->origin_url() == source_url) + notifications.insert(notification); + } + return notifications; +} + bool NotificationList::SetNotificationIcon(const std::string& notification_id, const gfx::Image& image) { auto iter = GetNotification(notification_id); @@ -186,9 +194,9 @@ return false; } -NotificationList::PopupNotifications -NotificationList::GetPopupNotifications(const NotificationBlockers& blockers, - std::list<std::string>* blocked) { +NotificationList::PopupNotifications NotificationList::GetPopupNotifications( + const NotificationBlockers& blockers, + std::list<std::string>* blocked) { PopupNotifications result; size_t default_priority_popup_count = 0; @@ -225,8 +233,8 @@ return result; } -void NotificationList::MarkSinglePopupAsShown( - const std::string& id, bool mark_notification_as_read) { +void NotificationList::MarkSinglePopupAsShown(const std::string& id, + bool mark_notification_as_read) { auto iter = GetNotification(id); DCHECK(iter != notifications_.end());
diff --git a/ui/message_center/notification_list.h b/ui/message_center/notification_list.h index c73cc732..df8b8d2 100644 --- a/ui/message_center/notification_list.h +++ b/ui/message_center/notification_list.h
@@ -107,6 +107,9 @@ // Returns all notifications that have a matching |app_id|. Notifications GetNotificationsByAppId(const std::string& app_id) const; + // Returns all notifications that have a matching `origin_url`. + Notifications GetNotificationsByOriginUrl(const GURL& origin_url) const; + // Returns true if the notification exists and was updated. bool SetNotificationIcon(const std::string& notification_id, const gfx::Image& image);
diff --git a/ui/message_center/notification_list_unittest.cc b/ui/message_center/notification_list_unittest.cc index b54f3a6..667c74b 100644 --- a/ui/message_center/notification_list_unittest.cc +++ b/ui/message_center/notification_list_unittest.cc
@@ -414,6 +414,71 @@ } } +// Tests that GetNotificationsByOriginUrl returns notifications regardless of +// their visibility. +TEST_F(NotificationListTest, GetNotificationsByOriginUrl) { + const GURL kUrl1(u"http://www.kurl1.com"); + const GURL kUrl2(u"http://www.kUrl2.com"); + + { + // Add a notification for `kurl1`. + const std::string id1("id1"); + std::unique_ptr<Notification> notification( + new Notification(NOTIFICATION_TYPE_PROGRESS, id1, u"updated", + u"updated", gfx::Image(), std::u16string(), kUrl1, + NotifierId(), RichNotificationData(), nullptr)); + notification_list_->AddNotification(std::move(notification)); + EXPECT_EQ(1u, + notification_list_->GetNotificationsByOriginUrl(kUrl1).size()); + + // Mark the popup as shown but not read. + notification_list_->MarkSinglePopupAsShown(id1, false); + EXPECT_EQ(1u, + notification_list_->GetNotificationsByOriginUrl(kUrl1).size()); + + // Mark the popup as shown and read. + notification_list_->MarkSinglePopupAsShown(id1, true); + EXPECT_EQ(1u, + notification_list_->GetNotificationsByOriginUrl(kUrl1).size()); + + // Remove the notification. + notification_list_->RemoveNotification(id1); + EXPECT_EQ(0u, + notification_list_->GetNotificationsByOriginUrl(kUrl1).size()); + + // Add two notifications for `kurl1` and one for `kUrl2`. + notification = std::make_unique<Notification>( + NOTIFICATION_TYPE_PROGRESS, id1, u"updated", u"updated", gfx::Image(), + std::u16string(), kUrl1, NotifierId(), RichNotificationData(), nullptr); + notification_list_->AddNotification(std::move(notification)); + + const std::string id2("id2"); + notification = std::make_unique<Notification>( + NOTIFICATION_TYPE_PROGRESS, id2, u"updated", u"updated", gfx::Image(), + std::u16string(), kUrl1, NotifierId(), RichNotificationData(), nullptr); + notification_list_->AddNotification(std::move(notification)); + EXPECT_EQ(2u, + notification_list_->GetNotificationsByOriginUrl(kUrl1).size()); + + const std::string id3("id3"); + notification = std::make_unique<Notification>( + NOTIFICATION_TYPE_PROGRESS, id3, u"updated", u"updated", gfx::Image(), + std::u16string(), kUrl2, NotifierId(), RichNotificationData(), nullptr); + notification_list_->AddNotification(std::move(notification)); + EXPECT_EQ(2u, + notification_list_->GetNotificationsByOriginUrl(kUrl1).size()); + EXPECT_EQ(1u, + notification_list_->GetNotificationsByOriginUrl(kUrl2).size()); + } + + for (GURL url : {kUrl1, kUrl2}) { + for (auto* notification : + notification_list_->GetNotificationsByOriginUrl(url)) { + EXPECT_EQ(url, notification->origin_url()); + } + } +} + TEST_F(NotificationListTest, HasPopupsWithPriority) { ASSERT_EQ(0u, notification_list_->NotificationCount(blockers_));
diff --git a/ui/ozone/platform/drm/common/drm_util.cc b/ui/ozone/platform/drm/common/drm_util.cc index ba79507..5e8b118 100644 --- a/ui/ozone/platform/drm/common/drm_util.cc +++ b/ui/ozone/platform/drm/common/drm_util.cc
@@ -50,23 +50,20 @@ return false; } -// Return a CRTC compatible with |connector| and not already used in |displays|. +// Returns a CRTC compatible with |connector| and not already used in |displays| +// and the CRTC that's currently connected to the connector. // If there are multiple compatible CRTCs, the one that supports the majority of -// planes will be returned. -uint32_t GetCrtc( +// planes will be returned as best CRTC. +std::pair<uint32_t /* best_crtc */, uint32_t /* connected_crtc */> GetCrtcs( int fd, drmModeConnector* connector, drmModeRes* resources, - const std::vector<std::unique_ptr<HardwareDisplayControllerInfo>>& - displays) { - ScopedDrmPlaneResPtr plane_resources(drmModeGetPlaneResources(fd)); - std::vector<ScopedDrmPlanePtr> planes; - for (uint32_t i = 0; i < plane_resources->count_planes; i++) - planes.emplace_back(drmModeGetPlane(fd, plane_resources->planes[i])); - + const std::vector<std::unique_ptr<HardwareDisplayControllerInfo>>& displays, + const std::vector<ScopedDrmPlanePtr>& planes) { DCHECK_GE(32, resources->count_crtcs); + int most_crtc_planes = -1; uint32_t best_crtc = 0; - int best_crtc_planes = -1; + uint32_t connected_crtc = 0; // Try to find an encoder for the connector. for (int i = 0; i < connector->count_encoders; ++i) { @@ -74,6 +71,9 @@ if (!encoder) continue; + if (connector->encoder_id == encoder->encoder_id) + connected_crtc = encoder->crtc_id; + for (int j = 0; j < resources->count_crtcs; ++j) { // Check if the encoder is compatible with this CRTC int crtc_bit = 1 << j; @@ -85,20 +85,16 @@ planes.begin(), planes.end(), [crtc_bit](const ScopedDrmPlanePtr& p) { return p->possible_crtcs & crtc_bit; }); - - uint32_t assigned_crtc = 0; - if (connector->encoder_id == encoder->encoder_id) - assigned_crtc = encoder->crtc_id; - if (supported_planes > best_crtc_planes || - (supported_planes == best_crtc_planes && - assigned_crtc == resources->crtcs[j])) { - best_crtc_planes = supported_planes; + if (supported_planes > most_crtc_planes || + (supported_planes == most_crtc_planes && + connected_crtc == resources->crtcs[j])) { + most_crtc_planes = supported_planes; best_crtc = resources->crtcs[j]; } } } - return best_crtc; + return std::make_pair(best_crtc, connected_crtc); } // Computes the refresh rate for the specific mode. If we have enough @@ -329,11 +325,12 @@ HardwareDisplayControllerInfo::~HardwareDisplayControllerInfo() = default; -std::vector<std::unique_ptr<HardwareDisplayControllerInfo>> -GetAvailableDisplayControllerInfos(int fd) { +std::pair<HardwareDisplayControllerInfoList, std::vector<uint32_t>> +GetDisplayInfosAndInvalidCrtcs(int fd) { ScopedDrmResourcesPtr resources(drmModeGetResources(fd)); DCHECK(resources) << "Failed to get DRM resources"; std::vector<std::unique_ptr<HardwareDisplayControllerInfo>> displays; + std::vector<uint32_t> invalid_crtcs; std::vector<ScopedDrmConnectorPtr> connectors; std::vector<drmModeConnector*> available_connectors; @@ -383,12 +380,24 @@ c1_crtcs != c2_crtcs; }); + ScopedDrmPlaneResPtr plane_resources(drmModeGetPlaneResources(fd)); + std::vector<ScopedDrmPlanePtr> planes; + for (uint32_t i = 0; i < plane_resources->count_planes; i++) + planes.emplace_back(drmModeGetPlane(fd, plane_resources->planes[i])); + for (auto* c : available_connectors) { - uint32_t crtc_id = GetCrtc(fd, c, resources.get(), displays); - if (!crtc_id) + uint32_t best_crtc, connected_crtc; + std::tie(best_crtc, connected_crtc) = + GetCrtcs(fd, c, resources.get(), displays, planes); + if (!best_crtc) continue; - ScopedDrmCrtcPtr crtc(drmModeGetCrtc(fd, crtc_id)); + // If the currently connected CRTC isn't the best CRTC for the connector, + // add the CRTC to the list of Invalid CRTCs. + if (connected_crtc && connected_crtc != best_crtc) + invalid_crtcs.push_back((connected_crtc)); + + ScopedDrmCrtcPtr crtc(drmModeGetCrtc(fd, best_crtc)); auto iter = std::find_if(connectors.begin(), connectors.end(), [c](const ScopedDrmConnectorPtr& connector) { return connector.get() == c; @@ -401,7 +410,12 @@ std::move(*iter), std::move(crtc), index)); } - return displays; + return std::make_pair(std::move(displays), std::move(invalid_crtcs)); +} + +std::vector<std::unique_ptr<HardwareDisplayControllerInfo>> +GetAvailableDisplayControllerInfos(int fd) { + return GetDisplayInfosAndInvalidCrtcs(fd).first; } bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs) {
diff --git a/ui/ozone/platform/drm/common/drm_util.h b/ui/ozone/platform/drm/common/drm_util.h index 51f3c35..9e91fae 100644 --- a/ui/ozone/platform/drm/common/drm_util.h +++ b/ui/ozone/platform/drm/common/drm_util.h
@@ -60,10 +60,18 @@ uint8_t index_; }; +using HardwareDisplayControllerInfoList = + std::vector<std::unique_ptr<HardwareDisplayControllerInfo>>; + // Looks-up and parses the native display configurations returning all available -// displays. -std::vector<std::unique_ptr<HardwareDisplayControllerInfo>> -GetAvailableDisplayControllerInfos(int fd); +// displays and CRTCs that weren't picked as best CRTC for each connector. +// TODO(markyacoub): Create unit tests that tests the different bits and pieces +// that this function goes through. +std::pair<HardwareDisplayControllerInfoList, std::vector<uint32_t>> +GetDisplayInfosAndInvalidCrtcs(int fd); + +// Returns the display infos parsed in |GetDisplayInfosAndInvalidCrtcs| +HardwareDisplayControllerInfoList GetAvailableDisplayControllerInfos(int fd); bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs);
diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc index 633510bb..cdd8db4 100644 --- a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc +++ b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc
@@ -15,10 +15,10 @@ #include "ui/display/types/display_snapshot.h" #include "ui/display/types/gamma_ramp_rgb_entry.h" #include "ui/gfx/linux/drm_util_linux.h" -#include "ui/ozone/platform/drm/common/drm_util.h" #include "ui/ozone/platform/drm/gpu/drm_device.h" #include "ui/ozone/platform/drm/gpu/drm_device_manager.h" #include "ui/ozone/platform/drm/gpu/drm_display.h" +#include "ui/ozone/platform/drm/gpu/drm_gpu_util.h" #include "ui/ozone/platform/drm/gpu/screen_manager.h" namespace ui { @@ -132,7 +132,7 @@ // Receiving a signal that DRM state was updated. Need to reset the plane // manager's resource cache since IDs may have changed. drm->plane_manager()->ResetConnectorsCache(drm->GetResources()); - auto display_infos = GetAvailableDisplayControllerInfos(drm->get_fd()); + auto display_infos = GetDisplayInfosAndUpdateCrtcs(drm->get_fd()); for (const auto& display_info : display_infos) { auto it = std::find_if( old_displays.begin(), old_displays.end(),
diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_util.cc b/ui/ozone/platform/drm/gpu/drm_gpu_util.cc index 4e70e45f..0ecc85f 100644 --- a/ui/ozone/platform/drm/gpu/drm_gpu_util.cc +++ b/ui/ozone/platform/drm/gpu/drm_gpu_util.cc
@@ -140,4 +140,18 @@ return false; } +HardwareDisplayControllerInfoList GetDisplayInfosAndUpdateCrtcs(int fd) { + HardwareDisplayControllerInfoList displays; + std::vector<uint32_t> invalid_crtcs; + std::tie(displays, invalid_crtcs) = GetDisplayInfosAndInvalidCrtcs(fd); + // Disable invalid CRTCs to allow the preferred CRTCs to be enabled later + // instead. + for (uint32_t crtc : invalid_crtcs) { + drmModeSetCrtc(fd, crtc, 0, 0, 0, nullptr, 0, nullptr); + LOG(ERROR) << "Disabled unpreferred CRTC " << crtc; + } + + return displays; +} + } // namespace ui
diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_util.h b/ui/ozone/platform/drm/gpu/drm_gpu_util.h index ab04da74..815ae51 100644 --- a/ui/ozone/platform/drm/gpu/drm_gpu_util.h +++ b/ui/ozone/platform/drm/gpu/drm_gpu_util.h
@@ -5,6 +5,7 @@ #ifndef UI_OZONE_PLATFORM_DRM_GPU_DRM_GPU_UTIL_H_ #define UI_OZONE_PLATFORM_DRM_GPU_DRM_GPU_UTIL_H_ +#include "ui/ozone/platform/drm/common//drm_util.h" #include "ui/ozone/platform/drm/common/scoped_drm_types.h" #include "ui/ozone/platform/drm/gpu/drm_device.h" @@ -39,6 +40,11 @@ // Check DRM driver name match. bool IsDriverName(const char* device_file_name, const char* driver); +// Returns the display infos parsed in +// |GetDisplayInfosAndInvalidCrtcs| and disables the invalid CRTCs +// that weren't picked as preferred CRTCs. +HardwareDisplayControllerInfoList GetDisplayInfosAndUpdateCrtcs(int fd); + } // namespace ui #endif // UI_OZONE_PLATFORM_DRM_GPU_DRM_GPU_UTIL_H_
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc index e3add6a..3768b20 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
@@ -357,7 +357,6 @@ return false; } - DisableConnectedConnectorsToCrtcs(resources); ResetConnectorsCache(resources); unsigned int num_crtcs_with_out_fence_ptr = 0; @@ -414,29 +413,6 @@ return true; } -void HardwareDisplayPlaneManager::DisableConnectedConnectorsToCrtcs( - const ScopedDrmResourcesPtr& resources) { - // Should only be called when no CRTC state has been set yet because we - // hard-disable CRTCs. - DCHECK(crtc_state_.empty()); - - for (int i = 0; i < resources->count_connectors; ++i) { - ScopedDrmConnectorPtr connector = - drm_->GetConnector(resources->connectors[i]); - if (!connector) - continue; - // Disable Zombie connectors (disconnected connectors but holding to an - // encoder). - if (connector->encoder_id && - connector->connection == DRM_MODE_DISCONNECTED) { - ScopedDrmEncoderPtr encoder( - drmModeGetEncoder(drm_->get_fd(), connector->encoder_id)); - if (encoder) - drm_->DisableCrtc(encoder->crtc_id); - } - } -} - const HardwareDisplayPlaneManager::CrtcState& HardwareDisplayPlaneManager::GetCrtcStateForCrtcId(uint32_t crtc_id) { return CrtcStateForCrtcId(crtc_id);
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h index b1defe85..fa052c5 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
@@ -209,16 +209,6 @@ void UpdateCrtcAndPlaneStatesAfterModeset( const CommitRequest& commit_request); - // As the CRTC is being initialized, all connectors connected to it should - // be disabled. This is a workaround for a bug on Hatch where Puff enables - // a connector in dev mode before Chrome even starts. The kernel maps the HW - // state at initial modeset (with a dangling connector attached to a CRTC). - // When an Atomic Modeset is performed, it fails to modeset as the CRTC is - // already attached to another dead connector. (Analysis: crbug/1067121#c5) - // TODO(b/168154314): Remove this call when the bug is fixed. - void DisableConnectedConnectorsToCrtcs( - const ScopedDrmResourcesPtr& resources); - virtual bool InitializePlanes() = 0; virtual bool SetPlaneData(HardwareDisplayPlaneList* plane_list,
diff --git a/ui/ozone/platform/wayland/common/wayland_util.cc b/ui/ozone/platform/wayland/common/wayland_util.cc index de0bbbf..834de30b 100644 --- a/ui/ozone/platform/wayland/common/wayland_util.cc +++ b/ui/ozone/platform/wayland/common/wayland_util.cc
@@ -272,7 +272,7 @@ return gfx::ScaleToRoundedRect( wl::TranslateBoundsToParentCoordinates(window->GetBounds(), parent_window->GetBounds()), - 1.0 / window->window_scale()); + 1.0f / window->window_scale()); } std::vector<gfx::Rect> CreateRectsFromSkPath(const SkPath& path) { @@ -288,7 +288,7 @@ return rects; } -SkPath ConvertPathToDIP(const SkPath& path_in_pixels, const int32_t scale) { +SkPath ConvertPathToDIP(const SkPath& path_in_pixels, float scale) { SkScalar sk_scale = SkFloatToScalar(1.0f / scale); gfx::Transform transform; transform.Scale(sk_scale, sk_scale);
diff --git a/ui/ozone/platform/wayland/common/wayland_util.h b/ui/ozone/platform/wayland/common/wayland_util.h index 9546e29..ecdc446e 100644 --- a/ui/ozone/platform/wayland/common/wayland_util.h +++ b/ui/ozone/platform/wayland/common/wayland_util.h
@@ -89,7 +89,7 @@ std::vector<gfx::Rect> CreateRectsFromSkPath(const SkPath& path); // Returns converted SkPath in DIPs from the one in pixels. -SkPath ConvertPathToDIP(const SkPath& path_in_pixels, const int32_t scale); +SkPath ConvertPathToDIP(const SkPath& path_in_pixels, float scale); } // namespace wl
diff --git a/ui/ozone/platform/wayland/host/wayland_output.cc b/ui/ozone/platform/wayland/host/wayland_output.cc index 7f52891..1765da540f 100644 --- a/ui/ozone/platform/wayland/host/wayland_output.cc +++ b/ui/ozone/platform/wayland/host/wayland_output.cc
@@ -92,11 +92,11 @@ const gfx::Size logical_size = xdg_output_->logical_size(); if (!logical_size.IsEmpty()) { if (logical_size.width() >= logical_size.height()) { - scale_factor_ = ceil(rect_in_physical_pixels_.width() / - static_cast<float>(logical_size.width())); + scale_factor_ = rect_in_physical_pixels_.width() / + static_cast<float>(logical_size.width()); } else { - scale_factor_ = ceil(rect_in_physical_pixels_.height() / - static_cast<float>(logical_size.height())); + scale_factor_ = rect_in_physical_pixels_.height() / + static_cast<float>(logical_size.height()); } } }
diff --git a/ui/ozone/platform/wayland/host/wayland_output.h b/ui/ozone/platform/wayland/host/wayland_output.h index fcf87cee..6b566a3 100644 --- a/ui/ozone/platform/wayland/host/wayland_output.h +++ b/ui/ozone/platform/wayland/host/wayland_output.h
@@ -32,7 +32,7 @@ public: virtual void OnOutputHandleMetrics(uint32_t output_id, const gfx::Rect& new_bounds, - int32_t scale_factor, + float scale_factor, int32_t transform) = 0; protected: @@ -52,7 +52,7 @@ uint32_t output_id() const { return output_id_; } bool has_output(wl_output* output) const { return output_.get() == output; } - int32_t scale_factor() const { return scale_factor_; } + float scale_factor() const { return scale_factor_; } int32_t transform() const { return transform_; } gfx::Rect bounds() const { return rect_in_physical_pixels_; } @@ -92,7 +92,7 @@ const uint32_t output_id_ = 0; wl::Object<wl_output> output_; std::unique_ptr<XDGOutput> xdg_output_; - int32_t scale_factor_ = kDefaultScaleFactor; + float scale_factor_ = kDefaultScaleFactor; int32_t transform_ = WL_OUTPUT_TRANSFORM_NORMAL; gfx::Rect rect_in_physical_pixels_;
diff --git a/ui/ozone/platform/wayland/host/wayland_output_manager.cc b/ui/ozone/platform/wayland/host/wayland_output_manager.cc index 848c9706..34600e65 100644 --- a/ui/ozone/platform/wayland/host/wayland_output_manager.cc +++ b/ui/ozone/platform/wayland/host/wayland_output_manager.cc
@@ -114,7 +114,7 @@ void WaylandOutputManager::OnOutputHandleMetrics(uint32_t output_id, const gfx::Rect& new_bounds, - int32_t scale_factor, + float scale_factor, int32_t transform) { if (wayland_screen_) { wayland_screen_->OnOutputAddedOrUpdated(output_id, new_bounds,
diff --git a/ui/ozone/platform/wayland/host/wayland_output_manager.h b/ui/ozone/platform/wayland/host/wayland_output_manager.h index ddecbde2..8ef08d5a 100644 --- a/ui/ozone/platform/wayland/host/wayland_output_manager.h +++ b/ui/ozone/platform/wayland/host/wayland_output_manager.h
@@ -55,7 +55,7 @@ // WaylandOutput::Delegate: void OnOutputHandleMetrics(uint32_t output_id, const gfx::Rect& new_bounds, - int32_t scale_factor, + float scale_factor, int32_t transform) override; using OutputList = base::flat_map<uint32_t, std::unique_ptr<WaylandOutput>>;
diff --git a/ui/ozone/platform/wayland/host/wayland_popup.cc b/ui/ozone/platform/wayland/host/wayland_popup.cc index 57480f7..b3faa8e 100644 --- a/ui/ozone/platform/wayland/host/wayland_popup.cc +++ b/ui/ozone/platform/wayland/host/wayland_popup.cc
@@ -10,6 +10,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/base/ui_base_types.h" #include "ui/display/display.h" +#include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/transform.h" #include "ui/ozone/platform/wayland/common/wayland_object.h" @@ -76,10 +77,11 @@ set_frame_insets_px(*parent_insets_px); // Popups should have the same offset for their geometry as their parents // have, otherwise Wayland draws them incorrectly. - shell_popup_->SetWindowGeometry({parent_insets_px->left() / window_scale(), - parent_insets_px->top() / window_scale(), - params.bounds.width(), - params.bounds.height()}); + const gfx::Point p = gfx::ScaleToRoundedPoint( + {parent_insets_px->left(), parent_insets_px->top()}, + 1.f / window_scale()); + shell_popup_->SetWindowGeometry( + {p.x(), p.y(), params.bounds.width(), params.bounds.height()}); } parent_window()->set_child_window(this);
diff --git a/ui/ozone/platform/wayland/host/wayland_screen.cc b/ui/ozone/platform/wayland/host/wayland_screen.cc index c998095..2cfe030 100644 --- a/ui/ozone/platform/wayland/host/wayland_screen.cc +++ b/ui/ozone/platform/wayland/host/wayland_screen.cc
@@ -108,7 +108,7 @@ void WaylandScreen::OnOutputAddedOrUpdated(uint32_t output_id, const gfx::Rect& bounds, - int32_t scale, + float scale, int32_t transform) { AddOrUpdateDisplay(output_id, bounds, scale, transform); } @@ -133,7 +133,7 @@ void WaylandScreen::AddOrUpdateDisplay(uint32_t output_id, const gfx::Rect& new_bounds, - int32_t scale_factor, + float scale_factor, int32_t transform) { display::Display changed_display(output_id); if (!display::Display::HasForceDeviceScaleFactor()) {
diff --git a/ui/ozone/platform/wayland/host/wayland_screen.h b/ui/ozone/platform/wayland/host/wayland_screen.h index 6cf8b1a0..916951e 100644 --- a/ui/ozone/platform/wayland/host/wayland_screen.h +++ b/ui/ozone/platform/wayland/host/wayland_screen.h
@@ -41,7 +41,7 @@ void OnOutputAddedOrUpdated(uint32_t output_id, const gfx::Rect& bounds, - int32_t output_scale, + float output_scale, int32_t output_transform); void OnOutputRemoved(uint32_t output_id); @@ -75,7 +75,7 @@ private: void AddOrUpdateDisplay(uint32_t output_id, const gfx::Rect& bounds, - int32_t scale, + float scale, int32_t transform); WaylandConnection* connection_ = nullptr;
diff --git a/ui/ozone/platform/wayland/host/wayland_subsurface.cc b/ui/ozone/platform/wayland/host/wayland_subsurface.cc index 1ff7728..585e758 100644 --- a/ui/ozone/platform/wayland/host/wayland_subsurface.cc +++ b/ui/ozone/platform/wayland/host/wayland_subsurface.cc
@@ -17,11 +17,11 @@ // Returns DIP bounds of the subsurface relative to the parent surface. gfx::Rect AdjustSubsurfaceBounds(const gfx::Rect& bounds_px, const gfx::Rect& parent_bounds_px, - int32_t buffer_scale) { + float buffer_scale) { const auto bounds_dip = - gfx::ScaleToEnclosingRect(bounds_px, 1.0 / buffer_scale); + gfx::ScaleToEnclosingRect(bounds_px, 1.0f / buffer_scale); const auto parent_bounds_dip = - gfx::ScaleToEnclosingRect(parent_bounds_px, 1.0 / buffer_scale); + gfx::ScaleToEnclosingRect(parent_bounds_px, 1.0f / buffer_scale); return wl::TranslateBoundsToParentCoordinates(bounds_dip, parent_bounds_dip); } @@ -90,7 +90,7 @@ void WaylandSubsurface::ConfigureAndShowSurface( const gfx::Rect& bounds_px, const gfx::Rect& parent_bounds_px, - int32_t buffer_scale, + float buffer_scale, const WaylandSurface* reference_below, const WaylandSurface* reference_above) { Show();
diff --git a/ui/ozone/platform/wayland/host/wayland_subsurface.h b/ui/ozone/platform/wayland/host/wayland_subsurface.h index f4a8808..e5c696d 100644 --- a/ui/ozone/platform/wayland/host/wayland_subsurface.h +++ b/ui/ozone/platform/wayland/host/wayland_subsurface.h
@@ -38,7 +38,7 @@ // reference subsurface. void ConfigureAndShowSurface(const gfx::Rect& bounds_px, const gfx::Rect& parent_bounds_px, - int32_t buffer_scale, + float buffer_scale, const WaylandSurface* reference_below, const WaylandSurface* reference_above);
diff --git a/ui/ozone/platform/wayland/host/wayland_surface.cc b/ui/ozone/platform/wayland/host/wayland_surface.cc index 587b058f..969f6a5c 100644 --- a/ui/ozone/platform/wayland/host/wayland_surface.cc +++ b/ui/ozone/platform/wayland/host/wayland_surface.cc
@@ -283,10 +283,10 @@ wl_surface_set_buffer_transform(surface_.get(), wl_transform); } -void WaylandSurface::SetSurfaceBufferScale(int32_t scale) { - DCHECK_GE(scale, 1); +void WaylandSurface::SetSurfaceBufferScale(float scale) { + DCHECK_GE(scale, 1.0f); if (!SurfaceSubmissionInPixelCoordinates()) { - wl_surface_set_buffer_scale(surface_.get(), scale); + wl_surface_set_buffer_scale(surface_.get(), static_cast<int>(scale)); buffer_scale_ = scale; } connection_->ScheduleFlush();
diff --git a/ui/ozone/platform/wayland/host/wayland_surface.h b/ui/ozone/platform/wayland/host/wayland_surface.h index 0fffb72..fa2d36434 100644 --- a/ui/ozone/platform/wayland/host/wayland_surface.h +++ b/ui/ozone/platform/wayland/host/wayland_surface.h
@@ -97,7 +97,7 @@ // process) for the next submitted buffer. This helps Wayland compositor to // determine buffer size in dip (GPU operates in pixels. So, when buffers are // created, their requested size is in pixels). - void SetSurfaceBufferScale(int32_t scale); + void SetSurfaceBufferScale(float scale); // Sets the region that is opaque on this surface in physical pixels. This is // expected to be called whenever the region that the surface span changes or
diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc index 04099ae..73d3d65 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_window.cc
@@ -119,10 +119,10 @@ if (!output) return; - int32_t new_scale = output->scale_factor(); + float new_scale = output->scale_factor(); ui_scale_ = output->GetUIScaleFactor(); - int32_t old_scale = window_scale(); + float old_scale = window_scale(); window_scale_ = new_scale; // We need to keep DIP size of the window the same whenever the scale changes. @@ -138,8 +138,8 @@ return accelerated_widget_; } -void WaylandWindow::SetWindowScale(int32_t new_scale) { - DCHECK_GE(new_scale, 0); +void WaylandWindow::SetWindowScale(float new_scale) { + DCHECK_GE(new_scale, 0.f); window_scale_ = new_scale; } @@ -278,7 +278,7 @@ } gfx::Rect WaylandWindow::GetBoundsInDIP() const { - return gfx::ScaleToRoundedRect(bounds_px_, 1.0 / window_scale()); + return gfx::ScaleToRoundedRect(bounds_px_, 1.0f / window_scale()); } void WaylandWindow::SetTitle(const std::u16string& title) {}
diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h index 0bc0fdc..cc97979 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.h +++ b/ui/ozone/platform/wayland/host/wayland_window.h
@@ -112,8 +112,8 @@ // Sets the window_scale for this window with respect to a display this window // is located at. This determines how events can be translated and how size of // the surface is treated (px to DIP conversion and vice versa.) - void SetWindowScale(int32_t new_scale); - int32_t window_scale() const { return window_scale_; } + void SetWindowScale(float new_scale); + float window_scale() const { return window_scale_; } float ui_scale() const { return ui_scale_; } // A preferred output is the one with the largest scale. This is needed to @@ -363,7 +363,7 @@ // We need it to place and size the menus properly. float ui_scale_ = 1.0f; // Current scale factor of the output where the window is located at. - int32_t window_scale_ = 1; + float window_scale_ = 1.f; // Stores current opacity of the window. Set on ::Initialize call. ui::PlatformWindowOpacity opacity_;
diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc index c9689a1..2892fb8ff 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
@@ -2992,7 +2992,7 @@ EXPECT_TRUE(mock_surface_subsurface); wayland_subsurface->ConfigureAndShowSurface( subsurface_bounds, gfx::Rect(0, 0, 640, 480) /*parent_bounds_px*/, - 1 /*buffer_scale*/, nullptr, nullptr); + 1.f /*buffer_scale*/, nullptr, nullptr); connection_->ScheduleFlush(); Sync();
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index 5a554d1..92a51e8 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -2974,25 +2974,23 @@ void MenuController::RepostEventAndCancel(SubmenuView* source, const ui::LocatedEvent* event) { - // Cancel can lead to the deletion |source| so we save the view and window to - // be used when reposting the event. gfx::Point screen_loc(event->location()); View::ConvertPointToScreen(source->GetScrollViewContainer(), &screen_loc); -#if defined(OS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH) - gfx::NativeView native_view = source->GetWidget()->GetNativeView(); - gfx::NativeWindow window = nullptr; - if (native_view) { - display::Screen* screen = display::Screen::GetScreen(); - window = screen->GetWindowAtScreenPoint(screen_loc); - } -#endif - #if defined(OS_WIN) if (event->IsMouseEvent() || event->IsTouchEvent()) { base::WeakPtr<MenuController> this_ref = AsWeakPtr(); if (state_.item) { + // This must be done before we ReleaseCapture() below, which can lead to + // deleting the `source`. + gfx::NativeView native_view = source->GetWidget()->GetNativeView(); + gfx::NativeWindow window = + native_view + ? display::Screen::GetScreen()->GetWindowAtScreenPoint(screen_loc) + : nullptr; + state_.item->GetRootMenuItem()->GetSubmenu()->ReleaseCapture(); + // We're going to close and we own the event capture. We need to repost // the event, otherwise the window the user clicked on won't get the // event.
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_base_page.html b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_base_page.html index 32a9fd4..7333517 100644 --- a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_base_page.html +++ b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_base_page.html
@@ -4,6 +4,15 @@ height: 276px; } + paper-progress { + left: 0; + position: absolute; + top: 0; + width: 100%; + --paper-progress-active-color: var(--google-blue-600); + --paper-progress-container-color: rgba(var(--google-blue-600-rgb), .24); + } + #buttonBar { align-self: flex-end; margin-top: 16px; @@ -13,7 +22,7 @@ display: flex; flex-direction: column; height: 100%; - margin: 8px; + margin: 0, 8px, 8px, 8px; } #title { @@ -32,6 +41,10 @@ } </style> <div id="container"> + <template is="dom-if" if="[[showScanProgress]]" restamp> + <paper-progress indeterminate> + </paper-progress> + </template> <h3 id="title">[[i18n('bluetoothPairNewDevice')]]</h3> <slot name="page-body" id="pageBody"></slot> <div id="buttonBar">
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_base_page.js b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_base_page.js index 4aaeddf..65dfd1e 100644 --- a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_base_page.js +++ b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_base_page.js
@@ -9,6 +9,7 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; +import 'chrome://resources/polymer/v3_0/paper-progress/paper-progress.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js'; import {I18nBehavior, I18nBehaviorInterface} from '//resources/js/i18n_behavior.m.js'; @@ -49,6 +50,12 @@ }, }, + /** @type {boolean} */ + showScanProgress: { + type: Boolean, + value: false, + }, + /** * Used to access |ButtonName| type in HTML. * @type {!ButtonName}
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_device_selection_page.html b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_device_selection_page.html index 5ee8700..22c06622c 100644 --- a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_device_selection_page.html +++ b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_device_selection_page.html
@@ -8,7 +8,7 @@ margin-top: 24px; } </style> -<bluetooth-base-page button-bar-state="[[buttonBarState_]]"> +<bluetooth-base-page show-scan-progress button-bar-state="[[buttonBarState_]]"> <div slot="page-body" id="pageBody"> <localized-link localized-string="[[i18nAdvanced('bluetoothPairingLearnMoreLabel')]]">
diff --git a/weblayer/browser/android/javatests/BUILD.gn b/weblayer/browser/android/javatests/BUILD.gn index 82f31eea..8b6ebe59 100644 --- a/weblayer/browser/android/javatests/BUILD.gn +++ b/weblayer/browser/android/javatests/BUILD.gn
@@ -181,7 +181,7 @@ forward_variables_from(invoker, "*") android_manifest = "AndroidManifest.xml" - min_sdk_version = 21 + min_sdk_version = default_min_sdk_version if (!defined(additional_apks)) { additional_apks = []
diff --git a/weblayer/browser/webapps/weblayer_webapps_client.cc b/weblayer/browser/webapps/weblayer_webapps_client.cc index 7597bf9..c0ce917 100644 --- a/weblayer/browser/webapps/weblayer_webapps_client.cc +++ b/weblayer/browser/webapps/weblayer_webapps_client.cc
@@ -18,7 +18,7 @@ #include "base/guid.h" #include "components/webapps/browser/android/add_to_homescreen_params.h" #include "components/webapps/browser/android/shortcut_info.h" -#include "ui/android/color_helpers.h" +#include "ui/android/color_utils_android.h" #include "ui/gfx/android/java_bitmap.h" #include "url/gurl.h" #endif
diff --git a/weblayer/shell/android/BUILD.gn b/weblayer/shell/android/BUILD.gn index e30ff09..fad4f5a1 100644 --- a/weblayer/shell/android/BUILD.gn +++ b/weblayer/shell/android/BUILD.gn
@@ -80,7 +80,7 @@ ] apk_name = invoker.apk_name android_manifest = _weblayer_shell_manifest - min_sdk_version = 21 + min_sdk_version = default_min_sdk_version target_sdk_version = 28 android_manifest_dep = ":$_manifest_target" @@ -268,7 +268,7 @@ apk_name = "WebLayerSupport" android_manifest = weblayer_support_manifest - min_sdk_version = 21 + min_sdk_version = default_min_sdk_version target_sdk_version = 28 android_manifest_dep = ":weblayer_support_manifest" shared_resources = true