diff --git a/DEPS b/DEPS index 23d6943..3f6ac0b 100644 --- a/DEPS +++ b/DEPS
@@ -129,11 +129,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '0e9401dafeb34b3459b528e78b6a9c47fe996089', + 'skia_revision': 'd0995493f8f3d1d4d882c6b5b5dbc327072dd41b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '1eaccad69d406ebb986c67009383c8d4ce8167bb', + 'v8_revision': 'c4cbeac0c0dcce8ac9351199474eb58917de2df7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -141,15 +141,15 @@ # 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': 'f2bf49e20849a2b95e0e962a3779e3258307e857', + 'angle_revision': '3e8a8d5b8567d08855d500c85bcf7cdcc4653f9a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '603a1b53f72ed4f99dfd47eeedffd6879545b027', + 'swiftshader_revision': 'b55772e6e7ddfebcb9cebf78ddcbe686d9cacf28', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'fbecffccd534a7431fd7a0d0577196b34576ac7f', + 'pdfium_revision': '459ad7fe015ed4858ed881fcf81dca3eaadc91f3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -192,7 +192,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '869dc82afef9e537154f8666c7b78acbba5e3366', + 'catapult_revision': '2f1832aff38dc3475514b0364f5d27117f6cc8a5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -801,7 +801,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '7192683560fe8a34d3277c3543b93482cc7f7648', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'ec6b379371e10acb0e7472473406331052b17449', 'condition': 'checkout_linux', }, @@ -1367,7 +1367,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/${{platform}}', - 'version': 'git_revision:1c5d71e846840d56aa37758548789d987a0515bc', + 'version': 'git_revision:eefd466493dd3cffb9ee22810c3e48466a3e67fb', }, ], 'dep_type': 'cipd', @@ -1380,7 +1380,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@847dfe2143dcd2240e1bd279c06592bf96aef572', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@00c5601ee11abb2cf141125c38eb31e907308aa2', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc index a2bcdeb..e4478620 100644 --- a/android_webview/browser/aw_contents.cc +++ b/android_webview/browser/aw_contents.cc
@@ -1286,9 +1286,6 @@ return static_cast<jint>(RendererPriority::LOW); case content::ChildProcessImportance::IMPORTANT: return static_cast<jint>(RendererPriority::HIGH); - case content::ChildProcessImportance::COUNT: - NOTREACHED(); - return 0; } NOTREACHED(); return 0;
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 7e4acc4..3e77d59 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -518,12 +518,14 @@ "session/teleport_warning_dialog.h", "shelf/app_list_button.cc", "shelf/app_list_button.h", - "shelf/app_list_shelf_item_delegate.cc", - "shelf/app_list_shelf_item_delegate.h", + "shelf/app_list_button_controller.cc", + "shelf/app_list_button_controller.h", "shelf/assistant_overlay.cc", "shelf/assistant_overlay.h", "shelf/back_button.cc", "shelf/back_button.h", + "shelf/home_button_delegate.cc", + "shelf/home_button_delegate.h", "shelf/ink_drop_button_listener.h", "shelf/login_shelf_view.cc", "shelf/login_shelf_view.h", @@ -1626,6 +1628,7 @@ "highlighter/highlighter_controller_unittest.cc", "highlighter/highlighter_gesture_util_unittest.cc", "home_screen/home_launcher_gesture_handler_unittest.cc", + "home_screen/home_screen_controller_unittest.cc", "ime/ime_controller_unittest.cc", "ime/ime_focus_handler_unittest.cc", "keyboard/arc/arc_input_method_surface_manager_unittest.cc", @@ -1690,7 +1693,6 @@ "screen_util_unittest.cc", "session/session_controller_unittest.cc", "shelf/app_list_button_unittest.cc", - "shelf/app_list_shelf_item_delegate_unittest.cc", "shelf/back_button_unittest.cc", "shelf/login_shelf_view_unittest.cc", "shelf/shelf_application_menu_model_unittest.cc",
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index e47e4fe1..e3abe52 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc
@@ -37,6 +37,7 @@ #include "ash/root_window_controller.h" #include "ash/rotator/window_rotation.h" #include "ash/session/session_controller.h" +#include "ash/shelf/home_button_delegate.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" @@ -515,7 +516,7 @@ if (accelerator.key_code() == ui::VKEY_LWIN) base::RecordAction(UserMetricsAction("Accel_Search_LWin")); - Shell::Get()->app_list_controller()->OnAppListButtonPressed( + HomeButtonDelegate::PerformHomeButtonAction( display::Screen::GetScreen() ->GetDisplayNearestWindow(Shell::GetRootWindowForNewWindows()) .id(),
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index ae50a24..ea2b11e 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -31,8 +31,8 @@ #include "ash/shell.h" #include "ash/voice_interaction/voice_interaction_controller.h" #include "ash/wallpaper/wallpaper_controller.h" +#include "ash/wm/mru_window_tracker.h" #include "ash/wm/overview/overview_controller.h" -#include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "base/logging.h" @@ -50,6 +50,10 @@ namespace { +bool IsHomeScreenAvailable() { + return Shell::Get()->home_screen_controller()->IsHomeScreenAvailable(); +} + bool IsTabletMode() { return Shell::Get() ->tablet_mode_controller() @@ -62,27 +66,6 @@ Shell::Get()->assistant_controller()->ui_controller()->CloseUi(exit_point); } -// Minimize all windows that aren't the app list in reverse order to preserve -// the mru ordering. -// Returns false if no window is minimized. -bool MinimizeAllWindows() { - bool handled = false; - aura::Window* app_list_container = - Shell::Get()->GetPrimaryRootWindow()->GetChildById( - kShellWindowId_AppListTabletModeContainer); - aura::Window::Windows windows = - Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(); - std::reverse(windows.begin(), windows.end()); - for (auto* window : windows) { - if (!app_list_container->Contains(window) && - !wm::GetWindowState(window)->IsMinimized()) { - wm::GetWindowState(window)->Minimize(); - handled = true; - } - } - return handled; -} - } // namespace AppListControllerImpl::AppListControllerImpl() @@ -411,7 +394,7 @@ void AppListControllerImpl::OnActiveUserPrefServiceChanged( PrefService* /* pref_service */) { - if (!IsTabletMode()) { + if (!IsHomeScreenAvailable()) { DismissAppList(); return; } @@ -498,7 +481,7 @@ int y_position_in_screen, float background_opacity) { // Avoid changing app list opacity and position when homecher is enabled. - if (IsTabletMode()) + if (IsHomeScreenAvailable()) return; presenter_.UpdateYPositionAndOpacity(y_position_in_screen, background_opacity); @@ -507,7 +490,7 @@ void AppListControllerImpl::EndDragFromShelf( app_list::AppListViewState app_list_state) { // Avoid dragging app list when homecher is enabled. - if (IsTabletMode()) + if (IsHomeScreenAvailable()) return; presenter_.EndDragFromShelf(app_list_state); } @@ -560,7 +543,7 @@ } void AppListControllerImpl::OnOverviewModeStarting() { - if (!IsTabletMode()) { + if (!IsHomeScreenAvailable()) { DismissAppList(); return; } @@ -577,7 +560,7 @@ void AppListControllerImpl::OnOverviewModeEnding( OverviewSession* overview_session) { - if (!IsTabletMode()) + if (!IsHomeScreenAvailable()) return; // Animate the launcher if overview mode is sliding out. Let @@ -592,7 +575,7 @@ void AppListControllerImpl::OnOverviewModeEndingAnimationComplete( bool canceled) { - if (!IsTabletMode() || canceled) + if (!IsHomeScreenAvailable() || canceled) return; presenter_.ScheduleOverviewModeAnimation(/*start=*/false, @@ -653,6 +636,7 @@ // expected if it's enabled and we're still in tablet mode. // https://crbug.com/900956. const bool should_be_shown = IsTabletMode(); + DCHECK_EQ(should_be_shown, IsHomeScreenAvailable()); if (should_be_shown == GetTargetVisibility()) return; @@ -693,7 +677,7 @@ // Reset model state. presenter_.ShowEmbeddedAssistantUI(false); - if (IsTabletMode()) { + if (IsHomeScreenAvailable()) { presenter_.GetView()->app_list_main_view()->ResetForShow(); presenter_.GetView()->SetState( app_list::AppListViewState::FULLSCREEN_ALL_APPS); @@ -752,33 +736,10 @@ int64_t display_id, app_list::AppListShowSource show_source, base::TimeTicks event_time_stamp) { - if (!IsTabletMode()) + if (!IsHomeScreenAvailable()) return ToggleAppList(display_id, show_source, event_time_stamp); - bool handled = - Shell::Get() - ->home_screen_controller() - ->home_launcher_gesture_handler() - ->ShowHomeLauncher( - Shell::Get()->display_manager()->GetDisplayForId(display_id)); - - if (!handled) { - if (Shell::Get()->overview_controller()->IsSelecting()) { - // End overview mode. - Shell::Get()->overview_controller()->ToggleOverview( - OverviewSession::EnterExitOverviewType::kWindowsMinimized); - handled = true; - } - if (Shell::Get()->split_view_controller()->IsSplitViewModeActive()) { - // End split view mode. - Shell::Get()->split_view_controller()->EndSplitView( - SplitViewController::EndReason::kHomeLauncherPressed); - handled = true; - } - } - - if (!handled) - handled = MinimizeAllWindows(); + bool handled = Shell::Get()->home_screen_controller()->GoHome(display_id); // Perform the "back" action for the app list. if (!handled) @@ -794,9 +755,9 @@ void AppListControllerImpl::UpdateExpandArrowVisibility() { bool should_show = false; - // Hide the expand arrow view when tablet mode is enabled and there is no - // activatable window. - if (IsTabletMode()) { + // Hide the expand arrow view when the home screen is available and there is + // no activatable window. + if (IsHomeScreenAvailable()) { should_show = !ash::Shell::Get() ->mru_window_tracker() ->BuildWindowForCycleList() @@ -834,7 +795,7 @@ return; } - if (!IsTabletMode()) + if (!IsHomeScreenAvailable()) DismissAppList(); ash::Shell::Get()->assistant_controller()->ui_controller()->ShowUi( @@ -1151,7 +1112,8 @@ } int64_t AppListControllerImpl::GetDisplayIdToShowAppListOn() { - if (IsTabletMode() && !Shell::Get()->display_manager()->IsInUnifiedMode()) { + if (IsHomeScreenAvailable() && + !Shell::Get()->display_manager()->IsInUnifiedMode()) { return display::Display::HasInternalDisplay() ? display::Display::InternalDisplayId() : display::Screen::GetScreen()->GetPrimaryDisplay().id(); @@ -1163,7 +1125,7 @@ } void AppListControllerImpl::ResetHomeLauncherIfShown() { - if (!IsTabletMode() || !presenter_.IsVisible()) + if (!IsHomeScreenAvailable() || !presenter_.IsVisible()) return; auto* const keyboard_controller = keyboard::KeyboardController::Get(); @@ -1177,7 +1139,7 @@ void AppListControllerImpl::UpdateLauncherContainer() { bool launcher_should_show_behind_apps = - IsTabletMode() && + IsHomeScreenAvailable() && model_->state() != ash::AppListState::kStateEmbeddedAssistant; aura::Window* window = presenter_.GetWindow();
diff --git a/ash/app_list/app_list_controller_impl_unittest.cc b/ash/app_list/app_list_controller_impl_unittest.cc index 4c62417..2fb3d5d 100644 --- a/ash/app_list/app_list_controller_impl_unittest.cc +++ b/ash/app_list/app_list_controller_impl_unittest.cc
@@ -9,8 +9,10 @@ #include "ash/app_list/views/app_list_view.h" #include "ash/app_list/views/contents_view.h" #include "ash/app_list/views/expand_arrow_view.h" +#include "ash/app_list/views/search_box_view.h" #include "ash/home_screen/home_launcher_gesture_handler.h" #include "ash/home_screen/home_screen_controller.h" +#include "ash/keyboard/ash_keyboard_controller.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" @@ -34,17 +36,32 @@ ->IsTabletModeWindowManagerEnabled(); } +app_list::AppListView* GetAppListView() { + return Shell::Get()->app_list_controller()->presenter()->GetView(); +} + bool GetExpandArrowViewVisibility() { - return Shell::Get() - ->app_list_controller() - ->presenter() - ->GetView() + return GetAppListView() ->app_list_main_view() ->contents_view() ->expand_arrow_view() ->visible(); } +app_list::SearchBoxView* GetSearchBoxView() { + return GetAppListView() + ->app_list_main_view() + ->contents_view() + ->GetSearchBoxView(); +} + +aura::Window* GetVirtualKeyboardWindow() { + return Shell::Get() + ->ash_keyboard_controller() + ->keyboard_controller() + ->GetKeyboardWindow(); +} + } // namespace class AppListControllerImplTest : public AshTestBase { @@ -94,6 +111,52 @@ EXPECT_FALSE(GetExpandArrowViewVisibility()); } +// In clamshell mode, when the AppListView's bottom is on the display edge +// and app list state is HALF, the rounded corners should be hidden +// (https://crbug.com/942084). +TEST_F(AppListControllerImplTest, HideRoundingCorners) { + Shell::Get()->ash_keyboard_controller()->SetEnableFlag( + keyboard::mojom::KeyboardEnableFlag::kShelfEnabled); + + // Show the app list view and click on the search box with mouse. So the + // VirtualKeyboard is shown. + Shell::Get()->app_list_controller()->presenter()->Show( + display::Screen::GetScreen()->GetPrimaryDisplay().id(), + base::TimeTicks::Now()); + GetSearchBoxView()->SetSearchBoxActive(true, ui::ET_MOUSE_PRESSED); + + // Wait until the virtual keyboard shows on the screen. + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(GetVirtualKeyboardWindow()->IsVisible()); + + // Test the following things: + // (1) AppListView is at the top of the screen. + // (2) AppListView's state is HALF. + // (3) AppListBackgroundShield is translated to hide the rounded corners. + aura::Window* native_window = + GetAppListView()->get_fullscreen_widget_for_test()->GetNativeView(); + gfx::Rect app_list_screen_bounds = native_window->GetBoundsInScreen(); + EXPECT_EQ(0, app_list_screen_bounds.y()); + EXPECT_EQ(app_list::AppListViewState::HALF, + GetAppListView()->app_list_state()); + gfx::Transform expected_transform; + expected_transform.Translate(0, -app_list::kAppListBackgroundRadius); + EXPECT_EQ( + expected_transform, + GetAppListView()->GetAppListBackgroundShieldForTest()->GetTransform()); + + // Set the search box inactive and wait until the virtual keyboard is hidden. + GetSearchBoxView()->SetSearchBoxActive(false, ui::ET_MOUSE_PRESSED); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(nullptr, GetVirtualKeyboardWindow()); + + // Test that the rounded corners should show again. + expected_transform = gfx::Transform(); + EXPECT_EQ( + expected_transform, + GetAppListView()->GetAppListBackgroundShieldForTest()->GetTransform()); +} + class AppListControllerImplMetricsTest : public AshTestBase { public: AppListControllerImplMetricsTest() = default;
diff --git a/ash/app_list/app_list_unittest.cc b/ash/app_list/app_list_unittest.cc index d4b26a7..ed49122 100644 --- a/ash/app_list/app_list_unittest.cc +++ b/ash/app_list/app_list_unittest.cc
@@ -42,7 +42,7 @@ EXPECT_FALSE(controller->GetTargetVisibility()); EXPECT_FALSE(presenter->GetTargetVisibility()); EXPECT_EQ(0u, app_list_container->children().size()); - EXPECT_FALSE(app_list_button->is_showing_app_list()); + EXPECT_FALSE(app_list_button->IsShowingAppList()); generator.set_current_screen_location( app_list_button->GetBoundsInScreen().CenterPoint()); generator.ClickLeftButton(); @@ -52,7 +52,7 @@ // Flush the mojo message from Chrome to Ash reporting the visibility change. EXPECT_TRUE(controller->GetTargetVisibility()); EXPECT_EQ(1u, app_list_container->children().size()); - EXPECT_TRUE(app_list_button->is_showing_app_list()); + EXPECT_TRUE(app_list_button->IsShowingAppList()); // Click the button again to dismiss the app list; it will animate to close. generator.ClickLeftButton(); @@ -62,7 +62,7 @@ // Flush the mojo message from Chrome to Ash reporting the visibility change. EXPECT_FALSE(controller->GetTargetVisibility()); EXPECT_EQ(1u, app_list_container->children().size()); - EXPECT_FALSE(app_list_button->is_showing_app_list()); + EXPECT_FALSE(app_list_button->IsShowingAppList()); } } // namespace ash
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc index e2df65f..555aae5 100644 --- a/ash/app_list/views/app_list_item_view.cc +++ b/ash/app_list/views/app_list_item_view.cc
@@ -475,8 +475,8 @@ base::BindOnce(&AppListItemView::OnMenuClosed, weak_ptr_factory_.GetWeakPtr())); context_menu_->Build(std::move(menu)); - context_menu_->Run(anchor_rect, views::MENU_ANCHOR_BUBBLE_TOUCHABLE_RIGHT, - run_types); + context_menu_->Run( + anchor_rect, views::MenuAnchorPosition::kBubbleTouchableRight, run_types); apps_grid_view_->SetSelectedView(this); }
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index 787ef01..c2e1d35 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -690,6 +690,7 @@ ->set_arrow_key_traversal_enabled_for_widget(true); widget_observer_ = std::make_unique<FullscreenWidgetObserver>(this); + fullscreen_widget_->GetNativeView()->AddObserver(this); } void AppListView::HandleClickOrTap(ui::LocatedEvent* event) { @@ -1588,6 +1589,32 @@ return state_animation_metrics_reporter_.get(); } +void AppListView::OnWindowDestroying(aura::Window* window) { + DCHECK_EQ(fullscreen_widget_->GetNativeView(), window); + window->RemoveObserver(this); +} + +void AppListView::OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds, + ui::PropertyChangeReason reason) { + DCHECK_EQ(fullscreen_widget_->GetNativeView(), window); + + // When the virtual keyboard shows, the AppListView is moved upward to avoid + // the overlapping area with the virtual keyboard. As a result, its bottom + // side may be on the display edge. Stop showing the rounded corners under + // this circumstance. + const bool hide_rounded_corners = + app_list_state_ == AppListViewState::HALF && new_bounds.y() == 0; + + gfx::Transform transform; + if (hide_rounded_corners) + transform.Translate(0, -kAppListBackgroundRadius); + + app_list_background_shield_->SetTransform(transform); + app_list_background_shield_->SchedulePaint(); +} + void AppListView::UpdateChildViewsYPositionAndOpacity() { if (app_list_state_ == AppListViewState::CLOSED) return; @@ -1656,6 +1683,7 @@ const int work_area_offset = GetDisplayNearestView().work_area().y(); OffsetYPositionOfAppList(shown ? work_area_offset : -work_area_offset); } + app_list_main_view_->contents_view()->NotifySearchBoxBoundsUpdated(); } bool AppListView::CloseKeyboardIfVisible() {
diff --git a/ash/app_list/views/app_list_view.h b/ash/app_list/views/app_list_view.h index 8af06e0..7871e125 100644 --- a/ash/app_list/views/app_list_view.h +++ b/ash/app_list/views/app_list_view.h
@@ -15,6 +15,7 @@ #include "base/callback.h" #include "base/macros.h" #include "build/build_config.h" +#include "ui/aura/window_observer.h" #include "ui/gfx/color_palette.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" @@ -53,7 +54,8 @@ // and hosts a AppsGridView and passes AppListModel to it for display. // TODO(newcomer|weidongg): Organize the cc file to match the order of // definitions in this header. -class APP_LIST_EXPORT AppListView : public views::WidgetDelegateView { +class APP_LIST_EXPORT AppListView : public views::WidgetDelegateView, + public aura::WindowObserver { public: class TestApi { public: @@ -238,6 +240,13 @@ // Returns a animation metrics reportre for state transition. ui::AnimationMetricsReporter* GetStateTransitionMetricsReporter(); + // WindowObserver overrides: + void OnWindowDestroying(aura::Window* window) override; + void OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds, + ui::PropertyChangeReason reason) override; + views::Widget* get_fullscreen_widget_for_test() const { return fullscreen_widget_; }
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 055042dd..bc00870 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -1594,10 +1594,6 @@ } void AppsGridView::HandleKeyboardAppMovement(ui::KeyboardCode key_code) { - // TODO(newcomer): Support app movement via key in folders. - if (folder_delegate_) - return; - DCHECK(selected_view_); const GridIndex target_index = GetTargetGridIndexForKeyboardMove(key_code); @@ -2630,8 +2626,11 @@ ((key_code == backward) ? -1 : 1); // A forward move on the last item in |view_model_| should result in page - // creation + // creation. if (target_model_index == view_model_.view_size()) { + // If the move is within a folder, do not allow page creation. + if (folder_delegate_) + return source_index; // If |source_index| is the last item in the grid on a page by itself, // moving right to a new page should be a no-op. if (view_structure_.items_on_page(source_index.page) == 1) @@ -2642,7 +2641,8 @@ target_index = GetIndexOfView( static_cast<const AppListItemView*>(GetItemViewAt(std::min( std::max(0, target_model_index), view_model_.view_size() - 1)))); - if (key_code == backward && target_index.page < source_index.page && + if (!folder_delegate_ && key_code == backward && + target_index.page < source_index.page && !view_structure_.IsFullPage(target_index.page)) { // Apps swap positions if the target page is the same as the // destination page, or the target page is full. If the page is not @@ -2669,22 +2669,32 @@ } else if (target_row > (GetItemsNumOfPage(target_page) - 1) / cols_) { // The app will move to the first row of the next page. ++target_page; - if (target_page >= view_structure_.total_pages()) { - // If |source_index| page only has one item, moving down to a new page - // should be a no-op. - if (view_structure_.items_on_page(source_index.page) == 1) + if (folder_delegate_) { + if (target_page >= pagination_model_.total_pages()) return source_index; - return GridIndex(target_page, 0); + } else { + if (target_page >= view_structure_.total_pages()) { + // If |source_index| page only has one item, moving down to a new page + // should be a no-op. + if (view_structure_.items_on_page(source_index.page) == 1) + return source_index; + return GridIndex(target_page, 0); + } } target_row = 0; } + // The ideal slot shares a column with |source_index|. + const int ideal_slot = target_row * cols_ + source_index.slot % cols_; + if (folder_delegate_) { + return GridIndex(target_page, + std::min(GetItemsNumOfPage(target_page) - 1, ideal_slot)); + } + // If the app is being moved to a new page there is 1 extra slot available. const int last_slot_in_target_page = view_structure_.items_on_page(target_page) - (source_index.page != target_page ? 0 : 1); - // The ideal slot shares a column with |source_index|. - const int ideal_slot = target_row * cols_ + source_index.slot % cols_; return GridIndex(target_page, std::min(last_slot_in_target_page, ideal_slot)); } @@ -2699,9 +2709,10 @@ const GridIndex original_selected_view_index = GetIndexOfView(original_selected_view); // Moving an AppListItemView is either a swap within the origin page, a swap - // to a full page, or a dump to a page with room. + // to a full page, or a dump to a page with room. A move within a folder is + // always a swap because there are no gaps. const bool swap_items = - view_structure_.IsFullPage(target_index.page) || + folder_delegate_ || view_structure_.IsFullPage(target_index.page) || target_index.page == original_selected_view_index.page; AppListItemView* target_view = GetViewAtIndex(target_index); @@ -2709,22 +2720,28 @@ // the initial move. Clearing the overflow when |target_index| is on a full // page results in the last item being pushed to the next page. MoveItemInModel(selected_view_, target_index, !swap_items /*clear_overflow*/); - view_structure_.SaveToMetadata(); + if (!folder_delegate_) + view_structure_.SaveToMetadata(); if (swap_items) { DCHECK(target_view); MoveItemInModel(target_view, original_selected_view_index); - view_structure_.SaveToMetadata(); + if (!folder_delegate_) + view_structure_.SaveToMetadata(); } - // Update |pagination_model_| because the move could have resulted in a - // page getting collapsed or created. - if (view_structure_.total_pages() != pagination_model_.total_pages()) - pagination_model_.SetTotalPages(view_structure_.total_pages()); - - pagination_model_.SelectPage( - std::min(view_structure_.total_pages() - 1, target_index.page), - false /*animate*/); + int target_page = target_index.page; + if (!folder_delegate_) { + // Update |pagination_model_| because the move could have resulted in a + // page getting collapsed or created. + if (view_structure_.total_pages() != pagination_model_.total_pages()) { + pagination_model_.SetTotalPages(view_structure_.total_pages()); + } + // |target_page| may change due to a page collapsing. + target_page = + std::min(pagination_model_.total_pages() - 1, target_index.page); + } + pagination_model_.SelectPage(target_page, false /*animate*/); SetSelectedView(original_selected_view); Layout();
diff --git a/ash/app_list/views/contents_view.cc b/ash/app_list/views/contents_view.cc index 43996ec..24274559 100644 --- a/ash/app_list/views/contents_view.cc +++ b/ash/app_list/views/contents_view.cc
@@ -365,9 +365,7 @@ gfx::Transform transform; transform.Scale(scale, scale); search_box->GetWidget()->GetNativeView()->SetTransform(transform); - - for (auto& observer : search_box_observers_) - observer.OnSearchBoxBoundsUpdated(); + NotifySearchBoxBoundsUpdated(); } void ContentsView::UpdateExpandArrowOpacity(double progress, @@ -641,6 +639,11 @@ expand_arrow_view_->SetVisible(show); } +void ContentsView::NotifySearchBoxBoundsUpdated() { + for (auto& observer : search_box_observers_) + observer.OnSearchBoxBoundsUpdated(); +} + void ContentsView::AddSearchBoxUpdateObserver( SearchBoxUpdateObserver* observer) { search_box_observers_.AddObserver(observer);
diff --git a/ash/app_list/views/contents_view.h b/ash/app_list/views/contents_view.h index 84b0071..29fcb8d8 100644 --- a/ash/app_list/views/contents_view.h +++ b/ash/app_list/views/contents_view.h
@@ -194,6 +194,8 @@ // and tablet mode is enabled. void SetExpandArrowViewVisibility(bool show); + void NotifySearchBoxBoundsUpdated(); + void AddSearchBoxUpdateObserver(SearchBoxUpdateObserver* observer); void RemoveSearchBoxUpdateObserver(SearchBoxUpdateObserver* observer);
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index ff58c634..393a3dd 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -151,12 +151,14 @@ if (!keyboard::KeyboardController::HasInstance()) return; auto* const keyboard_controller = keyboard::KeyboardController::Get(); + bool should_show_keyboard = + is_search_box_active() && search_box()->HasFocus(); if (!keyboard_controller->IsEnabled() || - is_search_box_active() == keyboard_controller->IsKeyboardVisible()) { + should_show_keyboard == keyboard_controller->IsKeyboardVisible()) { return; } - if (is_search_box_active()) { + if (should_show_keyboard) { keyboard_controller->ShowKeyboard(false); return; }
diff --git a/ash/app_list/views/search_result_tile_item_view.cc b/ash/app_list/views/search_result_tile_item_view.cc index 41a7779..aff95a0 100644 --- a/ash/app_list/views/search_result_tile_item_view.cc +++ b/ash/app_list/views/search_result_tile_item_view.cc
@@ -369,11 +369,11 @@ base::BindOnce(&SearchResultTileItemView::OnMenuClosed, weak_ptr_factory_.GetWeakPtr())); context_menu_->Build(std::move(menu)); - context_menu_->Run(anchor_rect, views::MENU_ANCHOR_BUBBLE_TOUCHABLE_RIGHT, - views::MenuRunner::HAS_MNEMONICS | - views::MenuRunner::USE_TOUCHABLE_LAYOUT | - views::MenuRunner::CONTEXT_MENU | - views::MenuRunner::FIXED_ANCHOR); + context_menu_->Run( + anchor_rect, views::MenuAnchorPosition::kBubbleTouchableRight, + views::MenuRunner::HAS_MNEMONICS | + views::MenuRunner::USE_TOUCHABLE_LAYOUT | + views::MenuRunner::CONTEXT_MENU | views::MenuRunner::FIXED_ANCHOR); source->RequestFocus(); }
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc index 0f46a138..b2dddca9 100644 --- a/ash/app_list/views/search_result_view.cc +++ b/ash/app_list/views/search_result_view.cc
@@ -526,7 +526,8 @@ std::string(), this, source_type, this, AppListMenuModelAdapter::SEARCH_RESULT, base::OnceClosure()); context_menu_->Build(std::move(menu)); - context_menu_->Run(gfx::Rect(point, gfx::Size()), views::MENU_ANCHOR_TOPLEFT, + context_menu_->Run(gfx::Rect(point, gfx::Size()), + views::MenuAnchorPosition::kTopLeft, views::MenuRunner::HAS_MNEMONICS); source->RequestFocus(); }
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index b34a9a8..f43eca23 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -906,7 +906,7 @@ <!-- Status tray screen share strings. --> <message name="IDS_ASH_STATUS_TRAY_SCREEN_SHARE_TITLE" desc="The title for screen sharing notification"> - You are sharing your screen + You're sharing your screen </message> <message name="IDS_ASH_STATUS_TRAY_SCREEN_SHARE_STOP" desc="label used for screen sharing stop button"> Stop
diff --git a/ash/frame/non_client_frame_view_ash.cc b/ash/frame/non_client_frame_view_ash.cc index a436c98..82615ec 100644 --- a/ash/frame/non_client_frame_view_ash.cc +++ b/ash/frame/non_client_frame_view_ash.cc
@@ -503,7 +503,7 @@ views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU); menu_runner_->RunMenuAt(GetWidget(), nullptr, gfx::Rect(point, gfx::Size(0, 0)), - views::MENU_ANCHOR_TOPLEFT, source_type); + views::MenuAnchorPosition::kTopLeft, source_type); } bool NonClientFrameViewAsh::IsCommandIdChecked(int command_id) const {
diff --git a/ash/home_screen/home_screen_controller.cc b/ash/home_screen/home_screen_controller.cc index 2292fad..1b89b1c 100644 --- a/ash/home_screen/home_screen_controller.cc +++ b/ash/home_screen/home_screen_controller.cc
@@ -6,16 +6,42 @@ #include "ash/home_screen/home_launcher_gesture_handler.h" #include "ash/home_screen/home_screen_delegate.h" +#include "ash/public/cpp/shell_window_ids.h" #include "ash/session/session_controller.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" #include "ash/wallpaper/wallpaper_controller.h" +#include "ash/wm/mru_window_tracker.h" #include "ash/wm/overview/overview_controller.h" +#include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" +#include "ash/wm/window_state.h" #include "base/logging.h" #include "ui/aura/window.h" +#include "ui/display/manager/display_manager.h" namespace ash { +namespace { + +// Minimizes all windows that aren't in the home screen container. Done in +// reverse order to preserve the mru ordering. +// Returns true if any windows are minimized. +bool MinimizeAllWindows() { + bool handled = false; + aura::Window* container = Shell::Get()->GetPrimaryRootWindow()->GetChildById( + kShellWindowId_AppListTabletModeContainer); + aura::Window::Windows windows = + Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(); + for (auto it = windows.rbegin(); it != windows.rend(); it++) { + if (!container->Contains(*it) && !wm::GetWindowState(*it)->IsMinimized()) { + wm::GetWindowState(*it)->Minimize(); + handled = true; + } + } + return handled; +} + +} // namespace HomeScreenController::HomeScreenController() : home_launcher_gesture_handler_( @@ -45,6 +71,34 @@ Shelf::ForWindow(window)->MaybeUpdateShelfBackground(); } +bool HomeScreenController::GoHome(int64_t display_id) { + DCHECK(IsHomeScreenAvailable()); + + if (home_launcher_gesture_handler_->ShowHomeLauncher( + Shell::Get()->display_manager()->GetDisplayForId(display_id))) { + return true; + } + + if (Shell::Get()->overview_controller()->IsSelecting()) { + // End overview mode. + Shell::Get()->overview_controller()->ToggleOverview( + OverviewSession::EnterExitOverviewType::kWindowsMinimized); + return true; + } + + if (Shell::Get()->split_view_controller()->IsSplitViewModeActive()) { + // End split view mode. + Shell::Get()->split_view_controller()->EndSplitView( + SplitViewController::EndReason::kHomeLauncherPressed); + return true; + } + + if (MinimizeAllWindows()) + return true; + + return false; +} + void HomeScreenController::SetDelegate(HomeScreenDelegate* delegate) { delegate_ = delegate; }
diff --git a/ash/home_screen/home_screen_controller.h b/ash/home_screen/home_screen_controller.h index 2969e0d..6def248 100644 --- a/ash/home_screen/home_screen_controller.h +++ b/ash/home_screen/home_screen_controller.h
@@ -33,6 +33,11 @@ // Shows the home screen. void Show(); + // Takes the user to the home screen, either by ending Overview Mode/Split + // View Mode or by minimizing the other windows. Returns false if there was + // nothing to do because the given display was already "home". + bool GoHome(int64_t display_id); + // Sets the delegate for home screen animations. void SetDelegate(HomeScreenDelegate* delegate);
diff --git a/ash/shelf/app_list_shelf_item_delegate_unittest.cc b/ash/home_screen/home_screen_controller_unittest.cc similarity index 60% rename from ash/shelf/app_list_shelf_item_delegate_unittest.cc rename to ash/home_screen/home_screen_controller_unittest.cc index 96d55ee..4d0227e 100644 --- a/ash/shelf/app_list_shelf_item_delegate_unittest.cc +++ b/ash/home_screen/home_screen_controller_unittest.cc
@@ -2,28 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/shelf/app_list_shelf_item_delegate.h" +#include "ash/home_screen/home_screen_controller.h" #include <memory> -#include <utility> #include "ash/shell.h" #include "ash/test/ash_test_base.h" -#include "ash/wm/mru_window_tracker.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" -#include "base/bind.h" #include "base/macros.h" namespace ash { namespace { -class AppListShelfItemDelegateTest : public AshTestBase { +class HomeScreenControllerTest : public AshTestBase { public: - AppListShelfItemDelegateTest() - : delegate_(std::make_unique<AppListShelfItemDelegate>()) {} - ~AppListShelfItemDelegateTest() override = default; + HomeScreenControllerTest() = default; + ~HomeScreenControllerTest() override = default; std::unique_ptr<aura::Window> CreateTestWindow() { return AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400)); @@ -34,26 +30,22 @@ aura::client::WINDOW_TYPE_POPUP); } - AppListShelfItemDelegate* delegate() { return delegate_.get(); } + HomeScreenController* home_screen_controller() { + return Shell::Get()->home_screen_controller(); + } private: - std::unique_ptr<AppListShelfItemDelegate> delegate_; - - DISALLOW_COPY_AND_ASSIGN(AppListShelfItemDelegateTest); + DISALLOW_COPY_AND_ASSIGN(HomeScreenControllerTest); }; -TEST_F(AppListShelfItemDelegateTest, OnlyMinimizeCycleListWindows) { +TEST_F(HomeScreenControllerTest, OnlyMinimizeCycleListWindows) { std::unique_ptr<aura::Window> w1(CreateTestWindow()); std::unique_ptr<aura::Window> w2(CreatePopupTestWindow()); Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true); std::unique_ptr<ui::Event> test_event = std::make_unique<ui::KeyEvent>( ui::EventType::ET_MOUSE_PRESSED, ui::VKEY_UNKNOWN, ui::EF_NONE); - delegate()->ItemSelected( - std::move(test_event), GetPrimaryDisplay().id(), - ShelfLaunchSource::LAUNCH_FROM_SHELF, - base::BindOnce( - [](ash::ShelfAction, base::Optional<ash::MenuItemList>) {})); + home_screen_controller()->GoHome(GetPrimaryDisplay().id()); ASSERT_TRUE(wm::GetWindowState(w1.get())->IsMinimized()); ASSERT_FALSE(wm::GetWindowState(w2.get())->IsMinimized()); }
diff --git a/ash/public/cpp/shelf_model.cc b/ash/public/cpp/shelf_model.cc index e16ac99..9fee37d 100644 --- a/ash/public/cpp/shelf_model.cc +++ b/ash/public/cpp/shelf_model.cc
@@ -42,6 +42,7 @@ } // namespace +// TODO(michaelpg): Rename App List item to Home Button. const char kAppListId[] = "jlfapfmkapbjlfbpjedlinehodkccjee"; const char kBackButtonId[] = "icmmkgojeloilfifneofeejijgdhjknf";
diff --git a/ash/public/cpp/shelf_types.h b/ash/public/cpp/shelf_types.h index d21997bd..438d880 100644 --- a/ash/public/cpp/shelf_types.h +++ b/ash/public/cpp/shelf_types.h
@@ -116,6 +116,7 @@ TYPE_PINNED_APP, // Toggles visiblity of the app list. + // TODO(michaelpg): Rename App List item to Home Button. TYPE_APP_LIST, // The browser shortcut button, the browser may be running or not.
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index 9262ba8..2fd50b41 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc
@@ -654,7 +654,7 @@ base::TimeTicks::Now())); menu_runner_->RunMenuAt(wallpaper_widget_controller()->GetWidget(), nullptr, gfx::Rect(location_in_screen, gfx::Size()), - views::MENU_ANCHOR_BUBBLE_TOUCHABLE_RIGHT, + views::MenuAnchorPosition::kBubbleTouchableRight, source_type); }
diff --git a/ash/shelf/app_list_button.cc b/ash/shelf/app_list_button.cc index 28af351..2997874 100644 --- a/ash/shelf/app_list_button.cc +++ b/ash/shelf/app_list_button.cc
@@ -4,190 +4,59 @@ #include "ash/shelf/app_list_button.h" -#include <algorithm> -#include <memory> -#include <utility> +#include <math.h> // std::ceil -#include "ash/app_list/app_list_controller_impl.h" -#include "ash/assistant/assistant_controller.h" -#include "ash/assistant/assistant_ui_controller.h" -#include "ash/assistant/model/assistant_ui_model.h" -#include "ash/home_screen/home_screen_controller.h" #include "ash/public/cpp/shelf_types.h" -#include "ash/session/session_controller.h" -#include "ash/shelf/assistant_overlay.h" -#include "ash/shelf/ink_drop_button_listener.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_constants.h" -#include "ash/shelf/shelf_view.h" -#include "ash/shell.h" -#include "ash/shell_state.h" -#include "ash/system/tray/tray_popup_utils.h" -#include "ash/voice_interaction/voice_interaction_controller.h" -#include "ash/wm/tablet_mode/tablet_mode_controller.h" -#include "base/bind.h" -#include "base/command_line.h" -#include "base/metrics/histogram_macros.h" -#include "base/metrics/user_metrics.h" -#include "base/metrics/user_metrics_action.h" -#include "base/timer/timer.h" -#include "chromeos/constants/chromeos_switches.h" +#include "base/logging.h" #include "chromeos/strings/grit/chromeos_strings.h" -#include "components/account_id/account_id.h" -#include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/display/screen.h" #include "ui/gfx/canvas.h" #include "ui/gfx/scoped_canvas.h" #include "ui/views/animation/flood_fill_ink_drop_ripple.h" #include "ui/views/animation/ink_drop_impl.h" -#include "ui/views/animation/ink_drop_mask.h" -#include "ui/views/painter.h" -#include "ui/views/widget/widget.h" namespace ash { namespace { -constexpr int kVoiceInteractionAnimationDelayMs = 200; -constexpr int kVoiceInteractionAnimationHideDelayMs = 500; constexpr uint8_t kVoiceInteractionRunningAlpha = 255; // 100% alpha constexpr uint8_t kVoiceInteractionNotRunningAlpha = 138; // 54% alpha -bool IsHomeScreenAvailable() { - return Shell::Get()->home_screen_controller()->IsHomeScreenAvailable(); -} - } // namespace // static const char AppListButton::kViewClassName[] = "ash/AppListButton"; AppListButton::AppListButton(ShelfView* shelf_view, Shelf* shelf) - : ShelfControlButton(shelf_view), shelf_(shelf) { - DCHECK(shelf_); - Shell::Get()->app_list_controller()->AddObserver(this); - Shell::Get()->session_controller()->AddObserver(this); - Shell::Get()->tablet_mode_controller()->AddObserver(this); - - Shell::Get()->voice_interaction_controller()->AddLocalObserver(this); + : ShelfControlButton(shelf_view), controller_(this, shelf) { + DCHECK(shelf_view); + DCHECK(shelf); SetAccessibleName( l10n_util::GetStringUTF16(IDS_ASH_SHELF_APP_LIST_LAUNCHER_TITLE)); set_notify_action(Button::NOTIFY_ON_PRESS); set_has_ink_drop_action_on_click(false); - - // Initialize voice interaction overlay and sync the flags if active user - // session has already started. This could happen when an external monitor - // is plugged in. - if (Shell::Get()->session_controller()->IsActiveUserSessionStarted() && - chromeos::switches::IsAssistantEnabled()) { - InitializeVoiceInteractionOverlay(); - } } -AppListButton::~AppListButton() { - // AppListController and TabletModeController are destroyed early when Shell - // is being destroyed, they may not exist. - if (Shell::Get()->app_list_controller()) - Shell::Get()->app_list_controller()->RemoveObserver(this); - if (Shell::Get()->tablet_mode_controller()) - Shell::Get()->tablet_mode_controller()->RemoveObserver(this); - Shell::Get()->session_controller()->RemoveObserver(this); - Shell::Get()->voice_interaction_controller()->RemoveLocalObserver(this); -} - -void AppListButton::OnAppListShown() { - // Do not show a highlight if the home screen is available, since the home - // screen view is always open in the background. - if (!IsHomeScreenAvailable()) - AnimateInkDrop(views::InkDropState::ACTIVATED, nullptr); - is_showing_app_list_ = true; - shelf_->UpdateAutoHideState(); -} - -void AppListButton::OnAppListDismissed() { - AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr); - is_showing_app_list_ = false; - shelf_->UpdateAutoHideState(); -} +AppListButton::~AppListButton() = default; void AppListButton::OnGestureEvent(ui::GestureEvent* event) { - // Handle gesture events that are on the app list circle. - switch (event->type()) { - case ui::ET_GESTURE_TAP: - case ui::ET_GESTURE_TAP_CANCEL: - if (UseVoiceInteractionStyle()) { - assistant_overlay_->EndAnimation(); - assistant_animation_delay_timer_->Stop(); - } - if (!Shell::Get()->app_list_controller()->IsVisible() || - IsHomeScreenAvailable()) { - AnimateInkDrop(views::InkDropState::ACTION_TRIGGERED, event); - } - - Button::OnGestureEvent(event); - return; - case ui::ET_GESTURE_TAP_DOWN: - // If |!ShouldEnterPushedState|, Button::OnGestureEvent will not set - // the event to be handled. This will cause the |ET_GESTURE_TAP| or - // |ET_GESTURE_TAP_CANCEL| not to be sent to |app_list_button|, therefore - // leaving the assistant overlay ripple stays visible. - if (!ShouldEnterPushedState(*event)) - return; - - if (UseVoiceInteractionStyle()) { - assistant_animation_delay_timer_->Start( - FROM_HERE, - base::TimeDelta::FromMilliseconds( - kVoiceInteractionAnimationDelayMs), - base::Bind(&AppListButton::StartVoiceInteractionAnimation, - base::Unretained(this))); - } - if (!Shell::Get()->app_list_controller()->IsVisible() || - IsHomeScreenAvailable()) { - AnimateInkDrop(views::InkDropState::ACTION_PENDING, event); - } - - Button::OnGestureEvent(event); - // If assistant overlay animation starts, we need to make sure the event - // is handled in order to end the animation in |ET_GESTURE_TAP| or - // |ET_GESTURE_TAP_CANCEL|. - DCHECK(event->handled()); - return; - case ui::ET_GESTURE_LONG_PRESS: - if (UseVoiceInteractionStyle()) { - base::RecordAction(base::UserMetricsAction( - "VoiceInteraction.Started.AppListButtonLongPress")); - assistant_overlay_->BurstAnimation(); - event->SetHandled(); - Shell::Get()->shell_state()->SetRootWindowForNewWindows( - GetWidget()->GetNativeWindow()->GetRootWindow()); - Shell::Get()->assistant_controller()->ui_controller()->ShowUi( - AssistantEntryPoint::kLongPressLauncher); - } else { - Button::OnGestureEvent(event); - } - return; - case ui::ET_GESTURE_LONG_TAP: - if (UseVoiceInteractionStyle()) { - // Also consume the long tap event. This happens after the user long - // presses and lifts the finger. We already handled the long press - // ignore the long tap to avoid bringing up the context menu again. - AnimateInkDrop(views::InkDropState::HIDDEN, event); - event->SetHandled(); - } else { - Button::OnGestureEvent(event); - } - return; - default: - Button::OnGestureEvent(event); - return; - } + if (!controller_.MaybeHandleGestureEvent(event, shelf_view())) + Button::OnGestureEvent(event); } const char* AppListButton::GetClassName() const { return kViewClassName; } +void AppListButton::OnVoiceInteractionAvailabilityChanged() { + SchedulePaint(); +} + +bool AppListButton::IsShowingAppList() const { + return controller_.is_showing_app_list(); +} + void AppListButton::PaintButtonContents(gfx::Canvas* canvas) { gfx::PointF circle_center(GetCenterPoint()); @@ -196,7 +65,7 @@ // factors. float ring_outer_radius_dp = 7.f; float ring_thickness_dp = 1.5f; - if (UseVoiceInteractionStyle()) { + if (controller_.IsVoiceInteractionAvailable()) { ring_outer_radius_dp = 8.f; ring_thickness_dp = 1.f; } @@ -209,14 +78,9 @@ fg_flags.setStyle(cc::PaintFlags::kStroke_Style); fg_flags.setColor(kShelfIconColor); - if (UseVoiceInteractionStyle()) { - mojom::VoiceInteractionState state = - Shell::Get() - ->voice_interaction_controller() - ->voice_interaction_state() - .value_or(mojom::VoiceInteractionState::STOPPED); + if (controller_.IsVoiceInteractionAvailable()) { // active: 100% alpha, inactive: 54% alpha - fg_flags.setAlpha(state == mojom::VoiceInteractionState::RUNNING + fg_flags.setAlpha(controller_.IsVoiceInteractionRunning() ? kVoiceInteractionRunningAlpha : kVoiceInteractionNotRunningAlpha); } @@ -227,7 +91,7 @@ // Make sure the center of the circle lands on pixel centers. canvas->DrawCircle(circle_center, radius, fg_flags); - if (UseVoiceInteractionStyle()) { + if (controller_.IsVoiceInteractionAvailable()) { fg_flags.setAlpha(255); const float kCircleRadiusDp = 5.f; fg_flags.setStyle(cc::PaintFlags::kFill_Style); @@ -237,108 +101,4 @@ } } -void AppListButton::OnAppListVisibilityChanged(bool shown, int64_t display_id) { - if (display::Screen::GetScreen() - ->GetDisplayNearestWindow(GetWidget()->GetNativeWindow()) - .id() != display_id) { - return; - } - if (shown) - OnAppListShown(); - else - OnAppListDismissed(); -} - -void AppListButton::OnVoiceInteractionStatusChanged( - mojom::VoiceInteractionState state) { - SchedulePaint(); - - if (!assistant_overlay_) - return; - - switch (state) { - case mojom::VoiceInteractionState::STOPPED: - UMA_HISTOGRAM_TIMES( - "VoiceInteraction.OpenDuration", - base::TimeTicks::Now() - voice_interaction_start_timestamp_); - break; - case mojom::VoiceInteractionState::NOT_READY: - // If we are showing the bursting or waiting animation, no need to do - // anything. Otherwise show the waiting animation now. - // NOTE: No waiting animation for native assistant. - if (!chromeos::switches::IsAssistantEnabled() && - !assistant_overlay_->IsBursting() && - !assistant_overlay_->IsWaiting()) { - assistant_overlay_->WaitingAnimation(); - } - break; - case mojom::VoiceInteractionState::RUNNING: - // we start hiding the animation if it is running. - if (assistant_overlay_->IsBursting() || assistant_overlay_->IsWaiting()) { - assistant_animation_hide_delay_timer_->Start( - FROM_HERE, - base::TimeDelta::FromMilliseconds( - kVoiceInteractionAnimationHideDelayMs), - base::Bind(&AssistantOverlay::HideAnimation, - base::Unretained(assistant_overlay_))); - } - - voice_interaction_start_timestamp_ = base::TimeTicks::Now(); - break; - } -} - -void AppListButton::OnVoiceInteractionSettingsEnabled(bool enabled) { - SchedulePaint(); -} - -void AppListButton::OnVoiceInteractionConsentStatusUpdated( - mojom::ConsentStatus consent_status) { - SchedulePaint(); -} - -void AppListButton::OnActiveUserSessionChanged(const AccountId& account_id) { - SchedulePaint(); - // Initialize voice interaction overlay when primary user session becomes - // active. - if (Shell::Get()->session_controller()->IsUserPrimary() && - !assistant_overlay_ && chromeos::switches::IsAssistantEnabled()) { - InitializeVoiceInteractionOverlay(); - } -} - -void AppListButton::OnTabletModeStarted() { - AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr); -} - -void AppListButton::StartVoiceInteractionAnimation() { - assistant_overlay_->StartAnimation(false); -} - -bool AppListButton::UseVoiceInteractionStyle() { - VoiceInteractionController* controller = - Shell::Get()->voice_interaction_controller(); - bool settings_enabled = controller->settings_enabled().value_or(false); - - const bool consent_given = controller->consent_status() == - mojom::ConsentStatus::kActivityControlAccepted; - - bool is_feature_allowed = - controller->allowed_state() == mojom::AssistantAllowedState::ALLOWED; - if (assistant_overlay_ && is_feature_allowed && - (settings_enabled || !consent_given)) { - return true; - } - return false; -} - -void AppListButton::InitializeVoiceInteractionOverlay() { - assistant_overlay_ = new AssistantOverlay(this); - AddChildView(assistant_overlay_); - assistant_overlay_->SetVisible(false); - assistant_animation_delay_timer_ = std::make_unique<base::OneShotTimer>(); - assistant_animation_hide_delay_timer_ = - std::make_unique<base::OneShotTimer>(); -} - } // namespace ash
diff --git a/ash/shelf/app_list_button.h b/ash/shelf/app_list_button.h index c698120..86c6bfc 100644 --- a/ash/shelf/app_list_button.h +++ b/ash/shelf/app_list_button.h
@@ -7,87 +7,48 @@ #include <memory> -#include "ash/app_list/app_list_controller_observer.h" #include "ash/ash_export.h" -#include "ash/public/cpp/assistant/default_voice_interaction_observer.h" -#include "ash/public/interfaces/voice_interaction_controller.mojom.h" -#include "ash/session/session_observer.h" +#include "ash/shelf/app_list_button_controller.h" #include "ash/shelf/shelf_control_button.h" -#include "ash/wm/tablet_mode/tablet_mode_observer.h" #include "base/macros.h" -#include "third_party/skia/include/core/SkColor.h" - -namespace base { -class OneShotTimer; -} // namespace base namespace ash { -class AssistantOverlay; class Shelf; class ShelfView; -// Button used for the AppList icon on the shelf. -class ASH_EXPORT AppListButton : public ShelfControlButton, - public AppListControllerObserver, - public SessionObserver, - public TabletModeObserver, - public DefaultVoiceInteractionObserver { +// Button used for the AppList icon on the shelf. It opens the app list (in +// clamshell mode) or home screen (in tablet mode). Because the clamshell-mode +// app list appears like a dismissable overlay, the button is highlighted while +// the app list is open in clamshell mode. +// +// If Assistant is enabled, the button is filled in; long-pressing it will +// launch Assistant. +class ASH_EXPORT AppListButton : public ShelfControlButton { public: static const char kViewClassName[]; AppListButton(ShelfView* shelf_view, Shelf* shelf); ~AppListButton() override; - void OnAppListShown(); - void OnAppListDismissed(); - - bool is_showing_app_list() const { return is_showing_app_list_; } - // views::Button: void OnGestureEvent(ui::GestureEvent* event) override; const char* GetClassName() const override; + // Called when the availability of a long-press gesture may have changed, e.g. + // when Assistant becomes enabled. + void OnVoiceInteractionAvailabilityChanged(); + + // True if the app list is shown for the display containing this button. + bool IsShowingAppList() const; + protected: // views::Button: void PaintButtonContents(gfx::Canvas* canvas) override; private: - // AppListControllerObserver: - void OnAppListVisibilityChanged(bool shown, int64_t display_id) override; - - // mojom::VoiceInteractionObserver: - void OnVoiceInteractionStatusChanged( - mojom::VoiceInteractionState state) override; - void OnVoiceInteractionSettingsEnabled(bool enabled) override; - void OnVoiceInteractionConsentStatusUpdated( - mojom::ConsentStatus consent_status) override; - - // SessionObserver: - void OnActiveUserSessionChanged(const AccountId& account_id) override; - - // TabletModeObserver: - void OnTabletModeStarted() override; - - void StartVoiceInteractionAnimation(); - - // Whether the voice interaction style should be used. - bool UseVoiceInteractionStyle(); - - // Initialize the voice interaction overlay. - void InitializeVoiceInteractionOverlay(); - - // True if the app list is currently showing for this display. - // This is useful because other app_list_visible functions aren't per-display. - bool is_showing_app_list_ = false; - - Shelf* shelf_; - - // Owned by the view hierarchy. Null if the voice interaction is not enabled. - AssistantOverlay* assistant_overlay_ = nullptr; - std::unique_ptr<base::OneShotTimer> assistant_animation_delay_timer_; - std::unique_ptr<base::OneShotTimer> assistant_animation_hide_delay_timer_; - base::TimeTicks voice_interaction_start_timestamp_; + // The controller used to determine the button's behavior. + AppListButtonController controller_; DISALLOW_COPY_AND_ASSIGN(AppListButton); };
diff --git a/ash/shelf/app_list_button_controller.cc b/ash/shelf/app_list_button_controller.cc new file mode 100644 index 0000000..bc1b6327 --- /dev/null +++ b/ash/shelf/app_list_button_controller.cc
@@ -0,0 +1,271 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/shelf/app_list_button_controller.h" + +#include "ash/app_list/app_list_controller_impl.h" +#include "ash/assistant/assistant_controller.h" +#include "ash/home_screen/home_screen_controller.h" +#include "ash/session/session_controller.h" +#include "ash/shelf/app_list_button.h" +#include "ash/shelf/assistant_overlay.h" +#include "ash/shelf/shelf.h" +#include "ash/shelf/shelf_view.h" +#include "ash/shell.h" +#include "ash/shell_state.h" +#include "ash/voice_interaction/voice_interaction_controller.h" +#include "ash/wm/tablet_mode/tablet_mode_controller.h" +#include "base/bind.h" +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "base/metrics/user_metrics.h" +#include "base/metrics/user_metrics_action.h" +#include "base/timer/timer.h" +#include "chromeos/constants/chromeos_switches.h" +#include "components/account_id/account_id.h" +#include "ui/display/screen.h" +#include "ui/views/animation/ink_drop_state.h" +#include "ui/views/widget/widget.h" + +namespace ash { +namespace { + +constexpr int kVoiceInteractionAnimationDelayMs = 200; +constexpr int kVoiceInteractionAnimationHideDelayMs = 500; + +// Returns true if the button should appear activatable. +bool CanActivate() { + return !Shell::Get()->app_list_controller()->IsVisible() || + Shell::Get()->home_screen_controller()->IsHomeScreenAvailable(); +} + +} // namespace + +AppListButtonController::AppListButtonController(AppListButton* button, + Shelf* shelf) + : button_(button), shelf_(shelf) { + DCHECK(button_); + DCHECK(shelf_); + Shell* shell = Shell::Get(); + shell->app_list_controller()->AddObserver(this); + shell->session_controller()->AddObserver(this); + shell->tablet_mode_controller()->AddObserver(this); + shell->voice_interaction_controller()->AddLocalObserver(this); + + // Initialize voice interaction overlay and sync the flags if active user + // session has already started. This could happen when an external monitor + // is plugged in. + if (shell->session_controller()->IsActiveUserSessionStarted() && + chromeos::switches::IsAssistantEnabled()) { + InitializeVoiceInteractionOverlay(); + } +} + +AppListButtonController::~AppListButtonController() { + Shell* shell = Shell::Get(); + + // AppListController and TabletModeController are destroyed early when Shell + // is being destroyed, so they may not exist. + if (shell->app_list_controller()) + shell->app_list_controller()->RemoveObserver(this); + if (shell->tablet_mode_controller()) + shell->tablet_mode_controller()->RemoveObserver(this); + shell->session_controller()->RemoveObserver(this); + shell->voice_interaction_controller()->RemoveLocalObserver(this); +} + +bool AppListButtonController::MaybeHandleGestureEvent(ui::GestureEvent* event, + ShelfView* shelf_view) { + switch (event->type()) { + case ui::ET_GESTURE_TAP: + case ui::ET_GESTURE_TAP_CANCEL: + if (IsVoiceInteractionAvailable()) { + assistant_overlay_->EndAnimation(); + assistant_animation_delay_timer_->Stop(); + } + + if (CanActivate()) + button_->AnimateInkDrop(views::InkDropState::ACTION_TRIGGERED, event); + + // After animating the ripple, let the button handle the event. + return false; + case ui::ET_GESTURE_TAP_DOWN: + // If |!ShouldEnterPushedState|, Button::OnGestureEvent will not set the + // |ET_GESTURE_TAP_DOWN| event to be handled. This will cause the + // |ET_GESTURE_TAP| or |ET_GESTURE_TAP_CANCEL| not to be sent to + // |button_|, therefore leaving the assistant overlay ripple visible. + if (!shelf_view->ShouldEventActivateButton(button_, *event)) + return true; + + if (IsVoiceInteractionAvailable()) { + assistant_animation_delay_timer_->Start( + FROM_HERE, + base::TimeDelta::FromMilliseconds( + kVoiceInteractionAnimationDelayMs), + base::BindOnce( + &AppListButtonController::StartVoiceInteractionAnimation, + base::Unretained(this))); + } + + if (CanActivate()) + button_->AnimateInkDrop(views::InkDropState::ACTION_PENDING, event); + + return false; + case ui::ET_GESTURE_LONG_PRESS: + // Only consume the long press event if voice interaction is available. + if (!IsVoiceInteractionAvailable()) + return false; + + base::RecordAction(base::UserMetricsAction( + "VoiceInteraction.Started.AppListButtonLongPress")); + assistant_overlay_->BurstAnimation(); + event->SetHandled(); + Shell::Get()->shell_state()->SetRootWindowForNewWindows( + button_->GetWidget()->GetNativeWindow()->GetRootWindow()); + Shell::Get()->assistant_controller()->ui_controller()->ShowUi( + AssistantEntryPoint::kLongPressLauncher); + return true; + case ui::ET_GESTURE_LONG_TAP: + // Only consume the long tap event if voice interaction is available. + if (!IsVoiceInteractionAvailable()) + return false; + + // This event happens after the user long presses and lifts the finger. + button_->AnimateInkDrop(views::InkDropState::HIDDEN, event); + + // We already handled the long press; consume the long tap to avoid + // bringing up the context menu again. + event->SetHandled(); + return true; + default: + return false; + } +} + +bool AppListButtonController::IsVoiceInteractionAvailable() { + VoiceInteractionController* controller = + Shell::Get()->voice_interaction_controller(); + bool settings_enabled = controller->settings_enabled().value_or(false); + bool consent_given = controller->consent_status() == + mojom::ConsentStatus::kActivityControlAccepted; + bool feature_allowed = + controller->allowed_state() == mojom::AssistantAllowedState::ALLOWED; + + return assistant_overlay_ && feature_allowed && + (settings_enabled || !consent_given); +} + +bool AppListButtonController::IsVoiceInteractionRunning() { + return Shell::Get() + ->voice_interaction_controller() + ->voice_interaction_state() + .value_or(mojom::VoiceInteractionState::STOPPED) == + mojom::VoiceInteractionState::RUNNING; +} + +void AppListButtonController::OnAppListVisibilityChanged(bool shown, + int64_t display_id) { + if (display::Screen::GetScreen() + ->GetDisplayNearestWindow(button_->GetWidget()->GetNativeWindow()) + .id() != display_id) { + return; + } + if (shown) + OnAppListShown(); + else + OnAppListDismissed(); +} + +void AppListButtonController::OnActiveUserSessionChanged( + const AccountId& account_id) { + button_->OnVoiceInteractionAvailabilityChanged(); + // Initialize voice interaction overlay when primary user session becomes + // active. + if (Shell::Get()->session_controller()->IsUserPrimary() && + !assistant_overlay_ && chromeos::switches::IsAssistantEnabled()) { + InitializeVoiceInteractionOverlay(); + } +} + +void AppListButtonController::OnTabletModeStarted() { + button_->AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr); +} + +void AppListButtonController::OnVoiceInteractionStatusChanged( + mojom::VoiceInteractionState state) { + button_->OnVoiceInteractionAvailabilityChanged(); + + if (!assistant_overlay_) + return; + + switch (state) { + case mojom::VoiceInteractionState::STOPPED: + UMA_HISTOGRAM_TIMES( + "VoiceInteraction.OpenDuration", + base::TimeTicks::Now() - voice_interaction_start_timestamp_); + break; + case mojom::VoiceInteractionState::NOT_READY: + // If we are showing the bursting or waiting animation, no need to do + // anything. Otherwise show the waiting animation now. + // NOTE: No waiting animation for native assistant. + if (!chromeos::switches::IsAssistantEnabled() && + !assistant_overlay_->IsBursting() && + !assistant_overlay_->IsWaiting()) { + assistant_overlay_->WaitingAnimation(); + } + break; + case mojom::VoiceInteractionState::RUNNING: + // we start hiding the animation if it is running. + if (assistant_overlay_->IsBursting() || assistant_overlay_->IsWaiting()) { + assistant_animation_hide_delay_timer_->Start( + FROM_HERE, + base::TimeDelta::FromMilliseconds( + kVoiceInteractionAnimationHideDelayMs), + base::BindOnce(&AssistantOverlay::HideAnimation, + base::Unretained(assistant_overlay_))); + } + + voice_interaction_start_timestamp_ = base::TimeTicks::Now(); + break; + } +} + +void AppListButtonController::OnVoiceInteractionSettingsEnabled(bool enabled) { + button_->OnVoiceInteractionAvailabilityChanged(); +} + +void AppListButtonController::OnVoiceInteractionConsentStatusUpdated( + mojom::ConsentStatus consent_status) { + button_->OnVoiceInteractionAvailabilityChanged(); +} + +void AppListButtonController::StartVoiceInteractionAnimation() { + assistant_overlay_->StartAnimation(false); +} + +void AppListButtonController::OnAppListShown() { + // Do not show a highlight if the home screen is available, since the home + // screen view is always open in the background. + if (!Shell::Get()->home_screen_controller()->IsHomeScreenAvailable()) + button_->AnimateInkDrop(views::InkDropState::ACTIVATED, nullptr); + is_showing_app_list_ = true; + shelf_->UpdateAutoHideState(); +} + +void AppListButtonController::OnAppListDismissed() { + button_->AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr); + is_showing_app_list_ = false; + shelf_->UpdateAutoHideState(); +} + +void AppListButtonController::InitializeVoiceInteractionOverlay() { + assistant_overlay_ = new AssistantOverlay(button_); + button_->AddChildView(assistant_overlay_); + assistant_overlay_->SetVisible(false); + assistant_animation_delay_timer_ = std::make_unique<base::OneShotTimer>(); + assistant_animation_hide_delay_timer_ = + std::make_unique<base::OneShotTimer>(); +} + +} // namespace ash
diff --git a/ash/shelf/app_list_button_controller.h b/ash/shelf/app_list_button_controller.h new file mode 100644 index 0000000..7203fada --- /dev/null +++ b/ash/shelf/app_list_button_controller.h
@@ -0,0 +1,106 @@ +// 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 ASH_SHELF_APP_LIST_BUTTON_CONTROLLER_H_ +#define ASH_SHELF_APP_LIST_BUTTON_CONTROLLER_H_ + +#include <memory> + +#include "ash/app_list/app_list_controller_observer.h" +#include "ash/public/cpp/assistant/default_voice_interaction_observer.h" +#include "ash/public/interfaces/voice_interaction_controller.mojom.h" +#include "ash/session/session_observer.h" +#include "ash/wm/tablet_mode/tablet_mode_observer.h" +#include "base/macros.h" + +namespace base { +class OneShotTimer; +} // namespace base + +namespace ui { +class GestureEvent; +} // namespace ui + +namespace ash { + +class AssistantOverlay; +class AppListButton; +class Shelf; +class ShelfView; + +// Controls behavior of the AppListButton, including a possible long-press +// action (for Assistant). +// Behavior is tested indirectly in AppListButtonTest and ShelfViewInkDropTest. +class AppListButtonController : public AppListControllerObserver, + public SessionObserver, + public TabletModeObserver, + public DefaultVoiceInteractionObserver { + public: + AppListButtonController(AppListButton* button, Shelf* shelf); + ~AppListButtonController() override; + + // Maybe handles a gesture event based on the event and whether voice + // interaction is available. + // |shelf_view| is used to determine whether it is safe to animate the ripple. + // + // Returns true if the event is consumed; otherwise, AppListButton should pass + // the event along to Button to consume. + bool MaybeHandleGestureEvent(ui::GestureEvent* event, ShelfView* shelf_view); + + // Whether voice interaction is available via long-press. + bool IsVoiceInteractionAvailable(); + + // Whether voice interaction is currently running. + bool IsVoiceInteractionRunning(); + + bool is_showing_app_list() const { return is_showing_app_list_; } + + private: + // AppListControllerObserver: + void OnAppListVisibilityChanged(bool shown, int64_t display_id) override; + + // SessionObserver: + void OnActiveUserSessionChanged(const AccountId& account_id) override; + + // TabletModeObserver: + void OnTabletModeStarted() override; + + // mojom::VoiceInteractionObserver: + void OnVoiceInteractionStatusChanged( + mojom::VoiceInteractionState state) override; + void OnVoiceInteractionSettingsEnabled(bool enabled) override; + void OnVoiceInteractionConsentStatusUpdated( + mojom::ConsentStatus consent_status) override; + + void OnAppListShown(); + void OnAppListDismissed(); + + void StartVoiceInteractionAnimation(); + + // Initialize the voice interaction overlay. + void InitializeVoiceInteractionOverlay(); + + // True if the app list is currently showing for the button's display. + // This is useful because other app_list_visible functions aren't per-display. + bool is_showing_app_list_ = false; + + // The button that owns this controller. + AppListButton* const button_; + + // The shelf the button resides in. + Shelf* const shelf_; + + // Owned by the button's view hierarchy. Null if voice interaction is not + // enabled. + AssistantOverlay* assistant_overlay_ = nullptr; + std::unique_ptr<base::OneShotTimer> assistant_animation_delay_timer_; + std::unique_ptr<base::OneShotTimer> assistant_animation_hide_delay_timer_; + base::TimeTicks voice_interaction_start_timestamp_; + + DISALLOW_COPY_AND_ASSIGN(AppListButtonController); +}; + +} // namespace ash + +#endif // ASH_SHELF_APP_LIST_BUTTON_CONTROLLER_H_
diff --git a/ash/shelf/app_list_shelf_item_delegate.cc b/ash/shelf/app_list_shelf_item_delegate.cc deleted file mode 100644 index a84e4640..0000000 --- a/ash/shelf/app_list_shelf_item_delegate.cc +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/shelf/app_list_shelf_item_delegate.h" - -#include <algorithm> -#include <utility> - -#include "ash/app_list/app_list_controller_impl.h" -#include "ash/public/cpp/shelf_model.h" -#include "ash/shell.h" - -namespace ash { - -AppListShelfItemDelegate::AppListShelfItemDelegate() - : ShelfItemDelegate(ShelfID(kAppListId)) {} - -AppListShelfItemDelegate::~AppListShelfItemDelegate() = default; - -void AppListShelfItemDelegate::ItemSelected(std::unique_ptr<ui::Event> event, - int64_t display_id, - ShelfLaunchSource source, - ItemSelectedCallback callback) { - std::move(callback).Run( - Shell::Get()->app_list_controller()->OnAppListButtonPressed( - display_id, - event->IsShiftDown() ? app_list::kShelfButtonFullscreen - : app_list::kShelfButton, - event->time_stamp()), - base::nullopt); -} - -void AppListShelfItemDelegate::ExecuteCommand(bool from_context_menu, - int64_t command_id, - int32_t event_flags, - int64_t display_id) { - // This delegate does not show custom context or application menu items. - NOTIMPLEMENTED(); -} - -void AppListShelfItemDelegate::Close() {} - -} // namespace ash
diff --git a/ash/shelf/app_list_shelf_item_delegate.h b/ash/shelf/app_list_shelf_item_delegate.h deleted file mode 100644 index fe6883b..0000000 --- a/ash/shelf/app_list_shelf_item_delegate.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_SHELF_APP_LIST_SHELF_ITEM_DELEGATE_H_ -#define ASH_SHELF_APP_LIST_SHELF_ITEM_DELEGATE_H_ - -#include <memory> - -#include "ash/ash_export.h" -#include "ash/public/cpp/shelf_item_delegate.h" -#include "base/macros.h" - -namespace ash { - -// ShelfItemDelegate for TYPE_APP_LIST. -class ASH_EXPORT AppListShelfItemDelegate : public ShelfItemDelegate { - public: - AppListShelfItemDelegate(); - ~AppListShelfItemDelegate() override; - - // ShelfItemDelegate: - void ItemSelected(std::unique_ptr<ui::Event> event, - int64_t display_id, - ShelfLaunchSource source, - ItemSelectedCallback callback) override; - void ExecuteCommand(bool from_context_menu, - int64_t command_id, - int32_t event_flags, - int64_t display_id) override; - void Close() override; - - private: - DISALLOW_COPY_AND_ASSIGN(AppListShelfItemDelegate); -}; - -} // namespace ash - -#endif // ASH_SHELF_APP_LIST_SHELF_ITEM_DELEGATE_H_
diff --git a/ash/shelf/home_button_delegate.cc b/ash/shelf/home_button_delegate.cc new file mode 100644 index 0000000..e7c7f7ae --- /dev/null +++ b/ash/shelf/home_button_delegate.cc
@@ -0,0 +1,61 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/shelf/home_button_delegate.h" + +#include <utility> + +#include "ash/app_list/app_list_controller_impl.h" +#include "ash/home_screen/home_screen_controller.h" +#include "ash/kiosk_next/kiosk_next_shell_controller.h" +#include "ash/public/cpp/shelf_model.h" +#include "ash/shell.h" +#include "base/logging.h" + +namespace ash { + +HomeButtonDelegate::HomeButtonDelegate() + : ShelfItemDelegate(ShelfID(kAppListId)) {} + +HomeButtonDelegate::~HomeButtonDelegate() = default; + +// static +ShelfAction HomeButtonDelegate::PerformHomeButtonAction( + int64_t display_id, + app_list::AppListShowSource show_source, + base::TimeTicks event_time_stamp) { + ShelfAction shelf_action = ash::SHELF_ACTION_NONE; + if (Shell::Get()->kiosk_next_shell_controller()->IsEnabled()) { + Shell::Get()->home_screen_controller()->GoHome(display_id); + shelf_action = ash::SHELF_ACTION_APP_LIST_SHOWN; + } else { + shelf_action = Shell::Get()->app_list_controller()->OnAppListButtonPressed( + display_id, show_source, event_time_stamp); + } + return shelf_action; +} + +void HomeButtonDelegate::ItemSelected(std::unique_ptr<ui::Event> event, + int64_t display_id, + ShelfLaunchSource source, + ItemSelectedCallback callback) { + ShelfAction shelf_action = PerformHomeButtonAction( + display_id, + event->IsShiftDown() ? app_list::kShelfButtonFullscreen + : app_list::kShelfButton, + event->time_stamp()); + std::move(callback).Run(shelf_action, base::nullopt); +} + +void HomeButtonDelegate::ExecuteCommand(bool from_context_menu, + int64_t command_id, + int32_t event_flags, + int64_t display_id) { + // This delegate does not show custom context or application menu items. + NOTIMPLEMENTED(); +} + +void HomeButtonDelegate::Close() {} + +} // namespace ash
diff --git a/ash/shelf/home_button_delegate.h b/ash/shelf/home_button_delegate.h new file mode 100644 index 0000000..a06bc7c --- /dev/null +++ b/ash/shelf/home_button_delegate.h
@@ -0,0 +1,53 @@ +// 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 ASH_SHELF_HOME_BUTTON_DELEGATE_H_ +#define ASH_SHELF_HOME_BUTTON_DELEGATE_H_ + +#include <memory> + +#include "ash/app_list/app_list_metrics.h" +#include "ash/ash_export.h" +#include "ash/public/cpp/shelf_item_delegate.h" +#include "ash/public/cpp/shelf_types.h" +#include "base/macros.h" + +namespace ash { + +// ShelfItemDelegate for the Home button, aka the app list button. +// TODO(michaelpg): Rename references to app list button to home button. +class ASH_EXPORT HomeButtonDelegate : public ShelfItemDelegate { + public: + HomeButtonDelegate(); + ~HomeButtonDelegate() override; + + // Responds to the home button being activated or the equivalent accelerator + // being pressed. + // |display_id| is the display of the button, indicating where the Home screen + // should be shown. + // |show_source| is the type of user action that triggered this. + // |event_time_stamp| is timestamp of the triggering event. + static ShelfAction PerformHomeButtonAction( + int64_t display_id, + app_list::AppListShowSource show_source, + base::TimeTicks event_time_stamp); + + // ShelfItemDelegate: + void ItemSelected(std::unique_ptr<ui::Event> event, + int64_t display_id, + ShelfLaunchSource source, + ItemSelectedCallback callback) override; + void ExecuteCommand(bool from_context_menu, + int64_t command_id, + int32_t event_flags, + int64_t display_id) override; + void Close() override; + + private: + DISALLOW_COPY_AND_ASSIGN(HomeButtonDelegate); +}; + +} // namespace ash + +#endif // ASH_SHELF_HOME_BUTTON_DELEGATE_H_
diff --git a/ash/shelf/login_shelf_view.cc b/ash/shelf/login_shelf_view.cc index 47ddc43d..16ce6f78 100644 --- a/ash/shelf/login_shelf_view.cc +++ b/ash/shelf/login_shelf_view.cc
@@ -336,7 +336,8 @@ origin.set_y(point.y() - source->height()); menu_runner_->RunMenuAt(source->GetWidget()->GetTopLevelWidget(), this, gfx::Rect(origin, gfx::Size()), - views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_NONE); + views::MenuAnchorPosition::kTopLeft, + ui::MENU_SOURCE_NONE); } // ui::SimpleMenuModel:
diff --git a/ash/shelf/shelf_controller.cc b/ash/shelf/shelf_controller.cc index 28d3915..8b4360b 100644 --- a/ash/shelf/shelf_controller.cc +++ b/ash/shelf/shelf_controller.cc
@@ -9,10 +9,11 @@ #include "ash/public/cpp/ash_pref_names.h" #include "ash/public/cpp/remote_shelf_item_delegate.h" +#include "ash/public/cpp/shelf_item_delegate.h" #include "ash/public/cpp/shelf_prefs.h" #include "ash/root_window_controller.h" #include "ash/session/session_controller.h" -#include "ash/shelf/app_list_shelf_item_delegate.h" +#include "ash/shelf/home_button_delegate.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_constants.h" #include "ash/shelf/shelf_widget.h" @@ -121,9 +122,9 @@ back_item.title = l10n_util::GetStringUTF16(IDS_ASH_SHELF_BACK_BUTTON_TITLE); model_.Set(0, back_item); - // Set the delegate and title string for the app list item. + // Set the delegate and title string for the home button. model_.SetShelfItemDelegate(ShelfID(kAppListId), - std::make_unique<AppListShelfItemDelegate>()); + std::make_unique<HomeButtonDelegate>()); DCHECK_EQ(1, model_.ItemIndexByID(ShelfID(kAppListId))); ShelfItem launcher_item = model_.items()[1]; launcher_item.title = @@ -131,9 +132,11 @@ model_.Set(1, launcher_item); model_.AddObserver(this); + Shell::Get()->session_controller()->AddObserver(this); Shell::Get()->tablet_mode_controller()->AddObserver(this); Shell::Get()->window_tree_host_manager()->AddObserver(this); + if (is_notification_indicator_enabled_) message_center_observer_.Add(message_center::MessageCenter::Get()); }
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index 87be8b8..54768094 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -483,7 +483,7 @@ const AppListButton* app_list_button = GetAppListButton(); if (app_list_button && app_list_button->GetMirroredBounds().Contains(cursor_location)) { - return app_list_button->is_showing_app_list(); + return app_list_button->IsShowingAppList(); } return !visible_shelf_item_bounds_union_.Contains(cursor_location); } @@ -492,7 +492,7 @@ // If this is the app list button, only show the tooltip if the app list is // not already showing. if (view == GetAppListButton()) - return !GetAppListButton()->is_showing_app_list(); + return !GetAppListButton()->IsShowingAppList(); if (view == overflow_button_) return true; // Don't show a tooltip for a view that's currently being dragged. @@ -2336,8 +2336,8 @@ shelf_menu_model_adapter_->Run( GetMenuAnchorRect(*source, click_point, context_menu), shelf_->IsHorizontalAlignment() - ? views::MENU_ANCHOR_BUBBLE_TOUCHABLE_ABOVE - : views::MENU_ANCHOR_BUBBLE_TOUCHABLE_LEFT, + ? views::MenuAnchorPosition::kBubbleTouchableAbove + : views::MenuAnchorPosition::kBubbleTouchableLeft, run_types); }
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc index a2c5ec7..8922a45 100644 --- a/ash/shelf/shelf_view_unittest.cc +++ b/ash/shelf/shelf_view_unittest.cc
@@ -1445,7 +1445,7 @@ const AppListButton* app_list_button = shelf_view_->GetAppListButton(); // Make sure we're not showing the app list. - EXPECT_FALSE(app_list_button->is_showing_app_list()) + EXPECT_FALSE(app_list_button->IsShowingAppList()) << "We should not be showing the app list"; // The tooltip shouldn't hide if the mouse is on normal buttons.
diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc index 687e132..415e670 100644 --- a/ash/shelf/shelf_widget.cc +++ b/ash/shelf/shelf_widget.cc
@@ -433,7 +433,7 @@ } bool ShelfWidget::IsShowingAppList() const { - return GetAppListButton() && GetAppListButton()->is_showing_app_list(); + return GetAppListButton() && GetAppListButton()->IsShowingAppList(); } bool ShelfWidget::IsShowingMenu() const {
diff --git a/ash/shell/window_type_launcher.cc b/ash/shell/window_type_launcher.cc index 113735b9..7198f6e 100644 --- a/ash/shell/window_type_launcher.cc +++ b/ash/shell/window_type_launcher.cc
@@ -340,7 +340,7 @@ menu_runner_.reset(new MenuRunner( root, MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU)); menu_runner_->RunMenuAt(GetWidget(), NULL, gfx::Rect(point, gfx::Size()), - views::MENU_ANCHOR_TOPLEFT, source_type); + views::MenuAnchorPosition::kTopLeft, source_type); } } // namespace shell
diff --git a/ash/shell_unittest.cc b/ash/shell_unittest.cc index 41c9b2b..a68fd576 100644 --- a/ash/shell_unittest.cc +++ b/ash/shell_unittest.cc
@@ -429,7 +429,8 @@ std::unique_ptr<views::MenuRunner> menu_runner( new views::MenuRunner(menu_model.get(), views::MenuRunner::CONTEXT_MENU)); - menu_runner->RunMenuAt(widget, NULL, gfx::Rect(), views::MENU_ANCHOR_TOPLEFT, + menu_runner->RunMenuAt(widget, NULL, gfx::Rect(), + views::MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_MOUSE); LockScreenAndVerifyMenuClosed(); }
diff --git a/ash/system/network/tray_network_state_observer.cc b/ash/system/network/tray_network_state_observer.cc index f0763d3..bf4b19b 100644 --- a/ash/system/network/tray_network_state_observer.cc +++ b/ash/system/network/tray_network_state_observer.cc
@@ -25,6 +25,12 @@ chromeos::NetworkTypePattern::WiFi()); } +bool IsMobileEnabled() { + return NetworkHandler::Get()->network_state_handler()->IsTechnologyEnabled( + chromeos::NetworkTypePattern::Cellular() | + chromeos::NetworkTypePattern::Tether()); +} + } // namespace namespace ash { @@ -78,11 +84,17 @@ } void TrayNetworkStateObserver::SignalUpdate(bool notify_a11y) { - bool old_state = wifi_enabled_; + bool old_wifi_state = wifi_enabled_; wifi_enabled_ = IsWifiEnabled(); - // Update immediately when wifi network changed from enabled->disabled. - if (old_state && !wifi_enabled_) { + bool old_mobile_state = mobile_enabled_; + mobile_enabled_ = IsMobileEnabled(); + + // Update immediately when Wi-Fi and/or Mobile have been turned on or off. + // This ensures that the UI for settings and quick settings stays in sync; see + // https://crbug.com/917325. + if (old_wifi_state != wifi_enabled_ || old_mobile_state != mobile_enabled_) { + timer_.Stop(); SendNetworkStateChanged(notify_a11y); return; }
diff --git a/ash/system/network/tray_network_state_observer.h b/ash/system/network/tray_network_state_observer.h index 2e91a3d..bbead095 100644 --- a/ash/system/network/tray_network_state_observer.h +++ b/ash/system/network/tray_network_state_observer.h
@@ -52,9 +52,12 @@ // Timer used to limit the frequency of NetworkStateChanged updates. base::OneShotTimer timer_; - // The previous state of the wifi network, used to immediately send - // NetworkStateChanged update when wifi changed from enabled->disabled. + // The cached states of whether Wi-Fi and Mobile are enabled. The tray + // includes expanding network lists of these types, so these cached values + // are used to determine when to prioritize updating the tray when they + // change. bool wifi_enabled_ = false; + bool mobile_enabled_ = false; DISALLOW_COPY_AND_ASSIGN(TrayNetworkStateObserver); };
diff --git a/base/profiler/native_stack_sampler_win.cc b/base/profiler/native_stack_sampler_win.cc index 4eda475..7487ad86 100644 --- a/base/profiler/native_stack_sampler_win.cc +++ b/base/profiler/native_stack_sampler_win.cc
@@ -264,9 +264,11 @@ ProfileBuilder* profile_builder) override; private: - // Suspends the thread with |thread_handle|, copies its stack, register - // context, and current metadata and resumes the thread. Returns true on - // success. + // Suspends the thread with |thread_handle|, copies its stack base address, + // stack, and register context, and records the current metadata, then resumes + // the thread. Returns true on success, and returns the copied state via the + // |base_address|, |stack_buffer|, |profile_builder|, and |thread_context| + // params. static bool CopyStack(HANDLE thread_handle, const void* base_address, StackBuffer* stack_buffer, @@ -313,8 +315,7 @@ "NativeStackSamplerWin::RecordStackFrames"); DCHECK(stack_buffer); - CONTEXT thread_context = {0}; - thread_context.ContextFlags = CONTEXT_FULL; + CONTEXT thread_context; bool success = CopyStack(thread_handle_.Get(), thread_stack_base_address_, stack_buffer, profile_builder, &thread_context); if (!success) @@ -342,6 +343,10 @@ CONTEXT* thread_context) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cpu_profiler.debug"), "SuspendThread"); + + *thread_context = {0}; + thread_context->ContextFlags = CONTEXT_FULL; + { ScopedSuspendThread suspend_thread(thread_handle);
diff --git a/build/android/gyp/java_cpp_enum.py b/build/android/gyp/java_cpp_enum.py index 2d493f7..bacc8e3 100755 --- a/build/android/gyp/java_cpp_enum.py +++ b/build/android/gyp/java_cpp_enum.py
@@ -385,7 +385,8 @@ comments_line_wrapper.wrap(enum_comments))) enum_entries_string.append(' */') enum_entries_string.append(enum_template.substitute(values)) - enum_names.append(enum_definition.class_name + '.' + enum_name) + if enum_name != "NUM_ENTRIES": + enum_names.append(enum_definition.class_name + '.' + enum_name) enum_entries_string = '\n'.join(enum_entries_string) enum_names_indent = ' ' * 4
diff --git a/build/android/stacktrace/crashpad_stackwalker.py b/build/android/stacktrace/crashpad_stackwalker.py index dc3fd89..a538105 100755 --- a/build/android/stacktrace/crashpad_stackwalker.py +++ b/build/android/stacktrace/crashpad_stackwalker.py
@@ -92,7 +92,7 @@ r'"(?P<library_name>lib[^. ]+.so)"') in_module = False for line in stdout.splitlines(): - line = line.rstrip('\n') + line = line.lstrip().rstrip('\n') if line == 'MDRawModule': in_module = True continue @@ -149,23 +149,23 @@ if not crashpad_file: logging.error('Could not locate a crashpad dump') return 1 - else: - dump_dir = tempfile.mkdtemp() - symbols_dir = None - try: - device.PullFile( - device_path=posixpath.join(device_crashpad_path, crashpad_file), - host_path=dump_dir) - dump_full_path = os.path.join(dump_dir, crashpad_file) - library_names = _ExtractLibraryNamesFromDump(args.build_path, - dump_full_path) - symbols_dir = _CreateSymbolsDir(args.build_path, library_names) - stackwalk_cmd = [stackwalk_path, dump_full_path, symbols_dir] - subprocess.call(stackwalk_cmd) - finally: - shutil.rmtree(dump_dir, ignore_errors=True) - if symbols_dir: - shutil.rmtree(symbols_dir, ignore_errors=True) + + dump_dir = tempfile.mkdtemp() + symbols_dir = None + try: + device.PullFile( + device_path=posixpath.join(device_crashpad_path, crashpad_file), + host_path=dump_dir) + dump_full_path = os.path.join(dump_dir, crashpad_file) + library_names = _ExtractLibraryNamesFromDump(args.build_path, + dump_full_path) + symbols_dir = _CreateSymbolsDir(args.build_path, library_names) + stackwalk_cmd = [stackwalk_path, dump_full_path, symbols_dir] + subprocess.call(stackwalk_cmd) + finally: + shutil.rmtree(dump_dir, ignore_errors=True) + if symbols_dir: + shutil.rmtree(symbols_dir, ignore_errors=True) return 0
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 83a07e1..a86f3b2 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -eaac7b7f5bb54fa74873c9d37796702e49e98987 \ No newline at end of file +0aba3e826b3187b0bd1bfdbf06fbaff168801edd \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 7641efa..b6be569 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -4186125ff0046e4fe61888e0ecb60eae34e42327 \ No newline at end of file +b058131a0406f496bda02c45ea22c75cf12f7d4d \ No newline at end of file
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 331491a4..e559854 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -954,6 +954,7 @@ "//third_party/gvr-android-sdk:controller_test_api_java", "//third_party/gvr-android-sdk:gvr_common_java", ":chrome_test_util_java", + "//components/module_installer/android:module_installer_java", "//components/module_installer/android:module_installer_test_java", ]
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index e3621c8..b22fce0 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -10,6 +10,7 @@ "java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupUtils.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinder.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetCoordinator.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetMediator.java", @@ -43,6 +44,7 @@ "//chrome/android:chrome_strings_grd", "//chrome/android:ui_locale_string_resources", "//chrome/app:java_strings_grd", + "//components/embedder_support/android:web_contents_delegate_java", "//components/feature_engagement:feature_engagement_java", "//components/policy/android:policy_java", "//content/public/android:content_java_resources",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java index 11cf153e..55a0d5d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java
@@ -6,6 +6,7 @@ import android.content.Context; +import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.layouts.OverviewModeController; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; @@ -33,6 +34,7 @@ private final ActivityLifecycleDispatcher mLifecycleDispatcher; private final TabListCoordinator mTabGridCoordinator; private final GridTabSwitcherMediator mMediator; + private final MultiThumbnailCardProvider mMultiThumbnailCardProvider; public GridTabSwitcherCoordinator(Context context, ActivityLifecycleDispatcher lifecycleDispatcher, ToolbarManager toolbarManager, @@ -40,8 +42,22 @@ CompositorViewHolder compositorViewHolder, ChromeFullscreenManager fullscreenManager) { PropertyModel containerViewModel = new PropertyModel(TabListContainerProperties.ALL_KEYS); + mMultiThumbnailCardProvider = + new MultiThumbnailCardProvider(context, tabContentManager, tabModelSelector); + + TabListMediator.TitleProvider titleProvider = tab -> { + int numRelatedTabs = tabModelSelector.getTabModelFilterProvider() + .getCurrentTabModelFilter() + .getRelatedTabList(tab.getId()) + .size(); + if (numRelatedTabs == 1) return tab.getTitle(); + return context.getResources().getQuantityString( + R.plurals.bottom_tab_grid_title_placeholder, numRelatedTabs, numRelatedTabs); + }; + mTabGridCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.GRID, context, - tabModelSelector, tabContentManager, compositorViewHolder, true, COMPONENT_NAME); + tabModelSelector, mMultiThumbnailCardProvider, titleProvider, compositorViewHolder, + true, COMPONENT_NAME); mContainerViewChangeProcessor = PropertyModelChangeProcessor.create(containerViewModel, mTabGridCoordinator.getContainerView(), TabGridContainerViewBinder::bind);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java new file mode 100644 index 0000000..1f3d1d44 --- /dev/null +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java
@@ -0,0 +1,224 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.tasks.tab_management; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.graphics.RectF; + +import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.Callback; +import org.chromium.base.PathUtils; +import org.chromium.base.ThreadUtils; +import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.PostTask; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.content_public.browser.UiThreadTaskTraits; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * A {@link TabListMediator.ThumbnailProvider} that will create a single Bitmap Thumbnail for all + * the related tabs for the given tabs. + */ +public class MultiThumbnailCardProvider implements TabListMediator.ThumbnailProvider { + private final TabContentManager mTabContentManager; + private final TabModelSelector mTabModelSelector; + + private final float mPadding; + private final float mRadius; + private final Paint mEmptyThumbnailPaint; + private final Paint mThumbnailFramePaint; + private final Paint mTextPaint; + private final int mSize; + private final List<RectF> mRects = new ArrayList<>(4); + + private class MultiThumbnailFetchingTask extends AsyncTask<Void> { + private final Tab mInitialTab; + private final Callback<Bitmap> mFinalCallback; + private final List<Tab> mTabs = new ArrayList<>(4); + private final AtomicInteger mThumbnailsToFetch = new AtomicInteger(); + + private Canvas mCanvas; + private Bitmap mMultiThumbnailBitmap; + private String mText; + + MultiThumbnailFetchingTask(Tab initialTab, Callback<Bitmap> finalCallback) { + mFinalCallback = finalCallback; + mInitialTab = initialTab; + } + + private void initializeAndStartFetching(Tab tab) { + // Initialize mMultiThumbnailBitmap. + int width = mSize; + int height = mSize; + mMultiThumbnailBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + mCanvas = new Canvas(mMultiThumbnailBitmap); + mCanvas.drawColor(Color.TRANSPARENT); + + // Initialize Tabs. + List<Tab> relatedTabList = new ArrayList<>(); + relatedTabList.addAll(mTabModelSelector.getTabModelFilterProvider() + .getCurrentTabModelFilter() + .getRelatedTabList(tab.getId())); + if (relatedTabList.size() <= 4) { + mThumbnailsToFetch.set(relatedTabList.size()); + + mTabs.add(tab); + relatedTabList.remove(tab); + + for (int i = 0; i < 3; i++) { + mTabs.add(i < relatedTabList.size() ? relatedTabList.get(i) : null); + } + } else { + mText = "+" + (relatedTabList.size() - 3); + mThumbnailsToFetch.set(3); + + mTabs.add(tab); + relatedTabList.remove(tab); + + mTabs.add(relatedTabList.get(0)); + mTabs.add(relatedTabList.get(1)); + mTabs.add(null); + } + + // Fetch and draw all. + for (int i = 0; i < 4; i++) { + if (mTabs.get(i) != null) { + if (hasThumbnailFileForTab(mTabs.get(i).getId())) { + final int index = i; + mTabContentManager.getTabThumbnailWithCallback(mTabs.get(i), result -> { + drawBitmapOnCanvasWithFrame(result, index, mEmptyThumbnailPaint); + if (mThumbnailsToFetch.decrementAndGet() == 0) { + PostTask.postTask(UiThreadTaskTraits.USER_VISIBLE, + () -> mFinalCallback.onResult(mMultiThumbnailBitmap)); + } + }); + } else { + if (mThumbnailsToFetch.decrementAndGet() == 0) { + PostTask.postTask(UiThreadTaskTraits.USER_VISIBLE, + () -> mFinalCallback.onResult(mMultiThumbnailBitmap)); + } + } + } else { + drawBitmapOnCanvasWithFrame(null, i, mEmptyThumbnailPaint); + if (mText != null && i == 3) { + // Draw the text exactly centered on the thumbnail rect. + mCanvas.drawText(mText, (mRects.get(i).left + mRects.get(i).right) / 2, + (mRects.get(i).top + mRects.get(i).bottom) / 2 + - ((mTextPaint.descent() + mTextPaint.ascent()) / 2), + mTextPaint); + } + } + } + } + + private void drawBitmapOnCanvasWithFrame( + Bitmap result, int index, Paint emptyThumbnailPaint) { + // Draw the rounded rect. If Bitmap is not null, this is used for XferMode. + mCanvas.drawRoundRect(mRects.get(index), mRadius, mRadius, emptyThumbnailPaint); + + if (result == null) return; + + result = Bitmap.createScaledBitmap(result, (int) mRects.get(index).width(), + (int) mRects.get(index).height(), true); + + emptyThumbnailPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); + mCanvas.drawBitmap(result, new Rect(0, 0, result.getWidth(), result.getHeight()), + mRects.get(index), emptyThumbnailPaint); + result.recycle(); + + emptyThumbnailPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); + + mCanvas.drawRoundRect(mRects.get(index), mRadius, mRadius, mThumbnailFramePaint); + } + + @Override + protected Void doInBackground() { + initializeAndStartFetching(mInitialTab); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) {} + } + + MultiThumbnailCardProvider(Context context, TabContentManager tabContentManager, + TabModelSelector tabModelSelector) { + mTabContentManager = tabContentManager; + mTabModelSelector = tabModelSelector; + mPadding = context.getResources().getDimension(R.dimen.tab_list_card_padding); + mRadius = context.getResources().getDimension(R.dimen.tab_list_mini_card_radius); + mSize = (int) context.getResources().getDimension( + R.dimen.tab_grid_thumbnail_card_default_size); + + // Initialize Paints to use. + mEmptyThumbnailPaint = new Paint(); + mEmptyThumbnailPaint.setStyle(Paint.Style.FILL); + mEmptyThumbnailPaint.setColor( + ApiCompatibilityUtils.getColor(context.getResources(), R.color.modern_grey_100)); + mEmptyThumbnailPaint.setAntiAlias(true); + + mThumbnailFramePaint = new Paint(); + mThumbnailFramePaint.setStyle(Paint.Style.STROKE); + mThumbnailFramePaint.setStrokeWidth( + context.getResources().getDimension(R.dimen.tab_list_mini_card_frame_size)); + mThumbnailFramePaint.setColor( + ApiCompatibilityUtils.getColor(context.getResources(), R.color.modern_grey_300)); + mThumbnailFramePaint.setAntiAlias(true); + + mTextPaint = new Paint(); + mTextPaint.setTextSize( + context.getResources().getDimension(R.dimen.compositor_tab_title_text_size)); + mTextPaint.setFakeBoldText(true); + mTextPaint.setAntiAlias(true); + mTextPaint.setTextAlign(Paint.Align.CENTER); + + // Initialize Rects. + mRects.add( + new RectF(mPadding, mPadding, mSize / 2 - mPadding / 2, mSize / 2 - mPadding / 2)); + mRects.add(new RectF( + mSize / 2 + mPadding / 2, mPadding, mSize - mPadding, mSize / 2 - mPadding / 2)); + mRects.add(new RectF( + mPadding, mSize / 2 + mPadding / 2, mSize / 2 - mPadding / 2, mSize - mPadding)); + mRects.add(new RectF(mSize / 2 + mPadding / 2, mSize / 2 + mPadding / 2, mSize - mPadding, + mSize - mPadding)); + } + + @Override + public void getTabThumbnailWithCallback(Tab tab, Callback<Bitmap> finalCallback) { + if (mTabModelSelector.getTabModelFilterProvider() + .getCurrentTabModelFilter() + .getRelatedTabList(tab.getId()) + .size() + == 1) { + mTabContentManager.getTabThumbnailWithCallback(tab, finalCallback); + return; + } + + new MultiThumbnailFetchingTask(tab, finalCallback) + .executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); + } + + private static boolean hasThumbnailFileForTab(int tabId) { + ThreadUtils.assertOnBackgroundThread(); + + // The thumbnail file path for a tab with id, ID is "cache_directory_path/ID". + File file = new File(PathUtils.getThumbnailCacheDirectory() + "/" + tabId); + return file.exists(); + } +}
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SilenceLintErrors.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SilenceLintErrors.java index 126c0cab..8db01bc 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SilenceLintErrors.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SilenceLintErrors.java
@@ -26,6 +26,8 @@ R.string.iph_tab_groups_tap_to_see_another_tab_accessibility_text, R.string.accessibility_bottom_tab_strip_expand_tab_sheet, R.layout.bottom_tab_strip_toolbar, R.drawable.tabstrip_selected, + R.dimen.tab_list_card_padding, R.dimen.tab_list_mini_card_text_size, + R.dimen.tab_list_mini_card_frame_size, R.dimen.tab_list_mini_card_radius, R.drawable.tabstrip_favicon_background}; private SilenceLintErrors() {}
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetCoordinator.java index 0c84d6b..4eca89d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetCoordinator.java
@@ -44,8 +44,8 @@ mToolbarPropertyModel = new PropertyModel(TabGridSheetProperties.ALL_KEYS); mTabGridCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.GRID, context, - tabModelSelector, tabContentManager, bottomSheetController.getBottomSheet(), false, - COMPONENT_NAME); + tabModelSelector, tabContentManager::getTabThumbnailWithCallback, null, + bottomSheetController.getBottomSheet(), false, COMPONENT_NAME); mMediator = new TabGridSheetMediator(mContext, bottomSheetController, this::resetWithListOfTabs, mToolbarPropertyModel, tabModelSelector,
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java index 6e6e44d3..f3c58a3 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
@@ -59,7 +59,7 @@ TabContentManager tabContentManager = activity.getTabContentManager(); mTabStripCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.STRIP, - mContext, tabModelSelector, tabContentManager, + mContext, tabModelSelector, null, null, mTabStripToolbarCoordinator.getTabListContainerView(), true, COMPONENT_NAME); mTabGridSheetCoordinator =
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java index fc83adeb..f1a69485 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
@@ -14,7 +14,6 @@ import android.view.ViewGroup; import org.chromium.chrome.R; -import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.lifecycle.Destroyable; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; @@ -55,7 +54,8 @@ * @param context The context to use for accessing {@link android.content.res.Resources}. * @param tabModelSelector {@link TabModelSelector} that will provide and receive signals about * the tabs concerned. - * @param tabContentManager {@link TabContentManager} to provide screenshot related details. + * @param thumbnailProvider Provider to provide screenshot related details. + * @param titleProvider Provider for a given tab's title. * @param parentView {@link ViewGroup} The root view of the UI. * @param attachToParent Whether the UI should attach to root view. * @param componentName A unique string uses to identify different components for UMA recording. @@ -63,7 +63,8 @@ * through actions.xml file. */ TabListCoordinator(@TabListMode int mode, Context context, TabModelSelector tabModelSelector, - TabContentManager tabContentManager, @NonNull ViewGroup parentView, + TabListMediator.ThumbnailProvider thumbnailProvider, + TabListMediator.TitleProvider titleProvider, @NonNull ViewGroup parentView, boolean attachToParent, String componentName) { TabListModel tabListModel = new TabListModel(); mMode = mode; @@ -106,11 +107,11 @@ mRecyclerView.setHasFixedSize(true); - TabListFaviconProvider mTabListFaviconProvider = + TabListFaviconProvider tabListFaviconProvider = new TabListFaviconProvider(context, Profile.getLastUsedProfile()); - mMediator = new TabListMediator(tabListModel, tabModelSelector, tabContentManager, - mTabListFaviconProvider, componentName); + mMediator = new TabListMediator(tabListModel, tabModelSelector, thumbnailProvider, + titleProvider, tabListFaviconProvider, componentName); } /**
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index d859691c..eefed2fb 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -11,7 +11,6 @@ import org.chromium.base.Callback; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; -import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.native_page.NativePageFactory; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; @@ -43,6 +42,11 @@ } /** + * An interface to get the title to be used for a tab. + */ + public interface TitleProvider { String getTitle(Tab tab); } + + /** * The object to set to TabProperties.THUMBNAIL_FETCHER for the TabGridViewBinder to obtain * the thumbnail asynchronously. */ @@ -62,7 +66,8 @@ private final TabListFaviconProvider mTabListFaviconProvider; private final TabListModel mModel; private final TabModelSelector mTabModelSelector; - private final TabContentManager mTabContentManager; + private final ThumbnailProvider mThumbnailProvider; + private final TitleProvider mTitleProvider; private final String mComponentName; private final TabActionListener mTabSelectedListener = new TabActionListener() { @@ -130,7 +135,7 @@ public void onTitleUpdated(Tab updatedTab) { int index = mModel.indexFromId(updatedTab.getId()); if (index == TabModel.INVALID_TAB_INDEX) return; - mModel.get(index).set(TabProperties.TITLE, updatedTab.getTitle()); + mModel.get(index).set(TabProperties.TITLE, mTitleProvider.getTitle(updatedTab)); } @Override @@ -156,18 +161,20 @@ * @param model The Model to keep state about a list of {@link Tab}s. * @param tabModelSelector {@link TabModelSelector} that will provide and receive signals about * the tabs concerned. - * @param tabContentManager {@link TabContentManager} to provide screenshot related details. + * @param thumbnailProvider {@link ThumbnailProvider} to provide screenshot related details. + * @param titleProvider {@link TitleProvider} for a given tab's title to show. + * @param tabListFaviconProvider Provider for all favicon related drawables. * @param componentName This is a unique string to identify different components. */ - public TabListMediator(TabListModel model, TabModelSelector tabModelSelector, - TabContentManager tabContentManager, TabListFaviconProvider tabListFaviconProvider, - String componentName) { + @Nullable ThumbnailProvider thumbnailProvider, @Nullable TitleProvider titleProvider, + TabListFaviconProvider tabListFaviconProvider, String componentName) { mTabModelSelector = tabModelSelector; - mTabContentManager = tabContentManager; + mThumbnailProvider = thumbnailProvider; mModel = model; mTabListFaviconProvider = tabListFaviconProvider; mComponentName = componentName; + mTitleProvider = titleProvider != null ? titleProvider : Tab::getTitle; mTabModelObserver = new EmptyTabModelObserver() { @Override @@ -247,7 +254,7 @@ PropertyModel tabInfo = new PropertyModel.Builder(TabProperties.ALL_KEYS_TAB_GRID) .with(TabProperties.TAB_ID, tab.getId()) - .with(TabProperties.TITLE, tab.getTitle()) + .with(TabProperties.TITLE, mTitleProvider.getTitle(tab)) .with(TabProperties.FAVICON, mTabListFaviconProvider.getDefaultFaviconDrawable()) .with(TabProperties.IS_SELECTED, isSelected) @@ -269,9 +276,10 @@ mTabListFaviconProvider.getFaviconForUrlAsync( tab.getUrl(), tab.isIncognito(), faviconCallback); - ThumbnailFetcher callback = - new ThumbnailFetcher(mTabContentManager::getTabThumbnailWithCallback, tab); - tabInfo.set(TabProperties.THUMBNAIL_FETCHER, callback); + if (mThumbnailProvider != null) { + ThumbnailFetcher callback = new ThumbnailFetcher(mThumbnailProvider, tab); + tabInfo.set(TabProperties.THUMBNAIL_FETCHER, callback); + } tab.addObserver(mTabObserver); } }
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java index 255f1a7..64514288 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -122,8 +122,9 @@ .getFaviconForUrlAsync(anyString(), anyBoolean(), mCallbackCaptor.capture()); mModel = new TabListModel(); - mMediator = new TabListMediator(mModel, mTabModelSelector, mTabContentManager, - mTabListFaviconProvider, getClass().getSimpleName()); + mMediator = new TabListMediator(mModel, mTabModelSelector, + mTabContentManager::getTabThumbnailWithCallback, null, mTabListFaviconProvider, + getClass().getSimpleName()); } @After
diff --git a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrModuleProvider.java b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrModuleProvider.java index 4cae074..6e97197 100644 --- a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrModuleProvider.java +++ b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrModuleProvider.java
@@ -4,13 +4,11 @@ package org.chromium.chrome.browser.vr; -import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.chrome.R; import org.chromium.chrome.browser.modules.ModuleInstallUi; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.components.module_installer.Module; import org.chromium.components.module_installer.OnModuleInstallFinishedListener; import java.util.ArrayList; @@ -87,15 +85,6 @@ for (VrModeObserver observer : sVrModeObservers) observer.onExitVr(); } - @VisibleForTesting - public static void setAlwaysUseFallbackDelegate(boolean useFallbackDelegate) { - // TODO(crbug.com/944216): Remove this method and call Module.setForceUninstalled("vr") - // directly once we change the restriction checking code to use the Daydream API directly so - // that a delegate provider doesn't get created during pre-test setup. - sDelegateProvider = null; - Module.setForceUninstalled("vr"); - } - /* package */ static void installModule(OnModuleInstallFinishedListener onFinishedListener) { VrModule.install((success) -> { if (success) {
diff --git a/chrome/android/java/res/drawable/selected_tab_background.xml b/chrome/android/java/res/drawable/selected_tab_background.xml index 6dd969f..23af4b4 100644 --- a/chrome/android/java/res/drawable/selected_tab_background.xml +++ b/chrome/android/java/res/drawable/selected_tab_background.xml
@@ -6,6 +6,6 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android"> <stroke android:width="2dp" - android:color="@color/modern_grey_700" /> + android:color="@color/modern_blue_600" /> <corners android:radius="@dimen/default_card_corner_radius" /> </shape> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/tab_grid_card_item.xml b/chrome/android/java/res/layout/tab_grid_card_item.xml index 04faf36..d8dc9d27 100644 --- a/chrome/android/java/res/layout/tab_grid_card_item.xml +++ b/chrome/android/java/res/layout/tab_grid_card_item.xml
@@ -6,7 +6,7 @@ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" - android:layout_height="216dp"> + android:layout_height="wrap_content"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" @@ -35,10 +35,12 @@ <org.chromium.ui.widget.RoundedCornerImageView android:id="@+id/tab_thumbnail" android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="wrap_content" + android:minHeight="@dimen/tab_grid_thumbnail_card_default_size" android:layout_below="@id/tab_title" android:gravity="center_horizontal" - android:scaleType="centerCrop" + android:adjustViewBounds="true" + android:scaleType="fitCenter" android:importantForAccessibility="no" android:src="@color/thumbnail_placeholder_on_primary_bg" app:cornerRadiusBottomStart="@dimen/default_card_corner_radius"
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index e421560..52ee5b4 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -596,6 +596,11 @@ <!-- Tab List dimensions --> <dimen name="tab_grid_favicon_size">32dp</dimen> - <dimen name="tab_list_selected_inset">6dp</dimen> + <dimen name="tab_list_selected_inset">7dp</dimen> + <dimen name="tab_list_card_padding">8dp</dimen> + <dimen name="tab_list_mini_card_radius">4dp</dimen> + <dimen name="tab_list_mini_card_frame_size">1dp</dimen> + <dimen name="tab_list_mini_card_text_size">12sp</dimen> + <dimen name="tab_grid_thumbnail_card_default_size">152dp</dimen> </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java b/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java index 167f67a..86eb1ca 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java
@@ -54,7 +54,7 @@ @Override protected boolean onStopTaskBeforeNativeLoaded(Context context, TaskParameters taskParameters) { - assert taskParameters.getTaskId() == TaskIds.OFFLINE_PAGES_BACKGROUND_JOB_ID; + assert taskParameters.getTaskId() == TaskIds.BACKGROUND_SYNC_ONE_SHOT_JOB_ID; // Native didn't complete loading, but it was supposed to. // Presume we need to reschedule. @@ -63,10 +63,12 @@ @Override protected boolean onStopTaskWithNative(Context context, TaskParameters taskParameters) { - assert taskParameters.getTaskId() == TaskIds.OFFLINE_PAGES_BACKGROUND_JOB_ID; + assert taskParameters.getTaskId() == TaskIds.BACKGROUND_SYNC_ONE_SHOT_JOB_ID; - // Don't reschedule again. - return false; + // The method is called when the task was interrupted due to some reason. + // It is not called when the task finishes successfully. Reschedule so + // we can attempt it again. + return true; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java index 35f45b51..c17abd5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
@@ -72,6 +72,21 @@ @VisibleForTesting static final String EXTRA_MARKET_REFERRER = "market_referrer"; + @IntDef({WebApkLaunchDecision.LAUNCHED, WebApkLaunchDecision.LAUNCH_FAILED, + WebApkLaunchDecision.ALREADY_IN_WEBAPK, + WebApkLaunchDecision.WEBAPK_NOT_SOLE_INTENT_HANDLER}) + public @interface WebApkLaunchDecision { + int LAUNCHED = 0; + int LAUNCH_FAILED = 1; + + // User is either in target WebAPK or in CCT launched by the target WebAPK. + int ALREADY_IN_WEBAPK = 2; + + // The WebAPK either cannot handle intent or there are multiple non-browser apps which + // can handle the intent. + int WEBAPK_NOT_SOLE_INTENT_HANDLER = 3; + } + // These values are persisted in histograms. Please do not renumber. Append only. @IntDef({AiaIntent.FALLBACK_USED, AiaIntent.SERP, AiaIntent.OTHER}) @Retention(RetentionPolicy.SOURCE) @@ -400,15 +415,7 @@ return OverrideUrlLoadingResult.NO_OVERRIDE; } - // Sanitize the Intent, ensuring web pages can not bypass browser - // security (only access to BROWSABLE activities). - intent.addCategory(Intent.CATEGORY_BROWSABLE); - intent.setComponent(null); - Intent selector = intent.getSelector(); - if (selector != null) { - selector.addCategory(Intent.CATEGORY_BROWSABLE); - selector.setComponent(null); - } + sanitizeQueryIntentActivitiesIntent(intent); List<ResolveInfo> resolvingInfos = mDelegate.queryIntentActivities(intent); if (resolvingInfos == null) return OverrideUrlLoadingResult.NO_OVERRIDE; @@ -419,6 +426,32 @@ // from the Market. if (!canResolveActivity) { if (hasBrowserFallbackUrl) { + // Launch WebAPK if it can handle the URL. + if (!TextUtils.isEmpty(intent.getPackage()) + || (intent.getSelector() != null + && !TextUtils.isEmpty(intent.getSelector().getPackage()))) { + try { + intent = Intent.parseUri(browserFallbackUrl, Intent.URI_INTENT_SCHEME); + } catch (Exception e) { + if (DEBUG) Log.i(TAG, "NO_OVERRIDE: Could not parse fallback url"); + return OverrideUrlLoadingResult.NO_OVERRIDE; + } + sanitizeQueryIntentActivitiesIntent(intent); + resolvingInfos = mDelegate.queryIntentActivities(intent); + switch (launchWebApkIfSoleIntentHandler(params, resolvingInfos, intent)) { + case WebApkLaunchDecision.ALREADY_IN_WEBAPK: + if (DEBUG) Log.i(TAG, "NO_OVERRIDE: Already in WebAPK"); + return OverrideUrlLoadingResult.NO_OVERRIDE; + case WebApkLaunchDecision.LAUNCH_FAILED: + if (DEBUG) Log.i(TAG, "NO_OVERRIDE: WebAPK launch failed"); + return OverrideUrlLoadingResult.NO_OVERRIDE; + case WebApkLaunchDecision.LAUNCHED: + if (DEBUG) Log.i(TAG, "OVERRIDE_WITH_EXTERNAL_INTENT: Launched WebAPK"); + return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT; + case WebApkLaunchDecision.WEBAPK_NOT_SOLE_INTENT_HANDLER: + break; + } + } return clobberCurrentTabWithFallbackUrl(browserFallbackUrl, params); } @@ -602,31 +635,18 @@ IntentWithGesturesHandler.getInstance().onNewIntentWithGesture(intent); } - // If the only specialized intent handler is a WebAPK, set the intent's package to - // launch the WebAPK without showing the intent picker. - String targetWebApkPackageName = mDelegate.findFirstWebApkPackageName(resolvingInfos); - - // We can't rely on this falling through to startActivityIfNeeded and behaving - // correctly for WebAPKs. This is because the target of the intent is the WebApk's main - // activity but that's just a bouncer which will redirect to WebApkActivity in chrome. - // To avoid bouncing indefinitely, don't override the navigation if we are currently - // showing the WebApk |params.webApkPackageName()| that we will redirect to. - if (targetWebApkPackageName != null - && targetWebApkPackageName.equals(params.nativeClientPackageName())) { - if (DEBUG) Log.i(TAG, "NO_OVERRIDE: Navigation in WebApk"); - return OverrideUrlLoadingResult.NO_OVERRIDE; - } - - if (targetWebApkPackageName != null - && mDelegate.countSpecializedHandlers(resolvingInfos) == 1) { - intent.setPackage(targetWebApkPackageName); - } - - // http://crbug.com/831806 : Stay in the CCT if the CCT is opened by WebAPK and the url - // is within the WebAPK scope. - if (shouldStayInWebappCCT(params, resolvingInfos)) { - if (DEBUG) Log.i(TAG, "NO_OVERRIDE: Navigation in CCT within scope of parent webapp."); - return OverrideUrlLoadingResult.NO_OVERRIDE; + switch (launchWebApkIfSoleIntentHandler(params, resolvingInfos, intent)) { + case WebApkLaunchDecision.ALREADY_IN_WEBAPK: + if (DEBUG) Log.i(TAG, "NO_OVERRIDE: Already in WebAPK"); + return OverrideUrlLoadingResult.NO_OVERRIDE; + case WebApkLaunchDecision.LAUNCH_FAILED: + if (DEBUG) Log.i(TAG, "NO_OVERRIDE: WebAPK launch failed"); + return OverrideUrlLoadingResult.NO_OVERRIDE; + case WebApkLaunchDecision.LAUNCHED: + if (DEBUG) Log.i(TAG, "OVERRIDE_WITH_EXTERNAL_INTENT: Launched WebAPK"); + return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT; + case WebApkLaunchDecision.WEBAPK_NOT_SOLE_INTENT_HANDLER: + break; } try { @@ -645,6 +665,20 @@ } /** + * Sanitize intent to be passed to {@link ExternalNavigationDelegate#queryIntentActivities()} + * ensuring that web pages cannot bypass browser security. + */ + private void sanitizeQueryIntentActivitiesIntent(Intent intent) { + intent.addCategory(Intent.CATEGORY_BROWSABLE); + intent.setComponent(null); + Intent selector = intent.getSelector(); + if (selector != null) { + selector.addCategory(Intent.CATEGORY_BROWSABLE); + selector.setComponent(null); + } + } + + /** * @return OVERRIDE_WITH_EXTERNAL_INTENT when we successfully started market activity, * NO_OVERRIDE otherwise. */ @@ -775,10 +809,10 @@ return null; } - // Returns whether a navigation in a CustomTabActivity opened from a WebAPK/TWA should stay + // Returns whether a navigation in a CustomTabActivity opened from a WebAPK should stay // within the CustomTabActivity. Returns false if the navigation does not occur within a // CustomTabActivity or the CustomTabActivity was not opened from a WebAPK/TWA. - private boolean shouldStayInWebappCCT( + private boolean shouldStayInWebApkCCT( ExternalNavigationParams params, List<ResolveInfo> handlers) { Tab tab = params.getTab(); if (tab == null || !tab.isCurrentlyACustomTab() || tab.getActivity() == null) { @@ -806,6 +840,43 @@ } /** + * Launches WebAPK if the WebAPK is the sole non-browser handler for the given intent. + * Returns whether a WebAPK was launched and if it was not launched returns why. + */ + private @WebApkLaunchDecision int launchWebApkIfSoleIntentHandler( + ExternalNavigationParams params, List<ResolveInfo> resolvingInfos, Intent intent) { + if (shouldStayInWebApkCCT(params, resolvingInfos)) { + return WebApkLaunchDecision.ALREADY_IN_WEBAPK; + } + + String targetWebApkPackageName = mDelegate.findFirstWebApkPackageName(resolvingInfos); + + // We can't rely on this falling through to startActivityIfNeeded and behaving + // correctly for WebAPKs. This is because the target of the intent is the WebApk's main + // activity but that's just a bouncer which will redirect to WebApkActivity in chrome. + // To avoid bouncing indefinitely, don't override the navigation if we are currently + // showing the WebApk |params.webApkPackageName()| that we will redirect to. + if (targetWebApkPackageName != null + && targetWebApkPackageName.equals(params.nativeClientPackageName())) { + return WebApkLaunchDecision.ALREADY_IN_WEBAPK; + } + + if (targetWebApkPackageName == null + || mDelegate.countSpecializedHandlers(resolvingInfos) != 1) { + return WebApkLaunchDecision.WEBAPK_NOT_SOLE_INTENT_HANDLER; + } + + intent.setPackage(targetWebApkPackageName); + try { + if (mDelegate.startActivityIfNeeded(intent, false)) { + return WebApkLaunchDecision.LAUNCHED; + } + } catch (ActivityNotFoundException e) { + } + return WebApkLaunchDecision.LAUNCH_FAILED; + } + + /** * Returns whether or not there's an activity available to handle the intent. */ private boolean deviceCanHandleIntent(Intent intent) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java index e4e83d5d3..cf7c8f6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java
@@ -836,6 +836,37 @@ @Test @SmallTest + public void testFallbackUrl_FallbackToWebApk() { + // IMDB app isn't installed. + mDelegate.setCanResolveActivityForExternalSchemes(false); + + mDelegate.add(new IntentActivity(IMDB_WEBPAGE_FOR_TOM_HANKS, WEBAPK_PACKAGE_NAME) + .withIsWebApk(true)); + checkUrl(INTENT_URL_WITH_FALLBACK_URL) + .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS) + .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, START_WEBAPK); + } + + @Test + @SmallTest + public void testFallbackUrl_DontFallbackToWebApkMultipleHandlers() { + // IMDB app isn't installed. + mDelegate.setCanResolveActivityForExternalSchemes(false); + + mDelegate.add(new IntentActivity(IMDB_WEBPAGE_FOR_TOM_HANKS, WEBAPK_PACKAGE_NAME) + .withIsWebApk(true)); + mDelegate.add(new IntentActivity(IMDB_WEBPAGE_FOR_TOM_HANKS, TEXT_APP_1_PACKAGE_NAME)); + checkUrl(INTENT_URL_WITH_FALLBACK_URL) + .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS) + .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE); + Assert.assertNull(mDelegate.startActivityIntent); + Assert.assertEquals(IMDB_WEBPAGE_FOR_TOM_HANKS, mDelegate.getNewUrlAfterClobbering()); + Assert.assertEquals( + SEARCH_RESULT_URL_FOR_TOM_HANKS, mDelegate.getReferrerUrlForClobbering()); + } + + @Test + @SmallTest public void testFallbackUrl_IntentResolutionFails() { // IMDB app isn't installed. mDelegate.setCanResolveActivityForExternalSchemes(false);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrTestRuleUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrTestRuleUtils.java index 85bf41e..e8c47c14 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrTestRuleUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrTestRuleUtils.java
@@ -19,13 +19,13 @@ import org.chromium.chrome.browser.vr.TestVrShellDelegate; import org.chromium.chrome.browser.vr.VrFeedbackStatus; import org.chromium.chrome.browser.vr.VrIntentDelegate; -import org.chromium.chrome.browser.vr.VrModuleProvider; import org.chromium.chrome.browser.vr.rules.ChromeTabbedActivityVrTestRule; import org.chromium.chrome.browser.vr.rules.CustomTabActivityVrTestRule; import org.chromium.chrome.browser.vr.rules.VrActivityRestrictionRule; import org.chromium.chrome.browser.vr.rules.VrModuleNotInstalled; import org.chromium.chrome.browser.vr.rules.VrTestRule; import org.chromium.chrome.browser.vr.rules.WebappActivityVrTestRule; +import org.chromium.components.module_installer.Module; import java.util.ArrayList; import java.util.concurrent.Callable; @@ -61,7 +61,7 @@ final VrTestRule rule, final ChromeLaunchMethod launcher) throws Throwable { // Should be called before any other VR methods get called. if (desc.getAnnotation(VrModuleNotInstalled.class) != null) { - VrModuleProvider.setAlwaysUseFallbackDelegate(true); + Module.setForceUninstalled("vr"); } TestVrShellDelegate.setDescription(desc);
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 268b2367..69f96c5 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -2750,15 +2750,21 @@ <message name="IDS_SET_TIME_PROMPT" desc="Text prompting the user to check and set the system time."> Chrome was unable to set the system time. Please check the time below and correct it if needed. </message> - <message name="IDS_SET_TIME_BUTTON_CLOSE" desc="Text for the button to close the window."> - Done - </message> <message name="IDS_SET_TIME_DATE_LABEL" desc="Label for the date input element."> System date </message> <message name="IDS_SET_TIME_TIME_LABEL" desc="Label for the time input element."> System time </message> + <message name="IDS_MD_SET_TIME_DATE_LABEL" desc="Label for the Material Design date input element."> + Date + </message> + <message name="IDS_MD_SET_TIME_TIME_LABEL" desc="Label for the Material Design time input element."> + Time + </message> + <message name="IDS_MD_SET_TIME_TIMEZONE_LABEL" desc="Label for the Material Design timezone select element."> + Timezone + </message> <message name="IDS_FILE_SYSTEM_REQUEST_FILE_SYSTEM_DIALOG_TITLE" desc="Title of a prompt dialog for granting permissions to a volume (eg. USB drive, SD card, MTP device) with the specified name. Only used for screen readers (a11y); not visible."> Permission requested
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 0ea08a1f..165ea5c9 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -5477,7 +5477,7 @@ </message> </if> <message name="IDS_FEEDBACK_INCLUDE_ASSISTANT_INFORMATION_CHKBOX" desc="Checkbox for including Assistant debug information in the feedback report"> - Include recent Assistant history via Sherlog. This may include your identity, location, and debug info <ph name="BEGIN_LINK"><a href="#" id="assistant-logs-info-link"></ph>Learn more<ph name="END_LINK"></a></ph> + Include recent Assistant history via Sherlog. This may include your identity, location, and debug info. <ph name="BEGIN_LINK"><a href="#" id="assistant-logs-info-link"></ph>Learn more<ph name="END_LINK"></a></ph> </message> <message name="IDS_FEEDBACK_ATTACH_FILE_NOTE" desc="Text for describing the maximum size for an attached file"> File will be sent to Google for debugging
diff --git a/chrome/app/generated_resources_grd/IDS_FEEDBACK_INCLUDE_ASSISTANT_INFORMATION_CHKBOX.png.sha1 b/chrome/app/generated_resources_grd/IDS_FEEDBACK_INCLUDE_ASSISTANT_INFORMATION_CHKBOX.png.sha1 index d251630e..59ba087 100644 --- a/chrome/app/generated_resources_grd/IDS_FEEDBACK_INCLUDE_ASSISTANT_INFORMATION_CHKBOX.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_FEEDBACK_INCLUDE_ASSISTANT_INFORMATION_CHKBOX.png.sha1
@@ -1 +1 @@ -2c9d52746631404e5a57862c489a826669ae4e2c \ No newline at end of file +411f0ae0be273eba2d989059e4d8203eddb99fca \ No newline at end of file
diff --git a/chrome/app/vr_strings_grd/OWNERS b/chrome/app/vr_strings_grdp/OWNERS similarity index 100% rename from chrome/app/vr_strings_grd/OWNERS rename to chrome/app/vr_strings_grdp/OWNERS
diff --git a/chrome/app/vr_strings_grd/README.md b/chrome/app/vr_strings_grdp/README.md similarity index 100% rename from chrome/app/vr_strings_grd/README.md rename to chrome/app/vr_strings_grdp/README.md
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 4aef7c16..d0049d2 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1038,6 +1038,8 @@ "page_load_metrics/page_load_metrics_util.h", "page_load_metrics/page_load_tracker.cc", "page_load_metrics/page_load_tracker.h", + "page_load_metrics/resource_tracker.cc", + "page_load_metrics/resource_tracker.h", "password_manager/chrome_password_manager_client.cc", "password_manager/chrome_password_manager_client.h", "password_manager/password_manager_util_linux.cc", @@ -1884,6 +1886,7 @@ "//components/language/content/browser", "//components/language/core/browser", "//components/language/core/common", + "//components/leveldb_proto", "//components/leveldb_proto/content:factory", "//components/live_tab_count_metrics", "//components/metrics:call_stack_profile_collector",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 2fef3a61..64aeef7 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -85,6 +85,7 @@ #include "components/safe_browsing/features.h" #include "components/security_state/core/features.h" #include "components/security_state/core/security_state.h" +#include "components/send_tab_to_self/features.h" #include "components/services/heap_profiling/public/cpp/switches.h" #include "components/signin/core/browser/account_reconcilor.h" #include "components/signin/core/browser/signin_buildflags.h" @@ -3849,6 +3850,11 @@ flag_descriptions::kSendTabToSelfDescription, kOsAll, FEATURE_VALUE_TYPE(switches::kSyncSendTabToSelf)}, + {"enable-send-tab-to-self-receive", + flag_descriptions::kSendTabToSelfReceiveName, + flag_descriptions::kSendTabToSelfReceiveDescription, kOsAll, + FEATURE_VALUE_TYPE(send_tab_to_self::kSendTabToSelfReceive)}, + {"enable-data-reduction-proxy-with-network-service", flag_descriptions::kEnableDataReductionProxyNetworkServiceName, flag_descriptions::kEnableDataReductionProxyNetworkServiceDescription, @@ -4055,10 +4061,12 @@ FEATURE_VALUE_TYPE(signin::kMiceFeature)}, #endif // defined(OS_ANDROID) - {"autofill-show-full-disclosure-label", - flag_descriptions::kAutofillShowFullDisclosureLabelName, - flag_descriptions::kAutofillShowFullDisclosureLabelDescription, kOsAll, - FEATURE_VALUE_TYPE(autofill::features::kAutofillShowFullDisclosureLabel)}, + {"autofill-use-improved-label-disambiguation", + flag_descriptions::kAutofillUseImprovedLabelDisambiguationName, + flag_descriptions::kAutofillUseImprovedLabelDisambiguationDescription, + kOsAll, + FEATURE_VALUE_TYPE( + autofill::features::kAutofillUseImprovedLabelDisambiguation)}, #if defined(OS_CHROMEOS) {"ash-notification-stacking-bar-redesign",
diff --git a/chrome/browser/accessibility/image_annotation_browsertest.cc b/chrome/browser/accessibility/image_annotation_browsertest.cc index 7efa8be..ffc76bc 100644 --- a/chrome/browser/accessibility/image_annotation_browsertest.cc +++ b/chrome/browser/accessibility/image_annotation_browsertest.cc
@@ -64,6 +64,12 @@ // API. class FakeAnnotator : public image_annotation::mojom::Annotator { public: + static void SetReturnOcrResults(bool ocr) { return_ocr_results_ = ocr; } + + static void SetReturnLabelResults(bool label) { + return_label_results_ = label; + } + FakeAnnotator() = default; ~FakeAnnotator() override = default; @@ -88,10 +94,12 @@ image_annotation::mojom::AnnotationType::kLabel, 1.0, image_filename + " Label"); - // Return that result as an annotation. + // Return enabled results as an annotation. std::vector<image_annotation::mojom::AnnotationPtr> annotations; - annotations.push_back(std::move(ocr_annotation)); - annotations.push_back(std::move(label_annotation)); + if (return_ocr_results_) + annotations.push_back(std::move(ocr_annotation)); + if (return_label_results_) + annotations.push_back(std::move(label_annotation)); image_annotation::mojom::AnnotateImageResultPtr result = image_annotation::mojom::AnnotateImageResult::NewAnnotations( @@ -101,10 +109,17 @@ private: mojo::BindingSet<image_annotation::mojom::Annotator> bindings_; + static bool return_ocr_results_; + static bool return_label_results_; DISALLOW_COPY_AND_ASSIGN(FakeAnnotator); }; +// static +bool FakeAnnotator::return_ocr_results_ = false; +// static +bool FakeAnnotator::return_label_results_ = false; + // The fake ImageAnnotationService, which handles mojo calls from the renderer // process and passes them to FakeAnnotator. class FakeImageAnnotationService : public service_manager::Service { @@ -190,6 +205,8 @@ IN_PROC_BROWSER_TEST_F(ImageAnnotationBrowserTest, AnnotateImageInAccessibilityTree) { + FakeAnnotator::SetReturnOcrResults(true); + FakeAnnotator::SetReturnLabelResults(true); ui_test_utils::NavigateToURL(browser(), https_server_.GetURL("/image_annotation.html")); @@ -201,23 +218,25 @@ "Appears to say: red.png Annotation. Appears to be: red.png Label"); } -// http://crbug.com/940043 -IN_PROC_BROWSER_TEST_F(ImageAnnotationBrowserTest, DISABLED_ImagesInLinks) { +IN_PROC_BROWSER_TEST_F(ImageAnnotationBrowserTest, ImagesInLinks) { + FakeAnnotator::SetReturnOcrResults(true); ui_test_utils::NavigateToURL( browser(), https_server_.GetURL("/image_annotation_link.html")); + // Block until the accessibility tree has at least 8 annotations. If + // that never happens, the test will time out. content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - - content::WaitForAccessibilityTreeToContainNodeWithName( - web_contents, "Appears to say: red.png Annotation"); - - ui::AXTreeUpdate ax_tree_update = - content::GetAccessibilityTreeSnapshot(web_contents); + while (8 > DescribeNodesWithAnnotations( + content::GetAccessibilityTreeSnapshot(web_contents)) + .size()) { + content::WaitForAccessibilityTreeToChange(web_contents); + } // All images should be annotated. Only links that contain exactly one image // should be annotated. - + ui::AXTreeUpdate ax_tree_update = + content::GetAccessibilityTreeSnapshot(web_contents); EXPECT_THAT( DescribeNodesWithAnnotations(ax_tree_update), testing::ElementsAre("image Appears to say: red.png Annotation", @@ -230,22 +249,25 @@ "image Appears to say: printer.png Annotation")); } -// http://crbug.com/940043 -IN_PROC_BROWSER_TEST_F(ImageAnnotationBrowserTest, DISABLED_ImageDoc) { +IN_PROC_BROWSER_TEST_F(ImageAnnotationBrowserTest, ImageDoc) { + FakeAnnotator::SetReturnOcrResults(true); ui_test_utils::NavigateToURL( browser(), https_server_.GetURL("/image_annotation_doc.html")); + // Block until the accessibility tree has at least 2 annotations. If + // that never happens, the test will time out. content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - - content::WaitForAccessibilityTreeToContainNodeWithName( - web_contents, "Appears to say: red.png Annotation"); - - ui::AXTreeUpdate ax_tree_update = - content::GetAccessibilityTreeSnapshot(web_contents); + while (2 > DescribeNodesWithAnnotations( + content::GetAccessibilityTreeSnapshot(web_contents)) + .size()) { + content::WaitForAccessibilityTreeToChange(web_contents); + } // When a document contains exactly one image, the document should be // annotated with the image's annotation, too. + ui::AXTreeUpdate ax_tree_update = + content::GetAccessibilityTreeSnapshot(web_contents); EXPECT_THAT( DescribeNodesWithAnnotations(ax_tree_update), testing::ElementsAre("rootWebArea Appears to say: red.png Annotation",
diff --git a/chrome/browser/android/usage_stats/usage_stats_database.cc b/chrome/browser/android/usage_stats/usage_stats_database.cc index 3ddb64e7..07b4ec8 100644 --- a/chrome/browser/android/usage_stats/usage_stats_database.cc +++ b/chrome/browser/android/usage_stats/usage_stats_database.cc
@@ -39,8 +39,8 @@ suspension_db_initialized_(false), token_mapping_db_initialized_(false), weak_ptr_factory_(this) { - ProtoDatabaseProvider* db_provider = - ProtoDatabaseProviderFactory::GetForBrowserContext(profile); + ProtoDatabaseProvider* db_provider = ProtoDatabaseProviderFactory::GetForKey( + profile->GetSimpleFactoryKey(), profile->GetPrefs()); base::FilePath usage_stats_dir = profile->GetPath().Append(kNamespace);
diff --git a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc index 1be1250..13e7609b 100644 --- a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc +++ b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc
@@ -117,8 +117,8 @@ InstallableManager* installable_manager = InstallableManager::FromWebContents(web_contents()); installable_manager->GetData( - params, base::Bind(&WebApkUpdateDataFetcher::OnDidGetInstallableData, - weak_ptr_factory_.GetWeakPtr())); + params, base::BindOnce(&WebApkUpdateDataFetcher::OnDidGetInstallableData, + weak_ptr_factory_.GetWeakPtr())); } void WebApkUpdateDataFetcher::OnDidGetInstallableData(
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc index aa940ddb..9409cb8b 100644 --- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc +++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
@@ -187,8 +187,8 @@ installable_manager_->GetData( ParamsToPerformManifestAndIconFetch(), - base::Bind(&AddToHomescreenDataFetcher::OnDidGetManifestAndIcons, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&AddToHomescreenDataFetcher::OnDidGetManifestAndIcons, + weak_ptr_factory_.GetWeakPtr())); } void AddToHomescreenDataFetcher::StopTimer() { @@ -259,8 +259,8 @@ installable_manager_->GetData( ParamsToPerformInstallableCheck(), - base::Bind(&AddToHomescreenDataFetcher::OnDidPerformInstallableCheck, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&AddToHomescreenDataFetcher::OnDidPerformInstallableCheck, + weak_ptr_factory_.GetWeakPtr())); } void AddToHomescreenDataFetcher::OnDidPerformInstallableCheck(
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc index 655589c..93e03f02 100644 --- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc +++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
@@ -133,7 +133,7 @@ // data fetcher. We manually call the metrics logging method which is normally // called by the superclass method. void GetData(const InstallableParams& params, - const InstallableCallback& callback) override { + InstallableCallback callback) override { metrics_->Start(); InstallableStatusCode code = NO_ERROR_DETECTED; @@ -159,8 +159,8 @@ // and isn't called (corresponding to InstallableManager finishing work // after the timeout, and when it never finishes at all). queued_metrics_callback_ = - base::Bind(&InstallableManager::ResolveMetrics, - base::Unretained(this), params, is_installable); + base::BindOnce(&InstallableManager::ResolveMetrics, + base::Unretained(this), params, is_installable); return; } @@ -171,14 +171,15 @@ std::vector<InstallableStatusCode> errors; if (code != NO_ERROR_DETECTED) errors.push_back(code); - callback.Run({std::move(errors), GURL(kDefaultManifestUrl), &manifest_, - params.valid_primary_icon ? primary_icon_url_ : GURL(), - params.valid_primary_icon ? primary_icon_.get() : nullptr, - params.prefer_maskable_icon, - params.valid_badge_icon ? badge_icon_url_ : GURL(), - params.valid_badge_icon ? badge_icon_.get() : nullptr, - params.valid_manifest ? is_installable : false, - params.has_worker ? is_installable : false}); + std::move(callback).Run( + {std::move(errors), GURL(kDefaultManifestUrl), &manifest_, + params.valid_primary_icon ? primary_icon_url_ : GURL(), + params.valid_primary_icon ? primary_icon_.get() : nullptr, + params.prefer_maskable_icon, + params.valid_badge_icon ? badge_icon_url_ : GURL(), + params.valid_badge_icon ? badge_icon_.get() : nullptr, + params.valid_manifest ? is_installable : false, + params.has_worker ? is_installable : false}); } void SetInstallable(bool is_installable) { is_installable_ = is_installable; }
diff --git a/chrome/browser/apps/app_service/app_icon_source.cc b/chrome/browser/apps/app_service/app_icon_source.cc index 88ae25b4..90cb9b3 100644 --- a/chrome/browser/apps/app_service/app_icon_source.cc +++ b/chrome/browser/apps/app_service/app_icon_source.cc
@@ -97,10 +97,12 @@ return; } + const apps::mojom::AppType app_type = + app_service_proxy->AppRegistryCache().GetAppType(app_id); constexpr bool allow_placeholder_icon = false; - app_service_proxy->LoadIcon(app_id, apps::mojom::IconCompression::kCompressed, - size_in_dip, allow_placeholder_icon, - base::BindOnce(&RunCallback, callback)); + app_service_proxy->LoadIcon( + app_type, app_id, apps::mojom::IconCompression::kCompressed, size_in_dip, + allow_placeholder_icon, base::BindOnce(&RunCallback, callback)); } } // namespace apps
diff --git a/chrome/browser/apps/app_service/app_service_proxy.cc b/chrome/browser/apps/app_service/app_service_proxy.cc index d512411..5b5b2f25 100644 --- a/chrome/browser/apps/app_service/app_service_proxy.cc +++ b/chrome/browser/apps/app_service/app_service_proxy.cc
@@ -36,6 +36,8 @@ std::unique_ptr<IconLoader::Releaser> AppServiceProxy::InnerIconLoader::LoadIconFromIconKey( + apps::mojom::AppType app_type, + const std::string& app_id, apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, @@ -43,8 +45,8 @@ apps::mojom::Publisher::LoadIconCallback callback) { if (overriding_icon_loader_for_testing_) { return overriding_icon_loader_for_testing_->LoadIconFromIconKey( - std::move(icon_key), icon_compression, size_hint_in_dip, - allow_placeholder_icon, std::move(callback)); + app_type, app_id, std::move(icon_key), icon_compression, + size_hint_in_dip, allow_placeholder_icon, std::move(callback)); } if (host_->app_service_.is_bound() && icon_key) { @@ -57,9 +59,9 @@ // for the app and app requested new icon. But new icon is not delivered // yet and you resolve old one instead. Now new icon arrives asynchronously // but you no longer notify the app or do?" - host_->app_service_->LoadIcon(std::move(icon_key), icon_compression, - size_hint_in_dip, allow_placeholder_icon, - std::move(callback)); + host_->app_service_->LoadIcon(app_type, app_id, std::move(icon_key), + icon_compression, size_hint_in_dip, + allow_placeholder_icon, std::move(callback)); } else { std::move(callback).Run(apps::mojom::IconValue::New()); } @@ -121,13 +123,15 @@ std::unique_ptr<apps::IconLoader::Releaser> AppServiceProxy::LoadIconFromIconKey( + apps::mojom::AppType app_type, + const std::string& app_id, apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::mojom::Publisher::LoadIconCallback callback) { return outer_icon_loader_.LoadIconFromIconKey( - std::move(icon_key), icon_compression, size_hint_in_dip, + app_type, app_id, std::move(icon_key), icon_compression, size_hint_in_dip, allow_placeholder_icon, std::move(callback)); }
diff --git a/chrome/browser/apps/app_service/app_service_proxy.h b/chrome/browser/apps/app_service/app_service_proxy.h index 0cb5c4a1..def5552a 100644 --- a/chrome/browser/apps/app_service/app_service_proxy.h +++ b/chrome/browser/apps/app_service/app_service_proxy.h
@@ -48,6 +48,8 @@ // apps::IconLoader overrides. apps::mojom::IconKeyPtr GetIconKey(const std::string& app_id) override; std::unique_ptr<IconLoader::Releaser> LoadIconFromIconKey( + apps::mojom::AppType app_type, + const std::string& app_id, apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, @@ -114,6 +116,8 @@ // apps::IconLoader overrides. apps::mojom::IconKeyPtr GetIconKey(const std::string& app_id) override; std::unique_ptr<IconLoader::Releaser> LoadIconFromIconKey( + apps::mojom::AppType app_type, + const std::string& app_id, apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip,
diff --git a/chrome/browser/apps/app_service/app_service_proxy_unittest.cc b/chrome/browser/apps/app_service/app_service_proxy_unittest.cc index e7f2d7f..cfad9c2 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_unittest.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_unittest.cc
@@ -36,11 +36,12 @@ private: apps::mojom::IconKeyPtr GetIconKey(const std::string& app_id) override { - return apps::mojom::IconKey::New(apps::mojom::AppType::kWeb, app_id, 0, 0, - 0); + return apps::mojom::IconKey::New(0, 0, 0); } std::unique_ptr<Releaser> LoadIconFromIconKey( + apps::mojom::AppType app_type, + const std::string& app_id, apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, @@ -57,13 +58,14 @@ }; UniqueReleaser LoadIcon(apps::IconLoader* loader, const std::string& app_id) { + static constexpr auto app_type = apps::mojom::AppType::kWeb; static constexpr auto icon_compression = apps::mojom::IconCompression::kUncompressed; static constexpr int32_t size_hint_in_dip = 1; static bool allow_placeholder_icon = false; - return loader->LoadIcon(app_id, icon_compression, size_hint_in_dip, - allow_placeholder_icon, + return loader->LoadIcon(app_type, app_id, icon_compression, + size_hint_in_dip, allow_placeholder_icon, base::BindOnce(&AppServiceProxyTest::OnLoadIcon, base::Unretained(this))); }
diff --git a/chrome/browser/apps/app_service/arc_apps.cc b/chrome/browser/apps/app_service/arc_apps.cc index 2628edc..5b2cdc4 100644 --- a/chrome/browser/apps/app_service/arc_apps.cc +++ b/chrome/browser/apps/app_service/arc_apps.cc
@@ -195,7 +195,8 @@ subscribers_.AddPtr(std::move(subscriber)); } -void ArcApps::LoadIcon(apps::mojom::IconKeyPtr icon_key, +void ArcApps::LoadIcon(const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon, @@ -207,7 +208,7 @@ // the Play Store icon (the UI for enabling and installing Android apps) // should be showable even before the user has installed their first // Android app and before bringing up an Android VM for the first time. - if (icon_key->app_id == arc::kPlayStoreAppId) { + if (app_id == arc::kPlayStoreAppId) { LoadPlayStoreIcon(icon_compression, size_hint_in_dip, static_cast<IconEffects>(icon_key->icon_effects), std::move(callback)); @@ -218,10 +219,10 @@ // LoadIconFromVM. LoadIconFromFileWithFallback( icon_compression, size_hint_in_dip, - GetCachedIconFilePath(icon_key->app_id, size_hint_in_dip), + GetCachedIconFilePath(app_id, size_hint_in_dip), static_cast<IconEffects>(icon_key->icon_effects), std::move(callback), base::BindOnce(&ArcApps::LoadIconFromVM, weak_ptr_factory_.GetWeakPtr(), - icon_key->app_id, icon_compression, size_hint_in_dip, + app_id, icon_compression, size_hint_in_dip, allow_placeholder_icon, static_cast<IconEffects>(icon_key->icon_effects))); return; @@ -359,8 +360,7 @@ apps::mojom::AppPtr app = apps::mojom::App::New(); app->app_type = apps::mojom::AppType::kArc; app->app_id = app_id; - app->icon_key = icon_key_factory_.MakeIconKey(apps::mojom::AppType::kArc, - app_id, icon_effects); + app->icon_key = icon_key_factory_.MakeIconKey(icon_effects); Publish(std::move(app)); } @@ -476,8 +476,7 @@ app->short_name = app->name; static constexpr uint32_t icon_effects = 0; - app->icon_key = icon_key_factory_.MakeIconKey(apps::mojom::AppType::kArc, - app_id, icon_effects); + app->icon_key = icon_key_factory_.MakeIconKey(icon_effects); app->last_launch_time = app_info.last_launch_time; app->install_time = app_info.install_time;
diff --git a/chrome/browser/apps/app_service/arc_apps.h b/chrome/browser/apps/app_service/arc_apps.h index 70f209b0..6577f13 100644 --- a/chrome/browser/apps/app_service/arc_apps.h +++ b/chrome/browser/apps/app_service/arc_apps.h
@@ -46,7 +46,8 @@ // apps::mojom::Publisher overrides. void Connect(apps::mojom::SubscriberPtr subscriber, apps::mojom::ConnectOptionsPtr opts) override; - void LoadIcon(apps::mojom::IconKeyPtr icon_key, + void LoadIcon(const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon,
diff --git a/chrome/browser/apps/app_service/built_in_chromeos_apps.cc b/chrome/browser/apps/app_service/built_in_chromeos_apps.cc index cc4ab993..79eb234 100644 --- a/chrome/browser/apps/app_service/built_in_chromeos_apps.cc +++ b/chrome/browser/apps/app_service/built_in_chromeos_apps.cc
@@ -39,7 +39,7 @@ } app->icon_key = apps::mojom::IconKey::New( - apps::mojom::AppType::kBuiltIn, internal_app.app_id, 0, + apps::mojom::IconKey::kDoesNotChangeOverTime, internal_app.icon_resource_id, apps::IconEffects::kNone); app->last_launch_time = base::Time(); @@ -111,6 +111,7 @@ } void BuiltInChromeOsApps::LoadIcon( + const std::string& app_id, apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip,
diff --git a/chrome/browser/apps/app_service/built_in_chromeos_apps.h b/chrome/browser/apps/app_service/built_in_chromeos_apps.h index 41360057..232c261 100644 --- a/chrome/browser/apps/app_service/built_in_chromeos_apps.h +++ b/chrome/browser/apps/app_service/built_in_chromeos_apps.h
@@ -30,7 +30,8 @@ // apps::mojom::Publisher overrides. void Connect(apps::mojom::SubscriberPtr subscriber, apps::mojom::ConnectOptionsPtr opts) override; - void LoadIcon(apps::mojom::IconKeyPtr icon_key, + void LoadIcon(const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon,
diff --git a/chrome/browser/apps/app_service/crostini_apps.cc b/chrome/browser/apps/app_service/crostini_apps.cc index b424eccb..9e189ff0 100644 --- a/chrome/browser/apps/app_service/crostini_apps.cc +++ b/chrome/browser/apps/app_service/crostini_apps.cc
@@ -60,7 +60,8 @@ subscribers_.AddPtr(std::move(subscriber)); } -void CrostiniApps::LoadIcon(apps::mojom::IconKeyPtr icon_key, +void CrostiniApps::LoadIcon(const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon, @@ -81,10 +82,10 @@ // to LoadIconFromVM. LoadIconFromFileWithFallback( icon_compression, size_hint_in_dip, - registry_->GetIconPath(icon_key->app_id, scale_factor), + registry_->GetIconPath(app_id, scale_factor), static_cast<IconEffects>(icon_key->icon_effects), std::move(callback), base::BindOnce(&CrostiniApps::LoadIconFromVM, - weak_ptr_factory_.GetWeakPtr(), icon_key->app_id, + weak_ptr_factory_.GetWeakPtr(), app_id, icon_compression, size_hint_in_dip, allow_placeholder_icon, scale_factor, static_cast<IconEffects>(icon_key->icon_effects))); @@ -218,8 +219,6 @@ apps::mojom::IconKeyPtr CrostiniApps::NewIconKey(const std::string& app_id) { DCHECK(!app_id.empty()); - static constexpr uint32_t icon_effects = 0; - // Treat the Crostini Terminal as a special case, loading an icon defined by // a resource instead of asking the Crostini VM (or the cache of previous // responses from the Crostini VM). Presumably this is for bootstrapping: the @@ -227,12 +226,12 @@ // should be showable even before the user has installed their first Crostini // app and before bringing up an Crostini VM for the first time. if (app_id == crostini::kCrostiniTerminalId) { - return apps::mojom::IconKey::New(apps::mojom::AppType::kCrostini, app_id, 0, - IDR_LOGO_CROSTINI_TERMINAL, icon_effects); + return apps::mojom::IconKey::New( + apps::mojom::IconKey::kDoesNotChangeOverTime, + IDR_LOGO_CROSTINI_TERMINAL, apps::IconEffects::kNone); } - return icon_key_factory_.MakeIconKey(apps::mojom::AppType::kCrostini, app_id, - icon_effects); + return icon_key_factory_.MakeIconKey(apps::IconEffects::kNone); } void CrostiniApps::PublishAppID(const std::string& app_id,
diff --git a/chrome/browser/apps/app_service/crostini_apps.h b/chrome/browser/apps/app_service/crostini_apps.h index 2e2676d..79fe8da 100644 --- a/chrome/browser/apps/app_service/crostini_apps.h +++ b/chrome/browser/apps/app_service/crostini_apps.h
@@ -45,7 +45,8 @@ // apps::mojom::Publisher overrides. void Connect(apps::mojom::SubscriberPtr subscriber, apps::mojom::ConnectOptionsPtr opts) override; - void LoadIcon(apps::mojom::IconKeyPtr icon_key, + void LoadIcon(const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon,
diff --git a/chrome/browser/apps/app_service/extension_apps.cc b/chrome/browser/apps/app_service/extension_apps.cc index a4d89e1..fbcc70a1 100644 --- a/chrome/browser/apps/app_service/extension_apps.cc +++ b/chrome/browser/apps/app_service/extension_apps.cc
@@ -125,15 +125,16 @@ subscribers_.AddPtr(std::move(subscriber)); } -void ExtensionApps::LoadIcon(apps::mojom::IconKeyPtr icon_key, +void ExtensionApps::LoadIcon(const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon, LoadIconCallback callback) { if (icon_key) { - LoadIconFromExtension( - icon_compression, size_hint_in_dip, profile_, icon_key->app_id, - static_cast<IconEffects>(icon_key->icon_effects), std::move(callback)); + LoadIconFromExtension(icon_compression, size_hint_in_dip, profile_, app_id, + static_cast<IconEffects>(icon_key->icon_effects), + std::move(callback)); return; } // On failure, we still run the callback, with the zero IconValue. @@ -440,8 +441,7 @@ icon_effects = static_cast<IconEffects>(icon_effects | IconEffects::kRoundCorners); } - app->icon_key = - icon_key_factory_.MakeIconKey(app_type_, extension->id(), icon_effects); + app->icon_key = icon_key_factory_.MakeIconKey(icon_effects); if (profile_) { auto* prefs = extensions::ExtensionPrefs::Get(profile_);
diff --git a/chrome/browser/apps/app_service/extension_apps.h b/chrome/browser/apps/app_service/extension_apps.h index cdf54ef..76ef9819 100644 --- a/chrome/browser/apps/app_service/extension_apps.h +++ b/chrome/browser/apps/app_service/extension_apps.h
@@ -51,7 +51,8 @@ // apps::mojom::Publisher overrides. void Connect(apps::mojom::SubscriberPtr subscriber, apps::mojom::ConnectOptionsPtr opts) override; - void LoadIcon(apps::mojom::IconKeyPtr icon_key, + void LoadIcon(const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon,
diff --git a/chrome/browser/apps/app_service/icon_key_util.cc b/chrome/browser/apps/app_service/icon_key_util.cc index 7c22ca6..58c03c0 100644 --- a/chrome/browser/apps/app_service/icon_key_util.cc +++ b/chrome/browser/apps/app_service/icon_key_util.cc
@@ -9,12 +9,9 @@ IncrementingIconKeyFactory::IncrementingIconKeyFactory() : last_timeline_(0) {} apps::mojom::IconKeyPtr IncrementingIconKeyFactory::MakeIconKey( - apps::mojom::AppType app_type, - const std::string& app_id, uint32_t icon_effects) { - return apps::mojom::IconKey::New(app_type, app_id, ++last_timeline_, - apps::mojom::IconKey::kInvalidResourceId, - icon_effects); + return apps::mojom::IconKey::New( + ++last_timeline_, apps::mojom::IconKey::kInvalidResourceId, icon_effects); } } // namespace apps_util
diff --git a/chrome/browser/apps/app_service/icon_key_util.h b/chrome/browser/apps/app_service/icon_key_util.h index 958386b0..b79c204 100644 --- a/chrome/browser/apps/app_service/icon_key_util.h +++ b/chrome/browser/apps/app_service/icon_key_util.h
@@ -29,9 +29,7 @@ public: IncrementingIconKeyFactory(); - apps::mojom::IconKeyPtr MakeIconKey(apps::mojom::AppType app_type, - const std::string& app_id, - uint32_t icon_effects); + apps::mojom::IconKeyPtr MakeIconKey(uint32_t icon_effects); private: uint64_t last_timeline_;
diff --git a/chrome/browser/banners/app_banner_manager.cc b/chrome/browser/banners/app_banner_manager.cc index 99911c3..b89384a0 100644 --- a/chrome/browser/banners/app_banner_manager.cc +++ b/chrome/browser/banners/app_banner_manager.cc
@@ -165,22 +165,11 @@ namespace banners { -void AppBannerManager::RequestAppBanner(const GURL& validated_url, - bool is_debug_mode) { - // The only time we should start the pipeline while it is already running is - // if it's been triggered from devtools. - if (state_ != State::INACTIVE) { - DCHECK(is_debug_mode); - weak_factory_.InvalidateWeakPtrs(); - ResetBindings(); - } +void AppBannerManager::RequestAppBanner(const GURL& validated_url) { + DCHECK_EQ(State::INACTIVE, state_); UpdateState(State::ACTIVE); - triggered_by_devtools_ = is_debug_mode; - - // We only need to use TrackingStatusReporter if we aren't in debug mode - // (this avoids skew from testing). - if (IsDebugMode()) + if (ShouldBypassEngagementChecks()) status_reporter_ = std::make_unique<ConsoleStatusReporter>(web_contents()); else status_reporter_ = std::make_unique<TrackingStatusReporter>(); @@ -191,7 +180,7 @@ UpdateState(State::FETCHING_MANIFEST); manager_->GetData( ParamsToGetManifest(), - base::Bind(&AppBannerManager::OnDidGetManifest, GetWeakPtr())); + base::BindOnce(&AppBannerManager::OnDidGetManifest, GetWeakPtr())); } void AppBannerManager::OnInstall(bool is_native, @@ -243,7 +232,6 @@ binding_(this), has_sufficient_engagement_(false), load_finished_(false), - triggered_by_devtools_(false), status_reporter_(std::make_unique<NullStatusReporter>()), install_animation_pending_(false), installable_(Installable::UNKNOWN), @@ -256,7 +244,7 @@ AppBannerManager::~AppBannerManager() { } bool AppBannerManager::CheckIfShouldShowBanner() { - if (IsDebugMode()) + if (ShouldBypassEngagementChecks()) return true; InstallableStatusCode code = ShouldShowBannerCode(); @@ -298,13 +286,12 @@ bool AppBannerManager::HasSufficientEngagement() const { - return has_sufficient_engagement_ || IsDebugMode(); + return has_sufficient_engagement_ || ShouldBypassEngagementChecks(); } -bool AppBannerManager::IsDebugMode() const { - return triggered_by_devtools_ || - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kBypassAppBannerEngagementChecks); +bool AppBannerManager::ShouldBypassEngagementChecks() const { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kBypassAppBannerEngagementChecks); } bool AppBannerManager::IsWebAppConsideredInstalled( @@ -336,8 +323,7 @@ params.valid_primary_icon = true; params.valid_manifest = true; params.has_worker = true; - // Don't wait for the service worker if this was triggered from devtools. - params.wait_for_worker = !triggered_by_devtools_; + params.wait_for_worker = true; return params; } @@ -348,9 +334,10 @@ // Fetch and verify the other required information. UpdateState(State::PENDING_INSTALLABLE_CHECK); - manager_->GetData(ParamsToPerformInstallableCheck(), - base::Bind(&AppBannerManager::OnDidPerformInstallableCheck, - GetWeakPtr())); + manager_->GetData( + ParamsToPerformInstallableCheck(), + base::BindOnce(&AppBannerManager::OnDidPerformInstallableCheck, + GetWeakPtr())); } void AppBannerManager::OnDidPerformInstallableCheck( @@ -428,9 +415,10 @@ } void AppBannerManager::Terminate() { - if (state_ == State::PENDING_PROMPT) + if (state_ == State::PENDING_PROMPT) { TrackBeforeInstallEvent( BEFORE_INSTALL_EVENT_PROMPT_NOT_CALLED_AFTER_PREVENT_DEFAULT); + } if (state_ == State::PENDING_ENGAGEMENT && !has_sufficient_engagement_) TrackDisplayEvent(DISPLAY_EVENT_NOT_VISITED_ENOUGH); @@ -563,7 +551,7 @@ // or if the experimental app banners feature is active. if (state_ == State::INACTIVE && (has_sufficient_engagement_ || IsExperimentalAppBannersEnabled())) { - RequestAppBanner(validated_url, false /* is_debug_mode */); + RequestAppBanner(validated_url); } } @@ -605,7 +593,7 @@ // This performs some simple tests and starts async checks to test // installability. It should be safe to start in response to user input. // Don't call if we're already working on processing a banner request. - RequestAppBanner(url, false /* is_debug_mode */); + RequestAppBanner(url); } } } @@ -704,7 +692,7 @@ // the banner immediately. if (reply == blink::mojom::AppBannerPromptReply::CANCEL) { TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_PREVENT_DEFAULT_CALLED); - if (IsDebugMode()) { + if (ShouldBypassEngagementChecks()) { web_contents()->GetMainFrame()->AddMessageToConsole( blink::mojom::ConsoleMessageLevel::kInfo, "Banner not shown: beforeinstallpromptevent.preventDefault() called. "
diff --git a/chrome/browser/banners/app_banner_manager.h b/chrome/browser/banners/app_banner_manager.h index ec0d45a..de5c54a 100644 --- a/chrome/browser/banners/app_banner_manager.h +++ b/chrome/browser/banners/app_banner_manager.h
@@ -152,9 +152,8 @@ // this returns and consumes the animation prompt if it is available. bool MaybeConsumeInstallAnimation(); - // Requests an app banner. If |is_debug_mode| is true, any failure in the - // pipeline will be reported to the devtools console. - virtual void RequestAppBanner(const GURL& validated_url, bool is_debug_mode); + // Requests an app banner. + virtual void RequestAppBanner(const GURL& validated_url); // Informs the page that it has been installed with appinstalled event and // performs logging related to the app installation. Appinstalled event is @@ -223,13 +222,12 @@ // alerting websites that a banner is about to be created. virtual std::string GetBannerType(); - // Returns true if |has_sufficient_engagement_| is true or IsDebugMode() - // returns true. + // Returns true if |has_sufficient_engagement_| is true or + // ShouldBypassEngagementChecks() returns true. bool HasSufficientEngagement() const; - // Returns true if |triggered_by_devtools_| is true or the - // kBypassAppBannerEngagementChecks flag is set. - bool IsDebugMode() const; + // Returns true if the kBypassAppBannerEngagementChecks flag is set. + bool ShouldBypassEngagementChecks() const; // Returns true if the webapp at |start_url| has already been installed, or // should be considered installed. On Android, we rely on a heuristic that @@ -387,9 +385,6 @@ bool has_sufficient_engagement_; bool load_finished_; - // Whether the current flow was begun via devtools. - bool triggered_by_devtools_; - std::unique_ptr<StatusReporter> status_reporter_; bool install_animation_pending_; Installable installable_;
diff --git a/chrome/browser/banners/app_banner_manager_android.cc b/chrome/browser/banners/app_banner_manager_android.cc index ce87de2..efb53ae 100644 --- a/chrome/browser/banners/app_banner_manager_android.cc +++ b/chrome/browser/banners/app_banner_manager_android.cc
@@ -116,13 +116,12 @@ base::BindOnce(&AppBannerManager::OnAppIconFetched, GetWeakPtr())); } -void AppBannerManagerAndroid::RequestAppBanner(const GURL& validated_url, - bool is_debug_mode) { +void AppBannerManagerAndroid::RequestAppBanner(const GURL& validated_url) { JNIEnv* env = base::android::AttachCurrentThread(); if (!Java_AppBannerManager_isEnabledForTab(env, java_banner_manager_)) return; - AppBannerManager::RequestAppBanner(validated_url, is_debug_mode); + AppBannerManager::RequestAppBanner(validated_url); } void AppBannerManagerAndroid::SendBannerDismissed() {
diff --git a/chrome/browser/banners/app_banner_manager_android.h b/chrome/browser/banners/app_banner_manager_android.h index 626d9d4..4724834 100644 --- a/chrome/browser/banners/app_banner_manager_android.h +++ b/chrome/browser/banners/app_banner_manager_android.h
@@ -83,7 +83,7 @@ const base::android::JavaParamRef<jstring>& jicon_url); // AppBannerManager overrides. - void RequestAppBanner(const GURL& validated_url, bool is_debug_mode) override; + void RequestAppBanner(const GURL& validated_url) override; void SendBannerDismissed() override; // InstallableAmbientBadgeInfoBarAndroid::Client overrides.
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc index dc534bc..fcfe838 100644 --- a/chrome/browser/banners/app_banner_manager_browsertest.cc +++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -42,14 +42,13 @@ ~AppBannerManagerTest() override {} - void RequestAppBanner(const GURL& validated_url, - bool is_debug_mode) override { + void RequestAppBanner(const GURL& validated_url) override { // Filter out about:blank navigations - we use these in testing to force // Stop() to be called. if (validated_url == GURL("about:blank")) return; - AppBannerManager::RequestAppBanner(validated_url, is_debug_mode); + AppBannerManager::RequestAppBanner(validated_url); } bool banner_shown() { return banner_shown_.get() && *banner_shown_; } @@ -667,33 +666,4 @@ SHOWING_WEB_APP_BANNER, 1); } -IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest, OverlappingDebugRequest) { - base::HistogramTester histograms; - GURL test_url = GetBannerURL(); - SiteEngagementService* service = - SiteEngagementService::Get(browser()->profile()); - service->ResetBaseScoreForURL(test_url, 10); - - ui_test_utils::NavigateToURL(browser(), test_url); - - std::unique_ptr<AppBannerManagerTest> manager( - CreateAppBannerManager(browser())); - base::RunLoop run_loop; - manager->PrepareDone(run_loop.QuitClosure()); - - // Call RequestAppBanner to start the pipeline, then call it again in debug - // mode to ensure that this doesn't fail. - manager->RequestAppBanner(test_url, false); - EXPECT_EQ(State::FETCHING_MANIFEST, manager->state()); - manager->RequestAppBanner(test_url, true); - run_loop.Run(); - - EXPECT_TRUE(manager->banner_shown()); - EXPECT_EQ(WebappInstallSource::DEVTOOLS, manager->install_source()); - EXPECT_EQ(State::COMPLETE, manager->state()); - - // Ensure that we do not record any histograms. - histograms.ExpectTotalCount(banners::kInstallableStatusCodeHistogram, 0); -} - } // namespace banners
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 1b8a8ef4..2ce84fe 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -837,7 +837,7 @@ ui_thread_profiler_->SetMainThreadTaskRunner( base::ThreadTaskRunnerHandle::Get()); - heap_profiler_controller_->StartIfEnabled(); + heap_profiler_controller_->Start(); system_monitor_ = performance_monitor::SystemMonitor::Create();
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 34d0bdf6..aaab785 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2281,11 +2281,12 @@ bool ChromeContentBrowserClient::IsDataSaverEnabled( content::BrowserContext* browser_context) { - Profile* profile = Profile::FromBrowserContext(browser_context); - if (!profile) - return false; - PrefService* prefs = profile->GetPrefs(); - return prefs && prefs->GetBoolean(prefs::kDataSaverEnabled); + data_reduction_proxy::DataReductionProxySettings* + data_reduction_proxy_settings = + DataReductionProxyChromeSettingsFactory::GetForBrowserContext( + browser_context); + return data_reduction_proxy_settings && + data_reduction_proxy_settings->IsDataSaverEnabledByUser(); } void ChromeContentBrowserClient::UpdateRendererPreferencesForWorker(
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc index 829911f..1f88cc14 100644 --- a/chrome/browser/chrome_content_browser_client_unittest.cc +++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -132,14 +132,6 @@ *target_contents = opened_contents; } -TEST_F(ChromeContentBrowserClientWindowTest, IsDataSaverEnabled) { - ChromeContentBrowserClient client; - content::BrowserContext* context = browser()->profile(); - EXPECT_FALSE(client.IsDataSaverEnabled(context)); - browser()->profile()->GetPrefs()->SetBoolean(prefs::kDataSaverEnabled, true); - EXPECT_TRUE(client.IsDataSaverEnabled(context)); -} - // This test opens two URLs using ContentBrowserClient::OpenURL. It expects the // URLs to be opened in new tabs and activated, changing the active tabs after // each call and increasing the tab count by 2.
diff --git a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc index 66a8dd76..361a87f 100644 --- a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc +++ b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc
@@ -28,7 +28,6 @@ #include "chromeos/components/account_manager/account_manager_factory.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/dbus/auth_policy/auth_policy_client.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" @@ -86,7 +85,7 @@ // Connecting to the signal sent by authpolicyd notifying that Kerberos files // have changed. - DBusThreadManager::Get()->GetAuthPolicyClient()->ConnectToSignal( + AuthPolicyClient::Get()->ConnectToSignal( authpolicy::kUserKerberosFilesChangedSignal, base::Bind( &AuthPolicyCredentialsManager::OnUserKerberosFilesChangedCallback, @@ -125,7 +124,7 @@ authpolicy::GetUserStatusRequest request; request.set_user_principal_name(account_id_.GetUserEmail()); request.set_account_id(account_id_.GetObjGuid()); - DBusThreadManager::Get()->GetAuthPolicyClient()->GetUserStatus( + AuthPolicyClient::Get()->GetUserStatus( request, base::BindOnce(&AuthPolicyCredentialsManager::OnGetUserStatusCallback, weak_factory_.GetWeakPtr())); @@ -188,7 +187,7 @@ } void AuthPolicyCredentialsManager::GetUserKerberosFiles() { - DBusThreadManager::Get()->GetAuthPolicyClient()->GetUserKerberosFiles( + AuthPolicyClient::Get()->GetUserKerberosFiles( account_id_.GetObjGuid(), base::BindOnce( &AuthPolicyCredentialsManager::OnGetUserKerberosFilesCallback,
diff --git a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager_unittest.cc b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager_unittest.cc index 543e0016..7f14c6cc 100644 --- a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager_unittest.cc +++ b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager_unittest.cc
@@ -52,6 +52,7 @@ void SetUp() override { chromeos::DBusThreadManager::Initialize(); chromeos::NetworkHandler::Initialize(); + AuthPolicyClient::InitializeFake(); fake_auth_policy_client()->DisableOperationDelayForTesting(); TestingProfile::Builder profile_builder; @@ -83,8 +84,9 @@ void TearDown() override { EXPECT_CALL(*mock_user_manager(), Shutdown()); profile_.reset(); - chromeos::NetworkHandler::Shutdown(); - chromeos::DBusThreadManager::Shutdown(); + AuthPolicyClient::Shutdown(); + NetworkHandler::Shutdown(); + DBusThreadManager::Shutdown(); } protected: @@ -94,8 +96,7 @@ return auth_policy_credentials_manager_; } chromeos::FakeAuthPolicyClient* fake_auth_policy_client() const { - return static_cast<chromeos::FakeAuthPolicyClient*>( - chromeos::DBusThreadManager::Get()->GetAuthPolicyClient()); + return chromeos::FakeAuthPolicyClient::Get(); } MockUserManager* mock_user_manager() {
diff --git a/chrome/browser/chromeos/dbus/dbus_helper.cc b/chrome/browser/chromeos/dbus/dbus_helper.cc index 060b852..6bb0a5cf3 100644 --- a/chrome/browser/chromeos/dbus/dbus_helper.cc +++ b/chrome/browser/chromeos/dbus/dbus_helper.cc
@@ -6,6 +6,7 @@ #include "chrome/browser/chromeos/settings/device_settings_service.h" #include "chromeos/cryptohome/system_salt_getter.h" +#include "chromeos/dbus/auth_policy/auth_policy_client.h" #include "chromeos/dbus/biod/biod_client.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/hammerd/hammerd_client.h" @@ -39,12 +40,14 @@ } if (bus) { + AuthPolicyClient::Initialize(bus); BiodClient::Initialize(bus); // For device::Fingerprint. KerberosClient::Initialize(bus); PowerManagerClient::Initialize(bus); SystemClockClient::Initialize(bus); UpstartClient::Initialize(bus); } else { + AuthPolicyClient::InitializeFake(); BiodClient::InitializeFake(); // For device::Fingerprint. KerberosClient::InitializeFake(); PowerManagerClient::InitializeFake(); @@ -60,6 +63,7 @@ } void ShutdownDBus() { + AuthPolicyClient::Shutdown(); UpstartClient::Shutdown(); SystemClockClient::Shutdown(); PowerManagerClient::Shutdown();
diff --git a/chrome/browser/chromeos/login/active_directory_login_browsertest.cc b/chrome/browser/chromeos/login/active_directory_login_browsertest.cc index ea0617b..5738b659 100644 --- a/chrome/browser/chromeos/login/active_directory_login_browsertest.cc +++ b/chrome/browser/chromeos/login/active_directory_login_browsertest.cc
@@ -83,11 +83,11 @@ void SetUpInProcessBrowserTestFixture() override { LoginManagerTest::SetUpInProcessBrowserTestFixture(); - auto fake_client = std::make_unique<FakeAuthPolicyClient>(); - fake_auth_policy_client_ = fake_client.get(); - fake_auth_policy_client_->DisableOperationDelayForTesting(); - DBusThreadManager::GetSetterForTesting()->SetAuthPolicyClient( - std::move(fake_client)); + // This is called before ChromeBrowserMain initializes the fake dbus + // clients, and DisableOperationDelayForTesting() needs to be called before + // other ChromeBrowserMain initialization occurs. + AuthPolicyClient::InitializeFake(); + FakeAuthPolicyClient::Get()->DisableOperationDelayForTesting(); // Note: FakeCryptohomeClient needs paths to be set to load install attribs. active_directory_test_helper::OverridePaths(); @@ -286,7 +286,7 @@ return "document.querySelector('#" + parent_id + "')." + selector; } FakeAuthPolicyClient* fake_auth_policy_client() { - return fake_auth_policy_client_; + return FakeAuthPolicyClient::Get(); } const std::string test_realm_; @@ -294,7 +294,6 @@ std::string autocomplete_realm_; private: - FakeAuthPolicyClient* fake_auth_policy_client_; DISALLOW_COPY_AND_ASSIGN(ActiveDirectoryLoginTest); };
diff --git a/chrome/browser/chromeos/login/active_directory_test_helper.cc b/chrome/browser/chromeos/login/active_directory_test_helper.cc index 0ecc814..be4160b8 100644 --- a/chrome/browser/chromeos/login/active_directory_test_helper.cc +++ b/chrome/browser/chromeos/login/active_directory_test_helper.cc
@@ -15,7 +15,6 @@ #include "chromeos/constants/chromeos_paths.h" #include "chromeos/dbus/auth_policy/auth_policy_client.h" #include "chromeos/dbus/authpolicy/active_directory_info.pb.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/upstart/upstart_client.h" #include "chromeos/dbus/util/tpm_util.h" #include "chromeos/login/auth/authpolicy_login_helper.h" @@ -69,14 +68,12 @@ // Fetch device policy. { base::RunLoop run_loop; - chromeos::DBusThreadManager::Get() - ->GetAuthPolicyClient() - ->RefreshDevicePolicy(base::BindOnce( - [](base::OnceClosure quit_closure, authpolicy::ErrorType error) { - EXPECT_EQ(authpolicy::ERROR_NONE, error); - std::move(quit_closure).Run(); - }, - run_loop.QuitClosure())); + AuthPolicyClient::Get()->RefreshDevicePolicy(base::BindOnce( + [](base::OnceClosure quit_closure, authpolicy::ErrorType error) { + EXPECT_EQ(authpolicy::ERROR_NONE, error); + std::move(quit_closure).Run(); + }, + run_loop.QuitClosure())); run_loop.Run(); } }
diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc index 2c84b697..10d02480 100644 --- a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc +++ b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
@@ -216,9 +216,9 @@ ActiveDirectoryJoinTest() = default; void SetUp() override { - DBusThreadManager::GetSetterForTesting()->SetAuthPolicyClient( - std::make_unique<MockAuthPolicyClient>()); + mock_auth_policy_client_ = new MockAuthPolicyClient(); mock_auth_policy_client()->DisableOperationDelayForTesting(); + EnterpriseEnrollmentTestBase::SetUp(); } @@ -372,8 +372,7 @@ MockAuthPolicyClient* mock_auth_policy_client() { - return static_cast<MockAuthPolicyClient*>( - DBusThreadManager::Get()->GetAuthPolicyClient()); + return mock_auth_policy_client_; } void SetupActiveDirectoryJSNotifications() { @@ -418,6 +417,9 @@ } private: + // Owned by the AuthPolicyClient global instance. + MockAuthPolicyClient* mock_auth_policy_client_ = nullptr; + DISALLOW_COPY_AND_ASSIGN(ActiveDirectoryJoinTest); };
diff --git a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc index 5662e479..371bdb5c 100644 --- a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
@@ -831,7 +831,13 @@ // Overriden from ExistingUserControllerTest: void SetUpInProcessBrowserTestFixture() override { ExistingUserControllerTest::SetUpInProcessBrowserTestFixture(); - fake_authpolicy_client()->DisableOperationDelayForTesting(); + + // This is called before ChromeBrowserMain initializes the fake dbus + // clients, and DisableOperationDelayForTesting() needs to be called before + // other ChromeBrowserMain initialization occurs. + AuthPolicyClient::InitializeFake(); + FakeAuthPolicyClient::Get()->DisableOperationDelayForTesting(); + ASSERT_TRUE( tpm_util::LockDeviceActiveDirectoryForTesting(kActiveDirectoryRealm)); RefreshDevicePolicy(); @@ -847,11 +853,6 @@ } protected: - chromeos::FakeAuthPolicyClient* fake_authpolicy_client() { - return static_cast<chromeos::FakeAuthPolicyClient*>( - chromeos::DBusThreadManager::Get()->GetAuthPolicyClient()); - } - void LoginAdOnline() { ExpectLoginSuccess(); UserContext user_context(user_manager::UserType::USER_TYPE_ACTIVE_DIRECTORY, @@ -899,7 +900,7 @@ std::string GetExpectedKerberosConfig(bool enable_dns_cname_lookup) { std::string config(base::StringPrintf( kKrb5CnameSettings, enable_dns_cname_lookup ? "true" : "false")); - config += fake_authpolicy_client()->user_kerberos_conf(); + config += FakeAuthPolicyClient::Get()->user_kerberos_conf(); return config; } @@ -913,7 +914,8 @@ EXPECT_TRUE(base::ReadFileToString( base::FilePath(GetKerberosCredentialsCacheFileName()), &file_contents)); - EXPECT_EQ(file_contents, fake_authpolicy_client()->user_kerberos_creds()); + EXPECT_EQ(file_contents, + FakeAuthPolicyClient::Get()->user_kerberos_creds()); } // Applies policy and waits until both config and credentials files changed. @@ -944,7 +946,7 @@ em::ChromeDeviceSettingsProto device_policy; device_policy.mutable_user_whitelist()->add_user_whitelist()->assign( kUserWhitelist); - fake_authpolicy_client()->set_device_policy(device_policy); + FakeAuthPolicyClient::Get()->set_device_policy(device_policy); } void SetUpLoginDisplay() override { @@ -988,8 +990,8 @@ DISABLED_UserKerberosFilesChangedSignalTriggersFileUpdate) { LoginAdOnline(); KerberosFilesChangeWaiter files_change_waiter(true /* files_must_exist */); - fake_authpolicy_client()->SetUserKerberosFiles("new_kerberos_creds", - "new_kerberos_config"); + FakeAuthPolicyClient::Get()->SetUserKerberosFiles("new_kerberos_creds", + "new_kerberos_config"); files_change_waiter.Wait(); CheckKerberosFiles(true /* enable_dns_cname_lookup */); }
diff --git a/chrome/browser/chromeos/policy/active_directory_policy_manager.cc b/chrome/browser/chromeos/policy/active_directory_policy_manager.cc index c15be7aa..09d5ef7a 100644 --- a/chrome/browser/chromeos/policy/active_directory_policy_manager.cc +++ b/chrome/browser/chromeos/policy/active_directory_policy_manager.cc
@@ -44,13 +44,7 @@ // Gets the AuthPolicy D-Bus interface. chromeos::AuthPolicyClient* GetAuthPolicyClient() { - chromeos::DBusThreadManager* thread_manager = - chromeos::DBusThreadManager::Get(); - DCHECK(thread_manager); - chromeos::AuthPolicyClient* auth_policy_client = - thread_manager->GetAuthPolicyClient(); - DCHECK(auth_policy_client); - return auth_policy_client; + return chromeos::AuthPolicyClient::Get(); } bool IsComponentPolicyDisabled() {
diff --git a/chrome/browser/chromeos/policy/active_directory_policy_manager_unittest.cc b/chrome/browser/chromeos/policy/active_directory_policy_manager_unittest.cc index 3783d7b14..b4fc979 100644 --- a/chrome/browser/chromeos/policy/active_directory_policy_manager_unittest.cc +++ b/chrome/browser/chromeos/policy/active_directory_policy_manager_unittest.cc
@@ -29,8 +29,6 @@ class TestAuthPolicyClient : public chromeos::AuthPolicyClient { public: - void Init(dbus::Bus* bus) override { NOTIMPLEMENTED(); } - void JoinAdDomain(const authpolicy::JoinDomainRequest& request, int password_fd, JoinCallback callback) override { @@ -101,16 +99,16 @@ // testing::Test overrides: void SetUp() override { - auto mock_client_unique_ptr = std::make_unique<TestAuthPolicyClient>(); - mock_client_ = mock_client_unique_ptr.get(); - chromeos::DBusThreadManager::GetSetterForTesting()->SetAuthPolicyClient( - std::move(mock_client_unique_ptr)); + // Base class constructor sets the global instance which will be destroyed + // in AuthPolicyClient::Shutdown(). + mock_client_ = new TestAuthPolicyClient(); } void TearDown() override { if (mock_external_data_manager()) EXPECT_CALL(*mock_external_data_manager(), Disconnect()); policy_manager_->Shutdown(); + chromeos::AuthPolicyClient::Shutdown(); } protected: @@ -141,7 +139,7 @@ testing::Mock::VerifyAndClearExpectations(mock_external_data_manager()); } - // Owned by DBusThreadManager. + // Owned by the AuthPolicyClient global instance. TestAuthPolicyClient* mock_client_ = nullptr; // Used to set FakeUserManager.
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc index 561b79f..2b28c20 100644 --- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc +++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
@@ -748,11 +748,9 @@ // policy is accepted. chromeos::DeviceSettingsService::Get()->SetDeviceMode( install_attributes_->GetMode()); - chromeos::DBusThreadManager::Get() - ->GetAuthPolicyClient() - ->RefreshDevicePolicy(base::BindOnce( - &EnrollmentHandlerChromeOS::HandleActiveDirectoryPolicyRefreshed, - weak_ptr_factory_.GetWeakPtr())); + chromeos::AuthPolicyClient::Get()->RefreshDevicePolicy(base::BindOnce( + &EnrollmentHandlerChromeOS::HandleActiveDirectoryPolicyRefreshed, + weak_ptr_factory_.GetWeakPtr())); } else { store_->InstallInitialPolicy(*policy_); }
diff --git a/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc b/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc index 2b76ee7..1fff02e 100644 --- a/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc +++ b/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc
@@ -165,19 +165,14 @@ chromeos::DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient( std::make_unique<chromeos::FakeCryptohomeClient>()); - // Initialize UpstartClient here so that it is available for - // FakeAuthPolicyClient. It will be shutdown in ChromeBrowserMain. + // Initialize clients here so they are available during setup. They will be + // shutdown in ChromeBrowserMain. chromeos::UpstartClient::InitializeFake(); - chromeos::FakeAuthPolicyClient* fake_auth_policy_client = nullptr; if (GetParam().active_directory) { - auto fake_auth_policy_client_owned = - std::make_unique<chromeos::FakeAuthPolicyClient>(); - fake_auth_policy_client = fake_auth_policy_client_owned.get(); + chromeos::AuthPolicyClient::InitializeFake(); + fake_auth_policy_client = chromeos::FakeAuthPolicyClient::Get(); fake_auth_policy_client->DisableOperationDelayForTesting(); - chromeos::DBusThreadManager::GetSetterForTesting()->SetAuthPolicyClient( - std::move(fake_auth_policy_client_owned)); - // PrepareLogin requires a message loop, which isn't available yet here. base::MessageLoop message_loop; chromeos::active_directory_test_helper::PrepareLogin(
diff --git a/chrome/browser/chromeos/set_time_dialog.cc b/chrome/browser/chromeos/set_time_dialog.cc index d96d75a..4d215e5 100644 --- a/chrome/browser/chromeos/set_time_dialog.cc +++ b/chrome/browser/chromeos/set_time_dialog.cc
@@ -20,8 +20,8 @@ // Material design dialog width and height in DIPs. const int kDefaultWidthMd = 530; -const int kDefaultHeightWithTimezone = 255; -const int kDefaultHeightWithoutTimezone = 215; +const int kDefaultHeightWithTimezone = 286; +const int kDefaultHeightWithoutTimezone = 228; } // namespace
diff --git a/chrome/browser/chromeos/smb_client/smb_service.cc b/chrome/browser/chromeos/smb_client/smb_service.cc index bdc79934..ce7d41cf 100644 --- a/chrome/browser/chromeos/smb_client/smb_service.cc +++ b/chrome/browser/chromeos/smb_client/smb_service.cc
@@ -221,10 +221,18 @@ bool use_chromad_kerberos, bool should_open_file_manager_after_mount, MountResponse callback) { + SmbUrl parsed_url(share_path.value()); + if (!parsed_url.IsValid() || parsed_url.GetShare().empty()) { + // Handle invalid URLs early to avoid having unaccounted for UMA counts for + // authentication method. + std::move(callback).Run( + TranslateErrorToMountResult(base::File::Error::FILE_ERROR_INVALID_URL)); + return; + } + std::string username; std::string password; std::string workgroup; - if (use_chromad_kerberos) { RecordAuthenticationMethod(AuthMethod::kSSOKerberos); // Get the user's username and workgroup from their email address to be used @@ -254,13 +262,6 @@ } } - SmbUrl parsed_url(share_path.value()); - if (!parsed_url.IsValid()) { - std::move(callback).Run( - TranslateErrorToMountResult(base::File::Error::FILE_ERROR_INVALID_URL)); - return; - } - // If using kerberos, the hostname should not be resolved since kerberos // service tickets are keyed on hosname. const std::string url = use_chromad_kerberos
diff --git a/chrome/browser/chromeos/smb_client/smb_service.h b/chrome/browser/chromeos/smb_client/smb_service.h index b74dd9d5..e5530c6 100644 --- a/chrome/browser/chromeos/smb_client/smb_service.h +++ b/chrome/browser/chromeos/smb_client/smb_service.h
@@ -105,6 +105,8 @@ StartReadDirIfSuccessfulCallback reply); private: + friend class SmbServiceTest; + // Calls SmbProviderClient::Mount(). |temp_file_manager_| must be initialized // before this is called. void CallMount(const file_system_provider::MountOptions& options,
diff --git a/chrome/browser/chromeos/smb_client/smb_service_unittest.cc b/chrome/browser/chromeos/smb_client/smb_service_unittest.cc index 608709d0..e9a2629 100644 --- a/chrome/browser/chromeos/smb_client/smb_service_unittest.cc +++ b/chrome/browser/chromeos/smb_client/smb_service_unittest.cc
@@ -26,6 +26,14 @@ namespace chromeos { namespace smb_client { +namespace { + +void SaveMountResult(SmbMountResult* out, SmbMountResult result) { + *out = result; +} + +} // namespace + class SmbServiceTest : public testing::Test { protected: SmbServiceTest() : profile_(NULL) { @@ -59,6 +67,16 @@ ~SmbServiceTest() override {} + void ExpectInvalidUrl(const std::string& url) { + SmbMountResult result = SmbMountResult::SUCCESS; + smb_service_->CallMount({} /* options */, base::FilePath(url), + "" /* username */, "" /* password */, + false /* use_chromad_kerberos */, + false /* should_open_file_manager_after_mount */, + base::BindOnce(&SaveMountResult, &result)); + EXPECT_EQ(result, SmbMountResult::INVALID_URL); + } + content::TestBrowserThreadBundle thread_bundle_; // Included so tests magically don't crash. TestingProfile* profile_; // Not owned. @@ -71,5 +89,18 @@ std::unique_ptr<extensions::ExtensionRegistry> extension_registry_; }; +TEST_F(SmbServiceTest, InvalidUrls) { + ExpectInvalidUrl(""); + ExpectInvalidUrl("foo"); + ExpectInvalidUrl("\\foo"); + ExpectInvalidUrl("\\\\foo"); + ExpectInvalidUrl("\\\\foo\\"); + ExpectInvalidUrl("file://foo/bar"); + ExpectInvalidUrl("smb://foo"); + ExpectInvalidUrl("smb://user@password:foo"); + ExpectInvalidUrl("smb:\\\\foo\\bar"); + ExpectInvalidUrl("//foo/bar"); +} + } // namespace smb_client } // namespace chromeos
diff --git a/chrome/browser/chromeos/smb_client/smb_url.cc b/chrome/browser/chromeos/smb_client/smb_url.cc index 46818ab94..fbf7e26 100644 --- a/chrome/browser/chromeos/smb_client/smb_url.cc +++ b/chrome/browser/chromeos/smb_client/smb_url.cc
@@ -4,7 +4,11 @@ #include "chrome/browser/chromeos/smb_client/smb_url.h" +#include <vector> + #include "base/strings/strcat.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "chrome/browser/chromeos/smb_client/smb_constants.h" #include "url/url_canon_stdstring.h" @@ -76,6 +80,12 @@ return url_.substr(host_.begin, host_.len); } +std::string SmbUrl::GetShare() const { + DCHECK(IsValid()); + + return share_; +} + const std::string& SmbUrl::ToString() const { DCHECK(IsValid()); @@ -123,11 +133,11 @@ canonical_output.push_back('/'); canonical_output.push_back('/'); - url::Component unused_path; + url::Component path; if (!(url::CanonicalizeHost(url.c_str(), initial_parsed.host, &canonical_output, &host_) && url::CanonicalizePath(url.c_str(), initial_parsed.path, - &canonical_output, &unused_path))) { + &canonical_output, &path))) { Reset(); return; } @@ -141,6 +151,20 @@ canonical_output.Complete(); + if (path.is_nonempty()) { + // Extract share name, which is the first path element. + // Paths always start with '/', but extra '/'s are not removed. + // So both "smb://foo" and "smb://foo//bar/" have the share name "", but + // "smb://foo/bar/" has the share name "bar". + std::string path_str = url_.substr(path.begin, path.len); + std::vector<base::StringPiece> split_path = base::SplitStringPiece( + path_str, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); + if (split_path.size() >= 2) { + DCHECK_EQ(split_path[0], ""); + share_ = split_path[1].as_string(); + } + } + DCHECK(host_.is_nonempty()); DCHECK_EQ(url_.substr(scheme.begin, scheme.len), kSmbScheme); }
diff --git a/chrome/browser/chromeos/smb_client/smb_url.h b/chrome/browser/chromeos/smb_client/smb_url.h index 3e23a45..4831f11 100644 --- a/chrome/browser/chromeos/smb_client/smb_url.h +++ b/chrome/browser/chromeos/smb_client/smb_url.h
@@ -27,6 +27,9 @@ // Returns the host of the URL which can be resolved or unresolved. std::string GetHost() const; + // Returns the share component of the URL. + std::string GetShare() const; + // Returns the full URL. const std::string& ToString() const; @@ -61,6 +64,9 @@ // Holds the identified host of the URL. This does not store the host itself. url::Component host_; + // Share name component of the URL. + std::string share_; + DISALLOW_COPY_AND_ASSIGN(SmbUrl); };
diff --git a/chrome/browser/chromeos/smb_client/smb_url_unittest.cc b/chrome/browser/chromeos/smb_client/smb_url_unittest.cc index 92d9399..4aef1b2 100644 --- a/chrome/browser/chromeos/smb_client/smb_url_unittest.cc +++ b/chrome/browser/chromeos/smb_client/smb_url_unittest.cc
@@ -24,11 +24,13 @@ void ExpectValidUrl(const std::string& url, const std::string& expected_url, - const std::string& expected_host) { + const std::string& expected_host, + const std::string& expected_share) { SmbUrl smb_url(url); EXPECT_TRUE(smb_url.IsValid()); EXPECT_EQ(expected_url, smb_url.ToString()); EXPECT_EQ(expected_host, smb_url.GetHost()); + EXPECT_EQ(expected_share, smb_url.GetShare()); } void ExpectValidWindowsUNC(const std::string& url, @@ -58,19 +60,24 @@ } TEST_F(SmbUrlTest, ValidUrls) { - ExpectValidUrl("smb://x", "smb://x/", "x"); - ExpectValidUrl("smb:///x", "smb://x/", "x"); + ExpectValidUrl("smb://x", "smb://x/", "x", ""); + ExpectValidUrl("smb:///x", "smb://x/", "x", ""); + ExpectValidUrl("smb:///x/y", "smb://x/y", "x", "y"); + ExpectValidUrl("smb:///x/y/", "smb://x/y/", "x", "y"); + ExpectValidUrl("smb:///x//y", "smb://x//y", "x", ""); + ExpectValidUrl("smb:///x//y//", "smb://x//y//", "x", ""); ExpectValidUrl("smb://server/share/long/folder", - "smb://server/share/long/folder", "server"); + "smb://server/share/long/folder", "server", "share"); ExpectValidUrl("smb://server/share/folder.with.dots", - "smb://server/share/folder.with.dots", "server"); + "smb://server/share/folder.with.dots", "server", "share"); ExpectValidUrl("smb://server\\share/mixed\\slashes", - "smb://server/share/mixed/slashes", "server"); - ExpectValidUrl("\\\\server/share", "smb://server/share", "server"); + "smb://server/share/mixed/slashes", "server", "share"); + ExpectValidUrl("\\\\server", "smb://server/", "server", ""); + ExpectValidUrl("\\\\server/share", "smb://server/share", "server", "share"); ExpectValidUrl("\\\\server\\share/mixed//slashes", - "smb://server/share/mixed//slashes", "server"); + "smb://server/share/mixed//slashes", "server", "share"); ExpectValidUrl("smb://192.168.0.1/share", "smb://192.168.0.1/share", - "192.168.0.1"); + "192.168.0.1", "share"); } TEST_F(SmbUrlTest, NotValidIfStartsWithoutSchemeOrDoubleBackslash) { @@ -79,20 +86,20 @@ TEST_F(SmbUrlTest, StartsWithBackslashRemovesBackslashAndAddsScheme) { ExpectValidUrl("\\\\192.168.0.1\\share", "smb://192.168.0.1/share", - "192.168.0.1"); + "192.168.0.1", "share"); } TEST_F(SmbUrlTest, GetHostWithIp) { ExpectValidUrl("smb://192.168.0.1/share", "smb://192.168.0.1/share", - "192.168.0.1"); + "192.168.0.1", "share"); } TEST_F(SmbUrlTest, GetHostWithDomain) { - ExpectValidUrl("smb://server/share", "smb://server/share", "server"); + ExpectValidUrl("smb://server/share", "smb://server/share", "server", "share"); } TEST_F(SmbUrlTest, HostBecomesLowerCase) { - ExpectValidUrl("smb://SERVER/share", "smb://server/share", "server"); + ExpectValidUrl("smb://SERVER/share", "smb://server/share", "server", "share"); } TEST_F(SmbUrlTest, ReplacesHost) {
diff --git a/chrome/browser/dom_distiller/dom_distiller_service_factory.cc b/chrome/browser/dom_distiller/dom_distiller_service_factory.cc index 73e3fd3b..b4c9bb8 100644 --- a/chrome/browser/dom_distiller/dom_distiller_service_factory.cc +++ b/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
@@ -50,22 +50,26 @@ DomDistillerServiceFactory::DomDistillerServiceFactory() : BrowserContextKeyedServiceFactory( "DomDistillerService", - BrowserContextDependencyManager::GetInstance()) {} + BrowserContextDependencyManager::GetInstance()) { + // Add this when this factory is a SimpleKeyedServiceFactory: + // DependsOn(leveldb_proto::ProtoDatabaseProviderFactory::GetInstance()); +} DomDistillerServiceFactory::~DomDistillerServiceFactory() {} KeyedService* DomDistillerServiceFactory::BuildServiceInstanceFor( - content::BrowserContext* profile) const { + content::BrowserContext* context) const { + Profile* profile = Profile::FromBrowserContext(context); scoped_refptr<base::SequencedTaskRunner> background_task_runner = base::CreateSequencedTaskRunnerWithTraits( {base::MayBlock(), base::TaskPriority::BEST_EFFORT}); base::FilePath database_dir( - profile->GetPath().Append(FILE_PATH_LITERAL("Articles"))); + context->GetPath().Append(FILE_PATH_LITERAL("Articles"))); leveldb_proto::ProtoDatabaseProvider* db_provider = - leveldb_proto::ProtoDatabaseProviderFactory::GetForBrowserContext( - profile); + leveldb_proto::ProtoDatabaseProviderFactory::GetForKey( + profile->GetSimpleFactoryKey(), profile->GetPrefs()); auto db = db_provider->GetDB<ArticleEntry>( leveldb_proto::ProtoDbType::DOM_DISTILLER_STORE, database_dir, @@ -75,10 +79,10 @@ new DomDistillerStore(std::move(db))); std::unique_ptr<DistillerPageFactory> distiller_page_factory( - new DistillerPageWebContentsFactory(profile)); + new DistillerPageWebContentsFactory(context)); std::unique_ptr<DistillerURLFetcherFactory> distiller_url_fetcher_factory( new DistillerURLFetcherFactory( - content::BrowserContext::GetDefaultStoragePartition(profile) + content::BrowserContext::GetDefaultStoragePartition(context) ->GetURLLoaderFactoryForBrowserProcess())); dom_distiller::proto::DomDistillerOptions options; @@ -94,7 +98,7 @@ std::unique_ptr<DistillerFactory> distiller_factory(new DistillerFactoryImpl( std::move(distiller_url_fetcher_factory), options)); std::unique_ptr<DistilledPagePrefs> distilled_page_prefs( - new DistilledPagePrefs(Profile::FromBrowserContext(profile)->GetPrefs())); + new DistilledPagePrefs(profile->GetPrefs())); DomDistillerContextKeyedService* service = new DomDistillerContextKeyedService(
diff --git a/chrome/browser/download/download_offline_content_provider.cc b/chrome/browser/download/download_offline_content_provider.cc index cc9da61..0067d0d9 100644 --- a/chrome/browser/download/download_offline_content_provider.cc +++ b/chrome/browser/download/download_offline_content_provider.cc
@@ -24,7 +24,6 @@ #if defined(OS_ANDROID) #include "chrome/browser/android/download/download_manager_bridge.h" -#include "chrome/browser/android/download/download_manager_service.h" #endif using OfflineItemFilter = offline_items_collection::OfflineItemFilter; @@ -57,11 +56,15 @@ DownloadOfflineContentProvider::~DownloadOfflineContentProvider() { aggregator_->UnregisterProvider(name_space_); + if (manager_) + manager_->RemoveObserver(this); } void DownloadOfflineContentProvider::SetDownloadManager( DownloadManager* manager) { + DCHECK(manager); manager_ = manager; + manager_->AddObserver(this); } // TODO(shaktisahu) : Pass DownloadOpenSource. @@ -201,6 +204,11 @@ observers_.RemoveObserver(observer); } +void DownloadOfflineContentProvider::ManagerGoingDown( + DownloadManager* manager) { + manager_ = nullptr; +} + void DownloadOfflineContentProvider::OnDownloadStarted(DownloadItem* item) { item->RemoveObserver(this); item->AddObserver(this); @@ -261,27 +269,13 @@ DownloadItem* DownloadOfflineContentProvider::GetDownload( const std::string& download_guid) { -#if defined(OS_ANDROID) - bool incognito = manager_ && manager_->GetBrowserContext() - ? manager_->GetBrowserContext()->IsOffTheRecord() - : false; - return DownloadManagerService::GetInstance()->GetDownload(download_guid, - incognito); -#else - return manager_->GetDownloadByGuid(download_guid); -#endif + return manager_ ? manager_->GetDownloadByGuid(download_guid) : nullptr; } void DownloadOfflineContentProvider::GetAllDownloads( DownloadManager::DownloadVector* all_items) { -#if defined(OS_ANDROID) - bool incognito = manager_ && manager_->GetBrowserContext() - ? manager_->GetBrowserContext()->IsOffTheRecord() - : false; - DownloadManagerService::GetInstance()->GetAllDownloads(all_items, incognito); -#else - manager_->GetAllDownloads(all_items); -#endif + if (manager_) + manager_->GetAllDownloads(all_items); } void DownloadOfflineContentProvider::UpdateObservers(DownloadItem* item) {
diff --git a/chrome/browser/download/download_offline_content_provider.h b/chrome/browser/download/download_offline_content_provider.h index 4798bbe..da0fff79 100644 --- a/chrome/browser/download/download_offline_content_provider.h +++ b/chrome/browser/download/download_offline_content_provider.h
@@ -29,7 +29,8 @@ // single DownloadManager (or in-progress download manager in service manager // only mode) and notifies UI about updates about various downloads. class DownloadOfflineContentProvider : public OfflineContentProvider, - public download::DownloadItem::Observer { + public download::DownloadItem::Observer, + public DownloadManager::Observer { public: explicit DownloadOfflineContentProvider(OfflineContentAggregator* aggregator, const std::string& name_space); @@ -66,9 +67,13 @@ void OnDownloadStarted(DownloadItem* download_item); private: + // DownloadItem::Observer overrides void OnDownloadUpdated(DownloadItem* item) override; void OnDownloadRemoved(DownloadItem* item) override; + // DownloadManager::Observer overrides + void ManagerGoingDown(DownloadManager* manager) override; + void GetAllDownloads(DownloadManager::DownloadVector* all_items); DownloadItem* GetDownload(const std::string& download_guid); void OnThumbnailRetrieved(const ContentId& id,
diff --git a/chrome/browser/extensions/bookmark_app_helper.cc b/chrome/browser/extensions/bookmark_app_helper.cc index c8e2913..8266f29 100644 --- a/chrome/browser/extensions/bookmark_app_helper.cc +++ b/chrome/browser/extensions/bookmark_app_helper.cc
@@ -296,8 +296,9 @@ // Do not wait for a service worker if it doesn't exist. params.has_worker = !bypass_service_worker_check_; installable_manager_->GetData( - params, base::Bind(&BookmarkAppHelper::OnDidPerformInstallableCheck, - weak_factory_.GetWeakPtr())); + params, + base::BindOnce(&BookmarkAppHelper::OnDidPerformInstallableCheck, + weak_factory_.GetWeakPtr())); } } else { for_installable_site_ = web_app::ForInstallableSite::kNo;
diff --git a/chrome/browser/feature_engagement/tracker_factory.cc b/chrome/browser/feature_engagement/tracker_factory.cc index 2ff6527..5c248c3 100644 --- a/chrome/browser/feature_engagement/tracker_factory.cc +++ b/chrome/browser/feature_engagement/tracker_factory.cc
@@ -35,7 +35,8 @@ : BrowserContextKeyedServiceFactory( "feature_engagement::Tracker", BrowserContextDependencyManager::GetInstance()) { - DependsOn(leveldb_proto::ProtoDatabaseProviderFactory::GetInstance()); + // Add this when this factory is a SimpleKeyedServiceFactory: + // DependsOn(leveldb_proto::ProtoDatabaseProviderFactory::GetInstance()); } TrackerFactory::~TrackerFactory() = default; @@ -52,8 +53,8 @@ chrome::kFeatureEngagementTrackerStorageDirname); leveldb_proto::ProtoDatabaseProvider* db_provider = - leveldb_proto::ProtoDatabaseProviderFactory::GetInstance() - ->GetForBrowserContext(context); + leveldb_proto::ProtoDatabaseProviderFactory::GetInstance()->GetForKey( + profile->GetSimpleFactoryKey(), profile->GetPrefs()); return feature_engagement::Tracker::Create( storage_dir, background_task_runner, db_provider); }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 576c115..55ae5f8b 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -272,7 +272,7 @@ "expiry_milestone": 75 }, { - "name": "autofill-show-full-disclosure-label", + "name": "autofill-use-improved-label-disambiguation", "owners": [ "ftirelo", "tmartino" ], "expiry_milestone": 77 }, @@ -1605,8 +1605,13 @@ }, { "name": "enable-send-tab-to-self", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "//components/send_tab_to_self/OWNERS" ], + "expiry_milestone": 77 + }, + { + "name": "enable-send-tab-to-self-receive", + "owners": [ "//components/send_tab_to_self/OWNERS" ], + "expiry_milestone": 77 }, { "name": "enable-sensor-content-setting",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index d13f97f..4c4d145 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -153,11 +153,11 @@ const char kAutofillProfileServerValidationDescription[] = "Allows autofill to use server side validation"; -const char kAutofillShowFullDisclosureLabelName[] = - "Autofill Show Full Disclosure Label"; -const char kAutofillShowFullDisclosureLabelDescription[] = - "When enabled, the Autofill dropdown's labels are displayed in the full " - "disclosure format."; +const char kAutofillUseImprovedLabelDisambiguationName[] = + "Autofill Uses Improved Label Disambiguation"; +const char kAutofillUseImprovedLabelDisambiguationDescription[] = + "When enabled, the Autofill dropdown's suggestions' labels are displayed " + "using the improved disambiguation format."; const char kAutofillEnforceMinRequiredFieldsForHeuristicsName[] = "Autofill Enforce Min Required Fields For Heuristics"; @@ -1700,6 +1700,11 @@ "Allows users to push tabs from Android devices to other synced " "devices, in order to easily transition those tabs to the new device "; +const char kSendTabToSelfReceiveName[] = "Send tab to self receive"; +const char kSendTabToSelfReceiveDescription[] = + "Allows users to receive tabs that were pushed from other synced " + "devices, in order to easily transition those tabs to the new device "; + const char kServiceWorkerImportedScriptUpdateCheckName[] = "Enable update check for service worker importScripts() resources"; const char kServiceWorkerImportedScriptUpdateCheckDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index dd8711f..fb5c793 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -122,8 +122,8 @@ extern const char kAutofillProfileServerValidationName[]; extern const char kAutofillProfileServerValidationDescription[]; -extern const char kAutofillShowFullDisclosureLabelName[]; -extern const char kAutofillShowFullDisclosureLabelDescription[]; +extern const char kAutofillUseImprovedLabelDisambiguationName[]; +extern const char kAutofillUseImprovedLabelDisambiguationDescription[]; extern const char kAutofillRestrictUnownedFieldsToFormlessCheckoutName[]; extern const char kAutofillRestrictUnownedFieldsToFormlessCheckoutDescription[]; @@ -1012,6 +1012,9 @@ extern const char kSendTabToSelfName[]; extern const char kSendTabToSelfDescription[]; +extern const char kSendTabToSelfReceiveName[]; +extern const char kSendTabToSelfReceiveDescription[]; + extern const char kServiceWorkerImportedScriptUpdateCheckName[]; extern const char kServiceWorkerImportedScriptUpdateCheckDescription[];
diff --git a/chrome/browser/installable/fake_installable_manager.cc b/chrome/browser/installable/fake_installable_manager.cc index c3dc027..2a7a566 100644 --- a/chrome/browser/installable/fake_installable_manager.cc +++ b/chrome/browser/installable/fake_installable_manager.cc
@@ -19,14 +19,14 @@ FakeInstallableManager::~FakeInstallableManager() {} void FakeInstallableManager::GetData(const InstallableParams& params, - const InstallableCallback& callback) { + InstallableCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&FakeInstallableManager::RunCallback, - base::Unretained(this), callback)); + base::Unretained(this), std::move(callback))); } -void FakeInstallableManager::RunCallback(const InstallableCallback& callback) { - callback.Run(*data_); +void FakeInstallableManager::RunCallback(InstallableCallback callback) { + std::move(callback).Run(*data_); } // static
diff --git a/chrome/browser/installable/fake_installable_manager.h b/chrome/browser/installable/fake_installable_manager.h index eb06b0f..a3cb0e7 100644 --- a/chrome/browser/installable/fake_installable_manager.h +++ b/chrome/browser/installable/fake_installable_manager.h
@@ -27,9 +27,9 @@ // InstallableManager: void GetData(const InstallableParams& params, - const InstallableCallback& callback) override; + InstallableCallback callback) override; - void RunCallback(const InstallableCallback& callback); + void RunCallback(InstallableCallback callback); // Create the manager and attach it to |web_contents|. static FakeInstallableManager* CreateForWebContents(
diff --git a/chrome/browser/installable/installable_data.h b/chrome/browser/installable/installable_data.h index e56fec6..5e97145e 100644 --- a/chrome/browser/installable/installable_data.h +++ b/chrome/browser/installable/installable_data.h
@@ -76,6 +76,6 @@ DISALLOW_COPY_AND_ASSIGN(InstallableData); }; -using InstallableCallback = base::Callback<void(const InstallableData&)>; +using InstallableCallback = base::OnceCallback<void(const InstallableData&)>; #endif // CHROME_BROWSER_INSTALLABLE_INSTALLABLE_DATA_H_
diff --git a/chrome/browser/installable/installable_logging.cc b/chrome/browser/installable/installable_logging.cc index 07a3ff92..b80db18 100644 --- a/chrome/browser/installable/installable_logging.cc +++ b/chrome/browser/installable/installable_logging.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/installable/installable_logging.h" -#include "base/macros.h" #include "base/no_destructor.h" #include "base/strings/stringprintf.h" #include "chrome/browser/installable/installable_manager.h" @@ -13,76 +12,66 @@ namespace { +// Error message strings corresponding to the InstallableStatusCode enum. +static const char kNotInMainFrameMessage[] = + "Page is not loaded in the main frame"; +static const char kNotFromSecureOriginMessage[] = + "Page is not served from a secure origin"; +static const char kNoManifestMessage[] = "Page has no manifest <link> URL"; +static const char kManifestEmptyMessage[] = + "Manifest could not be fetched, is empty, or could not be parsed"; +static const char kStartUrlNotValidMessage[] = + "Manifest start URL is not valid"; +static const char kManifestMissingNameOrShortNameMessage[] = + "Manifest does not contain a 'name' or 'short_name' field"; +static const char kManifestDisplayNotSupportedMessage[] = + "Manifest 'display' property must be one of 'standalone', 'fullscreen', or " + "'minimal-ui'"; +static const char kManifestMissingSuitableIconMessage[] = + "Manifest does not contain a suitable icon - PNG format of at least " + "%dpx is required, the sizes attribute must be set, and the purpose " + "attribute, if set, must include \"any\"."; +static const char kNoMatchingServiceWorkerMessage[] = + "No matching service worker detected. You may need to reload the page, or " + "check that the service worker for the current page also controls the " + "start URL from the manifest"; +static const char kNoAcceptableIconMessage[] = + "No supplied icon is at least %dpx square in PNG format"; +static const char kCannotDownloadIconMessage[] = + "Could not download a required icon from the manifest"; +static const char kNoIconAvailableMessage[] = + "Downloaded icon was empty or corrupted"; +static const char kPlatformNotSupportedOnAndroidMessage[] = + "The specified application platform is not supported on Android"; +static const char kNoIdSpecifiedMessage[] = "No Play store ID provided"; +static const char kIdsDoNotMatchMessage[] = + "The Play Store app URL and Play Store ID do not match"; +static const char kAlreadyInstalledMessage[] = "The app is already installed"; +static const char kUrlNotSupportedForWebApkMessage[] = + "A URL in the manifest contains a username, password, or port"; +static const char kInIncognitoMessage[] = + "Page is loaded in an incognito window"; +static const char kNotOfflineCapable[] = "the page does not work offline"; +static const char kNoUrlForServiceWorker[] = + "Could not check service worker without a 'start_url' field in the " + "manifest"; + const std::string& GetMessagePrefix() { static base::NoDestructor<std::string> message_prefix( "Site cannot be installed: "); return *message_prefix; } -// Error message strings corresponding to the InstallableStatusCode enum. -static const char kRendererExitingMessage[] = - "the page is in the process of being closed"; -static const char kRendererCancelledMessage[] = - "the page has requested the banner prompt be cancelled"; -static const char kUserNavigatedMessage[] = - "the page was navigated before the banner could be shown"; -static const char kNotInMainFrameMessage[] = - "the page is not loaded in the main frame"; -static const char kNotFromSecureOriginMessage[] = - "the page is not served from a secure origin"; -static const char kNoManifestMessage[] = - "the page has no manifest <link> URL"; -static const char kManifestEmptyMessage[] = - "the manifest could not be fetched, is empty, or could not be parsed"; -static const char kStartUrlNotValidMessage[] = - "the manifest start URL is not valid"; -static const char kManifestMissingNameOrShortNameMessage[] = - "one of manifest name or short name must be specified"; -static const char kManifestDisplayNotSupportedMessage[] = - "the manifest display property must be set to 'standalone' or 'fullscreen'"; -static const char kManifestMissingSuitableIconMessage[] = - "the manifest does not contain a suitable icon - PNG format of at least " - "%dpx is required, the sizes attribute must be set, and the purpose " - "attribute, if set, must include \"any\"."; -static const char kNoMatchingServiceWorkerMessage[] = - "no matching service worker detected. You may need to reload the page, or " - "check that the service worker for the current page also controls the " - "start URL from the manifest"; -static const char kNoAcceptableIconMessage[] = - "a %dpx square PNG icon is required, but no supplied icon meets this " - "requirement"; -static const char kCannotDownloadIconMessage[] = - "could not download a required icon from the manifest"; -static const char kNoIconAvailableMessage[] = - "icon downloaded from the manifest was empty or corrupted"; -static const char kPlatformNotSupportedOnAndroidMessage[] = - "the specified application platform is not supported on Android"; -static const char kNoIdSpecifiedMessage[] = - "no Play store ID provided"; -static const char kIdsDoNotMatchMessage[] = - "a Play Store app URL and Play Store ID were specified in the manifest, " - "but they do not match"; -static const char kUrlNotSupportedForWebApkMessage[] = - "a URL in the manifest contains a username, password, or port"; -static const char kInIncognitoMessage[] = - "the page is loaded in an incognito window"; -static const char kNotOfflineCapable[] = "the page does not work offline"; -static const char kNoUrlForServiceWorker[] = - "could not check service worker for null start URL"; } // namespace -void LogErrorToConsole(content::WebContents* web_contents, - InstallableStatusCode code) { - if (!web_contents) - return; - - blink::mojom::ConsoleMessageLevel severity = - blink::mojom::ConsoleMessageLevel::kError; +std::string GetErrorMessage(InstallableStatusCode code) { std::string message; switch (code) { case NO_ERROR_DETECTED: // These codes are solely used for UMA reporting. - case ALREADY_INSTALLED: + case RENDERER_EXITING: + case RENDERER_CANCELLED: + case USER_NAVIGATED: case INSUFFICIENT_ENGAGEMENT: case PACKAGE_NAME_OR_START_URL_EMPTY: case PREVIOUSLY_BLOCKED: @@ -96,17 +85,6 @@ case WAITING_FOR_NATIVE_DATA: case SHOWING_APP_INSTALLATION_DIALOG: case MAX_ERROR_CODE: - return; - case RENDERER_EXITING: - message = kRendererExitingMessage; - break; - case RENDERER_CANCELLED: - message = kRendererCancelledMessage; - severity = blink::mojom::ConsoleMessageLevel::kInfo; - break; - case USER_NAVIGATED: - message = kUserNavigatedMessage; - severity = blink::mojom::ConsoleMessageLevel::kWarning; break; case NOT_IN_MAIN_FRAME: message = kNotInMainFrameMessage; @@ -150,7 +128,6 @@ break; case PLATFORM_NOT_SUPPORTED_ON_ANDROID: message = kPlatformNotSupportedOnAndroidMessage; - severity = blink::mojom::ConsoleMessageLevel::kWarning; break; case NO_ID_SPECIFIED: message = kNoIdSpecifiedMessage; @@ -158,6 +135,9 @@ case IDS_DO_NOT_MATCH: message = kIdsDoNotMatchMessage; break; + case ALREADY_INSTALLED: + message = kAlreadyInstalledMessage; + break; case URL_NOT_SUPPORTED_FOR_WEBAPK: message = kUrlNotSupportedForWebApkMessage; break; @@ -172,6 +152,19 @@ break; } + return message; +} + +void LogErrorToConsole(content::WebContents* web_contents, + InstallableStatusCode code) { + if (!web_contents) + return; + + std::string message = GetErrorMessage(code); + + if (message.empty()) + return; + web_contents->GetMainFrame()->AddMessageToConsole( - severity, GetMessagePrefix() + message); + blink::mojom::ConsoleMessageLevel::kError, GetMessagePrefix() + message); }
diff --git a/chrome/browser/installable/installable_logging.h b/chrome/browser/installable/installable_logging.h index c8902ad..7cf4e3a 100644 --- a/chrome/browser/installable/installable_logging.h +++ b/chrome/browser/installable/installable_logging.h
@@ -56,6 +56,10 @@ MAX_ERROR_CODE, }; +// Returns a user-readable description for |code|, or an empty string if |code| +// should not be exposed. +std::string GetErrorMessage(InstallableStatusCode code); + // Logs a message associated with |code| to the devtools console attached to // |web_contents|. Does nothing if |web_contents| is nullptr. void LogErrorToConsole(content::WebContents* web_contents,
diff --git a/chrome/browser/installable/installable_manager.cc b/chrome/browser/installable/installable_manager.cc index 3a05c64..e899743 100644 --- a/chrome/browser/installable/installable_manager.cc +++ b/chrome/browser/installable/installable_manager.cc
@@ -4,8 +4,11 @@ #include "chrome/browser/installable/installable_manager.h" +#include <utility> + #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/callback.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "build/build_config.h" @@ -130,6 +133,19 @@ params.valid_primary_icon; } +void OnDidCompleteGetAllErrors( + base::OnceCallback<void(std::vector<std::string> errors)> callback, + const InstallableData& data) { + std::vector<std::string> error_messages; + for (auto error : data.errors) { + std::string message = GetErrorMessage(error); + if (!message.empty()) + error_messages.push_back(std::move(message)); + } + + std::move(callback).Run(std::move(error_messages)); +} + } // namespace InstallableManager::EligiblityProperty::EligiblityProperty() = default; @@ -185,7 +201,7 @@ } void InstallableManager::GetData(const InstallableParams& params, - const InstallableCallback& callback) { + InstallableCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (IsParamsForPwaCheck(params)) @@ -194,7 +210,7 @@ // Return immediately if we're already working on a task. The new task will be // looked at once the current task is finished. bool was_active = task_queue_.HasCurrent(); - task_queue_.Add({params, callback}); + task_queue_.Add({params, std::move(callback)}); if (was_active) return; @@ -202,6 +218,20 @@ WorkOnTask(); } +void InstallableManager::GetAllErrors( + base::OnceCallback<void(std::vector<std::string> errors)> callback) { + InstallableParams params; + params.check_eligibility = true; + params.valid_manifest = true; + params.check_webapp_manifest_display = true; + params.has_worker = true; + params.valid_primary_icon = true; + params.wait_for_worker = false; + params.is_debug_mode = true; + GetData(params, + base::BindOnce(OnDidCompleteGetAllErrors, std::move(callback))); +} + void InstallableManager::RecordMenuOpenHistogram() { metrics_->RecordMenuOpen(); } @@ -406,7 +436,7 @@ } void InstallableManager::RunCallback( - const InstallableTask& task, + InstallableTask task, std::vector<InstallableStatusCode> errors) { const InstallableParams& params = task.params; IconProperty null_icon; @@ -429,18 +459,21 @@ worker_->has_worker, }; - task.callback.Run(data); + std::move(task.callback).Run(data); } void InstallableManager::WorkOnTask() { - const InstallableTask& task = task_queue_.Current(); - const InstallableParams& params = task.params; + if (!task_queue_.HasCurrent()) + return; + + const InstallableParams& params = task_queue_.Current().params; auto errors = GetErrors(params); bool check_passed = errors.empty(); if ((!check_passed && !params.is_debug_mode) || IsComplete(params)) { + auto task = std::move(task_queue_.Current()); ResolveMetrics(params, check_passed); - RunCallback(task, std::move(errors)); + RunCallback(std::move(task), std::move(errors)); // Sites can always register a service worker after we finish checking, so // don't cache a missing service worker error to ensure we always check @@ -449,10 +482,7 @@ worker_ = std::make_unique<ServiceWorkerProperty>(); task_queue_.Next(); - - if (task_queue_.HasCurrent()) - WorkOnTask(); - + WorkOnTask(); return; } @@ -504,8 +534,8 @@ content::WebContents* web_contents = GetWebContents(); DCHECK(web_contents); - web_contents->GetManifest(base::Bind(&InstallableManager::OnDidGetManifest, - weak_factory_.GetWeakPtr())); + web_contents->GetManifest(base::BindOnce( + &InstallableManager::OnDidGetManifest, weak_factory_.GetWeakPtr())); } void InstallableManager::OnDidGetManifest(const GURL& manifest_url, @@ -589,8 +619,8 @@ // Check to see if there is a service worker for the manifest's start url. service_worker_context_->CheckHasServiceWorker( manifest().start_url, - base::Bind(&InstallableManager::OnDidCheckHasServiceWorker, - weak_factory_.GetWeakPtr())); + base::BindOnce(&InstallableManager::OnDidCheckHasServiceWorker, + weak_factory_.GetWeakPtr())); } void InstallableManager::OnDidCheckHasServiceWorker( @@ -614,9 +644,7 @@ task.params.wait_for_worker = false; OnWaitingForServiceWorker(); task_queue_.PauseCurrent(); - if (task_queue_.HasCurrent()) - WorkOnTask(); - + WorkOnTask(); return; } worker_->has_worker = false; @@ -659,11 +687,10 @@ void InstallableManager::OnIconFetched(const GURL icon_url, const IconPurpose purpose, const SkBitmap& bitmap) { - IconProperty& icon = icons_[purpose]; - if (!GetWebContents()) return; + IconProperty& icon = icons_[purpose]; if (bitmap.drawsNothing()) { icon.error = NO_ICON_AVAILABLE; } else { @@ -694,8 +721,7 @@ if (was_active) return; // If the pipeline was already running, we don't restart it. - if (task_queue_.HasCurrent()) - WorkOnTask(); + WorkOnTask(); } void InstallableManager::DidFinishNavigation(
diff --git a/chrome/browser/installable/installable_manager.h b/chrome/browser/installable/installable_manager.h index 5995a75..9b6716a8 100644 --- a/chrome/browser/installable/installable_manager.h +++ b/chrome/browser/installable/installable_manager.h
@@ -7,9 +7,9 @@ #include <map> #include <memory> -#include <utility> #include <vector> +#include "base/callback_forward.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -40,18 +40,23 @@ static int GetMinimumIconSizeInPx(); // Get the installable data, fetching the resources specified in |params|. - // |callback| is invoked synchronously (i.e. no via PostTask on the UI thread + // |callback| is invoked synchronously (i.e. not via PostTask on the UI thread // when the data is ready; the synchronous execution ensures that the // references |callback| receives in its InstallableData argument are valid. // - // Clients must be prepared for |callback| to not ever be invoked. For - // instance, if installability checking is requested, this method will wait - // until the site registers a service worker (and hence not invoke |callback| - // at all if a service worker is never registered). + // |callback| may never be invoked if |params.wait_for_worker| is true, or if + // the user navigates the page before fetching is complete. // - // Calls requesting data that is already fetched will return the cached data. + // Calls requesting data that has already been fetched will return the cached + // data. virtual void GetData(const InstallableParams& params, - const InstallableCallback& callback); + InstallableCallback callback); + + // Runs the full installability check, and when finished, runs |callback| + // passing a list of human-readable strings describing the errors encountered + // during the run. The list is empty if no errors were encountered. + void GetAllErrors( + base::OnceCallback<void(std::vector<std::string> errors)> callback); // Called via AppBannerManagerAndroid to record metrics on how often the // installable check is completed when the menu or add to homescreen menu item @@ -183,7 +188,7 @@ void SetManifestDependentTasksComplete(); // Methods coordinating and dispatching work for the current task. - void RunCallback(const InstallableTask& task, + void RunCallback(InstallableTask task, std::vector<InstallableStatusCode> errors); void WorkOnTask();
diff --git a/chrome/browser/installable/installable_manager_browsertest.cc b/chrome/browser/installable/installable_manager_browsertest.cc index 80c42fd5..53725cf 100644 --- a/chrome/browser/installable/installable_manager_browsertest.cc +++ b/chrome/browser/installable/installable_manager_browsertest.cc
@@ -8,8 +8,10 @@ #include "base/command_line.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind_test_util.h" #include "base/test/metrics/histogram_tester.h" #include "chrome/browser/banners/app_banner_manager_desktop.h" +#include "chrome/browser/installable/installable_logging.h" #include "chrome/browser/installable/installable_manager.h" #include "chrome/browser/installable/installable_metrics.h" #include "chrome/browser/ui/browser.h" @@ -129,7 +131,7 @@ quit_closure_.Run(); } - const std::vector<InstallableStatusCode> errors() const { return errors_; } + const std::vector<InstallableStatusCode>& errors() const { return errors_; } const GURL& manifest_url() const { return manifest_url_; } const blink::Manifest& manifest() const { return manifest_; } const GURL& primary_icon_url() const { return primary_icon_url_; } @@ -162,9 +164,9 @@ : manager_(manager), params_(params), quit_closure_(quit_closure) {} void Run() { - manager_->GetData(params_, - base::Bind(&NestedCallbackTester::OnDidFinishFirstCheck, - base::Unretained(this))); + manager_->GetData( + params_, base::BindOnce(&NestedCallbackTester::OnDidFinishFirstCheck, + base::Unretained(this))); } void OnDidFinishFirstCheck(const InstallableData& data) { @@ -177,9 +179,9 @@ valid_manifest_ = data.valid_manifest; has_worker_ = data.has_worker; - manager_->GetData(params_, - base::Bind(&NestedCallbackTester::OnDidFinishSecondCheck, - base::Unretained(this))); + manager_->GetData( + params_, base::BindOnce(&NestedCallbackTester::OnDidFinishSecondCheck, + base::Unretained(this))); } void OnDidFinishSecondCheck(const InstallableData& data) { @@ -238,13 +240,31 @@ RunInstallableManager(browser, tester, params); } + std::vector<std::string> NavigateAndGetAllErrors(Browser* browser, + const std::string& url) { + GURL test_url = embedded_test_server()->GetURL(url); + ui_test_utils::NavigateToURL(browser, test_url); + InstallableManager* manager = GetManager(browser); + + base::RunLoop run_loop; + std::vector<std::string> result; + + manager->GetAllErrors( + base::BindLambdaForTesting([&](std::vector<std::string> errors) { + result = std::move(errors); + run_loop.Quit(); + })); + run_loop.Run(); + return result; + } + void RunInstallableManager(Browser* browser, CallbackTester* tester, const InstallableParams& params) { InstallableManager* manager = GetManager(browser); - manager->GetData(params, - base::Bind(&CallbackTester::OnDidFinishInstallableCheck, - base::Unretained(tester))); + manager->GetData( + params, base::BindOnce(&CallbackTester::OnDidFinishInstallableCheck, + base::Unretained(tester))); } InstallableManager* GetManager(Browser* browser) { @@ -949,9 +969,10 @@ // Set up a GetData call which will not record an installable metric to // ensure we wait until the previous check has finished. - manager->GetData(GetManifestParams(), - base::Bind(&CallbackTester::OnDidFinishInstallableCheck, - base::Unretained(tester.get()))); + manager->GetData( + GetManifestParams(), + base::BindOnce(&CallbackTester::OnDidFinishInstallableCheck, + base::Unretained(tester.get()))); run_loop.Run(); ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); @@ -980,9 +1001,10 @@ // Set up a GetData call which will not record an installable metric to // ensure we wait until the previous check has finished. - manager->GetData(GetManifestParams(), - base::Bind(&CallbackTester::OnDidFinishInstallableCheck, - base::Unretained(tester.get()))); + manager->GetData( + GetManifestParams(), + base::BindOnce(&CallbackTester::OnDidFinishInstallableCheck, + base::Unretained(tester.get()))); run_loop.Run(); ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); @@ -1085,9 +1107,10 @@ ui_test_utils::NavigateToURL(browser(), test_url); // Kick off fetching the data. This should block on waiting for a worker. - manager->GetData(GetWebAppParams(), - base::Bind(&CallbackTester::OnDidFinishInstallableCheck, - base::Unretained(tester.get()))); + manager->GetData( + GetWebAppParams(), + base::BindOnce(&CallbackTester::OnDidFinishInstallableCheck, + base::Unretained(tester.get()))); sw_run_loop.Run(); } @@ -1113,9 +1136,10 @@ base::RunLoop run_loop; std::unique_ptr<CallbackTester> nested_tester( new CallbackTester(run_loop.QuitClosure())); - manager->GetData(GetPrimaryIconParams(), - base::Bind(&CallbackTester::OnDidFinishInstallableCheck, - base::Unretained(nested_tester.get()))); + manager->GetData( + GetPrimaryIconParams(), + base::BindOnce(&CallbackTester::OnDidFinishInstallableCheck, + base::Unretained(nested_tester.get()))); run_loop.Run(); EXPECT_FALSE(nested_tester->manifest().IsEmpty()); @@ -1179,8 +1203,8 @@ // Kick off fetching the data. This should block on waiting for a worker. manager->GetData(GetWebAppParams(), - base::Bind(&CallbackTester::OnDidFinishInstallableCheck, - base::Unretained(tester.get()))); + base::BindOnce(&CallbackTester::OnDidFinishInstallableCheck, + base::Unretained(tester.get()))); sw_run_loop.Run(); // We should now be waiting for the service worker. @@ -1228,9 +1252,10 @@ ui_test_utils::NavigateToURL(browser(), test_url); // Kick off fetching the data. This should block on waiting for a worker. - manager->GetData(GetWebAppParams(), - base::Bind(&CallbackTester::OnDidFinishInstallableCheck, - base::Unretained(tester.get()))); + manager->GetData( + GetWebAppParams(), + base::BindOnce(&CallbackTester::OnDidFinishInstallableCheck, + base::Unretained(tester.get()))); sw_run_loop.Run(); } @@ -1284,9 +1309,9 @@ InstallableParams params = GetWebAppParams(); params.wait_for_worker = false; - manager->GetData(params, - base::Bind(&CallbackTester::OnDidFinishInstallableCheck, - base::Unretained(tester.get()))); + manager->GetData( + params, base::BindOnce(&CallbackTester::OnDidFinishInstallableCheck, + base::Unretained(tester.get()))); tester_run_loop.Run(); // We should have returned with an error. @@ -1303,9 +1328,9 @@ new CallbackTester(tester_run_loop.QuitClosure())); InstallableParams params = GetWebAppParams(); - manager->GetData(params, - base::Bind(&CallbackTester::OnDidFinishInstallableCheck, - base::Unretained(tester.get()))); + manager->GetData( + params, base::BindOnce(&CallbackTester::OnDidFinishInstallableCheck, + base::Unretained(tester.get()))); sw_run_loop.Run(); EXPECT_TRUE(content::ExecuteScript( @@ -1495,9 +1520,10 @@ std::unique_ptr<CallbackTester> tester( new CallbackTester(run_loop.QuitClosure())); - manager->GetData(GetWebAppParams(), - base::Bind(&CallbackTester::OnDidFinishInstallableCheck, - base::Unretained(tester.get()))); + manager->GetData( + GetWebAppParams(), + base::BindOnce(&CallbackTester::OnDidFinishInstallableCheck, + base::Unretained(tester.get()))); run_loop.Run(); EXPECT_TRUE(tester->manifest().IsEmpty()); @@ -1523,9 +1549,10 @@ std::unique_ptr<CallbackTester> tester( new CallbackTester(run_loop.QuitClosure())); - manager->GetData(GetWebAppParams(), - base::Bind(&CallbackTester::OnDidFinishInstallableCheck, - base::Unretained(tester.get()))); + manager->GetData( + GetWebAppParams(), + base::BindOnce(&CallbackTester::OnDidFinishInstallableCheck, + base::Unretained(tester.get()))); run_loop.Run(); EXPECT_FALSE(tester->manifest().IsEmpty()); @@ -1555,9 +1582,10 @@ std::unique_ptr<CallbackTester> tester( new CallbackTester(run_loop.QuitClosure())); - manager->GetData(GetWebAppParams(), - base::Bind(&CallbackTester::OnDidFinishInstallableCheck, - base::Unretained(tester.get()))); + manager->GetData( + GetWebAppParams(), + base::BindOnce(&CallbackTester::OnDidFinishInstallableCheck, + base::Unretained(tester.get()))); run_loop.Run(); EXPECT_FALSE(tester->manifest().IsEmpty()); @@ -1606,6 +1634,33 @@ tester->errors()); } +IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest, GetAllErrorsNoErrors) { + EXPECT_EQ( + std::vector<std::string>{}, + NavigateAndGetAllErrors(browser(), "/banners/manifest_test_page.html")); +} + +IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest, + GetAllErrorsWithNoManifest) { + EXPECT_EQ(std::vector<std::string>{GetErrorMessage(NO_MANIFEST)}, + NavigateAndGetAllErrors(browser(), + "/banners/no_manifest_test_page.html")); +} + +IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest, + GetAllErrorsWithPlayAppManifest) { + EXPECT_EQ(std::vector<std::string>( + {GetErrorMessage(START_URL_NOT_VALID), + GetErrorMessage(MANIFEST_MISSING_NAME_OR_SHORT_NAME), + GetErrorMessage(MANIFEST_DISPLAY_NOT_SUPPORTED), + GetErrorMessage(MANIFEST_MISSING_SUITABLE_ICON), + GetErrorMessage(NO_URL_FOR_SERVICE_WORKER), + GetErrorMessage(NO_ACCEPTABLE_ICON)}), + NavigateAndGetAllErrors(browser(), + GetURLOfPageWithServiceWorkerAndManifest( + "/banners/play_app_manifest.json"))); +} + IN_PROC_BROWSER_TEST_F(InstallableManagerWhitelistOriginBrowserTest, SecureOriginCheckRespectsUnsafeFlag) { // The whitelisted origin should be regarded as secure.
diff --git a/chrome/browser/installable/installable_task_queue.cc b/chrome/browser/installable/installable_task_queue.cc index 6672db3..0151c8757 100644 --- a/chrome/browser/installable/installable_task_queue.cc +++ b/chrome/browser/installable/installable_task_queue.cc
@@ -2,34 +2,41 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <utility> + #include "chrome/browser/installable/installable_task_queue.h" -InstallableTask::InstallableTask() {} -InstallableTask::InstallableTask(const InstallableParams& params, - const InstallableCallback& callback) - : params(params), callback(callback) {} -InstallableTask::~InstallableTask() {} -InstallableTask::InstallableTask(const InstallableTask& other) = default; -InstallableTask& InstallableTask::operator=(const InstallableTask& other) = - default; +InstallableTask::InstallableTask() = default; -InstallableTaskQueue::InstallableTaskQueue() {} -InstallableTaskQueue::~InstallableTaskQueue() {} +InstallableTask::InstallableTask(const InstallableParams& params, + InstallableCallback callback) + : params(params), callback(std::move(callback)) {} + +InstallableTask::~InstallableTask() = default; + +InstallableTask::InstallableTask(InstallableTask&& other) = default; + +InstallableTask& InstallableTask::operator=(InstallableTask&& other) = default; + +InstallableTaskQueue::InstallableTaskQueue() = default; + +InstallableTaskQueue::~InstallableTaskQueue() = default; void InstallableTaskQueue::Add(InstallableTask task) { - tasks_.push_back(task); + tasks_.push_back(std::move(task)); } void InstallableTaskQueue::PauseCurrent() { - paused_tasks_.push_back(Current()); + DCHECK(HasCurrent()); + paused_tasks_.push_back(std::move(Current())); Next(); } void InstallableTaskQueue::UnpauseAll() { - for (const auto& task : paused_tasks_) - Add(task); - - paused_tasks_.clear(); + while (!paused_tasks_.empty()) { + Add(std::move(paused_tasks_.front())); + paused_tasks_.pop_front(); + } } bool InstallableTaskQueue::HasCurrent() const { @@ -41,13 +48,13 @@ } InstallableTask& InstallableTaskQueue::Current() { - DCHECK(!tasks_.empty()); - return tasks_[0]; + DCHECK(HasCurrent()); + return tasks_.front(); } void InstallableTaskQueue::Next() { - DCHECK(!tasks_.empty()); - tasks_.erase(tasks_.begin()); + DCHECK(HasCurrent()); + tasks_.pop_front(); } void InstallableTaskQueue::Reset() {
diff --git a/chrome/browser/installable/installable_task_queue.h b/chrome/browser/installable/installable_task_queue.h index 4f4ca9f..2a8b4e5 100644 --- a/chrome/browser/installable/installable_task_queue.h +++ b/chrome/browser/installable/installable_task_queue.h
@@ -5,23 +5,27 @@ #ifndef CHROME_BROWSER_INSTALLABLE_INSTALLABLE_TASK_QUEUE_H_ #define CHROME_BROWSER_INSTALLABLE_INSTALLABLE_TASK_QUEUE_H_ -#include "chrome/browser/installable/installable_data.h" -#include "chrome/browser/installable/installable_params.h" +#include <deque> #include "base/callback.h" #include "base/gtest_prod_util.h" +#include "base/macros.h" +#include "chrome/browser/installable/installable_data.h" +#include "chrome/browser/installable/installable_params.h" struct InstallableTask { InstallableTask(); InstallableTask(const InstallableParams& params, - const InstallableCallback& callback); - InstallableTask(const InstallableTask& other); + InstallableCallback callback); + InstallableTask(InstallableTask&& other); ~InstallableTask(); - InstallableTask& operator=(const InstallableTask& other); + InstallableTask& operator=(InstallableTask&& other); InstallableParams params; InstallableCallback callback; + + DISALLOW_COPY_AND_ASSIGN(InstallableTask); }; // InstallableTaskQueue keeps track of pending tasks. @@ -55,19 +59,19 @@ void Reset(); private: - // The list of <params, callback> pairs that have come from a call to - // InstallableManager::GetData. - std::vector<InstallableTask> tasks_; - - // Tasks which are waiting indefinitely for a service worker to be detected. - std::vector<InstallableTask> paused_tasks_; - friend class InstallableManagerBrowserTest; FRIEND_TEST_ALL_PREFIXES(InstallableManagerBrowserTest, CheckLazyServiceWorkerPassesWhenWaiting); FRIEND_TEST_ALL_PREFIXES(InstallableManagerBrowserTest, CheckLazyServiceWorkerNoFetchHandlerFails); + + // The list of <params, callback> pairs that have come from a call to + // InstallableManager::GetData. + std::deque<InstallableTask> tasks_; + + // Tasks which are waiting indefinitely for a service worker to be detected. + std::deque<InstallableTask> paused_tasks_; }; #endif // CHROME_BROWSER_INSTALLABLE_INSTALLABLE_TASK_QUEUE_H_
diff --git a/chrome/browser/installable/installable_task_queue_unittest.cc b/chrome/browser/installable/installable_task_queue_unittest.cc index a9ecf0c..710c0c7b 100644 --- a/chrome/browser/installable/installable_task_queue_unittest.cc +++ b/chrome/browser/installable/installable_task_queue_unittest.cc
@@ -1,73 +1,101 @@ // Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/installable/installable_manager.h" +#include "chrome/browser/installable/installable_task_queue.h" + +#include "chrome/browser/installable/installable_manager.h" #include "testing/gtest/include/gtest/gtest.h" -using IconPurpose = blink::Manifest::ImageResource::Purpose; - -class InstallableTaskQueueUnitTest : public testing::Test {}; +// A POD struct which holds booleans for creating and comparing against +// a (move-only) InstallableTask. +struct TaskParams { + bool valid_manifest = false; + bool has_worker = false; + bool valid_primary_icon = false; + bool valid_badge_icon = false; +}; // Constructs an InstallableTask, with the supplied bools stored in it. -InstallableTask CreateTask(bool valid_manifest, - bool has_worker, - bool valid_primary_icon, - bool valid_badge_icon) { +InstallableTask CreateTask(const TaskParams& params) { InstallableTask task; - task.params.valid_manifest = valid_manifest; - task.params.has_worker = has_worker; - task.params.valid_primary_icon = valid_primary_icon; - task.params.valid_badge_icon = valid_badge_icon; + task.params.valid_manifest = params.valid_manifest; + task.params.has_worker = params.has_worker; + task.params.valid_primary_icon = params.valid_primary_icon; + task.params.valid_badge_icon = params.valid_badge_icon; return task; } -bool IsEqual(const InstallableTask& task1, const InstallableTask& task2) { - return task1.params.valid_manifest == task2.params.valid_manifest && - task1.params.has_worker == task2.params.has_worker && - task1.params.valid_primary_icon == task2.params.valid_primary_icon && - task1.params.valid_badge_icon == task2.params.valid_badge_icon; +bool IsEqual(const TaskParams& params, const InstallableTask& task) { + return task.params.valid_manifest == params.valid_manifest && + task.params.has_worker == params.has_worker && + task.params.valid_primary_icon == params.valid_primary_icon && + task.params.valid_badge_icon == params.valid_badge_icon; } +class InstallableTaskQueueUnitTest : public testing::Test {}; + TEST_F(InstallableTaskQueueUnitTest, PausingMakesNextTaskAvailable) { InstallableTaskQueue task_queue; - InstallableTask task1 = CreateTask(false, false, false, false); - InstallableTask task2 = CreateTask(true, true, true, true); + TaskParams task1 = {false, false, false, false}; + TaskParams task2 = {true, true, true, true}; - task_queue.Add(task1); - task_queue.Add(task2); + EXPECT_FALSE(task_queue.HasCurrent()); + EXPECT_FALSE(task_queue.HasPaused()); + task_queue.Add(CreateTask(task1)); + task_queue.Add(CreateTask(task2)); + + EXPECT_TRUE(task_queue.HasCurrent()); + EXPECT_FALSE(task_queue.HasPaused()); EXPECT_TRUE(IsEqual(task1, task_queue.Current())); + // There is another task in the main queue, so it becomes current. task_queue.PauseCurrent(); + EXPECT_TRUE(task_queue.HasCurrent()); + EXPECT_TRUE(task_queue.HasPaused()); EXPECT_TRUE(IsEqual(task2, task_queue.Current())); + + task_queue.Reset(); + EXPECT_FALSE(task_queue.HasCurrent()); + EXPECT_FALSE(task_queue.HasPaused()); } TEST_F(InstallableTaskQueueUnitTest, PausedTaskCanBeRetrieved) { InstallableTaskQueue task_queue; - InstallableTask task1 = CreateTask(false, false, false, false); - InstallableTask task2 = CreateTask(true, true, true, true); + TaskParams task1 = {false, false, false, false}; + TaskParams task2 = {true, true, true, true}; - task_queue.Add(task1); - task_queue.Add(task2); + task_queue.Add(CreateTask(task1)); + task_queue.Add(CreateTask(task2)); EXPECT_TRUE(IsEqual(task1, task_queue.Current())); task_queue.PauseCurrent(); + EXPECT_TRUE(task_queue.HasCurrent()); + EXPECT_TRUE(task_queue.HasPaused()); EXPECT_TRUE(IsEqual(task2, task_queue.Current())); task_queue.UnpauseAll(); + // We've unpaused "1", but "2" is still current. + EXPECT_TRUE(task_queue.HasCurrent()); + EXPECT_FALSE(task_queue.HasPaused()); EXPECT_TRUE(IsEqual(task2, task_queue.Current())); task_queue.Next(); + EXPECT_TRUE(task_queue.HasCurrent()); EXPECT_TRUE(IsEqual(task1, task_queue.Current())); + + task_queue.Reset(); + EXPECT_FALSE(task_queue.HasCurrent()); + EXPECT_FALSE(task_queue.HasPaused()); } TEST_F(InstallableTaskQueueUnitTest, NextDiscardsTask) { InstallableTaskQueue task_queue; - InstallableTask task1 = CreateTask(false, false, false, false); - InstallableTask task2 = CreateTask(true, true, true, true); + TaskParams task1 = {false, false, false, false}; + TaskParams task2 = {true, true, true, true}; - task_queue.Add(task1); - task_queue.Add(task2); + task_queue.Add(CreateTask(task1)); + task_queue.Add(CreateTask(task2)); EXPECT_TRUE(IsEqual(task1, task_queue.Current())); task_queue.Next();
diff --git a/chrome/browser/metrics/google_update_metrics_provider_win.cc b/chrome/browser/metrics/google_update_metrics_provider_win.cc index f19ff2a8..e1cb5c3 100644 --- a/chrome/browser/metrics/google_update_metrics_provider_win.cc +++ b/chrome/browser/metrics/google_update_metrics_provider_win.cc
@@ -5,9 +5,13 @@ #include "chrome/browser/metrics/google_update_metrics_provider_win.h" #include "base/location.h" +#include "base/metrics/histogram_functions.h" +#include "base/metrics/metrics_hashes.h" #include "base/single_thread_task_runner.h" +#include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" #include "base/threading/thread_task_runner_handle.h" +#include "chrome/install_static/install_details.h" #include "third_party/metrics_proto/system_profile.pb.h" typedef metrics::SystemProfileProto::GoogleUpdate::ProductInfo ProductInfo; @@ -17,7 +21,7 @@ // Helper function for checking if this is an official build. Used instead of // the macro to allow checking for successful code compilation on non-official // builds. -bool IsOfficialBuild() { +bool IsGoogleChromeBuild() { #if defined(GOOGLE_CHROME_BUILD) return true; #else @@ -49,7 +53,7 @@ void GoogleUpdateMetricsProviderWin::AsyncInit( const base::Closure& done_callback) { - if (!IsOfficialBuild()) { + if (!IsGoogleChromeBuild()) { base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, done_callback); return; } @@ -65,9 +69,16 @@ void GoogleUpdateMetricsProviderWin::ProvideSystemProfileMetrics( metrics::SystemProfileProto* system_profile_proto) { - if (!IsOfficialBuild()) + // Do nothing for chromium builds. + if (!IsGoogleChromeBuild()) return; - + // Convert wstring to string. + std::string update_cohort_name = base::WideToUTF8( + install_static::InstallDetails::Get().update_cohort_name()); + // TODO(nikunjb): Once update_cohort_name is added to system profile + // update the code here. + base::UmaHistogramSparse("GoogleUpdate.InstallDetails.UpdateCohort", + base::HashMetricName(update_cohort_name)); metrics::SystemProfileProto::GoogleUpdate* google_update = system_profile_proto->mutable_google_update(); @@ -107,7 +118,7 @@ GoogleUpdateMetricsProviderWin::GetGoogleUpdateDataBlocking() { GoogleUpdateMetrics google_update_metrics; - if (!IsOfficialBuild()) + if (!IsGoogleChromeBuild()) return google_update_metrics; const bool is_system_install = GoogleUpdateSettings::IsSystemInstall();
diff --git a/chrome/browser/metrics/tab_stats_tracker.cc b/chrome/browser/metrics/tab_stats_tracker.cc index 87334be..fc5ec1a 100644 --- a/chrome/browser/metrics/tab_stats_tracker.cc +++ b/chrome/browser/metrics/tab_stats_tracker.cc
@@ -12,6 +12,7 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/power_monitor/power_monitor.h" +#include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/resource_coordinator/lifecycle_unit.h" @@ -115,6 +116,17 @@ "Discarding.ReloadsPer10Minutes.Urgent", }; +static_assert(base::size(kTabDiscardCountHistogramNames) == + static_cast<size_t>(LifecycleUnitDiscardReason::kMaxValue) + + 1, + "There must be an entry in kTabDiscardCountHistogramNames for " + "each discard reason."); +static_assert(base::size(kTabReloadCountHistogramNames) == + static_cast<size_t>(LifecycleUnitDiscardReason::kMaxValue) + + 1, + "There must be an entry in kTabReloadCountHistogramNames for " + "each discard reason."); + const TabStatsDataStore::TabsStats& TabStatsTracker::tab_stats() const { return tab_stats_data_store_->tab_stats(); } @@ -353,7 +365,7 @@ void TabStatsTracker::OnTabDiscardCountReportInterval() { for (size_t reason = 0; - reason < static_cast<size_t>(LifecycleUnitDiscardReason::kMaxValue); + reason < static_cast<size_t>(LifecycleUnitDiscardReason::kMaxValue) + 1; reason++) { base::UmaHistogramCounts100( kTabDiscardCountHistogramNames[reason],
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc index be00203..2cb825db 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc
@@ -14,8 +14,10 @@ #include "base/time/default_tick_clock.h" #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" #include "chrome/browser/page_load_metrics/page_load_metrics_util.h" +#include "chrome/browser/page_load_metrics/resource_tracker.h" #include "components/subresource_filter/core/common/common_features.h" #include "components/ukm/content/source_url_recorder.h" +#include "content/public/browser/global_request_id.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -132,7 +134,7 @@ // The main frame is never considered an ad. ad_frames_data_[navigation_handle->GetFrameTreeNodeId()] = nullptr; - ProcessOngoingNavigationResource(navigation_handle->GetFrameTreeNodeId()); + ProcessOngoingNavigationResource(navigation_handle->GetRenderFrameHost()); return CONTINUE_OBSERVING; } @@ -177,7 +179,7 @@ if (id_and_data != ad_frames_data_.end() && id_and_data->second) { DCHECK(frame_navigated); if (id_and_data->second->frame_navigated()) { - ProcessOngoingNavigationResource(ad_id); + ProcessOngoingNavigationResource(ad_host); return; } previous_data = id_and_data->second; @@ -269,7 +271,7 @@ RecordAdFrameData(frame_tree_node_id, is_adframe, ad_host, /*frame_navigated=*/true); - ProcessOngoingNavigationResource(frame_tree_node_id); + ProcessOngoingNavigationResource(ad_host); } void AdsPageLoadMetricsObserver::FrameReceivedFirstUserActivation( @@ -332,8 +334,11 @@ content::RenderFrameHost* rfh, const std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr>& resources) { - for (auto const& resource : resources) - UpdateResource(rfh, resource); + for (auto const& resource : resources) { + ProcessResourceForPage(rfh->GetProcess()->GetID(), resource); + ProcessResourceForFrame(rfh->GetFrameTreeNodeId(), + rfh->GetProcess()->GetID(), resource); + } } void AdsPageLoadMetricsObserver::OnSubframeNavigationEvaluated( @@ -435,13 +440,56 @@ return DetectSubresourceFilterAd(navigation_handle->GetFrameTreeNodeId()); } +int AdsPageLoadMetricsObserver::GetUnaccountedAdBytes( + int process_id, + const page_load_metrics::mojom::ResourceDataUpdatePtr& resource) const { + if (!resource->reported_as_ad_resource) + return 0; + content::GlobalRequestID global_request_id(process_id, resource->request_id); + + // Resource just started loading. + if (!GetDelegate()->GetResourceTracker().HasPreviousUpdateForResource( + global_request_id)) + return 0; + + // If the resource had already started loading, and is now labeled as an ad, + // but was not before, we need to account for all the previously received + // bytes. + auto const& previous_update = + GetDelegate()->GetResourceTracker().GetPreviousUpdateForResource( + global_request_id); + bool is_new_ad = !previous_update->reported_as_ad_resource; + return is_new_ad ? resource->received_data_length - resource->delta_bytes : 0; +} + +void AdsPageLoadMetricsObserver::ProcessResourceForPage( + int process_id, + const page_load_metrics::mojom::ResourceDataUpdatePtr& resource) { + // Log per-resource histograms for complete resources. + if (resource->is_complete) + RecordResourceHistograms(resource); + + auto mime_type = FrameData::GetResourceMimeType(resource); + int unaccounted_ad_bytes = GetUnaccountedAdBytes(process_id, resource); + aggregate_frame_data_->ProcessResourceLoadInFrame(resource); + if (unaccounted_ad_bytes) + aggregate_frame_data_->AdjustAdBytes(unaccounted_ad_bytes, mime_type); + if (resource->is_main_frame_resource) { + main_frame_data_->ProcessResourceLoadInFrame(resource); + if (unaccounted_ad_bytes) + main_frame_data_->AdjustAdBytes(unaccounted_ad_bytes, mime_type); + } +} + void AdsPageLoadMetricsObserver::ProcessResourceForFrame( FrameTreeNodeId frame_tree_node_id, + int process_id, const page_load_metrics::mojom::ResourceDataUpdatePtr& resource) { const auto& id_and_data = ad_frames_data_.find(frame_tree_node_id); if (id_and_data == ad_frames_data_.end()) { if (resource->is_primary_frame_resource) { - // Only hold onto primary resources if their load has finished. + // Only hold onto primary resources if their load has finished, otherwise + // we will receive a future update for them if the navigation finishes. if (!resource->is_complete) return; @@ -461,16 +509,17 @@ return; } - aggregate_frame_data_->ProcessResourceLoadInFrame(resource); - if (resource->is_main_frame_resource) - main_frame_data_->ProcessResourceLoadInFrame(resource); - // Determine if the frame (or its ancestor) is an ad, if so attribute the // bytes to the highest ad ancestor. FrameData* ancestor_data = id_and_data->second; if (!ancestor_data) return; + + auto mime_type = FrameData::GetResourceMimeType(resource); + int unaccounted_ad_bytes = GetUnaccountedAdBytes(process_id, resource); ancestor_data->ProcessResourceLoadInFrame(resource); + if (unaccounted_ad_bytes) + ancestor_data->AdjustAdBytes(unaccounted_ad_bytes, mime_type); if (ancestor_data->size_intervention_status() == FrameData::FrameSizeInterventionStatus::kTriggered) { @@ -480,57 +529,6 @@ } } -void AdsPageLoadMetricsObserver::AdjustAdBytesForFrame( - FrameTreeNodeId frame_tree_node_id, - const page_load_metrics::mojom::ResourceDataUpdatePtr& resource, - int64_t unaccounted_ad_bytes) { - const auto& id_and_data = ad_frames_data_.find(frame_tree_node_id); - FrameData* ancestor_data = id_and_data->second; - if (!ancestor_data) - return; - ancestor_data->AdjustAdBytes(unaccounted_ad_bytes, - FrameData::GetResourceMimeType(resource)); -} - -void AdsPageLoadMetricsObserver::UpdateResource( - content::RenderFrameHost* rfh, - const page_load_metrics::mojom::ResourceDataUpdatePtr& resource) { - content::GlobalRequestID global_id(rfh->GetProcess()->GetID(), - resource->request_id); - ProcessResourceForFrame(rfh->GetFrameTreeNodeId(), resource); - auto it = page_resources_.find(global_id); - - if (resource->reported_as_ad_resource) { - // If the resource had already started loading, and is now labeled as an ad, - // but was not before, we need to account for all the previously received - // bytes. - bool is_new_ad = - (it != page_resources_.end()) && !it->second->reported_as_ad_resource; - int unaccounted_ad_bytes = - is_new_ad ? resource->received_data_length - resource->delta_bytes : 0; - if (unaccounted_ad_bytes) - AdjustAdBytesForFrame(rfh->GetFrameTreeNodeId(), resource, - unaccounted_ad_bytes); - } - - // Update resource map. - if (resource->is_complete) { - RecordResourceHistograms(resource); - if (it != page_resources_.end()) - page_resources_.erase(it); - } else { - // Must clone resource so it will be accessible when the observer is - // destroyed. - if (it != page_resources_.end()) { - it->second = resource->Clone(); - } else { - page_resources_.emplace(std::piecewise_construct, - std::forward_as_tuple(global_id), - std::forward_as_tuple(resource->Clone())); - } - } -} - void AdsPageLoadMetricsObserver::RecordResourceMimeHistograms( const page_load_metrics::mojom::ResourceDataUpdatePtr& resource) { int64_t data_length = resource->was_fetched_via_cache @@ -590,11 +588,11 @@ PAGE_BYTES_HISTOGRAM("PageLoad.Clients.Ads.Resources.Bytes.Ads", aggregate_frame_data_->ad_bytes()); size_t unfinished_bytes = 0; - for (auto const& kv : page_resources_) + for (auto const& kv : + GetDelegate()->GetResourceTracker().unfinished_resources()) unfinished_bytes += kv.second->received_data_length; PAGE_BYTES_HISTOGRAM("PageLoad.Clients.Ads.Resources.Bytes.Unfinished", unfinished_bytes); - auto* ukm_recorder = ukm::UkmRecorder::Get(); ukm::builders::AdPageLoad builder(source_id); builder.SetTotalBytes(aggregate_frame_data_->network_bytes() >> 10) @@ -632,8 +630,10 @@ RecordHistogramsForAdTagging(FrameData::FrameVisibility::kVisible); RecordHistogramsForAdTagging(FrameData::FrameVisibility::kAnyVisibility); RecordPageResourceTotalHistograms(source_id); - for (auto const& kv : page_resources_) + for (auto const& kv : + GetDelegate()->GetResourceTracker().unfinished_resources()) { RecordResourceHistograms(kv.second); + } } // Computes a percentage given the numerator and denominator, bounded to 100%. @@ -886,12 +886,14 @@ } void AdsPageLoadMetricsObserver::ProcessOngoingNavigationResource( - FrameTreeNodeId frame_tree_node_id) { + content::RenderFrameHost* rfh) { + if (!rfh) + return; const auto& frame_id_and_request = - ongoing_navigation_resources_.find(frame_tree_node_id); + ongoing_navigation_resources_.find(rfh->GetFrameTreeNodeId()); if (frame_id_and_request == ongoing_navigation_resources_.end()) return; - - ProcessResourceForFrame(frame_tree_node_id, frame_id_and_request->second); + ProcessResourceForFrame(rfh->GetFrameTreeNodeId(), rfh->GetProcess()->GetID(), + frame_id_and_request->second); ongoing_navigation_resources_.erase(frame_id_and_request); }
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h index cc7dcab..a5b493ea 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h
@@ -19,7 +19,6 @@ #include "components/subresource_filter/content/browser/subresource_filter_observer.h" #include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h" #include "components/subresource_filter/core/common/load_policy.h" -#include "content/public/browser/global_request_id.h" #include "net/http/http_response_info.h" #include "services/metrics/public/cpp/ukm_source.h" @@ -107,20 +106,19 @@ // each call in order to free up memory. bool DetectAds(content::NavigationHandle* navigation_handle); + // Gets the number of bytes that we may have not attributed to ad + // resources due to the resource being reported as an ad late. + int GetUnaccountedAdBytes( + int process_id, + const page_load_metrics::mojom::ResourceDataUpdatePtr& resource) const; + + // Updates page level counters for resource loads. + void ProcessResourceForPage( + int process_id, + const page_load_metrics::mojom::ResourceDataUpdatePtr& resource); void ProcessResourceForFrame( FrameTreeNodeId frame_tree_node_id, - const page_load_metrics::mojom::ResourceDataUpdatePtr& resource); - - void AdjustAdBytesForFrame( - FrameTreeNodeId frame_tree_node_id, - const page_load_metrics::mojom::ResourceDataUpdatePtr& resource, - int64_t unaccounted_ad_bytes); - - // Update all of the per-resource page counters given a new resource data - // update. Updates |page_resources_| to reflect the new state of the resource. - // Called once per ResourceDataUpdate. - void UpdateResource( - content::RenderFrameHost* rfh, + int process_id, const page_load_metrics::mojom::ResourceDataUpdatePtr& resource); // Records size of resources by mime type. @@ -134,10 +132,11 @@ void RecordHistograms(ukm::SourceId source_id); void RecordHistogramsForAdTagging(FrameData::FrameVisibility visibility); void RecordHistogramsForCpuUsage(FrameData::FrameVisibility visibility); - // Checks to see if a resource is waiting for a navigation with the given - // |frame_tree_node_id| to commit before it can be processed. If so, call + + // Checks to see if a resource is waiting for a navigation in the given + // RenderFrameHost to commit before it can be processed. If so, call // OnResourceDataUpdate for the delayed resource. - void ProcessOngoingNavigationResource(FrameTreeNodeId frame_tree_node_id); + void ProcessOngoingNavigationResource(content::RenderFrameHost* rfh); // Stores the size data of each ad frame. Pointed to by ad_frames_ so use a // data structure that won't move the data around. @@ -161,15 +160,6 @@ std::map<FrameTreeNodeId, page_load_metrics::mojom::ResourceDataUpdatePtr> ongoing_navigation_resources_; - // Maps a GlobalRequestId consisting of (request_id, process_id) for a blink - // resource to the metadata for the resource load. GlobalRequestIds are used - // because this map aggregates across renderers and blink request ids are - // unique per-renderer. Only contains resources that have not completed - // loading. - std::map<content::GlobalRequestID, - page_load_metrics::mojom::ResourceDataUpdatePtr> - page_resources_; - // Tracks byte counts only for resources loaded in the main frame. std::unique_ptr<FrameData> main_frame_data_;
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc index 08c694e..9b680f5 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc
@@ -291,7 +291,8 @@ ResourceCached resource_cached, int resource_size_in_kbyte, std::string mime_type = "", - bool is_ad_resource = false) { + bool is_ad_resource = false, + bool is_main_frame_resource = false) { std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr> resources; page_load_metrics::mojom::ResourceDataUpdatePtr resource = page_load_metrics::mojom::ResourceDataUpdate::New(); @@ -304,6 +305,9 @@ resource->was_fetched_via_cache = static_cast<bool>(resource_cached); resource->mime_type = mime_type; resource->is_primary_frame_resource = true; + resource->is_main_frame_resource = + render_frame_host->GetFrameTreeNodeId() == + main_rfh()->GetFrameTreeNodeId(); resources.push_back(std::move(resource)); tester_->SimulateResourceDataUseUpdate(resources, render_frame_host); } @@ -689,14 +693,16 @@ ConfigureAsSubresourceFilterOnlyURL(GURL(kNonAdUrl)); NavigateMainFrame(kNonAdUrl); - ResourceDataUpdate(main_rfh(), ResourceCached::NOT_CACHED, 10); + ResourceDataUpdate(main_rfh(), ResourceCached::NOT_CACHED, 10, + "" /* mime_type */, false /* is_ad_resource */); RenderFrameHost* subframe = RenderFrameHostTester::For(main_rfh())->AppendChild("foo"); std::unique_ptr<NavigationSimulator> simulator = NavigationSimulator::CreateRendererInitiated(GURL(kDefaultDisallowedUrl), subframe); - ResourceDataUpdate(subframe, ResourceCached::CACHED, 10); + ResourceDataUpdate(subframe, ResourceCached::NOT_CACHED, 10, + "" /* mime_type */, true /* is_ad_resource */); simulator->Commit(); EXPECT_NE(content::NavigationThrottle::PROCEED, @@ -705,6 +711,8 @@ NavigateMainFrame(kNonAdUrl); TestHistograms(histogram_tester(), std::vector<ExpectedFrameBytes>(), 0u /* non_ad_cached_kb */, 0u /* non_ad_uncached_kb */); + histogram_tester().ExpectUniqueSample( + "Ads.ResourceUsage.Size.Network.Subframe.AdResource", 10, 1); } // UKM metrics for ad page load are recorded correctly.
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_observer_delegate.h b/chrome/browser/page_load_metrics/page_load_metrics_observer_delegate.h index 6171fa5..38cf1fc 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_observer_delegate.h +++ b/chrome/browser/page_load_metrics/page_load_metrics_observer_delegate.h
@@ -7,12 +7,15 @@ #include "base/optional.h" #include "base/time/time.h" +#include "chrome/browser/page_load_metrics/resource_tracker.h" #include "chrome/browser/scoped_visibility_tracker.h" namespace content { class WebContents; } // namespace content +namespace page_load_metrics { + // This class tracks global state for the page load that should be accessible // from any PageLoadMetricsObserver. class PageLoadMetricsObserverDelegate { @@ -22,8 +25,12 @@ virtual bool DidCommit() const = 0; virtual const ScopedVisibilityTracker& GetVisibilityTracker() const = 0; + virtual const ResourceTracker& GetResourceTracker() const = 0; + // TODO(crbug/939403): Consider migrating PageLoadExtraInfo data to this API // and deprecating that struct. }; +} // namespace page_load_metrics + #endif // CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_METRICS_OBSERVER_DELEGATE_H_
diff --git a/chrome/browser/page_load_metrics/page_load_tracker.cc b/chrome/browser/page_load_metrics/page_load_tracker.cc index 7af9b16..901cde1 100644 --- a/chrome/browser/page_load_metrics/page_load_tracker.cc +++ b/chrome/browser/page_load_metrics/page_load_tracker.cc
@@ -21,6 +21,7 @@ #include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "services/metrics/public/cpp/ukm_source_id.h" @@ -704,6 +705,8 @@ void PageLoadTracker::UpdateResourceDataUse( content::RenderFrameHost* rfh, const std::vector<mojom::ResourceDataUpdatePtr>& resources) { + resource_tracker_.UpdateResourceDataUse(rfh->GetProcess()->GetID(), + resources); for (const auto& observer : observers_) { observer->OnResourceDataUseObserved(rfh, resources); } @@ -732,4 +735,8 @@ return visibility_tracker_; } +const ResourceTracker& PageLoadTracker::GetResourceTracker() const { + return resource_tracker_; +} + } // namespace page_load_metrics
diff --git a/chrome/browser/page_load_metrics/page_load_tracker.h b/chrome/browser/page_load_metrics/page_load_tracker.h index 025866a..316ead692 100644 --- a/chrome/browser/page_load_metrics/page_load_tracker.h +++ b/chrome/browser/page_load_metrics/page_load_tracker.h
@@ -14,6 +14,7 @@ #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/page_load_metrics_observer_delegate.h" #include "chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.h" +#include "chrome/browser/page_load_metrics/resource_tracker.h" #include "chrome/browser/scoped_visibility_tracker.h" #include "chrome/common/page_load_metrics/page_load_timing.h" #include "content/public/browser/global_request_id.h" @@ -198,6 +199,7 @@ base::TimeTicks GetNavigationStart() const override; bool DidCommit() const override; const ScopedVisibilityTracker& GetVisibilityTracker() const override; + const ResourceTracker& GetResourceTracker() const override; void Redirect(content::NavigationHandle* navigation_handle); void WillProcessNavigationResponse( @@ -400,6 +402,9 @@ // always be less than or equal to |aborted_chain_size_|. const int aborted_chain_size_same_url_; + // Keeps track of actively loading resources on the page. + ResourceTracker resource_tracker_; + // Interface to chrome features. Must outlive the class. PageLoadMetricsEmbedderInterface* const embedder_interface_;
diff --git a/chrome/browser/page_load_metrics/resource_tracker.cc b/chrome/browser/page_load_metrics/resource_tracker.cc new file mode 100644 index 0000000..f7ffd3e --- /dev/null +++ b/chrome/browser/page_load_metrics/resource_tracker.cc
@@ -0,0 +1,69 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/page_load_metrics/resource_tracker.h" + +#include <tuple> + +namespace page_load_metrics { + +ResourceTracker::ResourceTracker() = default; + +ResourceTracker::~ResourceTracker() = default; + +void ResourceTracker::UpdateResourceDataUse( + int process_id, + const std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr>& + resources) { + // Clear the map of previous updates to prevent completed resources from + // remaining in the map. This is safe because the map is only expected + // to contain updates for resources that have actively received new data. + previous_resource_updates_.clear(); + for (auto const& resource : resources) { + ProcessResourceUpdate(process_id, resource); + } +} + +void ResourceTracker::ProcessResourceUpdate( + int process_id, + const page_load_metrics::mojom::ResourceDataUpdatePtr& resource) { + content::GlobalRequestID global_id(process_id, resource->request_id); + auto it = unfinished_resources_.find(global_id); + + // This is the first update received for a resource. + if (it == unfinished_resources_.end()) { + if (!resource->is_complete) { + unfinished_resources_.emplace(std::piecewise_construct, + std::forward_as_tuple(global_id), + std::forward_as_tuple(resource->Clone())); + } + return; + } + + // Update the map of previous resource data now that we have a new data update + // for a tracked resource. + previous_resource_updates_[global_id] = it->second->Clone(); + + // Either update the unfinished resource data or remove it from the map if it + // completed. Must clone resource so it will be accessible when the observer + // is destroyed. + if (resource->is_complete) + unfinished_resources_.erase(it); + else + it->second = resource->Clone(); +} + +bool ResourceTracker::HasPreviousUpdateForResource( + content::GlobalRequestID request_id) const { + return previous_resource_updates_.count(request_id) != 0; +} + +const page_load_metrics::mojom::ResourceDataUpdatePtr& +ResourceTracker::GetPreviousUpdateForResource( + content::GlobalRequestID request_id) const { + DCHECK(HasPreviousUpdateForResource(request_id)); + return previous_resource_updates_.find(request_id)->second; +} + +} // namespace page_load_metrics
diff --git a/chrome/browser/page_load_metrics/resource_tracker.h b/chrome/browser/page_load_metrics/resource_tracker.h new file mode 100644 index 0000000..e1476b46 --- /dev/null +++ b/chrome/browser/page_load_metrics/resource_tracker.h
@@ -0,0 +1,68 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_RESOURCE_TRACKER_H_ +#define CHROME_BROWSER_PAGE_LOAD_METRICS_RESOURCE_TRACKER_H_ + +#include <map> +#include <memory> +#include <vector> + +#include "chrome/common/page_load_metrics/page_load_metrics.mojom.h" +#include "content/public/browser/global_request_id.h" + +namespace page_load_metrics { + +// Tracks individual resource loads on the page. +class ResourceTracker { + public: + // Maps a request id for a blink resource to the metadata for the resource + // load. GlobalRequestIDs are used because this map may aggregate across + // renderers and blink request ids are unique per-renderer. + using ResourceMap = std::map<content::GlobalRequestID, + page_load_metrics::mojom::ResourceDataUpdatePtr>; + + ResourceTracker(); + ~ResourceTracker(); + + // Updates map of ongoing resource loads given a new update. |process_id| is + // the id of renderer process where the update originated and is used to + // create globally unique resource ids. + void UpdateResourceDataUse( + int process_id, + const std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr>& + resources); + + const ResourceMap& unfinished_resources() const { + return unfinished_resources_; + } + + // Previous ResourceDataUseUpdate objects are only stored for resources that + // are still actively loaded. These methods should only be used for resources + // that were received by observers in + // PageLoadMetricsObserver::OnResourceDataUseObserved(). + bool HasPreviousUpdateForResource(content::GlobalRequestID request_id) const; + const page_load_metrics::mojom::ResourceDataUpdatePtr& + GetPreviousUpdateForResource(content::GlobalRequestID request_id) const; + + private: + void ProcessResourceUpdate( + int process_id, + const page_load_metrics::mojom::ResourceDataUpdatePtr& resource); + + // Stores all resources that have started loading on the page but have + // not completed loading. + ResourceMap unfinished_resources_; + + // Maps a request_id for a blink resource to the previous ResourceDataUpdate + // received for the resource. This only stores previous updates for + // resources that are still actively receiving updates. A resource that was + // unfinished then completes will have its previous update in this map until + // the next call to UpdateResourceDataUse(). + ResourceMap previous_resource_updates_; +}; + +} // namespace page_load_metrics + +#endif // CHROME_BROWSER_PAGE_LOAD_METRICS_RESOURCE_TRACKER_H_
diff --git a/chrome/browser/page_load_metrics/resource_tracker_unittest.cc b/chrome/browser/page_load_metrics/resource_tracker_unittest.cc new file mode 100644 index 0000000..21d45b1e --- /dev/null +++ b/chrome/browser/page_load_metrics/resource_tracker_unittest.cc
@@ -0,0 +1,151 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <utility> + +#include "chrome/browser/page_load_metrics/resource_tracker.h" +#include "chrome/common/page_load_metrics/page_load_metrics.mojom.h" +#include "content/public/browser/global_request_id.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +class ResourceTrackerTest : public testing::Test { + public: + ResourceTrackerTest() = default; + + void StartResourceLoad(int resource_id, bool is_complete = false) { + CreateResourceUpdate(resource_id, 0 /* delta_bytes */, + is_complete /* is_complete */); + } + + void AdvanceResourceLoad(int resource_id, int bytes = 0) { + CreateResourceUpdate(resource_id, bytes /* delta_bytes */, + false /* is_complete */); + } + + void CompleteResourceLoad(int resource_id) { + CreateResourceUpdate(resource_id, 0 /* delta_bytes */, + true /* is_complete */); + } + + bool HasUnfinishedResource(int resource_id) { + return resource_tracker_.unfinished_resources().find( + content::GlobalRequestID(process_id_, resource_id)) != + resource_tracker_.unfinished_resources().end(); + } + + int GetUnfinishedResourceBytes(int resource_id) { + return resource_tracker_.unfinished_resources() + .find(content::GlobalRequestID(process_id_, resource_id)) + ->second->delta_bytes; + } + + bool HasPreviousUpdateForResource(int resource_id) { + return resource_tracker_.HasPreviousUpdateForResource( + content::GlobalRequestID(process_id_, resource_id)); + } + + int GetPreviousResourceUpdateBytes(int resource_id) { + return resource_tracker_ + .GetPreviousUpdateForResource( + content::GlobalRequestID(process_id_, resource_id)) + ->delta_bytes; + } + + private: + void CreateResourceUpdate(int request_id, + int64_t delta_bytes, + bool is_complete) { + std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr> resources; + auto resource_data_update = + page_load_metrics::mojom::ResourceDataUpdate::New(); + resource_data_update->request_id = request_id; + resource_data_update->delta_bytes = delta_bytes; + resource_data_update->is_complete = is_complete; + resources.push_back(std::move(resource_data_update)); + resource_tracker_.UpdateResourceDataUse(process_id_, resources); + } + + const int process_id_ = 0; + + page_load_metrics::ResourceTracker resource_tracker_; +}; + +// Verifies that resources are added to and removed from the map +// of ongoing resource loads as expected. +TEST_F(ResourceTrackerTest, UnfinishedResourceMap) { + StartResourceLoad(0 /* resource_id */); + StartResourceLoad(1 /* resource_id */); + StartResourceLoad(2 /* resource_id */); + + // Verify completed resources are not stored in the unfinished map. + EXPECT_TRUE(HasUnfinishedResource(0 /* resource_id */)); + CompleteResourceLoad(0 /* resource_id */); + EXPECT_FALSE(HasUnfinishedResource(0 /* resource_id */)); + + // Verify that resources receiving multiple updates are not removed from the + // map. + AdvanceResourceLoad(1 /* resource_id */, 10 /* bytes */); + AdvanceResourceLoad(1 /* resource_id */, 20 /* bytes */); + EXPECT_TRUE(HasUnfinishedResource(1 /* resource_id */)); + CompleteResourceLoad(1 /* resource_id */); + EXPECT_FALSE(HasUnfinishedResource(1 /* resource_id */)); + + // Verify the unfinished map stores the most recent resource update. + EXPECT_EQ(0, GetUnfinishedResourceBytes(2 /* resource_id */)); + AdvanceResourceLoad(2 /* resource_id */, 10 /* bytes */); + EXPECT_EQ(10, GetUnfinishedResourceBytes(2 /* resource_id */)); + AdvanceResourceLoad(2 /* resource_id */, 20 /* bytes */); + AdvanceResourceLoad(2 /* resource_id */, 30 /* bytes */); + EXPECT_EQ(30, GetUnfinishedResourceBytes(2 /* resource_id */)); +} + +// Verifies that resources are added to and removed from the map +// of previous resource updates as expected. +TEST_F(ResourceTrackerTest, PreviousUpdateResourceMap) { + StartResourceLoad(0 /* resource_id */); + StartResourceLoad(1 /* resource_id */); + EXPECT_FALSE(HasPreviousUpdateForResource(0 /* resource_id */)); + EXPECT_FALSE(HasPreviousUpdateForResource(1 /* resource_id */)); + + AdvanceResourceLoad(1 /* resource_id */, 10 /* bytes */); + EXPECT_TRUE(HasPreviousUpdateForResource(1 /* resource_id */)); + + // Previous resource update should only be available for resources + // who received resource updates in the previous call to + // ResourceTracker::UpdateResourceDataUse(). resource_id "1" should not be + // available in this case. + AdvanceResourceLoad(0 /* resource_id */, 0 /* bytes */); + EXPECT_FALSE(HasPreviousUpdateForResource(1 /* resource_id */)); + + // The update should not be available because the load for resource_id "1" was + // still ongoing. This should hold the data for the last update, 10 bytes. + AdvanceResourceLoad(1 /* resource_id */, 20 /* bytes */); + EXPECT_TRUE(HasPreviousUpdateForResource(1 /* resource_id */)); + EXPECT_EQ(10, GetPreviousResourceUpdateBytes(1 /* resource_id */)); + + // Verify previous resource update is available for newly complete resources. + CompleteResourceLoad(1 /* resource_id */); + EXPECT_TRUE(HasPreviousUpdateForResource(1 /* resource_id */)); + EXPECT_EQ(20, GetPreviousResourceUpdateBytes(1 /* resource_id */)); + + // Verify this completed resource update is removed once other resources are + // loaded. + CompleteResourceLoad(0 /* resource_id */); + EXPECT_FALSE(HasPreviousUpdateForResource(1 /* resource_id */)); +} + +TEST_F(ResourceTrackerTest, SingleUpdateResourceNotStored) { + // Verify that resources who only receive one update and complete are never + // stored. + StartResourceLoad(0 /* resource_id */, true /* is_complete */); + EXPECT_FALSE(HasUnfinishedResource(0 /* resource_id */)); + EXPECT_FALSE(HasPreviousUpdateForResource(0 /* resource_id */)); + + // Load new resource and verify we don't have a previous update for the + // resource that completed. + StartResourceLoad(1 /* resource_id */, true /* is_complete */); + EXPECT_FALSE(HasUnfinishedResource(0 /* resource_id */)); + EXPECT_FALSE(HasPreviousUpdateForResource(0 /* resource_id */)); +}
diff --git a/chrome/browser/resource_coordinator/tab_activity_watcher.cc b/chrome/browser/resource_coordinator/tab_activity_watcher.cc index 35a20ef..b4b16399 100644 --- a/chrome/browser/resource_coordinator/tab_activity_watcher.cc +++ b/chrome/browser/resource_coordinator/tab_activity_watcher.cc
@@ -21,7 +21,6 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/tabs/window_activity_watcher.h" #include "components/ukm/content/source_url_recorder.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_handle.h" @@ -415,7 +414,7 @@ // For window features. tab_ranker::WindowFeatures window = - WindowActivityWatcher::CreateWindowFeatures(browser); + TabMetricsLogger::CreateWindowFeatures(browser); tab.window_is_active = window.is_active; tab.window_show_state = window.show_state; tab.window_tab_count = window.tab_count; @@ -512,10 +511,6 @@ : tab_metrics_logger_(std::make_unique<TabMetricsLogger>()), browser_tab_strip_tracker_(this, this, this) { browser_tab_strip_tracker_.Init(); - - // TabMetrics UKMs reference WindowMetrics UKM entries, so ensure the - // WindowActivityWatcher is initialized. - WindowActivityWatcher::GetInstance(); } TabActivityWatcher::~TabActivityWatcher() = default;
diff --git a/chrome/browser/resource_coordinator/tab_metrics_logger.cc b/chrome/browser/resource_coordinator/tab_metrics_logger.cc index 28493d78..f00efa8 100644 --- a/chrome/browser/resource_coordinator/tab_metrics_logger.cc +++ b/chrome/browser/resource_coordinator/tab_metrics_logger.cc
@@ -7,16 +7,20 @@ #include <algorithm> #include <string> +#include "base/logging.h" #include "base/stl_util.h" #include "base/time/time.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/resource_coordinator/tab_metrics_event.pb.h" #include "chrome/browser/resource_coordinator/tab_ranker/mru_features.h" #include "chrome/browser/resource_coordinator/tab_ranker/tab_features.h" +#include "chrome/browser/resource_coordinator/tab_ranker/window_features.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/recently_audible_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "content/public/browser/render_frame_host.h" @@ -28,6 +32,7 @@ #include "url/gurl.h" using metrics::TabMetricsEvent; +using metrics::WindowMetricsEvent; namespace { @@ -197,3 +202,37 @@ .SetTimeSinceNavigation(time_since_navigation.InMilliseconds()) .Record(ukm::UkmRecorder::Get()); } + +// static +tab_ranker::WindowFeatures TabMetricsLogger::CreateWindowFeatures( + const Browser* browser) { + DCHECK(browser->window()); + + WindowMetricsEvent::Type window_type = WindowMetricsEvent::TYPE_UNKNOWN; + switch (browser->type()) { + case Browser::TYPE_TABBED: + window_type = WindowMetricsEvent::TYPE_TABBED; + break; + case Browser::TYPE_POPUP: + window_type = WindowMetricsEvent::TYPE_POPUP; + break; + default: + NOTREACHED(); + } + + WindowMetricsEvent::ShowState show_state = + WindowMetricsEvent::SHOW_STATE_UNKNOWN; + if (browser->window()->IsFullscreen()) + show_state = WindowMetricsEvent::SHOW_STATE_FULLSCREEN; + else if (browser->window()->IsMinimized()) + show_state = WindowMetricsEvent::SHOW_STATE_MINIMIZED; + else if (browser->window()->IsMaximized()) + show_state = WindowMetricsEvent::SHOW_STATE_MAXIMIZED; + else + show_state = WindowMetricsEvent::SHOW_STATE_NORMAL; + + const bool is_active = browser->window()->IsActive(); + const int tab_count = browser->tab_strip_model()->count(); + + return {window_type, show_state, is_active, tab_count}; +}
diff --git a/chrome/browser/resource_coordinator/tab_metrics_logger.h b/chrome/browser/resource_coordinator/tab_metrics_logger.h index 519d188..f1f0f0f 100644 --- a/chrome/browser/resource_coordinator/tab_metrics_logger.h +++ b/chrome/browser/resource_coordinator/tab_metrics_logger.h
@@ -22,6 +22,7 @@ namespace tab_ranker { struct TabFeatures; +struct WindowFeatures; } // namespace tab_ranker // Logs metrics for a tab and its WebContents when requested. @@ -100,6 +101,10 @@ const TabMetrics& tab_metrics, base::TimeDelta inactive_duration); + // Returns a populated WindowFeatures for the browser. + static tab_ranker::WindowFeatures CreateWindowFeatures( + const Browser* browser); + void set_query_id(int64_t query_id) { query_id_ = query_id; } private:
diff --git a/chrome/browser/resource_coordinator/tab_metrics_logger_interactive_uitest.cc b/chrome/browser/resource_coordinator/tab_metrics_logger_interactive_uitest.cc new file mode 100644 index 0000000..68f10a3 --- /dev/null +++ b/chrome/browser/resource_coordinator/tab_metrics_logger_interactive_uitest.cc
@@ -0,0 +1,186 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/resource_coordinator/tab_metrics_logger.h" + +#include <memory> + +#include "base/macros.h" +#include "build/build_config.h" +#include "chrome/browser/resource_coordinator/tab_metrics_event.pb.h" +#include "chrome/browser/resource_coordinator/tab_ranker/window_features.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/interactive_test_utils.h" +#include "chrome/test/base/ui_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +using metrics::WindowMetricsEvent; +using tab_ranker::WindowFeatures; + +const char* kTestUrl = "https://example.com/"; + +// Tests WindowFeatures generated by TabMetricsLogger::CreateWindowFeatures due +// to interactive changes to window state. +class CreateWindowFeaturesTest : public InProcessBrowserTest { + protected: + CreateWindowFeaturesTest() = default; + + // InProcessBrowserTest: + void PreRunTestOnMainThread() override { + InProcessBrowserTest::PreRunTestOnMainThread(); + } + + void SetUpOnMainThread() override { +#if defined(OS_MACOSX) + // On Mac, the browser window needs to be forced to the front. This will + // create a UKM entry for the activation because it happens after the + // WindowActivityWatcher creation. On other platforms, activation happens + // before creation, and as a result, no UKM entry is created. + // TODO(crbug.com/650859): Reassess after activation is restored in the + // focus manager. + ui_test_utils::BrowserActivationWaiter waiter(browser()); + ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); + waiter.WaitForActivation(); + ASSERT_TRUE(browser()->window()->IsActive()); +#endif + } + + private: + DISALLOW_COPY_AND_ASSIGN(CreateWindowFeaturesTest); +}; + +// Tests WindowMetrics of the current browser window. +IN_PROC_BROWSER_TEST_F(CreateWindowFeaturesTest, Basic) { + WindowFeatures expected_metrics{WindowMetricsEvent::TYPE_TABBED, + WindowMetricsEvent::SHOW_STATE_NORMAL, true, + 1}; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser()), + expected_metrics); + + // Updated metrics after adding tabs. + { + SCOPED_TRACE(""); + AddTabAtIndex(1, GURL(kTestUrl), ui::PAGE_TRANSITION_LINK); + expected_metrics.tab_count++; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser()), + expected_metrics); + } + { + SCOPED_TRACE(""); + AddTabAtIndex(0, GURL(kTestUrl), ui::PAGE_TRANSITION_LINK); + expected_metrics.tab_count++; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser()), + expected_metrics); + } + + // Closing the window doesn't log more WindowMetrics UKMs. + CloseBrowserSynchronously(browser()); +} + +// TODO(https://crbug.com/51364): Implement BrowserWindow::Deactivate() on Mac. +#if !defined(OS_MACOSX) +// Tests WindowMetrics by activating/deactivating the window. +IN_PROC_BROWSER_TEST_F(CreateWindowFeaturesTest, WindowActivation) { + WindowFeatures expected_metrics{WindowMetricsEvent::TYPE_TABBED, + WindowMetricsEvent::SHOW_STATE_NORMAL, false, + 1}; + + { + SCOPED_TRACE(""); + ui_test_utils::BrowserDeactivationWaiter waiter(browser()); + browser()->window()->Deactivate(); + waiter.WaitForDeactivation(); + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser()), + expected_metrics); + } + + { + SCOPED_TRACE(""); + ui_test_utils::BrowserActivationWaiter waiter(browser()); + browser()->window()->Activate(); + waiter.WaitForActivation(); + ASSERT_TRUE(browser()->window()->IsActive()); + expected_metrics.is_active = true; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser()), + expected_metrics); + } + + // Closing the window doesn't log more WindowMetrics UKMs. + CloseBrowserSynchronously(browser()); +} + +// Tests WindowMetrics when switching between windows. +IN_PROC_BROWSER_TEST_F(CreateWindowFeaturesTest, MultipleWindows) { + // Create a new browser window. + Browser* browser_2 = CreateBrowser(browser()->profile()); + WindowFeatures expected_metrics{WindowMetricsEvent::TYPE_TABBED, + WindowMetricsEvent::SHOW_STATE_NORMAL, false, + 1}; + WindowFeatures expected_metrics_2{WindowMetricsEvent::TYPE_TABBED, + WindowMetricsEvent::SHOW_STATE_NORMAL, + false, 1}; + + // Wait for the old window to be deactivated and the new window to be + // activated if they aren't yet. + { + ui_test_utils::BrowserActivationWaiter waiter(browser_2); + waiter.WaitForActivation(); + expected_metrics_2.is_active = true; + } + { + ui_test_utils::BrowserDeactivationWaiter waiter(browser()); + waiter.WaitForDeactivation(); + } + { + SCOPED_TRACE(""); + // Check for activation and deactivation. + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser_2), + expected_metrics_2); + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser()), + expected_metrics); + } + { + SCOPED_TRACE(""); + ui_test_utils::BrowserActivationWaiter activation_waiter(browser()); + ui_test_utils::BrowserDeactivationWaiter deactivation_waiter(browser_2); + + // Switch back to the first window. + // Note: use Activate() rather than Show() because on some platforms, Show() + // calls SetLastActive() before doing anything else. + browser()->window()->Activate(); + + activation_waiter.WaitForActivation(); + deactivation_waiter.WaitForDeactivation(); + + expected_metrics.is_active = true; + expected_metrics_2.is_active = false; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser()), + expected_metrics); + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser_2), + expected_metrics_2); + } + + CloseBrowserSynchronously(browser()); + + // GetLastActive could return browser2 if browser1 was active and then was + // removed, so browser2 might not actually be active. + { + ui_test_utils::BrowserActivationWaiter activation_waiter(browser_2); + browser_2->window()->Activate(); + activation_waiter.WaitForActivation(); + } + EXPECT_TRUE(BrowserList::GetInstance()->GetLastActive() == browser_2); + EXPECT_TRUE(browser_2->window()->IsActive()); + { + SCOPED_TRACE(""); + expected_metrics_2.is_active = true; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser_2), + expected_metrics_2); + } +} + +#endif // !defined(OS_MACOSX)
diff --git a/chrome/browser/resource_coordinator/tab_metrics_logger_unittest.cc b/chrome/browser/resource_coordinator/tab_metrics_logger_unittest.cc index 37af7826..b36cf31 100644 --- a/chrome/browser/resource_coordinator/tab_metrics_logger_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_metrics_logger_unittest.cc
@@ -4,13 +4,20 @@ #include "chrome/browser/resource_coordinator/tab_metrics_logger.h" +#include <memory> +#include <vector> + #include "base/containers/flat_map.h" +#include "base/macros.h" #include "base/test/scoped_task_environment.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/engagement/site_engagement_service.h" +#include "chrome/browser/resource_coordinator/tab_metrics_event.pb.h" #include "chrome/browser/resource_coordinator/tab_ranker/tab_features.h" #include "chrome/browser/resource_coordinator/tab_ranker/tab_features_test_helper.h" +#include "chrome/browser/resource_coordinator/tab_ranker/window_features.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/tabs/tab_activity_simulator.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" @@ -20,13 +27,88 @@ #include "content/public/browser/web_contents.h" #include "content/public/test/web_contents_tester.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/ui_base_types.h" using content::WebContentsTester; +using metrics::WindowMetricsEvent; +using tab_ranker::WindowFeatures; // Sanity checks for functions in TabMetricsLogger. // See TabActivityWatcherTest for more thorough tab usage UKM tests. using TabMetricsLoggerTest = ChromeRenderViewHostTestHarness; +namespace { + +const char* kTestUrl = "https://example.com/"; + +// TestBrowserWindow whose show state can be modified. +class FakeBrowserWindow : public TestBrowserWindow { + public: + FakeBrowserWindow() = default; + ~FakeBrowserWindow() override = default; + + // Helper function to handle FakeBrowserWindow lifetime. Modeled after + // CreateBrowserWithTestWindowForParams. + static std::unique_ptr<Browser> CreateBrowserWithFakeWindowForParams( + Browser::CreateParams* params) { + // TestBrowserWindowOwner takes ownersip of the window and will destroy the + // window (along with itself) automatically when the browser is closed. + FakeBrowserWindow* window = new FakeBrowserWindow; + new TestBrowserWindowOwner(window); + + params->window = window; + auto browser = std::make_unique<Browser>(*params); + window->browser_ = browser.get(); + window->Activate(); + return browser; + } + + // TestBrowserWindow: + void Activate() override { + if (is_active_) + return; + is_active_ = true; + // With a real view, activating would update the BrowserList. + BrowserList::SetLastActive(browser_); + } + void Deactivate() override { + if (!is_active_) + return; + is_active_ = false; + // With a real view, deactivating would notify the BrowserList. + BrowserList::NotifyBrowserNoLongerActive(browser_); + } + bool IsActive() const override { return is_active_; } + bool IsMaximized() const override { + return show_state_ == ui::SHOW_STATE_MAXIMIZED; + } + bool IsMinimized() const override { + return show_state_ == ui::SHOW_STATE_MINIMIZED; + } + void Maximize() override { + show_state_ = ui::SHOW_STATE_MAXIMIZED; + Activate(); + } + void Minimize() override { + show_state_ = ui::SHOW_STATE_MINIMIZED; + Deactivate(); + } + void Restore() override { + // This isn't true "restore" behavior. + show_state_ = ui::SHOW_STATE_NORMAL; + Activate(); + } + + private: + Browser* browser_; + bool is_active_ = false; + ui::WindowShowState show_state_ = ui::SHOW_STATE_NORMAL; + + DISALLOW_COPY_AND_ASSIGN(FakeBrowserWindow); +}; + +} // namespace + // Tests creating a flat TabFeatures structure for logging a tab and its // TabMetrics state. TEST_F(TabMetricsLoggerTest, GetTabFeatures) { @@ -239,3 +321,160 @@ {"TotalTabCount", foc_metrics.total_tab_count}, }); } + +// Tests WindowFeatures generated by CreateWindowFeatures. +class CreateWindowFeaturesTest : public ChromeRenderViewHostTestHarness { + protected: + CreateWindowFeaturesTest() = default; + ~CreateWindowFeaturesTest() override = default; + + // Adds a tab and simulates a basic navigation. + void AddTab(Browser* browser) { + content::WebContentsTester::For( + tab_activity_simulator_.AddWebContentsAndNavigate( + browser->tab_strip_model(), GURL(kTestUrl))) + ->TestSetIsLoading(false); + } + + private: + TabActivitySimulator tab_activity_simulator_; + + DISALLOW_COPY_AND_ASSIGN(CreateWindowFeaturesTest); +}; + +// Tests CreateWindowFeatures of two browser windows. +TEST_F(CreateWindowFeaturesTest, Basic) { + Browser::CreateParams params(profile(), true); + std::unique_ptr<Browser> browser = + FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms); + + AddTab(browser.get()); + WindowFeatures expected_metrics{WindowMetricsEvent::TYPE_TABBED, + WindowMetricsEvent::SHOW_STATE_NORMAL, true, + 1}; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser.get()), + expected_metrics); + + AddTab(browser.get()); + expected_metrics.tab_count++; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser.get()), + expected_metrics); + + browser->window()->Minimize(); + expected_metrics.show_state = WindowMetricsEvent::SHOW_STATE_MINIMIZED; + expected_metrics.is_active = false; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser.get()), + expected_metrics); + + // Create a second browser. + Browser::CreateParams params_2(Browser::TYPE_POPUP, profile(), true); + std::unique_ptr<Browser> browser_2 = + FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms_2); + + AddTab(browser_2.get()); + WindowFeatures expected_metrics_2{WindowMetricsEvent::TYPE_POPUP, + WindowMetricsEvent::SHOW_STATE_NORMAL, true, + 1}; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser_2.get()), + expected_metrics_2); + + // Switching the active browser. + browser_2->window()->Deactivate(); + expected_metrics_2.is_active = false; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser_2.get()), + expected_metrics_2); + + browser->window()->Restore(); + expected_metrics.show_state = WindowMetricsEvent::SHOW_STATE_NORMAL; + expected_metrics.is_active = true; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser.get()), + expected_metrics); + + browser->tab_strip_model()->CloseAllTabs(); + browser_2->tab_strip_model()->CloseAllTabs(); +} + +// Tests moving a tab between browser windows. +TEST_F(CreateWindowFeaturesTest, MoveTabToOtherWindow) { + Browser::CreateParams params(profile(), true); + std::unique_ptr<Browser> starting_browser = + FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms); + AddTab(starting_browser.get()); + WindowFeatures starting_browser_metrics{WindowMetricsEvent::TYPE_TABBED, + WindowMetricsEvent::SHOW_STATE_NORMAL, + true, 1}; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(starting_browser.get()), + starting_browser_metrics); + + // Add a second tab, so we can detach it while leaving the original window + // behind. + AddTab(starting_browser.get()); + starting_browser_metrics.tab_count++; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(starting_browser.get()), + starting_browser_metrics); + + // Drag the tab out of its window. + std::unique_ptr<content::WebContents> dragged_tab = + starting_browser->tab_strip_model()->DetachWebContentsAt(1); + starting_browser_metrics.tab_count--; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(starting_browser.get()), + starting_browser_metrics); + + starting_browser->window()->Deactivate(); + starting_browser_metrics.is_active = false; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(starting_browser.get()), + starting_browser_metrics); + + // Create a new Browser for the tab. + std::unique_ptr<Browser> created_browser = + FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms); + created_browser->window()->Activate(); + created_browser->tab_strip_model()->InsertWebContentsAt( + 0, std::move(dragged_tab), TabStripModel::ADD_ACTIVE); + + WindowFeatures created_browser_metrics{WindowMetricsEvent::TYPE_TABBED, + WindowMetricsEvent::SHOW_STATE_NORMAL, + true, 1}; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(created_browser.get()), + created_browser_metrics); + + starting_browser->tab_strip_model()->CloseAllTabs(); + created_browser->tab_strip_model()->CloseAllTabs(); +} + +// Tests replacing a tab. +TEST_F(CreateWindowFeaturesTest, ReplaceTab) { + Browser::CreateParams params(profile(), true); + std::unique_ptr<Browser> browser = + FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms); + AddTab(browser.get()); + WindowFeatures expected_metrics{WindowMetricsEvent::TYPE_TABBED, + WindowMetricsEvent::SHOW_STATE_NORMAL, true, + 1}; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser.get()), + expected_metrics); + + // Add a tab that will be replaced. + AddTab(browser.get()); + expected_metrics.tab_count++; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser.get()), + expected_metrics); + + // Replace the tab. + content::WebContents::CreateParams web_contents_params(profile(), nullptr); + std::unique_ptr<content::WebContents> new_contents = base::WrapUnique( + content::WebContentsTester::CreateTestWebContents(web_contents_params)); + std::unique_ptr<content::WebContents> old_contents = + browser->tab_strip_model()->ReplaceWebContentsAt(1, + std::move(new_contents)); + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser.get()), + expected_metrics); + + // Close the replaced tab. This should update TabCount. + browser->tab_strip_model()->CloseWebContentsAt(1, TabStripModel::CLOSE_NONE); + expected_metrics.tab_count--; + EXPECT_EQ(TabMetricsLogger::CreateWindowFeatures(browser.get()), + expected_metrics); + + browser->tab_strip_model()->CloseAllTabs(); +}
diff --git a/chrome/browser/resource_coordinator/tab_ranker/window_features.cc b/chrome/browser/resource_coordinator/tab_ranker/window_features.cc index 197e75e..5d3eccf 100644 --- a/chrome/browser/resource_coordinator/tab_ranker/window_features.cc +++ b/chrome/browser/resource_coordinator/tab_ranker/window_features.cc
@@ -6,18 +6,19 @@ namespace tab_ranker { -WindowFeatures::WindowFeatures(SessionID window_id, - metrics::WindowMetricsEvent::Type type) - : window_id(window_id), type(type) {} - -WindowFeatures::WindowFeatures(const WindowFeatures& other) = default; - -WindowFeatures::~WindowFeatures() = default; +WindowFeatures::WindowFeatures( + metrics::WindowMetricsEvent::Type type, + metrics::WindowMetricsEvent::ShowState show_state, + bool is_active, + int tab_count) + : type(type), + show_state(show_state), + is_active(is_active), + tab_count(tab_count) {} bool WindowFeatures::operator==(const WindowFeatures& other) const { - return window_id == other.window_id && type == other.type && - show_state == other.show_state && is_active == other.is_active && - tab_count == other.tab_count; + return type == other.type && show_state == other.show_state && + is_active == other.is_active && tab_count == other.tab_count; } bool WindowFeatures::operator!=(const WindowFeatures& other) const {
diff --git a/chrome/browser/resource_coordinator/tab_ranker/window_features.h b/chrome/browser/resource_coordinator/tab_ranker/window_features.h index 3d4cbf2..3bd97ff 100644 --- a/chrome/browser/resource_coordinator/tab_ranker/window_features.h +++ b/chrome/browser/resource_coordinator/tab_ranker/window_features.h
@@ -15,15 +15,16 @@ // Window features used for logging a Tab Ranker example to UKM or calculating a // Tab Ranker score. struct WindowFeatures { - WindowFeatures(SessionID window_id, metrics::WindowMetricsEvent::Type type); - WindowFeatures(const WindowFeatures& other); - ~WindowFeatures(); + WindowFeatures(metrics::WindowMetricsEvent::Type type, + metrics::WindowMetricsEvent::ShowState show_state, + bool is_active, + int tab_count); + + ~WindowFeatures() = default; bool operator==(const WindowFeatures& other) const; bool operator!=(const WindowFeatures& other) const; - // ID for the window, unique within the Chrome session. - const SessionID window_id; const metrics::WindowMetricsEvent::Type type; metrics::WindowMetricsEvent::ShowState show_state = metrics::WindowMetricsEvent::SHOW_STATE_UNKNOWN;
diff --git a/chrome/browser/resources/chromeos/md_set_time/set_time.html b/chrome/browser/resources/chromeos/md_set_time/set_time.html index 5abb4fd9..874d998 100644 --- a/chrome/browser/resources/chromeos/md_set_time/set_time.html +++ b/chrome/browser/resources/chromeos/md_set_time/set_time.html
@@ -10,6 +10,7 @@ <link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/html/load_time_data.html"> +<link rel="import" href="chrome://resources/html/md_select_css.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="set_time_browser_proxy.html"> @@ -23,9 +24,10 @@ <body> <dom-module id="set-time"> <template> - <style include="cr-shared-style paper-button-style"> + <style include="cr-shared-style md-select paper-button-style"> :host { @apply --cr-page-host; + user-select: none; } cr-dialog { @@ -36,17 +38,43 @@ } } - .row { - margin: 0.65em 0; + cr-dialog [slot=title] { + /* The native dialog caption area has enough visual whitespace. */ + padding-top: 0; } + cr-dialog [slot=button-container] { + /* Align right edge of "Done" button with right edge of time input. */ + padding-inline-end: 20px; + } + + .row { + display: flex; + margin-top: 16px; + } + + div.row:first-of-type { + margin-top: 0; + } + + .column { + flex: 1; + } + + /* Style to match md-select. */ input[type='date'], input[type='time'] { + background-color: var(--google-grey-refresh-100); + border: none; + border-radius: 4px; + box-sizing: border-box; + color: var(--google-grey-900); font-family: inherit; - font-size: 16px; - letter-spacing: 1px; - margin-bottom: 4px; - margin-inline-end: 8px; + font-size: inherit; + /* Ensure space for focus border. */ + margin-bottom: 2px; + padding: 6px 8px; + width: 100%; } input[type='date']::-webkit-clear-button, @@ -54,13 +82,23 @@ display: none; } - label { - margin-inline-end: 5px; + #timeColumn { + margin-inline-start: 20px; + } + + #timezone { + display: block; + /* No bottom margin to minimize height of dialog body. */ + margin-bottom: 0; } #timezoneSelect { + cursor: default; font-family: inherit; font-size: inherit; + /* Ensure space for focus border. */ + margin-bottom: 2px; + width: 100%; } </style> @@ -69,16 +107,26 @@ <div slot="body" id="dialogBody"> <div class="row">$i18n{prompt}</div> - <div> - <input id="dateInput" type="date" title="$i18n{dateLabel}" - on-blur="onTimeBlur_"> - <input id="timeInput" type="time" title="$i18n{timeLabel}" - on-blur="onTimeBlur_"> + <div class="row"> + <div class="column"> + <div id="label">$i18n{dateLabel}</div> + <input id="dateInput" type="date" aria-label="$i18n{dateLabel}" + on-blur="onTimeBlur_"> + </div> + <div class="column" id="timeColumn"> + <div id="label">$i18n{timeLabel}</div> + <input id="timeInput" type="time" aria-label="$i18n{timeLabel}" + on-blur="onTimeBlur_"> + </div> </div> <div id="timezone" class="row" hidden> - <label for="timezoneSelect">$i18n{timezone}</label> - <select id="timezoneSelect" on-change="onTimezoneChange_"></select> + <div id="label">$i18n{timezoneLabel}</div> + <select id="timezoneSelect" + class="md-select" + aria-label="$i18n{timezoneLabel}" + on-change="onTimezoneChange_"> + </select> </div> </div>
diff --git a/chrome/browser/resources/feed_internals/feed_internals.html b/chrome/browser/resources/feed_internals/feed_internals.html index 5d4c9c00..78054e8 100644 --- a/chrome/browser/resources/feed_internals/feed_internals.html +++ b/chrome/browser/resources/feed_internals/feed_internals.html
@@ -123,6 +123,15 @@ </template> </div> + <h2>Feed Histograms</h2> + <button id="load-feed-histograms"> + Load Feed Histograms + </button> + <details id="feed-histograms-details"> + <summary>Show/Hide</summary> + <pre id="feed-histograms-log"></pre> + </details> + <h2>Feed Process Scope</h2> <button id="dump-feed-process-scope"> Dump Feed Process Scope
diff --git a/chrome/browser/resources/feed_internals/feed_internals.js b/chrome/browser/resources/feed_internals/feed_internals.js index 224f5bd..02f22a2 100644 --- a/chrome/browser/resources/feed_internals/feed_internals.js +++ b/chrome/browser/resources/feed_internals/feed_internals.js
@@ -142,6 +142,13 @@ $('feed-process-scope-details').open = true; }); }); + + $('load-feed-histograms').addEventListener('click', function() { + pageHandler.getFeedHistograms().then(response => { + $('feed-histograms-log').textContent = response.log; + $('feed-histograms-details').open = true; + }); + }); } document.addEventListener('DOMContentLoaded', function() {
diff --git a/chrome/browser/resources/ntp4/incognito_tab.css b/chrome/browser/resources/ntp4/incognito_tab.css index 5a06e02..e4bdbe6 100644 --- a/chrome/browser/resources/ntp4/incognito_tab.css +++ b/chrome/browser/resources/ntp4/incognito_tab.css
@@ -14,14 +14,13 @@ /* This is identical to the default background color. It's necessary to set it for the case when a theme with a background image is installed. */ background-color: rgb(50, 54, 57); - color: rgb(189, 193, 198); + color: rgb(232, 234, 237); /* --google-grey-200 */ font-size: calc(100% - 2px); line-height: calc(100% + 6px); min-width: 240px; } h1 { - color: rgb(218, 220, 224); font-size: calc(100% + 8px); font-weight: 400; line-height: calc(100% + 8px);
diff --git a/chrome/browser/resources/ntp4/incognito_tab.js b/chrome/browser/resources/ntp4/incognito_tab.js index 8aaf797..b2d5eb7 100644 --- a/chrome/browser/resources/ntp4/incognito_tab.js +++ b/chrome/browser/resources/ntp4/incognito_tab.js
@@ -33,7 +33,10 @@ content.style.maxWidth = maxWidth + 'px'; } -window.addEventListener('load', recomputeLayoutWidth); +window.addEventListener('load', function() { + recomputeLayoutWidth(); + chrome.send('observeThemeChanges'); +}); // Handle the bookmark bar, theme, and font size change requests // from the C++ side.
diff --git a/chrome/browser/resources/ntp4/new_tab.js b/chrome/browser/resources/ntp4/new_tab.js index 0c3d114..88a3159 100644 --- a/chrome/browser/resources/ntp4/new_tab.js +++ b/chrome/browser/resources/ntp4/new_tab.js
@@ -139,10 +139,11 @@ newTabView.cardSlider.currentCardValue.navigationDot.classList.add( 'selected'); - cr.dispatchSimpleEvent(document, 'ntpLoaded', true, true); document.documentElement.classList.remove('starting-up'); startTime = Date.now(); + + chrome.send('observeThemeChanges'); }); }
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.js b/chrome/browser/resources/settings/internet_page/internet_detail_page.js index 738f8af..da512b7 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.js
@@ -242,7 +242,6 @@ this.networkProperties_ = { GUID: this.guid, Type: type, - ConnectionState: CrOnc.ConnectionState.NOT_CONNECTED, Name: {Active: name}, }; this.didSetFocus_ = false; @@ -251,8 +250,17 @@ close: function() { this.guid = ''; + // Delay navigating to allow other subpages to load first. - requestAnimationFrame(() => settings.navigateToPreviousRoute()); + requestAnimationFrame(() => { + // Clear network properties before navigating away to ensure that a future + // navigation back to the details page does not show a flicker of + // incorrect text. See https://crbug.com/905986. + this.networkProperties_ = undefined; + this.networkPropertiesReceived_ = false; + + settings.navigateToPreviousRoute(); + }); }, /** @private */ @@ -585,8 +593,7 @@ showDisconnect_: function(networkProperties) { return !!networkProperties && networkProperties.Type != CrOnc.Type.ETHERNET && - networkProperties.ConnectionState != - CrOnc.ConnectionState.NOT_CONNECTED; + CrOnc.isConnectingOrConnected(networkProperties); }, /** @@ -654,8 +661,7 @@ } } if ((type == CrOnc.Type.WI_FI || type == CrOnc.Type.WI_MAX) && - networkProperties.ConnectionState != - CrOnc.ConnectionState.NOT_CONNECTED) { + CrOnc.isConnectingOrConnected(networkProperties)) { return false; } if (this.isArcVpn_(networkProperties) &&
diff --git a/chrome/browser/resources/settings/people_page/users_add_user_dialog.html b/chrome/browser/resources/settings/people_page/users_add_user_dialog.html index df9f676..7915b03 100644 --- a/chrome/browser/resources/settings/people_page/users_add_user_dialog.html +++ b/chrome/browser/resources/settings/people_page/users_add_user_dialog.html
@@ -18,8 +18,9 @@ <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{addUsers}</div> <div slot="body"> - <cr-input id="addUserInput" label="$i18n{addUsersEmail}" autofocus - on-input="validate_" invalid="[[!isValid_]]"> + <cr-input id="addUserInput" label="$i18n{addUsersEmail}" + invalid="[[shouldShowError_(isEmail_, isEmpty_)]]" + on-value-changed="onInput_" autofocus> </cr-input> </div> <div slot="button-container"> @@ -27,7 +28,7 @@ $i18n{cancel} </paper-button> <paper-button on-click="addUser_" class="action-button" - disabled$="[[!isValid_]]"> + disabled$="[[!canAddUser_(isEmail_, isEmpty_)]]"> $i18n{add} </paper-button> </div>
diff --git a/chrome/browser/resources/settings/people_page/users_add_user_dialog.js b/chrome/browser/resources/settings/people_page/users_add_user_dialog.js index 35fb0351..37210248 100644 --- a/chrome/browser/resources/settings/people_page/users_add_user_dialog.js +++ b/chrome/browser/resources/settings/people_page/users_add_user_dialog.js
@@ -34,37 +34,30 @@ properties: { /** @private */ - isValid_: { + isEmail_: { type: Boolean, value: false, }, + + /** @private */ + isEmpty_: { + type: Boolean, + value: true, + }, }, open: function() { - this.isValid_ = false; + this.$.addUserInput.value = ''; + this.onInput_(); this.$.dialog.showModal(); - }, - - /** @private */ - onCancelTap_: function() { - this.$.dialog.cancel(); - }, - - /** - * Validates that the new user entered is valid. - * @private - * @return {boolean} - */ - validate_: function() { - const input = this.$.addUserInput.value; - this.isValid_ = NAME_ONLY_REGEX.test(input) || EMAIL_REGEX.test(input); - return this.isValid_; + // Set to valid initially since the user has not typed anything yet. + this.$.addUserInput.invalid = false; }, /** @private */ addUser_: function() { // May be submitted by the Enter key even if the input value is invalid. - if (!this.validate_()) { + if (this.$.addUserInput.disabled) { return; } @@ -87,6 +80,34 @@ this.$.addUserInput.value = ''; this.$.dialog.close(); }, + + /** + * @return {boolean} + * @private + */ + canAddUser_: function() { + return this.isEmail_ && !this.isEmpty_; + }, + + /** @private */ + onCancelTap_: function() { + this.$.dialog.cancel(); + }, + + /** @private */ + onInput_: function() { + const input = this.$.addUserInput.value; + this.isEmail_ = NAME_ONLY_REGEX.test(input) || EMAIL_REGEX.test(input); + this.isEmpty_ = input.length == 0; + }, + + /** + * @private + * @return {boolean} + */ + shouldShowError_: function() { + return !this.isEmail_ && !this.isEmpty_; + }, }); })();
diff --git a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html index 437d19c..26c46a34 100644 --- a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html +++ b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html
@@ -187,15 +187,14 @@ value="{{activePrinter.ppdModel}}"> </cr-searchable-drop-down> </div> - <div class="settings-box two-line last"> + <div class="settings-box two-line"> <cr-input class="browse-file-input" readonly value="[[newUserPPD_]]" label="$i18n{selectDriver}" invalid="[[invalidPPD_]]" error-message="$i18n{selectDriverErrorMessage}" tabindex="-1"> - <paper-button class="browse-button" on-click="onBrowseFile_" - slot="suffix"> - $i18n{selectDriverButtonText} - </paper-button> </cr-input> + <paper-button class="browse-button" on-click="onBrowseFile_"> + $i18n{selectDriverButtonText} + </paper-button> </div> </div> <div slot="dialog-buttons">
diff --git a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html index 7086f2d50..23eef54 100644 --- a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html +++ b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html
@@ -12,15 +12,7 @@ <dom-module id="settings-cups-edit-printer-dialog"> <template> - <style include="cups-printer-shared"> - /* This is needed to line up the existing PDD text with cr-input. - TODO(scottchen): move away from using .settings-box just for margin, - and then remove this hacky alignment. */ - .last { - align-items: start; - flex-direction: column; - } - </style> + <style include="cups-printer-shared"> </style> <add-printer-dialog> <div slot="dialog-title">$i18n{editPrinterDialogTitle}</div> <div slot="dialog-body" scrollable> @@ -102,16 +94,15 @@ value="{{activePrinter.ppdModel}}"> </cr-searchable-drop-down> </div> - <div class="settings-box two-line last"> + <div class="settings-box two-line"> <cr-input class="browse-file-input" readonly tabindex="-1" value="[[newUserPPD_]]" label="$i18n{selectDriver}" error-message="$i18n{selectDriverErrorMessage}" invalid="[[invalidPPD_]]"> - <paper-button class="browse-button" on-click="onBrowseFile_" - slot="suffix"> - $i18n{selectDriverButtonText} - </paper-button> </cr-input> + <paper-button class="browse-button" on-click="onBrowseFile_"> + $i18n{selectDriverButtonText} + </paper-button> <template is="dom-if" if="[[existingUserPPDMessage_]]"> <div class="secondary" id="existingUserPPD"> [[existingUserPPDMessage_]]
diff --git a/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html b/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html index 8b3f8c47..dc5d1fb7 100644 --- a/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html +++ b/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html
@@ -47,7 +47,8 @@ } [slot='dialog-body'] .settings-box .browse-button { - margin-inline-start: 5px; + margin-bottom: 8px; + margin-inline-start: 12px; } [slot='dialog-body'] .last {
diff --git a/chrome/browser/send_tab_to_self/receiving_ui_handler.h b/chrome/browser/send_tab_to_self/receiving_ui_handler.h index 65bd57053..d1125f1 100644 --- a/chrome/browser/send_tab_to_self/receiving_ui_handler.h +++ b/chrome/browser/send_tab_to_self/receiving_ui_handler.h
@@ -27,8 +27,7 @@ // Dismiss any UI associated with this entry. // Entry object is owned by the the model and should not be // modified by any implementors of this class. - // TODO(crbug.com/935719): Figure out whether we need to pass the entire entry - // or we can pass a smaller subset of information. + // TODO(crbug.com/944591): Pass a string at a time instead. virtual void DismissEntries(const std::vector<std::string>& guids) = 0; };
diff --git a/chrome/browser/send_tab_to_self/receiving_ui_handler_registry.cc b/chrome/browser/send_tab_to_self/receiving_ui_handler_registry.cc index 61a6148d..1ad569aa 100644 --- a/chrome/browser/send_tab_to_self/receiving_ui_handler_registry.cc +++ b/chrome/browser/send_tab_to_self/receiving_ui_handler_registry.cc
@@ -41,8 +41,8 @@ #endif } -std::vector<std::unique_ptr<ReceivingUiHandler>>& -ReceivingUiHandlerRegistry::GetHandlers() { +const std::vector<std::unique_ptr<ReceivingUiHandler>>& +ReceivingUiHandlerRegistry::GetHandlers() const { return applicable_handlers_; }
diff --git a/chrome/browser/send_tab_to_self/receiving_ui_handler_registry.h b/chrome/browser/send_tab_to_self/receiving_ui_handler_registry.h index f8e5d3d..45e5b3b2 100644 --- a/chrome/browser/send_tab_to_self/receiving_ui_handler_registry.h +++ b/chrome/browser/send_tab_to_self/receiving_ui_handler_registry.h
@@ -33,7 +33,7 @@ // Returns all the handlers to perform UI updates for the platform. // Called by the SendTabToSelfClientService. - std::vector<std::unique_ptr<ReceivingUiHandler>>& GetHandlers(); + const std::vector<std::unique_ptr<ReceivingUiHandler>>& GetHandlers() const; private: friend struct base::DefaultSingletonTraits<ReceivingUiHandlerRegistry>;
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.cc b/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.cc index f3f1862..b692b73 100644 --- a/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.cc +++ b/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.cc
@@ -21,8 +21,7 @@ model_ = model; model_->AddObserver(this); - registry_ = ReceivingUiHandlerRegistry::GetInstance(); - registry_->InstantiatePlatformSpecificHandlers(profile); + SetupHandlerRegistry(profile); } SendTabToSelfClientService::~SendTabToSelfClientService() { @@ -37,8 +36,7 @@ void SendTabToSelfClientService::EntriesAddedRemotely( const std::vector<const SendTabToSelfEntry*>& new_entries) { for (const SendTabToSelfEntry* entry : new_entries) { - for (std::unique_ptr<ReceivingUiHandler>& handler : - registry_->GetHandlers()) { + for (const std::unique_ptr<ReceivingUiHandler>& handler : GetHandlers()) { handler->DisplayNewEntry(entry); } } @@ -46,10 +44,19 @@ void SendTabToSelfClientService::EntriesRemovedRemotely( const std::vector<std::string>& guids) { - for (std::unique_ptr<ReceivingUiHandler>& handler : - registry_->GetHandlers()) { + for (const std::unique_ptr<ReceivingUiHandler>& handler : GetHandlers()) { handler->DismissEntries(guids); } } +void SendTabToSelfClientService::SetupHandlerRegistry(Profile* profile) { + registry_ = ReceivingUiHandlerRegistry::GetInstance(); + registry_->InstantiatePlatformSpecificHandlers(profile); +} + +const std::vector<std::unique_ptr<ReceivingUiHandler>>& +SendTabToSelfClientService::GetHandlers() const { + return registry_->GetHandlers(); +} + } // namespace send_tab_to_self
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.h b/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.h index 4fc750e..0478846c 100644 --- a/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.h +++ b/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/macros.h" +#include "chrome/browser/send_tab_to_self/receiving_ui_handler.h" #include "components/keyed_service/core/keyed_service.h" #include "components/send_tab_to_self/send_tab_to_self_model.h" #include "components/send_tab_to_self/send_tab_to_self_model_observer.h" @@ -41,6 +42,13 @@ protected: ~SendTabToSelfClientService() override; + // Sets up the ReceivingUiHandlerRegistry. + virtual void SetupHandlerRegistry(Profile* profile); + + // Returns a vector containing the registered ReceivingUiHandlers. + virtual const std::vector<std::unique_ptr<ReceivingUiHandler>>& GetHandlers() + const; + private: // Owned by the SendTabToSelfSyncService which should outlive this class SendTabToSelfModel* model_;
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_unittest.cc b/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_unittest.cc new file mode 100644 index 0000000..58da259 --- /dev/null +++ b/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_unittest.cc
@@ -0,0 +1,108 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/send_tab_to_self/send_tab_to_self_client_service.h" + +#include <memory> + +#include "base/time/time.h" +#include "chrome/browser/send_tab_to_self/receiving_ui_handler.h" +#include "components/send_tab_to_self/send_tab_to_self_model.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace send_tab_to_self { + +namespace { + +// A fake version of the SendTabToSelf model that doesn't do anything and return +// null pointers. Needed to setup the SendTabToSelfClientService. +class FakeSendTabToSelfModel : public SendTabToSelfModel { + public: + FakeSendTabToSelfModel() = default; + ~FakeSendTabToSelfModel() override = default; + + std::vector<std::string> GetAllGuids() const override { return {}; } + void DeleteAllEntries() override {} + const SendTabToSelfEntry* GetEntryByGUID( + const std::string& guid) const override { + return nullptr; + } + const SendTabToSelfEntry* AddEntry(const GURL& url, + const std::string& title, + base::Time navigation_time) override { + return nullptr; + } + void DeleteEntry(const std::string& guid) override {} + void DismissEntry(const std::string& guid) override {} +}; + +// A test ReceivingUiHandler that keeps track of the number of entries for which +// DisplayNewEntry was called. +class TestReceivingUiHandler : public ReceivingUiHandler { + public: + TestReceivingUiHandler() = default; + ~TestReceivingUiHandler() override {} + + void DisplayNewEntry(const SendTabToSelfEntry* entry) override { + ++number_displayed_entries_; + } + + void DismissEntries(const std::vector<std::string>& guids) override {} + + size_t number_displayed_entries() const { return number_displayed_entries_; } + + private: + size_t number_displayed_entries_ = 0; +}; + +// A test SendTabToSelfClientService that exposes the TestReceivingUiHandler. +class TestSendTabToSelfClientService : public SendTabToSelfClientService { + public: + explicit TestSendTabToSelfClientService(SendTabToSelfModel* model) + : SendTabToSelfClientService(nullptr, model) {} + + ~TestSendTabToSelfClientService() override = default; + + void SetupHandlerRegistry(Profile* profile) override {} + + TestReceivingUiHandler* SetupTestHandler() { + test_handlers_.clear(); + std::unique_ptr<TestReceivingUiHandler> handler = + std::make_unique<TestReceivingUiHandler>(); + TestReceivingUiHandler* handler_ptr = handler.get(); + test_handlers_.push_back(std::move(handler)); + return handler_ptr; + } + + const std::vector<std::unique_ptr<ReceivingUiHandler>>& GetHandlers() + const override { + return test_handlers_; + } + + protected: + std::vector<std::unique_ptr<ReceivingUiHandler>> test_handlers_; +}; + +// Tests that the UI handlers gets notified of each entries that were added +// remotely. +TEST(SendTabToSelfClientServiceTest, MultipleEntriesAdded) { + // Set up the test objects. + FakeSendTabToSelfModel fake_model_; + TestSendTabToSelfClientService client_service(&fake_model_); + TestReceivingUiHandler* test_handler = client_service.SetupTestHandler(); + + // Create 2 entries and simulated that they were both added remotely. + SendTabToSelfEntry entry1("a", GURL("http://www.example-a.com"), "a site", + base::Time(), base::Time(), "device a"); + SendTabToSelfEntry entry2("b", GURL("http://www.example-b.com"), "b site", + base::Time(), base::Time(), "device b"); + client_service.EntriesAddedRemotely({&entry1, &entry2}); + + EXPECT_EQ(2u, test_handler->number_displayed_entries()); +} + +} // namespace + +} // namespace send_tab_to_self
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc index a97b211..18e2d3f 100644 --- a/chrome/browser/themes/browser_theme_pack.cc +++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -265,7 +265,6 @@ TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INACTIVE, TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_ACTIVE, TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_INACTIVE, - TP::COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND, TP::COLOR_INFOBAR, TP::COLOR_DOWNLOAD_SHELF, TP::COLOR_STATUS_BUBBLE, @@ -1373,7 +1372,6 @@ // was introduced). SkColor toolbar_color; if (GetColor(TP::COLOR_TOOLBAR, &toolbar_color)) { - SetColor(TP::COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND, toolbar_color); SetColor(TP::COLOR_INFOBAR, toolbar_color); SetColor(TP::COLOR_DOWNLOAD_SHELF, toolbar_color); SetColor(TP::COLOR_STATUS_BUBBLE, toolbar_color);
diff --git a/chrome/browser/themes/browser_theme_pack_unittest.cc b/chrome/browser/themes/browser_theme_pack_unittest.cc index b0595bc0..bce43a0f 100644 --- a/chrome/browser/themes/browser_theme_pack_unittest.cc +++ b/chrome/browser/themes/browser_theme_pack_unittest.cc
@@ -1011,19 +1011,15 @@ pack.get()); SkColor infobar_color; - SkColor bookmark_bar_color; SkColor download_shelf_color; SkColor status_bubble_color; EXPECT_TRUE(pack->GetColor(TP::COLOR_INFOBAR, &infobar_color)); - EXPECT_TRUE(pack->GetColor(TP::COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND, - &bookmark_bar_color)); EXPECT_TRUE(pack->GetColor(TP::COLOR_DOWNLOAD_SHELF, &download_shelf_color)); EXPECT_TRUE(pack->GetColor(TP::COLOR_STATUS_BUBBLE, &status_bubble_color)); constexpr SkColor kExpectedColor = SkColorSetRGB(0, 255, 0); EXPECT_EQ(infobar_color, kExpectedColor); - EXPECT_EQ(infobar_color, bookmark_bar_color); EXPECT_EQ(infobar_color, download_shelf_color); EXPECT_EQ(infobar_color, status_bubble_color); } @@ -1036,19 +1032,15 @@ BuildTestExtensionTheme("theme_test_toolbar_color_no_image", pack.get()); SkColor infobar_color; - SkColor bookmark_bar_color; SkColor download_shelf_color; SkColor status_bubble_color; EXPECT_TRUE(pack->GetColor(TP::COLOR_INFOBAR, &infobar_color)); - EXPECT_TRUE(pack->GetColor(TP::COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND, - &bookmark_bar_color)); EXPECT_TRUE(pack->GetColor(TP::COLOR_DOWNLOAD_SHELF, &download_shelf_color)); EXPECT_TRUE(pack->GetColor(TP::COLOR_STATUS_BUBBLE, &status_bubble_color)); constexpr SkColor kExpectedColor = SkColorSetRGB(0, 255, 0); EXPECT_EQ(infobar_color, kExpectedColor); - EXPECT_EQ(infobar_color, bookmark_bar_color); EXPECT_EQ(infobar_color, download_shelf_color); EXPECT_EQ(infobar_color, status_bubble_color); }
diff --git a/chrome/browser/themes/theme_properties.cc b/chrome/browser/themes/theme_properties.cc index 065a69d..0257cdf4 100644 --- a/chrome/browser/themes/theme_properties.cc +++ b/chrome/browser/themes/theme_properties.cc
@@ -46,7 +46,6 @@ case ThemeProperties::COLOR_STATUS_BUBBLE: case ThemeProperties::COLOR_INFOBAR: case ThemeProperties::COLOR_TOOLBAR: - case ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND: case ThemeProperties::COLOR_NTP_BACKGROUND: return SkColorSetRGB(0x32, 0x36, 0x39); case ThemeProperties::COLOR_BOOKMARK_TEXT: @@ -254,13 +253,6 @@ return gfx::kGoogleBlue600; case COLOR_CONTROL_BACKGROUND: return SK_ColorWHITE; - case COLOR_DETACHED_BOOKMARK_BAR_SEPARATOR: - // We shouldn't reach this case because the color is calculated from - // others. - NOTREACHED(); - return gfx::kPlaceholderColor; - case COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND: - return SK_ColorWHITE; case COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR: return SkColorSetRGB(0xB6, 0xB4, 0xB6); case COLOR_TOOLBAR_TOP_SEPARATOR:
diff --git a/chrome/browser/themes/theme_properties.h b/chrome/browser/themes/theme_properties.h index e10916a..0db9494 100644 --- a/chrome/browser/themes/theme_properties.h +++ b/chrome/browser/themes/theme_properties.h
@@ -110,10 +110,6 @@ // shelf. COLOR_TOOLBAR_VERTICAL_SEPARATOR, - // Colors used for the detached (NTP) bookmark bar. - COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND, - COLOR_DETACHED_BOOKMARK_BAR_SEPARATOR, - // Color used for various 'shelves' and 'bars'. COLOR_DOWNLOAD_SHELF, COLOR_INFOBAR,
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc index 52fe12b..eae7007 100644 --- a/chrome/browser/themes/theme_service.cc +++ b/chrome/browser/themes/theme_service.cc
@@ -614,14 +614,6 @@ if (UsingDefaultTheme()) break; return GetColor(ThemeProperties::COLOR_LOCATION_BAR_BORDER, incognito); - case ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND: - if (UsingDefaultTheme()) - break; - return GetColor(ThemeProperties::COLOR_TOOLBAR, incognito); - case ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_SEPARATOR: - // Use a faint version of the text color as the separator color. - return SkColorSetA( - GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT, incognito), 0x26); case ThemeProperties::COLOR_NTP_TEXT_LIGHT: return IncreaseLightness(GetColor(kNtpText, incognito), 0.40); case ThemeProperties::COLOR_TAB_THROBBER_SPINNING:
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index db993e16..50341e58 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1050,8 +1050,6 @@ "tabs/tab_switch_event_latency_recorder.h", "tabs/tab_utils.cc", "tabs/tab_utils.h", - "tabs/window_activity_watcher.cc", - "tabs/window_activity_watcher.h", "task_manager/task_manager_columns.cc", "task_manager/task_manager_columns.h", "task_manager/task_manager_table_model.cc",
diff --git a/chrome/browser/ui/app_list/app_service_app_item.cc b/chrome/browser/ui/app_list/app_service_app_item.cc index e158a87..f993165f 100644 --- a/chrome/browser/ui/app_list/app_service_app_item.cc +++ b/chrome/browser/ui/app_list/app_service_app_item.cc
@@ -128,7 +128,8 @@ void AppServiceAppItem::CallLoadIcon(bool allow_placeholder_icon) { apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile()); if (proxy) { - proxy->LoadIcon(id(), apps::mojom::IconCompression::kUncompressed, + proxy->LoadIcon(app_type_, id(), + apps::mojom::IconCompression::kUncompressed, app_list::AppListConfig::instance().grid_icon_dimension(), allow_placeholder_icon, base::BindOnce(&AppServiceAppItem::OnLoadIcon,
diff --git a/chrome/browser/ui/app_list/search/app_service_app_result.cc b/chrome/browser/ui/app_list/search/app_service_app_result.cc index 2bfd6c1..02215215 100644 --- a/chrome/browser/ui/app_list/search/app_service_app_result.cc +++ b/chrome/browser/ui/app_list/search/app_service_app_result.cc
@@ -126,7 +126,7 @@ apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile()); if (proxy) { proxy->LoadIcon( - app_id(), apps::mojom::IconCompression::kUncompressed, + app_type_, app_id(), apps::mojom::IconCompression::kUncompressed, chip ? AppListConfig::instance().suggestion_chip_icon_dimension() : AppListConfig::instance().GetPreferredIconDimension( display_type()),
diff --git a/chrome/browser/ui/autofill/autofill_ui_util.cc b/chrome/browser/ui/autofill/autofill_ui_util.cc index fcd3e04..96fc99f 100644 --- a/chrome/browser/ui/autofill/autofill_ui_util.cc +++ b/chrome/browser/ui/autofill/autofill_ui_util.cc
@@ -16,7 +16,8 @@ namespace autofill { -void UpdateLocalCardMigrationIcon(content::WebContents* web_contents) { +void UpdateCreditCardIcon(PageActionIconType icon_type, + content::WebContents* web_contents) { #if !defined(OS_ANDROID) Browser* browser = chrome::FindBrowserWithWebContents(web_contents); if (!browser) @@ -31,15 +32,27 @@ if (!toolbar_page_action_container) return; - toolbar_page_action_container->UpdatePageActionIcon( - PageActionIconType::kLocalCardMigration); + toolbar_page_action_container->UpdatePageActionIcon(icon_type); } else { // Otherwise the icon will be in the LocationBar. LocationBar* location_bar = browser->window()->GetLocationBar(); if (!location_bar) return; - location_bar->UpdateLocalCardMigrationIcon(); + switch (icon_type) { + case PageActionIconType::kLocalCardMigration: + location_bar->UpdateLocalCardMigrationIcon(); + break; + case PageActionIconType::kSaveCard: + location_bar->UpdateSaveCreditCardIcon(); + break; + case PageActionIconType::kFind: + case PageActionIconType::kManagePasswords: + case PageActionIconType::kPwaInstall: + case PageActionIconType::kTranslate: + case PageActionIconType::kZoom: + NOTREACHED(); + } } #endif }
diff --git a/chrome/browser/ui/autofill/autofill_ui_util.h b/chrome/browser/ui/autofill/autofill_ui_util.h index 9f3c054d..21317e5 100644 --- a/chrome/browser/ui/autofill/autofill_ui_util.h +++ b/chrome/browser/ui/autofill/autofill_ui_util.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_UI_UTIL_H_ #define CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_UI_UTIL_H_ +#include "chrome/browser/ui/page_action/page_action_icon_container.h" #include "content/public/browser/web_contents.h" namespace autofill { @@ -13,8 +14,9 @@ // ToolbarPageActionContainerView once the status chip is fully // launched. -// Update the state of local card migration icon view. -void UpdateLocalCardMigrationIcon(content::WebContents* web_contents); +// Update the state of credit card icon. +void UpdateCreditCardIcon(PageActionIconType icon_type, + content::WebContents* web_contents); } // namespace autofill
diff --git a/chrome/browser/ui/autofill/local_card_migration_bubble_controller_impl.cc b/chrome/browser/ui/autofill/local_card_migration_bubble_controller_impl.cc index b4d5e8e..19a7cd0c 100644 --- a/chrome/browser/ui/autofill/local_card_migration_bubble_controller_impl.cc +++ b/chrome/browser/ui/autofill/local_card_migration_bubble_controller_impl.cc
@@ -101,7 +101,7 @@ void LocalCardMigrationBubbleControllerImpl::OnBubbleClosed() { local_card_migration_bubble_ = nullptr; - UpdateLocalCardMigrationIcon(web_contents()); + UpdateLocalCardMigrationIcon(); if (should_add_strikes_on_bubble_close_ && base::FeatureList::IsEnabled( features::kAutofillLocalCardMigrationUsesStrikeSystemV2)) { @@ -142,7 +142,7 @@ local_card_migration_bubble_->Hide(); OnBubbleClosed(); } else { - UpdateLocalCardMigrationIcon(web_contents()); + UpdateLocalCardMigrationIcon(); } AutofillMetrics::LogLocalCardMigrationBubbleUserInteractionMetric( @@ -170,20 +170,25 @@ // Update the visibility and toggled state of the credit card icon in either // Location bar or in Status Chip. - UpdateLocalCardMigrationIcon(web_contents()); + UpdateLocalCardMigrationIcon(); Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); local_card_migration_bubble_ = browser->window()->ShowLocalCardMigrationBubble(web_contents(), this, is_reshow_); DCHECK(local_card_migration_bubble_); - UpdateLocalCardMigrationIcon(web_contents()); + UpdateLocalCardMigrationIcon(); timer_.reset(new base::ElapsedTimer()); AutofillMetrics::LogLocalCardMigrationBubbleOfferMetric( AutofillMetrics::LOCAL_CARD_MIGRATION_BUBBLE_SHOWN, is_reshow_); } +void LocalCardMigrationBubbleControllerImpl::UpdateLocalCardMigrationIcon() { + ::autofill::UpdateCreditCardIcon(PageActionIconType::kLocalCardMigration, + web_contents()); +} + void LocalCardMigrationBubbleControllerImpl::AddStrikesForBubbleClose() { LocalCardMigrationStrikeDatabase local_card_migration_strike_database( StrikeDatabaseFactory::GetForProfile(
diff --git a/chrome/browser/ui/autofill/local_card_migration_bubble_controller_impl.h b/chrome/browser/ui/autofill/local_card_migration_bubble_controller_impl.h index fd512e3..3f653d2ff 100644 --- a/chrome/browser/ui/autofill/local_card_migration_bubble_controller_impl.h +++ b/chrome/browser/ui/autofill/local_card_migration_bubble_controller_impl.h
@@ -69,6 +69,8 @@ void ShowBubbleImplementation(); + void UpdateLocalCardMigrationIcon(); + // Add strikes for local card migration, to be called on user closing the // promo bubble. void AddStrikesForBubbleClose();
diff --git a/chrome/browser/ui/autofill/local_card_migration_dialog_controller_impl.cc b/chrome/browser/ui/autofill/local_card_migration_dialog_controller_impl.cc index 90c5994..1d072e7 100644 --- a/chrome/browser/ui/autofill/local_card_migration_dialog_controller_impl.cc +++ b/chrome/browser/ui/autofill/local_card_migration_dialog_controller_impl.cc
@@ -69,14 +69,14 @@ view_state_ = LocalCardMigrationDialogState::kOffered; // Need to create the icon first otherwise the dialog will not be shown. - UpdateLocalCardMigrationIcon(web_contents()); + UpdateLocalCardMigrationIcon(); local_card_migration_dialog_ = CreateLocalCardMigrationDialogView(this, web_contents()); start_migrating_cards_callback_ = std::move(start_migrating_cards_callback); migratable_credit_cards_ = migratable_credit_cards; user_email_ = user_email; local_card_migration_dialog_->ShowDialog(); - UpdateLocalCardMigrationIcon(web_contents()); + UpdateLocalCardMigrationIcon(); dialog_is_visible_duration_timer_ = base::ElapsedTimer(); AutofillMetrics::LogLocalCardMigrationDialogOfferMetric( @@ -102,7 +102,7 @@ break; } } - UpdateLocalCardMigrationIcon(web_contents()); + UpdateLocalCardMigrationIcon(); } void LocalCardMigrationDialogControllerImpl::ShowFeedbackDialog() { @@ -112,7 +112,7 @@ local_card_migration_dialog_ = CreateLocalCardMigrationDialogView(this, web_contents()); local_card_migration_dialog_->ShowDialog(); - UpdateLocalCardMigrationIcon(web_contents()); + UpdateLocalCardMigrationIcon(); dialog_is_visible_duration_timer_ = base::ElapsedTimer(); } @@ -122,7 +122,7 @@ local_card_migration_dialog_ = CreateLocalCardMigrationErrorDialogView(this, web_contents()); - UpdateLocalCardMigrationIcon(web_contents()); + UpdateLocalCardMigrationIcon(); local_card_migration_dialog_->ShowDialog(); dialog_is_visible_duration_timer_ = base::ElapsedTimer(); } @@ -243,7 +243,7 @@ if (local_card_migration_dialog_) local_card_migration_dialog_ = nullptr; - UpdateLocalCardMigrationIcon(web_contents()); + UpdateLocalCardMigrationIcon(); } bool LocalCardMigrationDialogControllerImpl::AllCardsInvalid() const { @@ -273,6 +273,11 @@ ui::PAGE_TRANSITION_LINK, false)); } +void LocalCardMigrationDialogControllerImpl::UpdateLocalCardMigrationIcon() { + ::autofill::UpdateCreditCardIcon(PageActionIconType::kLocalCardMigration, + web_contents()); +} + bool LocalCardMigrationDialogControllerImpl::HasFailedCard() const { return std::find_if( migratable_credit_cards_.begin(), migratable_credit_cards_.end(),
diff --git a/chrome/browser/ui/autofill/local_card_migration_dialog_controller_impl.h b/chrome/browser/ui/autofill/local_card_migration_dialog_controller_impl.h index 3da8ab01..0da5b5e 100644 --- a/chrome/browser/ui/autofill/local_card_migration_dialog_controller_impl.h +++ b/chrome/browser/ui/autofill/local_card_migration_dialog_controller_impl.h
@@ -86,6 +86,8 @@ void OpenUrl(const GURL& url); + void UpdateLocalCardMigrationIcon(); + // The dialog is showing cards of which the migration failed. We will show // the "Almost done" dialog in this case. bool HasFailedCard() const;
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc index ff9e36b..7a9ab184 100644 --- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc +++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/signin/signin_ui_util.h" #include "chrome/browser/ssl/security_state_tab_helper.h" #include "chrome/browser/sync/profile_sync_service_factory.h" +#include "chrome/browser/ui/autofill/autofill_ui_util.h" #include "chrome/browser/ui/autofill/popup_constants.h" #include "chrome/browser/ui/autofill/save_card_bubble_view.h" #include "chrome/browser/ui/autofill/save_card_ui.h" @@ -23,6 +24,7 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/location_bar/location_bar.h" +#include "chrome/browser/ui/page_action/page_action_icon_container.h" #include "chrome/browser/ui/sync/sync_promo_ui.h" #include "chrome/common/url_constants.h" #include "components/autofill/core/browser/autofill_experiments.h" @@ -325,7 +327,7 @@ case BubbleType::LOCAL_SAVE: DCHECK(!local_save_card_prompt_callback_.is_null()); // Show an animated card saved confirmation message next time - // UpdateIcon() is called. + // UpdateSaveCardIcon() is called. can_animate_ = base::FeatureList::IsEnabled( features::kAutofillSaveCardSignInAfterLocalSave); @@ -422,14 +424,14 @@ // reopening the bubble will show the card management bubble. if (current_bubble_type_ == BubbleType::SIGN_IN_PROMO) current_bubble_type_ = BubbleType::MANAGE_CARDS; - UpdateIcon(); + UpdateSaveCardIcon(); if (observer_for_testing_) observer_for_testing_->OnBubbleClosed(); } void SaveCardBubbleControllerImpl::OnAnimationEnded() { - // Do not repeat the animation next time UpdateIcon() is called, unless - // explicitly set somewhere else. + // Do not repeat the animation next time UpdateSaveCardIcon() is called, + // unless explicitly set somewhere else. can_animate_ = false; // We do not want to show the promo if the user clicked on the icon and the @@ -484,7 +486,7 @@ save_card_bubble_view_->Hide(); OnBubbleClosed(); } else { - UpdateIcon(); + UpdateSaveCardIcon(); } if (previous_bubble_type == BubbleType::LOCAL_SAVE || @@ -544,7 +546,7 @@ // Need to create location bar icon before bubble, otherwise bubble will be // unanchored. - UpdateIcon(); + UpdateSaveCardIcon(); Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); save_card_bubble_view_ = browser->window()->ShowSaveCreditCardBubble( @@ -553,7 +555,7 @@ // Update icon after creating |save_card_bubble_view_| so that icon will show // its "toggled on" state. - UpdateIcon(); + UpdateSaveCardIcon(); bubble_shown_timestamp_ = AutofillClock::Now(); @@ -594,7 +596,7 @@ // Show the icon only. The bubble can still be displayed if the user // explicitly clicks the icon. - UpdateIcon(); + UpdateSaveCardIcon(); bubble_shown_timestamp_ = AutofillClock::Now(); @@ -615,12 +617,9 @@ } } -void SaveCardBubbleControllerImpl::UpdateIcon() { - Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); - if (!browser) - return; - LocationBar* location_bar = browser->window()->GetLocationBar(); - location_bar->UpdateSaveCreditCardIcon(); +void SaveCardBubbleControllerImpl::UpdateSaveCardIcon() { + ::autofill::UpdateCreditCardIcon(PageActionIconType::kSaveCard, + web_contents()); } void SaveCardBubbleControllerImpl::OpenUrl(const GURL& url) {
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h index 203aa75c..637d9c2 100644 --- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h +++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h
@@ -151,8 +151,7 @@ // Displays the omnibox icon without popping up the offer-to-save bubble. void ShowIconOnly(); - // Update the visibility and toggled state of the Omnibox save card icon. - void UpdateIcon(); + void UpdateSaveCardIcon(); void OpenUrl(const GURL& url);
diff --git a/chrome/browser/ui/libgtkui/gtk_ui.cc b/chrome/browser/ui/libgtkui/gtk_ui.cc index 8733e118..98505d4 100644 --- a/chrome/browser/ui/libgtkui/gtk_ui.cc +++ b/chrome/browser/ui/libgtkui/gtk_ui.cc
@@ -836,8 +836,6 @@ colors_[ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR] = tab_border; // Separates entries in the downloads bar. colors_[ThemeProperties::COLOR_TOOLBAR_VERTICAL_SEPARATOR] = tab_border; - // Separates the detached bookmark bar from the NTP. - colors_[ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_SEPARATOR] = tab_border; colors_[ThemeProperties::COLOR_NTP_BACKGROUND] = native_theme_->GetSystemColor( @@ -912,9 +910,6 @@ color_map[ThemeProperties::COLOR_TOOLBAR] = tab_color; color_map[ThemeProperties::COLOR_CONTROL_BACKGROUND] = tab_color; - color_map[ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND] = - tab_color; - const SkColor background_tab_text_color = GetFgColor(header_selector + " GtkLabel.title"); const SkColor background_tab_text_color_inactive =
diff --git a/chrome/browser/ui/page_action/page_action_icon_container.h b/chrome/browser/ui/page_action/page_action_icon_container.h index 7d01f70..08fe659e 100644 --- a/chrome/browser/ui/page_action/page_action_icon_container.h +++ b/chrome/browser/ui/page_action/page_action_icon_container.h
@@ -12,6 +12,7 @@ kLocalCardMigration, kManagePasswords, kPwaInstall, + kSaveCard, kTranslate, kZoom, };
diff --git a/chrome/browser/ui/tabs/window_activity_watcher.cc b/chrome/browser/ui/tabs/window_activity_watcher.cc deleted file mode 100644 index 7915d58..0000000 --- a/chrome/browser/ui/tabs/window_activity_watcher.cc +++ /dev/null
@@ -1,239 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/tabs/window_activity_watcher.h" - -#include "base/logging.h" -#include "base/optional.h" -#include "base/scoped_observer.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/resource_coordinator/tab_metrics_event.pb.h" -#include "chrome/browser/resource_coordinator/tab_ranker/window_features.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/browser_window.h" -#include "services/metrics/public/cpp/metrics_utils.h" -#include "services/metrics/public/cpp/ukm_builders.h" -#include "services/metrics/public/cpp/ukm_recorder.h" -#include "services/metrics/public/cpp/ukm_source_id.h" - -#if defined(USE_AURA) -#include "ui/aura/window.h" -#endif - -using metrics::WindowMetricsEvent; -using tab_ranker::WindowFeatures; - -namespace { - -// Sets feature values that are dependent on the current window state. -void UpdateWindowFeatures(const Browser* browser, - WindowFeatures* window_features, - bool is_active) { - DCHECK(browser->window()); - - // TODO(michaelpg): Observe the show state and log when it changes. - if (browser->window()->IsFullscreen()) - window_features->show_state = WindowMetricsEvent::SHOW_STATE_FULLSCREEN; - else if (browser->window()->IsMinimized()) - window_features->show_state = WindowMetricsEvent::SHOW_STATE_MINIMIZED; - else if (browser->window()->IsMaximized()) - window_features->show_state = WindowMetricsEvent::SHOW_STATE_MAXIMIZED; - else - window_features->show_state = WindowMetricsEvent::SHOW_STATE_NORMAL; - - window_features->is_active = is_active; - window_features->tab_count = browser->tab_strip_model()->count(); -} - -// Returns a populated WindowFeatures for the browser. -// |is_active| is provided because IsActive() may be incorrect while browser -// activation is changing (namely, when deactivating a window on Windows). -WindowFeatures CreateWindowFeatures(const Browser* browser, bool is_active) { - WindowMetricsEvent::Type window_type = WindowMetricsEvent::TYPE_UNKNOWN; - switch (browser->type()) { - case Browser::TYPE_TABBED: - window_type = WindowMetricsEvent::TYPE_TABBED; - break; - case Browser::TYPE_POPUP: - window_type = WindowMetricsEvent::TYPE_POPUP; - break; - default: - NOTREACHED(); - } - - WindowFeatures window_features(browser->session_id(), window_type); - UpdateWindowFeatures(browser, &window_features, is_active); - return window_features; -} - -// Logs a UKM entry with the metrics from |window_features|. -void LogWindowMetricsUkmEntry(const WindowFeatures& window_features) { - ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get(); - if (!ukm_recorder) - return; - - ukm::builders::TabManager_WindowMetrics entry(ukm::AssignNewSourceId()); - entry.SetWindowId(window_features.window_id.id()) - .SetIsActive(window_features.is_active) - .SetShowState(window_features.show_state) - .SetType(window_features.type); - - // Bucketize values for privacy considerations. Use a spacing factor that - // ensures values up to 3 can be logged exactly; after that, the precise - // number becomes less significant. - int tab_count = window_features.tab_count; - if (tab_count > 3) - tab_count = ukm::GetExponentialBucketMin(tab_count, 1.5); - entry.SetTabCount(tab_count); - - entry.Record(ukm_recorder); -} - -} // namespace - -// Observes a browser window's tab strip and logs a WindowMetrics UKM event for -// the window upon changes to metrics like TabCount. -class WindowActivityWatcher::BrowserWatcher : public TabStripModelObserver { - public: - explicit BrowserWatcher(Browser* browser) - : browser_(browser), observer_(this) { - DCHECK(!browser->profile()->IsOffTheRecord()); - MaybeLogWindowMetricsUkmEntry(); - observer_.Add(browser->tab_strip_model()); - } - - ~BrowserWatcher() override = default; - - void MaybeLogWindowMetricsUkmEntry() { - MaybeLogWindowMetricsUkmEntry(browser_->window()->IsActive()); - } - - // Logs a new WindowMetrics entry to the UKM recorder if the entry would be - // different than the last one we logged. - // |is_active| is provided because IsActive() may be incorrect while browser - // activation is changing (namely, when deactivating a window on Windows). - void MaybeLogWindowMetricsUkmEntry(bool is_active) { - // Do nothing if the window has no tabs (which can happen when a window is - // opened, before a tab is added) or is being closed. - if (browser_->tab_strip_model()->empty() || - browser_->tab_strip_model()->closing_all()) { - return; - } - - if (!last_window_features_) { - last_window_features_.emplace( - ::CreateWindowFeatures(browser_, is_active)); - LogWindowMetricsUkmEntry(last_window_features_.value()); - return; - } - - // Copy old state to compare with. - WindowFeatures old_features(last_window_features_.value()); - UpdateWindowFeatures(browser_, &last_window_features_.value(), is_active); - - // We only need to create a new UKM entry if the metrics have changed. - if (old_features != last_window_features_.value()) - LogWindowMetricsUkmEntry(last_window_features_.value()); - } - - private: - // TabStripModelObserver: - void OnTabStripModelChanged( - TabStripModel* tab_strip_model, - const TabStripModelChange& change, - const TabStripSelectionChange& selection) override { - if (change.type() != TabStripModelChange::kInserted && - change.type() != TabStripModelChange::kRemoved) - return; - - MaybeLogWindowMetricsUkmEntry(); - } - - // The browser whose tab strip we track. WindowActivityWatcher should ensure - // this outlives us. - Browser* browser_; - - // The most recent WindowFeatures entry logged. We only log a new UKM entry if - // some metric value has changed. - base::Optional<WindowFeatures> last_window_features_; - - // Used to update the tab count for browser windows. - ScopedObserver<TabStripModel, TabStripModelObserver> observer_; - - DISALLOW_COPY_AND_ASSIGN(BrowserWatcher); -}; - -// static -WindowActivityWatcher* WindowActivityWatcher::GetInstance() { - static base::NoDestructor<WindowActivityWatcher> instance; - return instance.get(); -} - -// static -WindowFeatures WindowActivityWatcher::CreateWindowFeatures( - const Browser* browser) { - DCHECK(browser->window()); - return ::CreateWindowFeatures(browser, browser->window()->IsActive()); -} - -WindowActivityWatcher::WindowActivityWatcher() { - BrowserList::AddObserver(this); - for (Browser* browser : *BrowserList::GetInstance()) - OnBrowserAdded(browser); -} - -WindowActivityWatcher::~WindowActivityWatcher() { - BrowserList::RemoveObserver(this); -} - -bool WindowActivityWatcher::ShouldTrackBrowser(Browser* browser) { - // Don't track incognito browsers. This is also enforced by UKM. - return !browser->profile()->IsOffTheRecord(); -} - -void WindowActivityWatcher::OnBrowserAdded(Browser* browser) { - if (ShouldTrackBrowser(browser)) - browser_watchers_[browser] = std::make_unique<BrowserWatcher>(browser); -} - -void WindowActivityWatcher::OnBrowserRemoved(Browser* browser) { - browser_watchers_.erase(browser); -} - -void WindowActivityWatcher::OnBrowserSetLastActive(Browser* browser) { - // The browser may not have a window yet if activation calls happen during - // initialization. - // TODO(michaelpg): The browser window check should be unnecessary - // (https://crbug.com/811191, https://crbug.com/811243). - if (ShouldTrackBrowser(browser) && browser->window()) - browser_watchers_[browser]->MaybeLogWindowMetricsUkmEntry(); -} - -void WindowActivityWatcher::OnBrowserNoLongerActive(Browser* browser) { - // The browser may not have a window yet if activation calls happen during - // initialization. - // TODO(michaelpg): The browser window check should be unnecessary - // (https://crbug.com/811191, https://crbug.com/811243). - if (!ShouldTrackBrowser(browser) || !browser->window()) - return; - -#if defined(USE_AURA) - // On some platforms, the window is hidden (and deactivated) before it starts - // closing. Unless the window is minimized, assume that being deactivated - // while hidden means it's about to close, and don't log in that case. - if (browser->window()->GetNativeWindow() && - !browser->window()->GetNativeWindow()->IsVisible() && - !browser->window()->IsMinimized()) { - return; - } -#endif - - // On Windows, the browser window's IsActive() may still return true until the - // WM updates the focused window, and BrowserList::GetLastActive() still - // returns this browser until another one is activated. So we explicitly pass - // along that the window should be considered inactive. - browser_watchers_[browser]->MaybeLogWindowMetricsUkmEntry( - /*is_active=*/false); -}
diff --git a/chrome/browser/ui/tabs/window_activity_watcher.h b/chrome/browser/ui/tabs/window_activity_watcher.h deleted file mode 100644 index 1cf2d98..0000000 --- a/chrome/browser/ui/tabs/window_activity_watcher.h +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_TABS_WINDOW_ACTIVITY_WATCHER_H_ -#define CHROME_BROWSER_UI_TABS_WINDOW_ACTIVITY_WATCHER_H_ - -#include <memory> - -#include "base/containers/flat_map.h" -#include "base/macros.h" -#include "base/no_destructor.h" -#include "chrome/browser/ui/browser_list_observer.h" - -namespace tab_ranker { -struct WindowFeatures; -} // namespace tab_ranker - -// Observes browser window activity in order to log WindowMetrics UKMs for -// browser events relative to tab activation and discarding. -// Multiple tabs in the same browser can refer to the same WindowMetrics entry. -// Must be used on the UI thread. -// TODO(michaelpg): Observe app and ARC++ windows as well. -class WindowActivityWatcher : public BrowserListObserver { - public: - class BrowserWatcher; - - // Returns the single instance, creating it if necessary. - static WindowActivityWatcher* GetInstance(); - - // Returns a populated WindowFeatures for the browser. - static tab_ranker::WindowFeatures CreateWindowFeatures( - const Browser* browser); - - private: - friend class base::NoDestructor<WindowActivityWatcher>; - - WindowActivityWatcher(); - ~WindowActivityWatcher() override; - - bool ShouldTrackBrowser(Browser* browser); - - // BrowserListObserver: - void OnBrowserAdded(Browser* browser) override; - void OnBrowserRemoved(Browser* browser) override; - void OnBrowserSetLastActive(Browser* browser) override; - void OnBrowserNoLongerActive(Browser* browser) override; - - // Per-browser observers responsible for tracking the tab strip and logging - // new UKM entries on changes. - base::flat_map<Browser*, std::unique_ptr<BrowserWatcher>> browser_watchers_; - - DISALLOW_COPY_AND_ASSIGN(WindowActivityWatcher); -}; - -#endif // CHROME_BROWSER_UI_TABS_WINDOW_ACTIVITY_WATCHER_H_
diff --git a/chrome/browser/ui/tabs/window_activity_watcher_interactive_uitest.cc b/chrome/browser/ui/tabs/window_activity_watcher_interactive_uitest.cc deleted file mode 100644 index 082053a..0000000 --- a/chrome/browser/ui/tabs/window_activity_watcher_interactive_uitest.cc +++ /dev/null
@@ -1,313 +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. - -#include <memory> - -#include "base/macros.h" -#include "build/build_config.h" -#include "chrome/browser/resource_coordinator/tab_metrics_event.pb.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/tabs/tab_ukm_test_helper.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "chrome/test/base/interactive_test_utils.h" -#include "chrome/test/base/ui_test_utils.h" -#include "components/ukm/test_ukm_recorder.h" -#include "services/metrics/public/cpp/ukm_builders.h" -#include "testing/gtest/include/gtest/gtest.h" - -using metrics::WindowMetricsEvent; -using ukm::builders::TabManager_TabMetrics; -using ukm::builders::TabManager_WindowMetrics; - -namespace { - -const char* kEntryName = TabManager_WindowMetrics::kEntryName; -const char* kTestUrl = "https://example.com/"; - -} // namespace - -// Tests UKM entries generated by WindowActivityWatcher due to interactive -// changes to window state. -class WindowActivityWatcherTest : public InProcessBrowserTest { - protected: - WindowActivityWatcherTest() = default; - - // InProcessBrowserTest: - void PreRunTestOnMainThread() override { - InProcessBrowserTest::PreRunTestOnMainThread(); - ukm_entry_checker_ = std::make_unique<UkmEntryChecker>(); - } - - void SetUpOnMainThread() override { - // Browser is created in BrowserMain() before the test UKM recorder. - ASSERT_EQ(0u, ukm_entry_checker_->NumEntries(kEntryName)); - -#if defined(OS_MACOSX) - // On Mac, the browser window needs to be forced to the front. This will - // create a UKM entry for the activation because it happens after the - // WindowActivityWatcher creation. On other platforms, activation happens - // before creation, and as a result, no UKM entry is created. - // TODO(crbug.com/650859): Reassess after activation is restored in the - // focus manager. - ui_test_utils::BrowserActivationWaiter waiter(browser()); - ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); - waiter.WaitForActivation(); - ASSERT_TRUE(browser()->window()->IsActive()); - - UkmMetricMap expected_metrics({ - {TabManager_WindowMetrics::kWindowIdName, browser()->session_id().id()}, - {TabManager_WindowMetrics::kShowStateName, - WindowMetricsEvent::SHOW_STATE_NORMAL}, - {TabManager_WindowMetrics::kTypeName, WindowMetricsEvent::TYPE_TABBED}, - {TabManager_WindowMetrics::kIsActiveName, 1}, - {TabManager_WindowMetrics::kTabCountName, 1}, - }); - ukm_entry_checker_->ExpectNewEntry(kEntryName, GURL(), expected_metrics); -#endif - } - - protected: - std::unique_ptr<UkmEntryChecker> ukm_entry_checker_; - - private: - DISALLOW_COPY_AND_ASSIGN(WindowActivityWatcherTest); -}; - -// Tests WindowMetrics UKMs logged by the current browser window. -IN_PROC_BROWSER_TEST_F(WindowActivityWatcherTest, Basic) { - UkmMetricMap expected_metrics({ - {TabManager_WindowMetrics::kWindowIdName, browser()->session_id().id()}, - {TabManager_WindowMetrics::kShowStateName, - WindowMetricsEvent::SHOW_STATE_NORMAL}, - {TabManager_WindowMetrics::kTypeName, WindowMetricsEvent::TYPE_TABBED}, - {TabManager_WindowMetrics::kIsActiveName, 1}, - {TabManager_WindowMetrics::kTabCountName, 1}, - }); - - // Updated metrics are logged after adding tabs. - { - SCOPED_TRACE(""); - AddTabAtIndex(1, GURL(kTestUrl), ui::PAGE_TRANSITION_LINK); - expected_metrics[TabManager_WindowMetrics::kTabCountName] = 2; - ukm_entry_checker_->ExpectNewEntry(kEntryName, GURL(), expected_metrics); - } - { - SCOPED_TRACE(""); - AddTabAtIndex(0, GURL(kTestUrl), ui::PAGE_TRANSITION_LINK); - expected_metrics[TabManager_WindowMetrics::kTabCountName] = 3; - ukm_entry_checker_->ExpectNewEntry(kEntryName, GURL(), expected_metrics); - } - - // Closing the window doesn't log more WindowMetrics UKMs. - CloseBrowserSynchronously(browser()); -} - -// TODO(https://crbug.com/51364): Implement BrowserWindow::Deactivate() on Mac. -#if !defined(OS_MACOSX) -// Tests WindowMetrics UKMs logged by activating/deactivating the window. -IN_PROC_BROWSER_TEST_F(WindowActivityWatcherTest, WindowActivation) { - UkmMetricMap expected_metrics({ - {TabManager_WindowMetrics::kWindowIdName, browser()->session_id().id()}, - {TabManager_WindowMetrics::kShowStateName, - WindowMetricsEvent::SHOW_STATE_NORMAL}, - {TabManager_WindowMetrics::kTypeName, WindowMetricsEvent::TYPE_TABBED}, - {TabManager_WindowMetrics::kIsActiveName, 0}, - {TabManager_WindowMetrics::kTabCountName, 1}, - }); - - { - SCOPED_TRACE(""); - ui_test_utils::BrowserDeactivationWaiter waiter(browser()); - browser()->window()->Deactivate(); - waiter.WaitForDeactivation(); - ukm_entry_checker_->ExpectNewEntry(kEntryName, GURL(), expected_metrics); - } - - { - SCOPED_TRACE(""); - ui_test_utils::BrowserActivationWaiter waiter(browser()); - browser()->window()->Activate(); - waiter.WaitForActivation(); - ASSERT_TRUE(browser()->window()->IsActive()); - expected_metrics[TabManager_WindowMetrics::kIsActiveName] = 1; - ukm_entry_checker_->ExpectNewEntry(kEntryName, GURL(), expected_metrics); - } - - // Closing the window doesn't log more WindowMetrics UKMs. - CloseBrowserSynchronously(browser()); -} - -// Tests WindowMetrics UKMs logged when switching between windows. -IN_PROC_BROWSER_TEST_F(WindowActivityWatcherTest, MultipleWindows) { - // Create a new browser window. - Browser* browser_2 = CreateBrowser(browser()->profile()); - { - SCOPED_TRACE(""); - ukm_entry_checker_->ExpectNewEntry( - kEntryName, GURL(), - { - {TabManager_WindowMetrics::kWindowIdName, - browser_2->session_id().id()}, - {TabManager_WindowMetrics::kIsActiveName, 0}, - }); - } - - // Wait for the old window to be deactivated and the new window to be - // activated if they aren't yet. - { - ui_test_utils::BrowserActivationWaiter waiter(browser_2); - waiter.WaitForActivation(); - } - { - ui_test_utils::BrowserDeactivationWaiter waiter(browser()); - waiter.WaitForDeactivation(); - } - { - SCOPED_TRACE(""); - // Check for activation and deactivation events. The exact order is - // platform-dependent. - ukm_entry_checker_->ExpectNewEntries( - kEntryName, {{ - {TabManager_WindowMetrics::kWindowIdName, - browser_2->session_id().id()}, - {TabManager_WindowMetrics::kIsActiveName, 1}, - }, - { - {TabManager_WindowMetrics::kWindowIdName, - browser()->session_id().id()}, - {TabManager_WindowMetrics::kIsActiveName, 0}, - }}); - } - - { - SCOPED_TRACE(""); - ui_test_utils::BrowserActivationWaiter activation_waiter(browser()); - ui_test_utils::BrowserDeactivationWaiter deactivation_waiter(browser_2); - - // Switch back to the first window. - // Note: use Activate() rather than Show() because on some platforms, Show() - // calls SetLastActive() before doing anything else. - browser()->window()->Activate(); - - activation_waiter.WaitForActivation(); - deactivation_waiter.WaitForDeactivation(); - - // Check for activation and deactivation events. The exact order is - // platform-dependent. - ukm_entry_checker_->ExpectNewEntries( - kEntryName, {{ - {TabManager_WindowMetrics::kWindowIdName, - browser()->session_id().id()}, - {TabManager_WindowMetrics::kIsActiveName, 1}, - }, - { - {TabManager_WindowMetrics::kWindowIdName, - browser_2->session_id().id()}, - {TabManager_WindowMetrics::kIsActiveName, 0}, - }}); - } - - // Closing the active window activates the second window. - ASSERT_EQ(0, ukm_entry_checker_->NumNewEntriesRecorded(kEntryName)); - - CloseBrowserSynchronously(browser()); - - // GetLastActive could return browser2 if browser1 was active and then was - // removed, so browser2 might not actually be active. - { - ui_test_utils::BrowserActivationWaiter activation_waiter(browser_2); - browser_2->window()->Activate(); - activation_waiter.WaitForActivation(); - } - EXPECT_TRUE(BrowserList::GetInstance()->GetLastActive() == browser_2); - EXPECT_TRUE(browser_2->window()->IsActive()); - { - SCOPED_TRACE(""); - // Check for activation and deactivation events. The exact order is - // platform-dependent. - ukm_entry_checker_->ExpectNewEntries( - kEntryName, {{ - {TabManager_WindowMetrics::kWindowIdName, - browser_2->session_id().id()}, - {TabManager_WindowMetrics::kIsActiveName, 1}, - }}); - } - - // Occasionally, X sends an extraneous deactivate/reactivate cycle. - if (ukm_entry_checker_->NumNewEntriesRecorded(kEntryName) == 2) { - SCOPED_TRACE(""); - LOG(WARNING) << "Extra deactivate/reactivate detected."; - ukm_entry_checker_->ExpectNewEntries( - kEntryName, {{ - {TabManager_WindowMetrics::kWindowIdName, - browser_2->session_id().id()}, - {TabManager_WindowMetrics::kIsActiveName, 0}, - }, - { - {TabManager_WindowMetrics::kWindowIdName, - browser_2->session_id().id()}, - {TabManager_WindowMetrics::kIsActiveName, 1}, - }}); - } - - // Ignore UKMs that might be logged from spurious activation events. - ukm_entry_checker_.reset(); -} - -// Tests we don't emit a ridiculous number of UKMs, which may indicate -// unintended log entries or unexpected interactions between events. -IN_PROC_BROWSER_TEST_F(WindowActivityWatcherTest, DontFloodUkm) { - // TODO(michaelpg): Update once window metrics are folded into tab metrics. - constexpr int kTooManyWindowMetricsEntries = 40; - constexpr int kTooManyTabMetricsEntries = 20; - - // Add and activate some tabs. - for (int i = 0; i < 3; i++) - AddTabAtIndex(1, GURL(kTestUrl), ui::PAGE_TRANSITION_LINK); - - // Make more windows with tabs. - constexpr bool kCheckNavigationSuccess = false; - Browser* browser_2 = CreateBrowser(browser()->profile()); - for (int i = 0; i < 3; i++) { - AddTabAtIndexToBrowser(browser_2, 1, GURL(kTestUrl), - ui::PAGE_TRANSITION_LINK, kCheckNavigationSuccess); - } - Browser* browser_3 = CreateBrowser(browser()->profile()); - for (int i = 0; i < 3; i++) { - AddTabAtIndexToBrowser(browser_3, 1, GURL(kTestUrl), - ui::PAGE_TRANSITION_LINK, kCheckNavigationSuccess); - } - - // Cycle between windows. - for (Browser* next_browser : - {browser_2, browser_3, browser(), browser_2, browser_3}) { - next_browser->window()->Activate(); - ui_test_utils::BrowserActivationWaiter(next_browser).WaitForActivation(); - } - - // Manage windows. - browser_2->window()->Minimize(); - browser_2->window()->Maximize(); - browser_3->window()->Maximize(); - browser_2->window()->Restore(); - browser_3->window()->Minimize(); - - CloseBrowserSynchronously(browser()); - CloseBrowserSynchronously(browser_2); - CloseBrowserSynchronously(browser_3); - - ASSERT_GT(ukm_entry_checker_->NumNewEntriesRecorded(kEntryName), 0); - ASSERT_LT(ukm_entry_checker_->NumNewEntriesRecorded(kEntryName), - kTooManyWindowMetricsEntries); - - ASSERT_GT(ukm_entry_checker_->NumNewEntriesRecorded( - TabManager_TabMetrics::kEntryName), - 0); - ASSERT_LT(ukm_entry_checker_->NumNewEntriesRecorded( - TabManager_TabMetrics::kEntryName), - kTooManyTabMetricsEntries); -} -#endif // !defined(OS_MACOSX)
diff --git a/chrome/browser/ui/tabs/window_activity_watcher_unittest.cc b/chrome/browser/ui/tabs/window_activity_watcher_unittest.cc deleted file mode 100644 index 3a62ca0..0000000 --- a/chrome/browser/ui/tabs/window_activity_watcher_unittest.cc +++ /dev/null
@@ -1,369 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/tabs/window_activity_watcher.h" - -#include <memory> -#include <vector> - -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/strings/stringprintf.h" -#include "chrome/browser/resource_coordinator/tab_activity_watcher.h" -#include "chrome/browser/resource_coordinator/tab_metrics_event.pb.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/tabs/tab_activity_simulator.h" -#include "chrome/browser/ui/tabs/tab_ukm_test_helper.h" -#include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "chrome/test/base/test_browser_window.h" -#include "chrome/test/base/testing_profile.h" -#include "content/public/test/web_contents_tester.h" -#include "services/metrics/public/cpp/ukm_builders.h" -#include "services/metrics/public/mojom/ukm_interface.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/ui_base_types.h" - -using metrics::WindowMetricsEvent; -using ukm::builders::TabManager_WindowMetrics; - -namespace { - -const char* kEntryName = TabManager_WindowMetrics::kEntryName; -const char* kTestUrl = "https://example.com/"; - -// TestBrowserWindow whose show state can be modified. -class FakeBrowserWindow : public TestBrowserWindow { - public: - FakeBrowserWindow() = default; - ~FakeBrowserWindow() override = default; - - // Helper function to handle FakeBrowserWindow lifetime. Modeled after - // CreateBrowserWithTestWindowForParams. - static std::unique_ptr<Browser> CreateBrowserWithFakeWindowForParams( - Browser::CreateParams* params) { - // TestBrowserWindowOwner takes ownersip of the window and will destroy the - // window (along with itself) automatically when the browser is closed. - FakeBrowserWindow* window = new FakeBrowserWindow; - new TestBrowserWindowOwner(window); - - params->window = window; - auto browser = std::make_unique<Browser>(*params); - window->browser_ = browser.get(); - window->Activate(); - return browser; - } - - // TestBrowserWindow: - void Activate() override { - if (is_active_) - return; - is_active_ = true; - // With a real view, activating would update the BrowserList. - BrowserList::SetLastActive(browser_); - } - void Deactivate() override { - if (!is_active_) - return; - is_active_ = false; - // With a real view, deactivating would notify the BrowserList. - BrowserList::NotifyBrowserNoLongerActive(browser_); - } - bool IsActive() const override { return is_active_; } - bool IsMaximized() const override { - return show_state_ == ui::SHOW_STATE_MAXIMIZED; - } - bool IsMinimized() const override { - return show_state_ == ui::SHOW_STATE_MINIMIZED; - } - void Maximize() override { - show_state_ = ui::SHOW_STATE_MAXIMIZED; - Activate(); - } - void Minimize() override { - show_state_ = ui::SHOW_STATE_MINIMIZED; - Deactivate(); - } - void Restore() override { - // This isn't true "restore" behavior. - show_state_ = ui::SHOW_STATE_NORMAL; - Activate(); - } - - private: - Browser* browser_; - bool is_active_ = false; - ui::WindowShowState show_state_ = ui::SHOW_STATE_NORMAL; - - DISALLOW_COPY_AND_ASSIGN(FakeBrowserWindow); -}; - -} // namespace - -// Tests UKM entries generated by WindowMetricsLogger at the request of -// WindowActivityWatcher. -class WindowActivityWatcherTest : public ChromeRenderViewHostTestHarness { - protected: - WindowActivityWatcherTest() = default; - ~WindowActivityWatcherTest() override { EXPECT_FALSE(WasNewEntryRecorded()); } - - void SetUp() override { - ChromeRenderViewHostTestHarness::SetUp(); - - // Start TabActivityWatcher so it logs TabMetrics UKMs. - resource_coordinator::TabActivityWatcher::GetInstance(); - } - - // Adds a tab and simulates a basic navigation. - void AddTab(Browser* browser) { - content::WebContentsTester::For( - tab_activity_simulator_.AddWebContentsAndNavigate( - browser->tab_strip_model(), GURL(kTestUrl))) - ->TestSetIsLoading(false); - } - - bool WasNewEntryRecorded() { - return ukm_entry_checker_.NumNewEntriesRecorded(kEntryName) > 0; - } - - UkmEntryChecker* ukm_entry_checker() { return &ukm_entry_checker_; } - - private: - UkmEntryChecker ukm_entry_checker_; - TabActivitySimulator tab_activity_simulator_; - - DISALLOW_COPY_AND_ASSIGN(WindowActivityWatcherTest); -}; - -// Tests UKM logging of two browser windows. -// Test is flaky. See https://crbug.com/938055. -TEST_F(WindowActivityWatcherTest, DISABLED_Basic) { - Browser::CreateParams params(profile(), true); - std::unique_ptr<Browser> browser = - FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms); - AddTab(browser.get()); - - UkmMetricMap expected_metrics({ - {TabManager_WindowMetrics::kWindowIdName, browser->session_id().id()}, - {TabManager_WindowMetrics::kShowStateName, - WindowMetricsEvent::SHOW_STATE_NORMAL}, - {TabManager_WindowMetrics::kTypeName, WindowMetricsEvent::TYPE_TABBED}, - {TabManager_WindowMetrics::kIsActiveName, 1}, - {TabManager_WindowMetrics::kTabCountName, 1}, - }); - { - SCOPED_TRACE(""); - // Window UKMs are not expected to be associated with any particular URL. - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), expected_metrics); - } - - AddTab(browser.get()); - expected_metrics[TabManager_WindowMetrics::kTabCountName].value()++; - { - SCOPED_TRACE(""); - // Window UKMs are not expected to be associated with any particular URL. - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), expected_metrics); - } - - browser->window()->Minimize(); - expected_metrics[TabManager_WindowMetrics::kShowStateName] = - WindowMetricsEvent::SHOW_STATE_MINIMIZED; - expected_metrics[TabManager_WindowMetrics::kIsActiveName] = 0; - { - SCOPED_TRACE(""); - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), expected_metrics); - } - - // A new entry is not created if nothing changes. - EXPECT_FALSE(WasNewEntryRecorded()); - - // A second browser can be logged. - Browser::CreateParams params_2(Browser::TYPE_POPUP, profile(), true); - std::unique_ptr<Browser> browser_2 = - FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms_2); - - // An entry is not logged until a tab is added to the new window. - EXPECT_FALSE(WasNewEntryRecorded()); - - AddTab(browser_2.get()); - UkmMetricMap expected_metrics_2({ - {TabManager_WindowMetrics::kWindowIdName, browser_2->session_id().id()}, - {TabManager_WindowMetrics::kShowStateName, - WindowMetricsEvent::SHOW_STATE_NORMAL}, - {TabManager_WindowMetrics::kTypeName, WindowMetricsEvent::TYPE_POPUP}, - {TabManager_WindowMetrics::kIsActiveName, 1}, - {TabManager_WindowMetrics::kTabCountName, 1}, - }); - { - SCOPED_TRACE(""); - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), expected_metrics_2); - } - - // Switching the active browser logs two events. - browser_2->window()->Deactivate(); - expected_metrics_2[TabManager_WindowMetrics::kIsActiveName] = 0; - { - SCOPED_TRACE(""); - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), expected_metrics_2); - } - - browser->window()->Restore(); - expected_metrics[TabManager_WindowMetrics::kShowStateName] = - WindowMetricsEvent::SHOW_STATE_NORMAL; - expected_metrics[TabManager_WindowMetrics::kIsActiveName] = 1; - { - SCOPED_TRACE(""); - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), expected_metrics); - } - - browser->tab_strip_model()->CloseAllTabs(); - browser_2->tab_strip_model()->CloseAllTabs(); -} - -// Tests moving a tab between browser windows. -TEST_F(WindowActivityWatcherTest, MoveTabToOtherWindow) { - Browser::CreateParams params(profile(), true); - std::unique_ptr<Browser> starting_browser = - FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms); - AddTab(starting_browser.get()); - UkmMetricMap starting_browser_metrics({ - {TabManager_WindowMetrics::kWindowIdName, - starting_browser->session_id().id()}, - {TabManager_WindowMetrics::kIsActiveName, 1}, - {TabManager_WindowMetrics::kTabCountName, 1}, - }); - { - SCOPED_TRACE(""); - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), - starting_browser_metrics); - } - - // Add a second tab, so we can detach it while leaving the original window - // behind. - AddTab(starting_browser.get()); - starting_browser_metrics[TabManager_WindowMetrics::kTabCountName].value() = 2; - { - SCOPED_TRACE(""); - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), - starting_browser_metrics); - } - - // Drag the tab out of its window. - std::unique_ptr<content::WebContents> dragged_tab = - starting_browser->tab_strip_model()->DetachWebContentsAt(1); - starting_browser_metrics[TabManager_WindowMetrics::kTabCountName].value() = 1; - { - SCOPED_TRACE(""); - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), - starting_browser_metrics); - } - starting_browser->window()->Deactivate(); - starting_browser_metrics[TabManager_WindowMetrics::kIsActiveName].value() = - false; - { - SCOPED_TRACE(""); - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), - starting_browser_metrics); - } - - // Create a new Browser for the tab. - std::unique_ptr<Browser> created_browser = - FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms); - created_browser->window()->Activate(); - created_browser->tab_strip_model()->InsertWebContentsAt( - 0, std::move(dragged_tab), TabStripModel::ADD_ACTIVE); - UkmMetricMap created_browser_metrics({ - {TabManager_WindowMetrics::kWindowIdName, - created_browser->session_id().id()}, - {TabManager_WindowMetrics::kIsActiveName, 1}, - {TabManager_WindowMetrics::kTabCountName, 1}, - }); - { - SCOPED_TRACE(""); - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), - created_browser_metrics); - } - - starting_browser->tab_strip_model()->CloseAllTabs(); - created_browser->tab_strip_model()->CloseAllTabs(); -} - -// Tests that a replaced tab still causes event logging upon being detached. -// Test is flaky. See https://crbug.com/938055. -TEST_F(WindowActivityWatcherTest, DISABLED_ReplaceTab) { - Browser::CreateParams params(profile(), true); - std::unique_ptr<Browser> browser = - FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms); - AddTab(browser.get()); - UkmMetricMap expected_metrics({ - {TabManager_WindowMetrics::kWindowIdName, browser->session_id().id()}, - {TabManager_WindowMetrics::kTabCountName, 1}, - }); - { - SCOPED_TRACE(""); - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), expected_metrics); - } - - // Add a tab that will be replaced. - AddTab(browser.get()); - expected_metrics[TabManager_WindowMetrics::kTabCountName].value() = 2; - { - SCOPED_TRACE(""); - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), expected_metrics); - } - - // Replace the tab. - content::WebContents::CreateParams web_contents_params(profile(), nullptr); - std::unique_ptr<content::WebContents> new_contents = base::WrapUnique( - content::WebContentsTester::CreateTestWebContents(web_contents_params)); - std::unique_ptr<content::WebContents> old_contents = - browser->tab_strip_model()->ReplaceWebContentsAt(1, - std::move(new_contents)); - - // Close the replaced tab. This should log an event with an updated TabCount. - browser->tab_strip_model()->CloseWebContentsAt(1, TabStripModel::CLOSE_NONE); - expected_metrics[TabManager_WindowMetrics::kTabCountName].value() = 1; - { - SCOPED_TRACE(""); - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), expected_metrics); - } - - browser->tab_strip_model()->CloseAllTabs(); -} - -// Tests that counts are properly bucketized. -TEST_F(WindowActivityWatcherTest, Counts) { - Browser::CreateParams params(profile(), true); - std::unique_ptr<Browser> browser = - FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms); - UkmMetricMap expected_metrics; - - // Expected buckets for each tab count using a spacing factor of 1.5. - std::vector<int> expected_buckets = { - 0, // Not actually tested, since we don't log windows with 0 tabs. - 1, 2, 3, // Values up to 3 should be represented exactly. - 4, 4, 6, 6, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 18, - }; - - for (size_t i = 1; i < expected_buckets.size(); i++) { - SCOPED_TRACE(base::StringPrintf("Tab count: %zd", i)); - AddTab(browser.get()); - expected_metrics[TabManager_WindowMetrics::kTabCountName] = - expected_buckets[i]; - ukm_entry_checker()->ExpectNewEntry(kEntryName, GURL(), expected_metrics); - } - - browser->tab_strip_model()->CloseAllTabs(); -} - -// Tests that incognito windows are ignored. -TEST_F(WindowActivityWatcherTest, Incognito) { - Browser::CreateParams params(profile()->GetOffTheRecordProfile(), true); - std::unique_ptr<Browser> browser = - FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms); - AddTab(browser.get()); - EXPECT_EQ(0u, ukm_entry_checker()->NumEntries(kEntryName)); - - browser->tab_strip_model()->CloseAllTabs(); -}
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc index 1b7d23b8..294f3017 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
@@ -284,7 +284,7 @@ base::Unretained(this))); menu_runner_->RunMenuAt(source->GetWidget(), NULL, gfx::Rect(p, gfx::Size(0, 0)), - views::MENU_ANCHOR_TOPLEFT, source_type); + views::MenuAnchorPosition::kTopLeft, source_type); } else { menu_model_.reset(); }
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc index 705b80a1..b525e12 100644 --- a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/ui/views/autofill/save_card_bubble_views.h" #include "chrome/browser/ui/views/autofill/save_card_icon_view.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" +#include "chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/autofill/content/browser/content_autofill_driver.h" @@ -646,10 +647,25 @@ SaveCardIconView* GetSaveCardIconView() { if (!browser()) return nullptr; - LocationBarView* location_bar_view = - static_cast<LocationBarView*>(browser()->window()->GetLocationBar()); - DCHECK(location_bar_view->save_credit_card_icon_view()); - return location_bar_view->save_credit_card_icon_view(); + + SaveCardIconView* icon_view = nullptr; + if (base::FeatureList::IsEnabled( + features::kAutofillEnableToolbarStatusChip)) { + ToolbarPageActionIconContainerView* + toolbar_page_action_icon_container_view = + static_cast<ToolbarPageActionIconContainerView*>( + browser()->window()->GetToolbarPageActionIconContainer()); + DCHECK(toolbar_page_action_icon_container_view->save_card_icon_view()); + icon_view = + toolbar_page_action_icon_container_view->save_card_icon_view(); + } else { + LocationBarView* location_bar_view = + static_cast<LocationBarView*>(browser()->window()->GetLocationBar()); + DCHECK(location_bar_view->save_credit_card_icon_view()); + icon_view = location_bar_view->save_credit_card_icon_view(); + } + + return icon_view; } content::WebContents* GetActiveWebContents() { @@ -696,6 +712,25 @@ DISALLOW_COPY_AND_ASSIGN(SaveCardBubbleViewsFullFormBrowserTest); }; +// TODO(crbug.com/932818): Remove this class after experiment flag is cleaned +// up. Otherwise we need it because the toolbar is init-ed before each test is +// set up. Thus need to enable the feature in the general browsertest SetUp(). +class SaveCardBubbleViewsFullFormBrowserTestForStatusChip + : public SaveCardBubbleViewsFullFormBrowserTest { + protected: + SaveCardBubbleViewsFullFormBrowserTestForStatusChip() + : SaveCardBubbleViewsFullFormBrowserTest() {} + ~SaveCardBubbleViewsFullFormBrowserTestForStatusChip() override {} + + void SetUp() override { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kAutofillEnableToolbarStatusChip); + + SaveCardBubbleViewsFullFormBrowserTest::SetUp(); + } +}; + // Tests the local save bubble. Ensures that clicking the [Save] button // successfully causes the bubble to go away. IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, @@ -2715,4 +2750,33 @@ AutofillMetrics::SAVE_CARD_ICON_SHOWN_WITHOUT_PROMPT, 1); } +// Ensures that the credit card icon will show in status chip. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTestForStatusChip, + CreditCardIconShownInStatusChip) { + ResetEventWaiterForSequence({DialogEvent::OFFERED_LOCAL_SAVE}); + NavigateTo(kCreditCardUploadForm); + FillAndSubmitForm(); + WaitForObservedEvent(); + EXPECT_TRUE(GetSaveCardIconView()); + EXPECT_TRUE(GetSaveCardIconView()->visible()); +} + +// Ensures that the clicking on the credit card icon will reshow bubble. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTestForStatusChip, + ClickingOnCreditCardIconInStatusChipReshowsBubble) { + ResetEventWaiterForSequence({DialogEvent::OFFERED_LOCAL_SAVE}); + NavigateTo(kCreditCardUploadForm); + FillAndSubmitForm(); + WaitForObservedEvent(); + + ClickOnCloseButton(); + AddEventObserverToController(); + ResetEventWaiterForSequence({DialogEvent::BUBBLE_SHOWN}); + ClickOnView(GetSaveCardIconView()); + WaitForObservedEvent(); + + EXPECT_TRUE(GetSaveCardBubbleViews()); + EXPECT_TRUE(GetSaveCardBubbleViews()->visible()); +} + } // namespace autofill
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index bf09da8f..92e092746 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -678,10 +678,11 @@ void BookmarkBarView::GetAnchorPositionForButton( views::MenuButton* button, views::MenuAnchorPosition* anchor) { + using Position = views::MenuAnchorPosition; if (button == other_bookmarks_button_ || button == overflow_button_) - *anchor = views::MENU_ANCHOR_TOPRIGHT; + *anchor = Position::kTopRight; else - *anchor = views::MENU_ANCHOR_TOPLEFT; + *anchor = Position::kTopLeft; } views::MenuItemView* BookmarkBarView::GetMenu() {
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_context_menu.cc b/chrome/browser/ui/views/bookmarks/bookmark_context_menu.cc index cd2b00e..9749a873 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_context_menu.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_context_menu.cc
@@ -79,7 +79,7 @@ // width/height don't matter here. menu_runner_->RunMenuAt(parent_widget_, nullptr, gfx::Rect(point.x(), point.y(), 0, 0), - views::MENU_ANCHOR_TOPLEFT, source_type); + views::MenuAnchorPosition::kTopLeft, source_type); } void BookmarkContextMenu::SetPageNavigator(PageNavigator* navigator) {
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc index 935ba24..ea4a7c6 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
@@ -248,7 +248,8 @@ context_menu_runner_->RunMenuAt(source->GetWidget()->GetTopLevelWidget(), NULL, gfx::Rect(point, gfx::Size()), - views::MENU_ANCHOR_TOPRIGHT, source_type); + views::MenuAnchorPosition::kTopRight, + source_type); } const char* BookmarkEditorView::GetClassName() const {
diff --git a/chrome/browser/ui/views/download/download_shelf_context_menu_view.cc b/chrome/browser/ui/views/download/download_shelf_context_menu_view.cc index 47d2295..675e3a2 100644 --- a/chrome/browser/ui/views/download/download_shelf_context_menu_view.cc +++ b/chrome/browser/ui/views/download/download_shelf_context_menu_view.cc
@@ -25,6 +25,7 @@ const gfx::Rect& rect, ui::MenuSourceType source_type, const base::Closure& on_menu_closed_callback) { + using Position = views::MenuAnchorPosition; ui::MenuModel* menu_model = GetMenuModel(); // Run() should not be getting called if the DownloadItem was destroyed. DCHECK(menu_model); @@ -36,11 +37,11 @@ base::Unretained(this), on_menu_closed_callback))); // The menu's alignment is determined based on the UI layout. - views::MenuAnchorPosition position; + Position position; if (base::i18n::IsRTL()) - position = views::MENU_ANCHOR_TOPRIGHT; + position = Position::kTopRight; else - position = views::MENU_ANCHOR_TOPLEFT; + position = Position::kTopLeft; menu_runner_->RunMenuAt(parent_widget, NULL, rect, position, source_type); }
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc index 763eaf5a..cf3b11d3 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
@@ -316,7 +316,7 @@ context_menu_runner_->RunMenuAt( GetWidget(), NULL, gfx::Rect(point.x(), point.y(), views::GridLayout::kFixedSize, 0), - views::MENU_ANCHOR_TOPLEFT, source_type); + views::MenuAnchorPosition::kTopLeft, source_type); } bool MediaGalleriesDialogViews::ControllerHasWebContents() const {
diff --git a/chrome/browser/ui/views/frame/browser_frame.cc b/chrome/browser/ui/views/frame/browser_frame.cc index c03e309..116ad93 100644 --- a/chrome/browser/ui/views/frame/browser_frame.cc +++ b/chrome/browser/ui/views/frame/browser_frame.cc
@@ -257,7 +257,7 @@ base::Unretained(this)))); menu_runner_->RunMenuAt(source->GetWidget(), nullptr, gfx::Rect(p, gfx::Size(0, 0)), - views::MENU_ANCHOR_TOPLEFT, source_type); + views::MenuAnchorPosition::kTopLeft, source_type); } }
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 90a6abd..abfffb8 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1316,41 +1316,57 @@ bookmark_bar_view_.get()); } +// TODO(crbug.com/932818): Clean up this two functions and add helper for shared +// code. autofill::SaveCardBubbleView* BrowserView::ShowSaveCreditCardBubble( content::WebContents* web_contents, autofill::SaveCardBubbleController* controller, bool user_gesture) { - LocationBarView* location_bar = GetLocationBarView(); - PageActionIconView* card_view = location_bar->save_credit_card_icon_view(); - autofill::BubbleType bubble_type = controller->GetBubbleType(); - autofill::SaveCardBubbleViews* bubble = nullptr; + PageActionIconView* icon_view = nullptr; + views::View* anchor_view = nullptr; + if (base::FeatureList::IsEnabled( + autofill::features::kAutofillEnableToolbarStatusChip)) { + // Icon will be shown in the status chip when feature is enabled. The anchor + // view for the bubble is the status chip container. + ToolbarPageActionIconContainerView* toolbar_page_action_container = + toolbar_->toolbar_page_action_container(); + icon_view = toolbar_page_action_container->GetIconView( + PageActionIconType::kSaveCard); + anchor_view = toolbar_page_action_container; + } else { + // Otherwise the bubble is anchored to the credit card icon in the location + // bar. This will be removed when the feature is fully enabled. + LocationBarView* location_bar = GetLocationBarView(); + icon_view = location_bar->save_credit_card_icon_view(); + anchor_view = location_bar; + } + + autofill::SaveCardBubbleViews* bubble = nullptr; switch (bubble_type) { case autofill::BubbleType::LOCAL_SAVE: case autofill::BubbleType::UPLOAD_SAVE: - bubble = new autofill::SaveCardOfferBubbleViews( - location_bar, gfx::Point(), web_contents, controller); + bubble = new autofill::SaveCardOfferBubbleViews(anchor_view, gfx::Point(), + web_contents, controller); break; case autofill::BubbleType::SIGN_IN_PROMO: bubble = new autofill::SaveCardSignInPromoBubbleViews( - location_bar, gfx::Point(), web_contents, controller); + anchor_view, gfx::Point(), web_contents, controller); break; case autofill::BubbleType::MANAGE_CARDS: bubble = new autofill::SaveCardManageCardsBubbleViews( - location_bar, gfx::Point(), web_contents, controller); + anchor_view, gfx::Point(), web_contents, controller); break; case autofill::BubbleType::INACTIVE: break; } - DCHECK(bubble); - if (card_view) - bubble->SetHighlightedButton(card_view); + if (icon_view) + bubble->SetHighlightedButton(icon_view); views::BubbleDialogDelegateView::CreateBubble(bubble); - bubble->Show(user_gesture ? autofill::SaveCardBubbleViews::USER_GESTURE : autofill::SaveCardBubbleViews::AUTOMATIC); return bubble;
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc index 4cf12e1..43d9fa4 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
@@ -357,7 +357,8 @@ views::MenuRunner::HAS_MNEMONICS); menu_runner.RunMenuAt(browser_view()->GetWidget(), window_icon_, window_icon_->GetBoundsInScreen(), - views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE); + views::MenuAnchorPosition::kTopLeft, + ui::MENU_SOURCE_MOUSE); #endif }
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc index d5d52ce0..a7451a8e 100644 --- a/chrome/browser/ui/views/infobars/infobar_view.cc +++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -205,7 +205,7 @@ if (ShouldDrawSeparator()) { const SkColor color = - GetColor(ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_SEPARATOR); + GetColor(ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR); BrowserView::Paint1pxHorizontalLine(canvas, color, GetLocalBounds(), false); } }
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 4384187..fa5b068 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -264,7 +264,6 @@ } for (PageActionIconView* icon_view : page_action_icons_) { - icon_view->Init(); icon_view->SetVisible(false); icon_view->SetIconColor(icon_color); AddChildView(icon_view);
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view.cc b/chrome/browser/ui/views/media_router/cast_dialog_view.cc index 7871b6c..855469d06 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_view.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_view.cc
@@ -367,9 +367,9 @@ sources_menu_runner_ = std::make_unique<views::MenuRunner>( sources_menu_model_.get(), views::MenuRunner::COMBOBOX); const gfx::Rect& screen_bounds = sources_button_->GetBoundsInScreen(); - sources_menu_runner_->RunMenuAt(sources_button_->GetWidget(), nullptr, - screen_bounds, views::MENU_ANCHOR_TOPLEFT, - ui::MENU_SOURCE_MOUSE); + sources_menu_runner_->RunMenuAt( + sources_button_->GetWidget(), nullptr, screen_bounds, + views::MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_MOUSE); } void CastDialogView::SelectSource(SourceType source) {
diff --git a/chrome/browser/ui/views/menu_interactive_uitest.cc b/chrome/browser/ui/views/menu_interactive_uitest.cc index 1ed4e47..4acc26b 100644 --- a/chrome/browser/ui/views/menu_interactive_uitest.cc +++ b/chrome/browser/ui/views/menu_interactive_uitest.cc
@@ -39,7 +39,8 @@ menu_item->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two")); // Run the menu, so that the menu item size will be calculated. menu_runner_->RunMenuAt(widget, nullptr, gfx::Rect(), - views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_NONE); + views::MenuAnchorPosition::kTopLeft, + ui::MENU_SOURCE_NONE); RunPendingMessages(); // Figure out the middle of the first menu item. mouse_pos_.set_x(first_item_->width() / 2); @@ -88,7 +89,8 @@ // when we run the menu. SetupMenu(widget); menu_runner_->RunMenuAt(widget, nullptr, gfx::Rect(), - views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_NONE); + views::MenuAnchorPosition::kTopLeft, + ui::MENU_SOURCE_NONE); // One or two mouse events are posted by the menu being shown. // Process event(s), and check what's selected in the menu. RunPendingMessages(); @@ -123,7 +125,8 @@ menu_item->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One")); menu_item->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two")); menu_runner->RunMenuAt(nullptr, nullptr, gfx::Rect(), - views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_NONE); + views::MenuAnchorPosition::kTopLeft, + ui::MENU_SOURCE_NONE); base::RunLoop loop; // SendKeyPress fails if the window doesn't have focus. ASSERT_TRUE(ui_controls::SendKeyPressNotifyWhenDone(
diff --git a/chrome/browser/ui/views/menu_model_adapter_test.cc b/chrome/browser/ui/views/menu_model_adapter_test.cc index 5fafbf9..78ea1d3 100644 --- a/chrome/browser/ui/views/menu_model_adapter_test.cc +++ b/chrome/browser/ui/views/menu_model_adapter_test.cc
@@ -195,7 +195,8 @@ views::View::ConvertPointToScreen(source, &screen_location); gfx::Rect bounds(screen_location, source->size()); menu_runner_->RunMenuAt(source->GetWidget(), button_, bounds, - views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_NONE); + views::MenuAnchorPosition::kTopLeft, + ui::MENU_SOURCE_NONE); } // ViewEventTestBase implementation
diff --git a/chrome/browser/ui/views/menu_test_base.cc b/chrome/browser/ui/views/menu_test_base.cc index 5c892519..3b38b1e 100644 --- a/chrome/browser/ui/views/menu_test_base.cc +++ b/chrome/browser/ui/views/menu_test_base.cc
@@ -82,7 +82,8 @@ views::View::ConvertPointToScreen(source, &screen_location); gfx::Rect bounds(screen_location, source->size()); menu_runner_->RunMenuAt(source->GetWidget(), button_, bounds, - views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_NONE); + views::MenuAnchorPosition::kTopLeft, + ui::MENU_SOURCE_NONE); } void MenuTestBase::ExecuteCommand(int id) {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc index 210f888..e3a1f6a 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -436,9 +436,9 @@ &context_menu_contents_, views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU, set_hovered_false); - context_menu_runner_->RunMenuAt(GetWidget(), nullptr, - gfx::Rect(point, gfx::Size()), - views::MENU_ANCHOR_TOPLEFT, source_type); + context_menu_runner_->RunMenuAt( + GetWidget(), nullptr, gfx::Rect(point, gfx::Size()), + views::MenuAnchorPosition::kTopLeft, source_type); // Opening the context menu unsets the hover state, but we still want the // result 'hovered' as long as the context menu is open.
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc index df68c3d..76014ee 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
@@ -1180,3 +1180,23 @@ EXPECT_EQ(0U, end); } } + +TEST_F(OmniboxViewViewsSteadyStateElisionsAndQueryInOmniboxTest, + NoEmphasisForUrlLikeQueries) { + // Prevents regressions for crbug.com/942945. Set the displayed search terms + // to something somewhat URL-like. + location_bar_model()->set_display_search_terms(base::ASCIIToUTF16("foo:bar")); + omnibox_view()->model()->ResetDisplayTexts(); + omnibox_view()->RevertAll(); + EXPECT_EQ(base::ASCIIToUTF16("foo:bar"), omnibox_view()->text()); + EXPECT_FALSE(omnibox_view()->model()->user_input_in_progress()); + + omnibox_view()->ResetEmphasisTestState(); + omnibox_view()->EmphasizeURLComponents(); + + // Expect that no part is de-emphasized, there is no "scheme" range. + EXPECT_EQ(TestingOmniboxView::BaseTextEmphasis::EMPHASIZED, + omnibox_view()->base_text_emphasis()); + EXPECT_FALSE(omnibox_view()->emphasis_range().IsValid()); + EXPECT_FALSE(omnibox_view()->scheme_range().IsValid()); +}
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_container_view.cc b/chrome/browser/ui/views/page_action/page_action_icon_container_view.cc index e38c809f..38d9b54 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_container_view.cc +++ b/chrome/browser/ui/views/page_action/page_action_icon_container_view.cc
@@ -60,6 +60,7 @@ page_action_icons_.push_back(zoom_view_); break; case PageActionIconType::kLocalCardMigration: + case PageActionIconType::kSaveCard: NOTREACHED(); break; } @@ -68,7 +69,6 @@ for (PageActionIconView* icon : page_action_icons_) { icon->SetVisible(false); icon->set_icon_size(params.icon_size); - icon->Init(); icon->SetIconColor(params.icon_color); AddChildView(icon); } @@ -98,6 +98,7 @@ case PageActionIconType::kZoom: return zoom_view_; case PageActionIconType::kLocalCardMigration: + case PageActionIconType::kSaveCard: NOTREACHED(); return nullptr; }
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_view.cc b/chrome/browser/ui/views/page_action/page_action_icon_view.cc index 4f2521f..2fe912f9 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_view.cc +++ b/chrome/browser/ui/views/page_action/page_action_icon_view.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/ui/views/page_action/page_action_icon_view.h" #include "chrome/browser/command_updater.h" -#include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/omnibox/omnibox_theme.h" #include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h" #include "ui/accessibility/ax_node_data.h" @@ -31,27 +30,19 @@ } // namespace -void PageActionIconView::Init() { - AddChildView(image()); - image()->set_can_process_events_within_subtree(false); - image()->EnableCanvasFlippingForRTLUI(true); - SetInkDropMode(InkDropMode::ON); - SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); -} - PageActionIconView::PageActionIconView(CommandUpdater* command_updater, int command_id, PageActionIconView::Delegate* delegate, const gfx::FontList& font_list) : IconLabelBubbleView(font_list), - icon_size_(GetLayoutConstant(LOCATION_BAR_ICON_SIZE)), command_updater_(command_updater), delegate_(delegate), - command_id_(command_id), - active_(false), - suppress_mouse_released_action_(false) { + command_id_(command_id) { + image()->EnableCanvasFlippingForRTLUI(true); + SetInkDropMode(InkDropMode::ON); set_ink_drop_visible_opacity( GetOmniboxStateOpacity(OmniboxPartState::SELECTED)); + SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); } PageActionIconView::~PageActionIconView() {}
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_view.h b/chrome/browser/ui/views/page_action/page_action_icon_view.h index 0ad8eb7f..b9dd25a 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_view.h +++ b/chrome/browser/ui/views/page_action/page_action_icon_view.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/scoped_observer.h" +#include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/omnibox/omnibox_theme.h" #include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h" #include "third_party/skia/include/core/SkColor.h" @@ -43,8 +44,6 @@ virtual content::WebContents* GetWebContentsForPageActionIconView() = 0; }; - void Init(); - // Updates the color of the icon, this must be set before the icon is drawn. void SetIconColor(SkColor icon_color); @@ -142,7 +141,7 @@ private: // The size of the icon image (excluding the ink drop). - int icon_size_; + int icon_size_ = GetLayoutConstant(LOCATION_BAR_ICON_SIZE); // What color to paint the icon with. SkColor icon_color_ = gfx::kPlaceholderColor; @@ -159,12 +158,12 @@ // The active node_data. The precise definition of "active" is unique to each // subclass, but generally indicates that the associated feature is acting on // the web page. - bool active_; + bool active_ = false; // This is used to check if the bookmark bubble was showing during the mouse // pressed event. If this is true then the mouse released event is ignored to // prevent the bubble from reshowing. - bool suppress_mouse_released_action_; + bool suppress_mouse_released_action_ = false; DISALLOW_COPY_AND_ASSIGN(PageActionIconView); };
diff --git a/chrome/browser/ui/views/profiles/dice_accounts_menu.cc b/chrome/browser/ui/views/profiles/dice_accounts_menu.cc index 14840d0..ff9d008 100644 --- a/chrome/browser/ui/views/profiles/dice_accounts_menu.cc +++ b/chrome/browser/ui/views/profiles/dice_accounts_menu.cc
@@ -68,7 +68,8 @@ anchor_bounds.Inset(anchor_bounds.width(), 0, 0, 0); runner_->RunMenuAt(anchor_view->GetWidget(), menu_button, anchor_bounds, - views::MENU_ANCHOR_TOPRIGHT, ui::MENU_SOURCE_MOUSE); + views::MenuAnchorPosition::kTopRight, + ui::MENU_SOURCE_MOUSE); } DiceAccountsMenu::~DiceAccountsMenu() {}
diff --git a/chrome/browser/ui/views/status_icons/status_icon_win.cc b/chrome/browser/ui/views/status_icons/status_icon_win.cc index 9673855..909f1ba 100644 --- a/chrome/browser/ui/views/status_icons/status_icon_win.cc +++ b/chrome/browser/ui/views/status_icons/status_icon_win.cc
@@ -64,7 +64,8 @@ menu_runner_.reset(new views::MenuRunner(menu_model_, views::MenuRunner::HAS_MNEMONICS)); menu_runner_->RunMenuAt(NULL, NULL, gfx::Rect(cursor_pos, gfx::Size()), - views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE); + views::MenuAnchorPosition::kTopLeft, + ui::MENU_SOURCE_MOUSE); } void StatusIconWin::HandleBalloonClickEvent() {
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc index 2d1b6ecb..50d45952 100644 --- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -111,7 +111,7 @@ void RunMenuAt(const gfx::Point& point, ui::MenuSourceType source_type) { menu_runner_->RunMenuAt(tab_->GetWidget(), NULL, gfx::Rect(point, gfx::Size()), - views::MENU_ANCHOR_TOPLEFT, source_type); + views::MenuAnchorPosition::kTopLeft, source_type); } // Overridden from ui::SimpleMenuModel::Delegate:
diff --git a/chrome/browser/ui/views/task_manager_view.cc b/chrome/browser/ui/views/task_manager_view.cc index 653db3d5..0a3a2ba 100644 --- a/chrome/browser/ui/views/task_manager_view.cc +++ b/chrome/browser/ui/views/task_manager_view.cc
@@ -288,7 +288,7 @@ views::MenuRunner::CONTEXT_MENU)); menu_runner_->RunMenuAt(GetWidget(), nullptr, gfx::Rect(point, gfx::Size()), - views::MENU_ANCHOR_TOPLEFT, source_type); + views::MenuAnchorPosition::kTopLeft, source_type); } bool TaskManagerView::IsCommandIdChecked(int id) const {
diff --git a/chrome/browser/ui/views/toolbar/app_menu.cc b/chrome/browser/ui/views/toolbar/app_menu.cc index 771baf7d..67d3fa8 100644 --- a/chrome/browser/ui/views/toolbar/app_menu.cc +++ b/chrome/browser/ui/views/toolbar/app_menu.cc
@@ -813,9 +813,9 @@ void AppMenu::RunMenu(views::MenuButton* host) { base::RecordAction(UserMetricsAction("ShowAppMenu")); - menu_runner_->RunMenuAt(host->GetWidget(), host, - host->GetAnchorBoundsInScreen(), - views::MENU_ANCHOR_TOPRIGHT, ui::MENU_SOURCE_NONE); + menu_runner_->RunMenuAt( + host->GetWidget(), host, host->GetAnchorBoundsInScreen(), + views::MenuAnchorPosition::kTopRight, ui::MENU_SOURCE_NONE); } void AppMenu::CloseMenu() {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc index 55993269..a9f3ec9 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
@@ -349,7 +349,7 @@ menu_runner_.reset(new views::MenuRunner(menu_, run_types)); menu_runner_->RunMenuAt(parent, this, GetAnchorBoundsInScreen(), - views::MENU_ANCHOR_TOPLEFT, source_type); + views::MenuAnchorPosition::kTopLeft, source_type); } bool ToolbarActionView::CloseActiveMenuIfNeeded() {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc index a9aaf0b..0e3f452 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_button.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -372,7 +372,7 @@ menu_runner_ = std::make_unique<views::MenuRunner>( menu_model_adapter_->CreateMenu(), views::MenuRunner::HAS_MNEMONICS); menu_runner_->RunMenuAt(GetWidget(), nullptr, menu_anchor_bounds, - views::MENU_ANCHOR_TOPLEFT, source_type); + views::MenuAnchorPosition::kTopLeft, source_type); } void ToolbarButton::OnMenuClosed() {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view.cc b/chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view.cc index 5e097da..1491e3b 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view.cc
@@ -16,13 +16,21 @@ : ToolbarIconContainerView(), browser_(browser) { local_card_migration_icon_view_ = new autofill::LocalCardMigrationIconView( command_updater, browser, this, - // TODO(932818): The font list and the icon color may not be what we want - // here. Put placeholders for now. + // TODO(crbug.com/932818): The font list and the icon color may not be + // what we want here. Put placeholders for now. views::style::GetFont(CONTEXT_TOOLBAR_BUTTON, views::style::STYLE_PRIMARY)); - local_card_migration_icon_view_->Init(); local_card_migration_icon_view_->SetVisible(false); AddChildView(local_card_migration_icon_view_); + + save_card_icon_view_ = new autofill::SaveCardIconView( + command_updater, browser, this, + // TODO(crbug.com/932818): The font list and the icon color may not be + // what we want here. Put placeholders for now. + views::style::GetFont(CONTEXT_TOOLBAR_BUTTON, + views::style::STYLE_PRIMARY)); + save_card_icon_view_->SetVisible(false); + AddChildView(save_card_icon_view_); } ToolbarPageActionIconContainerView::~ToolbarPageActionIconContainerView() = @@ -31,6 +39,9 @@ void ToolbarPageActionIconContainerView::UpdateAllIcons() { if (local_card_migration_icon_view_) local_card_migration_icon_view_->Update(); + + if (save_card_icon_view_) + save_card_icon_view_->Update(); } PageActionIconView* ToolbarPageActionIconContainerView::GetIconView( @@ -38,7 +49,10 @@ switch (icon_type) { case PageActionIconType::kLocalCardMigration: return local_card_migration_icon_view_; + case PageActionIconType::kSaveCard: + return save_card_icon_view_; default: + NOTREACHED(); return nullptr; } }
diff --git a/chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view.h b/chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view.h index 5b208ebb..62018c7f 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view.h
@@ -15,6 +15,7 @@ namespace autofill { class LocalCardMigrationIconView; +class SaveCardIconView; } // namespace autofill // A container view for user-account-related PageActionIconViews and the profile @@ -41,13 +42,18 @@ SkColor GetPageActionInkDropColor() const override; content::WebContents* GetWebContentsForPageActionIconView() override; - autofill::LocalCardMigrationIconView* local_card_migration_icon_view() { + autofill::LocalCardMigrationIconView* local_card_migration_icon_view() const { return local_card_migration_icon_view_; } + autofill::SaveCardIconView* save_card_icon_view() const { + return save_card_icon_view_; + } + private: autofill::LocalCardMigrationIconView* local_card_migration_icon_view_ = nullptr; + autofill::SaveCardIconView* save_card_icon_view_ = nullptr; Browser* const browser_;
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc index 764c461f..a9042d8 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view.cc +++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -362,7 +362,7 @@ options_menu_model_.get(), views::MenuRunner::COMBOBOX)); gfx::Rect screen_bounds = source->GetBoundsInScreen(); options_menu_runner_->RunMenuAt(source->GetWidget(), nullptr, screen_bounds, - views::MENU_ANCHOR_TOPRIGHT, + views::MenuAnchorPosition::kTopRight, ui::MENU_SOURCE_MOUSE); }
diff --git a/chrome/browser/ui/views/webauthn/authenticator_request_dialog_view.cc b/chrome/browser/ui/views/webauthn/authenticator_request_dialog_view.cc index 619302f..db06f38 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_request_dialog_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_request_dialog_view.cc
@@ -257,7 +257,8 @@ gfx::Rect anchor_bounds = other_transports_button_->GetBoundsInScreen(); other_transports_menu_runner_->RunMenuAt( other_transports_button_->GetWidget(), nullptr /* menu_button */, - anchor_bounds, views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE); + anchor_bounds, views::MenuAnchorPosition::kTopLeft, + ui::MENU_SOURCE_MOUSE); } void AuthenticatorRequestDialogView::ReplaceCurrentSheetWith(
diff --git a/chrome/browser/ui/webui/chromeos/set_time_ui.cc b/chrome/browser/ui/webui/chromeos/set_time_ui.cc index f9c80ba..92ff3fa6 100644 --- a/chrome/browser/ui/webui/chromeos/set_time_ui.cc +++ b/chrome/browser/ui/webui/chromeos/set_time_ui.cc
@@ -24,6 +24,7 @@ #include "chromeos/constants/chromeos_features.h" #include "chromeos/dbus/system_clock/system_clock_client.h" #include "chromeos/settings/timezone_settings.h" +#include "components/strings/grit/components_strings.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" @@ -137,11 +138,17 @@ source->AddLocalizedString("setTimeTitle", IDS_SET_TIME_TITLE); source->AddLocalizedString("prompt", IDS_SET_TIME_PROMPT); - source->AddLocalizedString("doneButton", IDS_SET_TIME_BUTTON_CLOSE); - source->AddLocalizedString("timezone", - IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION); - source->AddLocalizedString("dateLabel", IDS_SET_TIME_DATE_LABEL); - source->AddLocalizedString("timeLabel", IDS_SET_TIME_TIME_LABEL); + if (chromeos::features::IsSetTimeDialogMd()) { + source->AddLocalizedString("timezoneLabel", IDS_MD_SET_TIME_TIMEZONE_LABEL); + source->AddLocalizedString("dateLabel", IDS_MD_SET_TIME_DATE_LABEL); + source->AddLocalizedString("timeLabel", IDS_MD_SET_TIME_TIME_LABEL); + } else { + source->AddLocalizedString("timezone", + IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION); + source->AddLocalizedString("dateLabel", IDS_SET_TIME_DATE_LABEL); + source->AddLocalizedString("timeLabel", IDS_SET_TIME_TIME_LABEL); + } + source->AddLocalizedString("doneButton", IDS_DONE); base::DictionaryValue values; // List of list of strings: [[ID, name], [ID, name], ...]
diff --git a/chrome/browser/ui/webui/feed_internals/feed_internals.mojom b/chrome/browser/ui/webui/feed_internals/feed_internals.mojom index 4382879..bf6f965 100644 --- a/chrome/browser/ui/webui/feed_internals/feed_internals.mojom +++ b/chrome/browser/ui/webui/feed_internals/feed_internals.mojom
@@ -102,4 +102,7 @@ // Internal state dump of the Feed library's process scope. GetFeedProcessScopeDump() => (string dump); + + // Record all Feed metrics into a log. + GetFeedHistograms() => (string log); };
diff --git a/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.cc b/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.cc index e210b27..51c01b6 100644 --- a/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.cc +++ b/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/feature_list.h" +#include "base/metrics/statistics_recorder.h" #include "base/time/time.h" #include "chrome/browser/android/feed/feed_debugging_bridge.h" #include "chrome/browser/android/feed/feed_lifecycle_bridge.h" @@ -23,6 +24,8 @@ namespace { +const char kFeedHistogramPrefix[] = "ContentSuggestions.Feed."; + feed_internals::mojom::TimePtr ToMojoTime(base::Time time) { return time.is_null() ? nullptr : feed_internals::mojom::Time::New(time.ToJsTime()); @@ -155,3 +158,10 @@ bool FeedInternalsPageHandler::IsFeedAllowed() { return pref_service_->GetBoolean(feed::prefs::kEnableSnippets); } + +void FeedInternalsPageHandler::GetFeedHistograms( + GetFeedHistogramsCallback callback) { + std::string log; + base::StatisticsRecorder::WriteGraph(kFeedHistogramPrefix, &log); + std::move(callback).Run(log); +}
diff --git a/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.h b/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.h index d3070c7..67f1327f 100644 --- a/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.h +++ b/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.h
@@ -42,6 +42,7 @@ void RefreshFeed() override; void GetCurrentContent(GetCurrentContentCallback) override; void GetFeedProcessScopeDump(GetFeedProcessScopeDumpCallback) override; + void GetFeedHistograms(GetFeedHistogramsCallback) override; private: // Binding from the mojo interface to concrete implementation.
diff --git a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc index b1982c6..99048ab 100644 --- a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
@@ -24,7 +24,9 @@ CrostiniHandler::CrostiniHandler(Profile* profile) : profile_(profile), weak_ptr_factory_(this) {} -CrostiniHandler::~CrostiniHandler() = default; +CrostiniHandler::~CrostiniHandler() { + DisallowJavascript(); +} void CrostiniHandler::RegisterMessages() { web_ui()->RegisterMessageCallback(
diff --git a/chrome/browser/ui/webui/theme_handler.cc b/chrome/browser/ui/webui/theme_handler.cc index d0696a7..033a87d 100644 --- a/chrome/browser/ui/webui/theme_handler.cc +++ b/chrome/browser/ui/webui/theme_handler.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/bind.h" #include "base/values.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile.h" @@ -15,38 +16,64 @@ #include "chrome/grit/theme_resources.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_ui.h" +#include "ui/native_theme/native_theme.h" /////////////////////////////////////////////////////////////////////////////// // ThemeHandler -ThemeHandler::ThemeHandler() { -} +ThemeHandler::ThemeHandler() : theme_observer_(this) {} -ThemeHandler::~ThemeHandler() { -} +ThemeHandler::~ThemeHandler() {} void ThemeHandler::RegisterMessages() { // These are not actual message registrations, but can't be done in the // constructor since they need the web_ui value to be set, which is done // post-construction, but before registering messages. InitializeCSSCaches(); + web_ui()->RegisterMessageCallback( + "observeThemeChanges", + base::BindRepeating(&ThemeHandler::HandleObserveThemeChanges, + base::Unretained(this))); +} + +void ThemeHandler::OnJavascriptAllowed() { // Listen for theme installation. registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, content::Source<ThemeService>( ThemeServiceFactory::GetForProfile(GetProfile()))); + // Or native theme change. + theme_observer_.Add(ui::NativeTheme::GetInstanceForNativeUi()); +} + +void ThemeHandler::OnJavascriptDisallowed() { + registrar_.RemoveAll(); + theme_observer_.RemoveAll(); } void ThemeHandler::Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) { DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type); + SendThemeChanged(); +} + +void ThemeHandler::OnNativeThemeUpdated(ui::NativeTheme* observed_theme) { + DCHECK_EQ(observed_theme, ui::NativeTheme::GetInstanceForNativeUi()); + SendThemeChanged(); +} + +void ThemeHandler::HandleObserveThemeChanges(const base::ListValue* /*args*/) { + AllowJavascript(); +} + +void ThemeHandler::SendThemeChanged() { InitializeCSSCaches(); bool has_custom_bg = ThemeService::GetThemeProviderForProfile(GetProfile()) .HasCustomImage(IDR_THEME_NTP_BACKGROUND); // TODO(dbeam): why does this need to be a dictionary? base::DictionaryValue dictionary; dictionary.SetBoolean("hasCustomBackground", has_custom_bg); - web_ui()->CallJavascriptFunctionUnsafe("ntp.themeChanged", dictionary); + CallJavascriptFunction("ntp.themeChanged", dictionary); } void ThemeHandler::InitializeCSSCaches() {
diff --git a/chrome/browser/ui/webui/theme_handler.h b/chrome/browser/ui/webui/theme_handler.h index 7c2b88b..5e52e81d1 100644 --- a/chrome/browser/ui/webui/theme_handler.h +++ b/chrome/browser/ui/webui/theme_handler.h
@@ -6,22 +6,31 @@ #define CHROME_BROWSER_UI_WEBUI_THEME_HANDLER_H_ #include "base/macros.h" +#include "base/scoped_observer.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/web_ui_message_handler.h" +#include "ui/native_theme/native_theme_observer.h" class Profile; +namespace ui { +class NativeTheme; +} + // A class to keep the ThemeSource up to date when theme changes. class ThemeHandler : public content::WebUIMessageHandler, - public content::NotificationObserver { + public content::NotificationObserver, + public ui::NativeThemeObserver { public: - explicit ThemeHandler(); + ThemeHandler(); ~ThemeHandler() override; private: - // content::WebUIMessageHandler implementation. + // content::WebUIMessageHandler: void RegisterMessages() override; + void OnJavascriptAllowed() override; + void OnJavascriptDisallowed() override; // Re/set the CSS caches. void InitializeCSSCaches(); @@ -31,10 +40,21 @@ const content::NotificationSource& source, const content::NotificationDetails& details) override; + // ui::NativeThemeObserver: + void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override; + + // Handler for "observeThemeChanges" chrome.send() message. No arguments. + void HandleObserveThemeChanges(const base::ListValue* args); + + // Notify the page (if allowed) that the theme has changed. + void SendThemeChanged(); + Profile* GetProfile() const; content::NotificationRegistrar registrar_; + ScopedObserver<ui::NativeTheme, ThemeHandler> theme_observer_; + DISALLOW_COPY_AND_ASSIGN(ThemeHandler); };
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index 0dd334a8..ec18992 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -156,6 +156,7 @@ deps = [ ":web_app_group", "//chrome/browser/web_applications/bookmark_apps:browser_tests", + "//chrome/browser/web_applications/components:browser_tests", "//chrome/browser/web_applications/extensions:browser_tests", ] }
diff --git a/chrome/browser/web_applications/components/BUILD.gn b/chrome/browser/web_applications/components/BUILD.gn index 91e65fa..6a201e1 100644 --- a/chrome/browser/web_applications/components/BUILD.gn +++ b/chrome/browser/web_applications/components/BUILD.gn
@@ -22,6 +22,10 @@ "web_app_icon_generator.h", "web_app_install_utils.cc", "web_app_install_utils.h", + "web_app_provider_base.cc", + "web_app_provider_base.h", + "web_app_provider_base_factory.cc", + "web_app_provider_base_factory.h", "web_app_shortcut.cc", "web_app_shortcut.h", "web_app_shortcut_chromeos.cc", @@ -31,6 +35,8 @@ "web_app_shortcut_win.h", "web_app_tab_helper_base.cc", "web_app_tab_helper_base.h", + "web_app_url_loader.cc", + "web_app_url_loader.h", # TODO(nigeltao): move these two files from # //chrome/browser/web_applications/components to a stand-alone @@ -59,6 +65,7 @@ "//chrome/common", "//components/crx_file", "//components/favicon/content", + "//components/keyed_service/content", "//content/public/browser", "//skia", ] @@ -111,3 +118,20 @@ "//testing/gtest", ] } + +source_set("browser_tests") { + testonly = true + + sources = [ + "web_app_url_loader_browsertest.cc", + ] + + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] + + deps = [ + "//chrome/browser/web_applications/components", + "//chrome/test:test_support", + "//chrome/test:test_support_ui", + "//net:test_support", + ] +}
diff --git a/chrome/browser/web_applications/components/web_app_data_retriever.cc b/chrome/browser/web_applications/components/web_app_data_retriever.cc index 70cc13a..f82d7f8 100644 --- a/chrome/browser/web_applications/components/web_app_data_retriever.cc +++ b/chrome/browser/web_applications/components/web_app_data_retriever.cc
@@ -82,9 +82,9 @@ params.has_worker = true; // Do not wait_for_worker. OnDidPerformInstallableCheck is always invoked. installable_manager->GetData( - params, base::BindRepeating( - &WebAppDataRetriever::OnDidPerformInstallableCheck, - weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback))); + params, + base::BindOnce(&WebAppDataRetriever::OnDidPerformInstallableCheck, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void WebAppDataRetriever::GetIcons(content::WebContents* web_contents,
diff --git a/chrome/browser/web_applications/components/web_app_provider_base.cc b/chrome/browser/web_applications/components/web_app_provider_base.cc new file mode 100644 index 0000000..6e4eb6c --- /dev/null +++ b/chrome/browser/web_applications/components/web_app_provider_base.cc
@@ -0,0 +1,21 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/web_applications/components/web_app_provider_base.h" + +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/web_applications/components/web_app_provider_base_factory.h" + +namespace web_app { + +// static +WebAppProviderBase* WebAppProviderBase::GetProviderBase(Profile* profile) { + return WebAppProviderBaseFactory::GetForProfile(profile); +} + +WebAppProviderBase::WebAppProviderBase() = default; + +WebAppProviderBase::~WebAppProviderBase() = default; + +} // namespace web_app
diff --git a/chrome/browser/web_applications/components/web_app_provider_base.h b/chrome/browser/web_applications/components/web_app_provider_base.h new file mode 100644 index 0000000..c950fde6 --- /dev/null +++ b/chrome/browser/web_applications/components/web_app_provider_base.h
@@ -0,0 +1,40 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_PROVIDER_BASE_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_PROVIDER_BASE_H_ + +#include "base/macros.h" +#include "components/keyed_service/core/keyed_service.h" + +class Profile; + +namespace web_app { + +// Forward declarations of generalized interfaces. +class PendingAppManager; +class InstallManager; +class AppRegistrar; + +class WebAppProviderBase : public KeyedService { + public: + static WebAppProviderBase* GetProviderBase(Profile* profile); + + WebAppProviderBase(); + ~WebAppProviderBase() override; + + // The app registry manager. + virtual AppRegistrar& registrar() = 0; + // UIs can use InstallManager for user-initiated Web Apps install. + virtual InstallManager& install_manager() = 0; + // Clients can use PendingAppManager to install, uninstall, and update + // Web Apps. + virtual PendingAppManager& pending_app_manager() = 0; + + DISALLOW_COPY_AND_ASSIGN(WebAppProviderBase); +}; + +} // namespace web_app + +#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_PROVIDER_BASE_H_
diff --git a/chrome/browser/web_applications/components/web_app_provider_base_factory.cc b/chrome/browser/web_applications/components/web_app_provider_base_factory.cc new file mode 100644 index 0000000..0c4eb01 --- /dev/null +++ b/chrome/browser/web_applications/components/web_app_provider_base_factory.cc
@@ -0,0 +1,41 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/web_applications/components/web_app_provider_base_factory.h" + +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/web_applications/components/web_app_provider_base.h" + +namespace web_app { + +namespace { +WebAppProviderBaseFactory* g_factory = nullptr; +} // namespace + +// static +WebAppProviderBase* WebAppProviderBaseFactory::GetForProfile(Profile* profile) { + return static_cast<WebAppProviderBase*>( + GetInstance()->GetServiceForBrowserContext(profile, /* create=*/true)); +} + +// static +WebAppProviderBaseFactory* WebAppProviderBaseFactory::GetInstance() { + DCHECK(g_factory); + return g_factory; +} + +// static +void WebAppProviderBaseFactory::SetInstance( + WebAppProviderBaseFactory* factory) { + g_factory = factory; +} + +WebAppProviderBaseFactory::WebAppProviderBaseFactory( + const char* service_name, + BrowserContextDependencyManager* dependency_manager) + : BrowserContextKeyedServiceFactory(service_name, dependency_manager) {} + +WebAppProviderBaseFactory::~WebAppProviderBaseFactory() = default; + +} // namespace web_app
diff --git a/chrome/browser/web_applications/components/web_app_provider_base_factory.h b/chrome/browser/web_applications/components/web_app_provider_base_factory.h new file mode 100644 index 0000000..41a3f50 --- /dev/null +++ b/chrome/browser/web_applications/components/web_app_provider_base_factory.h
@@ -0,0 +1,37 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_PROVIDER_BASE_FACTORY_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_PROVIDER_BASE_FACTORY_H_ + +#include "base/macros.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +class BrowserContextDependencyManager; +class Profile; + +namespace web_app { + +class WebAppProviderBase; + +// Singleton that associates WebAppProviderBase with Profile. +class WebAppProviderBaseFactory : public BrowserContextKeyedServiceFactory { + public: + static WebAppProviderBase* GetForProfile(Profile* profile); + + static WebAppProviderBaseFactory* GetInstance(); + static void SetInstance(WebAppProviderBaseFactory* factory); + + protected: + WebAppProviderBaseFactory( + const char* service_name, + BrowserContextDependencyManager* dependency_manager); + ~WebAppProviderBaseFactory() override; + + DISALLOW_COPY_AND_ASSIGN(WebAppProviderBaseFactory); +}; + +} // namespace web_app + +#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_PROVIDER_BASE_FACTORY_H_
diff --git a/chrome/browser/web_applications/components/web_app_url_loader.cc b/chrome/browser/web_applications/components/web_app_url_loader.cc new file mode 100644 index 0000000..27ee82a --- /dev/null +++ b/chrome/browser/web_applications/components/web_app_url_loader.cc
@@ -0,0 +1,135 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/web_applications/components/web_app_url_loader.h" + +#include <memory> +#include <utility> + +#include "base/memory/weak_ptr.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/timer/timer.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" + +namespace web_app { + +constexpr base::TimeDelta WebAppUrlLoader::kSecondsToWaitForWebContentsLoad; + +namespace { + +class LoaderTask : public content::WebContentsObserver { + public: + LoaderTask() = default; + ~LoaderTask() override = default; + + void LoadUrl(const GURL& url, + content::WebContents* web_contents, + WebAppUrlLoader::ResultCallback callback) { + url_ = url; + callback_ = std::move(callback); + Observe(web_contents); + + content::NavigationController::LoadURLParams load_params(url); + load_params.transition_type = ui::PAGE_TRANSITION_GENERATED; + + web_contents->GetController().LoadURLWithParams(load_params); + + timer_.Start(FROM_HERE, WebAppUrlLoader::kSecondsToWaitForWebContentsLoad, + base::BindOnce(&LoaderTask::OnLoadUrlTimeout, + // OneShotTimer is owned by this class and + // it guarantees that it will never run after + // it's destroyed. + base::Unretained(this))); + } + + // WebContentsObserver + // DidFinishLoad doesn't always get called after the page has fully loaded. + // TODO(ortuno): Use DidStopLoading instead. + void DidFinishLoad(content::RenderFrameHost* render_frame_host, + const GURL& validated_url) override { + // Ignore subframe loads. + if (web_contents()->GetMainFrame() != render_frame_host) { + return; + } + + timer_.Stop(); + + if (validated_url != url_) { + LOG(ERROR) << "Error loading " << url_; + LOG(ERROR) << " page redirected to " << validated_url; + PostResultTask(WebAppUrlLoader::Result::kRedirectedUrlLoaded); + return; + } + PostResultTask(WebAppUrlLoader::Result::kUrlLoaded); + } + + void DidFailLoad(content::RenderFrameHost* render_frame_host, + const GURL& validated_url, + int error_code, + const base::string16& error_description) override { + // Ignore subframe loads. + if (web_contents()->GetMainFrame() != render_frame_host) { + return; + } + + timer_.Stop(); + + LOG(ERROR) << "Error loading " << url_ << " page failed to load."; + PostResultTask(WebAppUrlLoader::Result::kFailedUnknownReason); + } + + void WebContentsDestroyed() override { + timer_.Stop(); + PostResultTask(WebAppUrlLoader::Result::kFailedWebContentsDestroyed); + } + + private: + void OnLoadUrlTimeout() { + web_contents()->Stop(); + LOG(ERROR) << "Error loading " << url_ << " page took too long to load."; + PostResultTask(WebAppUrlLoader::Result::kFailedPageTookTooLong); + } + + void PostResultTask(WebAppUrlLoader::Result result) { + Observe(nullptr); + // Post a task to avoid reentrancy issues e.g. adding a WebContentsObserver + // while a previous observer call is being executed. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback_), result)); + } + + WebAppUrlLoader::ResultCallback callback_; + GURL url_; + base::OneShotTimer timer_; + + base::WeakPtrFactory<LoaderTask> weak_ptr_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(LoaderTask); +}; + +} // namespace + +WebAppUrlLoader::WebAppUrlLoader() = default; + +WebAppUrlLoader::~WebAppUrlLoader() = default; + +void WebAppUrlLoader::LoadUrl(const GURL& url, + content::WebContents* web_contents, + ResultCallback callback) { + auto loader_task = std::make_unique<LoaderTask>(); + auto* loader_task_ptr = loader_task.get(); + loader_task_ptr->LoadUrl( + url, web_contents, + base::BindOnce( + [](ResultCallback callback, std::unique_ptr<LoaderTask> task, + Result result) { + std::move(callback).Run(result); + task.reset(); + }, + std::move(callback), std::move(loader_task))); +} + +} // namespace web_app
diff --git a/chrome/browser/web_applications/components/web_app_url_loader.h b/chrome/browser/web_applications/components/web_app_url_loader.h new file mode 100644 index 0000000..a98b848a --- /dev/null +++ b/chrome/browser/web_applications/components/web_app_url_loader.h
@@ -0,0 +1,49 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_URL_LOADER_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_URL_LOADER_H_ + +#include "base/callback.h" +#include "base/time/time.h" + +class GURL; + +namespace content { +class WebContents; +} // namespace content + +namespace web_app { + +// Callback-based wrapper around NavigationController::LoadUrl. +class WebAppUrlLoader { + public: + enum class Result { + kUrlLoaded, + // The provided URL redirected to another URL and the final URL + // was loaded. + kRedirectedUrlLoaded, + kFailedUnknownReason, + kFailedPageTookTooLong, + kFailedWebContentsDestroyed, + }; + + using ResultCallback = base::OnceCallback<void(Result)>; + + WebAppUrlLoader(); + ~WebAppUrlLoader(); + + // Navigates |web_contents| to |url| and runs callback with the result code. + void LoadUrl(const GURL& url, + content::WebContents* web_contents, + ResultCallback callback); + + // Exposed for testing. + static constexpr base::TimeDelta kSecondsToWaitForWebContentsLoad = + base::TimeDelta::FromSeconds(30); +}; + +} // namespace web_app + +#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_URL_LOADER_H_
diff --git a/chrome/browser/web_applications/components/web_app_url_loader_browsertest.cc b/chrome/browser/web_applications/components/web_app_url_loader_browsertest.cc new file mode 100644 index 0000000..5174c23a --- /dev/null +++ b/chrome/browser/web_applications/components/web_app_url_loader_browsertest.cc
@@ -0,0 +1,166 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/web_applications/components/web_app_url_loader.h" + +#include "base/barrier_closure.h" +#include "base/callback.h" +#include "base/optional.h" +#include "base/test/bind_test_util.h" +#include "base/test/test_mock_time_task_runner.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "content/public/browser/web_contents.h" +#include "net/base/escape.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace web_app { + +using Result = WebAppUrlLoader::Result; + +class WebAppUrlLoaderTest : public InProcessBrowserTest { + public: + WebAppUrlLoaderTest() = default; + ~WebAppUrlLoaderTest() override = default; + + void SetUpOnMainThread() override { + web_contents_ = content::WebContents::Create( + content::WebContents::CreateParams(browser()->profile())); + + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(embedded_test_server()->Start()); + } + + void TearDownOnMainThread() override { + // The WebContents needs to be destroyed before the profile. + web_contents_.reset(); + } + + Result LoadUrlAndWait(WebAppUrlLoader* loader, const std::string& path) { + base::Optional<Result> result; + base::RunLoop run_loop; + loader->LoadUrl(embedded_test_server()->GetURL(path), web_contents(), + base::BindLambdaForTesting([&](Result r) { + result = r; + run_loop.Quit(); + })); + EXPECT_TRUE(web_contents()->IsLoading()); + run_loop.Run(); + // Currently WebAppUrlLoader uses DidFinishLoad which might get called + // even if WebContents::IsLoading() is true. + // TODO(ortuno): Check that the WebContents is no longer loading after + // the callback is called. + + return result.value(); + } + + protected: + content::WebContents* web_contents() { return web_contents_.get(); } + + void ResetWebContents() { web_contents_.reset(); } + + private: + std::unique_ptr<content::WebContents> web_contents_; + + DISALLOW_COPY_AND_ASSIGN(WebAppUrlLoaderTest); +}; + +IN_PROC_BROWSER_TEST_F(WebAppUrlLoaderTest, Success) { + WebAppUrlLoader loader; + EXPECT_EQ(Result::kUrlLoaded, LoadUrlAndWait(&loader, "/simple.html")); +} + +IN_PROC_BROWSER_TEST_F(WebAppUrlLoaderTest, 302FoundRedirect) { + WebAppUrlLoader loader; + + const GURL final_url = embedded_test_server()->GetURL("/simple.html"); + EXPECT_EQ( + Result::kRedirectedUrlLoaded, + LoadUrlAndWait(&loader, "/server-redirect-302?" + final_url.spec())); +} + +IN_PROC_BROWSER_TEST_F(WebAppUrlLoaderTest, Hung) { + auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); + base::TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner); + + WebAppUrlLoader loader; + base::Optional<Result> result; + + loader.LoadUrl(embedded_test_server()->GetURL("/hung"), web_contents(), + base::BindLambdaForTesting([&](Result r) { result = r; })); + + // Run all pending tasks. The URL should still be loading. + EXPECT_TRUE(web_contents()->IsLoading()); + task_runner->RunUntilIdle(); + EXPECT_TRUE(web_contents()->IsLoading()); + + // The callback didn't run yet because the site is still loading. + EXPECT_FALSE(result.has_value()); + + // Forward the clock so that |loader| times out. + task_runner->FastForwardBy(WebAppUrlLoader::kSecondsToWaitForWebContentsLoad); + EXPECT_FALSE(web_contents()->IsLoading()); + EXPECT_EQ(Result::kFailedPageTookTooLong, result.value()); +} + +IN_PROC_BROWSER_TEST_F(WebAppUrlLoaderTest, WebContentsDestroyed) { + WebAppUrlLoader loader; + base::Optional<Result> result; + + base::RunLoop run_loop; + loader.LoadUrl(embedded_test_server()->GetURL("/hung"), web_contents(), + base::BindLambdaForTesting([&](Result r) { + result = r; + run_loop.Quit(); + })); + + // Run all pending tasks. The URL should still be loading. + EXPECT_TRUE(web_contents()->IsLoading()); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(web_contents()->IsLoading()); + + // The callback didn't run yet because the site is still loading. + EXPECT_FALSE(result.has_value()); + + ResetWebContents(); + run_loop.Run(); + + EXPECT_EQ(Result::kFailedWebContentsDestroyed, result.value()); +} + +IN_PROC_BROWSER_TEST_F(WebAppUrlLoaderTest, MultipleLoadUrlCalls) { + WebAppUrlLoader loader; + base::Optional<Result> title1_result; + base::Optional<Result> title2_result; + + std::unique_ptr<content::WebContents> web_contents1 = + content::WebContents::Create( + content::WebContents::CreateParams(browser()->profile())); + std::unique_ptr<content::WebContents> web_contents2 = + content::WebContents::Create( + content::WebContents::CreateParams(browser()->profile())); + + base::RunLoop run_loop; + base::RepeatingClosure barrier_closure = + base::BarrierClosure(2, run_loop.QuitClosure()); + + loader.LoadUrl(embedded_test_server()->GetURL("/title1.html"), + web_contents1.get(), base::BindLambdaForTesting([&](Result r) { + title1_result = r; + barrier_closure.Run(); + })); + loader.LoadUrl(embedded_test_server()->GetURL("/title2.html"), + web_contents2.get(), base::BindLambdaForTesting([&](Result r) { + title2_result = r; + barrier_closure.Run(); + })); + run_loop.Run(); + EXPECT_EQ(Result::kUrlLoaded, title1_result.value()); + EXPECT_EQ(Result::kUrlLoaded, title2_result.value()); +} + +} // namespace web_app
diff --git a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc index d8de5dc..0637775 100644 --- a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc +++ b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc
@@ -10,21 +10,16 @@ #include <vector> #include "base/bind.h" -#include "base/strings/string16.h" #include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/components/app_registrar.h" #include "chrome/browser/web_applications/components/web_app_constants.h" -#include "content/public/browser/navigation_controller.h" #include "content/public/browser/web_contents.h" namespace extensions { namespace { -const int kSecondsToWaitForWebContentsLoad = 30; - std::unique_ptr<content::WebContents> WebContentsCreateWrapper( Profile* profile) { return content::WebContents::Create( @@ -58,9 +53,9 @@ uninstaller_( std::make_unique<BookmarkAppUninstaller>(profile_, registrar_)), extension_ids_map_(profile->GetPrefs()), + url_loader_(std::make_unique<web_app::WebAppUrlLoader>()), web_contents_factory_(base::BindRepeating(&WebContentsCreateWrapper)), - task_factory_(base::BindRepeating(&InstallationTaskCreateWrapper)), - timer_(std::make_unique<base::OneShotTimer>()) {} + task_factory_(base::BindRepeating(&InstallationTaskCreateWrapper)) {} PendingBookmarkAppManager::~PendingBookmarkAppManager() = default; @@ -122,11 +117,6 @@ uninstaller_ = std::move(uninstaller); } -void PendingBookmarkAppManager::SetTimerForTesting( - std::unique_ptr<base::OneShotTimer> timer) { - timer_ = std::move(timer); -} - base::Optional<bool> PendingBookmarkAppManager::IsExtensionPresentAndInstalled( const std::string& extension_id) { if (registrar_->IsInstalled(extension_id)) { @@ -190,16 +180,11 @@ current_task_and_callback_ = std::move(task); CreateWebContentsIfNecessary(); - Observe(web_contents_.get()); - content::NavigationController::LoadURLParams load_params( - current_task_and_callback_->task->app_info().url); - load_params.transition_type = ui::PAGE_TRANSITION_GENERATED; - web_contents_->GetController().LoadURLWithParams(load_params); - timer_->Start( - FROM_HERE, base::TimeDelta::FromSeconds(kSecondsToWaitForWebContentsLoad), - base::BindOnce(&PendingBookmarkAppManager::OnWebContentsLoadTimedOut, - weak_ptr_factory_.GetWeakPtr())); + url_loader_->LoadUrl(current_task_and_callback_->task->app_info().url, + web_contents_.get(), + base::BindOnce(&PendingBookmarkAppManager::OnUrlLoaded, + weak_ptr_factory_.GetWeakPtr())); } void PendingBookmarkAppManager::CreateWebContentsIfNecessary() { @@ -210,26 +195,34 @@ BookmarkAppInstallationTask::CreateTabHelpers(web_contents_.get()); } +void PendingBookmarkAppManager::OnUrlLoaded( + web_app::WebAppUrlLoader::Result result) { + if (result != web_app::WebAppUrlLoader::Result::kUrlLoaded) { + CurrentInstallationFinished(base::nullopt); + return; + } + + current_task_and_callback_->task->Install( + web_contents_.get(), + base::BindOnce(&PendingBookmarkAppManager::OnInstalled, + // Safe because the installation task will not run its + // callback after being deleted and this class owns the + // task. + base::Unretained(this))); +} + void PendingBookmarkAppManager::OnInstalled( BookmarkAppInstallationTask::Result result) { CurrentInstallationFinished(result.app_id); } -void PendingBookmarkAppManager::OnWebContentsLoadTimedOut() { - web_contents_->Stop(); - LOG(ERROR) << "Error installing " - << current_task_and_callback_->task->app_info().url.spec(); - LOG(ERROR) << " page took too long to load."; - Observe(nullptr); - CurrentInstallationFinished(base::nullopt); -} - void PendingBookmarkAppManager::CurrentInstallationFinished( const base::Optional<std::string>& app_id) { - // Post a task to avoid reentrancy issues e.g. adding a WebContentsObserver - // while a previous observer call is being executed. Post a task before + // Post a task to avoid InstallableManager crashing and do so before // running the callback in case the callback tries to install another // app. + // TODO(crbug.com/943848): Run next installation synchronously once + // InstallableManager is fixed. base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&PendingBookmarkAppManager::MaybeStartNextInstallation, @@ -245,47 +238,4 @@ .Run(task_and_callback->task->app_info().url, install_result_code); } -void PendingBookmarkAppManager::DidFinishLoad( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url) { - timer_->Stop(); - if (web_contents_->GetMainFrame() != render_frame_host) { - return; - } - - if (validated_url != current_task_and_callback_->task->app_info().url) { - LOG(ERROR) << "Error installing " - << current_task_and_callback_->task->app_info().url.spec(); - LOG(ERROR) << " page redirected to " << validated_url.spec(); - CurrentInstallationFinished(base::nullopt); - return; - } - - Observe(nullptr); - current_task_and_callback_->task->Install( - web_contents_.get(), - base::BindOnce(&PendingBookmarkAppManager::OnInstalled, - // Safe because the installation task will not run its - // callback after being deleted and this class owns the - // task. - base::Unretained(this))); -} - -void PendingBookmarkAppManager::DidFailLoad( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description) { - timer_->Stop(); - if (web_contents_->GetMainFrame() != render_frame_host) { - return; - } - - LOG(ERROR) << "Error installing " - << current_task_and_callback_->task->app_info().url.spec(); - LOG(ERROR) << " page failed to load."; - Observe(nullptr); - CurrentInstallationFinished(base::nullopt); -} - } // namespace extensions
diff --git a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h index 696de12..18cb00e 100644 --- a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h +++ b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h
@@ -14,18 +14,16 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" -#include "base/timer/timer.h" #include "chrome/browser/web_applications/components/pending_app_manager.h" +#include "chrome/browser/web_applications/components/web_app_url_loader.h" #include "chrome/browser/web_applications/extensions/bookmark_app_installation_task.h" #include "chrome/browser/web_applications/extensions/bookmark_app_uninstaller.h" #include "chrome/browser/web_applications/extensions/web_app_extension_ids_map.h" -#include "content/public/browser/web_contents_observer.h" class GURL; class Profile; namespace content { -class RenderFrameHost; class WebContents; } // namespace content @@ -40,8 +38,7 @@ // // WebAppProvider creates an instance of this class and manages its // lifetime. This class should only be used from the UI thread. -class PendingBookmarkAppManager final : public web_app::PendingAppManager, - public content::WebContentsObserver { +class PendingBookmarkAppManager final : public web_app::PendingAppManager { public: using WebContentsFactory = base::RepeatingCallback<std::unique_ptr<content::WebContents>(Profile*)>; @@ -66,7 +63,6 @@ TaskFactory task_factory); void SetUninstallerForTesting( std::unique_ptr<BookmarkAppUninstaller> uninstaller); - void SetTimerForTesting(std::unique_ptr<base::OneShotTimer> timer); private: struct TaskAndCallback; @@ -84,30 +80,24 @@ void CreateWebContentsIfNecessary(); + void OnUrlLoaded(web_app::WebAppUrlLoader::Result result); + void OnInstalled(BookmarkAppInstallationTask::Result result); - void OnWebContentsLoadTimedOut(); - void CurrentInstallationFinished(const base::Optional<std::string>& app_id); - // WebContentsObserver - void DidFinishLoad(content::RenderFrameHost* render_frame_host, - const GURL& validated_url) override; - void DidFailLoad(content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description) override; - Profile* profile_; web_app::AppRegistrar* registrar_; std::unique_ptr<BookmarkAppUninstaller> uninstaller_; web_app::ExtensionIdsMap extension_ids_map_; + // unique_ptr so that it can be replaced in tests. + std::unique_ptr<web_app::WebAppUrlLoader> url_loader_; + WebContentsFactory web_contents_factory_; TaskFactory task_factory_; std::unique_ptr<content::WebContents> web_contents_; - std::unique_ptr<base::OneShotTimer> timer_; std::unique_ptr<TaskAndCallback> current_task_and_callback_;
diff --git a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager_unittest.cc b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager_unittest.cc index 1c6000a3..cda7af5 100644 --- a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager_unittest.cc +++ b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager_unittest.cc
@@ -34,7 +34,6 @@ const char kFooWebAppUrl[] = "https://foo.example"; const char kBarWebAppUrl[] = "https://bar.example"; const char kQuxWebAppUrl[] = "https://qux.example"; -const char kXyzWebAppUrl[] = "https://xyz.example"; const char kWrongUrl[] = "https://foobar.example"; @@ -65,13 +64,6 @@ return info; } -web_app::PendingAppManager::AppInfo GetXyzAppInfo() { - web_app::PendingAppManager::AppInfo info( - GURL(kXyzWebAppUrl), web_app::LaunchContainer::kWindow, - web_app::InstallSource::kExternalPolicy); - return info; -} - std::string GenerateFakeAppId(const GURL& url) { return std::string("fake_app_id_for:") + url.spec(); } @@ -286,6 +278,7 @@ void SuccessfullyLoad(const GURL& url) { web_contents_tester_->NavigateAndCommit(url); web_contents_tester_->TestDidFinishLoad(url); + base::RunLoop().RunUntilIdle(); } content::WebContentsTester* web_contents_tester() { @@ -581,15 +574,6 @@ EXPECT_TRUE(app_installed()); EXPECT_EQ(GetFooAppInfo(), last_app_info()); EXPECT_EQ(GURL(kFooWebAppUrl), install_callback_url()); - ResetResults(); - - base::RunLoop().RunUntilIdle(); - - // The second installation should succeed even though the app is installed - // already. - EXPECT_EQ(0u, installation_task_run_count()); - EXPECT_TRUE(app_installed()); - EXPECT_EQ(GURL(kFooWebAppUrl), install_callback_url()); } TEST_F(PendingBookmarkAppManagerTest, Install_AlwaysUpdate) { @@ -851,88 +835,6 @@ EXPECT_EQ(GURL(kBarWebAppUrl), install_callback_url()); } -TEST_F(PendingBookmarkAppManagerTest, WebContentsLoadTimedOut) { - auto pending_app_manager = GetPendingBookmarkAppManagerWithTestFactories(); - auto timer_to_pass = std::make_unique<base::MockOneShotTimer>(); - auto* timer = timer_to_pass.get(); - - pending_app_manager->SetTimerForTesting(std::move(timer_to_pass)); - - // Queue an app through Install. - pending_app_manager->Install( - GetQuxAppInfo(), - base::BindOnce(&PendingBookmarkAppManagerTest::InstallCallback, - base::Unretained(this))); - base::RunLoop().RunUntilIdle(); - - // Verify that the timer is stopped after a successful load. - EXPECT_TRUE(timer->IsRunning()); - SuccessfullyLoad(GURL(kQuxWebAppUrl)); - EXPECT_FALSE(timer->IsRunning()); - EXPECT_EQ(1u, installation_task_run_count()); - EXPECT_TRUE(app_installed()); - EXPECT_EQ(GURL(kQuxWebAppUrl), install_callback_url()); - ResetResults(); - - // Queue a different app through Install. - pending_app_manager->Install( - GetXyzAppInfo(), - base::BindOnce(&PendingBookmarkAppManagerTest::InstallCallback, - base::Unretained(this))); - base::RunLoop().RunUntilIdle(); - - // Fire the timer to simulate a failed load. - EXPECT_TRUE(timer->IsRunning()); - timer->Fire(); - EXPECT_FALSE(app_installed()); - EXPECT_EQ(GURL(kXyzWebAppUrl), install_callback_url()); - ResetResults(); - - // Queue two more apps, different from all those before, through InstallApps. - std::vector<web_app::PendingAppManager::AppInfo> apps_to_install; - apps_to_install.push_back(GetFooAppInfo()); - apps_to_install.push_back(GetBarAppInfo()); - - pending_app_manager->InstallApps( - std::move(apps_to_install), - base::BindRepeating(&PendingBookmarkAppManagerTest::InstallCallback, - base::Unretained(this))); - - base::RunLoop().RunUntilIdle(); - - // Fire the timer to simulate a failed load. - EXPECT_TRUE(timer->IsRunning()); - timer->Fire(); - EXPECT_FALSE(app_installed()); - EXPECT_EQ(GURL(kFooWebAppUrl), install_callback_url()); - ResetResults(); - - base::RunLoop().RunUntilIdle(); - - // Fire the timer to simulate a failed load. - EXPECT_TRUE(timer->IsRunning()); - timer->Fire(); - EXPECT_FALSE(app_installed()); - EXPECT_EQ(GURL(kBarWebAppUrl), install_callback_url()); - ResetResults(); - - // Ensure a successful load after a timer fire works. - pending_app_manager->Install( - GetBarAppInfo(), - base::BindOnce(&PendingBookmarkAppManagerTest::InstallCallback, - base::Unretained(this))); - base::RunLoop().RunUntilIdle(); - - // Verify that the timer is stopped after a successful load. - EXPECT_TRUE(timer->IsRunning()); - SuccessfullyLoad(GURL(kBarWebAppUrl)); - EXPECT_FALSE(timer->IsRunning()); - EXPECT_EQ(1u, installation_task_run_count()); - EXPECT_TRUE(app_installed()); - EXPECT_EQ(GetBarAppInfo(), last_app_info()); - EXPECT_EQ(GURL(kBarWebAppUrl), install_callback_url()); -} - TEST_F(PendingBookmarkAppManagerTest, ExtensionUninstalled) { auto pending_app_manager = GetPendingBookmarkAppManagerWithTestFactories(); pending_app_manager->Install(
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index 86f74cde..7d5a30b7d 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -82,6 +82,18 @@ weak_ptr_factory_.GetWeakPtr())); } +AppRegistrar& WebAppProvider::registrar() { + return *registrar_; +} + +InstallManager& WebAppProvider::install_manager() { + return *install_manager_; +} + +PendingAppManager& WebAppProvider::pending_app_manager() { + return *pending_app_manager_; +} + void WebAppProvider::CreateWebAppsSubsystems(Profile* profile) { database_factory_ = std::make_unique<WebAppDatabaseFactory>(profile); database_ = std::make_unique<WebAppDatabase>(database_factory_.get());
diff --git a/chrome/browser/web_applications/web_app_provider.h b/chrome/browser/web_applications/web_app_provider.h index fd72c4a7..0e6cc36 100644 --- a/chrome/browser/web_applications/web_app_provider.h +++ b/chrome/browser/web_applications/web_app_provider.h
@@ -14,7 +14,7 @@ #include "chrome/browser/web_applications/components/app_registrar.h" #include "chrome/browser/web_applications/components/pending_app_manager.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" -#include "components/keyed_service/core/keyed_service.h" +#include "chrome/browser/web_applications/components/web_app_provider_base.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -49,7 +49,7 @@ // Connects Web App features, such as the installation of default and // policy-managed web apps, with Profiles (as WebAppProvider is a // Profile-linked KeyedService) and their associated PrefService. -class WebAppProvider : public KeyedService, +class WebAppProvider : public WebAppProviderBase, public content::NotificationObserver { public: static WebAppProvider* Get(Profile* profile); @@ -63,14 +63,10 @@ // Start registry. All subsystems depend on it. void StartRegistry(); - AppRegistrar& registrar() { return *registrar_; } - - // UIs can use InstallManager for user-initiated Web Apps install. - InstallManager& install_manager() { return *install_manager_; } - - // Clients can use PendingAppManager to install, uninstall, and update - // Web Apps. - PendingAppManager& pending_app_manager() { return *pending_app_manager_; } + // WebAppProviderBase: + AppRegistrar& registrar() override; + InstallManager& install_manager() override; + PendingAppManager& pending_app_manager() override; const SystemWebAppManager& system_web_app_manager() { return *system_web_app_manager_;
diff --git a/chrome/browser/web_applications/web_app_provider_factory.cc b/chrome/browser/web_applications/web_app_provider_factory.cc index 297a911..4209d59 100644 --- a/chrome/browser/web_applications/web_app_provider_factory.cc +++ b/chrome/browser/web_applications/web_app_provider_factory.cc
@@ -26,14 +26,18 @@ } WebAppProviderFactory::WebAppProviderFactory() - : BrowserContextKeyedServiceFactory( + : WebAppProviderBaseFactory( "WebAppProvider", BrowserContextDependencyManager::GetInstance()) { + WebAppProviderBaseFactory::SetInstance(this); + DependsOn( extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); } -WebAppProviderFactory::~WebAppProviderFactory() = default; +WebAppProviderFactory::~WebAppProviderFactory() { + WebAppProviderBaseFactory::SetInstance(nullptr); +} KeyedService* WebAppProviderFactory::BuildServiceInstanceFor( content::BrowserContext* context) const {
diff --git a/chrome/browser/web_applications/web_app_provider_factory.h b/chrome/browser/web_applications/web_app_provider_factory.h index ec7dc86..7a8c53b 100644 --- a/chrome/browser/web_applications/web_app_provider_factory.h +++ b/chrome/browser/web_applications/web_app_provider_factory.h
@@ -7,7 +7,7 @@ #include "base/macros.h" #include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" +#include "chrome/browser/web_applications/components/web_app_provider_base_factory.h" namespace content { class BrowserContext; @@ -21,7 +21,7 @@ // Singleton that owns all WebAppProviderFactories and associates them with // Profile. -class WebAppProviderFactory : public BrowserContextKeyedServiceFactory { +class WebAppProviderFactory : public WebAppProviderBaseFactory { public: static WebAppProvider* GetForProfile(Profile* profile);
diff --git a/chrome/common/heap_profiler_controller.cc b/chrome/common/heap_profiler_controller.cc index e1943de..738953fb 100644 --- a/chrome/common/heap_profiler_controller.cc +++ b/chrome/common/heap_profiler_controller.cc
@@ -23,14 +23,6 @@ namespace { constexpr char kMetadataSizeField[] = "HeapProfiler.AllocationInBytes"; - -constexpr base::Feature kSamplingHeapProfilerFeature{ - "SamplingHeapProfiler", base::FEATURE_DISABLED_BY_DEFAULT}; - -constexpr char kSamplingHeapProfilerFeatureSamplingRateKB[] = - "sampling-rate-kb"; - -constexpr size_t kDefaultSamplingRateKB = 128; constexpr base::TimeDelta kHeapCollectionInterval = base::TimeDelta::FromHours(24); @@ -61,35 +53,7 @@ HeapProfilerController::HeapProfilerController() = default; HeapProfilerController::~HeapProfilerController() = default; -void HeapProfilerController::StartIfEnabled() { - DCHECK(!started_); - size_t sampling_rate_kb = 0; - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kSamplingHeapProfiler)) { - unsigned value; - bool parsed = base::StringToUint( - command_line->GetSwitchValueASCII(switches::kSamplingHeapProfiler), - &value); - sampling_rate_kb = parsed ? value : kDefaultSamplingRateKB; - } - - bool on_trial = base::FeatureList::IsEnabled(kSamplingHeapProfilerFeature); - if (on_trial && !sampling_rate_kb) { - sampling_rate_kb = std::max( - base::GetFieldTrialParamByFeatureAsInt( - kSamplingHeapProfilerFeature, - kSamplingHeapProfilerFeatureSamplingRateKB, kDefaultSamplingRateKB), - 0); - } - - if (!sampling_rate_kb) - return; - - started_ = true; - auto* profiler = base::SamplingHeapProfiler::Get(); - profiler->SetSamplingInterval(sampling_rate_kb * 1024); - profiler->Start(); - +void HeapProfilerController::Start() { ScheduleNextSnapshot(); }
diff --git a/chrome/common/heap_profiler_controller.h b/chrome/common/heap_profiler_controller.h index aef276b5..5f6bc53 100644 --- a/chrome/common/heap_profiler_controller.h +++ b/chrome/common/heap_profiler_controller.h
@@ -22,7 +22,7 @@ ~HeapProfilerController(); // Starts periodic heap snapshot collection. - void StartIfEnabled(); + void Start(); void SetTaskRunnerForTest(scoped_refptr<base::TaskRunner> task_runner) { task_runner_ = std::move(task_runner); @@ -33,7 +33,6 @@ void TakeSnapshot(); void RetrieveAndSendSnapshot(); - bool started_ = false; scoped_refptr<base::TaskRunner> task_runner_; base::WeakPtrFactory<HeapProfilerController> weak_factory_{this};
diff --git a/chrome/common/heap_profiler_controller_unittest.cc b/chrome/common/heap_profiler_controller_unittest.cc index 7d5c379..8f9ae673 100644 --- a/chrome/common/heap_profiler_controller_unittest.cc +++ b/chrome/common/heap_profiler_controller_unittest.cc
@@ -6,7 +6,7 @@ #include "base/command_line.h" #include "base/metrics/metrics_hashes.h" -#include "base/sampling_heap_profiler/poisson_allocation_sampler.h" +#include "base/sampling_heap_profiler/sampling_heap_profiler.h" #include "base/test/test_mock_time_task_runner.h" #include "build/build_config.h" #include "components/metrics/call_stack_profile_builder.h" @@ -52,26 +52,23 @@ ++*profiles_count; } -#if !defined(OS_ANDROID) || \ - BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && defined(OFFICIAL_BUILD) -#define MAYBE_ProfileCollectionsScheduler ProfileCollectionsScheduler -#else -#define MAYBE_ProfileCollectionsScheduler DISABLED_ProfileCollectionsScheduler -#endif -TEST(HeapProfilerControllerTest, MAYBE_ProfileCollectionsScheduler) { +// Sampling profiler is not capable of unwinding stack on Android under tests. +#if !defined(OS_ANDROID) +TEST(HeapProfilerControllerTest, ProfileCollectionsScheduler) { auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); base::TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner.get()); - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - command_line->AppendSwitchASCII(switches::kSamplingHeapProfiler, "1"); + base::SamplingHeapProfiler::Init(); + auto* profiler = base::SamplingHeapProfiler::Get(); + profiler->SetSamplingInterval(1024); + profiler->Start(); int profiles_collected = 0; metrics::CallStackProfileBuilder::SetBrowserProcessReceiverCallback( base::BindRepeating(&CheckProfile, &profiles_collected)); - base::PoissonAllocationSampler::Init(); HeapProfilerController controller; controller.SetTaskRunnerForTest(task_runner.get()); - controller.StartIfEnabled(); + controller.Start(); auto* sampler = base::PoissonAllocationSampler::Get(); sampler->SuppressRandomnessForTest(true); sampler->RecordAlloc(reinterpret_cast<void*>(0x1337), kAllocationSize, @@ -82,3 +79,4 @@ task_runner->FastForwardBy(base::TimeDelta::FromHours(1)); } while (profiles_collected < 2); } +#endif
diff --git a/chrome/renderer/extensions/automation_ax_tree_wrapper.cc b/chrome/renderer/extensions/automation_ax_tree_wrapper.cc index 498537a..2922a51 100644 --- a/chrome/renderer/extensions/automation_ax_tree_wrapper.cc +++ b/chrome/renderer/extensions/automation_ax_tree_wrapper.cc
@@ -192,8 +192,19 @@ case ui::AXEventGenerator::Event::STATE_CHANGED: return api::automation::EVENT_TYPE_ARIAATTRIBUTECHANGED; + case ui::AXEventGenerator::Event::ACCESS_KEY_CHANGED: + case ui::AXEventGenerator::Event::CLASS_NAME_CHANGED: + case ui::AXEventGenerator::Event::DESCRIBED_BY_CHANGED: case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED: + case ui::AXEventGenerator::Event::FLOW_TO_CHANGED: + case ui::AXEventGenerator::Event::HIERARCHICAL_LEVEL_CHANGED: + case ui::AXEventGenerator::Event::KEY_SHORTCUTS_CHANGED: + case ui::AXEventGenerator::Event::LABELED_BY_CHANGED: + case ui::AXEventGenerator::Event::LANGUAGE_CHANGED: case ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED: + case ui::AXEventGenerator::Event::PLACEHOLDER_CHANGED: + case ui::AXEventGenerator::Event::POSITION_IN_SET_CHANGED: + case ui::AXEventGenerator::Event::SET_SIZE_CHANGED: return api::automation::EVENT_TYPE_NONE; }
diff --git a/chrome/services/app_service/README.md b/chrome/services/app_service/README.md index af494d0..7d4fdf9 100644 --- a/chrome/services/app_service/README.md +++ b/chrome/services/app_service/README.md
@@ -258,19 +258,21 @@ `Publisher` sends an `IconKey`: enough information to load the icon at given resolutions. -An `IconKey` holds an `AppType app_type` and `string app_id`, plus additional -data. For example, some icons are statically built into the Chrome or Chrome OS -binary, as PNG-formatted resources, and can be loaded (synchronously, without -sandboxing). They can be loaded from the `IconKey.resource_id`. Other icons are -dynamically (and asynchronously) loaded from the extension database on disk. -They can be loaded just from the `app_id` alone. +An `IconKey` augments the `AppType app_type` and `string app_id`. For example, +some icons are statically built into the Chrome or Chrome OS binary, as +PNG-formatted resources, and can be loaded (synchronously, without sandboxing). +They can be loaded from the `IconKey.resource_id`. Other icons are dynamically +(and asynchronously) loaded from the extension database on disk. The base icon +can be loaded just from the `app_id` alone. In either case, the `IconKey.icon_effects` bitmask holds whether to apply -various image processing effects such as desaturation to gray. +further image processing effects such as desaturation to gray. interface AppService { // App Icon Factory methods. LoadIcon( + AppType app_type, + string app_id, IconKey icon_key, IconCompression icon_compression, int32 size_hint_in_dip, @@ -282,6 +284,7 @@ interface Publisher { // App Icon Factory methods. LoadIcon( + string app_id, IconKey icon_key, IconCompression icon_compression, int32 size_hint_in_dip, @@ -291,8 +294,6 @@ }; struct IconKey { - AppType app_type, - string app_id, // A monotonically increasing number so that, after an icon update, a new // IconKey, one that is different in terms of field-by-field equality, can be // broadcast by a Publisher.
diff --git a/chrome/services/app_service/app_service_impl.cc b/chrome/services/app_service/app_service_impl.cc index 903dbbb..6a5b24f 100644 --- a/chrome/services/app_service/app_service_impl.cc +++ b/chrome/services/app_service/app_service_impl.cc
@@ -63,17 +63,19 @@ subscribers_.AddPtr(std::move(subscriber)); } -void AppServiceImpl::LoadIcon(apps::mojom::IconKeyPtr icon_key, +void AppServiceImpl::LoadIcon(apps::mojom::AppType app_type, + const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon, LoadIconCallback callback) { - auto iter = publishers_.find(icon_key->app_type); + auto iter = publishers_.find(app_type); if (iter == publishers_.end()) { std::move(callback).Run(apps::mojom::IconValue::New()); return; } - iter->second->LoadIcon(std::move(icon_key), icon_compression, + iter->second->LoadIcon(app_id, std::move(icon_key), icon_compression, size_hint_in_dip, allow_placeholder_icon, std::move(callback)); }
diff --git a/chrome/services/app_service/app_service_impl.h b/chrome/services/app_service/app_service_impl.h index 4ff73651..61688131 100644 --- a/chrome/services/app_service/app_service_impl.h +++ b/chrome/services/app_service/app_service_impl.h
@@ -31,7 +31,9 @@ apps::mojom::AppType app_type) override; void RegisterSubscriber(apps::mojom::SubscriberPtr subscriber, apps::mojom::ConnectOptionsPtr opts) override; - void LoadIcon(apps::mojom::IconKeyPtr icon_key, + void LoadIcon(apps::mojom::AppType app_type, + const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon,
diff --git a/chrome/services/app_service/app_service_impl_unittest.cc b/chrome/services/app_service/app_service_impl_unittest.cc index 17c190e..fbf69105 100644 --- a/chrome/services/app_service/app_service_impl_unittest.cc +++ b/chrome/services/app_service/app_service_impl_unittest.cc
@@ -46,12 +46,13 @@ subscribers_.AddPtr(std::move(subscriber)); } - void LoadIcon(apps::mojom::IconKeyPtr icon_key, + void LoadIcon(const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon, LoadIconCallback callback) override { - load_icon_app_id = icon_key->app_id; + load_icon_app_id = app_id; std::move(callback).Run(apps::mojom::IconValue::New()); } @@ -196,11 +197,12 @@ pub0.load_icon_app_id = "-"; pub1.load_icon_app_id = "-"; pub2.load_icon_app_id = "-"; - auto icon_key = apps::mojom::IconKey::New(app_type, "o", 0, 0, 0); + auto icon_key = apps::mojom::IconKey::New(0, 0, 0); constexpr bool allow_placeholder_icon = false; impl.LoadIcon( - std::move(icon_key), apps::mojom::IconCompression::kUncompressed, - size_hint_in_dip, allow_placeholder_icon, + app_type, "o", std::move(icon_key), + apps::mojom::IconCompression::kUncompressed, size_hint_in_dip, + allow_placeholder_icon, base::BindOnce( [](bool* ran, apps::mojom::IconValuePtr iv) { *ran = true; }, &callback_ran));
diff --git a/chrome/services/app_service/public/cpp/app_update_unittest.cc b/chrome/services/app_service/public/cpp/app_update_unittest.cc index 62e4dc7..574c959a 100644 --- a/chrome/services/app_service/public/cpp/app_update_unittest.cc +++ b/chrome/services/app_service/public/cpp/app_update_unittest.cc
@@ -241,7 +241,7 @@ // IconKey tests. if (state) { - auto x = apps::mojom::IconKey::New(app_type, app_id, 100, 0, 0); + auto x = apps::mojom::IconKey::New(100, 0, 0); state->icon_key = x.Clone(); expect_icon_key_ = x.Clone(); expect_icon_key_changed_ = false; @@ -249,7 +249,7 @@ } if (delta) { - auto x = apps::mojom::IconKey::New(app_type, app_id, 200, 0, 0); + auto x = apps::mojom::IconKey::New(200, 0, 0); delta->icon_key = x.Clone(); expect_icon_key_ = x.Clone(); expect_icon_key_changed_ = true;
diff --git a/chrome/services/app_service/public/cpp/icon_cache.cc b/chrome/services/app_service/public/cpp/icon_cache.cc index 4c55201..ac86fe99 100644 --- a/chrome/services/app_service/public/cpp/icon_cache.cc +++ b/chrome/services/app_service/public/cpp/icon_cache.cc
@@ -34,6 +34,8 @@ } std::unique_ptr<IconLoader::Releaser> IconCache::LoadIconFromIconKey( + apps::mojom::AppType app_type, + const std::string& app_id, apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, @@ -42,7 +44,8 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); apps::mojom::IconKey null_icon_key; IconLoader::Key key( - icon_key ? *icon_key : null_icon_key, icon_compression, size_hint_in_dip, + app_type, app_id, icon_key ? *icon_key : null_icon_key, icon_compression, + size_hint_in_dip, // We pass false instead of allow_placeholder_icon, as the Value // already records placeholder-ness. If the allow_placeholder_icon // arg to this function is true, we can re-use a cache hit regardless @@ -71,8 +74,8 @@ std::move(callback).Run(cache_hit->AsIconValue()); } else if (wrapped_loader_) { releaser = wrapped_loader_->LoadIconFromIconKey( - std::move(icon_key), icon_compression, size_hint_in_dip, - allow_placeholder_icon, + app_type, app_id, std::move(icon_key), icon_compression, + size_hint_in_dip, allow_placeholder_icon, base::BindOnce(&IconCache::OnLoadIcon, weak_ptr_factory_.GetWeakPtr(), key, std::move(callback))); } else {
diff --git a/chrome/services/app_service/public/cpp/icon_cache.h b/chrome/services/app_service/public/cpp/icon_cache.h index 0f567fc..6ee992d 100644 --- a/chrome/services/app_service/public/cpp/icon_cache.h +++ b/chrome/services/app_service/public/cpp/icon_cache.h
@@ -72,6 +72,8 @@ // IconLoader overrides. apps::mojom::IconKeyPtr GetIconKey(const std::string& app_id) override; std::unique_ptr<IconLoader::Releaser> LoadIconFromIconKey( + apps::mojom::AppType app_type, + const std::string& app_id, apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip,
diff --git a/chrome/services/app_service/public/cpp/icon_cache_unittest.cc b/chrome/services/app_service/public/cpp/icon_cache_unittest.cc index 6cb7fd9..a0ab7e0 100644 --- a/chrome/services/app_service/public/cpp/icon_cache_unittest.cc +++ b/chrome/services/app_service/public/cpp/icon_cache_unittest.cc
@@ -30,11 +30,12 @@ private: apps::mojom::IconKeyPtr GetIconKey(const std::string& app_id) override { - return apps::mojom::IconKey::New(apps::mojom::AppType::kWeb, app_id, 0, 0, - 0); + return apps::mojom::IconKey::New(0, 0, 0); } std::unique_ptr<Releaser> LoadIconFromIconKey( + apps::mojom::AppType app_type, + const std::string& app_id, apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, @@ -63,6 +64,7 @@ const std::string& app_id, HitOrMiss expect_hom, bool allow_placeholder_icon = false) { + static constexpr auto app_type = apps::mojom::AppType::kWeb; static constexpr auto icon_compression = apps::mojom::IconCompression::kUncompressed; static constexpr int32_t size_hint_in_dip = 1; @@ -70,7 +72,7 @@ int before = fake->NumLoadIconFromIconKeyCalls(); UniqueReleaser releaser = - loader->LoadIcon(app_id, icon_compression, size_hint_in_dip, + loader->LoadIcon(app_type, app_id, icon_compression, size_hint_in_dip, allow_placeholder_icon, base::DoNothing()); int after = fake->NumLoadIconFromIconKeyCalls();
diff --git a/chrome/services/app_service/public/cpp/icon_loader.cc b/chrome/services/app_service/public/cpp/icon_loader.cc index b06b875..3f405dd 100644 --- a/chrome/services/app_service/public/cpp/icon_loader.cc +++ b/chrome/services/app_service/public/cpp/icon_loader.cc
@@ -18,12 +18,14 @@ std::move(closure_).Run(); } -IconLoader::Key::Key(const apps::mojom::IconKey& icon_key, +IconLoader::Key::Key(apps::mojom::AppType app_type, + const std::string& app_id, + const apps::mojom::IconKey& icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon) - : app_type_(icon_key.app_type), - app_id_(icon_key.app_id), + : app_type_(app_type), + app_id_(app_id), timeline_(icon_key.timeline), resource_id_(icon_key.resource_id), icon_effects_(icon_key.icon_effects), @@ -59,14 +61,15 @@ } std::unique_ptr<IconLoader::Releaser> IconLoader::LoadIcon( + apps::mojom::AppType app_type, const std::string& app_id, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::mojom::Publisher::LoadIconCallback callback) { - return LoadIconFromIconKey(GetIconKey(app_id), icon_compression, - size_hint_in_dip, allow_placeholder_icon, - std::move(callback)); + return LoadIconFromIconKey(app_type, app_id, GetIconKey(app_id), + icon_compression, size_hint_in_dip, + allow_placeholder_icon, std::move(callback)); } } // namespace apps
diff --git a/chrome/services/app_service/public/cpp/icon_loader.h b/chrome/services/app_service/public/cpp/icon_loader.h index 59f01be..4a1eb6f 100644 --- a/chrome/services/app_service/public/cpp/icon_loader.h +++ b/chrome/services/app_service/public/cpp/icon_loader.h
@@ -51,6 +51,8 @@ // This can return nullptr, meaning that the IconLoader does not track when // the icon is no longer actively used by the caller. virtual std::unique_ptr<Releaser> LoadIconFromIconKey( + apps::mojom::AppType app_type, + const std::string& app_id, apps::mojom::IconKeyPtr icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, @@ -59,6 +61,7 @@ // Convenience method that calls LoadIconFromIconKey(GetIconKey(app_id), etc). std::unique_ptr<Releaser> LoadIcon( + apps::mojom::AppType app_type, const std::string& app_id, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, @@ -75,9 +78,9 @@ // callers, are expected to refer to a Key. class Key { public: - // apps::mojom::IconKey fields. apps::mojom::AppType app_type_; std::string app_id_; + // apps::mojom::IconKey fields. uint64_t timeline_; int32_t resource_id_; uint32_t icon_effects_; @@ -86,7 +89,9 @@ int32_t size_hint_in_dip_; bool allow_placeholder_icon_; - Key(const apps::mojom::IconKey& icon_key, + Key(apps::mojom::AppType app_type, + const std::string& app_id, + const apps::mojom::IconKey& icon_key, apps::mojom::IconCompression icon_compression, int32_t size_hint_in_dip, bool allow_placeholder_icon);
diff --git a/chrome/services/app_service/public/mojom/app_service.mojom b/chrome/services/app_service/public/mojom/app_service.mojom index e1d90893..20bc648 100644 --- a/chrome/services/app_service/public/mojom/app_service.mojom +++ b/chrome/services/app_service/public/mojom/app_service.mojom
@@ -20,6 +20,8 @@ // App Icon Factory methods. LoadIcon( + AppType app_type, + string app_id, IconKey icon_key, IconCompression icon_compression, int32 size_hint_in_dip, @@ -53,6 +55,7 @@ // App Icon Factory methods. LoadIcon( + string app_id, IconKey icon_key, IconCompression icon_compression, int32 size_hint_in_dip,
diff --git a/chrome/services/app_service/public/mojom/types.mojom b/chrome/services/app_service/public/mojom/types.mojom index a556094..c0c1a2e 100644 --- a/chrome/services/app_service/public/mojom/types.mojom +++ b/chrome/services/app_service/public/mojom/types.mojom
@@ -90,8 +90,6 @@ const int32 kInvalidResourceId = 0; - AppType app_type; - string app_id; // A monotonically increasing number so that, after an icon update, a new // IconKey, one that is different in terms of field-by-field equality, can be // broadcast by a Publisher.
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index ab9fbfe..2dc0e85 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2752,6 +2752,7 @@ "../browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc", "../browser/page_load_metrics/observers/use_counter_page_load_metrics_observer_unittest.cc", "../browser/page_load_metrics/page_load_metrics_util_unittest.cc", + "../browser/page_load_metrics/resource_tracker_unittest.cc", "../browser/password_manager/chrome_password_manager_client_unittest.cc", "../browser/password_manager/password_manager_internals_service_unittest.cc", "../browser/password_manager/password_store_mac_unittest.cc", @@ -3384,6 +3385,7 @@ "../browser/search/search_suggest/search_suggest_service_unittest.cc", "../browser/search/search_unittest.cc", "../browser/send_tab_to_self/desktop_notification_handler_unittest.cc", + "../browser/send_tab_to_self/send_tab_to_self_client_service_unittest.cc", "../browser/send_tab_to_self/send_tab_to_self_util_unittest.cc", "../browser/serial/serial_chooser_context_unittest.cc", "../browser/sessions/tab_restore_service_unittest.cc", @@ -3445,7 +3447,6 @@ "../browser/ui/tabs/tab_switch_event_latency_recorder_unittest.cc", "../browser/ui/tabs/test_tab_strip_model_delegate.cc", "../browser/ui/tabs/test_tab_strip_model_delegate.h", - "../browser/ui/tabs/window_activity_watcher_unittest.cc", "../browser/ui/thumbnails/thumbnail_image_unittest.cc", "../browser/ui/toolbar/app_menu_model_unittest.cc", "../browser/ui/toolbar/back_forward_menu_model_unittest.cc", @@ -4961,6 +4962,7 @@ "../browser/renderer_context_menu/render_view_context_menu_browsertest_util.cc", "../browser/renderer_context_menu/render_view_context_menu_browsertest_util.h", "../browser/renderer_host/site_per_process_text_input_browsertest.cc", + "../browser/resource_coordinator/tab_metrics_logger_interactive_uitest.cc", "../browser/site_per_process_interactive_browsertest.cc", "../browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc", "../browser/ui/blocked_content/popup_blocker_browsertest.cc", @@ -4989,7 +4991,6 @@ "../browser/ui/signin_view_controller_interactive_uitest.cc", "../browser/ui/startup/invalid_user_data_dir_interactive_uitest.cc", "../browser/ui/startup/startup_browser_creator_interactive_uitest.cc", - "../browser/ui/tabs/window_activity_watcher_interactive_uitest.cc", "../browser/ui/translate/translate_bubble_test_utils.h", "../browser/ui/views/accessibility/navigation_accessibility_uitest_win.cc", "../browser/ui/views/permission_bubble/permission_bubble_views_interactive_uitest_mac.mm",
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index d0cb52a5..d23ca2c 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -97,6 +97,7 @@ "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/android_tools:android_test_base_java", + "//third_party/gvr-android-sdk:gvr_common_java", "//third_party/hamcrest:hamcrest_core_java", "//third_party/jsr-305:jsr_305_javalib", "//third_party/junit",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeJUnit4ClassRunner.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeJUnit4ClassRunner.java index beed2b5..7acc69a 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeJUnit4ClassRunner.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeJUnit4ClassRunner.java
@@ -11,24 +11,26 @@ import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; +import com.google.vr.ndk.base.DaydreamApi; +import com.google.vr.ndk.base.GvrApi; import org.junit.rules.TestRule; import org.junit.runners.model.InitializationError; import org.chromium.base.CommandLine; +import org.chromium.base.ContextUtils; +import org.chromium.base.StrictModeContext; import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseTestResult.PreTestHook; import org.chromium.base.test.util.RestrictionSkipCheck; import org.chromium.base.test.util.SkipCheck; import org.chromium.chrome.browser.ChromeVersionInfo; -import org.chromium.chrome.browser.vr.VrModuleProvider; import org.chromium.chrome.test.util.ChromeRestriction; import org.chromium.chrome.test.util.browser.Features; import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner; import org.chromium.policy.test.annotations.Policies; import java.util.List; -import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; /** @@ -66,22 +68,34 @@ } private boolean isDaydreamReady() { - return VrModuleProvider.getDelegate().isDaydreamReadyDevice(); + // We normally check things like this through VrShellDelegate. However, with the + // introduction of Dynamic Feature Modules (DFMs), we have tests that expect the VR + // DFM to not be loaded. Using the normal approach (VrModuleProvider.getDelegate()) + // causes the DFM to be loaded, which we don't want done before the test starts. So, + // access the Daydream API directly. + return DaydreamApi.isDaydreamReadyPlatform(ContextUtils.getApplicationContext()); } private boolean isDaydreamViewPaired() { if (!isDaydreamReady()) { return false; } - - // isDaydreamCurrentViewer() creates a concrete instance of DaydreamApi, - // which can only be done on the main thread + // We need to ensure that the DaydreamApi instance is created on the main thread. + DaydreamApi daydreamApi; try { - return ThreadUtils.runOnUiThreadBlocking( - VrModuleProvider.getDelegate()::isDaydreamCurrentViewer); - } catch (CancellationException | ExecutionException | IllegalArgumentException e) { + daydreamApi = ThreadUtils.runOnUiThreadBlocking( + () -> { return DaydreamApi.create(ContextUtils.getApplicationContext()); }); + } catch (ExecutionException e) { return false; } + int viewerType; + // Getting the current viewer type may result in a disk write in VrCore, so allow that + // to prevent StrictMode errors. + try (StrictModeContext smc = StrictModeContext.allowDiskWrites()) { + viewerType = daydreamApi.getCurrentViewerType(); + } + daydreamApi.close(); + return viewerType == GvrApi.ViewerType.DAYDREAM; } private boolean isOnStandaloneVrDevice() {
diff --git a/chrome/test/data/webui/settings/add_users_tests.js b/chrome/test/data/webui/settings/add_users_tests.js new file mode 100644 index 0000000..926fb06a --- /dev/null +++ b/chrome/test/data/webui/settings/add_users_tests.js
@@ -0,0 +1,51 @@ +// 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. + +suite('AddPersonDialog', function() { + let dialog = null; + + setup(function() { + PolymerTest.clearBody(); + + dialog = document.createElement('settings-users-add-user-dialog'); + + document.body.appendChild(dialog); + + dialog.open(); + }); + + teardown(function() { + dialog.remove(); + dialog = null; + }); + + + /** + * Test that the dialog reacts to valid and invalid input correctly. + */ + test('Add user', function() { + const userInputBox = dialog.$$('#addUserInput'); + assertTrue(!!userInputBox); + + const addButton = dialog.$$('.action-button'); + assertTrue(!!addButton); + assertTrue(addButton.disabled); + assertTrue(!userInputBox.invalid); + + // Try to add a valid username without domain + userInputBox.value = 'abcdef'; + assertTrue(!addButton.disabled); + assertTrue(!userInputBox.invalid); + + // Try to add a valid username with domain + userInputBox.value = 'abcdef@xyz.com'; + assertTrue(!addButton.disabled); + assertTrue(!userInputBox.invalid); + + // Try to add an invalid username + userInputBox.value = 'abcdef@'; + assertTrue(addButton.disabled); + assertTrue(userInputBox.invalid); + }); +});
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index a63af80b..759f1efd 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -2442,3 +2442,30 @@ TEST_F('CrSettingsSiteFaviconTest', 'All', function() { mocha.run(); }); + +GEN('#if defined(OS_CHROMEOS)'); + +/** + * Test fixture for the chrome://settings/accounts page + * @constructor + * @extends {CrSettingsBrowserTest} + */ +function CrSettingsAddUsersTest() {} + +CrSettingsAddUsersTest.prototype = { + __proto__: CrSettingsBrowserTest.prototype, + + /** @override */ + browsePreload: 'chrome://settings/accounts.html', + + /** @override */ + extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ + 'add_users_tests.js', + ]), +}; + +TEST_F('CrSettingsAddUsersTest', 'All', function() { + mocha.run(); +}); + +GEN('#endif // defined(OS_CHROMEOS)');
diff --git a/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc b/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc index d5ed9b7..aa829759 100644 --- a/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc +++ b/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc
@@ -193,8 +193,19 @@ case ui::AXEventGenerator::Event::STATE_CHANGED: return api::automation::EVENT_TYPE_ARIAATTRIBUTECHANGED; + case ui::AXEventGenerator::Event::ACCESS_KEY_CHANGED: + case ui::AXEventGenerator::Event::CLASS_NAME_CHANGED: + case ui::AXEventGenerator::Event::DESCRIBED_BY_CHANGED: case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED: + case ui::AXEventGenerator::Event::FLOW_TO_CHANGED: + case ui::AXEventGenerator::Event::HIERARCHICAL_LEVEL_CHANGED: + case ui::AXEventGenerator::Event::KEY_SHORTCUTS_CHANGED: + case ui::AXEventGenerator::Event::LABELED_BY_CHANGED: + case ui::AXEventGenerator::Event::LANGUAGE_CHANGED: case ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED: + case ui::AXEventGenerator::Event::PLACEHOLDER_CHANGED: + case ui::AXEventGenerator::Event::POSITION_IN_SET_CHANGED: + case ui::AXEventGenerator::Event::SET_SIZE_CHANGED: return api::automation::EVENT_TYPE_NONE; }
diff --git a/chromeos/dbus/auth_policy/auth_policy_client.cc b/chromeos/dbus/auth_policy/auth_policy_client.cc index 6656d78..22ef7181 100644 --- a/chromeos/dbus/auth_policy/auth_policy_client.cc +++ b/chromeos/dbus/auth_policy/auth_policy_client.cc
@@ -10,6 +10,7 @@ #include "base/location.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread_task_runner_handle.h" +#include "chromeos/dbus/auth_policy/fake_auth_policy_client.h" #include "components/account_id/account_id.h" #include "dbus/bus.h" #include "dbus/message.h" @@ -26,6 +27,8 @@ // call. constexpr int kSlowDbusTimeoutMilliseconds = 630 * 1000; +AuthPolicyClient* g_instance = nullptr; + authpolicy::ErrorType GetErrorFromReader(dbus::MessageReader* reader) { int32_t int_error; if (!reader->PopInt32(&int_error)) { @@ -174,8 +177,7 @@ proxy_->WaitForServiceToBeAvailable(std::move(callback)); } - protected: - void Init(dbus::Bus* bus) override { + void Init(dbus::Bus* bus) { bus_ = bus; proxy_ = bus_->GetObjectProxy( authpolicy::kAuthPolicyServiceName, @@ -232,13 +234,37 @@ } // namespace -AuthPolicyClient::AuthPolicyClient() = default; +AuthPolicyClient::AuthPolicyClient() { + DCHECK(!g_instance); + g_instance = this; +} -AuthPolicyClient::~AuthPolicyClient() = default; +AuthPolicyClient::~AuthPolicyClient() { + DCHECK_EQ(this, g_instance); + g_instance = nullptr; +} // static -AuthPolicyClient* AuthPolicyClient::Create() { - return new AuthPolicyClientImpl(); +void AuthPolicyClient::Initialize(dbus::Bus* bus) { + DCHECK(bus); + (new AuthPolicyClientImpl)->Init(bus); +} + +// static +void AuthPolicyClient::InitializeFake() { + if (!FakeAuthPolicyClient::Get()) + new FakeAuthPolicyClient(); +} + +// static +void AuthPolicyClient::Shutdown() { + DCHECK(g_instance); + delete g_instance; +} + +// static +AuthPolicyClient* AuthPolicyClient::Get() { + return g_instance; } } // namespace chromeos
diff --git a/chromeos/dbus/auth_policy/auth_policy_client.h b/chromeos/dbus/auth_policy/auth_policy_client.h index 1b4f94b..5b71b0b 100644 --- a/chromeos/dbus/auth_policy/auth_policy_client.h +++ b/chromeos/dbus/auth_policy/auth_policy_client.h
@@ -10,7 +10,6 @@ #include "base/callback.h" #include "base/component_export.h" #include "chromeos/dbus/authpolicy/active_directory_info.pb.h" -#include "chromeos/dbus/dbus_client.h" #include "dbus/object_proxy.h" #include "third_party/cros_system_api/dbus/service_constants.h" @@ -21,7 +20,7 @@ // AuthPolicyClient is used to communicate with the org.chromium.AuthPolicy // sevice. All method should be called from the origin thread (UI thread) which // initializes the DBusThreadManager instance. -class COMPONENT_EXPORT(CHROMEOS_DBUS) AuthPolicyClient : public DBusClient { +class COMPONENT_EXPORT(CHROMEOS_DBUS) AuthPolicyClient { public: using AuthCallback = base::OnceCallback<void( authpolicy::ErrorType error, @@ -38,11 +37,17 @@ using RefreshPolicyCallback = base::OnceCallback<void(authpolicy::ErrorType error)>; - ~AuthPolicyClient() override; + // Creates and initializes the global instance. |bus| must not be null. + static void Initialize(dbus::Bus* bus); - // Factory function, creates a new instance and returns ownership. - // For normal usage, access the singleton via DBusThreadManager::Get(). - static AuthPolicyClient* Create(); + // Creates and initializes a fake global instance if not already created. + static void InitializeFake(); + + // Destroys the global instance which must have been initialized. + static void Shutdown(); + + // Returns the global instance if initialized. May return null. + static AuthPolicyClient* Get(); // Calls JoinADDomain to join a machine/device to an Active Directory domain. // Password is read from the |password_fd|. |callback| is called after getting @@ -91,8 +96,9 @@ dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback) = 0; protected: - // Create() should be used instead. + // Initialize/Shutdown should be used instead. AuthPolicyClient(); + virtual ~AuthPolicyClient(); private: DISALLOW_COPY_AND_ASSIGN(AuthPolicyClient);
diff --git a/chromeos/dbus/auth_policy/fake_auth_policy_client.cc b/chromeos/dbus/auth_policy/fake_auth_policy_client.cc index 8554c19..7cd4f1d 100644 --- a/chromeos/dbus/auth_policy/fake_auth_policy_client.cc +++ b/chromeos/dbus/auth_policy/fake_auth_policy_client.cc
@@ -26,6 +26,8 @@ namespace em = enterprise_management; +namespace chromeos { + namespace { constexpr size_t kMaxMachineNameLength = 15; @@ -33,7 +35,9 @@ constexpr char kDefaultKerberosCreds[] = "credentials"; constexpr char kDefaultKerberosConf[] = "configuration"; -void OnStorePolicy(chromeos::AuthPolicyClient::RefreshPolicyCallback callback, +FakeAuthPolicyClient* g_instance = nullptr; + +void OnStorePolicy(AuthPolicyClient::RefreshPolicyCallback callback, bool success) { const authpolicy::ErrorType error = success ? authpolicy::ERROR_NONE : authpolicy::ERROR_STORE_POLICY_FAILED; @@ -57,13 +61,20 @@ } // namespace -namespace chromeos { +FakeAuthPolicyClient::FakeAuthPolicyClient() { + DCHECK(!g_instance); + g_instance = this; +} -FakeAuthPolicyClient::FakeAuthPolicyClient() = default; +FakeAuthPolicyClient::~FakeAuthPolicyClient() { + DCHECK_EQ(this, g_instance); + g_instance = nullptr; +} -FakeAuthPolicyClient::~FakeAuthPolicyClient() = default; - -void FakeAuthPolicyClient::Init(dbus::Bus* bus) {} +// static +FakeAuthPolicyClient* FakeAuthPolicyClient::Get() { + return g_instance; +} void FakeAuthPolicyClient::JoinAdDomain( const authpolicy::JoinDomainRequest& request, @@ -325,8 +336,8 @@ em::PolicyFetchResponse response; response.set_policy_data(policy_data.SerializeAsString()); - chromeos::SessionManagerClient* session_manager_client = - chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); + SessionManagerClient* session_manager_client = + DBusThreadManager::Get()->GetSessionManagerClient(); session_manager_client->StoreDevicePolicy( response.SerializeAsString(), base::BindOnce(&OnStorePolicy, std::move(callback)));
diff --git a/chromeos/dbus/auth_policy/fake_auth_policy_client.h b/chromeos/dbus/auth_policy/fake_auth_policy_client.h index f23fb6a2..57986ed 100644 --- a/chromeos/dbus/auth_policy/fake_auth_policy_client.h +++ b/chromeos/dbus/auth_policy/fake_auth_policy_client.h
@@ -28,8 +28,9 @@ FakeAuthPolicyClient(); ~FakeAuthPolicyClient() override; - // DBusClient overrides. - void Init(dbus::Bus* bus) override; + // Returns the fake global instance if initialized. May return null. + static FakeAuthPolicyClient* Get(); + // AuthPolicyClient overrides. // Performs basic checks on |request.machine_name| and
diff --git a/chromeos/dbus/auth_policy/fake_auth_policy_client_unittest.cc b/chromeos/dbus/auth_policy/fake_auth_policy_client_unittest.cc index 6d8dab7e..fb524ff 100644 --- a/chromeos/dbus/auth_policy/fake_auth_policy_client_unittest.cc +++ b/chromeos/dbus/auth_policy/fake_auth_policy_client_unittest.cc
@@ -32,7 +32,9 @@ FakeAuthPolicyClientTest() = default; protected: - FakeAuthPolicyClient* authpolicy_client() { return auth_policy_client_ptr_; } + FakeAuthPolicyClient* authpolicy_client() { + return FakeAuthPolicyClient::Get(); + } FakeSessionManagerClient* session_manager_client() { return session_manager_client_ptr_; } @@ -41,17 +43,21 @@ ::testing::Test::SetUp(); auto session_manager_client = std::make_unique<FakeSessionManagerClient>(); session_manager_client_ptr_ = session_manager_client.get(); + // DBusThreadManager::GetSetterForTesting initializes DBusThreadManager. DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( std::move(session_manager_client)); DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient( std::make_unique<FakeCryptohomeClient>()); - auto auth_policy_client = std::make_unique<FakeAuthPolicyClient>(); - auth_policy_client_ptr_ = auth_policy_client.get(); - DBusThreadManager::GetSetterForTesting()->SetAuthPolicyClient( - std::move(auth_policy_client)); + + AuthPolicyClient::InitializeFake(); authpolicy_client()->DisableOperationDelayForTesting(); } + void TearDown() override { + AuthPolicyClient::Shutdown(); + DBusThreadManager::Shutdown(); + } + void JoinAdDomain(const std::string& machine_name, const std::string& username, AuthPolicyClient::JoinCallback callback) { @@ -102,7 +108,6 @@ int service_is_available_called_num_ = 0; private: - FakeAuthPolicyClient* auth_policy_client_ptr_; // not owned. FakeSessionManagerClient* session_manager_client_ptr_; // not owned. base::MessageLoop loop_;
diff --git a/chromeos/dbus/dbus_clients_browser.cc b/chromeos/dbus/dbus_clients_browser.cc index 5e4f4170..3b5c4a0 100644 --- a/chromeos/dbus/dbus_clients_browser.cc +++ b/chromeos/dbus/dbus_clients_browser.cc
@@ -9,8 +9,6 @@ #include "chromeos/dbus/arc_midis_client.h" #include "chromeos/dbus/arc_obb_mounter_client.h" #include "chromeos/dbus/arc_oemcrypto_client.h" -#include "chromeos/dbus/auth_policy/auth_policy_client.h" -#include "chromeos/dbus/auth_policy/fake_auth_policy_client.h" #include "chromeos/dbus/cec_service_client.h" #include "chromeos/dbus/cicerone_client.h" #include "chromeos/dbus/concierge_client.h" @@ -78,11 +76,6 @@ else arc_oemcrypto_client_.reset(new FakeArcOemCryptoClient); - if (use_real_clients) - auth_policy_client_.reset(AuthPolicyClient::Create()); - else - auth_policy_client_.reset(new FakeAuthPolicyClient); - cec_service_client_ = CecServiceClient::Create(client_impl_type); cros_disks_client_.reset(CrosDisksClient::Create(client_impl_type)); @@ -169,7 +162,6 @@ arc_midis_client_->Init(system_bus); arc_obb_mounter_client_->Init(system_bus); arc_oemcrypto_client_->Init(system_bus); - auth_policy_client_->Init(system_bus); cec_service_client_->Init(system_bus); cicerone_client_->Init(system_bus); concierge_client_->Init(system_bus);
diff --git a/chromeos/dbus/dbus_clients_browser.h b/chromeos/dbus/dbus_clients_browser.h index a0fd299..24c86b6 100644 --- a/chromeos/dbus/dbus_clients_browser.h +++ b/chromeos/dbus/dbus_clients_browser.h
@@ -20,7 +20,6 @@ class ArcMidisClient; class ArcObbMounterClient; class ArcOemCryptoClient; -class AuthPolicyClient; class CecServiceClient; class CiceroneClient; class ConciergeClient; @@ -58,7 +57,6 @@ std::unique_ptr<ArcMidisClient> arc_midis_client_; std::unique_ptr<ArcObbMounterClient> arc_obb_mounter_client_; std::unique_ptr<ArcOemCryptoClient> arc_oemcrypto_client_; - std::unique_ptr<AuthPolicyClient> auth_policy_client_; std::unique_ptr<CecServiceClient> cec_service_client_; std::unique_ptr<CiceroneClient> cicerone_client_; std::unique_ptr<ConciergeClient> concierge_client_;
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc index 946f48ee9..2efc8ae 100644 --- a/chromeos/dbus/dbus_thread_manager.cc +++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -14,7 +14,6 @@ #include "chromeos/dbus/arc_midis_client.h" #include "chromeos/dbus/arc_obb_mounter_client.h" #include "chromeos/dbus/arc_oemcrypto_client.h" -#include "chromeos/dbus/auth_policy/auth_policy_client.h" #include "chromeos/dbus/cec_service_client.h" #include "chromeos/dbus/cicerone_client.h" #include "chromeos/dbus/concierge_client.h" @@ -134,11 +133,6 @@ : nullptr; } -AuthPolicyClient* DBusThreadManager::GetAuthPolicyClient() { - return clients_browser_ ? clients_browser_->auth_policy_client_.get() - : nullptr; -} - CecServiceClient* DBusThreadManager::GetCecServiceClient() { return clients_browser_ ? clients_browser_->cec_service_client_.get() : nullptr; @@ -359,12 +353,6 @@ DBusThreadManagerSetter::~DBusThreadManagerSetter() = default; -void DBusThreadManagerSetter::SetAuthPolicyClient( - std::unique_ptr<AuthPolicyClient> client) { - DBusThreadManager::Get()->clients_browser_->auth_policy_client_ = - std::move(client); -} - void DBusThreadManagerSetter::SetCiceroneClient( std::unique_ptr<CiceroneClient> client) { DBusThreadManager::Get()->clients_browser_->cicerone_client_ =
diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h index 1dfbbcdc..ad843cd 100644 --- a/chromeos/dbus/dbus_thread_manager.h +++ b/chromeos/dbus/dbus_thread_manager.h
@@ -28,7 +28,6 @@ class ArcMidisClient; class ArcObbMounterClient; class ArcOemCryptoClient; -class AuthPolicyClient; class CecServiceClient; class CiceroneClient; class ConciergeClient; @@ -126,7 +125,6 @@ ArcMidisClient* GetArcMidisClient(); ArcObbMounterClient* GetArcObbMounterClient(); ArcOemCryptoClient* GetArcOemCryptoClient(); - AuthPolicyClient* GetAuthPolicyClient(); CecServiceClient* GetCecServiceClient(); CiceroneClient* GetCiceroneClient(); ConciergeClient* GetConciergeClient(); @@ -191,7 +189,6 @@ public: ~DBusThreadManagerSetter(); - void SetAuthPolicyClient(std::unique_ptr<AuthPolicyClient> client); void SetCiceroneClient(std::unique_ptr<CiceroneClient> client); void SetConciergeClient(std::unique_ptr<ConciergeClient> client); void SetCrasAudioClient(std::unique_ptr<CrasAudioClient> client);
diff --git a/chromeos/dbus/upstart/fake_upstart_client.cc b/chromeos/dbus/upstart/fake_upstart_client.cc index 1672e4d..1cc6339 100644 --- a/chromeos/dbus/upstart/fake_upstart_client.cc +++ b/chromeos/dbus/upstart/fake_upstart_client.cc
@@ -46,17 +46,13 @@ } void FakeUpstartClient::StartAuthPolicyService() { - static_cast<FakeAuthPolicyClient*>( - DBusThreadManager::Get()->GetAuthPolicyClient()) - ->SetStarted(true); + FakeAuthPolicyClient::Get()->SetStarted(true); } void FakeUpstartClient::RestartAuthPolicyService() { - FakeAuthPolicyClient* authpolicy_client = static_cast<FakeAuthPolicyClient*>( - DBusThreadManager::Get()->GetAuthPolicyClient()); - DLOG_IF(WARNING, !authpolicy_client->started()) + DLOG_IF(WARNING, !FakeAuthPolicyClient::Get()->started()) << "Trying to restart authpolicyd which is not started"; - authpolicy_client->SetStarted(true); + FakeAuthPolicyClient::Get()->SetStarted(true); } void FakeUpstartClient::StartMediaAnalytics(
diff --git a/chromeos/login/auth/authpolicy_login_helper.cc b/chromeos/login/auth/authpolicy_login_helper.cc index 864a8e7..c1175f9 100644 --- a/chromeos/login/auth/authpolicy_login_helper.cc +++ b/chromeos/login/auth/authpolicy_login_helper.cc
@@ -147,7 +147,7 @@ authpolicy::AuthenticateUserRequest request; request.set_user_principal_name(username); request.set_account_id(object_guid); - chromeos::DBusThreadManager::Get()->GetAuthPolicyClient()->AuthenticateUser( + AuthPolicyClient::Get()->AuthenticateUser( request, GetDataReadPipe(password).get(), base::DoNothing()); } @@ -189,7 +189,7 @@ DCHECK(!dm_token_.empty()); request.set_dm_token(dm_token_); - chromeos::DBusThreadManager::Get()->GetAuthPolicyClient()->JoinAdDomain( + AuthPolicyClient::Get()->JoinAdDomain( request, GetDataReadPipe(password).get(), base::BindOnce(&AuthPolicyLoginHelper::OnJoinCallback, weak_factory_.GetWeakPtr(), std::move(callback))); @@ -203,7 +203,7 @@ authpolicy::AuthenticateUserRequest request; request.set_user_principal_name(username); request.set_account_id(object_guid); - chromeos::DBusThreadManager::Get()->GetAuthPolicyClient()->AuthenticateUser( + AuthPolicyClient::Get()->AuthenticateUser( request, GetDataReadPipe(password).get(), base::BindOnce(&AuthPolicyLoginHelper::OnAuthCallback, weak_factory_.GetWeakPtr(), std::move(callback))); @@ -223,11 +223,9 @@ std::move(callback).Run(error, machine_domain); return; } - chromeos::DBusThreadManager::Get() - ->GetAuthPolicyClient() - ->RefreshDevicePolicy(base::BindOnce( - &AuthPolicyLoginHelper::OnFirstPolicyRefreshCallback, - weak_factory_.GetWeakPtr(), std::move(callback), machine_domain)); + AuthPolicyClient::Get()->RefreshDevicePolicy(base::BindOnce( + &AuthPolicyLoginHelper::OnFirstPolicyRefreshCallback, + weak_factory_.GetWeakPtr(), std::move(callback), machine_domain)); } void AuthPolicyLoginHelper::OnFirstPolicyRefreshCallback(
diff --git a/chromeos/login/auth/authpolicy_login_helper_unittest.cc b/chromeos/login/auth/authpolicy_login_helper_unittest.cc index 56d53f58..19cff6e 100644 --- a/chromeos/login/auth/authpolicy_login_helper_unittest.cc +++ b/chromeos/login/auth/authpolicy_login_helper_unittest.cc
@@ -56,13 +56,11 @@ // Check that helper calls RefreshDevicePolicy after JoinAdDomain. TEST(AuthPolicyLoginHelper, JoinFollowedByRefreshDevicePolicy) { - std::unique_ptr<MockAuthPolicyClient> mock_client = - std::make_unique<MockAuthPolicyClient>(); - MockAuthPolicyClient* mock_client_ptr = mock_client.get(); - DBusThreadManager::GetSetterForTesting()->SetAuthPolicyClient( - std::move(mock_client)); DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient( std::make_unique<FakeCryptohomeClient>()); + + auto* mock_client = new MockAuthPolicyClient; + AuthPolicyLoginHelper helper; helper.set_dm_token(kDMToken); helper.JoinAdDomain(std::string(), std::string(), @@ -73,7 +71,8 @@ EXPECT_EQ(authpolicy::ERROR_NONE, error); EXPECT_TRUE(domain.empty()); })); - mock_client_ptr->CheckExpectations(); + mock_client->CheckExpectations(); + AuthPolicyClient::Shutdown(); } } // namespace chromeos
diff --git a/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl_unittest.cc b/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl_unittest.cc index e2b1e31..e476d80 100644 --- a/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl_unittest.cc +++ b/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl_unittest.cc
@@ -6,6 +6,7 @@ #include <utility> #include "base/base64url.h" +#include "base/no_destructor.h" #include "base/optional.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" @@ -51,17 +52,20 @@ const char kFakeV2PublicKey[] = "public_key_v2"; const char kFakeV2PrivateKey[] = "private_key_v2"; -const base::TimeDelta kFakeRefreshPeriod = base::TimeDelta::FromMilliseconds( - cryptauthv2::kTestClientDirectiveCheckinDelayMillis); -const base::TimeDelta kFakeRetryPeriod = base::TimeDelta::FromMilliseconds( - cryptauthv2::kTestClientDirectiveRetryPeriodMillis); -const base::Time kFakeLastEnrollmentTime = base::Time::UnixEpoch(); -const base::Time kFakeTimeAfterRefreshPeriod = kFakeLastEnrollmentTime + - kFakeRefreshPeriod + - base::TimeDelta::FromSeconds(1); -const base::Time kFakeTimeBeforeRefreshPeriod = kFakeLastEnrollmentTime + - kFakeRefreshPeriod - - base::TimeDelta::FromSeconds(1); +constexpr base::TimeDelta kFakeRefreshPeriod = + base::TimeDelta::FromMilliseconds(2592000000); +constexpr base::TimeDelta kFakeRetryPeriod = + base::TimeDelta::FromMilliseconds(43200000); + +const cryptauthv2::PolicyReference& GetClientDirectivePolicyReferenceForTest() { + static const base::NoDestructor<cryptauthv2::PolicyReference> + policy_reference([] { + return cryptauthv2::BuildPolicyReference("policy_reference_name", + 1 /* version */); + }()); + + return *policy_reference; +} // A child of FakeCryptAuthEnrollmentScheduler that sets scheduler parameters // based on the latest enrollment result. @@ -124,6 +128,11 @@ delegate, clock_); instance_ = instance.get(); + // Fix the scheduler's ClientDirective PolicyReference to test that it is + // passed to the enroller properly. + instance->set_client_directive_policy_reference( + GetClientDirectivePolicyReferenceForTest()); + if (initial_num_consecutive_failures_) { instance->set_num_consecutive_failures( *initial_num_consecutive_failures_); @@ -197,6 +206,8 @@ NetworkHandler::Initialize(); base::RunLoop().RunUntilIdle(); + test_clock_.SetNow(base::Time::UnixEpoch()); + CryptAuthV2EnrollmentManagerImpl::RegisterPrefs( test_pref_service_.registry()); CryptAuthKeyRegistryImpl::RegisterPrefs(test_pref_service_.registry()); @@ -218,8 +229,8 @@ // testing::Test: void TearDown() override { - if (enrollment_manager()) - enrollment_manager()->RemoveObserver(this); + if (enrollment_manager_) + enrollment_manager_->RemoveObserver(this); NetworkAwareEnrollmentScheduler::Factory::SetFactoryForTesting(nullptr); CryptAuthV2EnrollerImpl::Factory::SetFactoryForTesting(nullptr); @@ -228,6 +239,14 @@ DBusThreadManager::Shutdown(); } + // CryptAuthEnrollmentManager::Observer: + void OnEnrollmentStarted() override { + ++num_enrollment_started_notifications_; + } + void OnEnrollmentFinished(bool success) override { + observer_enrollment_finished_success_list_.push_back(success); + } + void AddV1UserKeyPairToV1Prefs(const std::string& public_key, const std::string& private_key) { std::string public_key_b64, private_key_b64; @@ -250,16 +269,6 @@ num_consecutive_failures); } - // CryptAuthEnrollmentManager::Observer: - void OnEnrollmentStarted() override { - ++num_enrollment_started_notifications_; - - enrollment_finished_success_ = base::nullopt; - } - void OnEnrollmentFinished(bool success) override { - enrollment_finished_success_ = success; - } - void CreateEnrollmentManager() { auto mock_timer = std::make_unique<base::MockOneShotTimer>(); mock_timer_ = mock_timer.get(); @@ -270,7 +279,11 @@ &mock_client_factory_, &fake_gcm_manager_, &test_pref_service_, &test_clock_, std::move(mock_timer)); - enrollment_manager()->AddObserver(this); + enrollment_manager_->AddObserver(this); + } + + void RequestEnrollmentThroughGcm() { + fake_gcm_manager_.PushReenrollMessage(); } void VerifyEnrollmentManagerObserversNotifiedOfStart( @@ -279,6 +292,135 @@ num_enrollment_started_notifications_); } + void CompleteGcmRegistration(bool success) { + EXPECT_TRUE(fake_gcm_manager_.GetRegistrationId().empty()); + + if (success) { + fake_gcm_manager_.CompleteRegistration( + cryptauthv2::kTestGcmRegistrationId); + } else { + // An empty registration ID is interpreted as an error by + // FakeCryptAuthGCMManager. + fake_gcm_manager_.CompleteRegistration(std::string()); + } + } + + void HandleGetClientAppMetadataRequest(bool success) { + EXPECT_GT(fake_client_app_metadata_provider_.metadata_requests().size(), + 0u); + EXPECT_EQ(cryptauthv2::kTestGcmRegistrationId, + fake_client_app_metadata_provider_.metadata_requests() + .back() + .gcm_registration_id); + + if (success) { + std::move(fake_client_app_metadata_provider_.metadata_requests() + .back() + .callback) + .Run(cryptauthv2::GetClientAppMetadataForTest()); + return; + } + + std::move( + fake_client_app_metadata_provider_.metadata_requests().back().callback) + .Run(base::nullopt /* client_app_metadata */); + } + + void FinishEnrollmentAttempt( + size_t expected_enroller_instance_index, + const cryptauthv2::ClientMetadata::InvocationReason& + expected_invocation_reason, + const CryptAuthEnrollmentResult& enrollment_result) { + EXPECT_TRUE(enrollment_manager_->IsEnrollmentInProgress()); + + // A valid GCM registration ID and valid ClientAppMetadata must exist before + // the enroller can be invoked. + EXPECT_EQ(cryptauthv2::kTestGcmRegistrationId, + fake_gcm_manager_.GetRegistrationId()); + EXPECT_GT(fake_client_app_metadata_provider_.metadata_requests().size(), + 0u); + + // Only the most recently created enroller is valid. + EXPECT_EQ(fake_enroller_factory_->created_instances().size() - 1, + expected_enroller_instance_index); + FakeCryptAuthV2Enroller* enroller = + fake_enroller_factory_ + ->created_instances()[expected_enroller_instance_index]; + + VerifyEnrollerData(enroller, expected_invocation_reason); + + enroller->FinishAttempt(enrollment_result); + + EXPECT_FALSE(enrollment_manager_->IsEnrollmentInProgress()); + + cryptauthv2::ClientMetadata::InvocationReason expected_persisted_reason = + enrollment_manager_->IsRecoveringFromFailure() + ? expected_invocation_reason + : cryptauthv2::ClientMetadata::INVOCATION_REASON_UNSPECIFIED; + VerifyPersistedFailureRecoveryInvocationReason(expected_persisted_reason); + } + + void VerifyEnrollmentResults( + const std::vector<CryptAuthEnrollmentResult>& expected_results) { + VerifyResultsSentToEnrollmentManagerObservers(expected_results); + VerifyResultsSentToEnrollmentScheduler(expected_results); + } + + CryptAuthKeyRegistry* key_registry() { return key_registry_.get(); } + + FakeCryptAuthEnrollmentSchedulerWithResultHandling* + fake_enrollment_scheduler() { + return fake_enrollment_scheduler_factory_->instance(); + } + + base::SimpleTestClock* test_clock() { return &test_clock_; } + + base::MockOneShotTimer* mock_timer() { return mock_timer_; } + + CryptAuthEnrollmentManager* enrollment_manager() { + return enrollment_manager_.get(); + } + + private: + void VerifyEnrollerData(FakeCryptAuthV2Enroller* enroller, + const cryptauthv2::ClientMetadata::InvocationReason& + expected_invocation_reason) { + EXPECT_TRUE(enroller->was_enroll_called()); + + EXPECT_EQ(cryptauthv2::BuildClientMetadata( + fake_enrollment_scheduler() + ->GetNumConsecutiveFailures() /* retry_count */, + expected_invocation_reason) + .SerializeAsString(), + enroller->client_metadata()->SerializeAsString()); + + EXPECT_EQ(cryptauthv2::GetClientAppMetadataForTest().SerializeAsString(), + enroller->client_app_metadata()->SerializeAsString()); + + EXPECT_EQ( + GetClientDirectivePolicyReferenceForTest().SerializeAsString(), + (*enroller->client_directive_policy_reference())->SerializeAsString()); + } + + void VerifyResultsSentToEnrollmentManagerObservers( + const std::vector<CryptAuthEnrollmentResult> + expected_enrollment_results) { + ASSERT_EQ(expected_enrollment_results.size(), + observer_enrollment_finished_success_list_.size()); + + for (size_t i = 0; i < expected_enrollment_results.size(); ++i) { + EXPECT_EQ(expected_enrollment_results[i].IsSuccess(), + observer_enrollment_finished_success_list_[i]); + } + } + + void VerifyResultsSentToEnrollmentScheduler( + const std::vector<CryptAuthEnrollmentResult> + expected_enrollment_results) { + EXPECT_EQ(expected_enrollment_results, + fake_enrollment_scheduler()->handled_enrollment_results()); + } + void VerifyPersistedFailureRecoveryInvocationReason( const cryptauthv2::ClientMetadata::InvocationReason& expected_failure_recovery_invocation_reason) { @@ -289,57 +431,11 @@ prefs::kCryptAuthEnrollmentFailureRecoveryInvocationReason))); } - void VerifyEnrollmentResult( - const CryptAuthEnrollmentResult& expected_result) { - VerifyResultSentToEnrollmentManagerObservers(expected_result.IsSuccess()); - EXPECT_EQ(expected_result, - fake_enrollment_scheduler()->handled_enrollment_results().back()); - } - - TestingPrefServiceSimple* test_pref_service() { return &test_pref_service_; } - - CryptAuthKeyRegistry* key_registry() { return key_registry_.get(); } - - FakeCryptAuthEnrollmentSchedulerWithResultHandling* - fake_enrollment_scheduler() { - return fake_enrollment_scheduler_factory_->instance(); - } - - FakeCryptAuthGCMManager* fake_gcm_manager() { return &fake_gcm_manager_; } - - base::SimpleTestClock* test_clock() { return &test_clock_; } - - base::MockOneShotTimer* mock_timer() { return mock_timer_; } - - FakeClientAppMetadataProvider* fake_client_app_metadata_provider() { - return &fake_client_app_metadata_provider_; - } - - MockCryptAuthClientFactory* mock_client_factory() { - return &mock_client_factory_; - } - - FakeCryptAuthV2Enroller* fake_enroller(size_t index = 0u) { - // Only the most recently created enroller is valid. - EXPECT_EQ(fake_enroller_factory_->created_instances().size() - 1, index); - - return fake_enroller_factory_->created_instances()[index]; - } - - CryptAuthEnrollmentManager* enrollment_manager() { - return enrollment_manager_.get(); - } - - private: - void VerifyResultSentToEnrollmentManagerObservers(bool success) { - EXPECT_EQ(success, enrollment_finished_success_); - } - base::test::ScopedTaskEnvironment scoped_task_environment_; size_t num_enrollment_started_notifications_ = 0; - base::Optional<bool> enrollment_finished_success_ = base::nullopt; size_t num_consecutive_failures_ = 0; + std::vector<bool> observer_enrollment_finished_success_list_; TestingPrefServiceSimple test_pref_service_; FakeClientAppMetadataProvider fake_client_app_metadata_provider_; @@ -365,52 +461,27 @@ // The user has never enrolled with v1 or v2 and has not registered with GCM. EXPECT_TRUE(key_registry()->enrolled_key_bundles().empty()); - EXPECT_TRUE(fake_gcm_manager()->GetRegistrationId().empty()); EXPECT_TRUE(enrollment_manager()->GetLastEnrollmentTime().is_null()); EXPECT_FALSE(enrollment_manager()->IsEnrollmentValid()); - cryptauthv2::PolicyReference expected_policy_reference = - cryptauthv2::BuildPolicyReference("expected_policy_reference_name", - 1 /* version */); - fake_enrollment_scheduler()->set_client_directive_policy_reference( - expected_policy_reference); fake_enrollment_scheduler()->RequestEnrollmentNow(); EXPECT_TRUE(enrollment_manager()->IsEnrollmentInProgress()); VerifyEnrollmentManagerObserversNotifiedOfStart( 1 /* expected_num_enrollment_started_notifications */); - fake_gcm_manager()->CompleteRegistration(cryptauthv2::kTestGcmRegistrationId); - - EXPECT_EQ(1u, - fake_client_app_metadata_provider()->metadata_requests().size()); - EXPECT_EQ(cryptauthv2::kTestGcmRegistrationId, - fake_client_app_metadata_provider() - ->metadata_requests()[0] - .gcm_registration_id); - std::move( - fake_client_app_metadata_provider()->metadata_requests()[0].callback) - .Run(cryptauthv2::GetClientAppMetadataForTest()); - - EXPECT_TRUE(fake_enroller()->was_enroll_called()); - EXPECT_EQ( - cryptauthv2::BuildClientMetadata( - 0 /* retry_count */, - cryptauthv2::ClientMetadata::INITIALIZATION /* invocation_reason */) - .SerializeAsString(), - fake_enroller()->client_metadata()->SerializeAsString()); - EXPECT_EQ(cryptauthv2::GetClientAppMetadataForTest().SerializeAsString(), - fake_enroller()->client_app_metadata()->SerializeAsString()); - EXPECT_EQ(expected_policy_reference.SerializeAsString(), - (*fake_enroller()->client_directive_policy_reference()) - ->SerializeAsString()); + CompleteGcmRegistration(true /* success */); + HandleGetClientAppMetadataRequest(true /* success */); CryptAuthEnrollmentResult expected_enrollment_result( CryptAuthEnrollmentResult::ResultCode::kSuccessNewKeysEnrolled, cryptauthv2::GetClientDirectiveForTest()); - fake_enroller()->FinishAttempt(expected_enrollment_result); - EXPECT_FALSE(enrollment_manager()->IsEnrollmentInProgress()); - VerifyEnrollmentResult(expected_enrollment_result); + FinishEnrollmentAttempt(0u /* expected_enroller_instance_index */, + cryptauthv2::ClientMetadata:: + INITIALIZATION /* expected_invocation_reason */, + expected_enrollment_result); + + VerifyEnrollmentResults({expected_enrollment_result}); } TEST_F(DeviceSyncCryptAuthV2EnrollmentManagerImplTest, GcmRegistrationFailed) { @@ -418,13 +489,11 @@ enrollment_manager()->Start(); fake_enrollment_scheduler()->RequestEnrollmentNow(); - // An empty registration ID is interpreted as an error by - // FakeCryptAuthGCMManager. - fake_gcm_manager()->CompleteRegistration(std::string() /* registration_id */); + CompleteGcmRegistration(false /* success */); - VerifyEnrollmentResult(CryptAuthEnrollmentResult( + VerifyEnrollmentResults({CryptAuthEnrollmentResult( CryptAuthEnrollmentResult::ResultCode::kErrorGcmRegistrationFailed, - base::nullopt /* client_directive */)); + base::nullopt /* client_directive */)}); } TEST_F(DeviceSyncCryptAuthV2EnrollmentManagerImplTest, GcmRegistrationTimeout) { @@ -436,10 +505,10 @@ EXPECT_TRUE(mock_timer()->IsRunning()); mock_timer()->Fire(); - VerifyEnrollmentResult( - CryptAuthEnrollmentResult(CryptAuthEnrollmentResult::ResultCode:: - kErrorTimeoutWaitingForGcmRegistration, - base::nullopt /* client_directive */)); + VerifyEnrollmentResults( + {CryptAuthEnrollmentResult(CryptAuthEnrollmentResult::ResultCode:: + kErrorTimeoutWaitingForGcmRegistration, + base::nullopt /* client_directive */)}); } TEST_F(DeviceSyncCryptAuthV2EnrollmentManagerImplTest, @@ -447,16 +516,12 @@ CreateEnrollmentManager(); enrollment_manager()->Start(); fake_enrollment_scheduler()->RequestEnrollmentNow(); - fake_gcm_manager()->CompleteRegistration(cryptauthv2::kTestGcmRegistrationId); + CompleteGcmRegistration(true /* success */); + HandleGetClientAppMetadataRequest(false /* success */); - // A failed metadata retrieval will return base::nullopt. - std::move( - fake_client_app_metadata_provider()->metadata_requests()[0].callback) - .Run(base::nullopt /* client_app_metadata */); - - VerifyEnrollmentResult(CryptAuthEnrollmentResult( + VerifyEnrollmentResults({CryptAuthEnrollmentResult( CryptAuthEnrollmentResult::ResultCode::kErrorClientAppMetadataFetchFailed, - base::nullopt /* client_directive */)); + base::nullopt /* client_directive */)}); } TEST_F(DeviceSyncCryptAuthV2EnrollmentManagerImplTest, @@ -464,16 +529,16 @@ CreateEnrollmentManager(); enrollment_manager()->Start(); fake_enrollment_scheduler()->RequestEnrollmentNow(); - fake_gcm_manager()->CompleteRegistration(cryptauthv2::kTestGcmRegistrationId); + CompleteGcmRegistration(true /* success */); // Timeout waiting for ClientAppMetadata. EXPECT_TRUE(mock_timer()->IsRunning()); mock_timer()->Fire(); - VerifyEnrollmentResult( - CryptAuthEnrollmentResult(CryptAuthEnrollmentResult::ResultCode:: - kErrorTimeoutWaitingForClientAppMetadata, - base::nullopt /* client_directive */)); + VerifyEnrollmentResults( + {CryptAuthEnrollmentResult(CryptAuthEnrollmentResult::ResultCode:: + kErrorTimeoutWaitingForClientAppMetadata, + base::nullopt /* client_directive */)}); } TEST_F(DeviceSyncCryptAuthV2EnrollmentManagerImplTest, ForcedEnrollment) { @@ -487,15 +552,17 @@ 1 /* expected_num_enrollment_started_notifications */); // Simulate a failed enrollment attempt due to CryptAuth server overload. - fake_gcm_manager()->CompleteRegistration(cryptauthv2::kTestGcmRegistrationId); - std::move( - fake_client_app_metadata_provider()->metadata_requests()[0].callback) - .Run(cryptauthv2::GetClientAppMetadataForTest()); + CompleteGcmRegistration(true /* success */); + HandleGetClientAppMetadataRequest(true /* success */); CryptAuthEnrollmentResult expected_enrollment_result( CryptAuthEnrollmentResult::ResultCode::kErrorCryptAuthServerOverloaded, base::nullopt /* client_directive */); - fake_enroller()->FinishAttempt(expected_enrollment_result); - VerifyEnrollmentResult(expected_enrollment_result); + FinishEnrollmentAttempt(0u /* expected_enroller_instance_index */, + cryptauthv2::ClientMetadata:: + FEATURE_TOGGLED /* expected_invocation_reason */, + expected_enrollment_result); + + VerifyEnrollmentResults({expected_enrollment_result}); } TEST_F(DeviceSyncCryptAuthV2EnrollmentManagerImplTest, @@ -504,52 +571,49 @@ enrollment_manager()->Start(); // The user has already enrolled and is due for a refresh. - base::Time expected_last_enrollment_time = kFakeLastEnrollmentTime; + base::Time expected_last_enrollment_time = test_clock()->Now(); fake_enrollment_scheduler()->set_last_successful_enrollment_time( expected_last_enrollment_time); fake_enrollment_scheduler()->set_refresh_period(kFakeRefreshPeriod); - test_clock()->SetNow(kFakeTimeAfterRefreshPeriod); + + // Set clock after refresh period. + test_clock()->SetNow(test_clock()->Now() + kFakeRefreshPeriod + + base::TimeDelta::FromSeconds(1)); + base::TimeDelta expected_time_to_next_attempt = base::TimeDelta::FromSeconds(0); fake_enrollment_scheduler()->set_time_to_next_enrollment_request( expected_time_to_next_attempt); - cryptauthv2::ClientMetadata::InvocationReason expected_invocation_reason = - cryptauthv2::ClientMetadata::PERIODIC; EXPECT_EQ(expected_last_enrollment_time, enrollment_manager()->GetLastEnrollmentTime()); EXPECT_FALSE(enrollment_manager()->IsEnrollmentValid()); EXPECT_EQ(expected_time_to_next_attempt, enrollment_manager()->GetTimeToNextAttempt()); - EXPECT_FALSE(enrollment_manager()->IsEnrollmentInProgress()); EXPECT_FALSE(enrollment_manager()->IsRecoveringFromFailure()); + cryptauthv2::ClientMetadata::InvocationReason expected_invocation_reason = + cryptauthv2::ClientMetadata::PERIODIC; + // First enrollment attempt fails. // Note: User does not yet have a GCM registration ID or ClientAppMetadata. fake_enrollment_scheduler()->RequestEnrollmentNow(); EXPECT_TRUE(enrollment_manager()->IsEnrollmentInProgress()); VerifyEnrollmentManagerObserversNotifiedOfStart( 1 /* expected_num_enrollment_started_notifications */); - fake_gcm_manager()->CompleteRegistration(cryptauthv2::kTestGcmRegistrationId); - std::move( - fake_client_app_metadata_provider()->metadata_requests()[0].callback) - .Run(cryptauthv2::GetClientAppMetadataForTest()); - EXPECT_EQ(cryptauthv2::BuildClientMetadata(0 /* retry_count */, - expected_invocation_reason) - .SerializeAsString(), - fake_enroller()->client_metadata()->SerializeAsString()); - CryptAuthEnrollmentResult expected_enrollment_result( + CompleteGcmRegistration(true /* success */); + HandleGetClientAppMetadataRequest(true /* success */); + + CryptAuthEnrollmentResult first_expected_enrollment_result( CryptAuthEnrollmentResult::ResultCode::kErrorCryptAuthServerOverloaded, base::nullopt /* client_directive */); - fake_enroller()->FinishAttempt(expected_enrollment_result); - EXPECT_FALSE(enrollment_manager()->IsEnrollmentInProgress()); - VerifyEnrollmentResult(expected_enrollment_result); - // The initial invocation reason is persisted for reuse in subsequent failure - // recovery attempts. - VerifyPersistedFailureRecoveryInvocationReason( - cryptauthv2::ClientMetadata::PERIODIC); + FinishEnrollmentAttempt(0u /* expected_enroller_instance_index */, + expected_invocation_reason, + first_expected_enrollment_result); + + EXPECT_EQ(kFakeRetryPeriod, enrollment_manager()->GetTimeToNextAttempt()); // Second (successful) enrollment attempt bypasses GCM registration and // ClientAppMetadata fetch because they were performed during the failed @@ -558,27 +622,18 @@ VerifyEnrollmentManagerObserversNotifiedOfStart( 2 /* expected_num_enrollment_started_notifications */); EXPECT_TRUE(enrollment_manager()->IsRecoveringFromFailure()); - expected_invocation_reason = cryptauthv2::ClientMetadata::PERIODIC; - EXPECT_EQ(cryptauthv2::kTestGcmRegistrationId, - fake_gcm_manager()->GetRegistrationId()); - EXPECT_EQ(1u, - fake_client_app_metadata_provider()->metadata_requests().size()); - EXPECT_EQ( - cryptauthv2::BuildClientMetadata(1 /* retry_count */, - expected_invocation_reason) - .SerializeAsString(), - fake_enroller(1u /* index */)->client_metadata()->SerializeAsString()); - expected_enrollment_result = CryptAuthEnrollmentResult( - CryptAuthEnrollmentResult::ResultCode::kSuccessNoNewKeysNeeded, - cryptauthv2::GetClientDirectiveForTest()); - fake_enroller(1u /* index */)->FinishAttempt(expected_enrollment_result); - VerifyEnrollmentResult(expected_enrollment_result); + CryptAuthEnrollmentResult second_expected_enrollment_result = + CryptAuthEnrollmentResult( + CryptAuthEnrollmentResult::ResultCode::kSuccessNoNewKeysNeeded, + cryptauthv2::GetClientDirectiveForTest()); - // The persisted invocation reason to be used for failure recovery is cleared - // after a successful enrollment attempt. - VerifyPersistedFailureRecoveryInvocationReason( - cryptauthv2::ClientMetadata::INVOCATION_REASON_UNSPECIFIED); + FinishEnrollmentAttempt(1u /* expected_enroller_instance_index */, + expected_invocation_reason, + second_expected_enrollment_result); + + VerifyEnrollmentResults( + {first_expected_enrollment_result, second_expected_enrollment_result}); EXPECT_EQ(test_clock()->Now(), enrollment_manager()->GetLastEnrollmentTime()); EXPECT_TRUE(enrollment_manager()->IsEnrollmentValid()); @@ -591,7 +646,7 @@ CreateEnrollmentManager(); enrollment_manager()->Start(); - fake_gcm_manager()->PushReenrollMessage(); + RequestEnrollmentThroughGcm(); EXPECT_TRUE(enrollment_manager()->IsEnrollmentInProgress()); } @@ -633,16 +688,7 @@ CryptAuthKeyBundle::Name::kUserKeyPair)); // A legacy v1 user key pair should overwrite any existing v2 user key pair - // when the enrollment manager is constructed. This can happen in the - // following rollback-->rollforward scenario: - // - User never enrolled with v1 - // - User enrolls with v2, storing v2 user key pair locally in key registry - // and in CryptAuth backend database - // - Chromium rolls back to v1 enrollment flow - // - User enrolls with v1, storing the v1 user key pair in prefs (not key - // registry) and overwriting the v2 key in the CryptAuth backend database - // - Chromium rolls forward to v2 enrollment flow, with different user key - // pairs stored in v1 prefs and the v2 key registry. + // when the enrollment manager is constructed. CreateEnrollmentManager(); EXPECT_EQ( @@ -668,6 +714,70 @@ EXPECT_EQ(kFakeV2PrivateKey, enrollment_manager()->GetUserPrivateKey()); } +TEST_F(DeviceSyncCryptAuthV2EnrollmentManagerImplTest, + MultipleEnrollmentAttempts) { + CreateEnrollmentManager(); + enrollment_manager()->Start(); + + std::vector<cryptauthv2::ClientMetadata::InvocationReason> + expected_invocation_reasons; + std::vector<CryptAuthEnrollmentResult> expected_enrollment_results; + + // Successfully enroll for the first time. + expected_invocation_reasons.push_back( + cryptauthv2::ClientMetadata::INITIALIZATION); + expected_enrollment_results.emplace_back( + CryptAuthEnrollmentResult::ResultCode::kSuccessNewKeysEnrolled, + cryptauthv2::GetClientDirectiveForTest()); + fake_enrollment_scheduler()->RequestEnrollmentNow(); + VerifyEnrollmentManagerObserversNotifiedOfStart( + 1 /* expected_num_enrollment_started_notifications */); + CompleteGcmRegistration(true /* success */); + HandleGetClientAppMetadataRequest(true /* success */); + FinishEnrollmentAttempt(0u /* expected_enroller_instance_index */, + expected_invocation_reasons.back(), + expected_enrollment_results.back()); + + // Fail periodic refresh twice due to overloaded CryptAuth server. + test_clock()->SetNow(test_clock()->Now() + kFakeRefreshPeriod + + base::TimeDelta::FromSeconds(1)); + expected_invocation_reasons.push_back(cryptauthv2::ClientMetadata::PERIODIC); + expected_enrollment_results.emplace_back( + CryptAuthEnrollmentResult::ResultCode::kErrorCryptAuthServerOverloaded, + cryptauthv2::GetClientDirectiveForTest()); + fake_enrollment_scheduler()->RequestEnrollmentNow(); + VerifyEnrollmentManagerObserversNotifiedOfStart( + 2 /* expected_num_enrollment_started_notifications */); + FinishEnrollmentAttempt(1u /* expected_enroller_instance_index */, + expected_invocation_reasons.back(), + expected_enrollment_results.back()); + + expected_invocation_reasons.push_back(cryptauthv2::ClientMetadata::PERIODIC); + expected_enrollment_results.emplace_back( + CryptAuthEnrollmentResult::ResultCode::kErrorCryptAuthServerOverloaded, + base::nullopt /* client_directive */); + fake_enrollment_scheduler()->RequestEnrollmentNow(); + VerifyEnrollmentManagerObserversNotifiedOfStart( + 3 /* expected_num_enrollment_started_notifications */); + FinishEnrollmentAttempt(2u /* expected_enroller_instance_index */, + expected_invocation_reasons.back(), + expected_enrollment_results.back()); + + // While waiting for retry, force a manual enrollment that succeeds. + expected_invocation_reasons.push_back(cryptauthv2::ClientMetadata::MANUAL); + expected_enrollment_results.emplace_back( + CryptAuthEnrollmentResult::ResultCode::kSuccessNoNewKeysNeeded, + base::nullopt /* client_directive */); + enrollment_manager()->ForceEnrollmentNow(cryptauth::INVOCATION_REASON_MANUAL); + VerifyEnrollmentManagerObserversNotifiedOfStart( + 4 /* expected_num_enrollment_started_notifications */); + FinishEnrollmentAttempt(3u /* expected_enroller_instance_index */, + expected_invocation_reasons.back(), + expected_enrollment_results.back()); + + VerifyEnrollmentResults(expected_enrollment_results); +} + } // namespace device_sync } // namespace chromeos
diff --git a/components/autofill/core/browser/suggestion_selection.cc b/components/autofill/core/browser/suggestion_selection.cc index 1a3f74b8..516899d 100644 --- a/components/autofill/core/browser/suggestion_selection.cc +++ b/components/autofill/core/browser/suggestion_selection.cc
@@ -105,7 +105,7 @@ // will be shown rather than 15084880800, 508 488 0800, or +15084880800 // for US phone numbers. if (base::FeatureList::IsEnabled( - autofill::features::kAutofillShowFullDisclosureLabel) && + autofill::features::kAutofillUseImprovedLabelDisambiguation) && AutofillType(AutofillType(server_field_type).GetStorableType()) .group() == PHONE_HOME) { value = base::UTF8ToUTF16(i18n::FormatPhoneNationallyForDisplay(
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index 03121ad..73a96419 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -180,10 +180,11 @@ "AutofillShowAutocompleteConsoleWarnings", base::FEATURE_DISABLED_BY_DEFAULT}; -// Controls whether suggestions' labels use the full disclosure format to -// display disambiguation information. -const base::Feature kAutofillShowFullDisclosureLabel{ - "AutofillShowFullDisclosureLabel", base::FEATURE_DISABLED_BY_DEFAULT}; +// Controls whether suggestions' labels use the improved label disambiguation +// format. +const base::Feature kAutofillUseImprovedLabelDisambiguation{ + "AutofillUseImprovedLabelDisambiguation", + base::FEATURE_DISABLED_BY_DEFAULT}; // Controls attaching the autofill type predictions to their respective // element in the DOM.
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h index 4e7fecf..d58a517 100644 --- a/components/autofill/core/common/autofill_features.h +++ b/components/autofill/core/common/autofill_features.h
@@ -54,7 +54,7 @@ extern const base::Feature kAutofillSettingsCardTypeSplit; extern const base::Feature kAutofillShowAllSuggestionsOnPrefilledForms; extern const base::Feature kAutofillShowAutocompleteConsoleWarnings; -extern const base::Feature kAutofillShowFullDisclosureLabel; +extern const base::Feature kAutofillUseImprovedLabelDisambiguation; extern const base::Feature kAutofillShowTypePredictions; extern const base::Feature kAutofillSkipComparingInferredLabels; extern const base::Feature kAutofillSuppressDisusedAddresses;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc index 6b0f30b3..a74d625f 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
@@ -122,16 +122,21 @@ RegisterDataReductionProxyFieldTrial(); } +bool DataReductionProxySettings::IsDataSaverEnabledByUser() const { + if (params::ShouldForceEnableDataReductionProxy()) + return true; + + if (spdy_proxy_auth_enabled_.GetPrefName().empty()) + return false; + return spdy_proxy_auth_enabled_.GetValue(); +} + bool DataReductionProxySettings::IsDataReductionProxyEnabled() const { if (base::FeatureList::IsEnabled(network::features::kNetworkService) && !params::IsEnabledWithNetworkService()) { return false; } - - if (spdy_proxy_auth_enabled_.GetPrefName().empty()) - return false; - return spdy_proxy_auth_enabled_.GetValue() || - params::ShouldForceEnableDataReductionProxy(); + return IsDataSaverEnabledByUser(); } bool DataReductionProxySettings::CanUseDataReductionProxy(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h index 16d8252..bff7336 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
@@ -98,6 +98,10 @@ const SyntheticFieldTrialRegistrationCallback& on_data_reduction_proxy_enabled); + // Returns true if DataSaver is enabled by checking only the prefs or forcing + // flag. Does not check any holdback experiments. + bool IsDataSaverEnabledByUser() const; + // Returns true if the proxy is enabled. bool IsDataReductionProxyEnabled() const;
diff --git a/components/dom_distiller/standalone/DEPS b/components/dom_distiller/standalone/DEPS index 5fa91387..ffbd1ead 100644 --- a/components/dom_distiller/standalone/DEPS +++ b/components/dom_distiller/standalone/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+components/dom_distiller/content", + "+components/keyed_service/core", "+content/public", "+content/shell", "+net",
diff --git a/components/dom_distiller/standalone/content_extractor_browsertest.cc b/components/dom_distiller/standalone/content_extractor_browsertest.cc index 6d7210f..d950b12 100644 --- a/components/dom_distiller/standalone/content_extractor_browsertest.cc +++ b/components/dom_distiller/standalone/content_extractor_browsertest.cc
@@ -30,6 +30,7 @@ #include "components/dom_distiller/core/proto/distilled_article.pb.h" #include "components/dom_distiller/core/proto/distilled_page.pb.h" #include "components/dom_distiller/core/task_tracker.h" +#include "components/keyed_service/core/simple_factory_key.h" #include "components/leveldb_proto/content/proto_database_provider_factory.h" #include "components/leveldb_proto/public/proto_database.h" #include "components/leveldb_proto/public/proto_database_provider.h" @@ -126,14 +127,19 @@ std::unique_ptr<DomDistillerService> CreateDomDistillerService( content::BrowserContext* context, + SimpleFactoryKey* key, const base::FilePath& db_path, const FileToUrlMap& file_to_url_map) { scoped_refptr<base::SequencedTaskRunner> background_task_runner = base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}); + // Setting up PrefService for DistilledPagePrefs. + sync_preferences::TestingPrefServiceSyncable* pref_service = + new sync_preferences::TestingPrefServiceSyncable(); + DistilledPagePrefs::RegisterProfilePrefs(pref_service->registry()); + auto* db_provider = - leveldb_proto::ProtoDatabaseProviderFactory::GetForBrowserContext( - context); + leveldb_proto::ProtoDatabaseProviderFactory::GetForKey(key, pref_service); // TODO(cjhopman): use an in-memory database instead of an on-disk one with // temporary directory. @@ -177,11 +183,6 @@ new TestDistillerFactoryImpl(std::move(distiller_url_fetcher_factory), options, file_to_url_map)); - // Setting up PrefService for DistilledPagePrefs. - sync_preferences::TestingPrefServiceSyncable* pref_service = - new sync_preferences::TestingPrefServiceSyncable(); - DistilledPagePrefs::RegisterProfilePrefs(pref_service->registry()); - return std::unique_ptr<DomDistillerService>(new DomDistillerService( std::move(dom_distiller_store), std::move(distiller_factory), std::move(distiller_page_factory), @@ -359,8 +360,9 @@ command_line, &file_to_url_map); content::BrowserContext* context = shell()->web_contents()->GetBrowserContext(); - service_ = - CreateDomDistillerService(context, db_dir_.GetPath(), file_to_url_map); + key_ = std::make_unique<SimpleFactoryKey>(context->GetPath()); + service_ = CreateDomDistillerService(context, key_.get(), db_dir_.GetPath(), + file_to_url_map); PumpQueue(); } @@ -435,6 +437,8 @@ size_t max_tasks_; size_t next_request_; + std::unique_ptr<SimpleFactoryKey> key_; + base::ScopedTempDir db_dir_; std::unique_ptr<net::ScopedDefaultHostResolverProc> mock_host_resolver_override_;
diff --git a/components/leveldb_proto/content/proto_database_provider_factory.cc b/components/leveldb_proto/content/proto_database_provider_factory.cc index dfdf057d..65c45c36 100644 --- a/components/leveldb_proto/content/proto_database_provider_factory.cc +++ b/components/leveldb_proto/content/proto_database_provider_factory.cc
@@ -4,38 +4,39 @@ #include "components/leveldb_proto/content/proto_database_provider_factory.h" -#include "base/files/file_path.h" #include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "base/no_destructor.h" +#include "components/keyed_service/core/simple_dependency_manager.h" +#include "components/keyed_service/core/simple_factory_key.h" #include "components/leveldb_proto/public/proto_database_provider.h" -#include "content/public/browser/browser_context.h" namespace leveldb_proto { // static ProtoDatabaseProviderFactory* ProtoDatabaseProviderFactory::GetInstance() { - return base::Singleton<ProtoDatabaseProviderFactory>::get(); + static base::NoDestructor<ProtoDatabaseProviderFactory> instance; + return instance.get(); } // static -leveldb_proto::ProtoDatabaseProvider* -ProtoDatabaseProviderFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<leveldb_proto::ProtoDatabaseProvider*>( - GetInstance()->GetServiceForBrowserContext(context, true)); +ProtoDatabaseProvider* ProtoDatabaseProviderFactory::GetForKey( + SimpleFactoryKey* key, + PrefService* prefs) { + return static_cast<ProtoDatabaseProvider*>( + GetInstance()->GetServiceForKey(key, prefs, true)); } ProtoDatabaseProviderFactory::ProtoDatabaseProviderFactory() - : BrowserContextKeyedServiceFactory( - "leveldb_proto::ProtoDatabaseProvider", - BrowserContextDependencyManager::GetInstance()) {} + : SimpleKeyedServiceFactory("leveldb_proto::ProtoDatabaseProvider", + SimpleDependencyManager::GetInstance()) {} ProtoDatabaseProviderFactory::~ProtoDatabaseProviderFactory() = default; -KeyedService* ProtoDatabaseProviderFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - base::FilePath profile_dir = context->GetPath(); - return leveldb_proto::ProtoDatabaseProvider::Create(profile_dir); +std::unique_ptr<KeyedService> +ProtoDatabaseProviderFactory::BuildServiceInstanceFor( + SimpleFactoryKey* key, + PrefService* prefs) const { + return std::make_unique<ProtoDatabaseProvider>(key->path()); } } // namespace leveldb_proto
diff --git a/components/leveldb_proto/content/proto_database_provider_factory.h b/components/leveldb_proto/content/proto_database_provider_factory.h index b83e692f..0126a39f 100644 --- a/components/leveldb_proto/content/proto_database_provider_factory.h +++ b/components/leveldb_proto/content/proto_database_provider_factory.h
@@ -5,12 +5,18 @@ #ifndef COMPONENTS_LEVELDB_PROTO_CONTENT_PROTO_DATABASE_PROVIDER_FACTORY_H_ #define COMPONENTS_LEVELDB_PROTO_CONTENT_PROTO_DATABASE_PROVIDER_FACTORY_H_ +#include <memory> + #include "base/macros.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" +#include "components/keyed_service/core/simple_keyed_service_factory.h" + +class KeyedService; +class PrefService; +class SimpleFactoryKey; namespace base { template <typename T> -struct DefaultSingletonTraits; +class NoDestructor; } // namespace base namespace leveldb_proto { @@ -18,25 +24,26 @@ // A factory for ProtoDatabaseProvider, a class that provides proto databases // stored in the appropriate directory for the current profile. -class ProtoDatabaseProviderFactory : public BrowserContextKeyedServiceFactory { +class ProtoDatabaseProviderFactory : public SimpleKeyedServiceFactory { public: // Returns singleton instance of ProtoDatabaseProviderFactory. static ProtoDatabaseProviderFactory* GetInstance(); - // Returns ProtoDatabaseProvider associated with |context|, so we can + // Returns ProtoDatabaseProvider associated with |key|, so we can // instantiate ProtoDatabases that use the appropriate profile directory. - static ProtoDatabaseProvider* GetForBrowserContext( - content::BrowserContext* context); + static ProtoDatabaseProvider* GetForKey(SimpleFactoryKey* key, + PrefService* prefs); private: - friend struct base::DefaultSingletonTraits<ProtoDatabaseProviderFactory>; + friend class base::NoDestructor<ProtoDatabaseProviderFactory>; ProtoDatabaseProviderFactory(); ~ProtoDatabaseProviderFactory() override; - // BrowserContextKeyedServiceFactory overrides: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; + // SimpleKeyedServiceFactory overrides: + std::unique_ptr<KeyedService> BuildServiceInstanceFor( + SimpleFactoryKey* key, + PrefService* prefs) const override; DISALLOW_COPY_AND_ASSIGN(ProtoDatabaseProviderFactory); };
diff --git a/components/leveldb_proto/internal/proto_database_impl_unittest.cc b/components/leveldb_proto/internal/proto_database_impl_unittest.cc index 43571a3..d8b413d 100644 --- a/components/leveldb_proto/internal/proto_database_impl_unittest.cc +++ b/components/leveldb_proto/internal/proto_database_impl_unittest.cc
@@ -177,8 +177,7 @@ db_type, db_dir, task_runner, std::move(db_provider)); } - void GetDbAndWait(leveldb_proto::ProtoDatabaseProvider* db_provider, - leveldb_proto::ProtoDbType db_type) { + void GetDbAndWait(ProtoDatabaseProvider* db_provider, ProtoDbType db_type) { base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); @@ -189,9 +188,9 @@ // Initialize a database, it should succeed. db->Init(base::BindOnce( - [](base::OnceClosure closure, leveldb_proto::Enums::InitStatus status) { + [](base::OnceClosure closure, Enums::InitStatus status) { std::move(closure).Run(); - EXPECT_TRUE(status == leveldb_proto::Enums::InitStatus::kOK); + EXPECT_TRUE(status == Enums::InitStatus::kOK); }, run_init.QuitClosure())); @@ -232,8 +231,8 @@ const std::string& client_name, bool use_shared_db, Callbacks::InitStatusCallback callback) { - db_impl->InitInternal(client_name, leveldb_proto::CreateSimpleOptions(), - use_shared_db, std::move(callback)); + db_impl->InitInternal(client_name, CreateSimpleOptions(), use_shared_db, + std::move(callback)); } void InitDBImplAndWait(ProtoDatabaseImpl<TestProto, T>* db_impl, @@ -948,7 +947,7 @@ this->CreateSharedProvider(db_provider.get())); base::RunLoop run_init; - auto options = leveldb_proto::CreateSimpleOptions(); + auto options = CreateSimpleOptions(); options.create_if_missing = false; // Initialize database with unique DB arguments, it should fail because we @@ -975,13 +974,13 @@ {"migrate_TestDatabase1", "false"}, {"migrate_TestDatabase2", "false"}}; this->SetUpExperimentParams(experiment_params); - leveldb_proto::ProtoDatabaseProvider* db_provider = - leveldb_proto::ProtoDatabaseProvider::Create(temp_dir_profile.GetPath()); + auto db_provider = + std::make_unique<ProtoDatabaseProvider>(temp_dir_profile.GetPath()); // Initialize a database, it should succeed. - this->GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE1); + this->GetDbAndWait(db_provider.get(), ProtoDbType::TEST_DATABASE1); // Initialize a second database, it should also succeed. - this->GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE2); + this->GetDbAndWait(db_provider.get(), ProtoDbType::TEST_DATABASE2); } TYPED_TEST(ProtoDatabaseImplTest, InitUniqueThenSharedShouldSucceed) { @@ -993,13 +992,13 @@ {"migrate_TestDatabase1", "false"}, {"migrate_TestDatabase2", "true"}}; this->SetUpExperimentParams(experiment_params); - leveldb_proto::ProtoDatabaseProvider* db_provider = - leveldb_proto::ProtoDatabaseProvider::Create(temp_dir_profile.GetPath()); + auto db_provider = + std::make_unique<ProtoDatabaseProvider>(temp_dir_profile.GetPath()); // Initialize a database, it should succeed. - this->GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE1); + this->GetDbAndWait(db_provider.get(), ProtoDbType::TEST_DATABASE1); // Initialize a second database, it should also succeed. - this->GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE2); + this->GetDbAndWait(db_provider.get(), ProtoDbType::TEST_DATABASE2); } TYPED_TEST(ProtoDatabaseImplTest, InitSharedThenUniqueShouldSucceed) { @@ -1011,13 +1010,13 @@ {"migrate_TestDatabase1", "true"}, {"migrate_TestDatabase2", "false"}}; this->SetUpExperimentParams(experiment_params); - leveldb_proto::ProtoDatabaseProvider* db_provider = - leveldb_proto::ProtoDatabaseProvider::Create(temp_dir_profile.GetPath()); + auto db_provider = + std::make_unique<ProtoDatabaseProvider>(temp_dir_profile.GetPath()); // Initialize a database, it should succeed. - this->GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE1); + this->GetDbAndWait(db_provider.get(), ProtoDbType::TEST_DATABASE1); // Initialize a second database, it should also succeed. - this->GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE2); + this->GetDbAndWait(db_provider.get(), ProtoDbType::TEST_DATABASE2); } TYPED_TEST(ProtoDatabaseImplTest, InitSharedTwiceShouldSucceed) { @@ -1029,13 +1028,13 @@ {"migrate_TestDatabase1", "true"}, {"migrate_TestDatabase2", "true"}}; this->SetUpExperimentParams(experiment_params); - leveldb_proto::ProtoDatabaseProvider* db_provider = - leveldb_proto::ProtoDatabaseProvider::Create(temp_dir_profile.GetPath()); + auto db_provider = + std::make_unique<ProtoDatabaseProvider>(temp_dir_profile.GetPath()); // Initialize a database, it should succeed. - this->GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE1); + this->GetDbAndWait(db_provider.get(), ProtoDbType::TEST_DATABASE1); // Initialize a second database, it should also succeed. - this->GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE2); + this->GetDbAndWait(db_provider.get(), ProtoDbType::TEST_DATABASE2); } } // namespace leveldb_proto
diff --git a/components/leveldb_proto/public/proto_database_provider.cc b/components/leveldb_proto/public/proto_database_provider.cc index 0ce62bc..c8059f5 100644 --- a/components/leveldb_proto/public/proto_database_provider.cc +++ b/components/leveldb_proto/public/proto_database_provider.cc
@@ -4,8 +4,11 @@ #include "components/leveldb_proto/public/proto_database_provider.h" +#include <memory> + #include "base/bind.h" #include "base/files/file_path.h" +#include "base/memory/ptr_util.h" #include "base/sequenced_task_runner.h" #include "base/synchronization/lock.h" #include "base/task/post_task.h" @@ -31,12 +34,6 @@ ProtoDatabaseProvider::~ProtoDatabaseProvider() = default; -// static -ProtoDatabaseProvider* ProtoDatabaseProvider::Create( - const base::FilePath& profile_dir) { - return new ProtoDatabaseProvider(profile_dir); -} - void ProtoDatabaseProvider::GetSharedDBInstance( GetSharedDBInstanceCallback callback, scoped_refptr<base::SequencedTaskRunner> callback_task_runner) {
diff --git a/components/leveldb_proto/public/proto_database_provider.h b/components/leveldb_proto/public/proto_database_provider.h index f80a6a6..82e4b04 100644 --- a/components/leveldb_proto/public/proto_database_provider.h +++ b/components/leveldb_proto/public/proto_database_provider.h
@@ -26,14 +26,16 @@ using GetSharedDBInstanceCallback = base::OnceCallback<void(scoped_refptr<SharedProtoDatabase>)>; - static ProtoDatabaseProvider* Create(const base::FilePath& profile_dir); - template <typename P, typename T = P> static std::unique_ptr<ProtoDatabase<P, T>> CreateUniqueDB( const scoped_refptr<base::SequencedTaskRunner>& task_runner) { return std::make_unique<ProtoDatabaseImpl<P, T>>(task_runner); } + // Do not create this directly, instead use the ProtoDatabaseProviderFactory + // for the embedder to ensure there's only one per context. + ProtoDatabaseProvider(const base::FilePath& profile_dir); + // |db_type|: Each database should have a type specified in ProtoDbType enum. // This type is used to index data in the shared database. |unique_db_dir|: // the subdirectory this database should live in within the profile directory. @@ -57,8 +59,6 @@ template <typename T_> friend class ProtoDatabaseImplTest; - ProtoDatabaseProvider(const base::FilePath& profile_dir); - base::FilePath profile_dir_; scoped_refptr<SharedProtoDatabase> db_; base::Lock get_db_lock_;
diff --git a/components/module_installer/android/java/src-common/org/chromium/components/module_installer/Module.java b/components/module_installer/android/java/src-common/org/chromium/components/module_installer/Module.java index 6cfb667..fd7a492f 100644 --- a/components/module_installer/android/java/src-common/org/chromium/components/module_installer/Module.java +++ b/components/module_installer/android/java/src-common/org/chromium/components/module_installer/Module.java
@@ -18,6 +18,7 @@ * @param <T> The interface of the module/ */ public class Module<T> { + private static final Set<String> sInstantiatedModuleNames = new HashSet<>(); private static final Set<String> sModulesUninstalledForTesting = new HashSet<>(); private final String mName; private final Class<T> mInterfaceClass; @@ -27,8 +28,9 @@ /** Forces a module to appear uninstalled. */ @VisibleForTesting public static void setForceUninstalled(String moduleName) { - // TODO(crbug.com/944223): Make sure that this is not set after the module API has been - // used. + // We should not be uninstalling anything after the module API has been used for a + // particular module. + assert !sInstantiatedModuleNames.contains(moduleName); sModulesUninstalledForTesting.add(moduleName); } @@ -44,6 +46,7 @@ mName = name; mInterfaceClass = interfaceClass; mImplClassName = implClassName; + sInstantiatedModuleNames.add(name); } /** Returns true if the module is currently installed and can be accessed. */
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc index f2b1f56..f8e7987 100644 --- a/components/omnibox/browser/autocomplete_match.cc +++ b/components/omnibox/browser/autocomplete_match.cc
@@ -101,18 +101,7 @@ const char AutocompleteMatch::kEllipsis[] = "... "; AutocompleteMatch::AutocompleteMatch() - : provider(nullptr), - relevance(0), - typed_count(-1), - deletable(false), - allowed_to_be_default_match(false), - document_type(DocumentType::NONE), - swap_contents_and_description(false), - transition(ui::PAGE_TRANSITION_GENERATED), - type(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED), - has_tab_match(false), - subtype_identifier(0), - from_previous(false) {} + : transition(ui::PAGE_TRANSITION_GENERATED) {} AutocompleteMatch::AutocompleteMatch(AutocompleteProvider* provider, int relevance, @@ -120,16 +109,9 @@ Type type) : provider(provider), relevance(relevance), - typed_count(-1), deletable(deletable), - allowed_to_be_default_match(false), - document_type(DocumentType::NONE), - swap_contents_and_description(false), transition(ui::PAGE_TRANSITION_TYPED), - type(type), - has_tab_match(false), - subtype_identifier(0), - from_previous(false) {} + type(type) {} AutocompleteMatch::AutocompleteMatch(const AutocompleteMatch& match) : provider(match.provider), @@ -159,6 +141,7 @@ ? new AutocompleteMatch(*match.associated_keyword) : nullptr), keyword(match.keyword), + from_keyword(match.from_keyword), pedal(match.pedal), from_previous(match.from_previous), search_terms_args( @@ -207,6 +190,7 @@ ? new AutocompleteMatch(*match.associated_keyword) : nullptr); keyword = match.keyword; + from_keyword = match.from_keyword; pedal = match.pedal; from_previous = match.from_previous; search_terms_args.reset( @@ -801,11 +785,11 @@ res += base::trace_event::EstimateMemoryUsage(stripped_destination_url); res += base::trace_event::EstimateMemoryUsage(image_dominant_color); res += base::trace_event::EstimateMemoryUsage(image_url); + res += base::trace_event::EstimateMemoryUsage(tail_suggest_common_prefix); res += base::trace_event::EstimateMemoryUsage(contents); res += base::trace_event::EstimateMemoryUsage(contents_class); res += base::trace_event::EstimateMemoryUsage(description); res += base::trace_event::EstimateMemoryUsage(description_class); - res += sizeof(int); if (answer) res += base::trace_event::EstimateMemoryUsage(answer.value()); else @@ -813,6 +797,7 @@ res += base::trace_event::EstimateMemoryUsage(associated_keyword); res += base::trace_event::EstimateMemoryUsage(keyword); res += base::trace_event::EstimateMemoryUsage(search_terms_args); + res += base::trace_event::EstimateMemoryUsage(post_content); res += base::trace_event::EstimateMemoryUsage(additional_info); res += base::trace_event::EstimateMemoryUsage(duplicate_matches);
diff --git a/components/omnibox/browser/autocomplete_match.h b/components/omnibox/browser/autocomplete_match.h index 587bd2d..2a560d3 100644 --- a/components/omnibox/browser/autocomplete_match.h +++ b/components/omnibox/browser/autocomplete_match.h
@@ -382,7 +382,7 @@ // The provider of this match, used to remember which provider the user had // selected when the input changes. This may be NULL, in which case there is // no provider (or memory of the user's selection). - AutocompleteProvider* provider; + AutocompleteProvider* provider = nullptr; // The relevance of this match. See table in autocomplete.h for scores // returned by various providers. This is used to rank matches among all @@ -391,16 +391,16 @@ // // TODO(pkasting): http://b/1111299 This should be calculated algorithmically, // rather than being a fairly fixed value defined by the table above. - int relevance; + int relevance = 0; // How many times this result was typed in / selected from the omnibox. // Only set for some providers and result_types. If it is not set, // its value is -1. At the time of writing this comment, it is only // set for matches from HistoryURL and HistoryQuickProvider. - int typed_count; + int typed_count = -1; // True if the user should be able to delete this match. - bool deletable; + bool deletable = false; // This string is loaded into the location bar when the item is selected // by pressing the arrow keys. This may be different than a URL, for example, @@ -420,7 +420,7 @@ // should only set this flag if ".com" will be inline autocompleted; // and a navigation to "foo/" (an intranet host) or search for "foo" // should set this flag. - bool allowed_to_be_default_match; + bool allowed_to_be_default_match = false; // The URL to actually load when the autocomplete item is selected. This URL // should be canonical so we can compare URLs with strcmp to avoid dupes. @@ -438,7 +438,7 @@ std::string image_url; // Optional override to use for types that specify an icon sub-type. - DocumentType document_type; + DocumentType document_type = DocumentType::NONE; // Holds the common part of tail suggestion. base::string16 tail_suggest_common_prefix; @@ -453,7 +453,7 @@ // If true, UI-level code should swap the contents and description fields // before displaying. - bool swap_contents_and_description; + bool swap_contents_and_description = false; // A rich-format version of the display for the dropdown. base::Optional<SuggestionAnswer> answer; @@ -461,19 +461,19 @@ // The transition type to use when the user opens this match. By default // this is TYPED. Providers whose matches do not look like URLs should set // it to GENERATED. - ui::PageTransition transition; + ui::PageTransition transition = ui::PAGE_TRANSITION_TYPED; // Type of this match. - Type type; + Type type = AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED; // True if we saw a tab that matched this suggestion. - bool has_tab_match; + bool has_tab_match = false; // Used to identify the specific source / type for suggestions by the // suggest server. See |result_subtype_identifier| in omnibox.proto for more // details. // The identifier 0 is reserved for cases where this specific type is unset. - int subtype_identifier; + int subtype_identifier = 0; // Set with a keyword provider match if this match can show a keyword hint. // For example, if this is a SearchProvider match for "www.amazon.com", @@ -499,14 +499,14 @@ base::string16 keyword; // Set in matches originating from keyword results. - bool from_keyword; + bool from_keyword = false; // Set to a matching pedal if appropriate. The pedal is not owned, and the // owning OmniboxPedalProvider must outlive this. OmniboxPedal* pedal = nullptr; // True if this match is from a previous result. - bool from_previous; + bool from_previous = false; // Optional search terms args. If present, // AutocompleteController::UpdateAssistedQueryStats() will incorporate this
diff --git a/components/omnibox/browser/omnibox_view.cc b/components/omnibox/browser/omnibox_view.cc index a33ce6b..7ea1a21f3 100644 --- a/components/omnibox/browser/omnibox_view.cc +++ b/components/omnibox/browser/omnibox_view.cc
@@ -281,6 +281,11 @@ const base::string16& display_text, const bool text_is_url, const AutocompleteSchemeClassifier& classifier) { + if (!text_is_url) { + SetEmphasis(true, gfx::Range::InvalidRange()); + return false; // Path not eligible for fading if it's not even a URL. + } + enum DemphasizeComponents { EVERYTHING, ALL_BUT_SCHEME, @@ -292,21 +297,19 @@ AutocompleteInput::ParseForEmphasizeComponents(display_text, classifier, &scheme, &host); - if (text_is_url) { - const base::string16 url_scheme = - display_text.substr(scheme.begin, scheme.len); - // Extension IDs are not human-readable, so deemphasize everything to draw - // attention to the human-readable name in the location icon text. - // Data URLs are rarely human-readable and can be used for spoofing, so draw - // attention to the scheme to emphasize "this is just a bunch of data". - // For normal URLs, the host is the best proxy for "identity". - if (url_scheme == base::UTF8ToUTF16(extensions::kExtensionScheme)) - deemphasize = EVERYTHING; - else if (url_scheme == base::UTF8ToUTF16(url::kDataScheme)) - deemphasize = ALL_BUT_SCHEME; - else if (host.is_nonempty()) - deemphasize = ALL_BUT_HOST; - } + const base::string16 url_scheme = + display_text.substr(scheme.begin, scheme.len); + // Extension IDs are not human-readable, so deemphasize everything to draw + // attention to the human-readable name in the location icon text. + // Data URLs are rarely human-readable and can be used for spoofing, so draw + // attention to the scheme to emphasize "this is just a bunch of data". + // For normal URLs, the host is the best proxy for "identity". + if (url_scheme == base::UTF8ToUTF16(extensions::kExtensionScheme)) + deemphasize = EVERYTHING; + else if (url_scheme == base::UTF8ToUTF16(url::kDataScheme)) + deemphasize = ALL_BUT_SCHEME; + else if (host.is_nonempty()) + deemphasize = ALL_BUT_HOST; gfx::Range scheme_range = scheme.is_nonempty() ? gfx::Range(scheme.begin, scheme.end())
diff --git a/components/policy/core/common/policy_map.cc b/components/policy/core/common/policy_map.cc index 7e94ec9e..fdd23ba5 100644 --- a/components/policy/core/common/policy_map.cc +++ b/components/policy/core/common/policy_map.cc
@@ -228,26 +228,33 @@ void PolicyMap::MergeFrom(const PolicyMap& other) { for (const auto& it : other) { - const Entry* entry = GetUntrusted(it.first); - bool same_value = false; - if (!entry) { - Set(it.first, it.second.DeepCopy()); - } else { - same_value = entry->value && it.second.value->Equals(entry->value.get()); - if (it.second.has_higher_priority_than(*entry)) { - auto new_policy = it.second.DeepCopy(); - new_policy.AddConflictingPolicy(*entry); - Set(it.first, std::move(new_policy)); - } else { - GetMutableUntrusted(it.first)->AddConflictingPolicy(it.second); - } + Entry* current_policy = GetMutableUntrusted(it.first); + auto other_policy = it.second.DeepCopy(); + + if (!current_policy) { + Set(it.first, std::move(other_policy)); + continue; } - if (entry) { - GetMutableUntrusted(it.first)->AddError( - same_value ? IDS_POLICY_CONFLICT_SAME_VALUE - : IDS_POLICY_CONFLICT_DIFF_VALUE); + auto& new_policy = other_policy.has_higher_priority_than(*current_policy) + ? other_policy + : *current_policy; + auto& conflict = + current_policy == &new_policy ? other_policy : *current_policy; + + bool overwriting_default_policy = + new_policy.source != conflict.source && + conflict.source == POLICY_SOURCE_ENTERPRISE_DEFAULT; + if (!overwriting_default_policy) { + new_policy.AddConflictingPolicy(conflict); + new_policy.AddError((current_policy->value && + it.second.value->Equals(current_policy->value.get())) + ? IDS_POLICY_CONFLICT_SAME_VALUE + : IDS_POLICY_CONFLICT_DIFF_VALUE); } + + if (current_policy != &new_policy) + Set(it.first, std::move(new_policy)); } } @@ -317,7 +324,8 @@ // static bool PolicyMap::MapEntryEquals(const PolicyMap::PolicyMapType::value_type& a, const PolicyMap::PolicyMapType::value_type& b) { - return a.first == b.first && a.second.Equals(b.second); + bool equals = a.first == b.first && a.second.Equals(b.second); + return equals; } void PolicyMap::FilterErase(
diff --git a/components/policy/core/common/policy_map_unittest.cc b/components/policy/core/common/policy_map_unittest.cc index 62937285..7b72c1a 100644 --- a/components/policy/core/common/policy_map_unittest.cc +++ b/components/policy/core/common/policy_map_unittest.cc
@@ -242,7 +242,6 @@ auto conflicted_policy_1 = a.Get(kTestPolicyName1)->DeepCopy(); auto conflicted_policy_4 = a.Get(kTestPolicyName4)->DeepCopy(); auto conflicted_policy_5 = a.Get(kTestPolicyName5)->DeepCopy(); - auto conflicted_policy_7 = a.Get(kTestPolicyName7)->DeepCopy(); auto conflicted_policy_8 = b.Get(kTestPolicyName8)->DeepCopy(); a.GetMutable(kTestPolicyName7)->SetBlocked(); @@ -287,8 +286,6 @@ c.Set(kTestPolicyName7, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_ACTIVE_DIRECTORY, std::make_unique<base::Value>(true), nullptr); - c.GetMutable(kTestPolicyName7)->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE); - c.GetMutable(kTestPolicyName7)->AddConflictingPolicy(conflicted_policy_7); c.GetMutable(kTestPolicyName7)->SetBlocked(); c.Set(kTestPolicyName8, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
diff --git a/components/previews/core/previews_experiments_unittest.cc b/components/previews/core/previews_experiments_unittest.cc index 144061e..3274188 100644 --- a/components/previews/core/previews_experiments_unittest.cc +++ b/components/previews/core/previews_experiments_unittest.cc
@@ -101,20 +101,10 @@ variations::testing::ClearAllVariationParams(); } -#if defined(OS_ANDROID) - -TEST(PreviewsExperimentsTest, TestClientLoFiEnabledByDefaultOnAndroid) { - EXPECT_TRUE(params::IsClientLoFiEnabled()); -} - -#else // !defined(OS_ANDROID) - -TEST(PreviewsExperimentsTest, TestClientLoFiDisabledByDefaultOnNonAndroid) { +TEST(PreviewsExperimentsTest, TestClientLoFiDisabledByDefault) { EXPECT_FALSE(params::IsClientLoFiEnabled()); } -#endif // defined(OS_ANDROID) - TEST(PreviewsExperimentsTest, TestClientLoFiExplicitlyDisabled) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndDisableFeature(features::kClientLoFi);
diff --git a/components/previews/core/previews_features.cc b/components/previews/core/previews_features.cc index 8fe59cfa..4514930a 100644 --- a/components/previews/core/previews_features.cc +++ b/components/previews/core/previews_features.cc
@@ -27,14 +27,8 @@ base::FEATURE_ENABLED_BY_DEFAULT}; // Enables the Client Lo-Fi previews. -const base::Feature kClientLoFi { - "ClientLoFi", -#if defined(OS_ANDROID) - base::FEATURE_ENABLED_BY_DEFAULT -#else // !defined(OS_ANDROID) - base::FEATURE_DISABLED_BY_DEFAULT -#endif // defined(OS_ANDROID) -}; +const base::Feature kClientLoFi{"ClientLoFi", + base::FEATURE_DISABLED_BY_DEFAULT}; // Enables the NoScript previews for Android. const base::Feature kNoScriptPreviews {
diff --git a/components/renderer_context_menu/views/toolkit_delegate_views.cc b/components/renderer_context_menu/views/toolkit_delegate_views.cc index a3a1698..2b90b13 100644 --- a/components/renderer_context_menu/views/toolkit_delegate_views.cc +++ b/components/renderer_context_menu/views/toolkit_delegate_views.cc
@@ -18,11 +18,11 @@ void ToolkitDelegateViews::RunMenuAt(views::Widget* parent, const gfx::Point& point, ui::MenuSourceType type) { - views::MenuAnchorPosition anchor_position = - (type == ui::MENU_SOURCE_TOUCH || - type == ui::MENU_SOURCE_TOUCH_EDIT_MENU) - ? views::MENU_ANCHOR_BOTTOMCENTER - : views::MENU_ANCHOR_TOPLEFT; + using Position = views::MenuAnchorPosition; + Position anchor_position = + (type == ui::MENU_SOURCE_TOUCH || type == ui::MENU_SOURCE_TOUCH_EDIT_MENU) + ? Position::kBottomCenter + : Position::kTopLeft; menu_runner_->RunMenuAt(parent, nullptr, gfx::Rect(point, gfx::Size()), anchor_position, type); }
diff --git a/components/send_tab_to_self/BUILD.gn b/components/send_tab_to_self/BUILD.gn index c9da2de7..1569e3b 100644 --- a/components/send_tab_to_self/BUILD.gn +++ b/components/send_tab_to_self/BUILD.gn
@@ -4,6 +4,8 @@ static_library("send_tab_to_self") { sources = [ + "features.cc", + "features.h", "send_tab_to_self_bridge.cc", "send_tab_to_self_bridge.h", "send_tab_to_self_entry.cc",
diff --git a/components/send_tab_to_self/features.cc b/components/send_tab_to_self/features.cc new file mode 100644 index 0000000..4db29f6 --- /dev/null +++ b/components/send_tab_to_self/features.cc
@@ -0,0 +1,12 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/send_tab_to_self/features.h" + +namespace send_tab_to_self { + +const base::Feature kSendTabToSelfReceive{"SendTabToSelfReceive", + base::FEATURE_DISABLED_BY_DEFAULT}; + +} // namespace send_tab_to_self
diff --git a/components/send_tab_to_self/features.h b/components/send_tab_to_self/features.h new file mode 100644 index 0000000..56c9723 --- /dev/null +++ b/components/send_tab_to_self/features.h
@@ -0,0 +1,17 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SEND_TAB_TO_SELF_FEATURES_H_ +#define COMPONENTS_SEND_TAB_TO_SELF_FEATURES_H_ + +#include "base/feature_list.h" + +namespace send_tab_to_self { + +// If this feature is enabled, we handle notifying users of sent tabs even if +// the sync feature is disabled. +extern const base::Feature kSendTabToSelfReceive; +} // namespace send_tab_to_self + +#endif // COMPONENTS_SEND_TAB_TO_SELF_FEATURES_H_
diff --git a/components/signin/core/browser/signin_investigator.cc b/components/signin/core/browser/signin_investigator.cc index ac8f2d8..7dc1236e 100644 --- a/components/signin/core/browser/signin_investigator.cc +++ b/components/signin/core/browser/signin_investigator.cc
@@ -17,7 +17,7 @@ void LogSigninScenario(InvestigatedScenario scenario) { UMA_HISTOGRAM_ENUMERATION( "Signin.InvestigatedScenario", static_cast<int>(scenario), - static_cast<int>(InvestigatedScenario::HISTOGRAM_COUNT)); + static_cast<int>(InvestigatedScenario::NUM_ENTRIES)); } } // namespace
diff --git a/components/signin/core/browser/signin_investigator.h b/components/signin/core/browser/signin_investigator.h index a4a8585..ce40682b 100644 --- a/components/signin/core/browser/signin_investigator.h +++ b/components/signin/core/browser/signin_investigator.h
@@ -26,7 +26,7 @@ // of local syncable data. DIFFERENT_ACCOUNT, // Always the last enumerated type. - HISTOGRAM_COUNT, + NUM_ENTRIES, }; // Performs various checks with the current account being used to login in and
diff --git a/components/viz/common/quads/draw_quad.h b/components/viz/common/quads/draw_quad.h index 01de49e..ecc0ef4 100644 --- a/components/viz/common/quads/draw_quad.h +++ b/components/viz/common/quads/draw_quad.h
@@ -75,7 +75,8 @@ bool ShouldDrawWithBlending() const { return needs_blending || shared_quad_state->opacity < 1.0f || - shared_quad_state->blend_mode != SkBlendMode::kSrcOver; + shared_quad_state->blend_mode != SkBlendMode::kSrcOver || + !shared_quad_state->rounded_corner_bounds.IsEmpty(); } // Is the left edge of this tile aligned with the originating layer's
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index 9e0979a..aedd863 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc
@@ -186,6 +186,34 @@ return active_unit; } +bool ShouldUseRoundedCornerShader(const DrawQuad* quad) { + const SharedQuadState* sqs = quad->shared_quad_state; + const gfx::RRectF& rounded_corner_bounds = sqs->rounded_corner_bounds; + + // There is no rounded corner set. + if (rounded_corner_bounds.IsEmpty()) + return false; + + const gfx::RectF target_quad = cc::MathUtil::MapClippedRect( + sqs->quad_to_target_transform, gfx::RectF(quad->visible_rect)); + + // If the rounded corner rect intersects with the quad, then we should run the + // fragment shader. + if (rounded_corner_bounds.rect().Intersects(target_quad)) + return true; + + // If the quad is not within the rounded corner bounds, neither does it + // intersect, we do not have to apply any rounded corner on it. + if (!rounded_corner_bounds.rect().Contains(target_quad)) + return false; + + // If the rounded corner bounding rect contains the quad but the rounded + // corner rrect does not, it means there is an intersection. Apply rounded + // corner on the quad. + SkRRect rrect = static_cast<SkRRect>(rounded_corner_bounds); + return !rrect.contains(gfx::RectFToSkRect(target_quad)); +} + // Parameters needed to draw a RenderPassDrawQuad. struct GLRenderer::DrawRenderPassDrawQuadParams { DrawRenderPassDrawQuadParams() {} @@ -1296,9 +1324,10 @@ void GLRenderer::UpdateRPDQBlendMode(DrawRenderPassDrawQuadParams* params) { SkBlendMode blend_mode = params->quad->shared_quad_state->blend_mode; - SetBlendEnabled(!params->use_shaders_for_blending && - (params->quad->ShouldDrawWithBlending() || - !IsDefaultBlendMode(blend_mode))); + SetBlendEnabled((!params->use_shaders_for_blending && + (params->quad->ShouldDrawWithBlending() || + !IsDefaultBlendMode(blend_mode))) || + ShouldUseRoundedCornerShader(params->quad)); if (!params->use_shaders_for_blending) { if (!use_blend_equation_advanced_coherent_ && use_blend_equation_advanced_) gl_->BlendBarrierKHR(); @@ -1330,7 +1359,8 @@ ProgramKey::RenderPass( tex_coord_precision, sampler_type, shader_blend_mode, params->use_aa ? USE_AA : NO_AA, mask_mode, mask_for_background, - params->use_color_matrix, tint_gl_composited_content_), + params->use_color_matrix, tint_gl_composited_content_, + ShouldUseRoundedCornerShader(params->quad)), params->contents_and_bypass_color_space, target_color_space); } @@ -1467,6 +1497,8 @@ } SetShaderOpacity(params->quad->shared_quad_state->opacity); + SetShaderRoundedCorner(params->quad->shared_quad_state->rounded_corner_bounds, + params->window_matrix * params->projection_matrix); SetShaderQuadF(params->surface_quad); } @@ -1796,10 +1828,14 @@ gfx::ColorSpace quad_color_space = gfx::ColorSpace::CreateSRGB(); SetUseProgram(ProgramKey::SolidColor(use_aa ? USE_AA : NO_AA, - tint_gl_composited_content_), + tint_gl_composited_content_, + ShouldUseRoundedCornerShader(quad)), quad_color_space, current_frame()->current_render_pass->color_space); SetShaderColor(color, opacity); + SetShaderRoundedCorner( + quad->shared_quad_state->rounded_corner_bounds, + current_frame()->window_matrix * current_frame()->projection_matrix); if (current_program_->tint_color_matrix_location() != -1) { auto matrix = cc::DebugColors::TintCompositedContentColorTransformMatrix(); @@ -1947,7 +1983,8 @@ quad->swizzle_contents ? DO_SWIZZLE : NO_SWIZZLE, quad->is_premultiplied ? PREMULTIPLIED_ALPHA : NON_PREMULTIPLIED_ALPHA, - false, false, tint_gl_composited_content_), + false, false, tint_gl_composited_content_, + ShouldUseRoundedCornerShader(quad)), quad_resource_lock.color_space(), current_frame()->current_render_pass->color_space); @@ -1969,6 +2006,9 @@ // Blending is required for antialiasing. SetBlendEnabled(true); SetShaderOpacity(quad->shared_quad_state->opacity); + SetShaderRoundedCorner( + quad->shared_quad_state->rounded_corner_bounds, + current_frame()->window_matrix * current_frame()->projection_matrix); DCHECK(CanApplyBlendModeUsingBlendFunc(quad->shared_quad_state->blend_mode)); ApplyBlendModeUsingBlendFunc(quad->shared_quad_state->blend_mode); @@ -2039,7 +2079,8 @@ quad->is_premultiplied ? PREMULTIPLIED_ALPHA : NON_PREMULTIPLIED_ALPHA, !quad->ShouldDrawWithBlending(), has_tex_clamp_rect, - tint_gl_composited_content_), + tint_gl_composited_content_, + ShouldUseRoundedCornerShader(quad)), quad_resource_lock.color_space(), current_frame()->current_render_pass->color_space); @@ -2062,6 +2103,9 @@ ApplyBlendModeUsingBlendFunc(quad->shared_quad_state->blend_mode); SetShaderOpacity(quad->shared_quad_state->opacity); + SetShaderRoundedCorner( + quad->shared_quad_state->rounded_corner_bounds, + current_frame()->window_matrix * current_frame()->projection_matrix); // Pass quad coordinates to the uniform in the same order as GeometryBinding // does, then vertices will match the texture mapping in the vertex buffer. @@ -2171,7 +2215,8 @@ SetUseProgram( ProgramKey::YUVVideo(tex_coord_precision, sampler, alpha_texture_mode, - uv_texture_mode, tint_gl_composited_content_), + uv_texture_mode, tint_gl_composited_content_, + ShouldUseRoundedCornerShader(quad)), src_color_space, dst_color_space); if (current_program_->tint_color_matrix_location() != -1) { @@ -2286,7 +2331,8 @@ DisplayResourceProvider::ScopedReadLockGL lock(resource_provider_, quad->resource_id()); - SetUseProgram(ProgramKey::VideoStream(tex_coord_precision), + SetUseProgram(ProgramKey::VideoStream(tex_coord_precision, + ShouldUseRoundedCornerShader(quad)), lock.color_space(), current_frame()->current_render_pass->color_space); @@ -2441,13 +2487,18 @@ bool need_tex_clamp_rect = !quad->resource_size_in_pixels().IsEmpty() && (quad->uv_top_left != gfx::PointF(0, 0) || quad->uv_bottom_right != gfx::PointF(1, 1)); + ProgramKey program_key = ProgramKey::Texture( tex_coord_precision, sampler, quad->premultiplied_alpha ? PREMULTIPLIED_ALPHA : NON_PREMULTIPLIED_ALPHA, quad->background_color != SK_ColorTRANSPARENT, need_tex_clamp_rect, - tint_gl_composited_content_); + tint_gl_composited_content_, ShouldUseRoundedCornerShader(quad)); int resource_id = quad->resource_id(); + SetShaderRoundedCorner( + quad->shared_quad_state->rounded_corner_bounds, + current_frame()->window_matrix * current_frame()->projection_matrix); + size_t max_quads = StaticGeometryBinding::NUM_QUADS; if (draw_cache_.is_empty || draw_cache_.program_key != program_key || draw_cache_.resource_id != resource_id || @@ -2697,6 +2748,35 @@ blend_shadow_ = enabled; } +void GLRenderer::SetShaderRoundedCorner( + const gfx::RRectF& rounded_corner_bounds, + const gfx::Transform& screen_transform) { + if (!current_program_ || + current_program_->rounded_corner_rect_location() == -1 || + current_program_->rounded_corner_radius_location() == -1 || + rounded_corner_bounds.IsEmpty()) { + return; + } + + DCHECK(screen_transform.IsScaleOrTranslation()); + const gfx::Vector2dF& translate = screen_transform.To2dTranslation(); + const gfx::Vector2dF& scale = screen_transform.Scale2d(); + gfx::RRectF bounds_in_screen = rounded_corner_bounds; + bounds_in_screen.Scale(scale.x(), scale.y()); + bounds_in_screen.Offset(translate.x(), translate.y()); + + gfx::RectF rect = bounds_in_screen.rect(); + + gl_->Uniform4f(current_program_->rounded_corner_rect_location(), rect.x(), + rect.y(), rect.width(), rect.height()); + gl_->Uniform4f( + current_program_->rounded_corner_radius_location(), + bounds_in_screen.GetCornerRadii(gfx::RRectF::Corner::kUpperLeft).x(), + bounds_in_screen.GetCornerRadii(gfx::RRectF::Corner::kUpperRight).x(), + bounds_in_screen.GetCornerRadii(gfx::RRectF::Corner::kLowerRight).x(), + bounds_in_screen.GetCornerRadii(gfx::RRectF::Corner::kLowerLeft).x()); +} + void GLRenderer::DrawQuadGeometryClippedByQuadF( const gfx::Transform& draw_transform, const gfx::RectF& quad_rect,
diff --git a/components/viz/service/display/gl_renderer.h b/components/viz/service/display/gl_renderer.h index e1ab3200..40d97137 100644 --- a/components/viz/service/display/gl_renderer.h +++ b/components/viz/service/display/gl_renderer.h
@@ -261,6 +261,8 @@ void SetShaderQuadF(const gfx::QuadF& quad); void SetShaderMatrix(const gfx::Transform& transform); void SetShaderColor(SkColor color, float opacity); + void SetShaderRoundedCorner(const gfx::RRectF& rounded_corner_bounds, + const gfx::Transform& screen_transform); void DrawQuadGeometryClippedByQuadF(const gfx::Transform& draw_transform, const gfx::RectF& quad_rect, const gfx::QuadF& clipping_region_quad,
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc index 584ac05..41244c16 100644 --- a/components/viz/service/display/gl_renderer_unittest.cc +++ b/components/viz/service/display/gl_renderer_unittest.cc
@@ -217,15 +217,18 @@ void TestBasicShaders() { TestShader(ProgramKey::DebugBorder()); - TestShader(ProgramKey::SolidColor(NO_AA, false)); - TestShader(ProgramKey::SolidColor(USE_AA, false)); + TestShader(ProgramKey::SolidColor(NO_AA, false, false)); + TestShader(ProgramKey::SolidColor(USE_AA, false, false)); TestShadersWithOutputColorMatrix(ProgramKey::DebugBorder()); - TestShadersWithOutputColorMatrix(ProgramKey::SolidColor(NO_AA, false)); - TestShadersWithOutputColorMatrix(ProgramKey::SolidColor(USE_AA, false)); + TestShadersWithOutputColorMatrix( + ProgramKey::SolidColor(NO_AA, false, false)); + TestShadersWithOutputColorMatrix( + ProgramKey::SolidColor(USE_AA, false, false)); - TestShader(ProgramKey::SolidColor(NO_AA, true)); - TestShadersWithOutputColorMatrix(ProgramKey::SolidColor(NO_AA, true)); + TestShader(ProgramKey::SolidColor(NO_AA, true, false)); + TestShadersWithOutputColorMatrix( + ProgramKey::SolidColor(NO_AA, true, false)); } void TestColorShaders() { @@ -254,8 +257,8 @@ gfx::ColorSpace::CreateCustom(primaries, transfer_fns[i]); renderer()->SetCurrentFrameForTesting(GLRenderer::DrawingFrame()); - renderer()->SetUseProgram(ProgramKey::SolidColor(NO_AA, false), src, - gfx::ColorSpace::CreateXYZD50()); + renderer()->SetUseProgram(ProgramKey::SolidColor(NO_AA, false, false), + src, gfx::ColorSpace::CreateXYZD50()); EXPECT_TRUE(renderer()->current_program_->initialized()); } } @@ -264,77 +267,97 @@ // This program uses external textures and sampler, so it won't compile // everywhere. if (context_provider()->ContextCapabilities().egl_image_external) { - TestShader(ProgramKey::VideoStream(precision)); + TestShader(ProgramKey::VideoStream(precision, false)); } } void TestShadersWithPrecisionAndBlend(TexCoordPrecision precision, BlendMode blend_mode) { TestShader(ProgramKey::RenderPass(precision, SAMPLER_TYPE_2D, blend_mode, - NO_AA, NO_MASK, false, false, false)); + NO_AA, NO_MASK, false, false, false, + false)); TestShader(ProgramKey::RenderPass(precision, SAMPLER_TYPE_2D, blend_mode, - USE_AA, NO_MASK, false, false, false)); + USE_AA, NO_MASK, false, false, false, + false)); } void TestShadersWithPrecisionAndSampler(TexCoordPrecision precision, SamplerType sampler) { TestShader(ProgramKey::Texture(precision, sampler, PREMULTIPLIED_ALPHA, - false, true, false)); + false, true, false, false)); TestShader(ProgramKey::Texture(precision, sampler, PREMULTIPLIED_ALPHA, - false, false, false)); + false, false, false, false)); TestShader(ProgramKey::Texture(precision, sampler, PREMULTIPLIED_ALPHA, - true, true, false)); + true, true, false, false)); TestShader(ProgramKey::Texture(precision, sampler, PREMULTIPLIED_ALPHA, - true, false, false)); + true, false, false, false)); TestShader(ProgramKey::Texture(precision, sampler, NON_PREMULTIPLIED_ALPHA, - false, true, false)); + false, true, false, false)); TestShader(ProgramKey::Texture(precision, sampler, NON_PREMULTIPLIED_ALPHA, - false, false, false)); + false, false, false, false)); TestShader(ProgramKey::Texture(precision, sampler, NON_PREMULTIPLIED_ALPHA, - true, true, false)); + true, true, false, false)); TestShader(ProgramKey::Texture(precision, sampler, NON_PREMULTIPLIED_ALPHA, - true, false, false)); + true, false, false, false)); TestShader(ProgramKey::Tile(precision, sampler, USE_AA, NO_SWIZZLE, - PREMULTIPLIED_ALPHA, false, false, false)); + PREMULTIPLIED_ALPHA, false, false, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, USE_AA, DO_SWIZZLE, - PREMULTIPLIED_ALPHA, false, false, false)); + PREMULTIPLIED_ALPHA, false, false, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, - PREMULTIPLIED_ALPHA, false, false, false)); + PREMULTIPLIED_ALPHA, false, false, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, - PREMULTIPLIED_ALPHA, false, false, false)); + PREMULTIPLIED_ALPHA, false, false, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, - PREMULTIPLIED_ALPHA, true, false, false)); + PREMULTIPLIED_ALPHA, true, false, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, - PREMULTIPLIED_ALPHA, true, false, false)); + PREMULTIPLIED_ALPHA, true, false, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, - PREMULTIPLIED_ALPHA, false, true, false)); + PREMULTIPLIED_ALPHA, false, true, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, - PREMULTIPLIED_ALPHA, false, true, false)); + PREMULTIPLIED_ALPHA, false, true, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, - PREMULTIPLIED_ALPHA, true, true, false)); + PREMULTIPLIED_ALPHA, true, true, false, false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, - PREMULTIPLIED_ALPHA, true, true, false)); + PREMULTIPLIED_ALPHA, true, true, false, false)); TestShader(ProgramKey::Tile(precision, sampler, USE_AA, NO_SWIZZLE, - NON_PREMULTIPLIED_ALPHA, false, false, false)); + NON_PREMULTIPLIED_ALPHA, false, false, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, USE_AA, DO_SWIZZLE, - NON_PREMULTIPLIED_ALPHA, false, false, false)); + NON_PREMULTIPLIED_ALPHA, false, false, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, - NON_PREMULTIPLIED_ALPHA, false, false, false)); + NON_PREMULTIPLIED_ALPHA, false, false, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, - NON_PREMULTIPLIED_ALPHA, false, false, false)); + NON_PREMULTIPLIED_ALPHA, false, false, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, - NON_PREMULTIPLIED_ALPHA, true, false, false)); + NON_PREMULTIPLIED_ALPHA, true, false, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, - NON_PREMULTIPLIED_ALPHA, true, false, false)); + NON_PREMULTIPLIED_ALPHA, true, false, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, - NON_PREMULTIPLIED_ALPHA, false, true, false)); + NON_PREMULTIPLIED_ALPHA, false, true, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, - NON_PREMULTIPLIED_ALPHA, false, true, false)); + NON_PREMULTIPLIED_ALPHA, false, true, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, - NON_PREMULTIPLIED_ALPHA, true, true, false)); + NON_PREMULTIPLIED_ALPHA, true, true, false, + false)); TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, - NON_PREMULTIPLIED_ALPHA, true, true, false)); + NON_PREMULTIPLIED_ALPHA, true, true, false, + false)); // Iterate over alpha plane, nv12, and color_lut parameters. UVTextureMode uv_modes[2] = {UV_TEXTURE_MODE_UV, UV_TEXTURE_MODE_U_V}; @@ -343,7 +366,7 @@ for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { TestShader(ProgramKey::YUVVideo(precision, sampler, a_modes[j], - uv_modes[k], false)); + uv_modes[k], false, false)); } } } @@ -354,16 +377,16 @@ bool mask_for_background) { TestShader(ProgramKey::RenderPass(precision, sampler, blend_mode, NO_AA, HAS_MASK, mask_for_background, false, - false)); + false, false)); TestShader(ProgramKey::RenderPass(precision, sampler, blend_mode, NO_AA, HAS_MASK, mask_for_background, true, - false)); + false, false)); TestShader(ProgramKey::RenderPass(precision, sampler, blend_mode, USE_AA, HAS_MASK, mask_for_background, false, - false)); + false, false)); TestShader(ProgramKey::RenderPass(precision, sampler, blend_mode, USE_AA, HAS_MASK, mask_for_background, true, - false)); + false, false)); } }; @@ -542,7 +565,7 @@ BlendMode blend_mode) { const Program* program = renderer_->GetProgramIfInitialized( ProgramKey::RenderPass(precision, SAMPLER_TYPE_2D, blend_mode, NO_AA, - NO_MASK, false, false, false)); + NO_MASK, false, false, false, false)); EXPECT_PROGRAM_VALID(program); EXPECT_EQ(program, renderer_->current_program_); } @@ -551,7 +574,7 @@ BlendMode blend_mode) { const Program* program = renderer_->GetProgramIfInitialized( ProgramKey::RenderPass(precision, SAMPLER_TYPE_2D, blend_mode, NO_AA, - NO_MASK, false, true, false)); + NO_MASK, false, true, false, false)); EXPECT_PROGRAM_VALID(program); EXPECT_EQ(program, renderer_->current_program_); } @@ -561,7 +584,7 @@ BlendMode blend_mode) { const Program* program = renderer_->GetProgramIfInitialized( ProgramKey::RenderPass(precision, sampler, blend_mode, NO_AA, HAS_MASK, - false, false, false)); + false, false, false, false)); EXPECT_PROGRAM_VALID(program); EXPECT_EQ(program, renderer_->current_program_); } @@ -571,7 +594,7 @@ BlendMode blend_mode) { const Program* program = renderer_->GetProgramIfInitialized( ProgramKey::RenderPass(precision, sampler, blend_mode, NO_AA, HAS_MASK, - false, true, false)); + false, true, false, false)); EXPECT_PROGRAM_VALID(program); EXPECT_EQ(program, renderer_->current_program_); } @@ -580,7 +603,7 @@ BlendMode blend_mode) { const Program* program = renderer_->GetProgramIfInitialized( ProgramKey::RenderPass(precision, SAMPLER_TYPE_2D, blend_mode, USE_AA, - NO_MASK, false, false, false)); + NO_MASK, false, false, false, false)); EXPECT_PROGRAM_VALID(program); EXPECT_EQ(program, renderer_->current_program_); } @@ -589,7 +612,7 @@ BlendMode blend_mode) { const Program* program = renderer_->GetProgramIfInitialized( ProgramKey::RenderPass(precision, SAMPLER_TYPE_2D, blend_mode, USE_AA, - NO_MASK, false, true, false)); + NO_MASK, false, true, false, false)); EXPECT_PROGRAM_VALID(program); EXPECT_EQ(program, renderer_->current_program_); } @@ -599,7 +622,7 @@ BlendMode blend_mode) { const Program* program = renderer_->GetProgramIfInitialized( ProgramKey::RenderPass(precision, sampler, blend_mode, USE_AA, HAS_MASK, - false, false, false)); + false, false, false, false)); EXPECT_PROGRAM_VALID(program); EXPECT_EQ(program, renderer_->current_program_); } @@ -609,14 +632,14 @@ BlendMode blend_mode) { const Program* program = renderer_->GetProgramIfInitialized( ProgramKey::RenderPass(precision, sampler, blend_mode, USE_AA, HAS_MASK, - false, true, false)); + false, true, false, false)); EXPECT_PROGRAM_VALID(program); EXPECT_EQ(program, renderer_->current_program_); } void TestSolidColorProgramAA() { const Program* program = renderer_->GetProgramIfInitialized( - ProgramKey::SolidColor(USE_AA, false)); + ProgramKey::SolidColor(USE_AA, false, false)); EXPECT_PROGRAM_VALID(program); EXPECT_EQ(program, renderer_->current_program_); }
diff --git a/components/viz/service/display/program_binding.cc b/components/viz/service/display/program_binding.cc index 9436dc3..e676be18 100644 --- a/components/viz/service/display/program_binding.cc +++ b/components/viz/service/display/program_binding.cc
@@ -35,7 +35,8 @@ uv_texture_mode_ == other.uv_texture_mode_ && color_conversion_mode_ == other.color_conversion_mode_ && color_transform_ == other.color_transform_ && - has_output_color_matrix_ == other.has_output_color_matrix_; + has_output_color_matrix_ == other.has_output_color_matrix_ && + has_rounded_corner_ == other.has_rounded_corner_; } bool ProgramKey::operator!=(const ProgramKey& other) const { @@ -50,11 +51,14 @@ } // static -ProgramKey ProgramKey::SolidColor(AAMode aa_mode, bool tint_color) { +ProgramKey ProgramKey::SolidColor(AAMode aa_mode, + bool tint_color, + bool rounded_corner) { ProgramKey result; result.type_ = PROGRAM_TYPE_SOLID_COLOR; result.aa_mode_ = aa_mode; result.has_tint_color_matrix_ = tint_color; + result.has_rounded_corner_ = rounded_corner; return result; } @@ -66,7 +70,8 @@ PremultipliedAlphaMode premultiplied_alpha, bool is_opaque, bool has_tex_clamp_rect, - bool tint_color) { + bool tint_color, + bool rounded_corner) { ProgramKey result; result.type_ = PROGRAM_TYPE_TILE; result.precision_ = precision; @@ -77,6 +82,7 @@ result.has_tex_clamp_rect_ = has_tex_clamp_rect; result.has_tint_color_matrix_ = tint_color; result.premultiplied_alpha_ = premultiplied_alpha; + result.has_rounded_corner_ = rounded_corner; return result; } @@ -86,7 +92,8 @@ PremultipliedAlphaMode premultiplied_alpha, bool has_background_color, bool has_tex_clamp_rect, - bool tint_color) { + bool tint_color, + bool rounded_corner) { ProgramKey result; result.type_ = PROGRAM_TYPE_TEXTURE; result.precision_ = precision; @@ -95,6 +102,7 @@ result.has_background_color_ = has_background_color; result.has_tex_clamp_rect_ = has_tex_clamp_rect; result.has_tint_color_matrix_ = tint_color; + result.has_rounded_corner_ = rounded_corner; return result; } @@ -106,7 +114,8 @@ MaskMode mask_mode, bool mask_for_background, bool has_color_matrix, - bool tint_color) { + bool tint_color, + bool rounded_corner) { ProgramKey result; result.type_ = PROGRAM_TYPE_RENDER_PASS; result.precision_ = precision; @@ -117,15 +126,18 @@ result.mask_for_background_ = mask_for_background; result.has_color_matrix_ = has_color_matrix; result.has_tint_color_matrix_ = tint_color; + result.has_rounded_corner_ = rounded_corner; return result; } // static -ProgramKey ProgramKey::VideoStream(TexCoordPrecision precision) { +ProgramKey ProgramKey::VideoStream(TexCoordPrecision precision, + bool rounded_corner) { ProgramKey result; result.type_ = PROGRAM_TYPE_VIDEO_STREAM; result.precision_ = precision; result.sampler_ = SAMPLER_TYPE_EXTERNAL_OES; + result.has_rounded_corner_ = rounded_corner; return result; } @@ -134,7 +146,8 @@ SamplerType sampler, YUVAlphaTextureMode yuv_alpha_texture_mode, UVTextureMode uv_texture_mode, - bool tint_color) { + bool tint_color, + bool rounded_corner) { ProgramKey result; result.type_ = PROGRAM_TYPE_YUV_VIDEO; result.precision_ = precision; @@ -146,6 +159,7 @@ DCHECK(uv_texture_mode == UV_TEXTURE_MODE_UV || uv_texture_mode == UV_TEXTURE_MODE_U_V); result.has_tint_color_matrix_ = tint_color; + result.has_rounded_corner_ = rounded_corner; return result; }
diff --git a/components/viz/service/display/program_binding.h b/components/viz/service/display/program_binding.h index 2a8fb9f..d222e145 100644 --- a/components/viz/service/display/program_binding.h +++ b/components/viz/service/display/program_binding.h
@@ -77,7 +77,9 @@ ~ProgramKey(); static ProgramKey DebugBorder(); - static ProgramKey SolidColor(AAMode aa_mode, bool tint_color); + static ProgramKey SolidColor(AAMode aa_mode, + bool tint_color, + bool rounded_corner); static ProgramKey Tile(TexCoordPrecision precision, SamplerType sampler, AAMode aa_mode, @@ -85,13 +87,15 @@ PremultipliedAlphaMode premultiplied_alpha, bool is_opaque, bool has_tex_clamp_rect, - bool tint_color); + bool tint_color, + bool rounded_corner); static ProgramKey Texture(TexCoordPrecision precision, SamplerType sampler, PremultipliedAlphaMode premultiplied_alpha, bool has_background_color, bool has_tex_clamp_rect, - bool tint_color); + bool tint_color, + bool rounded_corner); // TODO(ccameron): Merge |mask_for_background| into MaskMode. static ProgramKey RenderPass(TexCoordPrecision precision, @@ -101,13 +105,16 @@ MaskMode mask_mode, bool mask_for_background, bool has_color_matrix, - bool tint_color); - static ProgramKey VideoStream(TexCoordPrecision precision); + bool tint_color, + bool rounded_corner); + static ProgramKey VideoStream(TexCoordPrecision precision, + bool rounded_corner); static ProgramKey YUVVideo(TexCoordPrecision precision, SamplerType sampler, YUVAlphaTextureMode yuv_alpha_texture_mode, UVTextureMode uv_texture_mode, - bool tint_color); + bool tint_color, + bool rounded_corner); bool operator==(const ProgramKey& other) const; bool operator!=(const ProgramKey& other) const; @@ -149,6 +156,7 @@ bool has_output_color_matrix_ = false; bool has_tint_color_matrix_ = false; + bool has_rounded_corner_ = false; }; struct ProgramKeyHash { @@ -170,7 +178,8 @@ (static_cast<size_t>(key.color_conversion_mode_) << 26) ^ (static_cast<size_t>(key.has_tex_clamp_rect_) << 28) ^ (static_cast<size_t>(key.has_output_color_matrix_) << 29) ^ - (static_cast<size_t>(key.has_tint_color_matrix_) << 30); + (static_cast<size_t>(key.has_tint_color_matrix_) << 30) ^ + (static_cast<size_t>(key.has_rounded_corner_) << 31); } }; @@ -193,6 +202,7 @@ fragment_shader_.color_transform_ = key.color_transform_; fragment_shader_.has_output_color_matrix_ = key.has_output_color_matrix_; fragment_shader_.has_tint_color_matrix_ = key.has_tint_color_matrix_; + fragment_shader_.has_rounded_corner_ = key.has_rounded_corner_; switch (key.type_) { case PROGRAM_TYPE_DEBUG_BORDER: @@ -321,6 +331,12 @@ int tint_color_matrix_location() const { return fragment_shader_.tint_color_matrix_location_; } + int rounded_corner_rect_location() const { + return fragment_shader_.rounded_corner_rect_location_; + } + int rounded_corner_radius_location() const { + return fragment_shader_.rounded_corner_radius_location_; + } private: void InitializeDebugBorderProgram() {
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index 4c9232c3..00ba3b4 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -133,19 +133,21 @@ SharedQuadState* CreateTestSharedQuadState( gfx::Transform quad_to_target_transform, const gfx::Rect& rect, - RenderPass* render_pass) { + RenderPass* render_pass, + const gfx::RRectF& rrect) { const gfx::Rect layer_rect = rect; const gfx::Rect visible_layer_rect = rect; const gfx::Rect clip_rect = rect; const bool is_clipped = false; const bool are_contents_opaque = false; const float opacity = 1.0f; + const gfx::RRectF rounded_corner_bounds = rrect; const SkBlendMode blend_mode = SkBlendMode::kSrcOver; int sorting_context_id = 0; SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(quad_to_target_transform, layer_rect, visible_layer_rect, - /*rounded_corner_bounds=*/gfx::RRectF(), clip_rect, - is_clipped, are_contents_opaque, opacity, blend_mode, + rounded_corner_bounds, clip_rect, is_clipped, + are_contents_opaque, opacity, blend_mode, sorting_context_id); return shared_state; } @@ -937,8 +939,8 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(shared_state, rect, rect, SK_ColorGREEN, false); @@ -959,8 +961,8 @@ std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_id, small_rect, gfx::Transform()); - SharedQuadState* child_shared_state = - CreateTestSharedQuadState(gfx::Transform(), small_rect, child_pass.get()); + SharedQuadState* child_shared_state = CreateTestSharedQuadState( + gfx::Transform(), small_rect, child_pass.get(), gfx::RRectF()); auto* color_quad = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(child_shared_state, rect, rect, SK_ColorGREEN, false); @@ -969,8 +971,8 @@ std::unique_ptr<RenderPass> root_pass = CreateTestRenderPass(root_id, rect, gfx::Transform()); - SharedQuadState* root_shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, root_pass.get()); + SharedQuadState* root_shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, root_pass.get(), gfx::RRectF()); CreateTestRenderPassDrawQuad(root_shared_state, small_rect, child_id, root_pass.get()); @@ -993,8 +995,8 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); CreateTestTextureDrawQuad( this->use_gpu(), gfx::Rect(this->device_viewport_size_), @@ -1022,8 +1024,8 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* texture_quad_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* texture_quad_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); texture_quad_state->opacity = 0.8f; CreateTestTextureDrawQuad( @@ -1035,8 +1037,8 @@ this->child_resource_provider_.get(), this->shared_bitmap_manager_.get(), this->child_context_provider_, pass.get()); - SharedQuadState* color_quad_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* color_quad_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false); @@ -1054,16 +1056,16 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); shared_state->opacity = 1 - 16.0f / 255; shared_state->blend_mode = SkBlendMode::kDstOut; auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(shared_state, rect, rect, SK_ColorRED, false); - SharedQuadState* shared_state_background = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state_background = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); SkColor background_color = SkColorSetRGB(0xff, 0xff * 14 / 16, 0xff); auto* color_quad_background = @@ -1086,8 +1088,8 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(shared_state, rect, rect, SK_ColorYELLOW, false); @@ -1129,8 +1131,8 @@ gfx::Transform(), cc::FilterOperations()); cc::AddQuad(root_pass, root_rect, SK_ColorYELLOW); - SharedQuadState* pass_shared_state = - CreateTestSharedQuadState(gfx::Transform(), viewport_rect, root_pass); + SharedQuadState* pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), viewport_rect, root_pass, gfx::RRectF()); CreateTestRenderPassDrawQuad(pass_shared_state, viewport_rect, child_pass_id, root_pass); @@ -1155,8 +1157,8 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* texture_quad_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* texture_quad_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); texture_quad_state->opacity = 0.8f; float vertex_opacity[4] = {1.f, 1.f, 0.f, 0.f}; @@ -1170,8 +1172,8 @@ this->child_resource_provider_.get(), this->shared_bitmap_manager_.get(), this->child_context_provider_, pass.get()); - SharedQuadState* color_quad_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* color_quad_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false); @@ -1207,8 +1209,8 @@ trans.Translate3d(0, 0, 0.707 * this->device_viewport_size_.width() / 2.0); trans.RotateAboutZAxis(45.0); trans.RotateAboutYAxis(45.0); - front_quad_state_ = - CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get()); + front_quad_state_ = CreateTestSharedQuadState( + trans, viewport_rect_, render_pass_.get(), gfx::RRectF()); front_quad_state_->clip_rect = quad_rect_; // Make sure they end up in a 3d sorting context. front_quad_state_->sorting_context_id = 1; @@ -1218,15 +1220,15 @@ trans = gfx::Transform(); trans.Translate3d(0, 0, -0.707 * this->device_viewport_size_.width() / 2.0); trans.RotateAboutYAxis(-45.0); - back_quad_state_ = - CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get()); + back_quad_state_ = CreateTestSharedQuadState( + trans, viewport_rect_, render_pass_.get(), gfx::RRectF()); back_quad_state_->sorting_context_id = 1; back_quad_state_->clip_rect = quad_rect_; } void AppendBackgroundAndRunTest(const cc::PixelComparator& comparator, const base::FilePath::CharType* ref_file) { SharedQuadState* background_quad_state = CreateTestSharedQuadState( - gfx::Transform(), viewport_rect_, render_pass_.get()); + gfx::Transform(), viewport_rect_, render_pass_.get(), gfx::RRectF()); auto* background_quad = render_pass_->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); background_quad->SetNew(background_quad_state, viewport_rect_, @@ -1466,11 +1468,11 @@ std::unique_ptr<RenderPass> child_pass1 = CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform()); SharedQuadState* child1_quad_state = CreateTestSharedQuadState( - gfx::Transform(), this->quad_rect_, child_pass1.get()); + gfx::Transform(), this->quad_rect_, child_pass1.get(), gfx::RRectF()); std::unique_ptr<RenderPass> child_pass2 = CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform()); SharedQuadState* child2_quad_state = CreateTestSharedQuadState( - gfx::Transform(), this->quad_rect_, child_pass2.get()); + gfx::Transform(), this->quad_rect_, child_pass2.get(), gfx::RRectF()); CreateTestTwoColoredTextureDrawQuad( this->use_gpu(), this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), @@ -1564,8 +1566,8 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); CreateTestTextureDrawQuad( this->use_gpu(), gfx::Rect(this->device_viewport_size_), @@ -1594,8 +1596,8 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* texture_quad_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* texture_quad_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); texture_quad_state->opacity = 0.8f; CreateTestTextureDrawQuad( @@ -1607,8 +1609,8 @@ this->child_resource_provider_.get(), this->shared_bitmap_manager_.get(), this->child_context_provider_, pass.get()); - SharedQuadState* color_quad_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* color_quad_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false); @@ -1641,8 +1643,8 @@ gfx::Transform scale_by_2; scale_by_2.Scale(2.f, 2.f); gfx::Rect half_rect(100, 100); - SharedQuadState* shared_state = - CreateTestSharedQuadState(scale_by_2, half_rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + scale_by_2, half_rect, pass.get(), gfx::RRectF()); gfx::Size background_size(200, 200); gfx::Rect green_rect(16, 20, 100, 100); @@ -1706,8 +1708,8 @@ pass->color_space = gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE170M, gfx::ColorSpace::TransferID::SMPTE170M); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); CreateTestYUVVideoDrawQuad_Striped( shared_state, media::PIXEL_FORMAT_I420, gfx::ColorSpace::CreateREC601(), @@ -1734,8 +1736,8 @@ pass->color_space = gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE170M, gfx::ColorSpace::TransferID::SMPTE170M); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), viewport, pass.get(), gfx::RRectF()); CreateTestYUVVideoDrawQuad_Striped( shared_state, media::PIXEL_FORMAT_I420, gfx::ColorSpace::CreateREC601(), @@ -1783,8 +1785,8 @@ pass->color_space = gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE170M, gfx::ColorSpace::TransferID::SMPTE170M); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); // Intentionally sets frame format to I420 for testing coverage. CreateTestYUVVideoDrawQuad_Striped( @@ -1811,8 +1813,8 @@ pass->color_space = gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE170M, gfx::ColorSpace::TransferID::SMPTE170M); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); // In MPEG color range YUV values of (15,128,128) should produce black. CreateTestYUVVideoDrawQuad_Solid( @@ -1842,8 +1844,8 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); // YUV of (149,43,21) should be green (0,255,0) in RGB. CreateTestYUVVideoDrawQuad_Solid( @@ -1867,8 +1869,8 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); // YUV of (149,43,21) should be green (0,255,0) in RGB. CreateTestYUVVideoDrawQuad_NV12( @@ -1920,8 +1922,8 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); // Dark grey in JPEG color range (in MPEG, this is black). CreateTestYUVVideoDrawQuad_Solid( @@ -1950,8 +1952,8 @@ pass->color_space = gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE170M, gfx::ColorSpace::TransferID::SMPTE170M); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); CreateTestYUVVideoDrawQuad_Striped( shared_state, media::PIXEL_FORMAT_I420A, gfx::ColorSpace::CreateREC601(), @@ -1980,8 +1982,8 @@ pass->color_space = gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE170M, gfx::ColorSpace::TransferID::SMPTE170M); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); CreateTestYUVVideoDrawQuad_Striped( shared_state, media::PIXEL_FORMAT_I420A, gfx::ColorSpace::CreateREC601(), @@ -2007,8 +2009,8 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); gfx::Rect upper_rect(rect.x(), rect.y(), rect.width(), rect.height() / 2); CreateTestY16TextureDrawQuad_TwoColor( @@ -2063,7 +2065,7 @@ gfx::Transform quad_to_target_transform; SharedQuadState* shared_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); shared_state->opacity = 0.5f; gfx::Rect blue_rect(0, 0, this->device_viewport_size_.width(), @@ -2077,14 +2079,14 @@ yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); SharedQuadState* blank_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); auto* white = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); white->SetNew(blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false); - SharedQuadState* pass_shared_state = - CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); + SharedQuadState* pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), pass_rect, root_pass.get(), gfx::RRectF()); auto* render_pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); @@ -2123,7 +2125,7 @@ gfx::Transform quad_to_target_transform; SharedQuadState* shared_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); shared_state->opacity = 0.5f; gfx::Rect blue_rect(0, 0, this->device_viewport_size_.width(), @@ -2137,14 +2139,14 @@ yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); SharedQuadState* blank_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); auto* white = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); white->SetNew(blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false); - SharedQuadState* pass_shared_state = - CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); + SharedQuadState* pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), pass_rect, root_pass.get(), gfx::RRectF()); auto* render_pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); @@ -2184,7 +2186,7 @@ gfx::Transform quad_to_target_transform; SharedQuadState* shared_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); shared_state->opacity = 0.5f; gfx::Rect blue_rect(0, 0, this->device_viewport_size_.width(), @@ -2198,14 +2200,14 @@ yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); SharedQuadState* blank_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); auto* white = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); white->SetNew(blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false); - SharedQuadState* pass_shared_state = - CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); + SharedQuadState* pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), pass_rect, root_pass.get(), gfx::RRectF()); auto* render_pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); @@ -2266,7 +2268,7 @@ gfx::Transform quad_to_target_transform; SharedQuadState* shared_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); shared_state->opacity = 0.5f; gfx::Rect blue_rect(0, 0, this->device_viewport_size_.width(), @@ -2280,14 +2282,14 @@ yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); SharedQuadState* blank_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); auto* white = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); white->SetNew(blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false); - SharedQuadState* pass_shared_state = - CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); + SharedQuadState* pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), pass_rect, root_pass.get(), gfx::RRectF()); auto* render_pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); @@ -2324,7 +2326,7 @@ gfx::Transform quad_to_target_transform; SharedQuadState* shared_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); gfx::Rect blue_rect(0, 0, this->device_viewport_size_.width(), this->device_viewport_size_.height() / 2); @@ -2336,8 +2338,8 @@ auto* yellow = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); - SharedQuadState* pass_shared_state = - CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); + SharedQuadState* pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), pass_rect, root_pass.get(), gfx::RRectF()); CreateTestRenderPassDrawQuad(pass_shared_state, pass_rect, child_pass_id, root_pass.get()); @@ -2367,7 +2369,7 @@ gfx::Transform quad_to_target_transform; SharedQuadState* shared_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); gfx::Rect blue_rect(0, 0, this->device_viewport_size_.width(), this->device_viewport_size_.height() / 2); @@ -2382,13 +2384,13 @@ gfx::Transform aa_transform; aa_transform.Translate(0.5, 0.0); - SharedQuadState* pass_shared_state = - CreateTestSharedQuadState(aa_transform, pass_rect, root_pass.get()); + SharedQuadState* pass_shared_state = CreateTestSharedQuadState( + aa_transform, pass_rect, root_pass.get(), gfx::RRectF()); CreateTestRenderPassDrawQuad(pass_shared_state, pass_rect, child_pass_id, root_pass.get()); SharedQuadState* root_shared_state = CreateTestSharedQuadState( - gfx::Transform(), viewport_rect, root_pass.get()); + gfx::Transform(), viewport_rect, root_pass.get(), gfx::RRectF()); auto* background = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); background->SetNew(root_shared_state, gfx::Rect(this->device_viewport_size_), gfx::Rect(this->device_viewport_size_), SK_ColorWHITE, @@ -2415,14 +2417,14 @@ std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState( - gfx::Transform(), viewport_rect, root_pass.get()); + gfx::Transform(), viewport_rect, root_pass.get(), gfx::RRectF()); int child_pass_id = 2; gfx::Transform transform_to_root; std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root); SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState( - gfx::Transform(), viewport_rect, child_pass.get()); + gfx::Transform(), viewport_rect, child_pass.get(), gfx::RRectF()); // The child render pass is just a green box. static const SkColor kCSSGreen = 0xff008000; @@ -2512,14 +2514,14 @@ std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState( - gfx::Transform(), viewport_rect, root_pass.get()); + gfx::Transform(), viewport_rect, root_pass.get(), gfx::RRectF()); int child_pass_id = 2; gfx::Transform transform_to_root; std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root); SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState( - gfx::Transform(), viewport_rect, child_pass.get()); + gfx::Transform(), viewport_rect, child_pass.get(), gfx::RRectF()); // The child render pass is just a green box. static const SkColor kCSSGreen = 0xff008000; @@ -2600,6 +2602,196 @@ cc::ExactPixelComparator(true))); } +TYPED_TEST(RendererPixelTest, RenderPassAndMaskForRoundedCorner) { + gfx::Rect viewport_rect(this->device_viewport_size_); + constexpr int kInset = 20; + constexpr int kCornerRadius = 20; + + int root_pass_id = 1; + std::unique_ptr<RenderPass> root_pass = + CreateTestRootRenderPass(root_pass_id, viewport_rect); + SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), viewport_rect, root_pass.get(), gfx::RRectF()); + + int child_pass_id = 2; + gfx::Transform transform_to_root; + std::unique_ptr<RenderPass> child_pass = + CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root); + SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), viewport_rect, child_pass.get(), gfx::RRectF()); + + // The child render pass is just a blue box. + auto* blue = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + blue->SetNew(child_pass_shared_state, viewport_rect, viewport_rect, + SK_ColorBLUE, false); + + // Make a mask. + gfx::Rect mask_rect = viewport_rect; + SkBitmap bitmap; + bitmap.allocPixels( + SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height())); + cc::SkiaPaintCanvas canvas(bitmap); + cc::PaintFlags flags; + flags.setStyle(cc::PaintFlags::kFill_Style); + flags.setColor(SK_ColorWHITE); + flags.setAntiAlias(true); + canvas.clear(SK_ColorTRANSPARENT); + gfx::Rect rounded_corner_rect = mask_rect; + rounded_corner_rect.Inset(kInset, kInset); + SkRRect rounded_corner = SkRRect::MakeRectXY( + gfx::RectToSkRect(rounded_corner_rect), kCornerRadius, kCornerRadius); + canvas.drawRRect(rounded_corner, flags); + + ResourceId mask_resource_id; + if (this->use_gpu()) { + mask_resource_id = CreateGpuResource( + this->child_context_provider_, this->child_resource_provider_.get(), + mask_rect.size(), RGBA_8888, gfx::ColorSpace(), MakePixelSpan(bitmap)); + } else { + mask_resource_id = + this->AllocateAndFillSoftwareResource(mask_rect.size(), bitmap); + } + + // Return the mapped resource id. + std::unordered_map<ResourceId, ResourceId> resource_map = + cc::SendResourceAndGetChildToParentMap( + {mask_resource_id}, this->resource_provider_.get(), + this->child_resource_provider_.get(), + this->child_context_provider_.get()); + ResourceId mapped_mask_resource_id = resource_map[mask_resource_id]; + + // Set up a mask on the RenderPassDrawQuad. + auto* mask_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); + mask_quad->SetNew( + root_pass_shared_state, viewport_rect, viewport_rect, child_pass_id, + mapped_mask_resource_id, + gfx::ScaleRect(gfx::RectF(viewport_rect), 1.f / mask_rect.width(), + 1.f / mask_rect.height()), // mask_uv_rect + gfx::Size(mask_rect.size()), // mask_texture_size + gfx::Vector2dF(), // filters scale + gfx::PointF(), // filter origin + gfx::RectF(viewport_rect), // tex_coord_rect + false, // force_anti_aliasing_off + 1.0f); // backdrop_filter_quality + // White background behind the masked render pass. + auto* white = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + white->SetNew(root_pass_shared_state, viewport_rect, viewport_rect, + SK_ColorWHITE, false); + + RenderPassList pass_list; + pass_list.push_back(std::move(child_pass)); + pass_list.push_back(std::move(root_pass)); + + // The rounded corners generated by masks should be very close to the rounded + // corners generated by the fragment shader approach. The percentage of pixel + // mismatch is around 0.52%. + EXPECT_TRUE(this->RunPixelTest( + &pass_list, + base::FilePath(FILE_PATH_LITERAL("rounded_corner_simple.png")), + cc::FuzzyPixelComparator(true, 0.6f, 0.f, 255.f, 255, 0))); +} + +TYPED_TEST(RendererPixelTest, RenderPassAndMaskForRoundedCornerMultiRadii) { + gfx::Rect viewport_rect(this->device_viewport_size_); + constexpr int kInset = 20; + const SkVector kCornerRadii[4] = { + SkVector::Make(5.0, 5.0), + SkVector::Make(15.0, 15.0), + SkVector::Make(25.0, 25.0), + SkVector::Make(35.0, 35.0), + }; + + int root_pass_id = 1; + std::unique_ptr<RenderPass> root_pass = + CreateTestRootRenderPass(root_pass_id, viewport_rect); + SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), viewport_rect, root_pass.get(), gfx::RRectF()); + + int child_pass_id = 2; + gfx::Transform transform_to_root; + std::unique_ptr<RenderPass> child_pass = + CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root); + SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), viewport_rect, child_pass.get(), gfx::RRectF()); + + // The child render pass is half a blue box and other half yellow box. + gfx::Rect blue_rect(0, 0, this->device_viewport_size_.width(), + this->device_viewport_size_.height() / 2); + auto* blue = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + blue->SetNew(child_pass_shared_state, blue_rect, blue_rect, SK_ColorBLUE, + false); + + gfx::Rect yellow_rect(0, this->device_viewport_size_.height() / 2, + this->device_viewport_size_.width(), + this->device_viewport_size_.height() / 2); + auto* yellow = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + yellow->SetNew(child_pass_shared_state, yellow_rect, yellow_rect, + SK_ColorYELLOW, false); + + // Make a mask. + gfx::Rect mask_rect = viewport_rect; + SkBitmap bitmap; + bitmap.allocPixels( + SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height())); + cc::SkiaPaintCanvas canvas(bitmap); + cc::PaintFlags flags; + flags.setStyle(cc::PaintFlags::kFill_Style); + flags.setColor(SK_ColorWHITE); + flags.setAntiAlias(true); + canvas.clear(SK_ColorTRANSPARENT); + gfx::Rect rounded_corner_rect = mask_rect; + rounded_corner_rect.Inset(kInset, kInset); + SkRRect rounded_corner = + SkRRect::MakeRect(gfx::RectToSkRect(rounded_corner_rect)); + rounded_corner.setRectRadii(rounded_corner.rect(), kCornerRadii); + canvas.drawRRect(rounded_corner, flags); + + ResourceId mask_resource_id; + if (this->use_gpu()) { + mask_resource_id = CreateGpuResource( + this->child_context_provider_, this->child_resource_provider_.get(), + mask_rect.size(), RGBA_8888, gfx::ColorSpace(), MakePixelSpan(bitmap)); + } else { + mask_resource_id = + this->AllocateAndFillSoftwareResource(mask_rect.size(), bitmap); + } + + // Return the mapped resource id. + std::unordered_map<ResourceId, ResourceId> resource_map = + cc::SendResourceAndGetChildToParentMap( + {mask_resource_id}, this->resource_provider_.get(), + this->child_resource_provider_.get(), + this->child_context_provider_.get()); + ResourceId mapped_mask_resource_id = resource_map[mask_resource_id]; + + // Set up a mask on the RenderPassDrawQuad. + auto* mask_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); + mask_quad->SetNew( + root_pass_shared_state, viewport_rect, viewport_rect, child_pass_id, + mapped_mask_resource_id, + gfx::ScaleRect(gfx::RectF(viewport_rect), 1.f / mask_rect.width(), + 1.f / mask_rect.height()), // mask_uv_rect + gfx::Size(mask_rect.size()), // mask_texture_size + gfx::Vector2dF(), // filters scale + gfx::PointF(), // filter origin + gfx::RectF(viewport_rect), // tex_coord_rect + false, // force_anti_aliasing_off + 1.0f); // backdrop_filter_quality + // White background behind the masked render pass. + auto* white = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + white->SetNew(root_pass_shared_state, viewport_rect, viewport_rect, + SK_ColorWHITE, false); + + RenderPassList pass_list; + pass_list.push_back(std::move(child_pass)); + pass_list.push_back(std::move(root_pass)); + + EXPECT_TRUE(this->RunPixelTest( + &pass_list, + base::FilePath(FILE_PATH_LITERAL("rounded_corner_multi_radii.png")), + cc::FuzzyPixelComparator(true, 0.6f, 0.f, 255.f, 255, 0))); +} + template <typename RendererType> class RendererPixelTestWithBackgroundFilter : public RendererPixelTest<RendererType> { @@ -2623,9 +2815,9 @@ // A non-visible quad in the filtering render pass. { - SharedQuadState* shared_state = - CreateTestSharedQuadState(identity_quad_to_target_transform, - filter_pass_layer_rect_, filter_pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + identity_quad_to_target_transform, filter_pass_layer_rect_, + filter_pass.get(), gfx::RRectF()); auto* color_quad = filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(shared_state, filter_pass_layer_rect_, @@ -2633,9 +2825,9 @@ } { - SharedQuadState* shared_state = - CreateTestSharedQuadState(filter_pass_to_target_transform_, - filter_pass_layer_rect_, filter_pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + filter_pass_to_target_transform_, filter_pass_layer_rect_, + filter_pass.get(), gfx::RRectF()); auto* filter_pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); filter_pass_quad->SetNew(shared_state, filter_pass_layer_rect_, @@ -2654,8 +2846,9 @@ gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20); for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) { - SharedQuadState* shared_state = CreateTestSharedQuadState( - identity_quad_to_target_transform, left_rect, root_pass.get()); + SharedQuadState* shared_state = + CreateTestSharedQuadState(identity_quad_to_target_transform, + left_rect, root_pass.get(), gfx::RRectF()); auto* color_quad = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(shared_state, left_rect, left_rect, SK_ColorGREEN, @@ -2666,7 +2859,8 @@ gfx::Rect middle_rect = gfx::Rect(kColumnWidth + 1, 0, kColumnWidth, 20); for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) { SharedQuadState* shared_state = CreateTestSharedQuadState( - identity_quad_to_target_transform, middle_rect, root_pass.get()); + identity_quad_to_target_transform, middle_rect, root_pass.get(), + gfx::RRectF()); auto* color_quad = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(shared_state, middle_rect, middle_rect, SK_ColorRED, @@ -2677,8 +2871,9 @@ gfx::Rect right_rect = gfx::Rect((kColumnWidth + 1) * 2, 0, kColumnWidth, 20); for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) { - SharedQuadState* shared_state = CreateTestSharedQuadState( - identity_quad_to_target_transform, right_rect, root_pass.get()); + SharedQuadState* shared_state = + CreateTestSharedQuadState(identity_quad_to_target_transform, + right_rect, root_pass.get(), gfx::RRectF()); auto* color_quad = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(shared_state, right_rect, right_rect, SK_ColorBLUE, @@ -2686,9 +2881,9 @@ right_rect += gfx::Vector2d(0, right_rect.height() + 1); } - SharedQuadState* shared_state = - CreateTestSharedQuadState(identity_quad_to_target_transform, - device_viewport_rect, root_pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + identity_quad_to_target_transform, device_viewport_rect, + root_pass.get(), gfx::RRectF()); auto* background_quad = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); background_quad->SetNew(shared_state, device_viewport_rect, @@ -2776,8 +2971,8 @@ gfx::Rect rect(this->device_viewport_size_); int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* blue_shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* blue_shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); auto* blue = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); pass->has_transparent_background = false; @@ -2798,8 +2993,8 @@ gfx::Rect rect(this->device_viewport_size_); int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* green_shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* green_shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); auto* green = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false); RenderPassList pass_list; @@ -2831,15 +3026,15 @@ gfx::Transform quad_to_target_transform; SharedQuadState* shared_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); gfx::Rect blue_rect(0, 0, this->device_viewport_size_.width(), this->device_viewport_size_.height()); auto* blue = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); - SharedQuadState* pass_shared_state = - CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); + SharedQuadState* pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), pass_rect, root_pass.get(), gfx::RRectF()); CreateTestRenderPassDrawQuad(pass_shared_state, pass_rect, child_pass_id, root_pass.get()); RenderPassList pass_list; @@ -2861,8 +3056,8 @@ gfx::Transform red_quad_to_target_transform; red_quad_to_target_transform.Rotate(10); - SharedQuadState* red_shared_state = - CreateTestSharedQuadState(red_quad_to_target_transform, rect, pass.get()); + SharedQuadState* red_shared_state = CreateTestSharedQuadState( + red_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false); @@ -2870,14 +3065,14 @@ gfx::Transform yellow_quad_to_target_transform; yellow_quad_to_target_transform.Rotate(5); SharedQuadState* yellow_shared_state = CreateTestSharedQuadState( - yellow_quad_to_target_transform, rect, pass.get()); + yellow_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* yellow = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false); gfx::Transform blue_quad_to_target_transform; SharedQuadState* blue_shared_state = CreateTestSharedQuadState( - blue_quad_to_target_transform, rect, pass.get()); + blue_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* blue = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); @@ -2904,8 +3099,8 @@ red_quad_to_target_transform.Translate(50, 50); red_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f), 0.5f + 1.0f / (rect.height() * 2.0f)); - SharedQuadState* red_shared_state = - CreateTestSharedQuadState(red_quad_to_target_transform, rect, pass.get()); + SharedQuadState* red_shared_state = CreateTestSharedQuadState( + red_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false); @@ -2914,14 +3109,14 @@ yellow_quad_to_target_transform.Translate(25.5f, 25.5f); yellow_quad_to_target_transform.Scale(0.5f, 0.5f); SharedQuadState* yellow_shared_state = CreateTestSharedQuadState( - yellow_quad_to_target_transform, rect, pass.get()); + yellow_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* yellow = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false); gfx::Transform blue_quad_to_target_transform; SharedQuadState* blue_shared_state = CreateTestSharedQuadState( - blue_quad_to_target_transform, rect, pass.get()); + blue_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* blue = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); @@ -2950,14 +3145,14 @@ hole_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f), 0.5f + 1.0f / (rect.height() * 2.0f)); SharedQuadState* hole_shared_state = CreateTestSharedQuadState( - hole_quad_to_target_transform, rect, pass.get()); + hole_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* hole = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); hole->SetAll(hole_shared_state, rect, rect, false, SK_ColorTRANSPARENT, true); gfx::Transform green_quad_to_target_transform; SharedQuadState* green_shared_state = CreateTestSharedQuadState( - green_quad_to_target_transform, rect, pass.get()); + green_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* green = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false); @@ -2989,7 +3184,7 @@ gfx::Transform quad_to_target_transform; SharedQuadState* hole_shared_state = CreateTestSharedQuadState( - quad_to_target_transform, rect, child_pass.get()); + quad_to_target_transform, rect, child_pass.get(), gfx::RRectF()); SolidColorDrawQuad* hole = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); hole->SetAll(hole_shared_state, rect, rect, false, SK_ColorTRANSPARENT, @@ -3003,7 +3198,7 @@ hole_pass_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f), 0.5f + 1.0f / (rect.height() * 2.0f)); SharedQuadState* pass_shared_state = CreateTestSharedQuadState( - hole_pass_to_target_transform, rect, root_pass.get()); + hole_pass_to_target_transform, rect, root_pass.get(), gfx::RRectF()); RenderPassDrawQuad* pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); pass_quad->SetAll(pass_shared_state, rect, rect, needs_blending, @@ -3013,7 +3208,7 @@ gfx::Transform green_quad_to_target_transform; SharedQuadState* green_shared_state = CreateTestSharedQuadState( - green_quad_to_target_transform, rect, root_pass.get()); + green_quad_to_target_transform, rect, root_pass.get(), gfx::RRectF()); SolidColorDrawQuad* green = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); @@ -3073,7 +3268,7 @@ hole_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f), 0.5f + 1.0f / (rect.height() * 2.0f)); SharedQuadState* hole_shared_state = CreateTestSharedQuadState( - hole_quad_to_target_transform, rect, pass.get()); + hole_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); TileDrawQuad* hole = pass->CreateAndAppendDrawQuad<TileDrawQuad>(); hole->SetNew(hole_shared_state, rect, rect, needs_blending, mapped_resource, gfx::RectF(gfx::Rect(tile_size)), tile_size, swizzle_contents, @@ -3082,7 +3277,7 @@ gfx::Transform green_quad_to_target_transform; SharedQuadState* green_shared_state = CreateTestSharedQuadState( - green_quad_to_target_transform, rect, pass.get()); + green_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); SolidColorDrawQuad* green = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); @@ -3107,19 +3302,19 @@ 1.0f, 2.4520f, 10.6206f, 19.0f, 0.0f, 0.3528f, 5.9737f, 9.5f, 0.0f, -0.2250f, -0.9744f, 0.0f, 0.0f, 0.0225f, 0.0974f, 1.0f); SharedQuadState* red_shared_state = CreateTestSharedQuadState( - red_quad_to_target_transform, red_rect, pass.get()); + red_quad_to_target_transform, red_rect, pass.get(), gfx::RRectF()); auto* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false); gfx::Rect green_rect(19, 7, 180, 10); - SharedQuadState* green_shared_state = - CreateTestSharedQuadState(gfx::Transform(), green_rect, pass.get()); + SharedQuadState* green_shared_state = CreateTestSharedQuadState( + gfx::Transform(), green_rect, pass.get(), gfx::RRectF()); auto* green = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); green->SetNew(green_shared_state, green_rect, green_rect, SK_ColorGREEN, false); - SharedQuadState* blue_shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* blue_shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); auto* blue = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); @@ -3156,13 +3351,13 @@ // Small enough red rect that linear filtering will miss it but large enough // that it makes a meaningful contribution when using trilinear filtering. red_rect.ClampToCenteredSize(gfx::Size(2, child_pass_rect.height())); - SharedQuadState* red_shared_state = - CreateTestSharedQuadState(gfx::Transform(), red_rect, child_pass.get()); + SharedQuadState* red_shared_state = CreateTestSharedQuadState( + gfx::Transform(), red_rect, child_pass.get(), gfx::RRectF()); auto* red = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false); SharedQuadState* blue_shared_state = CreateTestSharedQuadState( - gfx::Transform(), child_pass_rect, child_pass.get()); + gfx::Transform(), child_pass_rect, child_pass.get(), gfx::RRectF()); auto* blue = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); blue->SetNew(blue_shared_state, child_pass_rect, child_pass_rect, SK_ColorBLUE, false); @@ -3171,7 +3366,7 @@ RectToSkRect(child_pass_rect), RectToSkRect(viewport_rect), SkMatrix::kFill_ScaleToFit)); SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState( - child_to_root_transform, child_pass_rect, root_pass.get()); + child_to_root_transform, child_pass_rect, root_pass.get(), gfx::RRectF()); auto* child_pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); child_pass_quad->SetNew(child_pass_shared_state, child_pass_rect, @@ -3247,7 +3442,7 @@ gfx::Transform green_quad_to_target_transform; SharedQuadState* green_shared_state = CreateTestSharedQuadState( - green_quad_to_target_transform, viewport, pass.get()); + green_quad_to_target_transform, viewport, pass.get(), gfx::RRectF()); auto* green_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); green_quad->SetNew(green_shared_state, viewport, viewport, needs_blending, @@ -3288,7 +3483,7 @@ gfx::Transform green_quad_to_target_transform; SharedQuadState* green_shared_state = CreateTestSharedQuadState( - green_quad_to_target_transform, viewport, pass.get()); + green_quad_to_target_transform, viewport, pass.get(), gfx::RRectF()); green_shared_state->opacity = 0.5f; auto* green_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); @@ -3309,7 +3504,7 @@ gfx::Transform white_quad_to_target_transform; SharedQuadState* white_shared_state = CreateTestSharedQuadState( - white_quad_to_target_transform, viewport, pass.get()); + white_quad_to_target_transform, viewport, pass.get(), gfx::RRectF()); auto* white_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); white_quad->SetNew(white_shared_state, viewport, viewport, needs_blending, @@ -3383,8 +3578,8 @@ recording->CreateRasterSource(); gfx::Transform quad_to_target_transform; - SharedQuadState* shared_state = - CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + quad_to_target_transform, viewport, pass.get(), gfx::RRectF()); auto* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); quad->SetNew(shared_state, viewport, viewport, needs_blending, @@ -3435,8 +3630,8 @@ recording->CreateRasterSource(); gfx::Transform quad_to_target_transform; - SharedQuadState* shared_state = - CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + quad_to_target_transform, viewport, pass.get(), gfx::RRectF()); auto* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); quad->SetNew(shared_state, viewport, viewport, needs_blending, @@ -3495,8 +3690,8 @@ CreateTestRenderPass(id, viewport, transform_to_root); gfx::Transform quad_to_target_transform; - SharedQuadState* shared_state = - CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + quad_to_target_transform, viewport, pass.get(), gfx::RRectF()); auto* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>(); quad->SetNew(shared_state, viewport, viewport, needs_blending, @@ -3546,8 +3741,8 @@ CreateTestRenderPass(id, viewport, transform_to_root); gfx::Transform quad_to_target_transform; - SharedQuadState* shared_state = - CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + quad_to_target_transform, viewport, pass.get(), gfx::RRectF()); float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; auto* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); @@ -3600,8 +3795,8 @@ CreateTestRenderPass(id, viewport, transform_to_root); gfx::Transform quad_to_target_transform; - SharedQuadState* shared_state = - CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + quad_to_target_transform, viewport, pass.get(), gfx::RRectF()); float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; auto* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); @@ -3657,7 +3852,7 @@ SharedQuadState* top_right_green_shared_quad_state = CreateTestSharedQuadState(green_quad_to_target_transform, viewport, - pass.get()); + pass.get(), gfx::RRectF()); auto* green_quad1 = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); green_quad1->SetNew( @@ -3729,7 +3924,7 @@ quad_to_target_transform.Scale(10.0, 10.0); gfx::Rect quad_content_rect(gfx::Size(20, 20)); SharedQuadState* blue_shared_state = CreateTestSharedQuadState( - quad_to_target_transform, quad_content_rect, pass.get()); + quad_to_target_transform, quad_content_rect, pass.get(), gfx::RRectF()); auto* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); blue_quad->SetNew(blue_shared_state, quad_content_rect, quad_content_rect, @@ -3741,8 +3936,9 @@ // Fill left half of viewport with green. gfx::Transform half_green_quad_to_target_transform; gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height())); - SharedQuadState* half_green_shared_state = CreateTestSharedQuadState( - half_green_quad_to_target_transform, half_green_rect, pass.get()); + SharedQuadState* half_green_shared_state = + CreateTestSharedQuadState(half_green_quad_to_target_transform, + half_green_rect, pass.get(), gfx::RRectF()); auto* half_color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); half_color_quad->SetNew(half_green_shared_state, half_green_rect, half_green_rect, SK_ColorGREEN, false); @@ -3783,7 +3979,7 @@ gfx::Transform quad_to_target_transform; SharedQuadState* shared_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); gfx::Rect blue_rect(0, 0, this->device_viewport_size_.width(), this->device_viewport_size_.height() / 2); @@ -3795,8 +3991,8 @@ auto* yellow = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); - SharedQuadState* pass_shared_state = - CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); + SharedQuadState* pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), pass_rect, root_pass.get(), gfx::RRectF()); CreateTestRenderPassDrawQuad(pass_shared_state, pass_rect, child_pass_id, root_pass.get()); @@ -3828,7 +4024,7 @@ gfx::Transform quad_to_target_transform; SharedQuadState* shared_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); gfx::Rect blue_rect(0, 0, this->device_viewport_size_.width(), this->device_viewport_size_.height() / 2); @@ -3840,8 +4036,8 @@ auto* yellow = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); - SharedQuadState* pass_shared_state = - CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); + SharedQuadState* pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), pass_rect, root_pass.get(), gfx::RRectF()); CreateTestRenderPassDrawQuad(pass_shared_state, pass_rect, child_pass_id, root_pass.get()); @@ -3871,7 +4067,7 @@ gfx::Transform quad_to_target_transform; SharedQuadState* shared_state = CreateTestSharedQuadState( - quad_to_target_transform, viewport_rect, child_pass.get()); + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); // Draw a green quad full-size with a blue quad in the lower-right corner. gfx::Rect blue_rect(this->device_viewport_size_.width() * 3 / 4, @@ -3885,8 +4081,8 @@ auto* green = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); green->SetNew(shared_state, green_rect, green_rect, SK_ColorGREEN, false); - SharedQuadState* pass_shared_state = - CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); + SharedQuadState* pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), pass_rect, root_pass.get(), gfx::RRectF()); CreateTestRenderPassDrawQuad(pass_shared_state, pass_rect, child_pass_id, root_pass.get()); @@ -3916,8 +4112,8 @@ int id = 1; std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); // Make a mask. gfx::Rect mask_rect = rect; @@ -4041,8 +4237,8 @@ // tex coord rect. gfx::Transform transform; transform.Scale(40, 40); - SharedQuadState* quad_shared = - CreateTestSharedQuadState(transform, gfx::Rect(layer_size), pass.get()); + SharedQuadState* quad_shared = CreateTestSharedQuadState( + transform, gfx::Rect(layer_size), pass.get(), gfx::RRectF()); auto* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>(); quad->SetNew(quad_shared, gfx::Rect(layer_size), gfx::Rect(layer_size), needs_blending, mapped_resource, tex_coord_rect, tile_size, @@ -4050,8 +4246,8 @@ use_aa); // Green background. - SharedQuadState* background_shared = - CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get()); + SharedQuadState* background_shared = CreateTestSharedQuadState( + gfx::Transform(), viewport, pass.get(), gfx::RRectF()); auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(background_shared, viewport, viewport, SK_ColorGREEN, false); @@ -4064,6 +4260,149 @@ cc::ExactPixelComparator(true))); } +TYPED_TEST(GLOnlyRendererPixelTest, RoundedCornerSimple) { + gfx::Rect viewport_rect(this->device_viewport_size_); + constexpr int kInset = 20; + constexpr int kCornerRadius = 20; + + int root_pass_id = 1; + std::unique_ptr<RenderPass> root_pass = + CreateTestRootRenderPass(root_pass_id, viewport_rect); + + gfx::Transform quad_to_target_transform; + gfx::Rect blue_rect(0, 0, this->device_viewport_size_.width(), + this->device_viewport_size_.height()); + gfx::Rect red_rect = blue_rect; + blue_rect.Inset(kInset, kInset); + + gfx::RRectF rounded_corner_rrect(gfx::RectF(blue_rect), kCornerRadius); + SharedQuadState* shared_state_rounded = + CreateTestSharedQuadState(quad_to_target_transform, viewport_rect, + root_pass.get(), rounded_corner_rrect); + + auto* blue = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + blue->SetNew(shared_state_rounded, blue_rect, blue_rect, SK_ColorBLUE, false); + + SharedQuadState* shared_state_normal = CreateTestSharedQuadState( + quad_to_target_transform, viewport_rect, root_pass.get(), gfx::RRectF()); + + auto* white = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + white->SetNew(shared_state_normal, red_rect, red_rect, SK_ColorWHITE, false); + + RenderPassList pass_list; + pass_list.push_back(std::move(root_pass)); + + EXPECT_TRUE(this->RunPixelTest( + &pass_list, + base::FilePath(FILE_PATH_LITERAL("rounded_corner_simple.png")), + cc::ExactPixelComparator(true))); +} + +// This draws a render pass with 2 solid color quads one of which has a rounded +// corner. The render pass itself also has a rounded corner. +TYPED_TEST(GLOnlyRendererPixelTest, RoundedCornerOnRenderPass) { + gfx::Rect viewport_rect(this->device_viewport_size_); + constexpr int kInset = 20; + constexpr int kCornerRadius = 20; + constexpr int kBlueCornerRadius = 10; + + int root_pass_id = 1; + std::unique_ptr<RenderPass> root_pass = + CreateTestRootRenderPass(root_pass_id, viewport_rect); + + int child_pass_id = 2; + gfx::Rect pass_rect(this->device_viewport_size_); + pass_rect.Inset(kInset, kInset); + gfx::Transform transform_to_root; + std::unique_ptr<RenderPass> child_pass = + CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); + + gfx::Rect blue_rect = pass_rect; + blue_rect.Offset(-30, 40); + gfx::RRectF blue_rrect(gfx::RectF(blue_rect), kBlueCornerRadius); + gfx::Transform quad_to_target_transform; + SharedQuadState* shared_state_with_rrect = CreateTestSharedQuadState( + quad_to_target_transform, viewport_rect, child_pass.get(), blue_rrect); + auto* blue = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + blue->SetNew(shared_state_with_rrect, blue_rect, blue_rect, SK_ColorBLUE, + false); + + SharedQuadState* shared_state_without_rrect = CreateTestSharedQuadState( + quad_to_target_transform, viewport_rect, child_pass.get(), gfx::RRectF()); + gfx::Rect yellow_rect = pass_rect; + yellow_rect.Offset(30, -60); + auto* yellow = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + yellow->SetNew(shared_state_without_rrect, yellow_rect, yellow_rect, + SK_ColorYELLOW, false); + + gfx::Rect white_rect = pass_rect; + auto* white = child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + white->SetNew(shared_state_without_rrect, white_rect, white_rect, + SK_ColorWHITE, false); + + gfx::RRectF rounded_corner_bounds(gfx::RectF(pass_rect), kCornerRadius); + SharedQuadState* pass_shared_state = CreateTestSharedQuadState( + gfx::Transform(), pass_rect, root_pass.get(), rounded_corner_bounds); + CreateTestRenderPassDrawQuad(pass_shared_state, pass_rect, child_pass_id, + root_pass.get()); + + RenderPassList pass_list; + pass_list.push_back(std::move(child_pass)); + pass_list.push_back(std::move(root_pass)); + + EXPECT_TRUE(this->RunPixelTest( + &pass_list, + base::FilePath(FILE_PATH_LITERAL("rounded_corner_render_pass.png")), + cc::ExactPixelComparator(true))); +} + +TYPED_TEST(GLOnlyRendererPixelTest, RoundedCornerMultiRadii) { + gfx::Rect viewport_rect(this->device_viewport_size_); + constexpr std::array<uint32_t, 4> kCornerRadii = {5, 15, 25, 35}; + constexpr int kInset = 20; + + int root_pass_id = 1; + std::unique_ptr<RenderPass> root_pass = + CreateTestRootRenderPass(root_pass_id, viewport_rect); + + gfx::Rect pass_rect(this->device_viewport_size_); + pass_rect.Inset(kInset, kInset); + gfx::RRectF rounded_corner_bounds( + gfx::RectF(pass_rect), kCornerRadii[0], kCornerRadii[0], kCornerRadii[1], + kCornerRadii[1], kCornerRadii[2], kCornerRadii[2], kCornerRadii[3], + kCornerRadii[3]); + gfx::Rect blue_rect = pass_rect; + blue_rect.set_height(blue_rect.height() / 2); + + gfx::Transform quad_to_target_transform; + SharedQuadState* shared_state_normal = + CreateTestSharedQuadState(quad_to_target_transform, pass_rect, + root_pass.get(), rounded_corner_bounds); + auto* blue = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + blue->SetNew(shared_state_normal, blue_rect, blue_rect, SK_ColorBLUE, false); + + gfx::Rect yellow_rect = blue_rect; + yellow_rect.Offset(0, blue_rect.height()); + + auto* yellow = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + yellow->SetNew(shared_state_normal, yellow_rect, yellow_rect, SK_ColorYELLOW, + false); + + SharedQuadState* sqs_white = CreateTestSharedQuadState( + quad_to_target_transform, viewport_rect, root_pass.get(), gfx::RRectF()); + gfx::Rect white_rect = gfx::Rect(this->device_viewport_size_); + auto* white = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + white->SetNew(sqs_white, white_rect, white_rect, SK_ColorWHITE, false); + + RenderPassList pass_list; + pass_list.push_back(std::move(root_pass)); + + EXPECT_TRUE(this->RunPixelTest( + &pass_list, + base::FilePath(FILE_PATH_LITERAL("rounded_corner_multi_radii.png")), + cc::ExactPixelComparator(true))); +} + template <typename RendererType> class RendererPixelTestWithOverdrawFeedback : public RendererPixelTest<RendererType> { @@ -4092,7 +4431,7 @@ 0.5f + 1.0f / (rect.width() * 2.0f), 0.5f + 1.0f / (rect.height() * 2.0f)); SharedQuadState* dark_gray_shared_state = CreateTestSharedQuadState( - dark_gray_quad_to_target_transform, rect, pass.get()); + dark_gray_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* dark_gray = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); dark_gray->SetNew(dark_gray_shared_state, rect, rect, 0x10444444, false); @@ -4101,14 +4440,14 @@ light_gray_quad_to_target_transform.Translate(25.5f, 25.5f); light_gray_quad_to_target_transform.Scale(0.5f, 0.5f); SharedQuadState* light_gray_shared_state = CreateTestSharedQuadState( - light_gray_quad_to_target_transform, rect, pass.get()); + light_gray_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* light_gray = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); light_gray->SetNew(light_gray_shared_state, rect, rect, 0x10CCCCCC, false); gfx::Transform bg_quad_to_target_transform; - SharedQuadState* bg_shared_state = - CreateTestSharedQuadState(bg_quad_to_target_transform, rect, pass.get()); + SharedQuadState* bg_shared_state = CreateTestSharedQuadState( + bg_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* bg = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); bg->SetNew(bg_shared_state, rect, rect, SK_ColorBLACK, false); @@ -4150,7 +4489,7 @@ 0.5f + 1.0f / (rect.width() * 2.0f), 0.5f + 1.0f / (rect.height() * 2.0f)); SharedQuadState* dark_gray_shared_state = CreateTestSharedQuadState( - dark_gray_quad_to_target_transform, rect, pass.get()); + dark_gray_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* dark_gray = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); dark_gray->SetNew(dark_gray_shared_state, rect, rect, 0x10444444, false); @@ -4159,14 +4498,14 @@ light_gray_quad_to_target_transform.Translate(25.5f, 25.5f); light_gray_quad_to_target_transform.Scale(0.5f, 0.5f); SharedQuadState* light_gray_shared_state = CreateTestSharedQuadState( - light_gray_quad_to_target_transform, rect, pass.get()); + light_gray_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* light_gray = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); light_gray->SetNew(light_gray_shared_state, rect, rect, 0x10CCCCCC, false); gfx::Transform bg_quad_to_target_transform; - SharedQuadState* bg_shared_state = - CreateTestSharedQuadState(bg_quad_to_target_transform, rect, pass.get()); + SharedQuadState* bg_shared_state = CreateTestSharedQuadState( + bg_quad_to_target_transform, rect, pass.get(), gfx::RRectF()); auto* bg = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); bg->SetNew(bg_shared_state, rect, rect, SK_ColorBLACK, false); @@ -4270,8 +4609,8 @@ // Append a quad to execute the transform. { - SharedQuadState* shared_state = - CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + SharedQuadState* shared_state = CreateTestSharedQuadState( + gfx::Transform(), rect, pass.get(), gfx::RRectF()); ResourceId resource = CreateGpuResource( this->child_context_provider_, this->child_resource_provider_.get(),
diff --git a/components/viz/service/display/shader.cc b/components/viz/service/display/shader.cc index 62bab35..25ed944 100644 --- a/components/viz/service/display/shader.cc +++ b/components/viz/service/display/shader.cc
@@ -394,6 +394,7 @@ precision = TEX_COORD_PRECISION_MEDIUM; std::string shader = GetShaderSource(); SetBlendModeFunctions(&shader); + SetRoundedCornerFunctions(&shader); SetFragmentSamplerType(sampler_type_, &shader); SetFragmentTexCoordPrecision(precision, &shader); return shader; @@ -459,6 +460,11 @@ if (has_tint_color_matrix_) uniforms.emplace_back("tint_color_matrix"); + if (has_rounded_corner_) { + uniforms.emplace_back("roundedCornerRect"); + uniforms.emplace_back("roundedCornerRadius"); + } + locations.resize(uniforms.size()); GetProgramUniformLocations(context, program, uniforms.size(), uniforms.data(), @@ -521,9 +527,123 @@ if (has_tint_color_matrix_) tint_color_matrix_location_ = locations[index++]; + if (has_rounded_corner_) { + rounded_corner_rect_location_ = locations[index++]; + rounded_corner_radius_location_ = locations[index++]; + } + DCHECK_EQ(index, locations.size()); } +void FragmentShader::SetRoundedCornerFunctions( + std::string* shader_string) const { + if (!has_rounded_corner_) + return; + + static constexpr base::StringPiece kUniforms = SHADER0([]() { + uniform vec4 roundedCornerRect; + uniform vec4 roundedCornerRadius; + }); + + static constexpr base::StringPiece kFunctionRcUtility = SHADER0([]() { + // Returns a vector of size 4. Each component of a vector is set to 1 or 0 + // representing whether |rcCoord| is a part of the respective corner or + // not. + // The component ordering is: + // [Top left, Top right, Bottom right, Bottom left] + vec4 IsCorner(vec2 rcCoord) { + // Top left corner + if (rcCoord.x < roundedCornerRadius.x && + rcCoord.y < roundedCornerRadius.x) { + return vec4(1.0, 0.0, 0.0, 0.0); + } + + // Top right corner + if (rcCoord.x > roundedCornerRect.z - roundedCornerRadius.y && + rcCoord.y < roundedCornerRadius.y) { + return vec4(0.0, 1.0, 0.0, 0.0); + } + + // Bottom right corner + if (rcCoord.x > roundedCornerRect.z - roundedCornerRadius.z && + rcCoord.y > roundedCornerRect.w - roundedCornerRadius.z) { + return vec4(0.0, 0.0, 1.0, 0.0); + } + + // Bottom left corner + if (rcCoord.x < roundedCornerRadius.w && + rcCoord.y > roundedCornerRect.w - roundedCornerRadius.w) { + return vec4(0.0, 0.0, 0.0, 1.0); + } + return vec4(0.0, 0.0, 0.0, 0.0); + } + + // Returns the center of the rounded corner. |corner| holds the info on + // which corner the center is requested for. + vec2 GetCenter(vec4 corner, float radius) { + if (corner.x == 1.0) { + // Top left corner + return vec2(radius, radius); + } else if (corner.y == 1.0) { + // Top right corner + return vec2(roundedCornerRect.z - radius, radius); + } else if (corner.z == 1.0) { + // Bottom right corner + return vec2(roundedCornerRect.z - radius, roundedCornerRect.w - radius); + } else { + // Bottom left corner + return vec2(radius, roundedCornerRect.w - radius); + } + } + }); + + static constexpr base::StringPiece kFunctionApplyRoundedCorner = + SHADER0([]() { + vec4 ApplyRoundedCorner(vec4 src) { + vec2 rcCoord = gl_FragCoord.xy - roundedCornerRect.xy; + + // If outside bounds, then just clip everything. + if (rcCoord.x < 0.0 || rcCoord.y < 0.0 || + rcCoord.x > roundedCornerRect.z || + rcCoord.y > roundedCornerRect.w) { + return vec4(0.0); + } + + vec4 isCorner = IsCorner(rcCoord); + + // Get the radius to use based on the corner this fragment lies in. + float r = dot(isCorner, roundedCornerRadius); + + // If the radius is 0, then there is no rounded corner here. We can do + // an early return. + if (r == 0.0) + return src; + + // Vector to the corner's center this frag is in. + vec2 cornerCenter = GetCenter(isCorner, r); + + // Vector from the center of the corner to the current fragment center + vec2 cxy = rcCoord - cornerCenter; + + // Compute the distance of the fragment's center from the corner's + // center. + float fragDst = length(cxy); + + float alpha = smoothstep(r - 1.0, r + 1.0, fragDst); + return vec4(0.0) * alpha + src * (1.0 - alpha); + } + }); + + std::string shader; + shader.reserve(shader_string->size() + 2048); + shader += "precision mediump float;"; + kUniforms.AppendToString(&shader); + kFunctionRcUtility.AppendToString(&shader); + kFunctionApplyRoundedCorner.AppendToString(&shader); + shader += *shader_string; + *shader_string = std::move(shader); +} + void FragmentShader::SetBlendModeFunctions(std::string* shader_string) const { if (!has_blend_mode()) { return; @@ -1070,6 +1190,10 @@ } break; } + + if (has_rounded_corner_) + SRC("gl_FragColor = ApplyRoundedCorner(gl_FragColor);"); + source += "}\n"; return header + source;
diff --git a/components/viz/service/display/shader.h b/components/viz/service/display/shader.h index 7ab139c..10b45af5 100644 --- a/components/viz/service/display/shader.h +++ b/components/viz/service/display/shader.h
@@ -234,6 +234,7 @@ bool has_blend_mode() const { return blend_mode_ != BLEND_MODE_NONE; } void SetBlendModeFunctions(std::string* shader_string) const; + void SetRoundedCornerFunctions(std::string* shader_string) const; // Settings that are modified by sub-classes. AAMode aa_mode_ = NO_AA; @@ -308,6 +309,11 @@ int ya_clamp_rect_location_ = -1; int uv_clamp_rect_location_ = -1; + // Rounded corner locations + bool has_rounded_corner_ = false; + int rounded_corner_rect_location_ = -1; + int rounded_corner_radius_location_ = -1; + // The resource offset and multiplier to adjust for bit depth. int resource_multiplier_location_ = -1; int resource_offset_location_ = -1;
diff --git a/components/viz/test/data/rounded_corner_multi_radii.png b/components/viz/test/data/rounded_corner_multi_radii.png new file mode 100644 index 0000000..38e3fcf --- /dev/null +++ b/components/viz/test/data/rounded_corner_multi_radii.png Binary files differ
diff --git a/components/viz/test/data/rounded_corner_render_pass.png b/components/viz/test/data/rounded_corner_render_pass.png new file mode 100644 index 0000000..49f930b8 --- /dev/null +++ b/components/viz/test/data/rounded_corner_render_pass.png Binary files differ
diff --git a/components/viz/test/data/rounded_corner_simple.png b/components/viz/test/data/rounded_corner_simple.png new file mode 100644 index 0000000..257c2a3 --- /dev/null +++ b/components/viz/test/data/rounded_corner_simple.png Binary files differ
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index a420ebfd..49ab076 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1343,6 +1343,8 @@ "renderer_host/cursor_manager.h", "renderer_host/dip_util.cc", "renderer_host/dip_util.h", + "renderer_host/direct_manipulation_win.cc", + "renderer_host/direct_manipulation_win.h", "renderer_host/display_util.cc", "renderer_host/display_util.h", "renderer_host/dwrite_font_file_util_win.cc",
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc index 98dba09..5e3c314e 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.cc +++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -195,26 +195,37 @@ wcax->HandleSliderChanged(android_node->unique_id()); } break; + case ui::AXEventGenerator::Event::ACCESS_KEY_CHANGED: case ui::AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED: case ui::AXEventGenerator::Event::AUTO_COMPLETE_CHANGED: case ui::AXEventGenerator::Event::CHILDREN_CHANGED: + case ui::AXEventGenerator::Event::CLASS_NAME_CHANGED: case ui::AXEventGenerator::Event::COLLAPSED: + case ui::AXEventGenerator::Event::DESCRIBED_BY_CHANGED: case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED: case ui::AXEventGenerator::Event::DOCUMENT_TITLE_CHANGED: case ui::AXEventGenerator::Event::EXPANDED: + case ui::AXEventGenerator::Event::FLOW_TO_CHANGED: + case ui::AXEventGenerator::Event::HIERARCHICAL_LEVEL_CHANGED: case ui::AXEventGenerator::Event::IMAGE_ANNOTATION_CHANGED: case ui::AXEventGenerator::Event::INVALID_STATUS_CHANGED: + case ui::AXEventGenerator::Event::KEY_SHORTCUTS_CHANGED: + case ui::AXEventGenerator::Event::LABELED_BY_CHANGED: + case ui::AXEventGenerator::Event::LANGUAGE_CHANGED: case ui::AXEventGenerator::Event::LIVE_REGION_CHANGED: case ui::AXEventGenerator::Event::LIVE_REGION_CREATED: case ui::AXEventGenerator::Event::LOAD_START: case ui::AXEventGenerator::Event::MENU_ITEM_SELECTED: case ui::AXEventGenerator::Event::NAME_CHANGED: case ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED: + case ui::AXEventGenerator::Event::PLACEHOLDER_CHANGED: + case ui::AXEventGenerator::Event::POSITION_IN_SET_CHANGED: case ui::AXEventGenerator::Event::RELATED_NODE_CHANGED: case ui::AXEventGenerator::Event::ROLE_CHANGED: case ui::AXEventGenerator::Event::ROW_COUNT_CHANGED: case ui::AXEventGenerator::Event::SELECTED_CHANGED: case ui::AXEventGenerator::Event::SELECTED_CHILDREN_CHANGED: + case ui::AXEventGenerator::Event::SET_SIZE_CHANGED: case ui::AXEventGenerator::Event::STATE_CHANGED: // There are some notifications that aren't meaningful on Android. // It's okay to skip them.
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm index 4752532..3ed0d0d3 100644 --- a/content/browser/accessibility/browser_accessibility_manager_mac.mm +++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -371,19 +371,30 @@ case ui::AXEventGenerator::Event::MENU_ITEM_SELECTED: mac_notification = NSAccessibilityMenuItemSelectedNotification; break; + case ui::AXEventGenerator::Event::ACCESS_KEY_CHANGED: case ui::AXEventGenerator::Event::AUTO_COMPLETE_CHANGED: case ui::AXEventGenerator::Event::CHILDREN_CHANGED: + case ui::AXEventGenerator::Event::CLASS_NAME_CHANGED: + case ui::AXEventGenerator::Event::DESCRIBED_BY_CHANGED: case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED: case ui::AXEventGenerator::Event::DOCUMENT_TITLE_CHANGED: + case ui::AXEventGenerator::Event::FLOW_TO_CHANGED: + case ui::AXEventGenerator::Event::HIERARCHICAL_LEVEL_CHANGED: case ui::AXEventGenerator::Event::IMAGE_ANNOTATION_CHANGED: + case ui::AXEventGenerator::Event::KEY_SHORTCUTS_CHANGED: + case ui::AXEventGenerator::Event::LABELED_BY_CHANGED: + case ui::AXEventGenerator::Event::LANGUAGE_CHANGED: case ui::AXEventGenerator::Event::LIVE_REGION_NODE_CHANGED: case ui::AXEventGenerator::Event::LOAD_START: case ui::AXEventGenerator::Event::NAME_CHANGED: case ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED: + case ui::AXEventGenerator::Event::PLACEHOLDER_CHANGED: + case ui::AXEventGenerator::Event::POSITION_IN_SET_CHANGED: case ui::AXEventGenerator::Event::RELATED_NODE_CHANGED: case ui::AXEventGenerator::Event::ROLE_CHANGED: case ui::AXEventGenerator::Event::SCROLL_POSITION_CHANGED: case ui::AXEventGenerator::Event::SELECTED_CHANGED: + case ui::AXEventGenerator::Event::SET_SIZE_CHANGED: case ui::AXEventGenerator::Event::STATE_CHANGED: // There are some notifications that aren't meaningful on Mac. // It's okay to skip them.
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc index 7350db70..1180f70 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.cc +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -145,6 +145,9 @@ } switch (event_type) { + case ui::AXEventGenerator::Event::ACCESS_KEY_CHANGED: + FireUiaPropertyChangedEvent(UIA_AccessKeyPropertyId, node); + break; case ui::AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED: FireWinAccessibilityEvent(IA2_EVENT_ACTIVE_DESCENDANT_CHANGED, node); break; @@ -152,12 +155,58 @@ FireWinAccessibilityEvent(EVENT_SYSTEM_ALERT, node); FireUiaAccessibilityEvent(UIA_SystemAlertEventId, node); break; + case ui::AXEventGenerator::Event::CHECKED_STATE_CHANGED: + FireUiaPropertyChangedEvent(UIA_ToggleToggleStatePropertyId, node); + break; case ui::AXEventGenerator::Event::CHILDREN_CHANGED: FireWinAccessibilityEvent(EVENT_OBJECT_REORDER, node); break; + case ui::AXEventGenerator::Event::CLASS_NAME_CHANGED: + FireUiaPropertyChangedEvent(UIA_ClassNamePropertyId, node); + break; + case ui::AXEventGenerator::Event::COLLAPSED: + case ui::AXEventGenerator::Event::EXPANDED: + FireUiaPropertyChangedEvent( + UIA_ExpandCollapseExpandCollapseStatePropertyId, node); + break; + case ui::AXEventGenerator::Event::DESCRIBED_BY_CHANGED: + FireUiaPropertyChangedEvent(UIA_DescribedByPropertyId, node); + break; + case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED: + FireUiaPropertyChangedEvent(UIA_FullDescriptionPropertyId, node); + break; + case ui::AXEventGenerator::Event::DOCUMENT_SELECTION_CHANGED: { + // Fire the event on the object where the focus of the selection is. + int32_t focus_id = GetTreeData().sel_focus_object_id; + BrowserAccessibility* focus_object = GetFromID(focus_id); + if (focus_object && focus_object->HasVisibleCaretOrSelection()) + FireWinAccessibilityEvent(IA2_EVENT_TEXT_CARET_MOVED, focus_object); + break; + } + case ui::AXEventGenerator::Event::FLOW_TO_CHANGED: + FireUiaPropertyChangedEvent(UIA_FlowsToPropertyId, node); + break; + case ui::AXEventGenerator::Event::HIERARCHICAL_LEVEL_CHANGED: + FireUiaPropertyChangedEvent(UIA_LevelPropertyId, node); + break; case ui::AXEventGenerator::Event::IMAGE_ANNOTATION_CHANGED: FireWinAccessibilityEvent(EVENT_OBJECT_NAMECHANGE, node); break; + case ui::AXEventGenerator::Event::INVALID_STATUS_CHANGED: + FireUiaPropertyChangedEvent(UIA_IsDataValidForFormPropertyId, node); + break; + case ui::AXEventGenerator::Event::KEY_SHORTCUTS_CHANGED: + FireUiaPropertyChangedEvent(UIA_AcceleratorKeyPropertyId, node); + break; + case ui::AXEventGenerator::Event::LABELED_BY_CHANGED: + FireUiaPropertyChangedEvent(UIA_LabeledByPropertyId, node); + break; + case ui::AXEventGenerator::Event::LANGUAGE_CHANGED: + FireUiaPropertyChangedEvent(UIA_CulturePropertyId, node); + break; + case ui::AXEventGenerator::Event::LIVE_REGION_CREATED: + FireUiaPropertyChangedEvent(UIA_LiveSettingPropertyId, node); + break; case ui::AXEventGenerator::Event::LIVE_REGION_CHANGED: // This event is redundant with the IA2_EVENT_TEXT_INSERTED events; // however, JAWS 2018 and earlier do not process the text inserted @@ -175,50 +224,43 @@ case ui::AXEventGenerator::Event::LOAD_COMPLETE: FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_LOAD_COMPLETE, node); break; + case ui::AXEventGenerator::Event::NAME_CHANGED: + FireUiaPropertyChangedEvent(UIA_NamePropertyId, node); + break; + case ui::AXEventGenerator::Event::PLACEHOLDER_CHANGED: + FireUiaPropertyChangedEvent(UIA_HelpTextPropertyId, node); + break; + case ui::AXEventGenerator::Event::POSITION_IN_SET_CHANGED: + FireUiaPropertyChangedEvent(UIA_PositionInSetPropertyId, node); + break; + case ui::AXEventGenerator::Event::ROLE_CHANGED: + FireUiaPropertyChangedEvent(UIA_AriaRolePropertyId, node); + break; case ui::AXEventGenerator::Event::SCROLL_POSITION_CHANGED: FireWinAccessibilityEvent(EVENT_SYSTEM_SCROLLINGEND, node); break; + case ui::AXEventGenerator::Event::SELECTED_CHANGED: + HandleSelectedStateChanged(node); + break; case ui::AXEventGenerator::Event::SELECTED_CHILDREN_CHANGED: FireWinAccessibilityEvent(EVENT_OBJECT_SELECTIONWITHIN, node); break; - case ui::AXEventGenerator::Event::DOCUMENT_SELECTION_CHANGED: { - // Fire the event on the object where the focus of the selection is. - int32_t focus_id = GetTreeData().sel_focus_object_id; - BrowserAccessibility* focus_object = GetFromID(focus_id); - if (focus_object && focus_object->HasVisibleCaretOrSelection()) - FireWinAccessibilityEvent(IA2_EVENT_TEXT_CARET_MOVED, focus_object); + case ui::AXEventGenerator::Event::SET_SIZE_CHANGED: + FireUiaPropertyChangedEvent(UIA_SizeOfSetPropertyId, node); break; - } - case ui::AXEventGenerator::Event::SELECTED_CHANGED: - HandleSelectedStateChanged(node); + case ui::AXEventGenerator::Event::VALUE_CHANGED: + FireUiaPropertyChangedEvent(UIA_ValueValuePropertyId, node); break; - case ui::AXEventGenerator::Event::CHECKED_STATE_CHANGED: - FireUiaPropertyChangedEvent(UIA_ToggleToggleStatePropertyId, node); - break; - case ui::AXEventGenerator::Event::EXPANDED: - case ui::AXEventGenerator::Event::COLLAPSED: - FireUiaPropertyChangedEvent( - UIA_ExpandCollapseExpandCollapseStatePropertyId, node); - break; - case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED: - FireUiaPropertyChangedEvent(UIA_FullDescriptionPropertyId, node); - break; - case ui::AXEventGenerator::Event::INVALID_STATUS_CHANGED: - FireUiaPropertyChangedEvent(UIA_IsDataValidForFormPropertyId, node); - break; + case ui::AXEventGenerator::Event::AUTO_COMPLETE_CHANGED: case ui::AXEventGenerator::Event::DOCUMENT_TITLE_CHANGED: - case ui::AXEventGenerator::Event::LIVE_REGION_CREATED: case ui::AXEventGenerator::Event::LIVE_REGION_NODE_CHANGED: case ui::AXEventGenerator::Event::LOAD_START: case ui::AXEventGenerator::Event::MENU_ITEM_SELECTED: - case ui::AXEventGenerator::Event::NAME_CHANGED: case ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED: case ui::AXEventGenerator::Event::RELATED_NODE_CHANGED: - case ui::AXEventGenerator::Event::ROLE_CHANGED: case ui::AXEventGenerator::Event::ROW_COUNT_CHANGED: case ui::AXEventGenerator::Event::STATE_CHANGED: - case ui::AXEventGenerator::Event::VALUE_CHANGED: // There are some notifications that aren't meaningful on Windows. // It's okay to skip them. break;
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 697dc4929..f843a47 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -1378,8 +1378,14 @@ DCHECK(render_frame_host_); - NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL(render_frame_host_, - common_params_.url); + // The check for WebUI should be performed only if error page isolation is + // enabled for this failed navigation. It is possible for subframe error page + // to be committed in a WebUI process as shown in https://crbug.com/944086. + if (SiteIsolationPolicy::IsErrorPageIsolationEnabled( + frame_tree_node_->IsMainFrame())) { + NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL( + render_frame_host_, common_params_.url); + } has_stale_copy_in_cache_ = status.exists_in_cache;
diff --git a/content/browser/frame_host/webui_navigation_browsertest.cc b/content/browser/frame_host/webui_navigation_browsertest.cc index aa8fedce..1dc739e 100644 --- a/content/browser/frame_host/webui_navigation_browsertest.cc +++ b/content/browser/frame_host/webui_navigation_browsertest.cc
@@ -147,9 +147,11 @@ // TODO(nasko): Replace this URL with one with a custom WebUI object that // doesn't have restrictive CSP, so the test can successfully add an - // iframe and test the actual throttle blocking. Currently the CSP policy - // will just block the navigation prior to the throttle being even - // invoked. See http://crbug.com/776900. + // iframe and test the actual throttle blocking. The default CSP policy + // on WebUI objects will just block the navigation prior to the throttle + // being even invoked. For now use the blob-internals URL, which is not + // backed by WebUI and does not have CSP policy attached to it. + // See http://crbug.com/776900. GURL chrome_url = GURL(std::string(kChromeUIScheme) + "://" + std::string(kChromeUIBlobInternalsHost)); EXPECT_TRUE(NavigateToURL(shell(), chrome_url)); @@ -206,6 +208,34 @@ } } +// Verify that a chrome: scheme document cannot add iframes with web content +// and does not crash if the navigation is blocked by CSP. +// See https://crbug.com/944086. +IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest, + WebFrameInChromeSchemeDisallowedByCSP) { + // Use the chrome://gpu WebUI, which has a restrictive CSP disallowing + // subframes. This will cause the navigation to fail due to the CSP check + // and ensure this behaves the same way as the repros steps in + // https://crbug.com/944086. + GURL chrome_url = GURL(std::string(kChromeUIScheme) + "://" + + std::string(kChromeUIGpuHost)); + EXPECT_TRUE(NavigateToURL(shell(), chrome_url)); + EXPECT_EQ(chrome_url, shell()->web_contents()->GetLastCommittedURL()); + + { + GURL web_url(embedded_test_server()->GetURL("/title2.html")); + TestNavigationObserver navigation_observer(shell()->web_contents()); + EXPECT_TRUE(ExecJs( + shell(), JsReplace("var frame = document.createElement('iframe');\n" + "frame.src = $1;\n" + "document.body.appendChild(frame);\n", + web_url))); + navigation_observer.Wait(); + + EXPECT_FALSE(navigation_observer.last_navigation_succeeded()); + } +} + // Verify that a WebUI document in the main frame is allowed to navigate to // web content and it properly does cross-process navigation. IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest, WebUIMainFrameToWebAllowed) {
diff --git a/content/browser/media/capture/screen_capture_device_android_unittest.cc b/content/browser/media/capture/screen_capture_device_android_unittest.cc index ef59073..ca204dd 100644 --- a/content/browser/media/capture/screen_capture_device_android_unittest.cc +++ b/content/browser/media/capture/screen_capture_device_android_unittest.cc
@@ -63,6 +63,7 @@ void OnIncomingCapturedBufferExt( Buffer buffer, const media::VideoCaptureFormat& format, + const gfx::ColorSpace& color_space, base::TimeTicks reference_time, base::TimeDelta timestamp, gfx::Rect visible_rect,
diff --git a/ui/base/win/direct_manipulation.cc b/content/browser/renderer_host/direct_manipulation_win.cc similarity index 95% rename from ui/base/win/direct_manipulation.cc rename to content/browser/renderer_host/direct_manipulation_win.cc index f38da1c..fca09cb6 100644 --- a/ui/base/win/direct_manipulation.cc +++ b/content/browser/renderer_host/direct_manipulation_win.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 "ui/base/win/direct_manipulation.h" +#include "content/browser/renderer_host/direct_manipulation_win.h" #include <objbase.h> #include <cmath> @@ -15,8 +15,7 @@ #include "ui/display/win/screen_win.h" #include "ui/gfx/geometry/rect.h" -namespace ui { -namespace win { +namespace content { namespace { @@ -42,7 +41,7 @@ // static std::unique_ptr<DirectManipulationHelper> DirectManipulationHelper::CreateInstance(HWND window, - WindowEventTarget* event_target) { + ui::WindowEventTarget* event_target) { if (!::IsWindow(window)) return nullptr; @@ -66,7 +65,7 @@ // static std::unique_ptr<DirectManipulationHelper> DirectManipulationHelper::CreateInstanceForTesting( - WindowEventTarget* event_target, + ui::WindowEventTarget* event_target, Microsoft::WRL::ComPtr<IDirectManipulationViewport> viewport) { if (!base::FeatureList::IsEnabled(features::kPrecisionTouchpad)) return nullptr; @@ -78,8 +77,9 @@ std::unique_ptr<DirectManipulationHelper> instance = base::WrapUnique(new DirectManipulationHelper()); - instance->event_handler_ = Microsoft::WRL::Make<DirectManipulationHandler>( - instance.get(), event_target); + instance->event_handler_ = + Microsoft::WRL::Make<DirectManipulationHandler>(instance.get()); + instance->event_handler_->SetWindowEventTarget(event_target); instance->viewport_ = viewport; @@ -93,7 +93,7 @@ DirectManipulationHelper::DirectManipulationHelper() {} -bool DirectManipulationHelper::Initialize(WindowEventTarget* event_target) { +bool DirectManipulationHelper::Initialize(ui::WindowEventTarget* event_target) { // IDirectManipulationUpdateManager is the first COM object created by the // application to retrieve other objects in the Direct Manipulation API. // It also serves to activate and deactivate Direct Manipulation functionality @@ -144,8 +144,8 @@ return false; } - event_handler_ = - Microsoft::WRL::Make<DirectManipulationHandler>(this, event_target); + event_handler_ = Microsoft::WRL::Make<DirectManipulationHandler>(this); + event_handler_->SetWindowEventTarget(event_target); // We got Direct Manipulation transform from // IDirectManipulationViewportEventHandler. @@ -230,7 +230,7 @@ bool DirectManipulationHelper::OnPointerHitTest( WPARAM w_param, - WindowEventTarget* event_target) { + ui::WindowEventTarget* event_target) { // Update the device scale factor. event_handler_->SetDeviceScaleFactor( display::win::ScreenWin::GetScaleFactorForHWND(window_)); @@ -296,9 +296,8 @@ } DirectManipulationHandler::DirectManipulationHandler( - DirectManipulationHelper* helper, - WindowEventTarget* event_target) - : helper_(helper), event_target_(event_target) {} + DirectManipulationHelper* helper) + : helper_(helper) {} DirectManipulationHandler::~DirectManipulationHandler() {} @@ -565,7 +564,7 @@ } void DirectManipulationHandler::SetWindowEventTarget( - WindowEventTarget* event_target) { + ui::WindowEventTarget* event_target) { if (!event_target && LoggingEnabled()) { DebugLogging("Event target is null.", S_OK); if (event_target_) { @@ -582,5 +581,4 @@ device_scale_factor_ = device_scale_factor; } -} // namespace win -} // namespace ui +} // namespace content
diff --git a/ui/base/win/direct_manipulation.h b/content/browser/renderer_host/direct_manipulation_win.h similarity index 87% rename from ui/base/win/direct_manipulation.h rename to content/browser/renderer_host/direct_manipulation_win.h index 2f709b2..1f759a8 100644 --- a/ui/base/win/direct_manipulation.h +++ b/content/browser/renderer_host/direct_manipulation_win.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 UI_WIN_DIRECT_MANIPULATION_H_ -#define UI_WIN_DIRECT_MANIPULATION_H_ +#ifndef CONTENT_BROWSER_RENDERER_HOST_DIRECT_MANIPULATION_WIN_H_ +#define CONTENT_BROWSER_RENDERER_HOST_DIRECT_MANIPULATION_WIN_H_ #include <windows.h> @@ -13,20 +13,15 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" -#include "ui/base/ui_base_export.h" +#include "content/common/content_export.h" #include "ui/base/win/window_event_target.h" #include "ui/gfx/geometry/size.h" namespace content { + class DirectManipulationBrowserTest; -} // namespace content - -namespace ui { -namespace win { - -class DirectManipulationUnitTest; - class DirectManipulationHelper; +class DirectManipulationUnitTest; // DirectManipulationHandler receives status update and gesture events from // Direct Manipulation API. @@ -40,12 +35,11 @@ Microsoft::WRL::FtmBase, IDirectManipulationViewportEventHandler>> { public: - explicit DirectManipulationHandler(DirectManipulationHelper* helper, - WindowEventTarget* event_target); + explicit DirectManipulationHandler(DirectManipulationHelper* helper); // WindowEventTarget updates for every DM_POINTERHITTEST in case window // hierarchy changed. - void SetWindowEventTarget(WindowEventTarget* event_target); + void SetWindowEventTarget(ui::WindowEventTarget* event_target); void SetDeviceScaleFactor(float device_scale_factor); @@ -72,7 +66,7 @@ _In_ IDirectManipulationContent* content) override; DirectManipulationHelper* helper_ = nullptr; - WindowEventTarget* event_target_ = nullptr; + ui::WindowEventTarget* event_target_ = nullptr; float device_scale_factor_ = 1.0f; float last_scale_ = 1.0f; int last_x_offset_ = 0; @@ -95,18 +89,18 @@ // when DM_POINTERHITTEST. // 3. OnViewportStatusChanged will be called when the gesture phase change. // OnContentUpdated will be called when the gesture update. -class UI_BASE_EXPORT DirectManipulationHelper { +class CONTENT_EXPORT DirectManipulationHelper { public: // Creates and initializes an instance of this class if Direct Manipulation is // enabled on the platform. Returns nullptr if it disabled or failed on // initialization. static std::unique_ptr<DirectManipulationHelper> CreateInstance( HWND window, - WindowEventTarget* event_target); + ui::WindowEventTarget* event_target); // Creates and initializes an instance for testing. static std::unique_ptr<DirectManipulationHelper> CreateInstanceForTesting( - WindowEventTarget* event_target, + ui::WindowEventTarget* event_target, Microsoft::WRL::ComPtr<IDirectManipulationViewport> viewport); ~DirectManipulationHelper(); @@ -126,7 +120,7 @@ // Pass the pointer hit test to Direct Manipulation. Return true indicated we // need poll for new events every frame from here. - bool OnPointerHitTest(WPARAM w_param, WindowEventTarget* event_target); + bool OnPointerHitTest(WPARAM w_param, ui::WindowEventTarget* event_target); // On each frame poll new Direct Manipulation events. Return true if we still // need poll for new events on next frame, otherwise stop request need begin @@ -141,7 +135,7 @@ // This function instantiates Direct Manipulation and creates a viewport for // the passed in |window|. Return false if initialize failed. - bool Initialize(WindowEventTarget* event_target); + bool Initialize(ui::WindowEventTarget* event_target); void SetDeviceScaleFactorForTesting(float factor); @@ -157,7 +151,6 @@ DISALLOW_COPY_AND_ASSIGN(DirectManipulationHelper); }; -} // namespace win -} // namespace ui +} // namespace content -#endif // UI_WIN_DIRECT_MANIPULATION_H_ +#endif // CONTENT_BROWSER_RENDERER_HOST_DIRECT_MANIPULATION_WIN_H_
diff --git a/content/browser/renderer_host/direct_manipulation_browsertest.cc b/content/browser/renderer_host/direct_manipulation_win_browsertest.cc similarity index 99% rename from content/browser/renderer_host/direct_manipulation_browsertest.cc rename to content/browser/renderer_host/direct_manipulation_win_browsertest.cc index 07b0aa2..b6855d4 100644 --- a/content/browser/renderer_host/direct_manipulation_browsertest.cc +++ b/content/browser/renderer_host/direct_manipulation_win_browsertest.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 "ui/base/win/direct_manipulation.h" +#include "content/browser/renderer_host/direct_manipulation_win.h" #include <windows.h>
diff --git a/ui/base/win/direct_manipulation_unittest.cc b/content/browser/renderer_host/direct_manipulation_win_unittest.cc similarity index 98% rename from ui/base/win/direct_manipulation_unittest.cc rename to content/browser/renderer_host/direct_manipulation_win_unittest.cc index 79d4bb77..5483889 100644 --- a/ui/base/win/direct_manipulation_unittest.cc +++ b/content/browser/renderer_host/direct_manipulation_win_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/base/win/direct_manipulation.h" +#include "content/browser/renderer_host/direct_manipulation_win.h" #include <objbase.h> @@ -12,9 +12,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ui_base_features.h" -namespace ui { - -namespace win { +namespace content { namespace { @@ -265,7 +263,7 @@ float scroll_y_ = 0; }; -class MockWindowEventTarget : public WindowEventTarget { +class MockWindowEventTarget : public ui::WindowEventTarget { public: MockWindowEventTarget() {} @@ -751,6 +749,4 @@ EXPECT_EQ(5, events[0].scroll_x_); } -} // namespace win - -} // namespace ui \ No newline at end of file +} // namespace content
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.cc b/content/browser/renderer_host/legacy_render_widget_host_win.cc index 2467b4b..492bbaaffa 100644 --- a/content/browser/renderer_host/legacy_render_widget_host_win.cc +++ b/content/browser/renderer_host/legacy_render_widget_host_win.cc
@@ -14,6 +14,7 @@ #include "content/browser/accessibility/browser_accessibility_manager_win.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "content/browser/accessibility/browser_accessibility_win.h" +#include "content/browser/renderer_host/direct_manipulation_win.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_aura.h" #include "content/public/common/content_switches.h" @@ -24,7 +25,6 @@ #include "ui/aura/window_tree_host.h" #include "ui/base/ui_base_features.h" #include "ui/base/view_prop.h" -#include "ui/base/win/direct_manipulation.h" #include "ui/base/win/internal_constants.h" #include "ui/base/win/window_event_target.h" #include "ui/compositor/compositor.h" @@ -214,9 +214,8 @@ // Direct Manipulation is enabled on Windows 10+. The CreateInstance function // returns NULL if Direct Manipulation is not available. - direct_manipulation_helper_ = - ui::win::DirectManipulationHelper::CreateInstance( - hwnd(), GetWindowEventTarget(GetParent())); + direct_manipulation_helper_ = DirectManipulationHelper::CreateInstance( + hwnd(), GetWindowEventTarget(GetParent())); // Disable pen flicks (http://crbug.com/506977) base::win::DisableFlicks(hwnd());
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.h b/content/browser/renderer_host/legacy_render_widget_host_win.h index ec2ec68..1f7e1f0 100644 --- a/content/browser/renderer_host/legacy_render_widget_host_win.h +++ b/content/browser/renderer_host/legacy_render_widget_host_win.h
@@ -21,17 +21,14 @@ namespace ui { class AXFragmentRootWin; class AXSystemCaretWin; -class DirectManipulationHelper; class WindowEventTarget; -namespace win { -class DirectManipulationHelper; -} // namespace win } // namespace ui namespace content { -class RenderWidgetHostViewAura; class DirectManipulationBrowserTest; +class DirectManipulationHelper; +class RenderWidgetHostViewAura; // Reasons for the existence of this class outlined below:- // 1. Some screen readers expect every tab / every unique web content container @@ -188,8 +185,7 @@ // This class provides functionality to register the legacy window as a // Direct Manipulation consumer. This allows us to support smooth scroll // in Chrome on Windows 10. - std::unique_ptr<ui::win::DirectManipulationHelper> - direct_manipulation_helper_; + std::unique_ptr<DirectManipulationHelper> direct_manipulation_helper_; std::unique_ptr<ui::CompositorAnimationObserver> compositor_animation_observer_;
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index b2edd8c..8ec3d837 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -528,11 +528,11 @@ "//services/video_capture/public/mojom", "//services/viz/public/interfaces", "//services/ws/public/mojom", - "//services/ws/public/mojom/ime", "//skia/public/interfaces", "//third_party/blink/public:mojo_bindings", "//third_party/blink/public/mojom:mojom_core", "//third_party/blink/public/mojom:web_feature_mojo_bindings", + "//ui/base/ime/mojo", "//ui/base/mojo", "//ui/events/mojo:interfaces", "//ui/gfx/geometry/mojo",
diff --git a/content/common/content_param_traits_macros.h b/content/common/content_param_traits_macros.h index e5663ef..a840303 100644 --- a/content/common/content_param_traits_macros.h +++ b/content/common/content_param_traits_macros.h
@@ -42,8 +42,8 @@ blink::WebInputEvent::kTypeLast) IPC_ENUM_TRAITS_MAX_VALUE(blink::WebImeTextSpan::Type, blink::WebImeTextSpan::Type::kMisspellingSuggestion) -IPC_ENUM_TRAITS_MAX_VALUE(ws::mojom::ImeTextSpanThickness, - ws::mojom::ImeTextSpanThickness::kThick) +IPC_ENUM_TRAITS_MAX_VALUE(ui::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanThickness::kThick) IPC_STRUCT_TRAITS_BEGIN(viz::Selection<gfx::SelectionBound>) IPC_STRUCT_TRAITS_MEMBER(start)
diff --git a/content/common/input/ime_text_span_conversions.cc b/content/common/input/ime_text_span_conversions.cc index 0898ec4..be91d760 100644 --- a/content/common/input/ime_text_span_conversions.cc +++ b/content/common/input/ime_text_span_conversions.cc
@@ -38,29 +38,29 @@ return ui::ImeTextSpan::Type::kComposition; } -ws::mojom::ImeTextSpanThickness ConvertUiThicknessToUiImeTextSpanThickness( +ui::mojom::ImeTextSpanThickness ConvertUiThicknessToUiImeTextSpanThickness( ui::ImeTextSpan::Thickness thickness) { switch (thickness) { case ui::ImeTextSpan::Thickness::kNone: - return ws::mojom::ImeTextSpanThickness::kNone; + return ui::mojom::ImeTextSpanThickness::kNone; case ui::ImeTextSpan::Thickness::kThin: - return ws::mojom::ImeTextSpanThickness::kThin; + return ui::mojom::ImeTextSpanThickness::kThin; case ui::ImeTextSpan::Thickness::kThick: - return ws::mojom::ImeTextSpanThickness::kThick; + return ui::mojom::ImeTextSpanThickness::kThick; } NOTREACHED(); - return ws::mojom::ImeTextSpanThickness::kThin; + return ui::mojom::ImeTextSpanThickness::kThin; } ui::ImeTextSpan::Thickness ConvertUiImeTextSpanThicknessToUiThickness( - ws::mojom::ImeTextSpanThickness thickness) { + ui::mojom::ImeTextSpanThickness thickness) { switch (thickness) { - case ws::mojom::ImeTextSpanThickness::kNone: + case ui::mojom::ImeTextSpanThickness::kNone: return ui::ImeTextSpan::Thickness::kNone; - case ws::mojom::ImeTextSpanThickness::kThin: + case ui::mojom::ImeTextSpanThickness::kThin: return ui::ImeTextSpan::Thickness::kThin; - case ws::mojom::ImeTextSpanThickness::kThick: + case ui::mojom::ImeTextSpanThickness::kThick: return ui::ImeTextSpan::Thickness::kThick; }
diff --git a/content/common/input/ime_text_span_conversions.h b/content/common/input/ime_text_span_conversions.h index 846a550fa..18353d30 100644 --- a/content/common/input/ime_text_span_conversions.h +++ b/content/common/input/ime_text_span_conversions.h
@@ -14,10 +14,10 @@ ui::ImeTextSpan::Type type); ui::ImeTextSpan::Type ConvertWebImeTextSpanTypeToUiType( blink::WebImeTextSpan::Type type); -ws::mojom::ImeTextSpanThickness ConvertUiThicknessToUiImeTextSpanThickness( +ui::mojom::ImeTextSpanThickness ConvertUiThicknessToUiImeTextSpanThickness( ui::ImeTextSpan::Thickness thickness); ui::ImeTextSpan::Thickness ConvertUiImeTextSpanThicknessToUiThickness( - ws::mojom::ImeTextSpanThickness thickness); + ui::mojom::ImeTextSpanThickness thickness); blink::WebImeTextSpan ConvertUiImeTextSpanToBlinkImeTextSpan( const ui::ImeTextSpan&); ui::ImeTextSpan ConvertBlinkImeTextSpanToUiImeTextSpan(
diff --git a/content/common/input/input_handler.mojom b/content/common/input/input_handler.mojom index 5ffd883..484d0ca 100644 --- a/content/common/input/input_handler.mojom +++ b/content/common/input/input_handler.mojom
@@ -8,8 +8,8 @@ import "content/common/native_types.mojom"; import "mojo/public/mojom/base/string16.mojom"; import "mojo/public/mojom/base/time.mojom"; -import "services/ws/public/mojom/ime/ime.mojom"; import "third_party/blink/public/mojom/selection_menu/selection_menu_behavior.mojom"; +import "ui/base/ime/mojo/ime_types.mojom"; import "ui/events/mojo/event.mojom"; import "ui/events/mojo/event_constants.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; @@ -228,13 +228,13 @@ // This message sends a string being composed with an input method. ImeSetComposition(mojo_base.mojom.String16 text, - array<ws.mojom.ImeTextSpan> ime_text_spans, + array<ui.mojom.ImeTextSpan> ime_text_spans, gfx.mojom.Range range, int32 start, int32 end); // This message deletes the current composition, inserts specified text, and // moves the cursor. ImeCommitText(mojo_base.mojom.String16 text, - array<ws.mojom.ImeTextSpan> ime_text_spans, + array<ui.mojom.ImeTextSpan> ime_text_spans, gfx.mojom.Range range, int32 relative_cursor_position) => (); // This message inserts the ongoing composition. @@ -290,7 +290,7 @@ // Sets the text composition to be between the given start and end offsets in // the currently focused editable field. SetCompositionFromExistingText( - int32 start, int32 end, array<ws.mojom.ImeTextSpan> ime_text_spans); + int32 start, int32 end, array<ui.mojom.ImeTextSpan> ime_text_spans); // Deletes the current selection plus the specified number of characters // before and after the selection or caret.
diff --git a/content/common/render_widget_host_ns_view.mojom b/content/common/render_widget_host_ns_view.mojom index 0dbe014..797404e 100644 --- a/content/common/render_widget_host_ns_view.mojom +++ b/content/common/render_widget_host_ns_view.mojom
@@ -7,7 +7,6 @@ import "content/common/native_types.mojom"; import "content/common/input/input_handler.mojom"; import "mojo/public/mojom/base/string16.mojom"; -import "services/ws/public/mojom/ime/ime.mojom"; import "ui/base/ime/mojo/ime_types.mojom"; import "ui/display/mojo/display.mojom"; import "ui/events/mojo/event.mojom"; @@ -168,7 +167,7 @@ // it is the result of GetActiveWidget. ImeSetComposition( mojo_base.mojom.String16 text, - array<ws.mojom.ImeTextSpan> ime_text_spans, + array<ui.mojom.ImeTextSpan> ime_text_spans, gfx.mojom.Range replacement_range, int32 selection_start, int32 selection_end);
diff --git a/content/common/sandbox_init_mac.cc b/content/common/sandbox_init_mac.cc index 0a4a263..398a3454 100644 --- a/content/common/sandbox_init_mac.cc +++ b/content/common/sandbox_init_mac.cc
@@ -15,7 +15,7 @@ #include "gpu/config/gpu_switches.h" #include "gpu/config/gpu_switching.h" #include "gpu/config/gpu_util.h" -#include "media/gpu/vt_video_decode_accelerator_mac.h" +#include "media/gpu/mac/vt_video_decode_accelerator_mac.h" #include "sandbox/mac/seatbelt.h" #include "sandbox/mac/seatbelt_exec.h" #include "services/service_manager/sandbox/mac/sandbox_mac.h"
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java index 21575052..e938cae 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java
@@ -488,9 +488,6 @@ case ChildProcessImportance.IMPORTANT: connection.addStrongBinding(); break; - case ChildProcessImportance.COUNT: - assert false; - break; default: assert false; } @@ -513,9 +510,6 @@ case ChildProcessImportance.IMPORTANT: connection.removeStrongBinding(); break; - case ChildProcessImportance.COUNT: - assert false; - break; default: assert false; }
diff --git a/content/public/browser/android/child_process_importance.h b/content/public/browser/android/child_process_importance.h index 45b3afa..4e2baea 100644 --- a/content/public/browser/android/child_process_importance.h +++ b/content/public/browser/android/child_process_importance.h
@@ -17,8 +17,6 @@ NORMAL = 0, MODERATE, IMPORTANT, - // Place holder to represent number of values. - COUNT, }; } // namespace content
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index a820de5..c2ebfd7 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -1917,6 +1917,12 @@ return false; } +void WaitForAccessibilityTreeToChange(WebContents* web_contents) { + AccessibilityNotificationWaiter accessibility_waiter( + web_contents, ui::AXMode(), ax::mojom::Event::kNone); + accessibility_waiter.WaitForNotification(); +} + void WaitForAccessibilityTreeToContainNodeWithName(WebContents* web_contents, const std::string& name) { WebContentsImpl* web_contents_impl = static_cast<WebContentsImpl*>( @@ -1927,9 +1933,7 @@ main_frame->browser_accessibility_manager(); while (!main_frame_manager || !AccessibilityTreeContainsNodeWithName( main_frame_manager->GetRoot(), name)) { - AccessibilityNotificationWaiter accessibility_waiter( - web_contents, ui::AXMode(), ax::mojom::Event::kNone); - accessibility_waiter.WaitForNotification(); + WaitForAccessibilityTreeToChange(web_contents); main_frame_manager = main_frame->browser_accessibility_manager(); } }
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 6c71c90..37f3a16 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -848,13 +848,14 @@ // This is intended to be a robust way to assert that the accessibility // tree eventually gets into the correct state, without worrying about -// the exact ordering of events received while getting there. -// +// the exact ordering of events received while getting there. Blocks +// until any change happens to the accessibility tree. +void WaitForAccessibilityTreeToChange(WebContents* web_contents); + // Searches the accessibility tree to see if any node's accessible name -// is equal to the given name. If not, sets up a notification waiter -// that listens for any accessibility event in any frame, and checks again -// after each event. Keeps looping until the text is found (or the -// test times out). +// is equal to the given name. If not, repeatedly calls +// WaitForAccessibilityTreeToChange, above, and then checks again. +// Keeps looping until the text is found (or the test times out). void WaitForAccessibilityTreeToContainNodeWithName(WebContents* web_contents, const std::string& name);
diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc index 0379d1d..dfc2a8d8 100644 --- a/content/renderer/media/video_capture_impl.cc +++ b/content/renderer/media/video_capture_impl.cc
@@ -452,6 +452,9 @@ &VideoCaptureImpl::OnAllClientsFinishedConsumingFrame, weak_factory_.GetWeakPtr(), buffer_id, std::move(buffer_context))))); + if (info->color_space.has_value() && info->color_space->IsValid()) + frame->set_color_space(info->color_space.value()); + frame->metadata()->MergeInternalValuesFrom(info->metadata); // TODO(qiangchen): Dive into the full code path to let frame metadata hold
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc index 02dd519..2f635880 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -1011,7 +1011,7 @@ // Set the composition target. for (size_t i = 0; i < ime_text_spans.size(); ++i) { if (ime_text_spans[i].thickness == - ws::mojom::ImeTextSpanThickness::kThick) { + ui::mojom::ImeTextSpanThickness::kThick) { auto it = std::find(event.composition_segment_offsets.begin(), event.composition_segment_offsets.end(), utf8_offsets[2 * i + 2]); @@ -2393,7 +2393,7 @@ ime_text_span.start_offset = offsets[i]; ime_text_span.end_offset = offsets[i + 1]; if (input_event.composition_target_segment == static_cast<int32_t>(i - 2)) - ime_text_span.thickness = ws::mojom::ImeTextSpanThickness::kThick; + ime_text_span.thickness = ui::mojom::ImeTextSpanThickness::kThick; ime_text_spans.push_back(ime_text_span); }
diff --git a/content/shell/browser/shell_web_contents_view_delegate_views.cc b/content/shell/browser/shell_web_contents_view_delegate_views.cc index 937639f..9289cdb9 100644 --- a/content/shell/browser/shell_web_contents_view_delegate_views.cc +++ b/content/shell/browser/shell_web_contents_view_delegate_views.cc
@@ -93,7 +93,7 @@ web_contents_->GetTopLevelNativeWindow()); context_menu_runner_->RunMenuAt( widget, nullptr, gfx::Rect(screen_point, gfx::Size()), - views::MENU_ANCHOR_TOPRIGHT, ui::MENU_SOURCE_NONE); + views::MenuAnchorPosition::kTopRight, ui::MENU_SOURCE_NONE); } } // namespace content
diff --git a/content/shell/test_runner/text_input_controller.cc b/content/shell/test_runner/text_input_controller.cc index 74b6018f..a2681bc5 100644 --- a/content/shell/test_runner/text_input_controller.cc +++ b/content/shell/test_runner/text_input_controller.cc
@@ -273,12 +273,12 @@ ime_text_span.start_offset = start; ime_text_span.end_offset = start + length; } - ime_text_span.thickness = ws::mojom::ImeTextSpanThickness::kThick; + ime_text_span.thickness = ui::mojom::ImeTextSpanThickness::kThick; ime_text_spans.push_back(ime_text_span); if (start + length < static_cast<int>(web_text.length())) { ime_text_span.start_offset = ime_text_span.end_offset; ime_text_span.end_offset = web_text.length(); - ime_text_span.thickness = ws::mojom::ImeTextSpanThickness::kThin; + ime_text_span.thickness = ui::mojom::ImeTextSpanThickness::kThin; ime_text_spans.push_back(ime_text_span); } @@ -385,7 +385,7 @@ std::vector<blink::WebImeTextSpan> ime_text_spans; ime_text_spans.push_back(blink::WebImeTextSpan( blink::WebImeTextSpan::Type::kComposition, 0, textLength, - ws::mojom::ImeTextSpanThickness::kThin, SK_ColorTRANSPARENT)); + ui::mojom::ImeTextSpanThickness::kThin, SK_ColorTRANSPARENT)); if (auto* controller = GetInputMethodController()) { controller->SetComposition( newText, blink::WebVector<blink::WebImeTextSpan>(ime_text_spans),
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 2e60501c..212e7766 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1145,7 +1145,7 @@ "../browser/accessibility/accessibility_win_browsertest.cc", "../browser/accessibility/ax_platform_node_win_browsertest.cc", "../browser/renderer_host/accessibility_tree_linkage_win_browsertest.cc", - "../browser/renderer_host/direct_manipulation_browsertest.cc", + "../browser/renderer_host/direct_manipulation_win_browsertest.cc", ] deps += [ @@ -1581,6 +1581,7 @@ "../browser/presentation/presentation_service_impl_unittest.cc", "../browser/renderer_host/clipboard_host_impl_unittest.cc", "../browser/renderer_host/cursor_manager_unittest.cc", + "../browser/renderer_host/direct_manipulation_win_unittest.cc", "../browser/renderer_host/dwrite_font_lookup_table_builder_win_unittest.cc", "../browser/renderer_host/dwrite_font_proxy_impl_win_unittest.cc", "../browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc",
diff --git a/content/test/data/accessibility/event/description-change-expected-uia-win.txt b/content/test/data/accessibility/event/description-change-expected-uia-win.txt index 367dbfc..bf611803 100644 --- a/content/test/data/accessibility/event/description-change-expected-uia-win.txt +++ b/content/test/data/accessibility/event/description-change-expected-uia-win.txt
@@ -1 +1,2 @@ +DescribedBy changed on role=heading, name=Before FullDescription changed on role=heading, name=Before
diff --git a/content/test/data/accessibility/event/description-change-expected-uia-win7.txt b/content/test/data/accessibility/event/description-change-expected-uia-win7.txt index e69de29..8a4ad677 100644 --- a/content/test/data/accessibility/event/description-change-expected-uia-win7.txt +++ b/content/test/data/accessibility/event/description-change-expected-uia-win7.txt
@@ -0,0 +1 @@ +DescribedBy changed on role=heading, name=Before
diff --git a/content/test/data/accessibility/event/description-change-indirect-expected-uia-win.txt b/content/test/data/accessibility/event/description-change-indirect-expected-uia-win.txt index 4ba19bd..f2d9c8f 100644 --- a/content/test/data/accessibility/event/description-change-indirect-expected-uia-win.txt +++ b/content/test/data/accessibility/event/description-change-indirect-expected-uia-win.txt
@@ -1 +1,2 @@ FullDescription changed on role=main +Name changed on role=heading, name=oranges
diff --git a/content/test/data/accessibility/event/description-change-indirect-expected-uia-win7.txt b/content/test/data/accessibility/event/description-change-indirect-expected-uia-win7.txt index e69de29..297423e 100644 --- a/content/test/data/accessibility/event/description-change-indirect-expected-uia-win7.txt +++ b/content/test/data/accessibility/event/description-change-indirect-expected-uia-win7.txt
@@ -0,0 +1 @@ +Name changed on role=heading, name=oranges
diff --git a/content/test/data/accessibility/event/live-region-change-expected-uia-win.txt b/content/test/data/accessibility/event/live-region-change-expected-uia-win.txt new file mode 100644 index 0000000..6dc8b6a --- /dev/null +++ b/content/test/data/accessibility/event/live-region-change-expected-uia-win.txt
@@ -0,0 +1 @@ +Name changed on role=description, name=After
diff --git a/content/test/data/accessibility/event/live-region-create-expected-uia-win.txt b/content/test/data/accessibility/event/live-region-create-expected-uia-win.txt new file mode 100644 index 0000000..bedabc06 --- /dev/null +++ b/content/test/data/accessibility/event/live-region-create-expected-uia-win.txt
@@ -0,0 +1 @@ +LiveSetting changed on role=group
diff --git a/content/test/data/accessibility/event/menulist-collapse-expected-uia-win.txt b/content/test/data/accessibility/event/menulist-collapse-expected-uia-win.txt new file mode 100644 index 0000000..7dff0a6 --- /dev/null +++ b/content/test/data/accessibility/event/menulist-collapse-expected-uia-win.txt
@@ -0,0 +1 @@ +ValueValue changed on role=combobox
diff --git a/content/test/data/accessibility/event/menulist-collapse-next-expected-uia-win.txt b/content/test/data/accessibility/event/menulist-collapse-next-expected-uia-win.txt new file mode 100644 index 0000000..9521fe9 --- /dev/null +++ b/content/test/data/accessibility/event/menulist-collapse-next-expected-uia-win.txt
@@ -0,0 +1,2 @@ +SelectionItem_ElementSelected on role=listitem, name=Orange +ValueValue changed on role=combobox
diff --git a/content/test/data/accessibility/event/name-change-expected-uia-win.txt b/content/test/data/accessibility/event/name-change-expected-uia-win.txt new file mode 100644 index 0000000..d42f91db --- /dev/null +++ b/content/test/data/accessibility/event/name-change-expected-uia-win.txt
@@ -0,0 +1 @@ +Name changed on role=heading, name=After
diff --git a/content/test/data/accessibility/event/name-change-indirect-expected-uia-win.txt b/content/test/data/accessibility/event/name-change-indirect-expected-uia-win.txt new file mode 100644 index 0000000..46c8c92 --- /dev/null +++ b/content/test/data/accessibility/event/name-change-indirect-expected-uia-win.txt
@@ -0,0 +1,2 @@ +Name changed on role=heading, name=oranges +Name changed on role=main, name=oranges
diff --git a/content/test/data/accessibility/event/text-changed-expected-uia-win.txt b/content/test/data/accessibility/event/text-changed-expected-uia-win.txt new file mode 100644 index 0000000..abbec0f --- /dev/null +++ b/content/test/data/accessibility/event/text-changed-expected-uia-win.txt
@@ -0,0 +1,2 @@ +Name changed on role=description, name=Text modified +Name changed on role=heading, name=Heading
diff --git a/device/gamepad/xbox_data_fetcher_mac.cc b/device/gamepad/xbox_data_fetcher_mac.cc index 4fddce07..097e07d0 100644 --- a/device/gamepad/xbox_data_fetcher_mac.cc +++ b/device/gamepad/xbox_data_fetcher_mac.cc
@@ -144,12 +144,9 @@ PendingController* pending) { // Destroying the PendingController object unregisters our interest // notification. - for (auto it = pending_controllers_.begin(); it != pending_controllers_.end(); - ++it) { - if (pending == it->get()) { - pending_controllers_.erase(it); - break; - } + auto it = pending_controllers_.find(pending); + if (it != pending_controllers_.end()) { + pending_controllers_.erase(it); } TryOpenDevice(service); }
diff --git a/device/gamepad/xbox_data_fetcher_mac.h b/device/gamepad/xbox_data_fetcher_mac.h index 46c5e06..c6e59fa 100644 --- a/device/gamepad/xbox_data_fetcher_mac.h +++ b/device/gamepad/xbox_data_fetcher_mac.h
@@ -12,6 +12,7 @@ #include <IOKit/IOMessage.h> +#include "base/containers/unique_ptr_adapters.h" #include "base/mac/scoped_ionotificationportref.h" #include "base/mac/scoped_ioobject.h" #include "base/macros.h" @@ -95,7 +96,8 @@ // The set of enumerated controllers that received an exclusive access error // on opening the device. The data fetcher is notified when these devices // become available so we can try opening them again. - std::set<std::unique_ptr<PendingController>> pending_controllers_; + std::set<std::unique_ptr<PendingController>, base::UniquePtrComparator> + pending_controllers_; bool listening_ = false;
diff --git a/fuchsia/base/agent_impl.cc b/fuchsia/base/agent_impl.cc index 4c9623a..c01a749 100644 --- a/fuchsia/base/agent_impl.cc +++ b/fuchsia/base/agent_impl.cc
@@ -46,8 +46,6 @@ : create_component_state_callback_( std::move(create_component_state_callback)), agent_binding_(service_directory, this) { - agent_binding_.SetOnLastClientCallback(base::BindOnce( - &AgentImpl::MaybeRunOnLastClientCallback, base::Unretained(this))); } AgentImpl::~AgentImpl() { @@ -80,15 +78,6 @@ void AgentImpl::DeleteComponentState(base::StringPiece component_id) { size_t removed_components = active_components_.erase(component_id); DCHECK_EQ(removed_components, 1u); - MaybeRunOnLastClientCallback(); -} - -void AgentImpl::MaybeRunOnLastClientCallback() { - if (!on_last_client_callback_) - return; - if (!active_components_.empty() || agent_binding_.has_clients()) - return; - std::move(on_last_client_callback_).Run(); } } // namespace cr_fuchsia
diff --git a/fuchsia/base/agent_impl.h b/fuchsia/base/agent_impl.h index 4bea609..e6b7e78 100644 --- a/fuchsia/base/agent_impl.h +++ b/fuchsia/base/agent_impl.h
@@ -106,12 +106,6 @@ CreateComponentStateCallback create_component_state_callback); ~AgentImpl() override; - // Configures a Closure that will be run when no component instances, nor - // connections to the Agent interface, remain. - void set_on_last_client_callback(base::OnceClosure on_last_client_callback) { - on_last_client_callback_ = std::move(on_last_client_callback); - } - // fuchsia::modular::Agent implementation. void Connect(std::string requester_url, fidl::InterfaceRequest<::fuchsia::sys::ServiceProvider> services) @@ -134,9 +128,6 @@ base::flat_map<std::string, std::unique_ptr<ComponentStateBase>> active_components_; - // Run when no active components, nor Agent clients, remain. - base::OnceClosure on_last_client_callback_; - DISALLOW_COPY_AND_ASSIGN(AgentImpl); };
diff --git a/fuchsia/base/agent_impl_unittests.cc b/fuchsia/base/agent_impl_unittests.cc index 6e97672..dee70fa 100644 --- a/fuchsia/base/agent_impl_unittests.cc +++ b/fuchsia/base/agent_impl_unittests.cc
@@ -109,10 +109,6 @@ DISALLOW_COPY_AND_ASSIGN(AgentImplTest); }; -void SetBoolToTrue(bool* bool_value) { - *bool_value = true; -} - } // namespace // Verify that the Agent can publish and unpublish itself. @@ -142,56 +138,6 @@ EXPECT_EQ(*client_disconnect_status2, ZX_ERR_PEER_CLOSED); } -// Verify that the on-last-client callback is not invoked if the Agent channel -// is closed, until the last component is gone. -TEST_F(AgentImplTest, OnLastClientCallbackAfterComponentOutlivesAgent) { - fuchsia::modular::AgentPtr agent = CreateAgentAndConnect(); - - // Register an on-last-client callback. - bool on_last_client_called = false; - agent_impl_->set_on_last_client_callback( - base::BindOnce(&SetBoolToTrue, base::Unretained(&on_last_client_called))); - - // Connect a component to the Agent. - fuchsia::sys::ServiceProviderPtr component_services; - agent->Connect(kNoServicesComponentId, component_services.NewRequest()); - - // Disconnect from the Agent API. - agent.Unbind(); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(on_last_client_called); - - // Disconnect the component. - component_services.Unbind(); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(on_last_client_called); -} - -// Verify that the on-last-client callback is not invoked when the last -// component disconnects, until the Agent channel is also closed. -TEST_F(AgentImplTest, OnLastClientCallbackAfterAgentOutlivesComponent) { - fuchsia::modular::AgentPtr agent = CreateAgentAndConnect(); - - // Register an on-last-client callback. - bool on_last_client_called = false; - agent_impl_->set_on_last_client_callback( - base::BindOnce(&SetBoolToTrue, base::Unretained(&on_last_client_called))); - - // Connect a component to the Agent. - fuchsia::sys::ServiceProviderPtr component_services; - agent->Connect(kNoServicesComponentId, component_services.NewRequest()); - - // Disconnect the component. - component_services.Unbind(); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(on_last_client_called); - - // Disconnect from the Agent API. - agent.Unbind(); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(on_last_client_called); -} - // Verify that multiple connection attempts with the different component Ids // to the same service get different instances. TEST_F(AgentImplTest, DifferentComponentIdSameService) {
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg index 6864224..c1a90a6b 100644 --- a/infra/config/cr-buildbucket.cfg +++ b/infra/config/cr-buildbucket.cfg
@@ -180,20 +180,15 @@ name: "android-gpu-fyi-ci" dimensions: "os:Ubuntu-14.04" mixins: "gpu-fyi-ci" -} - -builder_mixins { - name: "android-gpu-manual-try" - mixins: "android-optional-gpu-try" - # Increase timeout to allow tryjobs against small number of phones. mixins: "gpu-slow-bot" } builder_mixins { name: "android-optional-gpu-try" dimensions: "os:Ubuntu-14.04" - mixins: "gpu-optional-try" mixins: "android-try" + mixins: "gpu-optional-try" + mixins: "gpu-slow-bot" } builder_mixins { @@ -366,11 +361,9 @@ builder_mixins { name: "linux-optional-gpu-try" - mixins: "linux" + mixins: "linux-try" mixins: "gpu-optional-try" - recipe { - properties: "mastername:tryserver.chromium.linux" - } + mixins: "gpu-slow-bot" } builder_mixins { @@ -410,6 +403,7 @@ name: "linux-gpu-fyi-ci" mixins: "linux" mixins: "gpu-fyi-ci" + mixins: "gpu-slow-bot" } builder_mixins { @@ -442,11 +436,8 @@ builder_mixins { name: "mac-optional-gpu-try" - mixins: "mac" + mixins: "mac-try" mixins: "gpu-optional-try" - recipe { - properties: "mastername:tryserver.chromium.mac" - } } builder_mixins { @@ -536,11 +527,9 @@ builder_mixins { name: "win-optional-gpu-try" - mixins: "win" + mixins: "win-try" mixins: "gpu-optional-try" - recipe { - properties: "mastername:tryserver.chromium.win" - } + mixins: "gpu-slow-bot" } builder_mixins { @@ -669,15 +658,11 @@ builders { name: "Android FYI 32 dEQP Vk Release (Pixel 2)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { name: "Android FYI 32 dEQP Vk Release (Pixel XL)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { @@ -688,15 +673,11 @@ builders { name: "Android FYI 32 Vk Release (Pixel 2)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { name: "Android FYI 32 Vk Release (Pixel XL)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { @@ -707,15 +688,11 @@ builders { name: "Android FYI 64 dEQP Vk Release (Pixel 2)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { name: "Android FYI 64 dEQP Vk Release (Pixel XL)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { @@ -726,15 +703,11 @@ builders { name: "Android FYI 64 Vk Release (Pixel 2)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { name: "Android FYI 64 Vk Release (Pixel XL)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { @@ -745,8 +718,6 @@ builders { name: "Android FYI Release (Nexus 5)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { @@ -757,36 +728,26 @@ builders { name: "Android FYI Release (Nexus 6)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { name: "Android FYI Release (Nexus 6P)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { name: "Android FYI Release (Nexus 9)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { name: "Android FYI Release (NVIDIA Shield TV)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { name: "Android FYI Release (Pixel 2)" mixins: "android-gpu-fyi-ci" - # Increase timeout to allow tryjobs against small number of phones. - mixins: "gpu-slow-bot" } builders { @@ -1324,7 +1285,6 @@ builders { name: "Linux FYI Experimental Release (Intel HD 630)" - mixins: "gpu-slow-bot" mixins: "linux-gpu-fyi-ci" } @@ -1366,7 +1326,6 @@ builders { name: "Linux FYI Release (AMD R7 240)" mixins: "linux-gpu-fyi-ci" - mixins: "gpu-slow-bot" } builders { @@ -3161,59 +3120,59 @@ dimensions: "os:Ubuntu-14.04" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-l-nexus-5-32" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-l-nexus-6-32" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-m-nexus-6p-64" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-m-nexus-9-64" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-n-nvidia-shield-tv-64" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-p-pixel-2-32" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-p-pixel-2-32-vk" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-p-pixel-2-32-deqp-vk" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-p-pixel-2-64-vk" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-p-pixel-2-64-deqp-vk" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-p-pixel-xl-32-vk" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-p-pixel-xl-32-deqp-vk" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-p-pixel-xl-64-vk" } builders { - mixins: "android-gpu-manual-try" + mixins: "android-optional-gpu-try" name: "gpu-manual-try-android-p-pixel-xl-64-deqp-vk" } builders { @@ -3246,12 +3205,6 @@ name: "linux-chromeos-rel" } - builders { mixins: "linux-angle-try" name: "linux_angle_compile_dbg_ng" } - builders { mixins: "linux-angle-try" name: "linux_angle_dbg_ng" } - builders { mixins: "linux-angle-try" name: "linux_angle_deqp_rel_ng" } - builders { mixins: "linux-angle-try" name: "linux_angle_ozone_rel_ng" } - builders { mixins: "linux-angle-try" name: "linux_angle_rel_ng" } - builders { mixins: "linux-try" name: "cast_shell_audio_linux" } builders { mixins: "linux-try" name: "cast_shell_linux" } builders { mixins: "linux-try" name: "chromium_devtools" } @@ -3278,7 +3231,52 @@ builders { mixins: "linux-try" name: "fuchsia-fyi-x64-rel" } builders { mixins: "linux-try" name: "fuchsia_x64" } builders { mixins: "linux-try" name: "fuchsia-x64-cast" } + builders { + mixins: "linux-optional-gpu-try" + name: "gpu-manual-try-linux-amd-rel" + } + builders { + mixins: "linux-optional-gpu-try" + name: "gpu-manual-try-linux-intel-dqp" + } + builders { + mixins: "linux-optional-gpu-try" + name: "gpu-manual-try-linux-intel-exp" + } + builders { + mixins: "linux-optional-gpu-try" + name: "gpu-manual-try-linux-intel-ozn" + } + builders { + mixins: "linux-optional-gpu-try" + name: "gpu-manual-try-linux-intel-rel" + } + builders { + mixins: "linux-optional-gpu-try" + name: "gpu-manual-try-linux-nvidia-dbg" + } + builders { + mixins: "linux-optional-gpu-try" + name: "gpu-manual-try-linux-nvidia-dqp" + } + builders { + mixins: "linux-optional-gpu-try" + name: "gpu-manual-try-linux-nvidia-exp" + } + builders { + mixins: "linux-optional-gpu-try" + name: "gpu-manual-try-linux-nvidia-rel" + } + builders { + mixins: "linux-optional-gpu-try" + name: "gpu-manual-try-linux-nvidia-tsn" + } builders { mixins: "linux-try" name: "leak_detection_linux" } + builders { mixins: "linux-angle-try" name: "linux_angle_compile_dbg_ng" } + builders { mixins: "linux-angle-try" name: "linux_angle_dbg_ng" } + builders { mixins: "linux-angle-try" name: "linux_angle_deqp_rel_ng" } + builders { mixins: "linux-angle-try" name: "linux_angle_ozone_rel_ng" } + builders { mixins: "linux-angle-try" name: "linux_angle_rel_ng" } builders { mixins: "linux-try" name: "linux-blink-heap-incremental-marking" } builders { mixins: "linux-try" name: "linux-blink-heap-verification-try" } builders { mixins: "linux-try" name: "linux-dcheck-off-rel" } @@ -3437,8 +3435,55 @@ builders { mixins: "win-optional-gpu-try" - name: "gpu_manual_try_win7_nvidia_rel" - execution_timeout_secs: 10800 # 3h + name: "gpu-manual-try-win7-amd-dbg" + } + builders { + mixins: "win-optional-gpu-try" + name: "gpu-manual-try-win7-amd-dqp" + } + builders { + mixins: "win-optional-gpu-try" + name: "gpu-manual-try-win7-amd-rel" + } + builders { + mixins: "win-optional-gpu-try" + name: "gpu-manual-try-win7-nvidia-dqp-64" + } + builders { + mixins: "win-optional-gpu-try" + name: "gpu-manual-try-win7-nvidia-rel" + } + builders { + mixins: "win-optional-gpu-try" + name: "gpu-manual-try-win7-nvidia-rel-64" + } + builders { + mixins: "win-optional-gpu-try" + name: "gpu-manual-try-win10-intel-dqp" + } + builders { + mixins: "win-optional-gpu-try" + name: "gpu-manual-try-win10-intel-exp" + } + builders { + mixins: "win-optional-gpu-try" + name: "gpu-manual-try-win10-intel-rel" + } + builders { + mixins: "win-optional-gpu-try" + name: "gpu-manual-try-win10-nvidia-dbg" + } + builders { + mixins: "win-optional-gpu-try" + name: "gpu-manual-try-win10-nvidia-dqp" + } + builders { + mixins: "win-optional-gpu-try" + name: "gpu-manual-try-win10-nvidia-exp" + } + builders { + mixins: "win-optional-gpu-try" + name: "gpu-manual-try-win10-nvidia-rel" } builders { mixins: "win-try" name: "win10_chromium_x64_dbg_ng" } builders {
diff --git a/infra/config/luci-milo.cfg b/infra/config/luci-milo.cfg index 65c6f98..44e08ea 100644 --- a/infra/config/luci-milo.cfg +++ b/infra/config/luci-milo.cfg
@@ -4020,6 +4020,36 @@ name: "buildbucket/luci.chromium.try/fuchsia-x64-cast" } builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-amd-rel" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-intel-dqp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-intel-exp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-intel-ozn" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-intel-rel" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-nvidia-dbg" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-nvidia-dqp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-nvidia-exp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-nvidia-rel" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-nvidia-tsn" + } + builders { name: "buildbucket/luci.chromium.try/layout_test_leak_detection" } builders { @@ -4240,7 +4270,43 @@ refs: "refs/heads/master" manifest_name: "REVISION" builders { - name: "buildbucket/luci.chromium.try/gpu_manual_try_win7_nvidia_rel" + name: "buildbucket/luci.chromium.try/gpu-manual-try-win7-amd-dbg" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win7-amd-dqp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win7-amd-rel" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win7-nvidia-dqp-64" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win7-nvidia-rel" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win7-nvidia-rel-64" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-intel-dqp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-intel-exp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-intel-rel" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-nvidia-dbg" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-nvidia-dqp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-nvidia-exp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-nvidia-rel" } builders { name: "buildbucket/luci.chromium.try/win-libfuzzer-asan-rel" @@ -4534,7 +4600,73 @@ name: "buildbucket/luci.chromium.try/gpu-manual-try-android-p-pixel-xl-64-deqp-vk" } builders { - name: "buildbucket/luci.chromium.try/gpu_manual_try_win7_nvidia_rel" + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-amd-rel" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-intel-dqp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-intel-exp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-intel-ozn" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-intel-rel" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-nvidia-dbg" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-nvidia-dqp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-nvidia-exp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-nvidia-rel" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-linux-nvidia-tsn" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win7-amd-dbg" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win7-amd-dqp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win7-amd-rel" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win7-nvidia-dqp-64" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win7-nvidia-rel" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win7-nvidia-rel-64" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-intel-dqp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-intel-exp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-intel-rel" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-nvidia-dbg" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-nvidia-dqp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-nvidia-exp" + } + builders { + name: "buildbucket/luci.chromium.try/gpu-manual-try-win10-nvidia-rel" } builders { name: "buildbucket/luci.chromium.try/linux-blink-heap-incremental-marking"
diff --git a/ios/chrome/browser/leveldb_proto/proto_database_provider_factory.mm b/ios/chrome/browser/leveldb_proto/proto_database_provider_factory.mm index 29bfeac..420eec2 100644 --- a/ios/chrome/browser/leveldb_proto/proto_database_provider_factory.mm +++ b/ios/chrome/browser/leveldb_proto/proto_database_provider_factory.mm
@@ -22,10 +22,9 @@ } // static -leveldb_proto::ProtoDatabaseProvider* -ProtoDatabaseProviderFactory::GetForBrowserState( +ProtoDatabaseProvider* ProtoDatabaseProviderFactory::GetForBrowserState( ios::ChromeBrowserState* browser_state) { - return static_cast<leveldb_proto::ProtoDatabaseProvider*>( + return static_cast<ProtoDatabaseProvider*>( GetInstance()->GetServiceForBrowserState(browser_state, true)); } @@ -39,9 +38,7 @@ std::unique_ptr<KeyedService> ProtoDatabaseProviderFactory::BuildServiceInstanceFor( web::BrowserState* context) const { - base::FilePath profile_dir = context->GetStatePath(); - return base::WrapUnique( - leveldb_proto::ProtoDatabaseProvider::Create(profile_dir)); + return std::make_unique<ProtoDatabaseProvider>(context->GetStatePath()); } } // namespace leveldb_proto \ No newline at end of file
diff --git a/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper_unittest.mm b/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper_unittest.mm index 8fd7642..4183eeca 100644 --- a/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper_unittest.mm +++ b/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper_unittest.mm
@@ -80,7 +80,13 @@ // Tests that OverscrollActionsControllerDelegate is set correctly and triggered // When there is a view pull. -TEST_F(OverscrollActionsTabHelperTest, TestDelegateTrigger) { +// TODO(crbug.com/944599): Fails on device. +#if TARGET_IPHONE_SIMULATOR +#define MAYBE_TestDelegateTrigger TestDelegateTrigger +#else +#define MAYBE_TestDelegateTrigger DISABLED_TestDelegateTrigger +#endif +TEST_F(OverscrollActionsTabHelperTest, MAYBE_TestDelegateTrigger) { web_state_.SetBrowserState(browser_state_.get()); overscroll_tab_helper()->SetDelegate(overscroll_delegate_); // Start pull for page refresh action. @@ -96,7 +102,13 @@ // Tests that overscrolls actions view style is set correctly, for regular // browsing browser state. -TEST_F(OverscrollActionsTabHelperTest, TestRegularBrowserStateStyle) { +// TODO(crbug.com/944599): Fails on device. +#if TARGET_IPHONE_SIMULATOR +#define MAYBE_TestRegularBrowserStateStyle TestRegularBrowserStateStyle +#else +#define MAYBE_TestRegularBrowserStateStyle DISABLED_TestRegularBrowserStateStyle +#endif +TEST_F(OverscrollActionsTabHelperTest, MAYBE_TestRegularBrowserStateStyle) { web_state_.SetBrowserState(browser_state_.get()); overscroll_tab_helper()->SetDelegate(overscroll_delegate_); SimulatePullForRefreshAction(); @@ -109,7 +121,16 @@ // Tests that overscrolls actions view style is set correctly, for off the // record browser state. -TEST_F(OverscrollActionsTabHelperTest, TestOffTheRecordBrowserStateStyle) { +// TODO(crbug.com/944599): Fails on device. +#if TARGET_IPHONE_SIMULATOR +#define MAYBE_TestOffTheRecordBrowserStateStyle \ + TestOffTheRecordBrowserStateStyle +#else +#define MAYBE_TestOffTheRecordBrowserStateStyle \ + DISABLED_TestOffTheRecordBrowserStateStyle +#endif +TEST_F(OverscrollActionsTabHelperTest, + MAYBE_TestOffTheRecordBrowserStateStyle) { web_state_.SetBrowserState( browser_state_->GetOffTheRecordChromeBrowserState()); overscroll_tab_helper()->SetDelegate(overscroll_delegate_);
diff --git a/ios/web/find_in_page/find_in_page_constants.h b/ios/web/find_in_page/find_in_page_constants.h index 4ae2c52..8d23f4d0 100644 --- a/ios/web/find_in_page/find_in_page_constants.h +++ b/ios/web/find_in_page/find_in_page_constants.h
@@ -11,6 +11,8 @@ extern const char kFindInPageSearch[]; // The name of JavaScript function which continues an unfinished find. extern const char kFindInPagePump[]; +// The name of JavaScript function which highlights a match. +extern const char kFindInPageHighlightMatch[]; } // namespace web
diff --git a/ios/web/find_in_page/find_in_page_constants.mm b/ios/web/find_in_page/find_in_page_constants.mm index af4792f..05fd1f8 100644 --- a/ios/web/find_in_page/find_in_page_constants.mm +++ b/ios/web/find_in_page/find_in_page_constants.mm
@@ -14,4 +14,6 @@ const char kFindInPagePump[] = "findInPage.pumpSearch"; +const char kFindInPageHighlightMatch[] = "findInPage.highlightMatch"; + } // namespace web
diff --git a/ios/web/web_state/js/find_in_page_js_unittest.mm b/ios/web/web_state/js/find_in_page_js_unittest.mm index a1bd7837..748a096e 100644 --- a/ios/web/web_state/js/find_in_page_js_unittest.mm +++ b/ios/web/web_state/js/find_in_page_js_unittest.mm
@@ -4,12 +4,14 @@ #include "base/bind.h" #include "base/callback.h" +#include "base/run_loop.h" #import "base/test/ios/wait_util.h" #import "ios/web/find_in_page/find_in_page_constants.h" #import "ios/web/public/test/web_test_with_web_state.h" #import "ios/web/public/web_state/web_frame.h" #import "ios/web/public/web_state/web_frame_util.h" #import "ios/web/public/web_state/web_frames_manager.h" +#include "testing/gtest_mac.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -26,9 +28,6 @@ // Pump search timeout in milliseconds. const double kPumpSearchTimeout = 100.0; - -// Timeout for frame javascript execution, in seconds. -const double kCallJavascriptFunctionTimeout = 3.0; } namespace web { @@ -49,23 +48,25 @@ // with 1 match. TEST_F(FindInPageJsTest, FindText) { ASSERT_TRUE(LoadHtml("<span>foo</span>")); - WaitForCondition(^{ + base::TimeDelta kCallJavascriptFunctionTimeout = + base::TimeDelta::FromSeconds(kWaitForJSCompletionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return frames_manager()->GetAllWebFrames().size() == 1; - }); + })); __block bool message_received = false; std::vector<base::Value> params; params.push_back(base::Value(kFindStringFoo)); params.push_back(base::Value(kPumpSearchTimeout)); main_web_frame()->CallJavaScriptFunction( - kFindInPageSearch, params, base::BindOnce(^(const base::Value* res) { - ASSERT_TRUE(res); - ASSERT_TRUE(res->is_double()); - int count = static_cast<int>(res->GetDouble()); - ASSERT_TRUE(count == 1); + kFindInPageSearch, params, base::BindOnce(^(const base::Value* result) { + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_double()); + double count = result->GetDouble(); + ASSERT_EQ(1.0, count); message_received = true; }), - base::TimeDelta::FromSeconds(kCallJavascriptFunctionTimeout)); + kCallJavascriptFunctionTimeout); ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return message_received; @@ -76,22 +77,24 @@ // hidden and responds with 0 matches. TEST_F(FindInPageJsTest, FindTextNoResults) { ASSERT_TRUE(LoadHtml("<span style='display:none'>foo</span>")); - WaitForCondition(^{ + base::TimeDelta kCallJavascriptFunctionTimeout = + base::TimeDelta::FromSeconds(kWaitForJSCompletionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return frames_manager()->GetAllWebFrames().size() == 1; - }); + })); __block bool message_received = false; std::vector<base::Value> params; params.push_back(base::Value(kFindStringFoo)); params.push_back(base::Value(kPumpSearchTimeout)); main_web_frame()->CallJavaScriptFunction( - kFindInPageSearch, params, base::BindOnce(^(const base::Value* res) { - ASSERT_TRUE(res); - ASSERT_TRUE(res->is_double()); - int count = static_cast<int>(res->GetDouble()); - ASSERT_TRUE(count == 0); + kFindInPageSearch, params, base::BindOnce(^(const base::Value* result) { + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_double()); + double count = result->GetDouble(); + ASSERT_EQ(0.0, count); message_received = true; }), - base::TimeDelta::FromSeconds(kCallJavascriptFunctionTimeout)); + kCallJavascriptFunctionTimeout); ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return message_received; })); @@ -106,9 +109,11 @@ ASSERT_TRUE(LoadHtml( "<iframe " "srcdoc='<html><body><span>foo</span></body></html>'></iframe>")); - WaitForCondition(^{ + base::TimeDelta kCallJavascriptFunctionTimeout = + base::TimeDelta::FromSeconds(kWaitForJSCompletionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return frames_manager()->GetAllWebFrames().size() == 2; - }); + })); std::set<WebFrame*> all_frames = frames_manager()->GetAllWebFrames(); __block bool message_received = false; WebFrame* child_frame = nullptr; @@ -123,14 +128,14 @@ params.push_back(base::Value(kFindStringFoo)); params.push_back(base::Value(kPumpSearchTimeout)); child_frame->CallJavaScriptFunction( - kFindInPageSearch, params, base::BindOnce(^(const base::Value* res) { - ASSERT_TRUE(res); - ASSERT_TRUE(res->is_double()); - int count = static_cast<int>(res->GetDouble()); - ASSERT_TRUE(count == 1); + kFindInPageSearch, params, base::BindOnce(^(const base::Value* result) { + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_double()); + double count = result->GetDouble(); + ASSERT_EQ(1.0, count); message_received = true; }), - base::TimeDelta::FromSeconds(kCallJavascriptFunctionTimeout)); + kCallJavascriptFunctionTimeout); ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return message_received; })); @@ -140,22 +145,24 @@ // Tests that FindInPage works when searching for white space. TEST_F(FindInPageJsTest, FindWhiteSpace) { ASSERT_TRUE(LoadHtml("<span> </span>")); - WaitForCondition(^{ + base::TimeDelta kCallJavascriptFunctionTimeout = + base::TimeDelta::FromSeconds(kWaitForJSCompletionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return frames_manager()->GetAllWebFrames().size() == 1; - }); + })); __block bool message_received = false; std::vector<base::Value> params; params.push_back(base::Value(" ")); params.push_back(base::Value(kPumpSearchTimeout)); main_web_frame()->CallJavaScriptFunction( - kFindInPageSearch, params, base::BindOnce(^(const base::Value* res) { - ASSERT_TRUE(res); - ASSERT_TRUE(res->is_double()); - int count = static_cast<int>(res->GetDouble()); - ASSERT_TRUE(count == 1); + kFindInPageSearch, params, base::BindOnce(^(const base::Value* result) { + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_double()); + double count = result->GetDouble(); + ASSERT_EQ(1.0, count); message_received = true; }), - base::TimeDelta::FromSeconds(kCallJavascriptFunctionTimeout)); + kCallJavascriptFunctionTimeout); ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return message_received; })); @@ -165,25 +172,182 @@ TEST_F(FindInPageJsTest, FindAcrossMultipleNodes) { ASSERT_TRUE( LoadHtml("<p>xx1<span>2</span>3<a>4512345xxx12</a>34<a>5xxx12345xx</p>")); - WaitForCondition(^{ + base::TimeDelta kCallJavascriptFunctionTimeout = + base::TimeDelta::FromSeconds(kWaitForJSCompletionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return frames_manager()->GetAllWebFrames().size() == 1; - }); + })); __block bool message_received = false; std::vector<base::Value> params; params.push_back(base::Value(kFindString12345)); params.push_back(base::Value(kPumpSearchTimeout)); main_web_frame()->CallJavaScriptFunction( - kFindInPageSearch, params, base::BindOnce(^(const base::Value* res) { - ASSERT_TRUE(res); - ASSERT_TRUE(res->is_double()); - int count = static_cast<int>(res->GetDouble()); - ASSERT_TRUE(count == 4); + kFindInPageSearch, params, base::BindOnce(^(const base::Value* result) { + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_double()); + double count = result->GetDouble(); + ASSERT_EQ(4.0, count); message_received = true; }), - base::TimeDelta::FromSeconds(kCallJavascriptFunctionTimeout)); + kCallJavascriptFunctionTimeout); ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return message_received; })); } +// Tests that a FindInPage match can be highlighted. +TEST_F(FindInPageJsTest, FindHighlightMatch) { + ASSERT_TRUE(LoadHtml("<span>foo</span>")); + base::TimeDelta kCallJavascriptFunctionTimeout = + base::TimeDelta::FromSeconds(kWaitForJSCompletionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return frames_manager()->GetAllWebFrames().size() == 1; + })); + + __block bool message_received = false; + std::vector<base::Value> params; + params.push_back(base::Value(kFindStringFoo)); + params.push_back(base::Value(kPumpSearchTimeout)); + main_web_frame()->CallJavaScriptFunction( + kFindInPageSearch, params, base::BindOnce(^(const base::Value* result) { + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_double()); + double count = result->GetDouble(); + ASSERT_EQ(1.0, count); + message_received = true; + }), + kCallJavascriptFunctionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return message_received; + })); + + __block bool highlight_done = false; + std::vector<base::Value> highlight_params; + highlight_params.push_back(base::Value(0)); + main_web_frame()->CallJavaScriptFunction( + kFindInPageHighlightMatch, highlight_params, + base::BindOnce(^(const base::Value* result) { + highlight_done = true; + }), + kCallJavascriptFunctionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return highlight_done; + })); + + EXPECT_NSEQ(@1, + ExecuteJavaScript( + @"document.getElementsByClassName('find_selected').length")); +} + +// Tests that a FindInPage match can be highlighted and that a previous +// highlight is removed when another match is highlighted. +TEST_F(FindInPageJsTest, FindHighlightSeparateMatches) { + ASSERT_TRUE(LoadHtml("<span>foo foo</span>")); + base::TimeDelta kCallJavascriptFunctionTimeout = + base::TimeDelta::FromSeconds(kWaitForJSCompletionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return frames_manager()->GetAllWebFrames().size() == 1; + })); + + __block bool message_received = false; + std::vector<base::Value> params; + params.push_back(base::Value(kFindStringFoo)); + params.push_back(base::Value(kPumpSearchTimeout)); + main_web_frame()->CallJavaScriptFunction( + kFindInPageSearch, params, base::BindOnce(^(const base::Value* result) { + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_double()); + double count = result->GetDouble(); + ASSERT_EQ(2.0, count); + message_received = true; + }), + kCallJavascriptFunctionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return message_received; + })); + + __block bool highlight_done = false; + std::vector<base::Value> highlight_params; + highlight_params.push_back(base::Value(0)); + main_web_frame()->CallJavaScriptFunction( + kFindInPageHighlightMatch, highlight_params, + base::BindOnce(^(const base::Value* result) { + highlight_done = true; + }), + kCallJavascriptFunctionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return highlight_done; + })); + + EXPECT_NSEQ(@1, + ExecuteJavaScript( + @"document.getElementsByClassName('find_selected').length")); + + highlight_done = false; + std::vector<base::Value> highlight_second_params; + highlight_second_params.push_back(base::Value(1)); + main_web_frame()->CallJavaScriptFunction( + kFindInPageHighlightMatch, highlight_second_params, + base::BindOnce(^(const base::Value* result) { + highlight_done = true; + }), + kCallJavascriptFunctionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return highlight_done; + })); + + id inner_html = ExecuteJavaScript(@"document.body.innerHTML"); + ASSERT_TRUE([inner_html isKindOfClass:[NSString class]]); + EXPECT_TRUE([inner_html + containsString:@"<chrome_find class=\"find_in_page\">foo</chrome_find> " + @"<chrome_find class=\"find_in_page " + @"find_selected\">foo</chrome_find>"]); + EXPECT_TRUE( + [inner_html containsString:@"find_selected{background-color:#ff9632"]); +} + +// Tests that FindInPage does not highlight any matches given an invalid index. +TEST_F(FindInPageJsTest, FindHighlightMatchAtInvalidIndex) { + ASSERT_TRUE(LoadHtml("<span>invalid </span>")); + base::TimeDelta kCallJavascriptFunctionTimeout = + base::TimeDelta::FromSeconds(kWaitForJSCompletionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return frames_manager()->GetAllWebFrames().size() == 1; + })); + + __block bool message_received = false; + std::vector<base::Value> params; + params.push_back(base::Value(kFindStringFoo)); + params.push_back(base::Value(kPumpSearchTimeout)); + main_web_frame()->CallJavaScriptFunction( + kFindInPageSearch, params, base::BindOnce(^(const base::Value* result) { + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_double()); + double count = result->GetDouble(); + ASSERT_TRUE(count == 0.0); + message_received = true; + }), + kCallJavascriptFunctionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return message_received; + })); + + __block bool highlight_done = false; + std::vector<base::Value> highlight_params; + highlight_params.push_back(base::Value(0)); + main_web_frame()->CallJavaScriptFunction( + kFindInPageHighlightMatch, highlight_params, + base::BindOnce(^(const base::Value* result) { + highlight_done = true; + }), + kCallJavascriptFunctionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return highlight_done; + })); + + EXPECT_NSEQ(@0, + ExecuteJavaScript( + @"document.getElementsByClassName('find_selected').length")); +} + } // namespace web
diff --git a/ios/web/web_state/js/resources/find_in_page.js b/ios/web/web_state/js/resources/find_in_page.js index c5a00f2..b558ed2 100644 --- a/ios/web/web_state/js/resources/find_in_page.js +++ b/ios/web/web_state/js/resources/find_in_page.js
@@ -112,7 +112,7 @@ */ addSelectHighlight() { for (let i = 0; i < this.nodes.length; ++i) { - this.nodes[i].className = (this.nodes[i].className || '') + ' findysel'; + this.nodes[i].classList.add(CSS_CLASS_NAME_SELECT); } } @@ -122,8 +122,7 @@ */ removeSelectHighlight() { for (let i = 0; i < this.nodes.length; ++i) { - this.nodes[i].className = - (this.nodes[i].className || '').replace(/\sfindysel/g, ''); + this.nodes[i].classList.remove(CSS_CLASS_NAME_SELECT); } } } @@ -138,7 +137,7 @@ * Index of the current highlighted choice. -1 means none. * @type {number} */ -__gCrWeb.findInPage.selectedMatchIndex = -1; +let selectedMatchIndex_ = -1; /** * The ID for the next Match found in |allText_|. This ID is used for @@ -318,12 +317,18 @@ 'OBJECT', 'SELECT', 'TEXTAREA', 'IFRAME']); /** - * Class name of CSS element. + * Class name of CSS element that highlights matches with yellow. * @type {string} */ const CSS_CLASS_NAME = 'find_in_page'; /** + * Class name of CSS element that selects a highlighted match with orange. + * @type {string} + */ +const CSS_CLASS_NAME_SELECT = 'find_selected'; + +/** * ID of CSS style. * @type {string} */ @@ -342,10 +347,14 @@ const REGEX_ESCAPER = /([.?*+^$[\]\\(){}|-])/g; /** - * @return {Match} The currently selected Match. + * @return {Match} The currently selected Match. Returns null if no + * currently selected match. */ function getCurrentSelectedMatch_() { - return __gCrWeb.findInPage.matches[__gCrWeb.findInPage.selectedMatchIndex]; + if (selectedMatchIndex_ < 0) { + return null; + } + return __gCrWeb.findInPage.matches[selectedMatchIndex_]; }; /** @@ -566,7 +575,7 @@ sectionsIndex_ = 0; __gCrWeb.findInPage.matches = []; - __gCrWeb.findInPage.selectedMatchIndex = -1; + selectedMatchIndex_ = -1; matchId_ = 0; partialMatches_ = []; @@ -575,92 +584,25 @@ }; /** - * Increments the index of the current selected Match or, if the index is - * already at the end, sets it to the index of the first Match in the page. + * Highlights the match at |index|. Clears currently highlighted match if + * one exists. + * @param {Number} index of match to highlight. */ -__gCrWeb.findInPage.incrementIndex = function() { - if (__gCrWeb.findInPage.selectedMatchIndex >= - __gCrWeb.findInPage.matches.length - 1) { - __gCrWeb.findInPage.selectedMatchIndex = 0; - } else { - __gCrWeb.findInPage.selectedMatchIndex++; - } -}; - -/** - * Switches to the next result, animating a little highlight in the process. - * @return {string} JSON encoded array of coordinates to scroll to, or blank if - * nothing happened. - */ -__gCrWeb.findInPage.goNext = function() { - if (!__gCrWeb.findInPage.matches || __gCrWeb.findInPage.matches.length == 0) { - return ''; - } - if (__gCrWeb.findInPage.selectedMatchIndex >= 0) { - // Remove previous highlight. - getCurrentSelectedMatch_().removeSelectHighlight(); - } - // Iterate through to the next index, but because they might not be visible, - // keep trying until you find one that is. Make sure we don't loop forever by - // stopping on what we are currently highlighting. - let oldIndex = __gCrWeb.findInPage.selectedMatchIndex; - __gCrWeb.findInPage.incrementIndex(); - while (!getCurrentSelectedMatch_().visible()) { - if (oldIndex === __gCrWeb.findInPage.selectedMatchIndex) { - // Checked all matches but didn't find anything else visible. - return ''; - } - __gCrWeb.findInPage.incrementIndex(); - if (0 === __gCrWeb.findInPage.selectedMatchIndex && oldIndex < 0) { - // Didn't find anything visible and haven't highlighted anything yet. - return ''; - } - } - // Return scroll dimensions. - return findScrollDimensions_(); -}; - -/** - * Decrements the index of the current selected Match or, if the index is - * already at the beginning, sets it to the index of the last Match in the page. - */ -__gCrWeb.findInPage.decrementIndex = function() { - if (__gCrWeb.findInPage.selectedMatchIndex <= 0) { - __gCrWeb.findInPage.selectedMatchIndex = - __gCrWeb.findInPage.matches.length - 1; - } else { - __gCrWeb.findInPage.selectedMatchIndex--; - } -}; - -/** - * Switches to the previous result, animating a little highlight in the process. - * @return {string} JSON encoded array of coordinates to scroll to, or blank if - * nothing happened. - */ -__gCrWeb.findInPage.goPrev = function() { - if (!__gCrWeb.findInPage.matches || __gCrWeb.findInPage.matches.length == 0) { - return ''; - } - if (__gCrWeb.findInPage.selectedMatchIndex >= 0) { - // Remove previous highlight. - getCurrentSelectedMatch_().removeSelectHighlight(); - } - // Iterate through to the next index, but because they might not be visible, - // keep trying until you find one that is. Make sure we don't loop forever by - // stopping on what we are currently highlighting. - let old = __gCrWeb.findInPage.selectedMatchIndex; - __gCrWeb.findInPage.decrementIndex(); - while (!getCurrentSelectedMatch_().visible()) { - __gCrWeb.findInPage.decrementIndex(); - if (old == __gCrWeb.findInPage.selectedMatchIndex) { - // Checked all matches but didn't find anything. - return ''; - } +__gCrWeb.findInPage.highlightMatch = function(index) { + if (index >= __gCrWeb.findInPage.matches.length || index < 0) { + // Do nothing if invalid index is passed. + return; } - // Return scroll dimensions. - return findScrollDimensions_(); + // Remove previous highlight. + let match = getCurrentSelectedMatch_(); + if (match) { + match.removeSelectHighlight(); + } + + selectedMatchIndex_ = index; + + getCurrentSelectedMatch_().addSelectHighlight() }; /** @@ -751,7 +693,7 @@ 'padding:0px;margin:0px;' + 'overflow:visible !important;'); addCSSRule( - '.findysel', + '.' + CSS_CLASS_NAME_SELECT, 'background-color:#ff9632 !important;' + 'padding:0px;margin:0px;' + 'overflow:visible !important;');
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 66906e8..3770e35e 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -129,14 +129,14 @@ using web::WebState; using web::WebStateImpl; -namespace { - using web::wk_navigation_util::IsPlaceholderUrl; using web::wk_navigation_util::CreatePlaceholderUrlForUrl; using web::wk_navigation_util::ExtractUrlFromPlaceholderUrl; using web::wk_navigation_util::IsRestoreSessionUrl; using web::wk_navigation_util::IsWKInternalUrl; +namespace { + // Struct to capture data about a user interaction. Records the time of the // interaction and the main document URL at that time. struct UserInteractionEvent { @@ -161,6 +161,12 @@ // Message command sent when a frame is unloading. NSString* const kFrameBecameUnavailableMessageName = @"FrameBecameUnavailable"; +NSString* const kReferrerHeaderName = @"Referer"; // [sic] + +// The duration of the period following a screen touch during which the user is +// still considered to be interacting with the page. +const NSTimeInterval kMaximumDelayForUserInteractionInSeconds = 2; + // Values for the histogram that counts slow/fast back/forward navigations. enum class BackForwardNavigationType { // Fast back navigation through WKWebView back-forward list. @@ -194,6 +200,17 @@ // stored errors is not expected to be high. const CertVerificationErrorsCacheType::size_type kMaxCertErrorsCount = 100; +// URLs that are fed into UIWebView as history push/replace get escaped, +// potentially changing their format. Code that attempts to determine whether a +// URL hasn't changed can be confused by those differences though, so method +// will round-trip a URL through the escaping process so that it can be adjusted +// pre-storing, to allow later comparisons to work as expected. +GURL URLEscapedForHistory(const GURL& url) { + // TODO(stuartmorgan): This is a very large hammer; see if limited unicode + // escaping would be sufficient. + return net::GURLWithNSURL(net::NSURLWithGURL(url)); +} + } // namespace #pragma mark - @@ -608,26 +625,6 @@ @end -namespace { - -NSString* const kReferrerHeaderName = @"Referer"; // [sic] - -// The duration of the period following a screen touch during which the user is -// still considered to be interacting with the page. -const NSTimeInterval kMaximumDelayForUserInteractionInSeconds = 2; - -// URLs that are fed into UIWebView as history push/replace get escaped, -// potentially changing their format. Code that attempts to determine whether a -// URL hasn't changed can be confused by those differences though, so method -// will round-trip a URL through the escaping process so that it can be adjusted -// pre-storing, to allow later comparisons to work as expected. -GURL URLEscapedForHistory(const GURL& url) { - // TODO(stuartmorgan): This is a very large hammer; see if limited unicode - // escaping would be sufficient. - return net::GURLWithNSURL(net::NSURLWithGURL(url)); -} -} // namespace - @implementation CRWWebController // Synthesize as it is readonly. @@ -844,10 +841,6 @@ } } -- (id<CRWNativeContent>)nativeController { - return [_containerView nativeController]; -} - - (void)setNativeController:(id<CRWNativeContent>)nativeController { // Check for pointer equality. if (self.nativeController == nativeController) @@ -962,7 +955,7 @@ return _touchTrackingRecognizer; } -#pragma mark Session Information +#pragma mark Navigation and Session Information - (CRWSessionController*)sessionController { NavigationManagerImpl* navigationManager = self.navigationManagerImpl; @@ -1452,6 +1445,10 @@ } } +- (id<CRWNativeContent>)nativeController { + return [_containerView nativeController]; +} + - (void)didFinishGoToIndexSameDocumentNavigationWithType: (web::NavigationInitiationType)type hasUserGesture:(BOOL)hasUserGesture { @@ -1758,7 +1755,7 @@ } } -#pragma mark - Load helpers +#pragma mark - Navigation Helpers // Registers load request with empty referrer and link or client redirect // transition based on user interaction state. Returns navigation context for @@ -1915,7 +1912,7 @@ return context; } -// Load the current URL in a web view, first ensuring the web view is visible. +// Loads the current URL in a web view, first ensuring the web view is visible. - (void)loadCurrentURLInWebView { web::NavigationItem* item = self.currentNavItem; GURL targetURL = item ? item->GetVirtualURL() : GURL::EmptyGURL(); @@ -2352,7 +2349,7 @@ self.webStateImpl->OnPageLoaded(currentURL, YES); } -#pragma mark - Error helpers +#pragma mark - Error Helpers - (void)loadErrorPageForNavigationItem:(web::NavigationItemImpl*)item navigationContext:(web::NavigationContextImpl*)context { @@ -2714,7 +2711,7 @@ return [self.nativeProvider nativeContentInsetForWebState:self.webState]; } -#pragma mark - CRWJSInjectionEvaluator helper methods (Private) +#pragma mark - JavaScript message Helpers (Private) - (BOOL)respondToMessage:(base::DictionaryValue*)message userIsInteracting:(BOOL)userIsInteracting @@ -3199,7 +3196,7 @@ return YES; } -#pragma mark - JavaScript message helpers +#pragma mark - Navigation Helpers // 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 @@ -3594,7 +3591,7 @@ } } -#pragma mark - WebDelegate Calls +#pragma mark - WKNavigationDelegate Helpers - (BOOL)isMainFrameNavigationAction:(WKNavigationAction*)action { if (action.targetFrame) { @@ -3606,6 +3603,8 @@ return action.sourceFrame.mainFrame; } +#pragma mark - Security Helpers + - (void)updateSSLStatusForCurrentNavigationItem { if (_isBeingDestroyed) { return; @@ -3739,7 +3738,7 @@ [self loadCancelled]; } -#pragma mark - WebView helpers +#pragma mark - WebView Helpers // Creates a container view if it's not yet created. - (void)ensureContainerViewCreated { @@ -4036,7 +4035,7 @@ previewingViewController); } -#pragma mark - WKUIDelegate helper methods +#pragma mark - WKUIDelegate Helpers // Helper to respond to |webView:runJavaScript...| delegate methods. // |completionHandler| must not be nil. @@ -5909,7 +5908,7 @@ } } -#pragma mark - KVO helper methods +#pragma mark - KVO Helpers // Returns YES if a KVO change to |newURL| could be a 'navigation' within the // document (hash change, pushState/replaceState, etc.). This should only be
diff --git a/media/base/android/java/src/org/chromium/media/MediaDrmBridge.java b/media/base/android/java/src/org/chromium/media/MediaDrmBridge.java index f116052..4ff4574 100644 --- a/media/base/android/java/src/org/chromium/media/MediaDrmBridge.java +++ b/media/base/android/java/src/org/chromium/media/MediaDrmBridge.java
@@ -19,14 +19,13 @@ import org.chromium.media.MediaDrmSessionManager.SessionId; import org.chromium.media.MediaDrmSessionManager.SessionInfo; -import java.io.IOException; +import java.lang.reflect.Method; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Queue; -import java.util.Scanner; import java.util.UUID; // Implementation Notes of MediaDrmBridge: @@ -412,18 +411,13 @@ @CalledByNative private static int getFirstApiLevel() { int firstApiLevel = 0; - Scanner scanner = null; - // If first_api_level property is set, return it. try { - Process process = new ProcessBuilder("getprop", FIRST_API_LEVEL).start(); - scanner = new Scanner(process.getInputStream()); - firstApiLevel = Integer.parseInt(scanner.nextLine().trim()); - } catch (IOException | NumberFormatException e) { + final Class<?> systemProperties = Class.forName("android.os.SystemProperties"); + final Method getInt = systemProperties.getMethod("getInt", String.class, int.class); + firstApiLevel = (Integer) getInt.invoke(null, FIRST_API_LEVEL, 0); + } catch (Exception e) { + Log.e("Exception while getting system property %s. Using default.", FIRST_API_LEVEL, e); firstApiLevel = 0; - } finally { - if (scanner != null) { - scanner.close(); - } } return firstApiLevel; } @@ -527,7 +521,7 @@ assert !securityLevel.isEmpty(); String currentSecurityLevel = mMediaDrm.getPropertyString(SECURITY_LEVEL); - Log.e(TAG, "Security level: current %s, new %s", currentSecurityLevel, securityLevel); + Log.i(TAG, "Security level: current %s, new %s", currentSecurityLevel, securityLevel); if (securityLevel.equals(currentSecurityLevel)) { // No need to set the same security level again. This is not just // a shortcut! Setting the same security level actually causes an @@ -1113,7 +1107,7 @@ Log.e(TAG, "getSecurityLevel(): MediaDrm is null or security level is not supported."); return ""; } - return mMediaDrm.getPropertyString("securityLevel"); + return mMediaDrm.getPropertyString(SECURITY_LEVEL); } private void startProvisioning() { @@ -1317,7 +1311,7 @@ public void onEvent( MediaDrm mediaDrm, byte[] drmSessionId, int event, int extra, byte[] data) { if (drmSessionId == null) { - Log.e(TAG, "EventListener: Null session."); + Log.e(TAG, "EventListener: No session for event %d.", event); return; } SessionId sessionId = getSessionIdByDrmId(drmSessionId);
diff --git a/media/capture/content/android/thread_safe_capture_oracle.cc b/media/capture/content/android/thread_safe_capture_oracle.cc index e80f233..13d4a30 100644 --- a/media/capture/content/android/thread_safe_capture_oracle.cc +++ b/media/capture/content/android/thread_safe_capture_oracle.cc
@@ -237,8 +237,8 @@ params_.requested_format.frame_rate, frame->format()); client_->OnIncomingCapturedBufferExt( - std::move(capture->buffer), format, reference_time, frame->timestamp(), - frame->visible_rect(), *frame->metadata()); + std::move(capture->buffer), format, frame->ColorSpace(), reference_time, + frame->timestamp(), frame->visible_rect(), *frame->metadata()); } void ThreadSafeCaptureOracle::OnConsumerReportingUtilization(
diff --git a/media/capture/mojom/video_capture_types.mojom b/media/capture/mojom/video_capture_types.mojom index 233d135..ee201ab12 100644 --- a/media/capture/mojom/video_capture_types.mojom +++ b/media/capture/mojom/video_capture_types.mojom
@@ -274,7 +274,7 @@ // This field is only optional to work around the issue of native enums // not being usable for non-Chromium Mojo clients. // TODO(chfremer): Make this non-optional once gfx.mojom.ColorSpace has been - // migrated to a full Mojo struct. + // migrated to a full Mojo struct. See https://crbug.com/893203. gfx.mojom.ColorSpace? color_space; // Optionally, stride information can be provided. // If not provided, it is assumed that frame data is tightly packed.
diff --git a/media/capture/video/chromeos/mock_video_capture_client.cc b/media/capture/video/chromeos/mock_video_capture_client.cc index 2d90502f..04e26a48 100644 --- a/media/capture/video/chromeos/mock_video_capture_client.cc +++ b/media/capture/video/chromeos/mock_video_capture_client.cc
@@ -90,6 +90,7 @@ void MockVideoCaptureClient::OnIncomingCapturedBufferExt( Buffer buffer, const VideoCaptureFormat& format, + const gfx::ColorSpace& color_space, base::TimeTicks reference_time, base::TimeDelta timestamp, gfx::Rect visible_rect,
diff --git a/media/capture/video/chromeos/mock_video_capture_client.h b/media/capture/video/chromeos/mock_video_capture_client.h index 88039c7..7ab44a08 100644 --- a/media/capture/video/chromeos/mock_video_capture_client.h +++ b/media/capture/video/chromeos/mock_video_capture_client.h
@@ -64,6 +64,7 @@ void OnIncomingCapturedBufferExt( Buffer buffer, const VideoCaptureFormat& format, + const gfx::ColorSpace& color_space, base::TimeTicks reference_time, base::TimeDelta timestamp, gfx::Rect visible_rect,
diff --git a/media/capture/video/fake_video_capture_device_unittest.cc b/media/capture/video/fake_video_capture_device_unittest.cc index df0723b..c5b3d806 100644 --- a/media/capture/video/fake_video_capture_device_unittest.cc +++ b/media/capture/video/fake_video_capture_device_unittest.cc
@@ -175,12 +175,12 @@ const media::VideoCaptureFormat& frame_format, base::TimeTicks, base::TimeDelta) { OnFrameCaptured(frame_format); })); - ON_CALL(*result, DoOnIncomingCapturedBufferExt(_, _, _, _, _, _)) - .WillByDefault( - Invoke([this](media::VideoCaptureDevice::Client::Buffer&, - const media::VideoCaptureFormat& frame_format, - base::TimeTicks, base::TimeDelta, gfx::Rect, - const media::VideoFrameMetadata&) { + ON_CALL(*result, DoOnIncomingCapturedBufferExt(_, _, _, _, _, _, _)) + .WillByDefault(Invoke( + [this](media::VideoCaptureDevice::Client::Buffer&, + const media::VideoCaptureFormat& frame_format, + const gfx::ColorSpace&, base::TimeTicks, base::TimeDelta, + gfx::Rect, const media::VideoFrameMetadata&) { OnFrameCaptured(frame_format); })); return result;
diff --git a/media/capture/video/mock_video_capture_device_client.cc b/media/capture/video/mock_video_capture_device_client.cc index 74e1fda..b113c6a 100644 --- a/media/capture/video/mock_video_capture_device_client.cc +++ b/media/capture/video/mock_video_capture_device_client.cc
@@ -19,12 +19,13 @@ void MockVideoCaptureDeviceClient::OnIncomingCapturedBufferExt( Buffer buffer, const media::VideoCaptureFormat& format, + const gfx::ColorSpace& color_space, base::TimeTicks reference_time, base::TimeDelta timestamp, gfx::Rect visible_rect, const media::VideoFrameMetadata& additional_metadata) { - DoOnIncomingCapturedBufferExt(buffer, format, reference_time, timestamp, - visible_rect, additional_metadata); + DoOnIncomingCapturedBufferExt(buffer, format, color_space, reference_time, + timestamp, visible_rect, additional_metadata); } } // namespace media
diff --git a/media/capture/video/mock_video_capture_device_client.h b/media/capture/video/mock_video_capture_device_client.h index a7f83a3d..b0e2d76f 100644 --- a/media/capture/video/mock_video_capture_device_client.h +++ b/media/capture/video/mock_video_capture_device_client.h
@@ -47,6 +47,7 @@ void OnIncomingCapturedBufferExt( Buffer buffer, const media::VideoCaptureFormat& format, + const gfx::ColorSpace& color_space, base::TimeTicks reference_time, base::TimeDelta timestamp, gfx::Rect visible_rect, @@ -57,9 +58,10 @@ const media::VideoCaptureFormat&, base::TimeTicks, base::TimeDelta)); - MOCK_METHOD6(DoOnIncomingCapturedBufferExt, + MOCK_METHOD7(DoOnIncomingCapturedBufferExt, void(Buffer& buffer, const media::VideoCaptureFormat& format, + const gfx::ColorSpace& color_space, base::TimeTicks reference_time, base::TimeDelta timestamp, gfx::Rect visible_rect,
diff --git a/media/capture/video/video_capture_device.h b/media/capture/video/video_capture_device.h index d4ad22b..3cef019 100644 --- a/media/capture/video/video_capture_device.h +++ b/media/capture/video/video_capture_device.h
@@ -199,6 +199,7 @@ virtual void OnIncomingCapturedBufferExt( Buffer buffer, const VideoCaptureFormat& format, + const gfx::ColorSpace& color_space, base::TimeTicks reference_time, base::TimeDelta timestamp, gfx::Rect visible_rect,
diff --git a/media/capture/video/video_capture_device_client.cc b/media/capture/video/video_capture_device_client.cc index ef84b21..6c7cf02e 100644 --- a/media/capture/video/video_capture_device_client.cc +++ b/media/capture/video/video_capture_device_client.cc
@@ -202,7 +202,8 @@ int crop_x = 0; int crop_y = 0; - libyuv::FourCC origin_colorspace = libyuv::FOURCC_ANY; + libyuv::FourCC fourcc_format = libyuv::FOURCC_ANY; + gfx::ColorSpace color_space; bool flip = false; switch (format.pixel_format) { @@ -210,27 +211,27 @@ break; case PIXEL_FORMAT_I420: DCHECK(!chopped_width && !chopped_height); - origin_colorspace = libyuv::FOURCC_I420; + fourcc_format = libyuv::FOURCC_I420; break; case PIXEL_FORMAT_YV12: DCHECK(!chopped_width && !chopped_height); - origin_colorspace = libyuv::FOURCC_YV12; + fourcc_format = libyuv::FOURCC_YV12; break; case PIXEL_FORMAT_NV12: DCHECK(!chopped_width && !chopped_height); - origin_colorspace = libyuv::FOURCC_NV12; + fourcc_format = libyuv::FOURCC_NV12; break; case PIXEL_FORMAT_NV21: DCHECK(!chopped_width && !chopped_height); - origin_colorspace = libyuv::FOURCC_NV21; + fourcc_format = libyuv::FOURCC_NV21; break; case PIXEL_FORMAT_YUY2: DCHECK(!chopped_width && !chopped_height); - origin_colorspace = libyuv::FOURCC_YUY2; + fourcc_format = libyuv::FOURCC_YUY2; break; case PIXEL_FORMAT_UYVY: DCHECK(!chopped_width && !chopped_height); - origin_colorspace = libyuv::FOURCC_UYVY; + fourcc_format = libyuv::FOURCC_UYVY; break; case PIXEL_FORMAT_RGB24: // Linux RGB24 defines red at lowest byte address, @@ -238,9 +239,9 @@ // Windows RGB24 defines blue at lowest byte, // see https://msdn.microsoft.com/en-us/library/windows/desktop/dd407253 #if defined(OS_LINUX) - origin_colorspace = libyuv::FOURCC_RAW; + fourcc_format = libyuv::FOURCC_RAW; #elif defined(OS_WIN) - origin_colorspace = libyuv::FOURCC_24BG; + fourcc_format = libyuv::FOURCC_24BG; #else NOTREACHED() << "RGB24 is only available in Linux and Windows platforms"; #endif @@ -251,6 +252,11 @@ // that vertical flipping is needed. flip = true; #endif + // We don't actually know, for sure, what the source color space is. It's + // probably safe to assume its sRGB, though, and so it would be valid to + // assume libyuv::ConvertToI420() is going to produce results in Rec601 + // (or very close to it). + color_space = gfx::ColorSpace::CreateREC601(); break; case PIXEL_FORMAT_RGB32: // Fallback to PIXEL_FORMAT_ARGB setting |flip| in Windows @@ -260,10 +266,11 @@ FALLTHROUGH; #endif case PIXEL_FORMAT_ARGB: - origin_colorspace = libyuv::FOURCC_ARGB; + fourcc_format = libyuv::FOURCC_ARGB; + color_space = gfx::ColorSpace::CreateREC601(); break; case PIXEL_FORMAT_MJPEG: - origin_colorspace = libyuv::FOURCC_MJPG; + fourcc_format = libyuv::FOURCC_MJPG; break; default: NOTREACHED(); @@ -289,12 +296,13 @@ } } + // libyuv::ConvertToI420 use Rec601 to convert RGB to YUV. if (libyuv::ConvertToI420( data, length, y_plane_data, yplane_stride, u_plane_data, uv_plane_stride, v_plane_data, uv_plane_stride, crop_x, crop_y, format.frame_size.width(), (flip ? -1 : 1) * format.frame_size.height(), new_unrotated_width, - new_unrotated_height, rotation_mode, origin_colorspace) != 0) { + new_unrotated_height, rotation_mode, fourcc_format) != 0) { DLOG(WARNING) << "Failed to convert buffer's pixel format to I420 from " << VideoPixelFormatToString(format.pixel_format); receiver_->OnFrameDropped( @@ -304,8 +312,9 @@ const VideoCaptureFormat output_format = VideoCaptureFormat(dimensions, format.frame_rate, PIXEL_FORMAT_I420); - OnIncomingCapturedBuffer(std::move(buffer), output_format, reference_time, - timestamp); + OnIncomingCapturedBufferExt(std::move(buffer), output_format, color_space, + reference_time, timestamp, gfx::Rect(dimensions), + VideoFrameMetadata()); } void VideoCaptureDeviceClient::OnIncomingCapturedGfxBuffer( @@ -443,14 +452,15 @@ base::TimeTicks reference_time, base::TimeDelta timestamp) { DFAKE_SCOPED_RECURSIVE_LOCK(call_from_producer_); - OnIncomingCapturedBufferExt(std::move(buffer), format, reference_time, - timestamp, gfx::Rect(format.frame_size), - VideoFrameMetadata()); + OnIncomingCapturedBufferExt( + std::move(buffer), format, gfx::ColorSpace(), reference_time, timestamp, + gfx::Rect(format.frame_size), VideoFrameMetadata()); } void VideoCaptureDeviceClient::OnIncomingCapturedBufferExt( Buffer buffer, const VideoCaptureFormat& format, + const gfx::ColorSpace& color_space, base::TimeTicks reference_time, base::TimeDelta timestamp, gfx::Rect visible_rect, @@ -465,6 +475,7 @@ mojom::VideoFrameInfoPtr info = mojom::VideoFrameInfo::New(); info->timestamp = timestamp; info->pixel_format = format.pixel_format; + info->color_space = color_space; info->coded_size = format.frame_size; info->visible_rect = visible_rect; info->metadata = metadata.GetInternalValues().Clone();
diff --git a/media/capture/video/video_capture_device_client.h b/media/capture/video/video_capture_device_client.h index f93e44b..dfea6ac 100644 --- a/media/capture/video/video_capture_device_client.h +++ b/media/capture/video/video_capture_device_client.h
@@ -80,6 +80,7 @@ void OnIncomingCapturedBufferExt( Buffer buffer, const VideoCaptureFormat& format, + const gfx::ColorSpace& color_space, base::TimeTicks reference_time, base::TimeDelta timestamp, gfx::Rect visible_rect,
diff --git a/media/capture/video/video_capture_device_unittest.cc b/media/capture/video/video_capture_device_unittest.cc index fb39e510..73859b55 100644 --- a/media/capture/video/video_capture_device_unittest.cc +++ b/media/capture/video/video_capture_device_unittest.cc
@@ -309,7 +309,7 @@ ON_CALL(*result, OnError(_, _, _)).WillByDefault(Invoke(DumpError)); EXPECT_CALL(*result, ReserveOutputBuffer(_, _, _, _)).Times(0); EXPECT_CALL(*result, DoOnIncomingCapturedBuffer(_, _, _, _)).Times(0); - EXPECT_CALL(*result, DoOnIncomingCapturedBufferExt(_, _, _, _, _, _)) + EXPECT_CALL(*result, DoOnIncomingCapturedBufferExt(_, _, _, _, _, _, _)) .Times(0); ON_CALL(*result, OnIncomingCapturedData(_, _, _, _, _, _, _)) .WillByDefault(
diff --git a/media/capture/video/win/video_capture_device_mf_win_unittest.cc b/media/capture/video/win/video_capture_device_mf_win_unittest.cc index 8ad8f3fa..f8c252f 100644 --- a/media/capture/video/win/video_capture_device_mf_win_unittest.cc +++ b/media/capture/video/win/video_capture_device_mf_win_unittest.cc
@@ -53,6 +53,7 @@ void OnIncomingCapturedBufferExt( Buffer buffer, const VideoCaptureFormat& format, + const gfx::ColorSpace& color_space, base::TimeTicks reference_time, base::TimeDelta timestamp, gfx::Rect visible_rect,
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index 72803b2..b1750d5 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -69,8 +69,6 @@ "command_buffer_helper.h", "fake_jpeg_decode_accelerator.cc", "fake_jpeg_decode_accelerator.h", - "fake_video_decode_accelerator.cc", - "fake_video_decode_accelerator.h", "gles2_decoder_helper.cc", "gles2_decoder_helper.h", "gpu_jpeg_decode_accelerator_factory.cc", @@ -122,10 +120,10 @@ if (is_mac) { sources += [ - "vt_video_decode_accelerator_mac.cc", - "vt_video_decode_accelerator_mac.h", - "vt_video_encode_accelerator_mac.cc", - "vt_video_encode_accelerator_mac.h", + "mac/vt_video_decode_accelerator_mac.cc", + "mac/vt_video_decode_accelerator_mac.h", + "mac/vt_video_encode_accelerator_mac.cc", + "mac/vt_video_encode_accelerator_mac.h", ] public_deps += [ "//third_party/webrtc/common_video" ] libs += [ @@ -395,6 +393,8 @@ if (is_win || is_chromeos || use_v4l2_codec) { sources = [ + "test/fake_video_decode_accelerator.cc", + "test/fake_video_decode_accelerator.h", "video_decode_accelerator_unittest.cc", ] deps += [ @@ -589,8 +589,8 @@ visibility = [ "//media:test_support" ] testonly = true sources = [ - "fake_command_buffer_helper.cc", - "fake_command_buffer_helper.h", + "test/fake_command_buffer_helper.cc", + "test/fake_command_buffer_helper.h", ] configs += [ "//media:media_config" ] deps = [
diff --git a/media/gpu/android/texture_pool_unittest.cc b/media/gpu/android/texture_pool_unittest.cc index b294ff2..cc21988f 100644 --- a/media/gpu/android/texture_pool_unittest.cc +++ b/media/gpu/android/texture_pool_unittest.cc
@@ -15,7 +15,7 @@ #include "gpu/command_buffer/service/sequence_id.h" #include "gpu/ipc/common/gpu_messages.h" #include "media/gpu/android/mock_abstract_texture.h" -#include "media/gpu/fake_command_buffer_helper.h" +#include "media/gpu/test/fake_command_buffer_helper.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/media/gpu/gpu_video_decode_accelerator_factory.cc b/media/gpu/gpu_video_decode_accelerator_factory.cc index 27b3fe4e..dc9ff3f 100644 --- a/media/gpu/gpu_video_decode_accelerator_factory.cc +++ b/media/gpu/gpu_video_decode_accelerator_factory.cc
@@ -20,7 +20,7 @@ #include "media/gpu/windows/dxva_video_decode_accelerator_win.h" #endif #if defined(OS_MACOSX) -#include "media/gpu/vt_video_decode_accelerator_mac.h" +#include "media/gpu/mac/vt_video_decode_accelerator_mac.h" #endif #if BUILDFLAG(USE_V4L2_CODEC) #include "media/gpu/v4l2/v4l2_device.h"
diff --git a/media/gpu/gpu_video_encode_accelerator_factory.cc b/media/gpu/gpu_video_encode_accelerator_factory.cc index 2945abf..7e77b69 100644 --- a/media/gpu/gpu_video_encode_accelerator_factory.cc +++ b/media/gpu/gpu_video_encode_accelerator_factory.cc
@@ -17,7 +17,7 @@ #include "media/gpu/android/android_video_encode_accelerator.h" #endif #if defined(OS_MACOSX) -#include "media/gpu/vt_video_encode_accelerator_mac.h" +#include "media/gpu/mac/vt_video_encode_accelerator_mac.h" #endif #if defined(OS_WIN) #include "base/feature_list.h"
diff --git a/media/gpu/ipc/service/picture_buffer_manager_unittest.cc b/media/gpu/ipc/service/picture_buffer_manager_unittest.cc index fcf2475..2d3e284 100644 --- a/media/gpu/ipc/service/picture_buffer_manager_unittest.cc +++ b/media/gpu/ipc/service/picture_buffer_manager_unittest.cc
@@ -11,7 +11,7 @@ #include "base/test/mock_callback.h" #include "base/test/scoped_task_environment.h" #include "media/base/simple_sync_token_client.h" -#include "media/gpu/fake_command_buffer_helper.h" +#include "media/gpu/test/fake_command_buffer_helper.h" #include "testing/gtest/include/gtest/gtest.h" namespace media {
diff --git a/media/gpu/ipc/service/vda_video_decoder_unittest.cc b/media/gpu/ipc/service/vda_video_decoder_unittest.cc index 0264cf9..c7c79fe 100644 --- a/media/gpu/ipc/service/vda_video_decoder_unittest.cc +++ b/media/gpu/ipc/service/vda_video_decoder_unittest.cc
@@ -25,8 +25,8 @@ #include "media/base/video_frame.h" #include "media/base/video_rotation.h" #include "media/base/video_types.h" -#include "media/gpu/fake_command_buffer_helper.h" #include "media/gpu/ipc/service/picture_buffer_manager.h" +#include "media/gpu/test/fake_command_buffer_helper.h" #include "media/video/mock_video_decode_accelerator.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/media/gpu/vt_video_decode_accelerator_mac.cc b/media/gpu/mac/vt_video_decode_accelerator_mac.cc similarity index 99% rename from media/gpu/vt_video_decode_accelerator_mac.cc rename to media/gpu/mac/vt_video_decode_accelerator_mac.cc index f9a834a0..f01a29b0 100644 --- a/media/gpu/vt_video_decode_accelerator_mac.cc +++ b/media/gpu/mac/vt_video_decode_accelerator_mac.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 "media/gpu/vt_video_decode_accelerator_mac.h" +#include "media/gpu/mac/vt_video_decode_accelerator_mac.h" #include <CoreFoundation/CoreFoundation.h> #include <CoreVideo/CoreVideo.h>
diff --git a/media/gpu/vt_video_decode_accelerator_mac.h b/media/gpu/mac/vt_video_decode_accelerator_mac.h similarity index 97% rename from media/gpu/vt_video_decode_accelerator_mac.h rename to media/gpu/mac/vt_video_decode_accelerator_mac.h index 3f01a8b..5ecad5a8 100644 --- a/media/gpu/vt_video_decode_accelerator_mac.h +++ b/media/gpu/mac/vt_video_decode_accelerator_mac.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 MEDIA_GPU_VT_VIDEO_DECODE_ACCELERATOR_MAC_H_ -#define MEDIA_GPU_VT_VIDEO_DECODE_ACCELERATOR_MAC_H_ +#ifndef MEDIA_GPU_MAC_VT_VIDEO_DECODE_ACCELERATOR_MAC_H_ +#define MEDIA_GPU_MAC_VT_VIDEO_DECODE_ACCELERATOR_MAC_H_ #include <stdint.h> @@ -288,4 +288,4 @@ } // namespace media -#endif // MEDIA_GPU_VT_VIDEO_DECODE_ACCELERATOR_MAC_H_ +#endif // MEDIA_GPU_MAC_VT_VIDEO_DECODE_ACCELERATOR_MAC_H_
diff --git a/media/gpu/vt_video_encode_accelerator_mac.cc b/media/gpu/mac/vt_video_encode_accelerator_mac.cc similarity index 99% rename from media/gpu/vt_video_encode_accelerator_mac.cc rename to media/gpu/mac/vt_video_encode_accelerator_mac.cc index d3fce17..243bf4b 100644 --- a/media/gpu/vt_video_encode_accelerator_mac.cc +++ b/media/gpu/mac/vt_video_encode_accelerator_mac.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 "media/gpu/vt_video_encode_accelerator_mac.h" +#include "media/gpu/mac/vt_video_encode_accelerator_mac.h" #include <memory>
diff --git a/media/gpu/vt_video_encode_accelerator_mac.h b/media/gpu/mac/vt_video_encode_accelerator_mac.h similarity index 96% rename from media/gpu/vt_video_encode_accelerator_mac.h rename to media/gpu/mac/vt_video_encode_accelerator_mac.h index 391e14c..255bd5dd 100644 --- a/media/gpu/vt_video_encode_accelerator_mac.h +++ b/media/gpu/mac/vt_video_encode_accelerator_mac.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 MEDIA_GPU_VT_VIDEO_ENCODE_ACCELERATOR_MAC_H_ -#define MEDIA_GPU_VT_VIDEO_ENCODE_ACCELERATOR_MAC_H_ +#ifndef MEDIA_GPU_MAC_VT_VIDEO_ENCODE_ACCELERATOR_MAC_H_ +#define MEDIA_GPU_MAC_VT_VIDEO_ENCODE_ACCELERATOR_MAC_H_ #include <memory> @@ -142,4 +142,4 @@ } // namespace media -#endif // MEDIA_GPU_VT_VIDEO_ENCODE_ACCELERATOR_MAC_H_ +#endif // MEDIA_GPU_MAC_VT_VIDEO_ENCODE_ACCELERATOR_MAC_H_
diff --git a/media/gpu/fake_command_buffer_helper.cc b/media/gpu/test/fake_command_buffer_helper.cc similarity index 98% rename from media/gpu/fake_command_buffer_helper.cc rename to media/gpu/test/fake_command_buffer_helper.cc index 5e061a6..4e7a92cb 100644 --- a/media/gpu/fake_command_buffer_helper.cc +++ b/media/gpu/test/fake_command_buffer_helper.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 "media/gpu/fake_command_buffer_helper.h" +#include "media/gpu/test/fake_command_buffer_helper.h" #include "base/logging.h"
diff --git a/media/gpu/fake_command_buffer_helper.h b/media/gpu/test/fake_command_buffer_helper.h similarity index 93% rename from media/gpu/fake_command_buffer_helper.h rename to media/gpu/test/fake_command_buffer_helper.h index e99f114f..e136974 100644 --- a/media/gpu/fake_command_buffer_helper.h +++ b/media/gpu/test/fake_command_buffer_helper.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 MEDIA_GPU_FAKE_COMMAND_BUFFER_HELPER_H_ -#define MEDIA_GPU_FAKE_COMMAND_BUFFER_HELPER_H_ +#ifndef MEDIA_GPU_TEST_FAKE_COMMAND_BUFFER_HELPER_H_ +#define MEDIA_GPU_TEST_FAKE_COMMAND_BUFFER_HELPER_H_ #include <map> #include <set> @@ -78,4 +78,4 @@ } // namespace media -#endif // MEDIA_GPU_FAKE_COMMAND_BUFFER_HELPER_H_ +#endif // MEDIA_GPU_TEST_FAKE_COMMAND_BUFFER_HELPER_H_
diff --git a/media/gpu/fake_video_decode_accelerator.cc b/media/gpu/test/fake_video_decode_accelerator.cc similarity index 98% rename from media/gpu/fake_video_decode_accelerator.cc rename to media/gpu/test/fake_video_decode_accelerator.cc index 41c4962..935917a 100644 --- a/media/gpu/fake_video_decode_accelerator.cc +++ b/media/gpu/test/fake_video_decode_accelerator.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 "media/gpu/fake_video_decode_accelerator.h" +#include "media/gpu/test/fake_video_decode_accelerator.h" #include <stddef.h> #include <string.h>
diff --git a/media/gpu/fake_video_decode_accelerator.h b/media/gpu/test/fake_video_decode_accelerator.h similarity index 92% rename from media/gpu/fake_video_decode_accelerator.h rename to media/gpu/test/fake_video_decode_accelerator.h index 24c48976..609bb0bd 100644 --- a/media/gpu/fake_video_decode_accelerator.h +++ b/media/gpu/test/fake_video_decode_accelerator.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 MEDIA_GPU_FAKE_VIDEO_DECODE_ACCELERATOR_H_ -#define MEDIA_GPU_FAKE_VIDEO_DECODE_ACCELERATOR_H_ +#ifndef MEDIA_GPU_TEST_FAKE_VIDEO_DECODE_ACCELERATOR_H_ +#define MEDIA_GPU_TEST_FAKE_VIDEO_DECODE_ACCELERATOR_H_ #include <stdint.h> @@ -71,4 +71,4 @@ } // namespace media -#endif // MEDIA_GPU_FAKE_VIDEO_DECODE_ACCELERATOR_H_ +#endif // MEDIA_GPU_TEST_FAKE_VIDEO_DECODE_ACCELERATOR_H_
diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc index 09289b9..41a06c83 100644 --- a/media/gpu/video_decode_accelerator_unittest.cc +++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -61,9 +61,9 @@ #include "media/base/test_data_util.h" #include "media/base/video_frame.h" #include "media/gpu/buildflags.h" -#include "media/gpu/fake_video_decode_accelerator.h" #include "media/gpu/format_utils.h" #include "media/gpu/gpu_video_decode_accelerator_factory.h" +#include "media/gpu/test/fake_video_decode_accelerator.h" #include "media/gpu/test/rendering_helper.h" #include "media/gpu/test/texture_ref.h" #include "media/gpu/test/video_accelerator_unittest_helpers.h"
diff --git a/mojo/core/channel_posix.cc b/mojo/core/channel_posix.cc index 2ef2a5f..9348a93 100644 --- a/mojo/core/channel_posix.cc +++ b/mojo/core/channel_posix.cc
@@ -53,12 +53,7 @@ MessageView(MessageView&& other) { *this = std::move(other); } - MessageView& operator=(MessageView&& other) { - message_ = std::move(other.message_); - offset_ = other.offset_; - handles_ = std::move(other.handles_); - return *this; - } + MessageView& operator=(MessageView&& other) = default; ~MessageView() {}
diff --git a/net/BUILD.gn b/net/BUILD.gn index 71eb22dc..531044e1 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -6053,6 +6053,50 @@ ] } +fuzzer_test("net_cert_ocsp_parse_ocsp_cert_id_fuzzer") { + sources = [ + "cert/internal/ocsp_parse_ocsp_cert_id_fuzzer.cc", + ] + seed_corpus = "data/fuzzer_data/parse_ocsp_cert_id_fuzzer" + deps = [ + "//base", + "//net", + ] +} + +fuzzer_test("net_cert_ocsp_parse_ocsp_single_response_fuzzer") { + sources = [ + "cert/internal/ocsp_parse_ocsp_single_response_fuzzer.cc", + ] + seed_corpus = "data/fuzzer_data/parse_ocsp_single_response_fuzzer" + deps = [ + "//base", + "//net", + ] +} + +fuzzer_test("net_cert_ocsp_parse_ocsp_response_data_fuzzer") { + sources = [ + "cert/internal/ocsp_parse_ocsp_response_data_fuzzer.cc", + ] + seed_corpus = "data/fuzzer_data/parse_ocsp_response_data_fuzzer" + deps = [ + "//base", + "//net", + ] +} + +fuzzer_test("net_cert_ocsp_parse_ocsp_response_fuzzer") { + sources = [ + "cert/internal/ocsp_parse_ocsp_response_fuzzer.cc", + ] + seed_corpus = "data/fuzzer_data/parse_ocsp_response_fuzzer" + deps = [ + "//base", + "//net", + ] +} + fuzzer_test("net_cert_parse_certificate_fuzzer") { sources = [ "cert/internal/parse_certificate_fuzzer.cc",
diff --git a/net/cert/internal/ocsp.h b/net/cert/internal/ocsp.h index 53f5b19d..c530e5b 100644 --- a/net/cert/internal/ocsp.h +++ b/net/cert/internal/ocsp.h
@@ -39,7 +39,7 @@ // issuerKeyHash OCTET STRING, -- Hash of issuer's public key // serialNumber CertificateSerialNumber // } -struct OCSPCertID { +struct NET_EXPORT_PRIVATE OCSPCertID { OCSPCertID(); ~OCSPCertID();
diff --git a/net/cert/internal/ocsp_parse_ocsp_cert_id_fuzzer.cc b/net/cert/internal/ocsp_parse_ocsp_cert_id_fuzzer.cc new file mode 100644 index 0000000..855908d --- /dev/null +++ b/net/cert/internal/ocsp_parse_ocsp_cert_id_fuzzer.cc
@@ -0,0 +1,17 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stddef.h> +#include <stdint.h> + +#include "net/cert/internal/ocsp.h" +#include "net/der/input.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + net::der::Input cert_id_der(data, size); + net::OCSPCertID cert_id; + net::ParseOCSPCertID(cert_id_der, &cert_id); + + return 0; +}
diff --git a/net/cert/internal/ocsp_parse_ocsp_response_data_fuzzer.cc b/net/cert/internal/ocsp_parse_ocsp_response_data_fuzzer.cc new file mode 100644 index 0000000..4d7ca75 --- /dev/null +++ b/net/cert/internal/ocsp_parse_ocsp_response_data_fuzzer.cc
@@ -0,0 +1,17 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stddef.h> +#include <stdint.h> + +#include "net/cert/internal/ocsp.h" +#include "net/der/input.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + net::der::Input response_data_der(data, size); + net::OCSPResponseData response_data; + net::ParseOCSPResponseData(response_data_der, &response_data); + + return 0; +}
diff --git a/net/cert/internal/ocsp_parse_ocsp_response_fuzzer.cc b/net/cert/internal/ocsp_parse_ocsp_response_fuzzer.cc new file mode 100644 index 0000000..f5dae65 --- /dev/null +++ b/net/cert/internal/ocsp_parse_ocsp_response_fuzzer.cc
@@ -0,0 +1,17 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stddef.h> +#include <stdint.h> + +#include "net/cert/internal/ocsp.h" +#include "net/der/input.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + net::der::Input response_der(data, size); + net::OCSPResponse response; + net::ParseOCSPResponse(response_der, &response); + + return 0; +}
diff --git a/net/cert/internal/ocsp_parse_ocsp_single_response_fuzzer.cc b/net/cert/internal/ocsp_parse_ocsp_single_response_fuzzer.cc new file mode 100644 index 0000000..9eddfec4 --- /dev/null +++ b/net/cert/internal/ocsp_parse_ocsp_single_response_fuzzer.cc
@@ -0,0 +1,17 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stddef.h> +#include <stdint.h> + +#include "net/cert/internal/ocsp.h" +#include "net/der/input.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + net::der::Input single_response_der(data, size); + net::OCSPSingleResponse single_response; + net::ParseOCSPSingleResponse(single_response_der, &single_response); + + return 0; +}
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc index 0e3e8a5a..d786360 100644 --- a/net/cookies/cookie_monster_unittest.cc +++ b/net/cookies/cookie_monster_unittest.cc
@@ -119,10 +119,7 @@ const CookieOptions& options) { DCHECK(cm); GetCookieListCallback callback; - cm->GetCookieListWithOptionsAsync( - url, options, - base::BindOnce(&GetCookieListCallback::Run, - base::Unretained(&callback))); + cm->GetCookieListWithOptionsAsync(url, options, callback.MakeCallback()); callback.WaitUntilDone(); return callback.cookies(); } @@ -133,10 +130,7 @@ const CookieOptions& options) { DCHECK(cm); GetCookieListCallback callback; - cm->GetCookieListWithOptionsAsync( - url, options, - base::BindOnce(&GetCookieListCallback::Run, - base::Unretained(&callback))); + cm->GetCookieListWithOptionsAsync(url, options, callback.MakeCallback()); callback.WaitUntilDone(); return callback.excluded_cookies(); } @@ -144,10 +138,7 @@ bool SetAllCookies(CookieMonster* cm, const CookieList& list) { DCHECK(cm); ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback; - cm->SetAllCookiesAsync( - list, base::BindOnce(&ResultSavingCookieCallback< - CanonicalCookie::CookieInclusionStatus>::Run, - base::Unretained(&callback))); + cm->SetAllCookiesAsync(list, callback.MakeCallback()); callback.WaitUntilDone(); return callback.result() == CanonicalCookie::CookieInclusionStatus::INCLUDE; } @@ -162,10 +153,7 @@ cm->SetCanonicalCookieAsync( CanonicalCookie::Create(url, cookie_line, creation_time, CookieOptions()), - url.scheme(), CookieOptions(), - base::BindOnce(&ResultSavingCookieCallback< - CanonicalCookie::CookieInclusionStatus>::Run, - base::Unretained(&callback))); + url.scheme(), CookieOptions(), callback.MakeCallback()); callback.WaitUntilDone(); return callback.result() == CanonicalCookie::CookieInclusionStatus::INCLUDE; } @@ -174,10 +162,8 @@ const TimeRange& creation_range) { DCHECK(cm); ResultSavingCookieCallback<uint32_t> callback; - cm->DeleteAllCreatedInTimeRangeAsync( - creation_range, - base::BindRepeating(&ResultSavingCookieCallback<uint32_t>::Run, - base::Unretained(&callback))); + cm->DeleteAllCreatedInTimeRangeAsync(creation_range, + callback.MakeCallback()); callback.WaitUntilDone(); return callback.result(); } @@ -186,10 +172,8 @@ CookieDeletionInfo delete_info) { DCHECK(cm); ResultSavingCookieCallback<uint32_t> callback; - cm->DeleteAllMatchingInfoAsync( - std::move(delete_info), - base::BindOnce(&ResultSavingCookieCallback<uint32_t>::Run, - base::Unretained(&callback))); + cm->DeleteAllMatchingInfoAsync(std::move(delete_info), + callback.MakeCallback()); callback.WaitUntilDone(); return callback.result(); } @@ -2198,16 +2182,11 @@ // Get all cookies task that queues a task to set a cookie when executed. ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> set_cookie_callback; - cm->SetCookieWithOptionsAsync( - kUrl, "a=b", CookieOptions(), - base::BindOnce(&ResultSavingCookieCallback< - CanonicalCookie::CookieInclusionStatus>::Run, - base::Unretained(&set_cookie_callback))); + cm->SetCookieWithOptionsAsync(kUrl, "a=b", CookieOptions(), + set_cookie_callback.MakeCallback()); GetCookieListCallback get_cookie_list_callback1; - cm->GetAllCookiesAsync( - base::BindOnce(&GetCookieListCallback::Run, - base::Unretained(&get_cookie_list_callback1))); + cm->GetAllCookiesAsync(get_cookie_list_callback1.MakeCallback()); // Two load events should have been queued. ASSERT_EQ(2u, store->commands().size()); @@ -2235,9 +2214,7 @@ // The just set cookie should still be in the store. GetCookieListCallback get_cookie_list_callback2; - cm->GetAllCookiesAsync( - base::BindOnce(&GetCookieListCallback::Run, - base::Unretained(&get_cookie_list_callback2))); + cm->GetAllCookiesAsync(get_cookie_list_callback2.MakeCallback()); get_cookie_list_callback2.WaitUntilDone(); EXPECT_EQ(1u, get_cookie_list_callback2.cookies().size()); } @@ -2253,14 +2230,11 @@ std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); ResultSavingCookieCallback<uint32_t> delete_callback; - cm->DeleteAllAsync(base::BindOnce(&ResultSavingCookieCallback<uint32_t>::Run, - base::Unretained(&delete_callback))); + cm->DeleteAllAsync(delete_callback.MakeCallback()); GetCookieListCallback get_cookie_list_callback; - cm->GetCookieListWithOptionsAsync( - kUrl, CookieOptions(), - base::BindOnce(&GetCookieListCallback::Run, - base::Unretained(&get_cookie_list_callback))); + cm->GetCookieListWithOptionsAsync(kUrl, CookieOptions(), + get_cookie_list_callback.MakeCallback()); // Only the main load should have been queued. ASSERT_EQ(1u, store->commands().size()); @@ -2293,22 +2267,15 @@ std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_)); GetCookieListCallback get_cookie_list_callback1; - cm->GetAllCookiesAsync( - base::BindOnce(&GetCookieListCallback::Run, - base::Unretained(&get_cookie_list_callback1))); + cm->GetAllCookiesAsync(get_cookie_list_callback1.MakeCallback()); ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> set_cookie_callback; - cm->SetCookieWithOptionsAsync( - kUrl, "a=b", CookieOptions(), - base::BindOnce(&ResultSavingCookieCallback< - CanonicalCookie::CookieInclusionStatus>::Run, - base::Unretained(&set_cookie_callback))); + cm->SetCookieWithOptionsAsync(kUrl, "a=b", CookieOptions(), + set_cookie_callback.MakeCallback()); GetCookieListCallback get_cookie_list_callback2; - cm->GetAllCookiesAsync( - base::BindOnce(&GetCookieListCallback::Run, - base::Unretained(&get_cookie_list_callback2))); + cm->GetAllCookiesAsync(get_cookie_list_callback2.MakeCallback()); // Only the main load should have been queued. ASSERT_EQ(1u, store->commands().size()); @@ -2354,19 +2321,14 @@ set_cookie_callback; cm->GetAllCookiesAsync(base::BindOnce( &RunClosureOnCookieListReceived, - base::BindOnce( - &CookieStore::SetCookieWithOptionsAsync, base::Unretained(cm.get()), - kUrl, "a=b", CookieOptions(), - base::BindOnce(&ResultSavingCookieCallback< - CanonicalCookie::CookieInclusionStatus>::Run, - base::Unretained(&set_cookie_callback))))); + base::BindOnce(&CookieStore::SetCookieWithOptionsAsync, + base::Unretained(cm.get()), kUrl, "a=b", CookieOptions(), + set_cookie_callback.MakeCallback()))); // Get cookie task. Queued before the delete task is executed, so should not // see the set cookie. GetCookieListCallback get_cookie_list_callback1; - cm->GetAllCookiesAsync( - base::BindOnce(&GetCookieListCallback::Run, - base::Unretained(&get_cookie_list_callback1))); + cm->GetAllCookiesAsync(get_cookie_list_callback1.MakeCallback()); // Only the main load should have been queued. ASSERT_EQ(1u, store->commands().size()); @@ -2386,9 +2348,7 @@ // A subsequent get cookies call should see the new cookie. GetCookieListCallback get_cookie_list_callback2; - cm->GetAllCookiesAsync( - base::BindOnce(&GetCookieListCallback::Run, - base::Unretained(&get_cookie_list_callback2))); + cm->GetAllCookiesAsync(get_cookie_list_callback2.MakeCallback()); get_cookie_list_callback2.WaitUntilDone(); EXPECT_EQ(1u, get_cookie_list_callback2.cookies().size()); } @@ -3163,17 +3123,12 @@ cm.SetCanonicalCookieAsync( CanonicalCookie::Create(GURL("http://a.com/"), "A=B", base::Time::Now(), CookieOptions()), - "http", CookieOptions(), - base::BindOnce(&ResultSavingCookieCallback< - CanonicalCookie::CookieInclusionStatus>::Run, - base::Unretained(&callback_set))); + "http", CookieOptions(), callback_set.MakeCallback()); // Get cookies for a different URL. GetCookieListCallback callback_get; - cm.GetCookieListWithOptionsAsync( - GURL("http://b.com/"), CookieOptions(), - base::BindOnce(&GetCookieListCallback::Run, - base::Unretained(&callback_get))); + cm.GetCookieListWithOptionsAsync(GURL("http://b.com/"), CookieOptions(), + callback_get.MakeCallback()); // Now go through the store commands, and execute individual loads. for (const CookieStoreCommand& command : persistent_store->commands()) { @@ -3246,31 +3201,23 @@ auto cookie = CanonicalCookie::Create(url, cookie_line, t1, options); ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> set_callback_1; - cm.SetCanonicalCookieAsync( - std::move(cookie), url.scheme(), options, - base::BindOnce(&ResultSavingCookieCallback< - CanonicalCookie::CookieInclusionStatus>::Run, - base::Unretained(&set_callback_1))); + cm.SetCanonicalCookieAsync(std::move(cookie), url.scheme(), options, + set_callback_1.MakeCallback()); set_callback_1.WaitUntilDone(); // Overwrite the cookie at |t2|. cookie = CanonicalCookie::Create(url, cookie_line, t2, options); ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> set_callback_2; - cm.SetCanonicalCookieAsync( - std::move(cookie), url.scheme(), options, - base::BindOnce(&ResultSavingCookieCallback< - CanonicalCookie::CookieInclusionStatus>::Run, - base::Unretained(&set_callback_2))); + cm.SetCanonicalCookieAsync(std::move(cookie), url.scheme(), options, + set_callback_2.MakeCallback()); set_callback_2.WaitUntilDone(); // The second cookie overwrites the first one but it will inherit the creation // timestamp |t1|. Test that deleting the new cookie still works. cookie = CanonicalCookie::Create(url, cookie_line, t2, options); ResultSavingCookieCallback<unsigned int> delete_callback; - cm.DeleteCanonicalCookieAsync( - *cookie, base::BindOnce(&ResultSavingCookieCallback<unsigned int>::Run, - base::Unretained(&delete_callback))); + cm.DeleteCanonicalCookieAsync(*cookie, delete_callback.MakeCallback()); delete_callback.WaitUntilDone(); EXPECT_EQ(1U, delete_callback.result()); }
diff --git a/net/cookies/cookie_store_unittest.h b/net/cookies/cookie_store_unittest.h index 682823e..b8fd108 100644 --- a/net/cookies/cookie_store_unittest.h +++ b/net/cookies/cookie_store_unittest.h
@@ -141,9 +141,7 @@ const CookieOptions& options) { DCHECK(cs); GetCookieListCallback callback; - cs->GetCookieListWithOptionsAsync( - url, options, - base::Bind(&GetCookieListCallback::Run, base::Unretained(&callback))); + cs->GetCookieListWithOptionsAsync(url, options, callback.MakeCallback()); callback.WaitUntilDone(); return CanonicalCookie::BuildCookieLine(callback.cookies()); } @@ -153,9 +151,7 @@ const CookieOptions& options) { DCHECK(cs); GetCookieListCallback callback; - cs->GetCookieListWithOptionsAsync( - url, options, - base::Bind(&GetCookieListCallback::Run, base::Unretained(&callback))); + cs->GetCookieListWithOptionsAsync(url, options, callback.MakeCallback()); callback.WaitUntilDone(); return callback.cookies(); } @@ -163,8 +159,7 @@ CookieList GetAllCookiesForURL(CookieStore* cs, const GURL& url) { DCHECK(cs); GetCookieListCallback callback; - cs->GetAllCookiesForURLAsync(url, base::Bind(&GetCookieListCallback::Run, - base::Unretained(&callback))); + cs->GetAllCookiesForURLAsync(url, callback.MakeCallback()); callback.WaitUntilDone(); return callback.cookies(); } @@ -177,10 +172,7 @@ options.set_same_site_cookie_context( CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT); options.set_return_excluded_cookies(); - cs->GetCookieListWithOptionsAsync( - url, options, - base::BindOnce(&GetCookieListCallback::Run, - base::Unretained(&callback))); + cs->GetCookieListWithOptionsAsync(url, options, callback.MakeCallback()); callback.WaitUntilDone(); return callback.excluded_cookies(); } @@ -188,8 +180,7 @@ CookieList GetAllCookies(CookieStore* cs) { DCHECK(cs); GetCookieListCallback callback; - cs->GetAllCookiesAsync( - base::Bind(&GetCookieListCallback::Run, base::Unretained(&callback))); + cs->GetAllCookiesAsync(callback.MakeCallback()); callback.WaitUntilDone(); return callback.cookies(); } @@ -200,11 +191,8 @@ const CookieOptions& options) { DCHECK(cs); ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback; - cs->SetCookieWithOptionsAsync( - url, cookie_line, options, - base::BindOnce(&ResultSavingCookieCallback< - CanonicalCookie::CookieInclusionStatus>::Run, - base::Unretained(&callback))); + cs->SetCookieWithOptionsAsync(url, cookie_line, options, + callback.MakeCallback()); callback.WaitUntilDone(); return callback.result() == CanonicalCookie::CookieInclusionStatus::INCLUDE; } @@ -218,11 +206,8 @@ CookieOptions options; if (can_modify_httponly) options.set_include_httponly(); - cs->SetCanonicalCookieAsync( - std::move(cookie), std::move(source_scheme), options, - base::BindOnce(&ResultSavingCookieCallback< - CanonicalCookie::CookieInclusionStatus>::Run, - base::Unretained(&callback))); + cs->SetCanonicalCookieAsync(std::move(cookie), std::move(source_scheme), + options, callback.MakeCallback()); callback.WaitUntilDone(); return callback.result() == CanonicalCookie::CookieInclusionStatus::INCLUDE; } @@ -257,11 +242,8 @@ DCHECK(cs); ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback; - cs->SetCookieWithOptionsAsync( - url, cookie_line, options, - base::BindOnce(&ResultSavingCookieCallback< - CanonicalCookie::CookieInclusionStatus>::Run, - base::Unretained(&callback))); + cs->SetCookieWithOptionsAsync(url, cookie_line, options, + callback.MakeCallback()); callback.WaitUntilDone(); return callback.result(); } @@ -276,11 +258,8 @@ CookieOptions options; if (can_modify_httponly) options.set_include_httponly(); - cs->SetCanonicalCookieAsync( - std::move(cookie), std::move(source_scheme), options, - base::BindOnce(&ResultSavingCookieCallback< - CanonicalCookie::CookieInclusionStatus>::Run, - base::Unretained(&callback))); + cs->SetCanonicalCookieAsync(std::move(cookie), std::move(source_scheme), + options, callback.MakeCallback()); callback.WaitUntilDone(); return callback.result(); } @@ -289,9 +268,7 @@ const CanonicalCookie& cookie) { DCHECK(cs); ResultSavingCookieCallback<uint32_t> callback; - cs->DeleteCanonicalCookieAsync( - cookie, base::Bind(&ResultSavingCookieCallback<uint32_t>::Run, - base::Unretained(&callback))); + cs->DeleteCanonicalCookieAsync(cookie, callback.MakeCallback()); callback.WaitUntilDone(); return callback.result(); } @@ -300,10 +277,8 @@ const TimeRange& creation_range) { DCHECK(cs); ResultSavingCookieCallback<uint32_t> callback; - cs->DeleteAllCreatedInTimeRangeAsync( - creation_range, - base::BindRepeating(&ResultSavingCookieCallback<uint32_t>::Run, - base::Unretained(&callback))); + cs->DeleteAllCreatedInTimeRangeAsync(creation_range, + callback.MakeCallback()); callback.WaitUntilDone(); return callback.result(); } @@ -312,10 +287,8 @@ CookieDeletionInfo delete_info) { DCHECK(cs); ResultSavingCookieCallback<uint32_t> callback; - cs->DeleteAllMatchingInfoAsync( - std::move(delete_info), - base::Bind(&ResultSavingCookieCallback<uint32_t>::Run, - base::Unretained(&callback))); + cs->DeleteAllMatchingInfoAsync(std::move(delete_info), + callback.MakeCallback()); callback.WaitUntilDone(); return callback.result(); } @@ -323,9 +296,7 @@ uint32_t DeleteSessionCookies(CookieStore* cs) { DCHECK(cs); ResultSavingCookieCallback<uint32_t> callback; - cs->DeleteSessionCookiesAsync( - base::Bind(&ResultSavingCookieCallback<uint32_t>::Run, - base::Unretained(&callback))); + cs->DeleteSessionCookiesAsync(callback.MakeCallback()); callback.WaitUntilDone(); return callback.result(); } @@ -333,8 +304,7 @@ uint32_t DeleteAll(CookieStore* cs) { DCHECK(cs); ResultSavingCookieCallback<uint32_t> callback; - cs->DeleteAllAsync(base::Bind(&ResultSavingCookieCallback<uint32_t>::Run, - base::Unretained(&callback))); + cs->DeleteAllAsync(callback.MakeCallback()); callback.WaitUntilDone(); return callback.result(); }
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/bad_issuer_key_hash_type b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/bad_issuer_key_hash_type new file mode 100644 index 0000000..8b001aa --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/bad_issuer_key_hash_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/bad_name_hash_type b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/bad_name_hash_type new file mode 100644 index 0000000..63084c2 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/bad_name_hash_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/bad_params b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/bad_params new file mode 100644 index 0000000..059120ed --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/bad_params Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/bad_serial_number_type b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/bad_serial_number_type new file mode 100644 index 0000000..29224ffd --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/bad_serial_number_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/empty_hash b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/empty_hash new file mode 100644 index 0000000..595db6b --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/empty_hash Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/empty_hash_oid b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/empty_hash_oid new file mode 100644 index 0000000..282dbb1 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/empty_hash_oid Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/empty_sequence b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/empty_sequence new file mode 100644 index 0000000..def7fcb --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/empty_sequence Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/empty_serial_number b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/empty_serial_number new file mode 100644 index 0000000..6296a22 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/empty_serial_number Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/good b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/good new file mode 100644 index 0000000..788cbf0 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/good
@@ -0,0 +1,2 @@ +0;0 +*ÏUuÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/hash_as_integer b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/hash_as_integer new file mode 100644 index 0000000..7b407db --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/hash_as_integer Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/hash_oid_as_integer b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/hash_oid_as_integer new file mode 100644 index 0000000..f2234fb --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/hash_oid_as_integer Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/md4_params b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/md4_params new file mode 100644 index 0000000..8448edb --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/md4_params Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/negative_serial b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/negative_serial new file mode 100644 index 0000000..009e7f4 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/negative_serial Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/non_minimal_serial b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/non_minimal_serial new file mode 100644 index 0000000..32bd979 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/non_minimal_serial Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/not_sequence b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/not_sequence new file mode 100644 index 0000000..cfcc2fe --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/not_sequence
@@ -0,0 +1 @@ + \ No newline at end of file
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/null_params b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/null_params new file mode 100644 index 0000000..2bc8fb5 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/null_params Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/overlong_serial b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/overlong_serial new file mode 100644 index 0000000..ee0e2b6 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/overlong_serial Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/trailing_data b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/trailing_data new file mode 100644 index 0000000..8507597 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/trailing_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/trailing_inner_data b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/trailing_inner_data new file mode 100644 index 0000000..13f1aec4 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/trailing_inner_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/unknown_hash_oid b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/unknown_hash_oid new file mode 100644 index 0000000..c11ffee --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/unknown_hash_oid
@@ -0,0 +1 @@ +0 0+ \ No newline at end of file
diff --git a/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/zero_serial b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/zero_serial new file mode 100644 index 0000000..cb9c66422 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_cert_id_fuzzer/zero_serial Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_produced_at_type b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_produced_at_type new file mode 100644 index 0000000..033c54b --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_produced_at_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responder_id_key_hash_length b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responder_id_key_hash_length new file mode 100644 index 0000000..302c64b --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responder_id_key_hash_length
@@ -0,0 +1 @@ +0¢ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responder_id_key_hash_trailing_data b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responder_id_key_hash_trailing_data new file mode 100644 index 0000000..42906d0 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responder_id_key_hash_trailing_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responder_id_key_hash_type b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responder_id_key_hash_type new file mode 100644 index 0000000..5b667cc --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responder_id_key_hash_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responses_data b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responses_data new file mode 100644 index 0000000..6638cbfc --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responses_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responses_type b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responses_type new file mode 100644 index 0000000..4b09b3c --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/bad_responses_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/empty_extensions b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/empty_extensions new file mode 100644 index 0000000..c46e843 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/empty_extensions Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/empty_responder_id_name b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/empty_responder_id_name new file mode 100644 index 0000000..7cb619dc --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/empty_responder_id_name Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/empty_responses b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/empty_responses new file mode 100644 index 0000000..62840b94 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/empty_responses Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/empty_version b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/empty_version new file mode 100644 index 0000000..fa20e44 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/empty_version Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/null_responses_data b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/null_responses_data new file mode 100644 index 0000000..29bbc444 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/null_responses_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/trailing_junk b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/trailing_junk new file mode 100644 index 0000000..d69f701a --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/trailing_junk Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/trailing_outer_data b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/trailing_outer_data new file mode 100644 index 0000000..3b73587 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/trailing_outer_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/version_explicit_default b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/version_explicit_default new file mode 100644 index 0000000..15c89fbb5 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/version_explicit_default Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/version_too_large b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/version_too_large new file mode 100644 index 0000000..4c5e703 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/version_too_large
@@ -0,0 +1 @@ +0 \ No newline at end of file
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/version_too_new b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/version_too_new new file mode 100644 index 0000000..6dfd6ad --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/version_too_new
@@ -0,0 +1 @@ +0 \ No newline at end of file
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/version_trailing_data b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/version_trailing_data new file mode 100644 index 0000000..75412ad --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/version_trailing_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/wrong_outer_type b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/wrong_outer_type new file mode 100644 index 0000000..19b3e94 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/wrong_outer_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/wrong_responder_id_type b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/wrong_responder_id_type new file mode 100644 index 0000000..df0dd6d --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_data_fuzzer/wrong_responder_id_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/baisc_response_bad_data b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/baisc_response_bad_data new file mode 100644 index 0000000..418147d1 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/baisc_response_bad_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/baisc_response_trailing_data b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/baisc_response_trailing_data new file mode 100644 index 0000000..6e5c0fe3 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/baisc_response_trailing_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_certs b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_certs new file mode 100644 index 0000000..0460e1af --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_certs Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_certs_inner_data b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_certs_inner_data new file mode 100644 index 0000000..eb4dd03a --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_certs_inner_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_certs_trailing_data b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_certs_trailing_data new file mode 100644 index 0000000..9c322c4 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_certs_trailing_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_certs_type b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_certs_type new file mode 100644 index 0000000..61fd3a2 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_certs_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg new file mode 100644 index 0000000..2b501de --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_bad_params b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_bad_params new file mode 100644 index 0000000..cb855ef --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_bad_params Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_bad_sha1_non_empty_params b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_bad_sha1_non_empty_params new file mode 100644 index 0000000..8a593e7 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_bad_sha1_non_empty_params Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_bad_sha1_params b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_bad_sha1_params new file mode 100644 index 0000000..497e993 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_bad_sha1_params Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_data_trailing_params b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_data_trailing_params new file mode 100644 index 0000000..c6ce25e --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_data_trailing_params Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_empty_oid b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_empty_oid new file mode 100644 index 0000000..b27581b --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_empty_oid Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_oid_type b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_oid_type new file mode 100644 index 0000000..2a2db0a --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_oid_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_type b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_type new file mode 100644 index 0000000..cef9501 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_alg_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_type b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_type new file mode 100644 index 0000000..a0d9616 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_bad_sig_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_empty_certs b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_empty_certs new file mode 100644 index 0000000..6da3aa0 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_empty_certs Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_empty_sig b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_empty_sig new file mode 100644 index 0000000..97ef6a9a --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_empty_sig Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_null_certs b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_null_certs new file mode 100644 index 0000000..73ff9c0 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_null_certs Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_trailing_inner_junk b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_trailing_inner_junk new file mode 100644 index 0000000..169dbea --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_trailing_inner_junk Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_trailing_junk b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_trailing_junk new file mode 100644 index 0000000..3ce548d --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_trailing_junk Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_trailing_outer_junk b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_trailing_outer_junk new file mode 100644 index 0000000..52eb0f86 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/basic_response_trailing_outer_junk Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_bad_oid_type b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_bad_oid_type new file mode 100644 index 0000000..a821342c --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_bad_oid_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_bad_response_type b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_bad_response_type new file mode 100644 index 0000000..cd6df83 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_bad_response_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_empty_oid b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_empty_oid new file mode 100644 index 0000000..63152f7 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_empty_oid Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_empty_response b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_empty_response new file mode 100644 index 0000000..8c42956 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_empty_response Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_trailing_data b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_trailing_data new file mode 100644 index 0000000..ffdf181 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_bytes_trailing_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_status_type_out_of_range b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_status_type_out_of_range new file mode 100644 index 0000000..e96966e --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_status_type_out_of_range
@@ -0,0 +1,2 @@ +0 + \ No newline at end of file
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_status_type_too_large b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_status_type_too_large new file mode 100644 index 0000000..a071026 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/response_status_type_too_large
@@ -0,0 +1,2 @@ +0 + \ No newline at end of file
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/trailing_inner_data b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/trailing_inner_data new file mode 100644 index 0000000..d3fa1b40 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/trailing_inner_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/trailing_outer_data b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/trailing_outer_data new file mode 100644 index 0000000..3b73587 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/trailing_outer_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/try_later b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/try_later new file mode 100644 index 0000000..39e09cf --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/try_later
@@ -0,0 +1,2 @@ +0 + \ No newline at end of file
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/unused b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/unused new file mode 100644 index 0000000..38383937 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/unused
@@ -0,0 +1,2 @@ +0 + \ No newline at end of file
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_basic_response_type b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_basic_response_type new file mode 100644 index 0000000..7966443 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_basic_response_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_outer_type b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_outer_type new file mode 100644 index 0000000..bbfb76b --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_outer_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_response_bytes b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_response_bytes new file mode 100644 index 0000000..0b7768bc --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_response_bytes Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_response_bytes_type b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_response_bytes_type new file mode 100644 index 0000000..5bd1e98 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_response_bytes_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_response_status_type b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_response_status_type new file mode 100644 index 0000000..7b407db --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_response_fuzzer/wrong_response_status_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_cert_status_context b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_cert_status_context new file mode 100644 index 0000000..610d533 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_cert_status_context Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_cert_status_type b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_cert_status_type new file mode 100644 index 0000000..f3ca9af89 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_cert_status_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_extensions b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_extensions new file mode 100644 index 0000000..e654d41 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_extensions Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_next_update b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_next_update new file mode 100644 index 0000000..b04f3adc --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_next_update Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_next_update_trailing_data b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_next_update_trailing_data new file mode 100644 index 0000000..d228524 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_next_update_trailing_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_next_update_type b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_next_update_type new file mode 100644 index 0000000..f0d1489 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_next_update_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_outer_type b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_outer_type new file mode 100644 index 0000000..bbfb76b --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_outer_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_date_offset b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_date_offset new file mode 100644 index 0000000..85b7ccf --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_date_offset Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_date_type b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_date_type new file mode 100644 index 0000000..e890edb6 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_date_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_date_value b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_date_value new file mode 100644 index 0000000..65e3709 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_date_value Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_integer b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_integer new file mode 100644 index 0000000..03c66fe --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_integer Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_primitive b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_primitive new file mode 100644 index 0000000..5a849848 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_primitive Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_out_of_range b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_out_of_range new file mode 100644 index 0000000..a31531c --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_out_of_range Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_too_large b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_too_large new file mode 100644 index 0000000..bec5172 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_too_large Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_trailing_data b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_trailing_data new file mode 100644 index 0000000..778630f --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_trailing_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_type b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_type new file mode 100644 index 0000000..144078b --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_unused b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_unused new file mode 100644 index 0000000..0bade04 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_reason_value_unused Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_trailing_data b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_trailing_data new file mode 100644 index 0000000..5e5bcbc --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_revoked_info_trailing_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_this_update_type b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_this_update_type new file mode 100644 index 0000000..0d82e23 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/bad_this_update_type Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/empty_extensions b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/empty_extensions new file mode 100644 index 0000000..457a329 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/empty_extensions Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/empty_next_update b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/empty_next_update new file mode 100644 index 0000000..d401d935 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/empty_next_update Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/no_extensions b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/no_extensions new file mode 100644 index 0000000..d026ebb --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/no_extensions Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/trailing_inner_data b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/trailing_inner_data new file mode 100644 index 0000000..5f58d17 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/trailing_inner_data Binary files differ
diff --git a/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/trailing_outer_data b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/trailing_outer_data new file mode 100644 index 0000000..8507597 --- /dev/null +++ b/net/data/fuzzer_data/parse_ocsp_single_response_fuzzer/trailing_outer_data Binary files differ
diff --git a/net/http/http_stream_factory.cc b/net/http/http_stream_factory.cc index ab4168da..6eded7b5 100644 --- a/net/http/http_stream_factory.cc +++ b/net/http/http_stream_factory.cc
@@ -217,14 +217,12 @@ } void HttpStreamFactory::OnJobControllerComplete(JobController* controller) { - for (auto it = job_controller_set_.begin(); it != job_controller_set_.end(); - ++it) { - if (it->get() == controller) { - job_controller_set_.erase(it); - return; - } + auto it = job_controller_set_.find(controller); + if (it != job_controller_set_.end()) { + job_controller_set_.erase(it); + } else { + NOTREACHED(); } - NOTREACHED(); } HttpStreamFactory::PreconnectingProxyServer::PreconnectingProxyServer(
diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h index 45a0657..ffffb93 100644 --- a/net/http/http_stream_factory.h +++ b/net/http/http_stream_factory.h
@@ -13,6 +13,7 @@ #include <set> #include <string> +#include "base/containers/unique_ptr_adapters.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -123,7 +124,8 @@ friend class HttpStreamFactoryPeer; - using JobControllerSet = std::set<std::unique_ptr<JobController>>; + using JobControllerSet = + std::set<std::unique_ptr<JobController>, base::UniquePtrComparator>; url::SchemeHostPort RewriteHost(const url::SchemeHostPort& server);
diff --git a/services/network/p2p/socket_manager.cc b/services/network/p2p/socket_manager.cc index 475c27ff..071c13e 100644 --- a/services/network/p2p/socket_manager.cc +++ b/services/network/p2p/socket_manager.cc
@@ -6,7 +6,6 @@ #include <stddef.h> -#include <algorithm> #include <utility> #include "base/bind.h" @@ -374,11 +373,7 @@ const net::IPAddressList& addresses) { std::move(callback).Run(addresses); - dns_requests_.erase( - std::find_if(dns_requests_.begin(), dns_requests_.end(), - [request](const std::unique_ptr<DnsRequest>& ptr) { - return ptr.get() == request; - })); + dns_requests_.erase(dns_requests_.find(request)); } void P2PSocketManager::OnConnectionError() {
diff --git a/services/network/p2p/socket_manager.h b/services/network/p2p/socket_manager.h index 191fe96f..4ba2788 100644 --- a/services/network/p2p/socket_manager.h +++ b/services/network/p2p/socket_manager.h
@@ -14,6 +14,7 @@ #include "base/callback.h" #include "base/containers/flat_map.h" +#include "base/containers/unique_ptr_adapters.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" @@ -121,7 +122,8 @@ base::flat_map<P2PSocket*, std::unique_ptr<P2PSocket>> sockets_; - std::set<std::unique_ptr<DnsRequest>> dns_requests_; + std::set<std::unique_ptr<DnsRequest>, base::UniquePtrComparator> + dns_requests_; P2PMessageThrottler throttler_; bool dump_incoming_rtp_packet_ = false;
diff --git a/services/ws/public/mojom/ime/ime.mojom b/services/ws/public/mojom/ime/ime.mojom index 5548b31..04ca6de 100644 --- a/services/ws/public/mojom/ime/ime.mojom +++ b/services/ws/public/mojom/ime/ime.mojom
@@ -59,47 +59,6 @@ mojo_base.mojom.String16 description_body; }; -// See comments for ui::ImeTextSpan::Type for more details. -enum ImeTextSpanType { - kComposition, - kSuggestion, - kMisspellingSuggestion, -}; - -// This enum represents the thickness of an underline segment of text, -// the thickness of a ui::ImeTextSpan element. -// The possible values are: -// * kNone: When you don't want to paint the underline. -// * kThin: For regular size. -// * kThick: For thick underlines. -enum ImeTextSpanThickness { - kNone, - kThin, - kThick, -}; - -// Represents an underlined segment of text currently composed by IME. -// Corresponds to ui::ImeTextSpan. -struct ImeTextSpan { - ImeTextSpanType type; - uint32 start_offset; - uint32 end_offset; - uint32 underline_color; - ImeTextSpanThickness thickness; - uint32 background_color; - uint32 suggestion_highlight_color; - bool remove_on_finish_composing; - array<string> suggestions; -}; - -// Represents a text currently being composed by IME. Corresponds to -// ui::CompositionText. -struct CompositionText { - mojo_base.mojom.String16 text; - array<ImeTextSpan> ime_text_spans; - gfx.mojom.Range selection; -}; - // Represents the text input state of a client. struct TextInputState { ui.mojom.TextInputType text_input_type; @@ -123,16 +82,6 @@ array<bool>? edit_command_enabled; }; -// Represents how a text client gets focused. Corresponds to -// ui::TextInputClient::FocusReason. -enum FocusReason { - kNone, // Not focused. - kMouse, // User initiated with mouse. - kTouch, // User initiated with touch. - kPen, // User initiated with pen. - kOther, // All other reasons (e.g. system initiated, mouse) -}; - // Detailed data of an IME session. struct SessionDetails { // State of the text input client. @@ -145,7 +94,7 @@ TextInputClientData data; // How the text input client was focused. - FocusReason focus_reason; + ui.mojom.FocusReason focus_reason; // ukm::SourceId for identifying the text input client. int64 client_source_for_metrics; @@ -205,7 +154,7 @@ // Sets composition text and attributes. See comments for // ui::TextInputClient::SetCompositionText() for more details. - SetCompositionText(CompositionText composition); + SetCompositionText(ui.mojom.CompositionText composition); // Converts current composition text into final content. ConfirmCompositionText();
diff --git a/services/ws/public/mojom/ime/ime.typemap b/services/ws/public/mojom/ime/ime.typemap index 325e7354..e1492ceb 100644 --- a/services/ws/public/mojom/ime/ime.typemap +++ b/services/ws/public/mojom/ime/ime.typemap
@@ -3,31 +3,16 @@ # found in the LICENSE file. mojom = "//services/ws/public/mojom/ime/ime.mojom" -public_headers = [ - "//ui/base/ime/candidate_window.h", - "//ui/base/ime/composition_text.h", - "//ui/base/ime/ime_text_span.h", - "//ui/base/ime/text_input_client.h", - "//ui/base/ime/text_input_mode.h", - "//ui/base/ime/text_input_type.h", -] +public_headers = [ "//ui/base/ime/candidate_window.h" ] traits_headers = [ "//services/ws/public/mojom/ime/ime_struct_traits.h" ] sources = [ "//services/ws/public/mojom/ime/ime_struct_traits.cc", ] public_deps = [ - "//ui/base/ime", -] -deps = [ - "//ui/gfx/range", - "//ui/gfx/range/mojo:struct_traits", + "//ui/base/ime:ime_types", ] type_mappings = [ "ws.mojom.CandidateWindowEntry=ui::CandidateWindow::Entry", "ws.mojom.CandidateWindowProperties=ui::CandidateWindow::CandidateWindowProperty", - "ws.mojom.CompositionText=ui::CompositionText", - "ws.mojom.FocusReason=ui::TextInputClient::FocusReason", - "ws.mojom.ImeTextSpan=ui::ImeTextSpan", - "ws.mojom.ImeTextSpanThickness=ui::ImeTextSpan::Thickness", ]
diff --git a/services/ws/public/mojom/ime/ime_struct_traits.cc b/services/ws/public/mojom/ime/ime_struct_traits.cc index 156d7b7..a5bc13b 100644 --- a/services/ws/public/mojom/ime/ime_struct_traits.cc +++ b/services/ws/public/mojom/ime/ime_struct_traits.cc
@@ -5,7 +5,6 @@ #include "services/ws/public/mojom/ime/ime_struct_traits.h" #include "mojo/public/cpp/base/string16_mojom_traits.h" -#include "ui/gfx/range/mojo/range_struct_traits.h" namespace mojo { @@ -40,154 +39,4 @@ data.ReadDescriptionBody(&out->description_body); } -// static -bool StructTraits<ws::mojom::ImeTextSpanDataView, ui::ImeTextSpan>::Read( - ws::mojom::ImeTextSpanDataView data, - ui::ImeTextSpan* out) { - if (data.is_null()) - return false; - if (!data.ReadType(&out->type)) - return false; - out->start_offset = data.start_offset(); - out->end_offset = data.end_offset(); - out->underline_color = data.underline_color(); - if (!data.ReadThickness(&out->thickness)) - return false; - out->background_color = data.background_color(); - out->suggestion_highlight_color = data.suggestion_highlight_color(); - out->remove_on_finish_composing = data.remove_on_finish_composing(); - if (!data.ReadSuggestions(&out->suggestions)) - return false; - return true; -} - -// static -bool StructTraits<ws::mojom::CompositionTextDataView, ui::CompositionText>:: - Read(ws::mojom::CompositionTextDataView data, ui::CompositionText* out) { - return !data.is_null() && data.ReadText(&out->text) && - data.ReadImeTextSpans(&out->ime_text_spans) && - data.ReadSelection(&out->selection); -} - -// static -ws::mojom::FocusReason -EnumTraits<ws::mojom::FocusReason, ui::TextInputClient::FocusReason>::ToMojom( - ui::TextInputClient::FocusReason input) { - switch (input) { - case ui::TextInputClient::FOCUS_REASON_NONE: - return ws::mojom::FocusReason::kNone; - case ui::TextInputClient::FOCUS_REASON_MOUSE: - return ws::mojom::FocusReason::kMouse; - case ui::TextInputClient::FOCUS_REASON_TOUCH: - return ws::mojom::FocusReason::kTouch; - case ui::TextInputClient::FOCUS_REASON_PEN: - return ws::mojom::FocusReason::kPen; - case ui::TextInputClient::FOCUS_REASON_OTHER: - return ws::mojom::FocusReason::kOther; - } - - NOTREACHED(); - return ws::mojom::FocusReason::kNone; -} - -// static -bool EnumTraits<ws::mojom::FocusReason, ui::TextInputClient::FocusReason>:: - FromMojom(ws::mojom::FocusReason input, - ui::TextInputClient::FocusReason* out) { - switch (input) { - case ws::mojom::FocusReason::kNone: - *out = ui::TextInputClient::FOCUS_REASON_NONE; - return true; - case ws::mojom::FocusReason::kMouse: - *out = ui::TextInputClient::FOCUS_REASON_MOUSE; - return true; - case ws::mojom::FocusReason::kTouch: - *out = ui::TextInputClient::FOCUS_REASON_TOUCH; - return true; - case ws::mojom::FocusReason::kPen: - *out = ui::TextInputClient::FOCUS_REASON_PEN; - return true; - case ws::mojom::FocusReason::kOther: - *out = ui::TextInputClient::FOCUS_REASON_OTHER; - return true; - } - - NOTREACHED(); - return false; -} - -// static -ws::mojom::ImeTextSpanType -EnumTraits<ws::mojom::ImeTextSpanType, ui::ImeTextSpan::Type>::ToMojom( - ui::ImeTextSpan::Type ime_text_span_type) { - switch (ime_text_span_type) { - case ui::ImeTextSpan::Type::kComposition: - return ws::mojom::ImeTextSpanType::kComposition; - case ui::ImeTextSpan::Type::kSuggestion: - return ws::mojom::ImeTextSpanType::kSuggestion; - case ui::ImeTextSpan::Type::kMisspellingSuggestion: - return ws::mojom::ImeTextSpanType::kMisspellingSuggestion; - } - - NOTREACHED(); - return ws::mojom::ImeTextSpanType::kComposition; -} - -// static -bool EnumTraits<ws::mojom::ImeTextSpanType, ui::ImeTextSpan::Type>::FromMojom( - ws::mojom::ImeTextSpanType type, - ui::ImeTextSpan::Type* out) { - switch (type) { - case ws::mojom::ImeTextSpanType::kComposition: - *out = ui::ImeTextSpan::Type::kComposition; - return true; - case ws::mojom::ImeTextSpanType::kSuggestion: - *out = ui::ImeTextSpan::Type::kSuggestion; - return true; - case ws::mojom::ImeTextSpanType::kMisspellingSuggestion: - *out = ui::ImeTextSpan::Type::kMisspellingSuggestion; - return true; - } - - NOTREACHED(); - return false; -} - -// static -ws::mojom::ImeTextSpanThickness EnumTraits< - ws::mojom::ImeTextSpanThickness, - ui::ImeTextSpan::Thickness>::ToMojom(ui::ImeTextSpan::Thickness thickness) { - switch (thickness) { - case ui::ImeTextSpan::Thickness::kNone: - return ws::mojom::ImeTextSpanThickness::kNone; - case ui::ImeTextSpan::Thickness::kThin: - return ws::mojom::ImeTextSpanThickness::kThin; - case ui::ImeTextSpan::Thickness::kThick: - return ws::mojom::ImeTextSpanThickness::kThick; - } - - NOTREACHED(); - return ws::mojom::ImeTextSpanThickness::kThin; -} - -// static -bool EnumTraits<ws::mojom::ImeTextSpanThickness, ui::ImeTextSpan::Thickness>:: - FromMojom(ws::mojom::ImeTextSpanThickness input, - ui::ImeTextSpan::Thickness* out) { - switch (input) { - case ws::mojom::ImeTextSpanThickness::kNone: - *out = ui::ImeTextSpan::Thickness::kNone; - return true; - case ws::mojom::ImeTextSpanThickness::kThin: - *out = ui::ImeTextSpan::Thickness::kThin; - return true; - case ws::mojom::ImeTextSpanThickness::kThick: - *out = ui::ImeTextSpan::Thickness::kThick; - return true; - } - - NOTREACHED(); - return false; -} - } // namespace mojo
diff --git a/services/ws/public/mojom/ime/ime_struct_traits.h b/services/ws/public/mojom/ime/ime_struct_traits.h index b0974f2..0d7e959 100644 --- a/services/ws/public/mojom/ime/ime_struct_traits.h +++ b/services/ws/public/mojom/ime/ime_struct_traits.h
@@ -7,11 +7,6 @@ #include "services/ws/public/mojom/ime/ime.mojom-shared.h" #include "ui/base/ime/candidate_window.h" -#include "ui/base/ime/composition_text.h" -#include "ui/base/ime/ime_text_span.h" -#include "ui/base/ime/text_input_client.h" -#include "ui/base/ime/text_input_mode.h" -#include "ui/base/ime/text_input_type.h" namespace mojo { @@ -73,70 +68,6 @@ ui::CandidateWindow::Entry* out); }; -template <> -struct StructTraits<ws::mojom::CompositionTextDataView, ui::CompositionText> { - static base::string16 text(const ui::CompositionText& c) { return c.text; } - static ui::ImeTextSpans ime_text_spans(const ui::CompositionText& c) { - return c.ime_text_spans; - } - static gfx::Range selection(const ui::CompositionText& c) { - return c.selection; - } - static bool Read(ws::mojom::CompositionTextDataView data, - ui::CompositionText* out); -}; - -template <> -struct EnumTraits<ws::mojom::FocusReason, ui::TextInputClient::FocusReason> { - static ws::mojom::FocusReason ToMojom(ui::TextInputClient::FocusReason input); - static bool FromMojom(ws::mojom::FocusReason input, - ui::TextInputClient::FocusReason* out); -}; - -template <> -struct StructTraits<ws::mojom::ImeTextSpanDataView, ui::ImeTextSpan> { - static ui::ImeTextSpan::Type type(const ui::ImeTextSpan& c) { return c.type; } - static uint32_t start_offset(const ui::ImeTextSpan& c) { - return c.start_offset; - } - static uint32_t end_offset(const ui::ImeTextSpan& c) { return c.end_offset; } - static uint32_t underline_color(const ui::ImeTextSpan& c) { - return c.underline_color; - } - static ui::ImeTextSpan::Thickness thickness(const ui::ImeTextSpan& i) { - return i.thickness; - } - static uint32_t background_color(const ui::ImeTextSpan& c) { - return c.background_color; - } - static uint32_t suggestion_highlight_color(const ui::ImeTextSpan& c) { - return c.suggestion_highlight_color; - } - static bool remove_on_finish_composing(const ui::ImeTextSpan& c) { - return c.remove_on_finish_composing; - } - static std::vector<std::string> suggestions(const ui::ImeTextSpan& c) { - return c.suggestions; - } - static bool Read(ws::mojom::ImeTextSpanDataView data, ui::ImeTextSpan* out); -}; - -template <> -struct EnumTraits<ws::mojom::ImeTextSpanType, ui::ImeTextSpan::Type> { - static ws::mojom::ImeTextSpanType ToMojom( - ui::ImeTextSpan::Type ime_text_span_type); - static bool FromMojom(ws::mojom::ImeTextSpanType input, - ui::ImeTextSpan::Type* out); -}; - -template <> -struct EnumTraits<ws::mojom::ImeTextSpanThickness, ui::ImeTextSpan::Thickness> { - static ws::mojom::ImeTextSpanThickness ToMojom( - ui::ImeTextSpan::Thickness thickness); - static bool FromMojom(ws::mojom::ImeTextSpanThickness input, - ui::ImeTextSpan::Thickness* out); -}; - } // namespace mojo #endif // SERVICES_WS_PUBLIC_MOJOM_IME_IME_STRUCT_TRAITS_H_
diff --git a/services/ws/public/mojom/ime/ime_struct_traits_unittest.cc b/services/ws/public/mojom/ime/ime_struct_traits_unittest.cc index f122553..ad28ee1f 100644 --- a/services/ws/public/mojom/ime/ime_struct_traits_unittest.cc +++ b/services/ws/public/mojom/ime/ime_struct_traits_unittest.cc
@@ -12,9 +12,6 @@ #include "mojo/public/cpp/bindings/binding_set.h" #include "services/ws/public/mojom/ime/ime.mojom.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/ime/composition_text.h" -#include "ui/base/ime/ime_text_span.h" -#include "ui/gfx/range/mojo/range_struct_traits.h" namespace ws { @@ -87,24 +84,4 @@ EXPECT_EQ(input.description_body, output.description_body); } -TEST_F(IMEStructTraitsTest, CompositionText) { - ui::CompositionText input; - input.text = base::UTF8ToUTF16("abcdefghij"); - ui::ImeTextSpan ime_text_span_1(0, 2, ui::ImeTextSpan::Thickness::kThin); - ime_text_span_1.underline_color = SK_ColorGRAY; - input.ime_text_spans.push_back(ime_text_span_1); - ui::ImeTextSpan ime_text_span_2(ui::ImeTextSpan::Type::kComposition, 3, 6, - ui::ImeTextSpan::Thickness::kThick, - SK_ColorGREEN); - ime_text_span_2.underline_color = SK_ColorRED; - input.ime_text_spans.push_back(ime_text_span_2); - input.selection = gfx::Range(1, 7); - - ui::CompositionText output; - EXPECT_TRUE(mojom::CompositionText::Deserialize( - mojom::CompositionText::Serialize(&input), &output)); - - EXPECT_EQ(input, output); -} - } // namespace ws
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index e08bf46..15f65a1 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2976,6 +2976,28 @@ ] } ], + "NetUnusedIdleSocketTimeout": [ + { + "platforms": [ + "android", + "windows", + "mac", + "chromeos", + "linux" + ], + "experiments": [ + { + "name": "Enabled_300_seconds_20190314", + "params": { + "unused_idle_socket_timeout_seconds": "300" + }, + "enable_features": [ + "NetUnusedIdleSocketTimeout" + ] + } + ] + } + ], "NetworkQualityEstimator": [ { "platforms": [
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index e9778e6..5364917 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -538,10 +538,10 @@ public_deps = [ "//net", "//services/service_manager/public/cpp", - "//services/ws/public/mojom/ime", "//skia", "//third_party/blink/public/common", "//ui/accessibility:ax_enums_mojo", + "//ui/base/ime/mojo", "//url", ]
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 343118e..e3e5c000 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2239,7 +2239,6 @@ kRTCStatsRelativePacketArrivalDelay = 2827, // The above items are available in M74 branch. - kFlexboxWithOverflowFlexItemIntrinsicSize = 2828, kCSSSelectorHostContextInSnapshotProfile = 2829, kCSSSelectorHostContextInLiveProfile = 2830, kImportMap = 2831,
diff --git a/third_party/blink/public/web/DEPS b/third_party/blink/public/web/DEPS index 6489048..38d6dc41 100644 --- a/third_party/blink/public/web/DEPS +++ b/third_party/blink/public/web/DEPS
@@ -22,10 +22,10 @@ "+services/service_manager/public", # Enforce to use mojom-shared.h in blink/public so that it can compile # inside and outside Blink. - "+services/ws/public/mojom/ime/ime.mojom-shared.h", "+third_party/blink/public/platform", "+third_party/blink/public/web", "+ui/accessibility/ax_enums.mojom-shared.h", + "+ui/base/ime/mojo/ime_types.mojom-shared.h", # Allowed only inside INSIDE_BLINK "+third_party/blink/renderer/core",
diff --git a/third_party/blink/public/web/web_ime_text_span.h b/third_party/blink/public/web/web_ime_text_span.h index 94fa241..9fb26aae 100644 --- a/third_party/blink/public/web/web_ime_text_span.h +++ b/third_party/blink/public/web/web_ime_text_span.h
@@ -34,8 +34,8 @@ #include <string> #include <vector> -#include "services/ws/public/mojom/ime/ime.mojom-shared.h" #include "third_party/skia/include/core/SkColor.h" +#include "ui/base/ime/mojo/ime_types.mojom-shared.h" namespace blink { @@ -58,7 +58,7 @@ : type(Type::kComposition), start_offset(0), end_offset(0), - thickness(ws::mojom::ImeTextSpanThickness::kThin), + thickness(ui::mojom::ImeTextSpanThickness::kThin), background_color(0), suggestion_highlight_color(0), suggestions(std::vector<std::string>()) {} @@ -67,7 +67,7 @@ Type ty, unsigned s, unsigned e, - ws::mojom::ImeTextSpanThickness th, + ui::mojom::ImeTextSpanThickness th, SkColor bc, SkColor shc = 0, const std::vector<std::string>& su = std::vector<std::string>()) @@ -91,7 +91,7 @@ unsigned start_offset; unsigned end_offset; SkColor underline_color = SK_ColorTRANSPARENT; - ws::mojom::ImeTextSpanThickness thickness; + ui::mojom::ImeTextSpanThickness thickness; SkColor background_color; SkColor suggestion_highlight_color; bool remove_on_finish_composing;
diff --git a/third_party/blink/renderer/build/scripts/templates/origin_trials.cc.tmpl b/third_party/blink/renderer/build/scripts/templates/origin_trials.cc.tmpl index 137742a..ae2d194 100644 --- a/third_party/blink/renderer/build/scripts/templates/origin_trials.cc.tmpl +++ b/third_party/blink/renderer/build/scripts/templates/origin_trials.cc.tmpl
@@ -52,11 +52,10 @@ bool origin_trials::{{feature.name}}Enabled(const ExecutionContext* executionContext) { if (RuntimeEnabledFeatures::{{feature.name}}EnabledByRuntimeFlag()) return true; -{%- for depends_on in feature.depends_on %} +{% for depends_on in feature.depends_on %} if (!RuntimeEnabledFeatures::{{depends_on}}Enabled()) return false; -{%- endfor %} - +{% endfor %} const OriginTrialContext* context = OriginTrialContext::From(executionContext); if (!context) return false; if (context->IsFeatureEnabled(OriginTrialFeature::k{{feature.name}}))
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index e1ab9cd..7fe3498 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -102,7 +102,6 @@ public_deps = [ "//services/network/public/cpp:cpp", "//services/service_manager/public/cpp", - "//services/ws/public/mojom/ime", "//skia", "//third_party/angle:translator", "//third_party/blink/public:core_mojo_bindings_blink", @@ -118,6 +117,7 @@ "//third_party/ots", "//third_party/snappy", "//third_party/zlib", + "//ui/base/ime/mojo", "//ui/events:dom_keycode_converter", "//ui/gfx/geometry", "//ui/native_theme",
diff --git a/third_party/blink/renderer/core/DEPS b/third_party/blink/renderer/core/DEPS index 43985918..41da7a6 100644 --- a/third_party/blink/renderer/core/DEPS +++ b/third_party/blink/renderer/core/DEPS
@@ -55,7 +55,6 @@ "+services/resource_coordinator/public/cpp/resource_coordinator_features.h", "+services/resource_coordinator/public/mojom/coordination_unit.mojom-blink.h", "+services/service_manager/public", - "+services/ws/public/mojom/ime/ime.mojom-shared.h", "+skia/public/interfaces/bitmap_skbitmap_struct_traits.h", "+skia/ext/image_operations.h", "+skia/ext/skia_utils_mac.h", @@ -68,6 +67,7 @@ "+third_party/blink/renderer/core", "-third_party/blink/renderer/modules", "+third_party/skia/include", + "+ui/base/ime/mojo/ime_types.mojom-shared.h", "+ui/gfx/geometry", "+ui/gfx/skia_util.h", "-web",
diff --git a/third_party/blink/renderer/core/editing/ime/ime_text_span.cc b/third_party/blink/renderer/core/editing/ime/ime_text_span.cc index 9295aab..8463319c 100644 --- a/third_party/blink/renderer/core/editing/ime/ime_text_span.cc +++ b/third_party/blink/renderer/core/editing/ime/ime_text_span.cc
@@ -13,7 +13,7 @@ unsigned start_offset, unsigned end_offset, const Color& underline_color, - ws::mojom::ImeTextSpanThickness thickness, + ui::mojom::ImeTextSpanThickness thickness, const Color& background_color, const Color& suggestion_highlight_color, bool remove_on_finish_composing,
diff --git a/third_party/blink/renderer/core/editing/ime/ime_text_span.h b/third_party/blink/renderer/core/editing/ime/ime_text_span.h index 8a317d5..6215e623 100644 --- a/third_party/blink/renderer/core/editing/ime/ime_text_span.h +++ b/third_party/blink/renderer/core/editing/ime/ime_text_span.h
@@ -26,12 +26,12 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_IME_IME_TEXT_SPAN_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_IME_IME_TEXT_SPAN_H_ -#include "services/ws/public/mojom/ime/ime.mojom-shared.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "ui/base/ime/mojo/ime_types.mojom-shared.h" namespace blink { @@ -47,7 +47,7 @@ unsigned start_offset, unsigned end_offset, const Color& underline_color, - ws::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanThickness, const Color& background_color, const Color& suggestion_highlight_color = Color::kTransparent, bool remove_on_finish_composing = false, @@ -59,7 +59,7 @@ unsigned StartOffset() const { return start_offset_; } unsigned EndOffset() const { return end_offset_; } const Color& UnderlineColor() const { return underline_color_; } - ws::mojom::ImeTextSpanThickness Thickness() const { return thickness_; } + ui::mojom::ImeTextSpanThickness Thickness() const { return thickness_; } const Color& BackgroundColor() const { return background_color_; } const Color& SuggestionHighlightColor() const { return suggestion_highlight_color_; @@ -74,7 +74,7 @@ unsigned start_offset_; unsigned end_offset_; Color underline_color_; - ws::mojom::ImeTextSpanThickness thickness_; + ui::mojom::ImeTextSpanThickness thickness_; Color background_color_; Color suggestion_highlight_color_; bool remove_on_finish_composing_;
diff --git a/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc b/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc index d8e1764..6118240 100644 --- a/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc +++ b/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc
@@ -12,7 +12,7 @@ ImeTextSpan CreateImeTextSpan(unsigned start_offset, unsigned end_offset) { return ImeTextSpan(ImeTextSpan::Type::kComposition, start_offset, end_offset, Color::kTransparent, - ws::mojom::ImeTextSpanThickness::kNone, + ui::mojom::ImeTextSpanThickness::kNone, Color::kTransparent); }
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc index 930f404..07874c0 100644 --- a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc +++ b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
@@ -912,7 +912,7 @@ if (ime_text_spans.IsEmpty()) { GetDocument().Markers().AddCompositionMarker( CompositionEphemeralRange(), Color::kTransparent, - ws::mojom::ImeTextSpanThickness::kThin, + ui::mojom::ImeTextSpanThickness::kThin, LayoutTheme::GetTheme().PlatformDefaultCompositionBackgroundColor()); return; }
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc index a015b21..5177fdf9 100644 --- a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc +++ b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
@@ -23,7 +23,7 @@ #include "third_party/blink/renderer/core/html/forms/html_input_element.h" #include "third_party/blink/renderer/core/html/forms/html_text_area_element.h" -using ws::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanThickness; namespace blink {
diff --git a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc index 0c410be..926d2c85 100644 --- a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc +++ b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc
@@ -10,7 +10,7 @@ unsigned start_offset, unsigned end_offset, Color underline_color, - ws::mojom::ImeTextSpanThickness thickness, + ui::mojom::ImeTextSpanThickness thickness, Color background_color) : StyleableMarker(start_offset, end_offset,
diff --git a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h index 1f14b3a7..4c559c2 100644 --- a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h +++ b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h
@@ -17,7 +17,7 @@ ActiveSuggestionMarker(unsigned start_offset, unsigned end_offset, Color underline_color, - ws::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanThickness, Color background_color); // DocumentMarker implementations
diff --git a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc index fa085a4..3278806 100644 --- a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc +++ b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc
@@ -17,7 +17,7 @@ DocumentMarker* CreateMarker(unsigned start_offset, unsigned end_offset) { return MakeGarbageCollected<ActiveSuggestionMarker>( start_offset, end_offset, Color::kTransparent, - ws::mojom::ImeTextSpanThickness::kThin, Color::kBlack); + ui::mojom::ImeTextSpanThickness::kThin, Color::kBlack); } Persistent<ActiveSuggestionMarkerListImpl> marker_list_;
diff --git a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc index d4921c61..1e3872b 100644 --- a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc +++ b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc
@@ -6,7 +6,7 @@ #include "testing/gtest/include/gtest/gtest.h" -using ws::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanThickness; namespace blink {
diff --git a/third_party/blink/renderer/core/editing/markers/composition_marker.cc b/third_party/blink/renderer/core/editing/markers/composition_marker.cc index b0c2616..954fa2a 100644 --- a/third_party/blink/renderer/core/editing/markers/composition_marker.cc +++ b/third_party/blink/renderer/core/editing/markers/composition_marker.cc
@@ -9,7 +9,7 @@ CompositionMarker::CompositionMarker(unsigned start_offset, unsigned end_offset, Color underline_color, - ws::mojom::ImeTextSpanThickness thickness, + ui::mojom::ImeTextSpanThickness thickness, Color background_color) : StyleableMarker(start_offset, end_offset,
diff --git a/third_party/blink/renderer/core/editing/markers/composition_marker.h b/third_party/blink/renderer/core/editing/markers/composition_marker.h index 3db0263..ba5af65c 100644 --- a/third_party/blink/renderer/core/editing/markers/composition_marker.h +++ b/third_party/blink/renderer/core/editing/markers/composition_marker.h
@@ -19,7 +19,7 @@ CompositionMarker(unsigned start_offset, unsigned end_offset, Color underline_color, - ws::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanThickness, Color background_color); // DocumentMarker implementations
diff --git a/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc b/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc index fc7fd27..d1d3b40 100644 --- a/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc +++ b/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc
@@ -18,7 +18,7 @@ DocumentMarker* CreateMarker(unsigned start_offset, unsigned end_offset) { return MakeGarbageCollected<CompositionMarker>( start_offset, end_offset, Color::kTransparent, - ws::mojom::ImeTextSpanThickness::kThin, Color::kBlack); + ui::mojom::ImeTextSpanThickness::kThin, Color::kBlack); } Persistent<CompositionMarkerListImpl> marker_list_;
diff --git a/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc b/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc index 7414cfa6..5bf0d80 100644 --- a/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc +++ b/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc
@@ -6,7 +6,7 @@ #include "testing/gtest/include/gtest/gtest.h" -using ws::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanThickness; namespace blink {
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc index f7dc533..99d9bea 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc +++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc
@@ -182,7 +182,7 @@ void DocumentMarkerController::AddCompositionMarker( const EphemeralRange& range, Color underline_color, - ws::mojom::ImeTextSpanThickness thickness, + ui::mojom::ImeTextSpanThickness thickness, Color background_color) { DCHECK(!document_->NeedsLayoutTreeUpdate()); AddMarkerInternal(range, [underline_color, thickness, background_color]( @@ -195,7 +195,7 @@ void DocumentMarkerController::AddActiveSuggestionMarker( const EphemeralRange& range, Color underline_color, - ws::mojom::ImeTextSpanThickness thickness, + ui::mojom::ImeTextSpanThickness thickness, Color background_color) { DCHECK(!document_->NeedsLayoutTreeUpdate()); AddMarkerInternal(range, [underline_color, thickness, background_color](
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller.h b/third_party/blink/renderer/core/editing/markers/document_marker_controller.h index b16ee42..e0a51ae 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker_controller.h +++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller.h
@@ -66,11 +66,11 @@ void AddTextMatchMarker(const EphemeralRange&, TextMatchMarker::MatchStatus); void AddCompositionMarker(const EphemeralRange&, Color underline_color, - ws::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanThickness, Color background_color); void AddActiveSuggestionMarker(const EphemeralRange&, Color underline_color, - ws::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanThickness, Color background_color); void AddSuggestionMarker(const EphemeralRange&, const SuggestionMarkerProperties&);
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc b/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc index 498146a..871086e 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc +++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc
@@ -240,10 +240,10 @@ Node* text = GetDocument().body()->firstChild()->firstChild(); MarkerController().AddCompositionMarker( EphemeralRange(Position(text, 0), Position(text, 1)), Color::kTransparent, - ws::mojom::ImeTextSpanThickness::kThin, Color::kBlack); + ui::mojom::ImeTextSpanThickness::kThin, Color::kBlack); MarkerController().AddCompositionMarker( EphemeralRange(Position(text, 1), Position(text, 3)), Color::kTransparent, - ws::mojom::ImeTextSpanThickness::kThick, Color::kBlack); + ui::mojom::ImeTextSpanThickness::kThick, Color::kBlack); EXPECT_EQ(2u, MarkerController().Markers().size()); }
diff --git a/third_party/blink/renderer/core/editing/markers/styleable_marker.cc b/third_party/blink/renderer/core/editing/markers/styleable_marker.cc index 15826e6e..51691b29 100644 --- a/third_party/blink/renderer/core/editing/markers/styleable_marker.cc +++ b/third_party/blink/renderer/core/editing/markers/styleable_marker.cc
@@ -4,7 +4,7 @@ #include "third_party/blink/renderer/core/editing/markers/styleable_marker.h" -using ws::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanThickness; namespace blink {
diff --git a/third_party/blink/renderer/core/editing/markers/styleable_marker.h b/third_party/blink/renderer/core/editing/markers/styleable_marker.h index 0074660..d58e82fd 100644 --- a/third_party/blink/renderer/core/editing/markers/styleable_marker.h +++ b/third_party/blink/renderer/core/editing/markers/styleable_marker.h
@@ -5,8 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_MARKERS_STYLEABLE_MARKER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_MARKERS_STYLEABLE_MARKER_H_ -#include "services/ws/public/mojom/ime/ime.mojom-shared.h" #include "third_party/blink/renderer/core/editing/markers/document_marker.h" +#include "ui/base/ime/mojo/ime_types.mojom-shared.h" namespace blink { @@ -17,7 +17,7 @@ StyleableMarker(unsigned start_offset, unsigned end_offset, Color underline_color, - ws::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanThickness, Color background_color); // StyleableMarker-specific @@ -31,7 +31,7 @@ private: const Color underline_color_; const Color background_color_; - const ws::mojom::ImeTextSpanThickness thickness_; + const ui::mojom::ImeTextSpanThickness thickness_; DISALLOW_COPY_AND_ASSIGN(StyleableMarker); };
diff --git a/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc b/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc index 414c696..4e446603 100644 --- a/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc +++ b/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc
@@ -65,7 +65,7 @@ SuggestionMarkerProperties::Builder& SuggestionMarkerProperties::Builder::SetThickness( - ws::mojom::ImeTextSpanThickness thickness) { + ui::mojom::ImeTextSpanThickness thickness) { data_.thickness_ = thickness; return *this; }
diff --git a/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h b/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h index 3fe4bc29..a69b47a 100644 --- a/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h +++ b/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/editing/markers/styleable_marker.h" #include "third_party/blink/renderer/core/editing/markers/suggestion_marker.h" -using ws::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanThickness; namespace blink {
diff --git a/third_party/blink/renderer/core/editing/markers/suggestion_marker_test.cc b/third_party/blink/renderer/core/editing/markers/suggestion_marker_test.cc index f5e81d7a..6aad718 100644 --- a/third_party/blink/renderer/core/editing/markers/suggestion_marker_test.cc +++ b/third_party/blink/renderer/core/editing/markers/suggestion_marker_test.cc
@@ -32,7 +32,7 @@ .SetSuggestions(suggestions) .SetHighlightColor(Color::kTransparent) .SetUnderlineColor(Color::kDarkGray) - .SetThickness(ws::mojom::ImeTextSpanThickness::kThin) + .SetThickness(ui::mojom::ImeTextSpanThickness::kThin) .SetBackgroundColor(Color::kGray) .Build()); EXPECT_EQ(suggestions, marker->Suggestions()); @@ -47,7 +47,7 @@ SuggestionMarkerProperties::Builder() .SetType(SuggestionMarker::SuggestionType::kMisspelling) .SetHighlightColor(Color::kBlack) - .SetThickness(ws::mojom::ImeTextSpanThickness::kThick) + .SetThickness(ui::mojom::ImeTextSpanThickness::kThick) .Build()); EXPECT_TRUE(marker2->HasThicknessThick()); EXPECT_TRUE(marker2->IsMisspelling());
diff --git a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc index be988931..38f71c8 100644 --- a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc +++ b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc
@@ -424,7 +424,7 @@ GetFrame().Selection().SetCaretVisible(false); GetDocument().Markers().AddActiveSuggestionMarker( active_suggestion_range, SK_ColorTRANSPARENT, - ws::mojom::ImeTextSpanThickness::kNone, + ui::mojom::ImeTextSpanThickness::kNone, LayoutTheme::GetTheme().PlatformActiveSpellingMarkerHighlightColor()); Vector<String> suggestions; @@ -489,7 +489,7 @@ Position(text_node, span_union_end)); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, SK_ColorTRANSPARENT, ws::mojom::ImeTextSpanThickness::kThin, + marker_range, SK_ColorTRANSPARENT, ui::mojom::ImeTextSpanThickness::kThin, suggestion_infos_with_node_and_highlight_color.highlight_color); is_suggestion_menu_open_ = true;
diff --git a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc index a86bfbe..aaa175fa 100644 --- a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc +++ b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/editing/testing/editing_test_base.h" #include "third_party/blink/renderer/core/editing/visible_selection.h" -using ws::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanThickness; namespace blink {
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc index 90b689d6..e22f352 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -1587,7 +1587,7 @@ web_view->SetInitialFocus(false); WebVector<WebImeTextSpan> ime_text_spans(static_cast<size_t>(1)); ime_text_spans[0] = WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4, - ws::mojom::ImeTextSpanThickness::kThin, 0); + ui::mojom::ImeTextSpanThickness::kThin, 0); WebLocalFrameImpl* frame = web_view->MainFrameImpl(); WebInputMethodController* active_input_method_controller = frame->GetInputMethodController(); @@ -1614,7 +1614,7 @@ web_view->SetInitialFocus(false); WebVector<WebImeTextSpan> ime_text_spans(static_cast<size_t>(1)); ime_text_spans[0] = WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4, - ws::mojom::ImeTextSpanThickness::kThin, 0); + ui::mojom::ImeTextSpanThickness::kThin, 0); WebLocalFrameImpl* frame = web_view->MainFrameImpl(); WebInputMethodController* active_input_method_controller = frame->FrameWidget()->GetActiveWebInputMethodController(); @@ -1658,7 +1658,7 @@ web_view->SetInitialFocus(false); WebVector<WebImeTextSpan> ime_text_spans(static_cast<size_t>(1)); ime_text_spans[0] = WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4, - ws::mojom::ImeTextSpanThickness::kThin, 0); + ui::mojom::ImeTextSpanThickness::kThin, 0); WebLocalFrameImpl* frame = web_view->MainFrameImpl(); frame->SetEditableSelectionOffsets(1, 1); WebDocument document = web_view->MainFrameImpl()->GetDocument();
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 7bb3906..136a804a 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -386,11 +386,10 @@ if (!Client()) return; - // stopAllLoaders() needs to be called after detachChildren(), because + // Detach() needs to be called after detachChildren(), because // detachChildren() will trigger the unload event handlers of any child // frames, and those event handlers might start a new subresource load in this - // frame. - loader_.StopAllLoaders(); + // frame which should be stopped by Detach. loader_.Detach(); GetDocument()->Shutdown();
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.cc b/third_party/blink/renderer/core/layout/layout_flexible_box.cc index 44e5bda..11827668 100644 --- a/third_party/blink/renderer/core/layout/layout_flexible_box.cc +++ b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
@@ -94,31 +94,6 @@ max_preferred_logical_width += margin; if (!IsColumnFlow()) { max_logical_width += max_preferred_logical_width; - - EOverflow overflow = StyleRef().IsHorizontalWritingMode() - ? child->StyleRef().OverflowX() - : child->StyleRef().OverflowY(); - const Length& main_axis_length = IsHorizontalFlow() - ? child->StyleRef().Width() - : child->StyleRef().Height(); - // This code experimentally implements the proposal in - // https://github.com/w3c/csswg-drafts/issues/1865 - // to see if it is web-compatible. - if (overflow != EOverflow::kVisible && !main_axis_length.IsFixed()) { - LayoutUnit border_and_padding = - StyleRef().IsHorizontalWritingMode() - ? child->BorderAndPaddingWidth() + - child->VerticalScrollbarWidth() - : child->BorderAndPaddingHeight() + - child->HorizontalScrollbarHeight(); - if (min_preferred_logical_width != margin + border_and_padding) { - min_preferred_logical_width = margin + border_and_padding; - UseCounter::Count( - GetDocument(), - WebFeature::kFlexboxWithOverflowFlexItemIntrinsicSize); - } - } - if (IsMultiline()) { // For multiline, the min preferred width is if you put a break between // each item.
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.h b/third_party/blink/renderer/core/layout/layout_flexible_box.h index e8565c9..3df70c5 100644 --- a/third_party/blink/renderer/core/layout/layout_flexible_box.h +++ b/third_party/blink/renderer/core/layout/layout_flexible_box.h
@@ -162,6 +162,7 @@ const Length& flex_basis) const; bool NeedToStretchChildLogicalHeight(const LayoutBox& child) const; bool ChildHasIntrinsicMainAxisSize(const LayoutBox& child) const; + EOverflow MainAxisOverflowForChild(const LayoutBox& child) const; EOverflow CrossAxisOverflowForChild(const LayoutBox& child) const; void CacheChildMainSize(const LayoutBox& child); bool CanAvoidLayoutForNGChild(const LayoutBox& child) const;
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 7e97ab7..34ba3ab 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -191,11 +191,9 @@ FrameLoader::FrameLoader(LocalFrame* frame) : frame_(frame), progress_tracker_(ProgressTracker::Create(frame)), - in_stop_all_loaders_(false), in_restore_scroll_(false), forced_sandbox_flags_(kSandboxNone), dispatching_did_clear_window_object_in_main_world_(false), - protect_provisional_loader_(false), detached_(false), virtual_time_pauser_( frame_->GetFrameScheduler()->CreateWebScopedVirtualTimePauser( @@ -317,10 +315,6 @@ void FrameLoader::DispatchUnloadEvent() { FrameNavigationDisabler navigation_disabler(*frame_); - - // If the frame is unloading, the provisional loader should no longer be - // protected. It will be detached soon. - protect_provisional_loader_ = false; SaveScrollState(); Document* document = frame_->GetDocument(); @@ -811,9 +805,6 @@ if (HTMLFrameOwnerElement* element = frame_->DeprecatedLocalOwner()) element->CancelPendingLazyLoad(); - if (in_stop_all_loaders_) - return; - FrameLoadRequest request(passed_request); ResourceRequest& resource_request = request.GetResourceRequest(); const KURL& url = resource_request.Url(); @@ -977,7 +968,7 @@ DCHECK(frame_->GetDocument()); DCHECK(Client()->HasWebView()); - if (in_stop_all_loaders_ || !frame_->IsNavigationAllowed() || + if (!frame_->IsNavigationAllowed() || frame_->GetDocument()->PageDismissalEventBeingDispatched() != Document::kNoDismissal) { // Any of the checks above should not be necessary. @@ -1058,12 +1049,9 @@ DCHECK(!IsReloadLoadType(frame_load_type)); DCHECK(frame_->GetDocument()); - if (in_stop_all_loaders_) - return mojom::CommitResult::Aborted; - bool history_navigation = IsBackForwardLoadType(frame_load_type); - if (!frame_->IsNavigationAllowed() && history_navigation) + if (!frame_->IsNavigationAllowed()) return mojom::CommitResult::Aborted; if (!history_navigation) { @@ -1123,16 +1111,15 @@ } void FrameLoader::StopAllLoaders() { - if (frame_->GetDocument()->PageDismissalEventBeingDispatched() != - Document::kNoDismissal) + if (!frame_->IsNavigationAllowed() || + frame_->GetDocument()->PageDismissalEventBeingDispatched() != + Document::kNoDismissal) { return; + } - // If this method is called from within this method, infinite recursion can - // occur (3442218). Avoid this. - if (in_stop_all_loaders_) - return; - - base::AutoReset<bool> in_stop_all_loaders(&in_stop_all_loaders_, true); + // This method could be called from within this method, e.g. through plugin + // detach. Avoid infinite recursion by disabling navigations. + FrameNavigationDisabler navigation_disabler(*frame_); for (Frame* child = frame_->Tree().FirstChild(); child; child = child->Tree().NextSibling()) { @@ -1143,8 +1130,7 @@ frame_->GetDocument()->CancelParsing(); if (document_loader_) document_loader_->StopLoading(); - if (!protect_provisional_loader_) - DetachDocumentLoader(provisional_document_loader_); + DetachDocumentLoader(provisional_document_loader_); frame_->GetNavigationScheduler().Cancel(); DidFinishNavigation(); @@ -1198,23 +1184,24 @@ frame_->DetachChildren(); // The previous calls to dispatchUnloadEvent() and detachChildren() can // execute arbitrary script via things like unload events. If the executed - // script intiates a new load or causes the current frame to be detached, we - // need to abandon the current load. - if (pdl != provisional_document_loader_) + // script causes the current frame to be detached, we need to abandon the + // current load. + if (!frame_->Client()) return false; + // FrameNavigationDisabler should prevent another load from starting. + DCHECK_EQ(provisional_document_loader_, pdl); // detachFromFrame() will abort XHRs that haven't completed, which can trigger // event listeners for 'abort'. These event listeners might call // window.stop(), which will in turn detach the provisional document loader. // At this point, the provisional document loader should not detach, because - // then the FrameLoader would not have any attached DocumentLoaders. - if (document_loader_) { - base::AutoReset<bool> in_detach_document_loader( - &protect_provisional_loader_, true); + // then the FrameLoader would not have any attached DocumentLoaders. This is + // guaranteed by FrameNavigationDisabler above. + if (document_loader_) DetachDocumentLoader(document_loader_, true); - } // 'abort' listeners can also detach the frame. if (!frame_->Client()) return false; + // FrameNavigationDisabler should prevent another load from starting. DCHECK_EQ(provisional_document_loader_, pdl); // No more events will be dispatched so detach the Document. @@ -1382,8 +1369,11 @@ } void FrameLoader::Detach() { + frame_->GetDocument()->CancelParsing(); DetachDocumentLoader(document_loader_); DetachDocumentLoader(provisional_document_loader_); + frame_->GetNavigationScheduler().Cancel(); + DidFinishNavigation(); if (progress_tracker_) { progress_tracker_->Dispose();
diff --git a/third_party/blink/renderer/core/loader/frame_loader.h b/third_party/blink/renderer/core/loader/frame_loader.h index fbcc2aa..352af2a 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.h +++ b/third_party/blink/renderer/core/loader/frame_loader.h
@@ -294,13 +294,11 @@ Member<DocumentLoader> document_loader_; Member<DocumentLoader> provisional_document_loader_; - bool in_stop_all_loaders_; bool in_restore_scroll_; SandboxFlags forced_sandbox_flags_; bool dispatching_did_clear_window_object_in_main_world_; - bool protect_provisional_loader_; bool detached_; WebScopedVirtualTimePauser virtual_time_pauser_;
diff --git a/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc b/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc index f6a0af64..6773e44 100644 --- a/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc +++ b/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc
@@ -75,9 +75,12 @@ if (RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled()) { // We should consider using the text node as the tracking node, instead of // the line layout item. - PaintTimingDetector::NotifyTextPaint( - ellipsis_box_.GetLineLayoutItem().GetNode(), - paint_info.context.GetPaintController().CurrentPaintChunkProperties()); + Node* node = ellipsis_box_.GetLineLayoutItem().GetNode(); + if (node) { + PaintTimingDetector::NotifyTextPaint( + *node->GetLayoutObject(), paint_info.context.GetPaintController() + .CurrentPaintChunkProperties()); + } } }
diff --git a/third_party/blink/renderer/core/paint/paint_timing_detector.cc b/third_party/blink/renderer/core/paint/paint_timing_detector.cc index dd34552f..874c6215 100644 --- a/third_party/blink/renderer/core/paint/paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/paint_timing_detector.cc
@@ -62,18 +62,6 @@ // static void PaintTimingDetector::NotifyImagePaint( - const Node* node, - const PropertyTreeState& current_paint_chunk_properties) { - if (!node) - return; - LayoutObject* object = node->GetLayoutObject(); - if (!object) - return; - NotifyImagePaint(*object, current_paint_chunk_properties); -} - -// static -void PaintTimingDetector::NotifyImagePaint( const LayoutObject& object, const PropertyTreeState& current_paint_chunk_properties) { LocalFrameView* frame_view = object.GetFrameView(); @@ -86,18 +74,6 @@ // static void PaintTimingDetector::NotifyTextPaint( - const Node* node, - const PropertyTreeState& current_paint_chunk_properties) { - if (!node) - return; - LayoutObject* object = node->GetLayoutObject(); - if (!object) - return; - NotifyTextPaint(*object, current_paint_chunk_properties); -} - -// static -void PaintTimingDetector::NotifyTextPaint( const LayoutObject& object, const PropertyTreeState& current_paint_chunk_properties) { LocalFrameView* frame_view = object.GetFrameView();
diff --git a/third_party/blink/renderer/core/paint/paint_timing_detector.h b/third_party/blink/renderer/core/paint/paint_timing_detector.h index f312b4ee..035707c 100644 --- a/third_party/blink/renderer/core/paint/paint_timing_detector.h +++ b/third_party/blink/renderer/core/paint/paint_timing_detector.h
@@ -40,13 +40,9 @@ Image* image, const PropertyTreeState& current_paint_chunk_properties); static void NotifyImagePaint( - const Node* node, - const PropertyTreeState& current_paint_chunk_properties); - static void NotifyImagePaint( const LayoutObject& object, const PropertyTreeState& current_paint_chunk_properties); - static void NotifyTextPaint(const Node* node, const PropertyTreeState&); static void NotifyTextPaint(const LayoutObject& object, const PropertyTreeState&); void NotifyNodeRemoved(const LayoutObject& object);
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index 91eb76d..8304844 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -180,7 +180,7 @@ namespace blink { -using ws::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanThickness; namespace {
diff --git a/third_party/blink/renderer/devtools/PRESUBMIT.py b/third_party/blink/renderer/devtools/PRESUBMIT.py index 5ecc368..5fadb7a 100644 --- a/third_party/blink/renderer/devtools/PRESUBMIT.py +++ b/third_party/blink/renderer/devtools/PRESUBMIT.py
@@ -94,6 +94,18 @@ ] +def _CheckDevtoolsLocalization(input_api, output_api): # pylint: disable=invalid-name + affected_front_end_files = _getAffectedFrontEndFiles(input_api) + if len(affected_front_end_files) == 0: + return [] + else: + affected_front_end_files = [ + input_api.os_path.join(input_api.PresubmitLocalPath(), file_path) for file_path in affected_front_end_files + ] + script_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts", "check_localizability.js") + return _checkWithNodeScript(input_api, output_api, script_path, affected_front_end_files) + + def _CheckDevtoolsStyle(input_api, output_api): affected_front_end_files = _getAffectedFrontEndFiles(input_api) if len(affected_front_end_files) > 0: @@ -190,6 +202,7 @@ results = [] results.extend(_CheckBuildGN(input_api, output_api)) results.extend(_CheckFormat(input_api, output_api)) + # results.extend(_CheckDevtoolsLocalization(input_api, output_api)) results.extend(_CheckDevtoolsStyle(input_api, output_api)) results.extend(_CompileDevtoolsFrontend(input_api, output_api)) results.extend(_CheckConvertSVGToPNGHashes(input_api, output_api)) @@ -224,7 +237,7 @@ return [input_api.os_path.relpath(file_name, devtools_root) for file_name in affected_js_files] -def _checkWithNodeScript(input_api, output_api, script_path): +def _checkWithNodeScript(input_api, output_api, script_path, files=None): # pylint: disable=invalid-name original_sys_path = sys.path try: sys.path = sys.path + [input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts")] @@ -234,8 +247,11 @@ node_path = local_node.node_path() + if files is None: + files = [] + process = input_api.subprocess.Popen( - [node_path, script_path], stdout=input_api.subprocess.PIPE, stderr=input_api.subprocess.STDOUT) + [node_path, script_path] + files, stdout=input_api.subprocess.PIPE, stderr=input_api.subprocess.STDOUT) out, _ = process.communicate() if process.returncode != 0:
diff --git a/third_party/blink/renderer/devtools/package.json b/third_party/blink/renderer/devtools/package.json index 5fe0fdb..4a01845 100644 --- a/third_party/blink/renderer/devtools/package.json +++ b/third_party/blink/renderer/devtools/package.json
@@ -14,6 +14,7 @@ "extract": "node scripts/extract_module/extract_module.js", "check-gn": "node scripts/check_gn.js", "check-json": "node scripts/json_validator/validate_module_json.js", + "check-loc": "node scripts/check_localizability.js -a", "generate-jsconfig": "node scripts/generate_jsconfig.js" }, "repository": {
diff --git a/third_party/blink/renderer/devtools/scripts/check_localizability.js b/third_party/blink/renderer/devtools/scripts/check_localizability.js new file mode 100644 index 0000000..3cbe973b --- /dev/null +++ b/third_party/blink/renderer/devtools/scripts/check_localizability.js
@@ -0,0 +1,313 @@ +// 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. +'use strict'; + +// Description: Scans for localizability violations in the DevTools front-end. +// Audits all Common.UIString(), UI.formatLocalized(), and ls`` calls and +// checks for misuses of concatenation and conditionals. It also looks for +// specific arguments to functions that are expected to be a localized string. +// Since the check scans for common error patterns, it might misidentify something. +// In this case, add it to the excluded errors at the top of the script. + +const path = require('path'); + +// Use modules in third_party/node/node_modules +const THIRD_PARTY_PATH = path.resolve(__dirname, '..', '..', '..', '..'); +const REPO_NODE_MODULES_PATH = path.resolve(THIRD_PARTY_PATH, 'node', 'node_modules'); +const escodegen = require(path.resolve(REPO_NODE_MODULES_PATH, 'escodegen')); +const esprima = require(path.resolve(REPO_NODE_MODULES_PATH, 'esprima')); + +const fs = require('fs'); +const {promisify} = require('util'); +const readDirAsync = promisify(fs.readdir); +const readFileAsync = promisify(fs.readFile); +const statAsync = promisify(fs.stat); + +const excludeFiles = ['lighthouse-dt-bundle.js', 'Tests.js']; +const excludeDirs = ['_test_runner', 'Images', 'node_modules']; +// Exclude known errors +const excludeErrors = [ + 'Common.UIString(view.title())', 'Common.UIString(setting.title() || \'\')', 'Common.UIString(option.text)', + 'Common.UIString(experiment.title)', 'Common.UIString(phase.message)', + 'Common.UIString(Help.latestReleaseNote().header)', 'Common.UIString(conditions.title)', + 'Common.UIString(extension.title())', 'Common.UIString(this._currentValueLabel, value)' +]; + +const esprimaTypes = { + BI_EXPR: 'BinaryExpression', + CALL_EXPR: 'CallExpression', + COND_EXPR: 'ConditionalExpression', + IDENTIFIER: 'Identifier', + MEMBER_EXPR: 'MemberExpression', + TAGGED_TEMP_EXPR: 'TaggedTemplateExpression', + TEMP_LITERAL: 'TemplateLiteral' +}; + +const usage = `Usage: node ${path.basename(process.argv[0])} [-a | <.js file path>*] + +-a: If present, check all devtools frontend .js files +<.js file path>*: List of .js files with absolute paths separated by a space +`; + +async function main() { + if (process.argv.length < 3 || process.argv[2] === '--help') { + console.log(usage); + process.exit(0); + } + + const errors = []; + + try { + let filePaths = []; + if (process.argv[2] === '-a') { + const frontendPath = path.resolve(__dirname, '..', 'front_end'); + await getFilesFromDirectory(frontendPath, filePaths); + } else { + filePaths = process.argv.slice(2); + } + + const promises = []; + for (const filePath of filePaths) + promises.push(auditFileForLocalizability(filePath, errors)); + + await Promise.all(promises); + } catch (err) { + console.log(err); + process.exit(1); + } + + if (errors.length > 0) { + console.log(`DevTools localization checker detected errors!\n${errors.join('\n')}`); + process.exit(1); + } + console.log('DevTools localization checker passed'); +} + +main(); + +function verifyIdentifier(node, name) { + return node !== undefined && node.type === esprimaTypes.IDENTIFIER && node.name === name; +} + +/** + * Verify callee of objectName.propertyName(), e.g. Common.UIString(). + */ +function verifyCallExpressionCallee(callee, objectName, propertyName) { + return callee !== undefined && callee.type === esprimaTypes.MEMBER_EXPR && callee.computed === false && + verifyIdentifier(callee.object, objectName) && verifyIdentifier(callee.property, propertyName); +} + +function isNodeCallOnObject(node, objectName, propertyName) { + return node !== undefined && node.type === esprimaTypes.CALL_EXPR && + verifyCallExpressionCallee(node.callee, objectName, propertyName); +} + +function isNodeCommonUIStringCall(node) { + return isNodeCallOnObject(node, 'Common', 'UIString'); +} + +function isNodeUIformatLocalized(node) { + return isNodeCallOnObject(node, 'UI', 'formatLocalized'); +} + +function isNodelsTaggedTemplateExpression(node) { + return node !== undefined && node.type === esprimaTypes.TAGGED_TEMP_EXPR && verifyIdentifier(node.tag, 'ls') && + node.quasi !== undefined && node.quasi.type !== undefined && node.quasi.type === esprimaTypes.TEMP_LITERAL; +} + +function includesConditionalExpression(listOfElements) { + return listOfElements.filter(ele => ele !== undefined && ele.type === esprimaTypes.COND_EXPR).length > 0; +} + +function getLocalizationCase(node) { + if (isNodeCommonUIStringCall(node)) + return 'Common.UIString'; + else if (isNodelsTaggedTemplateExpression(node)) + return 'Tagged Template'; + else if (isNodeUIformatLocalized(node)) + return 'UI.formatLocalized'; + else + return null; +} + +function isLocalizationCall(node) { + return isNodeCommonUIStringCall(node) || isNodelsTaggedTemplateExpression(node) || isNodeUIformatLocalized(node); +} + +function addError(error, errors) { + if (!errors.includes(error)) + errors.push(error); +} + +function getLocation(node) { + if (node !== undefined && node.loc !== undefined && node.loc.start !== undefined && node.loc.end !== undefined && + node.loc.start.line !== undefined && node.loc.end.line !== undefined) { + const startLine = node.loc.start.line; + const endLine = node.loc.end.line; + if (startLine === endLine) + return ` Line ${startLine}`; + else + return ` Line ${node.loc.start.line}-${node.loc.end.line}`; + } + return ''; +} + +/** + * Recursively check if there is concatenation to localization call. + */ +function checkConcatenation(node, filePath, errors) { + if (node !== undefined && node.type === esprimaTypes.BI_EXPR && node.operator === '+') { + const code = escodegen.generate(node); + if (isLocalizationCall(node.left) || isLocalizationCall(node.right)) { + addError( + `${filePath}${getLocation(node)}: string concatenation should be changed to variable substitution with ls: ${ + code}`, + errors); + } else { + [node.left, node.right].forEach(node => checkConcatenation(node, filePath, errors)); + } + } +} + +/** + * Verify if callee is functionName() or object.functionName(). + */ +function verifyFunctionCallee(callee, functionName) { + return callee !== undefined && + ((callee.type === esprimaTypes.IDENTIFIER && callee.name === functionName) || + (callee.type === esprimaTypes.MEMBER_EXPR && verifyIdentifier(callee.property, functionName))); +} + +/** + * Check if an argument of a function is localized. + */ +function checkFunctionArgument(functionName, argumentIndex, node, filePath, errors) { + if (node !== undefined && node.type === esprimaTypes.CALL_EXPR && verifyFunctionCallee(node.callee, functionName) && + node.arguments !== undefined && node.arguments.length > argumentIndex) { + const arg = node.arguments[argumentIndex]; + if (!isLocalizationCall(arg)) { + let order = ''; + switch (argumentIndex) { + case 0: + order = 'first'; + break; + case 1: + order = 'second'; + break; + case 2: + order = 'third'; + break; + default: + order = `${argumentIndex + 1}th`; + } + addError( + `${filePath}${getLocation(node)}: ${order} argument to ${functionName}() should be localized: ${ + escodegen.generate(node)}`, + errors); + } + } +} + +/** + * Check esprima node object that represents the AST of code + * to see if there is any localization error. + */ +function analyzeNode(node, filePath, errors) { + if (node === undefined || node === null) + return; + + if (node instanceof Array) { + for (const child of node) + analyzeNode(child, filePath, errors); + + return; + } + + const keys = Object.keys(node); + const objKeys = keys.filter(key => { + return typeof node[key] === 'object' && key !== 'loc'; + }); + if (objKeys.length === 0) { + // base case: all values are non-objects -> node is a leaf + return; + } + + const locCase = getLocalizationCase(node); + const code = escodegen.generate(node); + switch (locCase) { + case 'Common.UIString': + case 'UI.formatLocalized': + const firstArgType = node.arguments[0].type; + if (firstArgType !== 'Literal' && firstArgType !== 'TemplateLiteral' && firstArgType !== 'Identifier' && + !excludeErrors.includes(code)) { + addError(`${filePath}${getLocation(node)}: first argument to call should be a string: ${code}`, errors); + } + if (includesConditionalExpression(node.arguments.slice(1))) { + addError( + `${filePath}${getLocation(node)}: conditional(s) found in ${ + code}. Please extract conditional(s) out of the localization call.`, + errors); + } + break; + case 'Tagged Template': + if (includesConditionalExpression(node.quasi.expressions)) { + addError( + `${filePath}${getLocation(node)}: conditional(s) found in ${ + code}. Please extract conditional(s) out of the localization call.`, + errors); + } + break; + default: + // String concatenation to localization call(s) should be changed + checkConcatenation(node, filePath, errors); + // 3rd argument to createInput() should be localized + checkFunctionArgument('createInput', 2, node, filePath, errors); + break; + } + + for (const key of objKeys) { + // recursively parse all the child nodes + analyzeNode(node[key], filePath, errors); + } +} + +function getRelativeFilePathFromSrc(fullFilePath) { + return path.relative(path.resolve(THIRD_PARTY_PATH, '..'), fullFilePath); +} + +async function auditFileForLocalizability(filePath, errors) { + const fileContent = await readFileAsync(filePath); + const ast = esprima.parse(fileContent.toString(), {loc: true}); + + const relativeFilePath = getRelativeFilePathFromSrc(filePath); + for (const node of ast.body) + analyzeNode(node, relativeFilePath, errors); +} + +function shouldParseDirectory(directoryName) { + return !excludeDirs.reduce((result, dir) => result || directoryName.indexOf(dir) !== -1, false); +} + +function shouldParseFile(filePath) { + return (path.extname(filePath) === '.js' && !excludeFiles.includes(path.basename(filePath))); +} + +async function getFilesFromItem(itemPath, filePaths) { + const stat = await statAsync(itemPath); + if (stat.isDirectory() && shouldParseDirectory(itemPath)) + return await getFilesFromDirectory(itemPath, filePaths); + + if (shouldParseFile(itemPath)) + filePaths.push(itemPath); +} + +async function getFilesFromDirectory(directoryPath, filePaths) { + const itemNames = await readDirAsync(directoryPath); + const promises = []; + for (const itemName of itemNames) { + const itemPath = path.resolve(directoryPath, itemName); + promises.push(getFilesFromItem(itemPath, filePaths)); + } + await Promise.all(promises); +}
diff --git a/third_party/blink/renderer/modules/xr/xr_grip_space.cc b/third_party/blink/renderer/modules/xr/xr_grip_space.cc index 32e47c78..146a388 100644 --- a/third_party/blink/renderer/modules/xr/xr_grip_space.cc +++ b/third_party/blink/renderer/modules/xr/xr_grip_space.cc
@@ -38,7 +38,7 @@ // Account for any changes made to the reference space's origin offset so // that things like teleportation works. grip_pose = std::make_unique<TransformationMatrix>( - other_space->OriginOffsetMatrix().Inverse().Multiply(*grip_pose)); + other_space->InverseOriginOffsetMatrix().Multiply(*grip_pose)); return MakeGarbageCollected<XRPose>(std::move(grip_pose), input_source_->emulatedPosition());
diff --git a/third_party/blink/renderer/modules/xr/xr_reference_space.cc b/third_party/blink/renderer/modules/xr/xr_reference_space.cc index 220f349..c5398bcb 100644 --- a/third_party/blink/renderer/modules/xr/xr_reference_space.cc +++ b/third_party/blink/renderer/modules/xr/xr_reference_space.cc
@@ -67,8 +67,8 @@ origin_offset_ = transform; } -TransformationMatrix XRReferenceSpace::OriginOffsetMatrix() { - return origin_offset_->TransformMatrix(); +TransformationMatrix XRReferenceSpace::InverseOriginOffsetMatrix() { + return origin_offset_->InverseTransformMatrix(); } void XRReferenceSpace::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/modules/xr/xr_reference_space.h b/third_party/blink/renderer/modules/xr/xr_reference_space.h index 53b73c0..3d1c507f 100644 --- a/third_party/blink/renderer/modules/xr/xr_reference_space.h +++ b/third_party/blink/renderer/modules/xr/xr_reference_space.h
@@ -32,7 +32,7 @@ XRRigidTransform* originOffset() const { return origin_offset_; } void setOriginOffset(XRRigidTransform*); - TransformationMatrix OriginOffsetMatrix() override; + TransformationMatrix InverseOriginOffsetMatrix() override; void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc b/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc index adfb30fa..ee34bad 100644 --- a/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc +++ b/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc
@@ -66,6 +66,10 @@ if (other.matrix_) { matrix_ = std::make_unique<TransformationMatrix>(*(other.matrix_.get())); } + if (other.inv_matrix_) { + inv_matrix_ = + std::make_unique<TransformationMatrix>(*(other.inv_matrix_.get())); + } return *this; } @@ -105,9 +109,16 @@ } TransformationMatrix XRRigidTransform::InverseTransformMatrix() { - EnsureMatrix(); - DCHECK(matrix_->IsInvertible()); - return matrix_->Inverse(); + // Only compute inverse matrix when it's requested, but cache it once we do. + // matrix_ does not change once the XRRigidTransfrorm has been constructed, so + // the caching is safe. + if (!inv_matrix_) { + EnsureMatrix(); + DCHECK(matrix_->IsInvertible()); + inv_matrix_ = std::make_unique<TransformationMatrix>(matrix_->Inverse()); + } + + return *inv_matrix_; } TransformationMatrix XRRigidTransform::TransformMatrix() {
diff --git a/third_party/blink/renderer/modules/xr/xr_rigid_transform.h b/third_party/blink/renderer/modules/xr/xr_rigid_transform.h index 0697decc..732e006ea 100644 --- a/third_party/blink/renderer/modules/xr/xr_rigid_transform.h +++ b/third_party/blink/renderer/modules/xr/xr_rigid_transform.h
@@ -51,6 +51,7 @@ Member<DOMPointReadOnly> position_; Member<DOMPointReadOnly> orientation_; std::unique_ptr<TransformationMatrix> matrix_; + std::unique_ptr<TransformationMatrix> inv_matrix_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_space.cc b/third_party/blink/renderer/modules/xr/xr_space.cc index 5b15d8c9..33de78b 100644 --- a/third_party/blink/renderer/modules/xr/xr_space.cc +++ b/third_party/blink/renderer/modules/xr/xr_space.cc
@@ -37,7 +37,7 @@ return nullptr; } -TransformationMatrix XRSpace::OriginOffsetMatrix() { +TransformationMatrix XRSpace::InverseOriginOffsetMatrix() { TransformationMatrix identity; return identity; } @@ -90,7 +90,7 @@ // Account for any changes made to the reference space's origin offset so that // things like teleportation works. return std::make_unique<TransformationMatrix>( - OriginOffsetMatrix().Inverse().Multiply(*pose)); + InverseOriginOffsetMatrix().Multiply(*pose)); } ExecutionContext* XRSpace::GetExecutionContext() const {
diff --git a/third_party/blink/renderer/modules/xr/xr_space.h b/third_party/blink/renderer/modules/xr/xr_space.h index 0cc22a0..da2ce0b 100644 --- a/third_party/blink/renderer/modules/xr/xr_space.h +++ b/third_party/blink/renderer/modules/xr/xr_space.h
@@ -53,7 +53,7 @@ ExecutionContext* GetExecutionContext() const override; const AtomicString& InterfaceName() const override; - virtual TransformationMatrix OriginOffsetMatrix(); + virtual TransformationMatrix InverseOriginOffsetMatrix(); void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc b/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc index 8f04c2166..e6ba36a 100644 --- a/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc +++ b/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc
@@ -95,7 +95,7 @@ // Account for any changes made to the reference space's origin offset so that // things like teleportation works. pointer_pose = std::make_unique<TransformationMatrix>( - other_space->OriginOffsetMatrix().Inverse().Multiply(*pointer_pose)); + other_space->InverseOriginOffsetMatrix().Multiply(*pointer_pose)); return MakeGarbageCollected<XRPose>(std::move(pointer_pose), input_source_->emulatedPosition());
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 1ffedcd..56b80cad 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -2013,7 +2013,7 @@ external/wpt/payment-request/algorithms-manual.https.html [ WontFix ] external/wpt/payment-request/change-shipping-option-manual.https.html [ WontFix ] external/wpt/payment-request/change-shipping-option-select-last-manual.https.html [ WontFix ] -external/wpt/payment-request/payment-request-hasenrolledinstrument-method-manual.https.html [ WontFix ] +external/wpt/payment-request/payment-request-hasenrolledinstrument-method-manual.tentative.https.html [ WontFix ] external/wpt/payment-request/payment-response/complete-method-manual.https.html [ WontFix ] external/wpt/payment-request/payment-response/methodName-attribute-manual.https.html [ WontFix ] external/wpt/payment-request/payment-response/onpayerdetailchange-attribute-manual.https.html [ WontFix ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 02930e41..86349de 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1716,7 +1716,6 @@ crbug.com/467127 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/ttwf-reftest-flex-wrap-reverse.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/hittest-overlapping-margin.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/hittest-overlapping-order.html [ Failure ] -crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html [ Failure ] ### virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-lines/ crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-lines/multi-line-wrap-reverse-column-reverse.html [ Failure ] @@ -3026,6 +3025,8 @@ crbug.com/939181 virtual/not-site-per-process/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Failure Timeout ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/media-source/mediasource-correct-frames-after-reappend.html [ Timeout ] +crbug.com/626703 external/wpt/media-source/mediasource-correct-frames.html [ Timeout ] crbug.com/626703 external/wpt/payment-method-basic-card/steps_for_selecting_the_payment_handler.html [ Timeout ] crbug.com/626703 external/wpt/payment-method-basic-card/apply_the_modifiers.html [ Timeout ] crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/tables/table-border-3s.html [ Failure ]
diff --git a/third_party/blink/web_tests/clipboard/copy-image-at-with-pinch-zoom.html b/third_party/blink/web_tests/clipboard/copy-image-at-with-pinch-zoom.html index c3356099..2e4474c3 100644 --- a/third_party/blink/web_tests/clipboard/copy-image-at-with-pinch-zoom.html +++ b/third_party/blink/web_tests/clipboard/copy-image-at-with-pinch-zoom.html
@@ -7,8 +7,8 @@ testRunner.waitUntilDone(); testRunner.dumpAsText(); requestAnimationFrame(() => { - var canvas = document.querySelector('canvas'); - var context = canvas.getContext('2d'); + const canvas = document.querySelector('canvas'); + const context = canvas.getContext('2d'); context.fillStyle = 'red'; context.fillRect(0, 0, 200, 200); internals.setPageScaleFactor(2); @@ -18,7 +18,7 @@ try { if (width !== 200 || height !== 200) testFailed('The copied image must be 200x200.'); - var topleft = new Uint8Array(snapshot).subarray(0, 4); + const topleft = new Uint8Array(snapshot).subarray(0, 4); if (topleft[0] !== 255 || topleft[1] !== 0 || topleft[2] !== 0 || topleft[3] !== 255) testFailed("The copied image's top left must be red. " + JSON.stringify(topleft)); } catch (e) {
diff --git a/third_party/blink/web_tests/clipboard/copy-image-at.html b/third_party/blink/web_tests/clipboard/copy-image-at.html index 5abc4ce2..5146035 100644 --- a/third_party/blink/web_tests/clipboard/copy-image-at.html +++ b/third_party/blink/web_tests/clipboard/copy-image-at.html
@@ -7,8 +7,8 @@ testRunner.waitUntilDone(); testRunner.dumpAsText(); requestAnimationFrame(() => { - var canvas = document.querySelector('canvas'); - var context = canvas.getContext('2d'); + const canvas = document.querySelector('canvas'); + const context = canvas.getContext('2d'); context.fillStyle = 'red'; context.fillRect(0, 0, 200, 200); requestAnimationFrame(() => { @@ -16,7 +16,7 @@ try { if (width !== 200 || height !== 200) testFailed('The copied image must be 200x200.'); - var topleft = new Uint8Array(snapshot).subarray(0, 4); + const topleft = new Uint8Array(snapshot).subarray(0, 4); if (topleft[0] !== 255 || topleft[1] !== 0 || topleft[2] !== 0 || topleft[3] !== 255) testFailed("The copied image's top left must be red. " + JSON.stringify(topleft)); } catch (e) {
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json index 3d18ee7..0ff024c 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -5641,9 +5641,9 @@ {} ] ], - "payment-request/payment-request-hasenrolledinstrument-method-manual.https.html": [ + "payment-request/payment-request-hasenrolledinstrument-method-manual.tentative.https.html": [ [ - "/payment-request/payment-request-hasenrolledinstrument-method-manual.https.html", + "/payment-request/payment-request-hasenrolledinstrument-method-manual.tentative.https.html", {} ] ], @@ -74087,6 +74087,30 @@ {} ] ], + "css/css-transforms/subpixel-perspective-backface-hidden.html": [ + [ + "/css/css-transforms/subpixel-perspective-backface-hidden.html", + [ + [ + "/css/css-transforms/subpixel-perspective-backface-hidden-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-transforms/subpixel-perspective-translate-z-0.html": [ + [ + "/css/css-transforms/subpixel-perspective-translate-z-0.html", + [ + [ + "/css/css-transforms/subpixel-perspective-translate-z-0-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-transforms/text-perspective-001.html": [ [ "/css/css-transforms/text-perspective-001.html", @@ -148011,6 +148035,16 @@ {} ] ], + "css/css-transforms/subpixel-perspective-backface-hidden-ref.html": [ + [ + {} + ] + ], + "css/css-transforms/subpixel-perspective-translate-z-0-ref.html": [ + [ + {} + ] + ], "css/css-transforms/support/1x1-green.png": [ [ {} @@ -178336,6 +178370,16 @@ {} ] ], + "media-source/mp4/test-boxes-audio.mp4": [ + [ + {} + ] + ], + "media-source/mp4/test-boxes-video.mp4": [ + [ + {} + ] + ], "media-source/mp4/test-v-128k-320x240-24fps-8kfr-manifest.json": [ [ {} @@ -180746,11 +180790,21 @@ {} ] ], + "payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https-expected.txt": [ + [ + {} + ] + ], "payment-request/payment-request-hasenrolledinstrument-method.https-expected.txt": [ [ {} ] ], + "payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt": [ + [ + {} + ] + ], "payment-request/payment-request-show-method.https-expected.txt": [ [ {} @@ -262029,6 +262083,22 @@ {} ] ], + "media-source/mediasource-correct-frames-after-reappend.html": [ + [ + "/media-source/mediasource-correct-frames-after-reappend.html", + { + "timeout": "long" + } + ] + ], + "media-source/mediasource-correct-frames.html": [ + [ + "/media-source/mediasource-correct-frames.html", + { + "timeout": "long" + } + ] + ], "media-source/mediasource-detach.html": [ [ "/media-source/mediasource-detach.html", @@ -275777,17 +275847,17 @@ {} ] ], - "payment-request/payment-request-hasenrolledinstrument-method-protection.https.html": [ + "payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https.html": [ [ - "/payment-request/payment-request-hasenrolledinstrument-method-protection.https.html", + "/payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https.html", { "testdriver": true } ] ], - "payment-request/payment-request-hasenrolledinstrument-method.https.html": [ + "payment-request/payment-request-hasenrolledinstrument-method.tentative.https.html": [ [ - "/payment-request/payment-request-hasenrolledinstrument-method.https.html", + "/payment-request/payment-request-hasenrolledinstrument-method.tentative.https.html", { "testdriver": true } @@ -321700,35 +321770,35 @@ "support" ], "clipboard-apis/async-interfaces.https.html": [ - "0617ac11ac2e7dbc2cac3f0665e2df121d1ae477", + "e0d0977959b5dbe943005587c1442de451d9a18d", "testharness" ], "clipboard-apis/async-navigator-clipboard-basics.https.html": [ - "7d2cba8b5090d1ef268ddc6d159d1e06a49a3158", + "b71b43efe064c3fba60c6922c09da7e835398903", "testharness" ], "clipboard-apis/async-write-blobs-read-blobs-manual.https.html": [ - "3666c93df027fd3962d0b31a6735dc56651ecd58", + "57cf542ca77bc648d4a839e21775957f287ec60f", "manual" ], "clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html": [ - "44c574247825612ec906ba42d3f0171a97a17668", + "fded721f9bfa1a9efd9e42b05b4ddcc40a3b8e48", "manual" ], "clipboard-apis/async-write-blobtext-read-text-manual.https.html": [ - "c991f1fd324a330d4b322a1f33bb07a0f6ad6199", + "98ff7c27b667182432d744edcdbdfc5ca36dabb0", "manual" ], "clipboard-apis/async-write-image-read-image-manual.https.html": [ - "2a32348507f7206316f5851e2ff1f6dc6829fbdb", + "6c326cf8ddeaa8777ef6b41d6bc9e4c32282a5c3", "manual" ], "clipboard-apis/async-write-text-read-blobtext-manual.https.html": [ - "24e6b6ed3cc3510f21620d86769e0fdfa3e0a9cb", + "ab85a6fc649e6a6c7a86127adb1a41845324f3ff", "manual" ], "clipboard-apis/async-write-text-read-text-manual.https.html": [ - "496bdd78c7ab2ec0d26adafea6449ec18cc03340", + "25c7edb43f061552717459caf6d4df969383e84c", "manual" ], "clipboard-apis/clipboard-events-synthetic.html": [ @@ -321736,15 +321806,15 @@ "testharness" ], "clipboard-apis/copy-event-manual.html": [ - "e4cf3379ace559671d4ca03c1ed7dcd32f565ed8", + "6f687af196fa198cda7d83f468945f9f69330568", "manual" ], "clipboard-apis/cut-event-manual.html": [ - "abef6f94bf640c210e56121e5407a1d00e558d71", + "c5593171754cfa2bd684e1ff3a8a724283456cbd", "manual" ], "clipboard-apis/paste-event-manual.html": [ - "4131a41bff6fd6bf5fb22fa805aea219ec7f72aa", + "19e6b95c5f32a0eb7dbccb0f5bd538e9dbb1360e", "manual" ], "clipboard-apis/resources/greenbox.png": [ @@ -380099,6 +380169,22 @@ "a83705e3985de757804bcc7134d17129b0f26516", "reftest" ], + "css/css-transforms/subpixel-perspective-backface-hidden-ref.html": [ + "8413e3e2d2cf5f0e18b5cb1a15095d2696e2c280", + "support" + ], + "css/css-transforms/subpixel-perspective-backface-hidden.html": [ + "e24539bfa2f50e9db422237d089acdaa2d3c178e", + "reftest" + ], + "css/css-transforms/subpixel-perspective-translate-z-0-ref.html": [ + "5f3a8e279b48f314ad8d7a46091cc6ff0a49a814", + "support" + ], + "css/css-transforms/subpixel-perspective-translate-z-0.html": [ + "4033e46f8ac2cee4e54fe672560323795fb89f0d", + "reftest" + ], "css/css-transforms/support/1x1-green.png": [ "b98ca0ba0a03c580ac339e4a3653539cfa8edc71", "support" @@ -434504,7 +434590,7 @@ "support" ], "infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini": [ - "5df5c1f4561dcebdf92ff13c64a1e2fa28092f4e", + "f62bf62a9713c2c12e4d572e0701efde494224c0", "support" ], "infrastructure/metadata/infrastructure/testdriver/actions/elementPosition.html.ini": [ @@ -436795,6 +436881,14 @@ "b28aa90f1f3d8135a7ea86b82820ffd414451920", "support" ], + "media-source/mediasource-correct-frames-after-reappend.html": [ + "5c0f2e11195c3b8fe6292f726f12bf6190df32de", + "testharness" + ], + "media-source/mediasource-correct-frames.html": [ + "4ef3f4605e6580f949e4e53e6192f0eec1206e78", + "testharness" + ], "media-source/mediasource-detach.html": [ "b25b5c6f02f6e6abdb32de0902438c0b24d1f1c4", "testharness" @@ -436983,6 +437077,14 @@ "f224a5426a16e0a44df788f704ce6e602663b61a", "support" ], + "media-source/mp4/test-boxes-audio.mp4": [ + "b1cabbfd21efdc08bff28a6b043f8eb856b7e322", + "support" + ], + "media-source/mp4/test-boxes-video.mp4": [ + "714c17ca126c110d64e9fe58a50798e2a0ebc414", + "support" + ], "media-source/mp4/test-v-128k-320x240-24fps-8kfr-manifest.json": [ "a31b6d0245ba5de8a59dcdf795ba2ab008647ef4", "support" @@ -448163,7 +448265,7 @@ "5f888f0389f6c756ede8c3e481ece7bcf8b71ccf", "testharness" ], - "payment-request/payment-request-hasenrolledinstrument-method-manual.https.html": [ + "payment-request/payment-request-hasenrolledinstrument-method-manual.tentative.https.html": [ "e6b164f7cc7b8f1c57b8fa9fd14cbc7f5ef81eea", "manual" ], @@ -448171,7 +448273,11 @@ "20a6f53208ac5e4c29a504f3e444066cce5bba89", "support" ], - "payment-request/payment-request-hasenrolledinstrument-method-protection.https.html": [ + "payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https-expected.txt": [ + "20a6f53208ac5e4c29a504f3e444066cce5bba89", + "support" + ], + "payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https.html": [ "4da11304a21427040f72317e3746feebb251d12e", "testharness" ], @@ -448179,7 +448285,11 @@ "fe7f16769673e2d5b809417456fd1b0c1546d9cc", "support" ], - "payment-request/payment-request-hasenrolledinstrument-method.https.html": [ + "payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt": [ + "fe7f16769673e2d5b809417456fd1b0c1546d9cc", + "support" + ], + "payment-request/payment-request-hasenrolledinstrument-method.tentative.https.html": [ "c1f7b27a22b41fe64a7fb77e73336d3d0daec159", "testharness" ], @@ -471836,7 +471946,7 @@ "support" ], "tools/wpt/browser.py": [ - "c4469800608ad73b4a00c3bbef558cf9d0f7e596", + "f5bc7c0af02697c29818a8800c1d11a379023790", "support" ], "tools/wpt/commands.json": [ @@ -471864,7 +471974,7 @@ "support" ], "tools/wpt/run.py": [ - "ea4bd1c8054ae874a098cf762627613e2511bd67", + "1178c5a3f6d3f041ed5e4fe8597139d21d64de00", "support" ], "tools/wpt/testfiles.py": [ @@ -472144,11 +472254,11 @@ "support" ], "tools/wptrunner/wptrunner/formatters/chromium.py": [ - "f54f23e5a9d5f6e8bf1698a50c597155c5a1d727", + "071c2f378902965971a77d46911fd89a85a18bdc", "support" ], "tools/wptrunner/wptrunner/formatters/tests/test_chromium.py": [ - "a6e6c2e1ed08d4c0d4209230082212c7988f8f11", + "22d9fb4e7ea022ed109047c0887a3443d19bc28c", "support" ], "tools/wptrunner/wptrunner/formatters/wptreport.py": [ @@ -482968,7 +483078,7 @@ "support" ], "webxr/idlharness.https.window-expected.txt": [ - "e15f9c4f30f66871b2f5d1411f991ba582bdad4c", + "b9df588c70e3c521a84d5335f0e3e32f9cd12cbf", "support" ], "webxr/idlharness.https.window.js": [ @@ -483100,7 +483210,7 @@ "testharness" ], "webxr/xrSession_requestAnimationFrame_data_valid.https.html": [ - "41801bcd3643b9173e0b447545967beb60cee330", + "6c567d2fda6888ee0b30e4f4716e75ee4763516d", "testharness" ], "webxr/xrSession_requestAnimationFrame_getViewerPose.https.html": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html deleted file mode 100644 index 8310e66..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html +++ /dev/null
@@ -1,21 +0,0 @@ -<!DOCTYPE html> -<link rel="author" title="Google" href="https://www.google.com/" /> -<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#intrinsic-sizes" /> -<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1865" /> - -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/check-layout-th.js"></script> - -<body onload="checkLayout('.flexbox')"> -<div class="flexbox" style="display: flex; width: min-content;" data-expected-width="0"> - <div style="overflow: auto;"> - <div style="width: 100px; height: 100px;"></div> - </div> -</div> - -<div class="flexbox" style="display: flex; width: min-content;" data-expected-width="10"> - <div style="overflow: auto; border: 5px solid;"> - <div style="width: 100px; height: 100px;"></div> - </div> -</div>
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini index 5df5c1f4..f62bf62a 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini
@@ -1,3 +1,9 @@ [actionsWithKeyPressed.html] expected: if product == "safari" or product == "firefox": ERROR + + + [TestDriver actions: actions with key pressed] + expected: + if product == "chrome": FAIL +
diff --git a/third_party/blink/web_tests/external/wpt/media-source/mediasource-correct-frames-after-reappend.html b/third_party/blink/web_tests/external/wpt/media-source/mediasource-correct-frames-after-reappend.html new file mode 100644 index 0000000..5c0f2e1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/media-source/mediasource-correct-frames-after-reappend.html
@@ -0,0 +1,162 @@ +<!DOCTYPE html> +<!-- Copyright © 2019 Igalia. --> +<html> +<head> + <title>Frame checking test for MSE playback in presence of a reappend.</title> + <meta name="timeout" content="long"> + <meta name="charset" content="UTF-8"> + <link rel="author" title="Alicia Boya García" href="mailto:aboya@igalia.com"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="mediasource-util.js"></script> +</head> +<body> +<div id="log"></div> +<canvas id="test-canvas"></canvas> +<script> + function waitForEventPromise(element, event) { + return new Promise(resolve => { + function handler(ev) { + element.removeEventListener(event, handler); + resolve(ev); + } + element.addEventListener(event, handler); + }); + } + + function appendBufferPromise(sourceBuffer, data) { + sourceBuffer.appendBuffer(data); + return waitForEventPromise(sourceBuffer, "update"); + } + + function waitForPlayerToReachTimePromise(mediaElement, time) { + return new Promise(resolve => { + function timeupdate() { + if (mediaElement.currentTime < time) + return; + + mediaElement.removeEventListener("timeupdate", timeupdate); + resolve(); + } + mediaElement.addEventListener("timeupdate", timeupdate); + }); + } + + function readPixel(imageData, x, y) { + return { + r: imageData.data[4 * (y * imageData.width + x)], + g: imageData.data[1 + 4 * (y * imageData.width + x)], + b: imageData.data[2 + 4 * (y * imageData.width + x)], + a: imageData.data[3 + 4 * (y * imageData.width + x)], + }; + } + + function isPixelLit(pixel) { + const threshold = 200; // out of 255 + return pixel.r >= threshold && pixel.g >= threshold && pixel.b >= threshold; + } + + // The test video has a few gray boxes. Each box interval (1 second) a new box is lit white and a different note + // is played. This test makes sure the right number of lit boxes and the right note are played at the right time. + const totalBoxes = 7; + const boxInterval = 1; // seconds + + const videoWidth = 320; + const videoHeight = 240; + const boxesY = 210; + const boxSide = 20; + const boxMargin = 20; + const allBoxesWidth = totalBoxes * boxSide + (totalBoxes - 1) * boxMargin; + const boxesX = new Array(totalBoxes).fill(undefined) + .map((_, i) => (videoWidth - allBoxesWidth) / 2 + boxSide / 2 + i * (boxSide + boxMargin)); + + // Sound starts playing A4 (440 Hz) and goes one chromatic note up with every box lit. + // By comparing the player position to both the amount of boxes lit and the note played we can detect A/V + // synchronization issues automatically. + const noteFrequencies = new Array(1 + totalBoxes).fill(undefined) + .map((_, i) => 440 * Math.pow(Math.pow(2, 1 / 12), i)); + + // We also check the first second [0, 1) where no boxes are lit, therefore we start counting at -1 to do the check + // for zero lit boxes. + let boxesLitSoFar = -1; + + mediasource_test(async function (test, mediaElement, mediaSource) { + const canvas = document.getElementById("test-canvas"); + const canvasCtx = canvas.getContext("2d"); + canvas.width = videoWidth; + canvas.height = videoHeight; + + const videoData = await (await fetch("mp4/test-boxes-video.mp4")).arrayBuffer(); + const audioData = (await (await fetch("mp4/test-boxes-audio.mp4")).arrayBuffer()); + + const videoSb = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.4d401f"'); + const audioSb = mediaSource.addSourceBuffer('audio/mp4; codecs="mp4a.40.2"'); + + mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'")); + mediaElement.addEventListener('ended', onEnded); + mediaElement.addEventListener('timeupdate', onTimeUpdate); + + await appendBufferPromise(videoSb, videoData); + await appendBufferPromise(audioSb, audioData); + mediaElement.play(); + + audioCtx = new (window.AudioContext || window.webkitAudioContext)(); + source = audioCtx.createMediaElementSource(mediaElement); + analyser = audioCtx.createAnalyser(); + analyser.fftSize = 8192; + source.connect(analyser); + analyser.connect(audioCtx.destination); + + const freqDomainArray = new Float32Array(analyser.frequencyBinCount); + + function checkNoteBeingPlayed() { + const expectedNoteFrequency = noteFrequencies[boxesLitSoFar]; + + analyser.getFloatFrequencyData(freqDomainArray); + const maxBin = freqDomainArray.reduce((prev, curValue, i) => + curValue > prev.value ? {index: i, value: curValue} : prev, + {index: -1, value: -Infinity}); + const binFrequencyWidth = audioCtx.sampleRate / analyser.fftSize; + const binFreq = maxBin.index * binFrequencyWidth; + + assert_true(Math.abs(expectedNoteFrequency - binFreq) <= binFrequencyWidth, + `The note being played matches the expected one (boxes lit: ${boxesLitSoFar}, ${expectedNoteFrequency.toFixed(1)} Hz)` + + `, found ~${binFreq.toFixed(1)} Hz`); + } + + function countLitBoxesInCurrentVideoFrame() { + canvasCtx.drawImage(mediaElement, 0, 0); + const imageData = canvasCtx.getImageData(0, 0, videoWidth, videoHeight); + const lights = boxesX.map(boxX => isPixelLit(readPixel(imageData, boxX, boxesY))); + let litBoxes = 0; + for (let i = 0; i < lights.length; i++) { + if (lights[i]) + litBoxes++; + } + for (let i = litBoxes; i < lights.length; i++) { + assert_false(lights[i], 'After the first non-lit box, all boxes must non-lit'); + } + return litBoxes; + } + + await waitForPlayerToReachTimePromise(mediaElement, 2.5); + await appendBufferPromise(audioSb, audioData); + mediaSource.endOfStream(); + + function onTimeUpdate() { + const graceTime = 0.5; + if (mediaElement.currentTime >= (1 + boxesLitSoFar) * boxInterval + graceTime && boxesLitSoFar < totalBoxes) { + assert_equals(countLitBoxesInCurrentVideoFrame(), boxesLitSoFar + 1, "Num of lit boxes:"); + boxesLitSoFar++; + checkNoteBeingPlayed(); + } + } + + function onEnded() { + assert_equals(boxesLitSoFar, totalBoxes, "Boxes lit at video ended event"); + test.done(); + } + }, "Test the expected frames are played at the expected times, even in presence of reappends"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/media-source/mediasource-correct-frames.html b/third_party/blink/web_tests/external/wpt/media-source/mediasource-correct-frames.html new file mode 100644 index 0000000..4ef3f46 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/media-source/mediasource-correct-frames.html
@@ -0,0 +1,146 @@ +<!DOCTYPE html> +<!-- Copyright © 2019 Igalia. --> +<html> +<head> + <title>Frame checking test for simple MSE playback.</title> + <meta name="timeout" content="long"> + <meta name="charset" content="UTF-8"> + <link rel="author" title="Alicia Boya García" href="mailto:aboya@igalia.com"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="mediasource-util.js"></script> +</head> +<body> +<div id="log"></div> +<canvas id="test-canvas"></canvas> +<script> + function waitForEventPromise(element, event) { + return new Promise(resolve => { + function handler(ev) { + element.removeEventListener(event, handler); + resolve(ev); + } + element.addEventListener(event, handler); + }); + } + + function appendBufferPromise(sourceBuffer, data) { + sourceBuffer.appendBuffer(data); + return waitForEventPromise(sourceBuffer, "update"); + } + + function readPixel(imageData, x, y) { + return { + r: imageData.data[4 * (y * imageData.width + x)], + g: imageData.data[1 + 4 * (y * imageData.width + x)], + b: imageData.data[2 + 4 * (y * imageData.width + x)], + a: imageData.data[3 + 4 * (y * imageData.width + x)], + }; + } + + function isPixelLit(pixel) { + const threshold = 200; // out of 255 + return pixel.r >= threshold && pixel.g >= threshold && pixel.b >= threshold; + } + + // The test video has a few gray boxes. Each box interval (1 second) a new box is lit white and a different note + // is played. This test makes sure the right number of lit boxes and the right note are played at the right time. + const totalBoxes = 7; + const boxInterval = 1; // seconds + + const videoWidth = 320; + const videoHeight = 240; + const boxesY = 210; + const boxSide = 20; + const boxMargin = 20; + const allBoxesWidth = totalBoxes * boxSide + (totalBoxes - 1) * boxMargin; + const boxesX = new Array(totalBoxes).fill(undefined) + .map((_, i) => (videoWidth - allBoxesWidth) / 2 + boxSide / 2 + i * (boxSide + boxMargin)); + + // Sound starts playing A4 (440 Hz) and goes one chromatic note up with every box lit. + // By comparing the player position to both the amount of boxes lit and the note played we can detect A/V + // synchronization issues automatically. + const noteFrequencies = new Array(1 + totalBoxes).fill(undefined) + .map((_, i) => 440 * Math.pow(Math.pow(2, 1 / 12), i)); + + // We also check the first second [0, 1) where no boxes are lit, therefore we start counting at -1 to do the check + // for zero lit boxes. + let boxesLitSoFar = -1; + + mediasource_test(async function (test, mediaElement, mediaSource) { + const canvas = document.getElementById("test-canvas"); + const canvasCtx = canvas.getContext("2d"); + canvas.width = videoWidth; + canvas.height = videoHeight; + + const videoData = await (await fetch("mp4/test-boxes-video.mp4")).arrayBuffer(); + const audioData = (await (await fetch("mp4/test-boxes-audio.mp4")).arrayBuffer()); + + const videoSb = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.4d401f"'); + const audioSb = mediaSource.addSourceBuffer('audio/mp4; codecs="mp4a.40.2"'); + + mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'")); + mediaElement.addEventListener('ended', onEnded); + mediaElement.addEventListener('timeupdate', onTimeUpdate); + + await appendBufferPromise(videoSb, videoData); + await appendBufferPromise(audioSb, audioData); + mediaSource.endOfStream(); + mediaElement.play(); + + const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); + const source = audioCtx.createMediaElementSource(mediaElement); + const analyser = audioCtx.createAnalyser(); + analyser.fftSize = 8192; + source.connect(analyser); + analyser.connect(audioCtx.destination); + + const freqDomainArray = new Float32Array(analyser.frequencyBinCount); + + function checkNoteBeingPlayed() { + const expectedNoteFrequency = noteFrequencies[boxesLitSoFar]; + + analyser.getFloatFrequencyData(freqDomainArray); + const maxBin = freqDomainArray.reduce((prev, curValue, i) => + curValue > prev.value ? {index: i, value: curValue} : prev, + {index: -1, value: -Infinity}); + const binFrequencyWidth = audioCtx.sampleRate / analyser.fftSize; + const binFreq = maxBin.index * binFrequencyWidth; + + assert_true(Math.abs(expectedNoteFrequency - binFreq) <= binFrequencyWidth, + `The note being played matches the expected one (boxes lit: ${boxesLitSoFar}, ${expectedNoteFrequency.toFixed(1)} Hz)` + + `, found ~${binFreq.toFixed(1)} Hz`); + } + + function countLitBoxesInCurrentVideoFrame() { + canvasCtx.drawImage(mediaElement, 0, 0); + const imageData = canvasCtx.getImageData(0, 0, videoWidth, videoHeight); + const lights = boxesX.map(boxX => isPixelLit(readPixel(imageData, boxX, boxesY))); + let litBoxes = 0; + for (let i = 0; i < lights.length; i++) { + if (lights[i]) + litBoxes++; + } + for (let i = litBoxes; i < lights.length; i++) { + assert_false(lights[i], 'After the first non-lit box, all boxes must non-lit'); + } + return litBoxes; + } + + function onTimeUpdate() { + const graceTime = 0.5; + if (mediaElement.currentTime >= (1 + boxesLitSoFar) * boxInterval + graceTime && boxesLitSoFar < totalBoxes) { + assert_equals(countLitBoxesInCurrentVideoFrame(), boxesLitSoFar + 1, "Num of lit boxes:"); + boxesLitSoFar++; + checkNoteBeingPlayed(); + } + } + + function onEnded() { + assert_equals(boxesLitSoFar, totalBoxes, "Boxes lit at video ended event"); + test.done(); + } + }, "Test the expected frames are played at the expected times"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/media-source/mp4/test-boxes-audio.mp4 b/third_party/blink/web_tests/external/wpt/media-source/mp4/test-boxes-audio.mp4 new file mode 100644 index 0000000..b1cabbf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/media-source/mp4/test-boxes-audio.mp4 Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/media-source/mp4/test-boxes-video.mp4 b/third_party/blink/web_tests/external/wpt/media-source/mp4/test-boxes-video.mp4 new file mode 100644 index 0000000..714c17c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/media-source/mp4/test-boxes-video.mp4 Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-manual.tentative.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-manual.https.html rename to third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-manual.tentative.https.html
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https-expected.txt new file mode 100644 index 0000000..20a6f53 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException. assert_equals: If it throws, then it must be a NotAllowedError. expected "NotAllowedError" but got "UnknownError" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-protection.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-protection.https.html rename to third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https.html
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt new file mode 100644 index 0000000..fe7f1676 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +Harness Error. harness_status.status = 1 , harness_status.message = Already called show() once +FAIL hasEnrolledInstrument() resolves to false for unsupported payment methods. promise_test: Unhandled rejection with value: object "UnknownError: Request failed" +FAIL If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "InvalidStateError: No show() or retry() in progress, so nothing to abort" +FAIL If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "InvalidStateError: No show() or retry() in progress, so nothing to abort" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.https.html rename to third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https.html
diff --git a/third_party/blink/web_tests/external/wpt/tools/wpt/browser.py b/third_party/blink/web_tests/external/wpt/tools/wpt/browser.py index c446980..f5bc7c0 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wpt/browser.py +++ b/third_party/blink/web_tests/external/wpt/tools/wpt/browser.py
@@ -29,7 +29,7 @@ return NotImplemented @abstractmethod - def install_webdriver(self, dest=None, channel=None): + def install_webdriver(self, dest=None, channel=None, browser_binary=None): """Install the WebDriver implementation for this browser.""" return NotImplemented @@ -166,11 +166,11 @@ os.remove(installer_path) return self.find_binary_path(dest) - def find_binary_path(self,path=None, channel="nightly"): + def find_binary_path(self, path=None, channel="nightly"): """Looks for the firefox binary in the virtual environment""" if path is None: - #os.getcwd() doesn't include the venv path + # os.getcwd() doesn't include the venv path path = os.path.join(os.getcwd(), "_venv", "browsers", channel) binary = None @@ -315,7 +315,7 @@ assert latest_release != 0 return "v%s.%s.%s" % tuple(str(item) for item in latest_release) - def install_webdriver(self, dest=None, channel=None): + def install_webdriver(self, dest=None, channel=None, browser_binary=None): """Install latest Geckodriver.""" if dest is None: dest = os.getcwd() @@ -392,7 +392,7 @@ def find_webdriver(self, channel=None): raise NotImplementedError - def install_webdriver(self, dest=None, channel=None): + def install_webdriver(self, dest=None, channel=None, browser_binary=None): raise NotImplementedError def version(self, binary=None, webdriver_binary=None): @@ -440,24 +440,66 @@ return "%s%s" % (platform, bits) + def chromium_platform_string(self): + platform = { + "Linux": "Linux", + "Windows": "Win", + "Darwin": "Mac" + }.get(uname[0]) + + if platform is None: + raise ValueError("Unable to construct a valid Chromium package name for current platform") + + if (platform == "Linux" or platform == "Win") and uname[4] == "x86_64": + platform += "_x64" + + return platform + def find_binary(self, venv_path=None, channel=None): raise NotImplementedError def find_webdriver(self, channel=None): return find_executable("chromedriver") - def install_webdriver(self, dest=None, channel=None): + def _latest_chromedriver_url(self, browser_binary=None): + latest = None + chrome_version = self.version(browser_binary) + if chrome_version is not None: + parts = chrome_version.split(".") + if len(parts) == 4: + latest_url = "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_%s.%s.%s" % ( + parts[0], parts[1], parts[2]) + try: + latest = get(latest_url).text.strip() + except requests.RequestException: + latest_url = "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_%s" % parts[0] + try: + latest = get(latest_url).text.strip() + except requests.RequestException: + pass + if latest is None: + # Fall back to the tip-of-tree *Chromium* build. + latest_url = "https://storage.googleapis.com/chromium-browser-snapshots/%s/LAST_CHANGE" % ( + self.chromium_platform_string()) + latest = get(latest_url).text.strip() + url = "https://storage.googleapis.com/chromium-browser-snapshots/%s/%s/chromedriver_%s.zip" % ( + self.chromium_platform_string(), latest, self.platform_string()) + else: + url = "https://chromedriver.storage.googleapis.com/%s/chromedriver_%s.zip" % ( + latest, self.platform_string()) + return url + + def install_webdriver(self, dest=None, channel=None, browser_binary=None): if dest is None: dest = os.pwd - latest = get("http://chromedriver.storage.googleapis.com/LATEST_RELEASE").text.strip() - url = "http://chromedriver.storage.googleapis.com/%s/chromedriver_%s.zip" % (latest, - self.platform_string()) + url = self._latest_chromedriver_url(browser_binary) + self.logger.info("Downloading ChromeDriver from %s" % url) unzip(get(url).raw, dest) - - path = find_executable("chromedriver", dest) - st = os.stat(path) - os.chmod(path, st.st_mode | stat.S_IEXEC) - return path + chromedriver_dir = os.path.join(dest, 'chromedriver_%s' % self.platform_string()) + if os.path.isfile(os.path.join(chromedriver_dir, "chromedriver")): + shutil.move(os.path.join(chromedriver_dir, "chromedriver"), dest) + shutil.rmtree(chromedriver_dir) + return find_executable("chromedriver", dest) def version(self, binary=None, webdriver_binary=None): binary = binary or self.binary @@ -465,11 +507,11 @@ try: version_string = call(binary, "--version").strip() except subprocess.CalledProcessError: - self.logger.warning("Failed to call %s", binary) + self.logger.warning("Failed to call %s" % binary) return None - m = re.match(r"Google Chrome (.*)", version_string) + m = re.match(r"(?:Google Chrome|Chromium) (.*)", version_string) if not m: - self.logger.warning("Failed to extract version from: %s", version_string) + self.logger.warning("Failed to extract version from: %s" % version_string) return None return m.group(1) self.logger.warning("Unable to extract version from binary on Windows.") @@ -494,13 +536,14 @@ def find_webdriver(self, channel=None): return find_executable("chromedriver") - def install_webdriver(self, dest=None, channel=None): + def install_webdriver(self, dest=None, channel=None, browser_binary=None): chrome = Chrome() return chrome.install_webdriver(dest, channel) def version(self, binary=None, webdriver_binary=None): return None + class Opera(Browser): """Opera-specific interface. @@ -546,7 +589,7 @@ def find_webdriver(self, channel=None): return find_executable("operadriver") - def install_webdriver(self, dest=None, channel=None): + def install_webdriver(self, dest=None, channel=None, browser_binary=None): if dest is None: dest = os.pwd latest = get("https://api.github.com/repos/operasoftware/operachromiumdriver/releases/latest").json()["tag_name"] @@ -569,7 +612,7 @@ try: output = call(binary, "--version") except subprocess.CalledProcessError: - self.logger.warning("Failed to call %s", binary) + self.logger.warning("Failed to call %s" % binary) return None m = re.search(r"[0-9\.]+( [a-z]+)?$", output.strip()) if m: @@ -591,7 +634,7 @@ def find_webdriver(self, channel=None): return find_executable("MicrosoftWebDriver") - def install_webdriver(self, dest=None, channel=None): + def install_webdriver(self, dest=None, channel=None, browser_binary=None): raise NotImplementedError def version(self, binary=None, webdriver_binary=None): @@ -599,9 +642,10 @@ try: return call("powershell.exe", command).strip() except (subprocess.CalledProcessError, OSError): - self.logger.warning("Failed to call %s in PowerShell", command) + self.logger.warning("Failed to call %s in PowerShell" % command) return None + class EdgeWebDriver(Edge): product = "edge_webdriver" @@ -621,7 +665,7 @@ def find_webdriver(self, channel=None): return find_executable("IEDriverServer.exe") - def install_webdriver(self, dest=None, channel=None): + def install_webdriver(self, dest=None, channel=None, browser_binary=None): raise NotImplementedError def version(self, binary=None, webdriver_binary=None): @@ -649,7 +693,7 @@ path = "/Applications/Safari Technology Preview.app/Contents/MacOS" return find_executable("safaridriver", path) - def install_webdriver(self, dest=None, channel=None): + def install_webdriver(self, dest=None, channel=None, browser_binary=None): raise NotImplementedError def version(self, binary=None, webdriver_binary=None): @@ -663,11 +707,11 @@ try: version_string = call(webdriver_binary, "--version").strip() except subprocess.CalledProcessError: - self.logger.warning("Failed to call %s --version", webdriver_binary) + self.logger.warning("Failed to call %s --version" % webdriver_binary) return None m = re.match(r"Included with Safari (.*)", version_string) if not m: - self.logger.warning("Failed to extract version from: %s", version_string) + self.logger.warning("Failed to extract version from: %s" % version_string) return None return m.group(1) @@ -721,7 +765,7 @@ def find_webdriver(self, channel=None): return None - def install_webdriver(self, dest=None, channel=None): + def install_webdriver(self, dest=None, channel=None, browser_binary=None): raise NotImplementedError def version(self, binary=None, webdriver_binary=None): @@ -751,7 +795,7 @@ def find_webdriver(self, channel=None): raise NotImplementedError - def install_webdriver(self, dest=None, channel=None): + def install_webdriver(self, dest=None, channel=None, browser_binary=None): raise NotImplementedError def version(self, binary=None, webdriver_binary=None): @@ -773,7 +817,7 @@ def find_webdriver(self, channel=None): return None - def install_webdriver(self, dest=None, channel=None): + def install_webdriver(self, dest=None, channel=None, browser_binary=None): raise NotImplementedError def version(self, binary=None, webdriver_binary=None): @@ -795,7 +839,7 @@ def find_webdriver(self, channel=None): return find_executable("WebKitWebDriver") - def install_webdriver(self, dest=None, channel=None): + def install_webdriver(self, dest=None, channel=None, browser_binary=None): raise NotImplementedError def version(self, binary=None, webdriver_binary=None):
diff --git a/third_party/blink/web_tests/external/wpt/tools/wpt/run.py b/third_party/blink/web_tests/external/wpt/tools/wpt/run.py index ea4bd1c..1178c5a3 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wpt/run.py +++ b/third_party/blink/web_tests/external/wpt/tools/wpt/run.py
@@ -266,7 +266,7 @@ if install: logger.info("Downloading chromedriver") - webdriver_binary = self.browser.install_webdriver(dest=self.venv.bin_path) + webdriver_binary = self.browser.install_webdriver(dest=self.venv.bin_path, browser_binary=kwargs["binary"]) else: logger.info("Using webdriver binary %s" % webdriver_binary)
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/chromium.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/chromium.py index f54f23e5..071c2f3 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/chromium.py +++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/chromium.py
@@ -88,7 +88,7 @@ final_result = { # There are some required fields that we just hard-code. "interrupted": False, - "path_delimeter": "/", + "path_delimiter": "/", "version": 3, "seconds_since_epoch": self.start_timestamp_seconds, "num_failures_by_type": self.num_failures_by_status,
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py index a6e6c2e..22d9fb4 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py +++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py
@@ -35,7 +35,7 @@ # Check for existence of required fields assert "interrupted" in output_obj - assert "path_delimeter" in output_obj + assert "path_delimiter" in output_obj assert "version" in output_obj assert "num_failures_by_type" in output_obj assert "tests" in output_obj
diff --git a/third_party/blink/web_tests/resources/idlharness.js b/third_party/blink/web_tests/resources/idlharness.js index 950df6fa..c7a0409 100644 --- a/third_party/blink/web_tests/resources/idlharness.js +++ b/third_party/blink/web_tests/resources/idlharness.js
@@ -298,15 +298,29 @@ }.bind(this)); deps.forEach(function(name) { - new_options.only.push(name); + if (!new_options.only.includes(name)) { + new_options.only.push(name); + } const follow_up = new Set(); for (const dep_type of ["inheritance", "implements", "includes"]) { if (parsed[dep_type]) { const inheriting = parsed[dep_type]; const inheritor = parsed.name || parsed.target; - for (const dep of [inheriting, inheritor]) { - new_options.only.push(dep); + const deps = [inheriting]; + // For A includes B, we can ignore A, unless B (or some of its + // members) is being tested. + if (dep_type !== "includes" + || inheriting in this.members && !this.members[inheriting].untested + || this.partials.some(function(p) { + return p.name === inheriting; + })) { + deps.push(inheritor); + } + for (const dep of deps) { + if (!new_options.only.includes(dep)) { + new_options.only.push(dep); + } all_deps.add(dep); follow_up.add(dep); } @@ -320,7 +334,7 @@ next.forEach(process); } } - }); + }.bind(this)); }.bind(this); for (let parsed of parsed_idls) { @@ -1256,6 +1270,48 @@ }); }; +/** + * Value of the LegacyNamespace extended attribute, if any. + * + * https://heycam.github.io/webidl/#LegacyNamespace + */ +IdlInterface.prototype.get_legacy_namespace = function() +{ + var legacyNamespace = this.extAttrs.find(function(attribute) { + return attribute.name === "LegacyNamespace"; + }); + return legacyNamespace ? legacyNamespace.rhs.value : undefined; +}; + +IdlInterface.prototype.get_interface_object_owner = function() +{ + var legacyNamespace = this.get_legacy_namespace(); + return legacyNamespace ? self[legacyNamespace] : self; +}; + +IdlInterface.prototype.assert_interface_object_exists = function() +{ + var owner = this.get_legacy_namespace() || "self"; + assert_own_property(self[owner], this.name, owner + " does not have own property " + format_value(this.name)); +}; + +IdlInterface.prototype.get_interface_object = function() { + if (this.has_extended_attribute("NoInterfaceObject")) { + throw new IdlHarnessError(this.name + " has no interface object due to NoInterfaceObject"); + } + + return this.get_interface_object_owner()[this.name]; +}; + +IdlInterface.prototype.get_qualified_name = function() { + // https://heycam.github.io/webidl/#qualified-name + var legacyNamespace = this.get_legacy_namespace(); + if (legacyNamespace) { + return legacyNamespace + "." + this.name; + } + return this.name; +}; + IdlInterface.prototype.has_to_json_regular_operation = function() { return this.members.some(function(m) { return m.is_to_json_regular_operation(); @@ -1436,9 +1492,8 @@ // TODO: Should we test here that the property is actually writable // etc., or trust getOwnPropertyDescriptor? - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); - var desc = Object.getOwnPropertyDescriptor(self, this.name); + this.assert_interface_object_exists(); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object_owner(), this.name); assert_false("get" in desc, "self's property " + format_value(this.name) + " should not have a getter"); assert_false("set" in desc, "self's property " + format_value(this.name) + " should not have a setter"); assert_true(desc.writable, "self's property " + format_value(this.name) + " should be writable"); @@ -1448,7 +1503,7 @@ if (this.is_callback()) { // "The internal [[Prototype]] property of an interface object for // a callback interface must be the Function.prototype object." - assert_equals(Object.getPrototypeOf(self[this.name]), Function.prototype, + assert_equals(Object.getPrototypeOf(this.get_interface_object()), Function.prototype, "prototype of self's property " + format_value(this.name) + " is not Object.prototype"); return; @@ -1478,24 +1533,19 @@ // ES6 (rev 30) 19.1.3.6: // "Else, if O has a [[Call]] internal method, then let builtinTag be // "Function"." - assert_class_string(self[this.name], "Function", "class string of " + this.name); + assert_class_string(this.get_interface_object(), "Function", "class string of " + this.name); // "The [[Prototype]] internal property of an interface object for a // non-callback interface is determined as follows:" - var prototype = Object.getPrototypeOf(self[this.name]); + var prototype = Object.getPrototypeOf(this.get_interface_object()); if (this.base) { // "* If the interface inherits from some other interface, the // value of [[Prototype]] is the interface object for that other // interface." - var has_interface_object = - !this.array - .members[this.base] - .has_extended_attribute("NoInterfaceObject"); - if (has_interface_object) { - assert_own_property(self, this.base, - 'should inherit from ' + this.base + - ', but self has no such property'); - assert_equals(prototype, self[this.base], + var inherited_interface = this.array.members[this.base]; + if (!inherited_interface.has_extended_attribute("NoInterfaceObject")) { + inherited_interface.assert_interface_object_exists(); + assert_equals(prototype, inherited_interface.get_interface_object(), 'prototype of ' + this.name + ' is not ' + this.base); } @@ -1513,12 +1563,13 @@ // // "If I was not declared with a [Constructor] extended attribute, // then throw a TypeError." + var interface_object = this.get_interface_object(); assert_throws(new TypeError(), function() { - self[this.name](); - }.bind(this), "interface object didn't throw TypeError when called as a function"); + interface_object(); + }, "interface object didn't throw TypeError when called as a function"); assert_throws(new TypeError(), function() { - new self[this.name](); - }.bind(this), "interface object didn't throw TypeError when called as a constructor"); + new interface_object(); + }, "interface object didn't throw TypeError when called as a constructor"); } }.bind(this), this.name + " interface: existence and properties of interface object"); @@ -1527,15 +1578,14 @@ // This function tests WebIDL as of 2014-10-25. // https://heycam.github.io/webidl/#es-interface-call - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); // "Interface objects for non-callback interfaces MUST have a // property named “length” with attributes { [[Writable]]: false, // [[Enumerable]]: false, [[Configurable]]: true } whose value is // a Number." - assert_own_property(self[this.name], "length"); - var desc = Object.getOwnPropertyDescriptor(self[this.name], "length"); + assert_own_property(this.get_interface_object(), "length"); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), "length"); assert_false("get" in desc, this.name + ".length should not have a getter"); assert_false("set" in desc, this.name + ".length should not have a setter"); assert_false(desc.writable, this.name + ".length should not be writable"); @@ -1545,7 +1595,7 @@ var constructors = this.extAttrs .filter(function(attr) { return attr.name == "Constructor"; }); var expected_length = minOverloadLength(constructors); - assert_equals(self[this.name].length, expected_length, "wrong value for " + this.name + ".length"); + assert_equals(this.get_interface_object().length, expected_length, "wrong value for " + this.name + ".length"); }.bind(this), this.name + " interface object length"); } @@ -1554,22 +1604,21 @@ // This function tests WebIDL as of 2015-11-17. // https://heycam.github.io/webidl/#interface-object - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); // "All interface objects must have a property named “name” with // attributes { [[Writable]]: false, [[Enumerable]]: false, // [[Configurable]]: true } whose value is the identifier of the // corresponding interface." - assert_own_property(self[this.name], "name"); - var desc = Object.getOwnPropertyDescriptor(self[this.name], "name"); + assert_own_property(this.get_interface_object(), "name"); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), "name"); assert_false("get" in desc, this.name + ".name should not have a getter"); assert_false("set" in desc, this.name + ".name should not have a setter"); assert_false(desc.writable, this.name + ".name should not be writable"); assert_false(desc.enumerable, this.name + ".name should not be enumerable"); assert_true(desc.configurable, this.name + ".name should be configurable"); - assert_equals(self[this.name].name, this.name, "wrong value for " + this.name + ".name"); + assert_equals(this.get_interface_object().name, this.name, "wrong value for " + this.name + ".name"); }.bind(this), this.name + " interface object name"); } @@ -1608,9 +1657,9 @@ if (exposed_in(exposure_set(this, this.exposureSet)) && 'document' in self) { for (alias of aliases) { assert_true(alias in self, alias + " should exist"); - assert_equals(self[alias], self[this.name], "self." + alias + " should be the same value as self." + this.name); + assert_equals(self[alias], this.get_interface_object(), "self." + alias + " should be the same value as self." + this.get_qualified_name()); var desc = Object.getOwnPropertyDescriptor(self, alias); - assert_equals(desc.value, self[this.name], "wrong value in " + alias + " property descriptor"); + assert_equals(desc.value, this.get_interface_object(), "wrong value in " + alias + " property descriptor"); assert_true(desc.writable, alias + " should be writable"); assert_false(desc.enumerable, alias + " should not be enumerable"); assert_true(desc.configurable, alias + " should be configurable"); @@ -1625,7 +1674,122 @@ }.bind(this), this.name + " interface: legacy window alias"); } - // TODO: Test named constructors if I find any interfaces that have them. + + if (this.has_extended_attribute("NamedConstructor")) { + var constructors = this.extAttrs + .filter(function(attr) { return attr.name == "NamedConstructor"; }); + if (constructors.length !== 1) { + throw new IdlHarnessError("Internal error: missing support for multiple NamedConstructor extended attributes"); + } + var constructor = constructors[0]; + var min_length = minOverloadLength([constructor]); + + subsetTestByKey(this.name, test, function() + { + // This function tests WebIDL as of 2019-01-14. + + // "for every [NamedConstructor] extended attribute on an exposed + // interface, a corresponding property must exist on the ECMAScript + // global object. The name of the property is the + // [NamedConstructor]'s identifier, and its value is an object + // called a named constructor, ... . The property has the attributes + // { [[Writable]]: true, [[Enumerable]]: false, + // [[Configurable]]: true }." + var name = constructor.rhs.value; + assert_own_property(self, name); + var desc = Object.getOwnPropertyDescriptor(self, name); + assert_equals(desc.value, self[name], "wrong value in " + name + " property descriptor"); + assert_true(desc.writable, name + " should be writable"); + assert_false(desc.enumerable, name + " should not be enumerable"); + assert_true(desc.configurable, name + " should be configurable"); + assert_false("get" in desc, name + " should not have a getter"); + assert_false("set" in desc, name + " should not have a setter"); + }.bind(this), this.name + " interface: named constructor"); + + subsetTestByKey(this.name, test, function() + { + // This function tests WebIDL as of 2019-01-14. + + // "2. Let F be ! CreateBuiltinFunction(realm, steps, + // realm.[[Intrinsics]].[[%FunctionPrototype%]])." + var name = constructor.rhs.value; + var value = self[name]; + assert_equals(typeof value, "function", "type of value in " + name + " property descriptor"); + assert_not_equals(value, this.get_interface_object(), "wrong value in " + name + " property descriptor"); + assert_equals(Object.getPrototypeOf(value), Function.prototype, "wrong value for " + name + "'s prototype"); + }.bind(this), this.name + " interface: named constructor object"); + + subsetTestByKey(this.name, test, function() + { + // This function tests WebIDL as of 2019-01-14. + + // "7. Let proto be the interface prototype object of interface I + // in realm. + // "8. Perform ! DefinePropertyOrThrow(F, "prototype", + // PropertyDescriptor{ + // [[Value]]: proto, [[Writable]]: false, + // [[Enumerable]]: false, [[Configurable]]: false + // })." + var name = constructor.rhs.value; + var expected = this.get_interface_object().prototype; + var desc = Object.getOwnPropertyDescriptor(self[name], "prototype"); + assert_equals(desc.value, expected, "wrong value for " + name + ".prototype"); + assert_false(desc.writable, "prototype should not be writable"); + assert_false(desc.enumerable, "prototype should not be enumerable"); + assert_false(desc.configurable, "prototype should not be configurable"); + assert_false("get" in desc, "prototype should not have a getter"); + assert_false("set" in desc, "prototype should not have a setter"); + }.bind(this), this.name + " interface: named constructor prototype property"); + + subsetTestByKey(this.name, test, function() + { + // This function tests WebIDL as of 2019-01-14. + + // "3. Perform ! SetFunctionName(F, id)." + var name = constructor.rhs.value; + var desc = Object.getOwnPropertyDescriptor(self[name], "name"); + assert_equals(desc.value, name, "wrong value for " + name + ".name"); + assert_false(desc.writable, "name should not be writable"); + assert_false(desc.enumerable, "name should not be enumerable"); + assert_true(desc.configurable, "name should be configurable"); + assert_false("get" in desc, "name should not have a getter"); + assert_false("set" in desc, "name should not have a setter"); + }.bind(this), this.name + " interface: named constructor name"); + + subsetTestByKey(this.name, test, function() + { + // This function tests WebIDL as of 2019-01-14. + + // "4. Initialize S to the effective overload set for constructors + // with identifier id on interface I and with argument count 0. + // "5. Let length be the length of the shortest argument list of + // the entries in S. + // "6. Perform ! SetFunctionLength(F, length)." + var name = constructor.rhs.value; + var desc = Object.getOwnPropertyDescriptor(self[name], "length"); + assert_equals(desc.value, min_length, "wrong value for " + name + ".length"); + assert_false(desc.writable, "length should not be writable"); + assert_false(desc.enumerable, "length should not be enumerable"); + assert_true(desc.configurable, "length should be configurable"); + assert_false("get" in desc, "length should not have a getter"); + assert_false("set" in desc, "length should not have a setter"); + }.bind(this), this.name + " interface: named constructor length"); + + subsetTestByKey(this.name, test, function() + { + // This function tests WebIDL as of 2019-01-14. + + // "1. Let steps be the following steps: + // " 1. If NewTarget is undefined, then throw a TypeError." + var name = constructor.rhs.value; + var args = constructor.arguments.map(function(arg) { + return create_suitable_object(arg.idlType); + }); + assert_throws(new TypeError(), function() { + self[name](...args); + }.bind(this)); + }.bind(this), this.name + " interface: named constructor without 'new'"); + } subsetTestByKey(this.name, test, function() { @@ -1636,11 +1800,10 @@ return; } - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); if (this.is_callback()) { - assert_false("prototype" in self[this.name], + assert_false("prototype" in this.get_interface_object(), this.name + ' should not have a "prototype" property'); return; } @@ -1652,9 +1815,9 @@ // properties that correspond to the regular attributes and regular // operations defined on the interface, and is described in more detail // in section 4.5.4 below." - assert_own_property(self[this.name], "prototype", + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); - var desc = Object.getOwnPropertyDescriptor(self[this.name], "prototype"); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), "prototype"); assert_false("get" in desc, this.name + ".prototype should not have a getter"); assert_false("set" in desc, this.name + ".prototype should not have a setter"); assert_false(desc.writable, this.name + ".prototype should not be writable"); @@ -1687,38 +1850,39 @@ // object %ErrorPrototype%." // if (this.name === "Window") { - assert_class_string(Object.getPrototypeOf(self[this.name].prototype), + assert_class_string(Object.getPrototypeOf(this.get_interface_object().prototype), 'WindowProperties', 'Class name for prototype of Window' + '.prototype is not "WindowProperties"'); } else { - var inherit_interface, inherit_interface_has_interface_object; + var inherit_interface, inherit_interface_interface_object; if (this.base) { inherit_interface = this.base; - inherit_interface_has_interface_object = - !this.array - .members[inherit_interface] - .has_extended_attribute("NoInterfaceObject"); + var parent = this.array.members[inherit_interface]; + if (!parent.has_extended_attribute("NoInterfaceObject")) { + parent.assert_interface_object_exists(); + inherit_interface_interface_object = parent.get_interface_object(); + } } else if (this.name === "DOMException") { inherit_interface = 'Error'; - inherit_interface_has_interface_object = true; + inherit_interface_interface_object = self.Error; } else { inherit_interface = 'Object'; - inherit_interface_has_interface_object = true; + inherit_interface_interface_object = self.Object; } - if (inherit_interface_has_interface_object) { - assert_own_property(self, inherit_interface, - 'should inherit from ' + inherit_interface + ', but self has no such property'); - assert_own_property(self[inherit_interface], 'prototype', + if (inherit_interface_interface_object) { + assert_not_equals(inherit_interface_interface_object, undefined, + 'should inherit from ' + inherit_interface + ', but there is no such property'); + assert_own_property(inherit_interface_interface_object, 'prototype', 'should inherit from ' + inherit_interface + ', but that object has no "prototype" property'); - assert_equals(Object.getPrototypeOf(self[this.name].prototype), - self[inherit_interface].prototype, + assert_equals(Object.getPrototypeOf(this.get_interface_object().prototype), + inherit_interface_interface_object.prototype, 'prototype of ' + this.name + '.prototype is not ' + inherit_interface + '.prototype'); } else { // We can't test that we get the correct object, because this is the // only way to get our hands on it. We only test that its class // string, at least, is correct. - assert_class_string(Object.getPrototypeOf(self[this.name].prototype), + assert_class_string(Object.getPrototypeOf(this.get_interface_object().prototype), inherit_interface + 'Prototype', 'Class name for prototype of ' + this.name + '.prototype is not "' + inherit_interface + 'Prototype"'); @@ -1726,20 +1890,20 @@ } // "The class string of an interface prototype object is the - // concatenation of the interface’s identifier and the string + // concatenation of the interface’s qualified identifier and the string // “Prototype”." // Skip these tests for now due to a specification issue about // prototype name. // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28244 - // assert_class_string(self[this.name].prototype, this.name + "Prototype", + // assert_class_string(this.get_interface_object().prototype, this.get_qualified_name() + "Prototype", // "class string of " + this.name + ".prototype"); // String() should end up calling {}.toString if nothing defines a // stringifier. if (!this.has_stringifier()) { - // assert_equals(String(self[this.name].prototype), "[object " + this.name + "Prototype]", + // assert_equals(String(this.get_interface_object().prototype), "[object " + this.get_qualified_name() + "Prototype]", // "String(" + this.name + ".prototype)"); } }.bind(this), this.name + " interface: existence and properties of interface prototype object"); @@ -1751,7 +1915,7 @@ // prototype exotic object." // https://heycam.github.io/webidl/#interface-prototype-object if (this.is_global()) { - this.test_immutable_prototype("interface prototype object", self[this.name].prototype); + this.test_immutable_prototype("interface prototype object", this.get_interface_object().prototype); } subsetTestByKey(this.name, test, function() @@ -1760,16 +1924,15 @@ return; } - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); if (this.is_callback()) { - assert_false("prototype" in self[this.name], + assert_false("prototype" in this.get_interface_object(), this.name + ' should not have a "prototype" property'); return; } - assert_own_property(self[this.name], "prototype", + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); // "If the [NoInterfaceObject] extended attribute was not specified on @@ -1777,15 +1940,15 @@ // property named “constructor” with attributes { [[Writable]]: true, // [[Enumerable]]: false, [[Configurable]]: true } whose value is a // reference to the interface object for the interface." - assert_own_property(self[this.name].prototype, "constructor", + assert_own_property(this.get_interface_object().prototype, "constructor", this.name + '.prototype does not have own property "constructor"'); - var desc = Object.getOwnPropertyDescriptor(self[this.name].prototype, "constructor"); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object().prototype, "constructor"); assert_false("get" in desc, this.name + ".prototype.constructor should not have a getter"); assert_false("set" in desc, this.name + ".prototype.constructor should not have a setter"); assert_true(desc.writable, this.name + ".prototype.constructor should be writable"); assert_false(desc.enumerable, this.name + ".prototype.constructor should not be enumerable"); assert_true(desc.configurable, this.name + ".prototype.constructor should be configurable"); - assert_equals(self[this.name].prototype.constructor, self[this.name], + assert_equals(this.get_interface_object().prototype.constructor, this.get_interface_object(), this.name + '.prototype.constructor is not the same object as ' + this.name); }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s "constructor" property'); @@ -1796,16 +1959,15 @@ return; } - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); if (this.is_callback()) { - assert_false("prototype" in self[this.name], + assert_false("prototype" in this.get_interface_object(), this.name + ' should not have a "prototype" property'); return; } - assert_own_property(self[this.name], "prototype", + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); // If the interface has any member declared with the [Unscopable] extended @@ -1814,7 +1976,7 @@ // { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }, // and whose value is an object created as follows... var unscopables = this.get_unscopables().map(m => m.name); - var proto = self[this.name].prototype; + var proto = this.get_interface_object().prototype; if (unscopables.length != 0) { assert_own_property( proto, Symbol.unscopables, @@ -1845,7 +2007,7 @@ this.name + '.prototype[Symbol.unscopables] has unexpected property "' + prop + '"'); } } else { - assert_equals(Object.getOwnPropertyDescriptor(self[this.name].prototype, Symbol.unscopables), + assert_equals(Object.getOwnPropertyDescriptor(this.get_interface_object().prototype, Symbol.unscopables), undefined, this.name + '.prototype should not have @@unscopables'); } @@ -1962,21 +2124,20 @@ subsetTestByKey(this.name, test, function() { - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); // "For each constant defined on an interface A, there must be // a corresponding property on the interface object, if it // exists." - assert_own_property(self[this.name], member.name); + assert_own_property(this.get_interface_object(), member.name); // "The value of the property is that which is obtained by // converting the constant’s IDL value to an ECMAScript // value." - assert_equals(self[this.name][member.name], constValue(member.value), + assert_equals(this.get_interface_object()[member.name], constValue(member.value), "property has wrong value"); // "The property has attributes { [[Writable]]: false, // [[Enumerable]]: true, [[Configurable]]: false }." - var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), member.name); assert_false("get" in desc, "property should not have a getter"); assert_false("set" in desc, "property should not have a setter"); assert_false(desc.writable, "property should not be writable"); @@ -1988,22 +2149,21 @@ // exist on the interface prototype object." subsetTestByKey(this.name, test, function() { - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); if (this.is_callback()) { - assert_false("prototype" in self[this.name], + assert_false("prototype" in this.get_interface_object(), this.name + ' should not have a "prototype" property'); return; } - assert_own_property(self[this.name], "prototype", + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); - assert_own_property(self[this.name].prototype, member.name); - assert_equals(self[this.name].prototype[member.name], constValue(member.value), + assert_own_property(this.get_interface_object().prototype, member.name); + assert_equals(this.get_interface_object().prototype[member.name], constValue(member.value), "property has wrong value"); - var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), member.name); assert_false("get" in desc, "property should not have a getter"); assert_false("set" in desc, "property should not have a setter"); assert_false(desc.writable, "property should not be writable"); @@ -2026,13 +2186,12 @@ return; } - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); - assert_own_property(self[this.name], "prototype", + this.assert_interface_object_exists(); + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); if (member["static"]) { - assert_own_property(self[this.name], member.name, + assert_own_property(this.get_interface_object(), member.name, "The interface object must have a property " + format_value(member.name)); a_test.done(); @@ -2045,7 +2204,7 @@ assert_own_property(self, member.name, "The global object must have a property " + format_value(member.name)); - assert_false(member.name in self[this.name].prototype, + assert_false(member.name in this.get_interface_object().prototype, "The prototype object should not have a property " + format_value(member.name)); @@ -2073,34 +2232,34 @@ // since it will call done() on a_test. this.do_interface_attribute_asserts(self, member, a_test); } else { - assert_true(member.name in self[this.name].prototype, + assert_true(member.name in this.get_interface_object().prototype, "The prototype object must have a property " + format_value(member.name)); if (!member.has_extended_attribute("LenientThis")) { if (member.idlType.generic !== "Promise") { assert_throws(new TypeError(), function() { - self[this.name].prototype[member.name]; + this.get_interface_object().prototype[member.name]; }.bind(this), "getting property on prototype object must throw TypeError"); // do_interface_attribute_asserts must be the last thing we // do, since it will call done() on a_test. - this.do_interface_attribute_asserts(self[this.name].prototype, member, a_test); + this.do_interface_attribute_asserts(this.get_interface_object().prototype, member, a_test); } else { promise_rejects(a_test, new TypeError(), - self[this.name].prototype[member.name]) + this.get_interface_object().prototype[member.name]) .then(function() { // do_interface_attribute_asserts must be the last // thing we do, since it will call done() on a_test. - this.do_interface_attribute_asserts(self[this.name].prototype, + this.do_interface_attribute_asserts(this.get_interface_object().prototype, member, a_test); }.bind(this)); } } else { - assert_equals(self[this.name].prototype[member.name], undefined, + assert_equals(this.get_interface_object().prototype[member.name], undefined, "getting property on prototype object must return undefined"); // do_interface_attribute_asserts must be the last thing we do, // since it will call done() on a_test. - this.do_interface_attribute_asserts(self[this.name].prototype, member, a_test); + this.do_interface_attribute_asserts(this.get_interface_object().prototype, member, a_test); } } }.bind(this)); @@ -2125,17 +2284,16 @@ return; } - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); if (this.is_callback()) { - assert_false("prototype" in self[this.name], + assert_false("prototype" in this.get_interface_object(), this.name + ' should not have a "prototype" property'); a_test.done(); return; } - assert_own_property(self[this.name], "prototype", + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); // "For each unique identifier of an exposed operation defined on the @@ -2150,9 +2308,9 @@ // "* If the operation is static, then the property exists on the // interface object." if (member["static"]) { - assert_own_property(self[this.name], member.name, + assert_own_property(this.get_interface_object(), member.name, "interface object missing static operation"); - memberHolderObject = self[this.name]; + memberHolderObject = this.get_interface_object(); // "* Otherwise, [...] if the interface was declared with the [Global] // extended attribute, then the property exists // on every object that implements the interface." @@ -2163,9 +2321,9 @@ // "* Otherwise, the property exists solely on the interface’s // interface prototype object." } else { - assert_own_property(self[this.name].prototype, member.name, + assert_own_property(this.get_interface_object().prototype, member.name, "interface prototype object missing non-static operation"); - memberHolderObject = self[this.name].prototype; + memberHolderObject = this.get_interface_object().prototype; } this.do_member_unscopable_asserts(member); this.do_member_operation_asserts(memberHolderObject, member, a_test); @@ -2180,7 +2338,7 @@ return; } - var unscopables = self[this.name].prototype[Symbol.unscopables]; + var unscopables = this.get_interface_object().prototype[Symbol.unscopables]; var prop = member.name; var propDesc = Object.getOwnPropertyDescriptor(unscopables, prop); assert_equals(typeof propDesc, "object", @@ -2266,22 +2424,7 @@ } } -IdlInterface.prototype.add_iterable_members = function(member) -{ - this.members.push(new IdlInterfaceMember( - { type: "operation", name: "entries", idlType: "iterator", arguments: []})); - this.members.push(new IdlInterfaceMember( - { type: "operation", name: "keys", idlType: "iterator", arguments: []})); - this.members.push(new IdlInterfaceMember( - { type: "operation", name: "values", idlType: "iterator", arguments: []})); - this.members.push(new IdlInterfaceMember( - { type: "operation", name: "forEach", idlType: "void", - arguments: - [{ name: "callback", idlType: {idlType: "function"}}, - { name: "thisValue", idlType: {idlType: "any"}, optional: true}]})); -}; - -IdlInterface.prototype.test_to_json_operation = function(memberHolderObject, member) { +IdlInterface.prototype.test_to_json_operation = function(desc, memberHolderObject, member) { var instanceName = memberHolderObject && memberHolderObject.constructor.name || member.name + " object"; if (member.has_extended_attribute("Default")) { @@ -2297,39 +2440,40 @@ this.array.assert_type_is(json[k], type); delete json[k]; }, this); - }.bind(this), "Test default toJSON operation of " + instanceName); + }.bind(this), this.name + " interface: default toJSON operation on " + desc); } else { subsetTestByKey(this.name, test, function() { assert_true(this.array.is_json_type(member.idlType), JSON.stringify(member.idlType) + " is not an appropriate return value for the toJSON operation of " + instanceName); this.array.assert_type_is(memberHolderObject.toJSON(), member.idlType); - }.bind(this), "Test toJSON operation of " + instanceName); + }.bind(this), this.name + " interface: toJSON operation on " + desc); } }; IdlInterface.prototype.test_member_iterable = function(member) { - var interfaceName = this.name; - var isPairIterator = member.idlType.length === 2; subsetTestByKey(this.name, test, function() { - var descriptor = Object.getOwnPropertyDescriptor(self[interfaceName].prototype, Symbol.iterator); - assert_true(descriptor.writable, "property should be writable"); - assert_true(descriptor.configurable, "property should be configurable"); - assert_false(descriptor.enumerable, "property should not be enumerable"); - assert_equals(self[interfaceName].prototype[Symbol.iterator].name, isPairIterator ? "entries" : "values", "@@iterator function does not have the right name"); - }, "Testing Symbol.iterator property of iterable interface " + interfaceName); + var isPairIterator = member.idlType.length === 2; + var proto = this.get_interface_object().prototype; + var descriptor = Object.getOwnPropertyDescriptor(proto, Symbol.iterator); - if (isPairIterator) { - subsetTestByKey(this.name, test, function() { - assert_equals(self[interfaceName].prototype[Symbol.iterator], self[interfaceName].prototype["entries"], "entries method is not the same as @@iterator"); - }, "Testing pair iterable interface " + interfaceName); - } else { - subsetTestByKey(this.name, test, function() { - ["entries", "keys", "values", "forEach", Symbol.Iterator].forEach(function(property) { - assert_equals(self[interfaceName].prototype[property], Array.prototype[property], property + " function is not the same as Array one"); - }); - }, "Testing value iterable interface " + interfaceName); - } + assert_true(descriptor.writable, "@@iterator property should be writable"); + assert_true(descriptor.configurable, "@@iterator property should be configurable"); + assert_false(descriptor.enumerable, "@@iterator property should not be enumerable"); + assert_equals(typeof descriptor.value, "function", "@@iterator property should be a function"); + assert_equals(descriptor.value.length, 0, "@@iterator function object length should be 0"); + assert_equals(descriptor.value.name, isPairIterator ? "entries" : "values", "@@iterator function object should have the right name"); + + if (isPairIterator) { + assert_equals(proto["entries"], proto[Symbol.iterator], "entries method should be the same as @@iterator method"); + } else { + assert_equals(proto[Symbol.iterator], Array.prototype[Symbol.iterator], "@@iterator method should be the same as Array prototype's"); + ["entries", "keys", "values", "forEach", Symbol.iterator].forEach(function(property) { + var propertyName = property === Symbol.iterator ? "@@iterator" : property; + assert_equals(proto[property], Array.prototype[property], propertyName + " method should be the same as Array prototype's"); + }.bind(this)); + } + }.bind(this), this.name + " interface: iterable<" + member.idlType.map(function(t) { return t.idlType; }).join(", ") + ">"); }; IdlInterface.prototype.test_member_stringifier = function(member) @@ -2340,21 +2484,20 @@ return; } - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); if (this.is_callback()) { - assert_false("prototype" in self[this.name], + assert_false("prototype" in this.get_interface_object(), this.name + ' should not have a "prototype" property'); return; } - assert_own_property(self[this.name], "prototype", + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); // ". . . the property exists on the interface prototype object." - var interfacePrototypeObject = self[this.name].prototype; - assert_own_property(self[this.name].prototype, "toString", + var interfacePrototypeObject = this.get_interface_object().prototype; + assert_own_property(interfacePrototypeObject, "toString", "interface prototype object missing non-static operation"); var stringifierUnforgeable = member.isUnforgeable; @@ -2380,7 +2523,7 @@ // "Let O be the result of calling ToObject on the this value." assert_throws(new TypeError(), function() { - self[this.name].prototype.toString.apply(null, []); + interfacePrototypeObject.toString.apply(null, []); }, "calling stringifier with this = null didn't throw TypeError"); // "If O is not an object that implements the interface on which the @@ -2389,7 +2532,7 @@ // TODO: Test a platform object that implements some other // interface. (Have to be sure to get inheritance right.) assert_throws(new TypeError(), function() { - self[this.name].prototype.toString.apply({}, []); + interfacePrototypeObject.toString.apply({}, []); }, "calling stringifier with this = {} didn't throw TypeError"); }.bind(this), this.name + " interface: stringifier"); }; @@ -2399,19 +2542,6 @@ for (var i = 0; i < this.members.length; i++) { var member = this.members[i]; - switch (member.type) { - case "iterable": - this.add_iterable_members(member); - break; - // TODO: add setlike and maplike handling. - default: - break; - } - } - - for (var i = 0; i < this.members.length; i++) - { - var member = this.members[i]; if (member.untested) { continue; } @@ -2419,10 +2549,10 @@ if (!exposed_in(exposure_set(member, this.exposureSet))) { subsetTestByKey(this.name, test, function() { // It's not exposed, so we shouldn't find it anywhere. - assert_false(member.name in self[this.name], + assert_false(member.name in this.get_interface_object(), "The interface object must not have a property " + format_value(member.name)); - assert_false(member.name in self[this.name].prototype, + assert_false(member.name in this.get_interface_object().prototype, "The prototype object must not have a property " + format_value(member.name)); }.bind(this), this.name + " interface: member " + member.name); @@ -2538,9 +2668,8 @@ { assert_equals(exception, null, "Unexpected exception when evaluating object"); assert_equals(typeof obj, expected_typeof, "wrong typeof object"); - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); - assert_own_property(self[this.name], "prototype", + this.assert_interface_object_exists(); + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); // "The value of the internal [[Prototype]] property of the @@ -2548,22 +2677,22 @@ // interface from the platform object’s associated global // environment." assert_equals(Object.getPrototypeOf(obj), - self[this.name].prototype, + this.get_interface_object().prototype, desc + "'s prototype is not " + this.name + ".prototype"); }.bind(this), this.name + " must be primary interface of " + desc); } // "The class string of a platform object that implements one or more - // interfaces must be the identifier of the primary interface of the + // interfaces must be the qualified name of the primary interface of the // platform object." subsetTestByKey(this.name, test, function() { assert_equals(exception, null, "Unexpected exception when evaluating object"); assert_equals(typeof obj, expected_typeof, "wrong typeof object"); - assert_class_string(obj, this.name, "class string of " + desc); + assert_class_string(obj, this.get_qualified_name(), "class string of " + desc); if (!this.has_stringifier()) { - assert_equals(String(obj), "[object " + this.name + "]", "String(" + desc + ")"); + assert_equals(String(obj), "[object " + this.get_qualified_name() + "]", "String(" + desc + ")"); } }.bind(this), "Stringification of " + desc); }; @@ -2708,7 +2837,7 @@ } if (member.is_to_json_regular_operation()) { - this.test_to_json_operation(obj, member); + this.test_to_json_operation(desc, obj, member); } } };
diff --git a/third_party/blink/web_tests/resources/testdriver.js b/third_party/blink/web_tests/resources/testdriver.js index 8ffd7650..031be1b 100644 --- a/third_party/blink/web_tests/resources/testdriver.js +++ b/third_party/blink/web_tests/resources/testdriver.js
@@ -194,30 +194,87 @@ */ action_sequence: function(actions) { return window.test_driver_internal.action_sequence(actions); + }, + + /** + * Generates a test report on the current page + * + * The generate_test_report function generates a report (to be observed + * by ReportingObserver) for testing purposes, as described in + * {@link https://w3c.github.io/reporting/#generate-test-report-command} + * + * @returns {Promise} fulfilled after the report is generated, or + * rejected if the report generation fails + */ + generate_test_report: function(message) { + return window.test_driver_internal.generate_test_report(message); } }; window.test_driver_internal = { /** - * Triggers a user-initiated click + * This flag should be set to `true` by any code which implements the + * internal methods defined below for automation purposes. Doing so + * allows the library to signal failure immediately when an automated + * implementation of one of the methods is not available. + */ + in_automation: false, + + /** + * Waits for a user-initiated click * * @param {Element} element - element to be clicked * @param {{x: number, y: number} coords - viewport coordinates to click at - * @returns {Promise} fulfilled after click occurs or rejected if click fails + * @returns {Promise} fulfilled after click occurs */ click: function(element, coords) { - return Promise.reject(new Error("unimplemented")); + if (this.in_automation) { + return Promise.reject(new Error('Not implemented')); + } + + return new Promise(function(resolve, reject) { + element.addEventListener("click", resolve); + }); }, /** - * Triggers a user-initiated click + * Waits for an element to receive a series of key presses * - * @param {Element} element - element to be clicked - * @param {String} keys - keys to send to the element - * @returns {Promise} fulfilled after keys are sent or rejected if click fails + * @param {Element} element - element which should receve key presses + * @param {String} keys - keys to expect + * @returns {Promise} fulfilled after keys are received or rejected if + * an incorrect key sequence is received */ send_keys: function(element, keys) { - return Promise.reject(new Error("unimplemented")); + if (this.in_automation) { + return Promise.reject(new Error('Not implemented')); + } + + return new Promise(function(resolve, reject) { + var seen = ""; + + function remove() { + element.removeEventListener("keydown", onKeyDown); + } + + function onKeyDown(event) { + if (event.key.length > 1) { + return; + } + + seen += event.key; + + if (keys.indexOf(seen) !== 0) { + reject(new Error("Unexpected key sequence: " + seen)); + remove(); + } else if (seen === keys) { + resolve(); + remove(); + } + } + + element.addEventListener("keydown", onKeyDown); + }); }, /** @@ -233,11 +290,22 @@ /** * Send a sequence of pointer actions * - * @returns {Promise} fulfilled after actions are sent, rejected if any actions + * @returns {Promise} fufilled after actions are sent, rejected if any actions * fail */ action_sequence: function(actions) { return Promise.reject(new Error("unimplemented")); + }, + + /** + * Generates a test report on the current page + * + * @param {String} message - the message to be contained in the report + * @returns {Promise} fulfilled after the report is generated, or + * rejected if the report generation fails + */ + generate_test_report: function(message) { + return Promise.reject(new Error("unimplemented")); } }; })();
diff --git a/third_party/blink/web_tests/resources/testharness.js b/third_party/blink/web_tests/resources/testharness.js index 867f88b3..d40817c 100644 --- a/third_party/blink/web_tests/resources/testharness.js +++ b/third_party/blink/web_tests/resources/testharness.js
@@ -145,9 +145,9 @@ }; WindowTestEnvironment.prototype._forEach_windows = function(callback) { - // Iterate of the the windows [self ... top, opener]. The callback is passed - // two objects, the first one is the windows object itself, the second one - // is a boolean indicating whether or not its on the same origin as the + // Iterate over the windows [self ... top, opener]. The callback is passed + // two objects, the first one is the window object itself, the second one + // is a boolean indicating whether or not it's on the same origin as the // current window. var cache = this.window_cache; if (!cache) { @@ -513,7 +513,7 @@ return new DedicatedWorkerTestEnvironment(); } - if (!('self' in global_scope)) { + if (!('location' in global_scope)) { return new ShellTestEnvironment(); } @@ -635,7 +635,7 @@ * which can make it a lot easier to test a very specific series of events, * including ensuring that unexpected events are not fired at any point. */ - function EventWatcher(test, watchedNode, eventTypes) + function EventWatcher(test, watchedNode, eventTypes, timeoutPromise) { if (typeof eventTypes == 'string') { eventTypes = [eventTypes]; @@ -712,6 +712,27 @@ recordedEvents = []; } return new Promise(function(resolve, reject) { + var timeout = test.step_func(function() { + // If the timeout fires after the events have been received + // or during a subsequent call to wait_for, ignore it. + if (!waitingFor || waitingFor.resolve !== resolve) + return; + + // This should always fail, otherwise we should have + // resolved the promise. + assert_true(waitingFor.types.length == 0, + 'Timed out waiting for ' + waitingFor.types.join(', ')); + var result = recordedEvents; + recordedEvents = null; + var resolveFunc = waitingFor.resolve; + waitingFor = null; + resolveFunc(result); + }); + + if (timeoutPromise) { + timeoutPromise().then(timeout); + } + waitingFor = { types: types, resolve: resolve, @@ -754,7 +775,7 @@ } if (tests.file_is_test) { // file is test files never have asynchronous cleanup logic, - // meaning the fully-sycnronous `done` function can be used here. + // meaning the fully-synchronous `done` function can be used here. tests.tests[0].done(); } tests.end_wait(); @@ -1262,6 +1283,13 @@ } expose(assert_own_property, "assert_own_property"); + function assert_not_own_property(object, property_name, description) { + assert(!object.hasOwnProperty(property_name), + "assert_not_own_property", description, + "unexpected property ${p} is found on object", {p:property_name}); + } + expose(assert_not_own_property, "assert_not_own_property"); + function _assert_inherits(name) { return function (object, property_name, description) { @@ -1479,11 +1507,9 @@ this.index = null; this.properties = properties; - var timeout = properties.timeout ? properties.timeout : settings.test_timeout; - if (timeout !== null) { - this.timeout_length = timeout * tests.timeout_multiplier; - } else { - this.timeout_length = null; + this.timeout_length = settings.test_timeout; + if (this.timeout_length !== null) { + this.timeout_length *= tests.timeout_multiplier; } this.message = null; @@ -1541,7 +1567,7 @@ return; } this.phase = this.phases.STARTED; - //If we don't get a result before the harness times out that will be a test timout + //If we don't get a result before the harness times out that will be a test timeout this.set_status(this.TIMEOUT, "Test timed out"); tests.started = true; @@ -1897,7 +1923,9 @@ */ function RemoteContext(remote, message_target, message_filter) { this.running = true; + this.started = false; this.tests = new Array(); + this.early_exception = null; var this_obj = this; // If remote context is cross origin assigning to onerror is not @@ -1936,6 +1964,21 @@ } RemoteContext.prototype.remote_error = function(error) { + if (error.preventDefault) { + error.preventDefault(); + } + + // Defer interpretation of errors until the testing protocol has + // started and the remote test's `allow_uncaught_exception` property + // is available. + if (!this.started) { + this.early_exception = error; + } else if (!this.allow_uncaught_exception) { + this.report_uncaught(error); + } + }; + + RemoteContext.prototype.report_uncaught = function(error) { var message = error.message || String(error); var filename = (error.filename ? " " + error.filename: ""); // FIXME: Display remote error states separately from main document @@ -1943,9 +1986,14 @@ tests.set_status(tests.status.ERROR, "Error in remote" + filename + ": " + message, error.stack); + }; - if (error.preventDefault) { - error.preventDefault(); + RemoteContext.prototype.start = function(data) { + this.started = true; + this.allow_uncaught_exception = data.properties.allow_uncaught_exception; + + if (this.early_exception && !this.allow_uncaught_exception) { + this.report_uncaught(this.early_exception); } }; @@ -1995,6 +2043,7 @@ }; RemoteContext.prototype.message_handlers = { + start: RemoteContext.prototype.start, test_state: RemoteContext.prototype.test_state, result: RemoteContext.prototype.test_done, complete: RemoteContext.prototype.remote_done @@ -2107,6 +2156,9 @@ } } else if (p == "timeout_multiplier") { this.timeout_multiplier = value; + if (this.timeout_length) { + this.timeout_length *= this.timeout_multiplier; + } } } } @@ -2529,6 +2581,9 @@ Output.prototype.resolve_log = function() { var output_document; + if (this.output_node) { + return; + } if (typeof this.output_document === "function") { output_document = this.output_document.apply(undefined); } else { @@ -2539,7 +2594,7 @@ } var node = output_document.getElementById("log"); if (!node) { - if (!document.readyState == "loading") { + if (output_document.readyState === "loading") { return; } node = output_document.createElementNS("http://www.w3.org/1999/xhtml", "div"); @@ -2579,8 +2634,8 @@ if (!this.enabled) { return; } + this.resolve_log(); if (this.phase < this.HAVE_RESULTS) { - this.resolve_log(); this.phase = this.HAVE_RESULTS; } var done_count = tests.tests.length - tests.num_pending; @@ -2787,7 +2842,7 @@ /* * Template code * - * A template is just a javascript structure. An element is represented as: + * A template is just a JavaScript structure. An element is represented as: * * [tag_name, {attr_name:attr_value}, child1, child2] * @@ -2949,7 +3004,7 @@ } /* - * Utility funcions + * Utility functions */ function assert(expected_true, function_name, description, error, substitutions) { @@ -3212,7 +3267,7 @@ // Touching the postMessage prop on a window can throw if the window is // not from the same origin AND post message is not supported in that // browser. So just doing an existence test here won't do, you also need - // to wrap it in a try..cacth block. + // to wrap it in a try..catch block. try { type = typeof w.postMessage; if (type === "function") {
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index a9e9d86..f8d2d1a 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -696,6 +696,16 @@ 'fuchsia-fyi-x64-rel': 'release_trybot_fuchsia', 'fuchsia_x64': 'release_trybot_fuchsia', 'fuchsia-x64-cast': 'release_trybot_fuchsia_cast', + 'gpu-manual-try-linux-amd-rel': 'gpu_fyi_tests_release_trybot', + 'gpu-manual-try-linux-intel-dqp': 'deqp_release_trybot', + 'gpu-manual-try-linux-intel-exp': 'gpu_fyi_tests_release_trybot', + 'gpu-manual-try-linux-intel-ozn': 'gpu_fyi_tests_ozone_linux_system_gbm_libdrm_release_trybot', + 'gpu-manual-try-linux-intel-rel': 'gpu_fyi_tests_release_trybot', + 'gpu-manual-try-linux-nvidia-dbg': 'gpu_fyi_tests_debug_trybot', + 'gpu-manual-try-linux-nvidia-dqp': 'deqp_release_trybot', + 'gpu-manual-try-linux-nvidia-exp': 'gpu_fyi_tests_release_trybot', + 'gpu-manual-try-linux-nvidia-rel': 'gpu_fyi_tests_release_trybot', + 'gpu-manual-try-linux-nvidia-tsn': 'gpu_fyi_tests_release_trybot_tsan', 'layout_test_leak_detection': 'release_trybot', 'leak_detection_linux': 'release_trybot', 'linux-blink-heap-incremental-marking': 'debug_trybot_enable_blink_heap_incremental_marking', @@ -771,7 +781,19 @@ }, 'tryserver.chromium.win': { - 'gpu_manual_try_win7_nvidia_rel': 'gpu_fyi_tests_release_trybot_x86', + 'gpu-manual-try-win7-amd-dbg': 'gpu_fyi_tests_debug_trybot_x86', + 'gpu-manual-try-win7-amd-dqp': 'deqp_release_trybot_x86', + 'gpu-manual-try-win7-amd-rel': 'gpu_fyi_tests_release_trybot_x86', + 'gpu-manual-try-win7-nvidia-dqp-64': 'deqp_release_trybot', + 'gpu-manual-try-win7-nvidia-rel': 'gpu_fyi_tests_release_trybot_x86', + 'gpu-manual-try-win7-nvidia-rel-64': 'gpu_fyi_tests_release_trybot', + 'gpu-manual-try-win10-intel-dqp': 'deqp_release_trybot_x86', + 'gpu-manual-try-win10-intel-exp': 'gpu_fyi_tests_release_trybot_x86', + 'gpu-manual-try-win10-intel-rel': 'gpu_fyi_tests_release_trybot_x86', + 'gpu-manual-try-win10-nvidia-dbg': 'gpu_fyi_tests_debug_trybot_x86', + 'gpu-manual-try-win10-nvidia-dqp': 'deqp_release_trybot_x86', + 'gpu-manual-try-win10-nvidia-exp': 'gpu_fyi_tests_release_trybot_x86', + 'gpu-manual-try-win10-nvidia-rel': 'gpu_fyi_tests_release_trybot_x86', 'win7_chromium_rel_loc_exp': 'gpu_tests_release_trybot_x86_minimal_symbols_resource_whitelisting', 'win10_chromium_x64_dbg_ng': 'gpu_tests_debug_trybot', 'win10_chromium_x64_rel_ng': 'gpu_tests_release_trybot_resource_whitelisting',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 2a9fdb4..2985d30 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -22534,7 +22534,6 @@ <int value="2825" label="BuiltInModuleVirtualScroller"/> <int value="2826" label="AdClickNavigation"/> <int value="2827" label="RTCStatsRelativePacketArrivalDelay"/> - <int value="2828" label="FlexboxWithOverflowFlexItemIntrinsicSize"/> <int value="2829" label="CSSSelectorHostContextInSnapshotProfile"/> <int value="2830" label="CSSSelectorHostContextInLiveProfile"/> <int value="2831" label="ImportMap"/> @@ -31765,6 +31764,8 @@ <int value="-2133892372" label="ResamplingInputEvents:disabled"/> <int value="-2133277113" label="CCTModuleCustomHeader:disabled"/> <int value="-2132591642" label="enable-input-view"/> + <int value="-2131746498" + label="AutofillUseImprovedLabelDisambiguation:enabled"/> <int value="-2128705444" label="AssistantAppSupport:enabled"/> <int value="-2124839789" label="OmniboxUIExperimentHideSteadyStateUrlSchemeAndSubdomains:enabled"/> @@ -32298,7 +32299,6 @@ <int value="-1349826793" label="ArcInputMethod:disabled"/> <int value="-1349532167" label="enable-wifi-credential-sync"/> <int value="-1346722635" label="gesture-selection"/> - <int value="-1346288427" label="AutofillShowFullDisclosureLabel:disabled"/> <int value="-1344375439" label="ServiceWorkerPaymentApps:disabled"/> <int value="-1343259222" label="RegionalLocalesAsDisplayUI:disabled"/> <int value="-1342961844" label="InlineUpdateFlow:disabled"/> @@ -32496,6 +32496,7 @@ <int value="-1039555838" label="GamepadExtensions:enabled"/> <int value="-1037128156" label="HomeLauncherGestures:disabled"/> <int value="-1034344165" label="V8NoTurbo:disabled"/> + <int value="-1034152207" label="SendTabToSelfReceive:enabled"/> <int value="-1033738911" label="enable-mac-views-dialogs"/> <int value="-1031350684" label="PdfIsolation:disabled"/> <int value="-1029920490" label="IdleTimeSpellChecking:enabled"/> @@ -33369,7 +33370,6 @@ <int value="417709910" label="AutofillSendExperimentIdsInPaymentsRPCs:disabled"/> <int value="422307097" label="PhysicalWeb:disabled"/> - <int value="422426657" label="AutofillShowFullDisclosureLabel:enabled"/> <int value="423615350" label="enable-tab-audio-muting"/> <int value="423855924" label="enable-tab-switcher-theme-colors"/> <int value="430959979" label="SyncStandaloneTransport:disabled"/> @@ -33717,6 +33717,8 @@ <int value="1005684777" label="PictureInPicture:disabled"/> <int value="1006608931" label="ArcEnableUnifiedAudioFocus:disabled"/> <int value="1007444341" label="enable-prefixed-encrypted-media"/> + <int value="1008677979" + label="AutofillUseImprovedLabelDisambiguation:disabled"/> <int value="1012942422" label="HorizontalTabSwitcherAndroid:disabled"/> <int value="1015895665" label="drop-sync-credential:enabled"/> <int value="1017364362" label="VrIconInDaydreamHome:enabled"/> @@ -33893,6 +33895,7 @@ <int value="1277386636" label="QueryInOmnibox:disabled"/> <int value="1279584261" label="enable-carrier-switching"/> <int value="1280614081" label="show-overdraw-feedback"/> + <int value="1281553299" label="SendTabToSelfReceive:disabled"/> <int value="1283908088" label="ImprovedLanguageSettings:disabled"/> <int value="1283956865" label="force-tablet-mode"/> <int value="1283960113" label="disable-fixed-position-compositing"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 2c1a07cf..5f641b7 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -39744,6 +39744,16 @@ </summary> </histogram> +<histogram name="GoogleUpdate.InstallDetails.UpdateCohort" + expires_after="2019-06-01"> + <owner>nikunjb@chromium.org</owner> + <owner>chrome-metrics-team@google.com</owner> + <summary> + Store the hash of update cohort name as reported by Chrome Updater on + Windows. Recorded at the start of metrics service. + </summary> +</histogram> + <histogram name="GoogleUpdate.InstallerExitCode" enum="InstallStatus"> <owner>grt@chromium.org</owner> <summary> @@ -86491,6 +86501,15 @@ </summary> </histogram> +<histogram name="Platform.StatefulLifetimeWrites" units="GB" + expires_after="2020-03-07"> + <owner>asavery@chromium.org</owner> + <owner>gwendal@chromium.org</owner> + <summary> + Chrome OS stateful partition lifetime writes. Sampled once daily. + </summary> +</histogram> + <histogram name="Platform.StatefulUsage" units="%"> <owner>achuith@chromium.org</owner> <owner>omrilio@chromium.org</owner> @@ -110487,7 +110506,7 @@ </histogram> <histogram name="Signin.RefreshTokenRevocationCompleted" - enum="GaiaTokenRevocationStatus" expires_after="2019-03-31"> + enum="GaiaTokenRevocationStatus" expires_after="2021-03-31"> <owner>droger@chromium.org</owner> <owner>msarda@chromium.org</owner> <summary>
diff --git a/ui/accessibility/ax_event_generator.cc b/ui/accessibility/ax_event_generator.cc index 0fac38e..36844d9 100644 --- a/ui/accessibility/ax_event_generator.cc +++ b/ui/accessibility/ax_event_generator.cc
@@ -178,6 +178,35 @@ DCHECK_EQ(tree_, tree); switch (attr) { + case ax::mojom::StringAttribute::kAccessKey: + AddEvent(node, Event::ACCESS_KEY_CHANGED); + break; + case ax::mojom::StringAttribute::kAriaInvalidValue: + AddEvent(node, Event::INVALID_STATUS_CHANGED); + break; + case ax::mojom::StringAttribute::kAutoComplete: + AddEvent(node, Event::AUTO_COMPLETE_CHANGED); + break; + case ax::mojom::StringAttribute::kClassName: + AddEvent(node, Event::CLASS_NAME_CHANGED); + break; + case ax::mojom::StringAttribute::kDescription: + AddEvent(node, Event::DESCRIPTION_CHANGED); + break; + case ax::mojom::StringAttribute::kKeyShortcuts: + AddEvent(node, Event::KEY_SHORTCUTS_CHANGED); + break; + case ax::mojom::StringAttribute::kLanguage: + AddEvent(node, Event::LANGUAGE_CHANGED); + break; + case ax::mojom::StringAttribute::kLiveStatus: + // TODO(accessibility): tree in the midst of updates. Disallow access to + // |node|. + if (node->data().GetStringAttribute( + ax::mojom::StringAttribute::kLiveStatus) != "off" && + node->data().role != ax::mojom::Role::kAlert) + AddEvent(node, Event::LIVE_REGION_CREATED); + break; case ax::mojom::StringAttribute::kName: // If the name of the root node changes, we expect OnTreeDataChanged to // add a DOCUMENT_TITLE_CHANGED event instead. @@ -191,26 +220,12 @@ FireLiveRegionEvents(node); } break; - case ax::mojom::StringAttribute::kDescription: - AddEvent(node, Event::DESCRIPTION_CHANGED); + case ax::mojom::StringAttribute::kPlaceholder: + AddEvent(node, Event::PLACEHOLDER_CHANGED); break; case ax::mojom::StringAttribute::kValue: AddEvent(node, Event::VALUE_CHANGED); break; - case ax::mojom::StringAttribute::kAriaInvalidValue: - AddEvent(node, Event::INVALID_STATUS_CHANGED); - break; - case ax::mojom::StringAttribute::kLiveStatus: - // TODO(accessibility): tree in the midst of updates. Disallow access to - // |node|. - if (node->data().GetStringAttribute( - ax::mojom::StringAttribute::kLiveStatus) != "off" && - node->data().role != ax::mojom::Role::kAlert) - AddEvent(node, Event::LIVE_REGION_CREATED); - break; - case ax::mojom::StringAttribute::kAutoComplete: - AddEvent(node, Event::AUTO_COMPLETE_CHANGED); - break; case ax::mojom::StringAttribute::kImageAnnotation: // The image annotation is reported as part of the accessible name. AddEvent(node, Event::IMAGE_ANNOTATION_CHANGED); @@ -240,9 +255,15 @@ case ax::mojom::IntAttribute::kCheckedState: AddEvent(node, Event::CHECKED_STATE_CHANGED); break; + case ax::mojom::IntAttribute::kHierarchicalLevel: + AddEvent(node, Event::HIERARCHICAL_LEVEL_CHANGED); + break; case ax::mojom::IntAttribute::kInvalidState: AddEvent(node, Event::INVALID_STATUS_CHANGED); break; + case ax::mojom::IntAttribute::kPosInSet: + AddEvent(node, Event::POSITION_IN_SET_CHANGED); + break; case ax::mojom::IntAttribute::kRestriction: AddEvent(node, Event::STATE_CHANGED); break; @@ -254,6 +275,9 @@ // The image annotation is reported as part of the accessible name. AddEvent(node, Event::IMAGE_ANNOTATION_CHANGED); break; + case ax::mojom::IntAttribute::kSetSize: + AddEvent(node, Event::SET_SIZE_CHANGED); + break; default: AddEvent(node, Event::OTHER_ATTRIBUTE_CHANGED); break; @@ -300,7 +324,21 @@ const std::vector<int32_t>& old_value, const std::vector<int32_t>& new_value) { DCHECK_EQ(tree_, tree); - AddEvent(node, Event::OTHER_ATTRIBUTE_CHANGED); + + switch (attr) { + case ax::mojom::IntListAttribute::kDescribedbyIds: + AddEvent(node, Event::DESCRIBED_BY_CHANGED); + break; + case ax::mojom::IntListAttribute::kFlowtoIds: + AddEvent(node, Event::FLOW_TO_CHANGED); + break; + case ax::mojom::IntListAttribute::kLabelledbyIds: + AddEvent(node, Event::LABELED_BY_CHANGED); + break; + default: + AddEvent(node, Event::OTHER_ATTRIBUTE_CHANGED); + break; + } } void AXEventGenerator::OnTreeDataChanged(AXTree* tree,
diff --git a/ui/accessibility/ax_event_generator.h b/ui/accessibility/ax_event_generator.h index f68a285..72cc658 100644 --- a/ui/accessibility/ax_event_generator.h +++ b/ui/accessibility/ax_event_generator.h
@@ -22,18 +22,26 @@ class AX_EXPORT AXEventGenerator : public AXTreeObserver { public: enum class Event : int32_t { + ACCESS_KEY_CHANGED, ACTIVE_DESCENDANT_CHANGED, ALERT, AUTO_COMPLETE_CHANGED, CHECKED_STATE_CHANGED, CHILDREN_CHANGED, + CLASS_NAME_CHANGED, COLLAPSED, + DESCRIBED_BY_CHANGED, DESCRIPTION_CHANGED, DOCUMENT_SELECTION_CHANGED, DOCUMENT_TITLE_CHANGED, EXPANDED, + FLOW_TO_CHANGED, + HIERARCHICAL_LEVEL_CHANGED, IMAGE_ANNOTATION_CHANGED, INVALID_STATUS_CHANGED, + KEY_SHORTCUTS_CHANGED, + LABELED_BY_CHANGED, + LANGUAGE_CHANGED, LIVE_REGION_CHANGED, // Fired on the root of a live region. LIVE_REGION_CREATED, LIVE_REGION_NODE_CHANGED, // Fired on a node within a live region. @@ -42,12 +50,15 @@ MENU_ITEM_SELECTED, NAME_CHANGED, OTHER_ATTRIBUTE_CHANGED, + PLACEHOLDER_CHANGED, + POSITION_IN_SET_CHANGED, RELATED_NODE_CHANGED, ROLE_CHANGED, ROW_COUNT_CHANGED, SCROLL_POSITION_CHANGED, SELECTED_CHANGED, SELECTED_CHILDREN_CHANGED, + SET_SIZE_CHANGED, STATE_CHANGED, VALUE_CHANGED, };
diff --git a/ui/accessibility/ax_event_generator_unittest.cc b/ui/accessibility/ax_event_generator_unittest.cc index 850922e..92bc42e1 100644 --- a/ui/accessibility/ax_event_generator_unittest.cc +++ b/ui/accessibility/ax_event_generator_unittest.cc
@@ -20,6 +20,9 @@ for (auto targeted_event : *generator) { const char* event_name; switch (targeted_event.event_params.event) { + case AXEventGenerator::Event::ACCESS_KEY_CHANGED: + event_name = "ACCESS_KEY_CHANGED"; + break; case AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED: event_name = "ACTIVE_DESCENDANT_CHANGED"; break; @@ -32,9 +35,15 @@ case AXEventGenerator::Event::CHILDREN_CHANGED: event_name = "CHILDREN_CHANGED"; break; + case AXEventGenerator::Event::CLASS_NAME_CHANGED: + event_name = "CLASS_NAME_CHANGED"; + break; case AXEventGenerator::Event::COLLAPSED: event_name = "COLLAPSED"; break; + case AXEventGenerator::Event::DESCRIBED_BY_CHANGED: + event_name = "DESCRIBED_BY_CHANGED"; + break; case AXEventGenerator::Event::DESCRIPTION_CHANGED: event_name = "DESCRIPTION_CHANGED"; break; @@ -47,12 +56,27 @@ case AXEventGenerator::Event::EXPANDED: event_name = "EXPANDED"; break; + case AXEventGenerator::Event::FLOW_TO_CHANGED: + event_name = "FLOW_TO_CHANGED"; + break; + case AXEventGenerator::Event::HIERARCHICAL_LEVEL_CHANGED: + event_name = "HIERARCHICAL_LEVEL_CHANGED"; + break; case AXEventGenerator::Event::IMAGE_ANNOTATION_CHANGED: event_name = "IMAGE_ANNOTATION_CHANGED"; break; case AXEventGenerator::Event::INVALID_STATUS_CHANGED: event_name = "INVALID_STATUS_CHANGED"; break; + case AXEventGenerator::Event::KEY_SHORTCUTS_CHANGED: + event_name = "KEY_SHORTCUTS_CHANGED"; + break; + case AXEventGenerator::Event::LABELED_BY_CHANGED: + event_name = "LABELED_BY_CHANGED"; + break; + case AXEventGenerator::Event::LANGUAGE_CHANGED: + event_name = "LANGUAGE_CHANGED"; + break; case AXEventGenerator::Event::LIVE_REGION_CHANGED: event_name = "LIVE_REGION_CHANGED"; break; @@ -77,6 +101,12 @@ case AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED: event_name = "OTHER_ATTRIBUTE_CHANGED"; break; + case AXEventGenerator::Event::PLACEHOLDER_CHANGED: + event_name = "PLACEHOLDER_CHANGED"; + break; + case AXEventGenerator::Event::POSITION_IN_SET_CHANGED: + event_name = "POSITION_IN_SET_CHANGED"; + break; case AXEventGenerator::Event::RELATED_NODE_CHANGED: event_name = "RELATED_NODE_CHANGED"; break; @@ -95,6 +125,9 @@ case AXEventGenerator::Event::SELECTED_CHILDREN_CHANGED: event_name = "SELECTED_CHILDREN_CHANGED"; break; + case AXEventGenerator::Event::SET_SIZE_CHANGED: + event_name = "SET_SIZE_CHANGED"; + break; case AXEventGenerator::Event::STATE_CHANGED: event_name = "STATE_CHANGED"; break; @@ -685,7 +718,7 @@ ids); ASSERT_TRUE(tree.Unserialize(update)); EXPECT_EQ( - "OTHER_ATTRIBUTE_CHANGED on 2, " + "LANGUAGE_CHANGED on 2, " "OTHER_ATTRIBUTE_CHANGED on 3, " "OTHER_ATTRIBUTE_CHANGED on 4, " "OTHER_ATTRIBUTE_CHANGED on 5, " @@ -865,8 +898,10 @@ AXTreeUpdate update = initial_state; update.node_id_to_clear = 2; ASSERT_TRUE(tree.Unserialize(update)); - EXPECT_EQ("ACTIVE_DESCENDANT_CHANGED on 3, RELATED_NODE_CHANGED on 3", - DumpEvents(&event_generator)); + EXPECT_EQ( + "ACTIVE_DESCENDANT_CHANGED on 3, " + "RELATED_NODE_CHANGED on 3", + DumpEvents(&event_generator)); } TEST(AXEventGeneratorTest, ImageAnnotationChanged) { @@ -900,4 +935,129 @@ EXPECT_EQ("IMAGE_ANNOTATION_CHANGED on 1", DumpEvents(&event_generator)); } +TEST(AXEventGeneratorTest, StringPropertyChanges) { + AXTreeUpdate initial_state; + initial_state.root_id = 1; + initial_state.nodes.resize(1); + initial_state.nodes[0].id = 1; + + struct { + ax::mojom::StringAttribute id; + std::string old_value; + std::string new_value; + } attributes[] = { + {ax::mojom::StringAttribute::kAccessKey, "a", "b"}, + {ax::mojom::StringAttribute::kClassName, "a", "b"}, + {ax::mojom::StringAttribute::kKeyShortcuts, "a", "b"}, + {ax::mojom::StringAttribute::kLanguage, "a", "b"}, + {ax::mojom::StringAttribute::kPlaceholder, "a", "b"}, + }; + for (auto&& attrib : attributes) { + initial_state.nodes.push_back({}); + initial_state.nodes.back().id = initial_state.nodes.size(); + initial_state.nodes.back().AddStringAttribute(attrib.id, attrib.old_value); + initial_state.nodes[0].child_ids.push_back(initial_state.nodes.size()); + } + + AXTree tree(initial_state); + + AXEventGenerator event_generator(&tree); + int index = 1; + for (auto&& attrib : attributes) { + initial_state.nodes[index++].AddStringAttribute(attrib.id, + attrib.new_value); + } + + AXTreeUpdate update = initial_state; + EXPECT_TRUE(tree.Unserialize(update)); + EXPECT_EQ( + "ACCESS_KEY_CHANGED on 2, " + "CLASS_NAME_CHANGED on 3, " + "KEY_SHORTCUTS_CHANGED on 4, " + "LANGUAGE_CHANGED on 5, " + "PLACEHOLDER_CHANGED on 6", + DumpEvents(&event_generator)); +} + +TEST(AXEventGeneratorTest, IntPropertyChanges) { + AXTreeUpdate initial_state; + initial_state.root_id = 1; + initial_state.nodes.resize(1); + initial_state.nodes[0].id = 1; + + struct { + ax::mojom::IntAttribute id; + int old_value; + int new_value; + } attributes[] = { + {ax::mojom::IntAttribute::kHierarchicalLevel, 1, 2}, + {ax::mojom::IntAttribute::kPosInSet, 1, 2}, + {ax::mojom::IntAttribute::kSetSize, 1, 2}, + }; + for (auto&& attrib : attributes) { + initial_state.nodes.push_back({}); + initial_state.nodes.back().id = initial_state.nodes.size(); + initial_state.nodes.back().AddIntAttribute(attrib.id, attrib.old_value); + initial_state.nodes[0].child_ids.push_back(initial_state.nodes.size()); + } + + AXTree tree(initial_state); + + AXEventGenerator event_generator(&tree); + int index = 1; + for (auto&& attrib : attributes) + initial_state.nodes[index++].AddIntAttribute(attrib.id, attrib.new_value); + + AXTreeUpdate update = initial_state; + EXPECT_TRUE(tree.Unserialize(update)); + EXPECT_EQ( + "HIERARCHICAL_LEVEL_CHANGED on 2, " + "POSITION_IN_SET_CHANGED on 3, " + "SET_SIZE_CHANGED on 4", + DumpEvents(&event_generator)); +} + +TEST(AXEventGeneratorTest, IntListPropertyChanges) { + AXTreeUpdate initial_state; + initial_state.root_id = 1; + initial_state.nodes.resize(1); + initial_state.nodes[0].id = 1; + + struct { + ax::mojom::IntListAttribute id; + std::vector<int> old_value; + std::vector<int> new_value; + } attributes[] = { + {ax::mojom::IntListAttribute::kDescribedbyIds, {1}, {2}}, + {ax::mojom::IntListAttribute::kFlowtoIds, {1}, {2}}, + {ax::mojom::IntListAttribute::kLabelledbyIds, {1}, {2}}, + }; + for (auto&& attrib : attributes) { + initial_state.nodes.push_back({}); + initial_state.nodes.back().id = initial_state.nodes.size(); + initial_state.nodes.back().AddIntListAttribute(attrib.id, attrib.old_value); + initial_state.nodes[0].child_ids.push_back(initial_state.nodes.size()); + } + + AXTree tree(initial_state); + + AXEventGenerator event_generator(&tree); + int index = 1; + for (auto&& attrib : attributes) { + initial_state.nodes[index++].AddIntListAttribute(attrib.id, + attrib.new_value); + } + + AXTreeUpdate update = initial_state; + EXPECT_TRUE(tree.Unserialize(update)); + EXPECT_EQ( + "DESCRIBED_BY_CHANGED on 2, " + "FLOW_TO_CHANGED on 3, " + "LABELED_BY_CHANGED on 4, " + "RELATED_NODE_CHANGED on 2, " + "RELATED_NODE_CHANGED on 3, " + "RELATED_NODE_CHANGED on 4", + DumpEvents(&event_generator)); +} + } // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index aacf91a4..635b1a1 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -3757,7 +3757,7 @@ case UIA_ClassNamePropertyId: result->vt = VT_BSTR; - GetStringAttributeAsBstr(ax::mojom::StringAttribute::kName, + GetStringAttributeAsBstr(ax::mojom::StringAttribute::kClassName, &result->bstrVal); break;
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_win_unittest.cc index c1319fc6..004df13 100644 --- a/ui/accessibility/platform/ax_platform_node_win_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
@@ -3265,7 +3265,6 @@ EXPECT_UIA_BSTR_EQ(root_node, UIA_AriaPropertiesPropertyId, L"readonly=true;expanded=false;multiline=false;" L"multiselectable=false;required=false;setsize=2"); - EXPECT_UIA_BSTR_EQ(root_node, UIA_ClassNamePropertyId, L"fake name"); EXPECT_UIA_BSTR_EQ(root_node, UIA_CulturePropertyId, L"en-us"); EXPECT_UIA_BSTR_EQ(root_node, UIA_NamePropertyId, L"fake name"); EXPECT_UIA_INT_EQ(root_node, UIA_ControlTypePropertyId,
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn index 5a058e6..141af6a 100644 --- a/ui/aura/BUILD.gn +++ b/ui/aura/BUILD.gn
@@ -187,7 +187,6 @@ "//skia", "//ui/base", "//ui/base/clipboard", - "//ui/base/ime", "//ui/display", "//ui/events", "//ui/events:dom_keyboard_layout", @@ -202,6 +201,7 @@ ] public_deps = [ + "//ui/base/ime", "//ui/compositor", ]
diff --git a/ui/aura/native_window_occlusion_tracker_win.cc b/ui/aura/native_window_occlusion_tracker_win.cc index e2500b1f..aed87f55 100644 --- a/ui/aura/native_window_occlusion_tracker_win.cc +++ b/ui/aura/native_window_occlusion_tracker_win.cc
@@ -535,8 +535,8 @@ void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator:: ProcessEventHookCallback(DWORD event, HWND hwnd, - LONG idObject, - LONG idChild) { + LONG id_object, + LONG id_child) { // Can't do DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_) here. See // comment before call to PostTask below as to why. @@ -545,6 +545,12 @@ // events. if (!hwnd) return; + + // We only care about events for window objects. In particular, we don't care + // about OBJID_CARET, which is spammy. + if (id_object != OBJID_WINDOW) + return; + // Don't continually calculate occlusion while a window is moving, but rather // once at the beginning and once at the end. if (event == EVENT_SYSTEM_MOVESIZESTART) { @@ -561,6 +567,7 @@ // that case, we want to go back to calculating occlusion. window_is_moving_ = false; } + // ProcessEventHookCallback is called from the task_runner's PeekMessage // call, on the task runner's thread, but before the task_tracker thread sets // up the thread sequence. In order to prevent DCHECK failures with the
diff --git a/ui/aura/native_window_occlusion_tracker_win.h b/ui/aura/native_window_occlusion_tracker_win.h index 96c46737..8c6d85f0 100644 --- a/ui/aura/native_window_occlusion_tracker_win.h +++ b/ui/aura/native_window_occlusion_tracker_win.h
@@ -84,8 +84,8 @@ static void CALLBACK EventHookCallback(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, - LONG idObject, - LONG idChild, + LONG id_object, + LONG id_child, DWORD dwEventThread, DWORD dwmsEventTime);
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index 2d8e6b12..c063211 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -265,8 +265,6 @@ "win/accessibility_misc_utils.cc", "win/accessibility_misc_utils.h", "win/atl_module.h", - "win/direct_manipulation.cc", - "win/direct_manipulation.h", "win/foreground_helper.cc", "win/foreground_helper.h", "win/hidden_window.cc", @@ -969,6 +967,7 @@ deps += [ "//ui/base/ime", "//ui/base/ime/mojo:test_interfaces", + "//ui/gfx/range/mojo:struct_traits", ] } @@ -984,7 +983,6 @@ if (is_win) { sources += [ "dragdrop/os_exchange_data_win_unittest.cc", - "win/direct_manipulation_unittest.cc", "win/hwnd_subclass_unittest.cc", ]
diff --git a/ui/base/ime/mojo/BUILD.gn b/ui/base/ime/mojo/BUILD.gn index 7443702..29d64d0 100644 --- a/ui/base/ime/mojo/BUILD.gn +++ b/ui/base/ime/mojo/BUILD.gn
@@ -8,6 +8,11 @@ sources = [ "ime_types.mojom", ] + + public_deps = [ + "//mojo/public/mojom/base", + "//ui/gfx/range/mojo", + ] } mojom("test_interfaces") {
diff --git a/ui/base/ime/mojo/ime_struct_traits_unittest.cc b/ui/base/ime/mojo/ime_struct_traits_unittest.cc index 21ad47c5..86f6d56 100644 --- a/ui/base/ime/mojo/ime_struct_traits_unittest.cc +++ b/ui/base/ime/mojo/ime_struct_traits_unittest.cc
@@ -8,9 +8,12 @@ #include "base/message_loop/message_loop.h" #include "base/stl_util.h" +#include "base/strings/utf_string_conversions.h" +#include "mojo/public/cpp/base/string16_mojom_traits.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/mojo/ime_struct_traits_test.mojom.h" +#include "ui/gfx/range/mojo/range_struct_traits.h" namespace ui { @@ -93,4 +96,24 @@ } } +TEST_F(IMEStructTraitsTest, CompositionText) { + ui::CompositionText input; + input.text = base::UTF8ToUTF16("abcdefghij"); + ui::ImeTextSpan ime_text_span_1(0, 2, ui::ImeTextSpan::Thickness::kThin); + ime_text_span_1.underline_color = SK_ColorGRAY; + input.ime_text_spans.push_back(ime_text_span_1); + ui::ImeTextSpan ime_text_span_2(ui::ImeTextSpan::Type::kComposition, 3, 6, + ui::ImeTextSpan::Thickness::kThick, + SK_ColorGREEN); + ime_text_span_2.underline_color = SK_ColorRED; + input.ime_text_spans.push_back(ime_text_span_2); + input.selection = gfx::Range(1, 7); + + ui::CompositionText output; + EXPECT_TRUE(mojom::CompositionText::Deserialize( + mojom::CompositionText::Serialize(&input), &output)); + + EXPECT_EQ(input, output); +} + } // namespace ui
diff --git a/ui/base/ime/mojo/ime_types.mojom b/ui/base/ime/mojo/ime_types.mojom index d1356e3..c575a30 100644 --- a/ui/base/ime/mojo/ime_types.mojom +++ b/ui/base/ime/mojo/ime_types.mojom
@@ -4,6 +4,9 @@ module ui.mojom; +import "mojo/public/mojom/base/string16.mojom"; +import "ui/gfx/range/mojo/range.mojom"; + // Text input type which is based on blink::WebTextInputType. enum TextInputType { NONE, @@ -54,3 +57,54 @@ AUTOCAPITALIZE_SENTENCES = 0x200, ALL = 0x3FF, }; + +// See comments for ui::ImeTextSpan::Type for more details. +enum ImeTextSpanType { + kComposition, + kSuggestion, + kMisspellingSuggestion, +}; + +// This enum represents the thickness of an underline segment of text, +// the thickness of a ui::ImeTextSpan element. +// The possible values are: +// * kNone: When you don't want to paint the underline. +// * kThin: For regular size. +// * kThick: For thick underlines. +enum ImeTextSpanThickness { + kNone, + kThin, + kThick, +}; + +// Represents an underlined segment of text currently composed by IME. +// Corresponds to ui::ImeTextSpan. +struct ImeTextSpan { + ImeTextSpanType type; + uint32 start_offset; + uint32 end_offset; + uint32 underline_color; + ImeTextSpanThickness thickness; + uint32 background_color; + uint32 suggestion_highlight_color; + bool remove_on_finish_composing; + array<string> suggestions; +}; + +// Represents a text currently being composed by IME. Corresponds to +// ui::CompositionText. +struct CompositionText { + mojo_base.mojom.String16 text; + array<ImeTextSpan> ime_text_spans; + gfx.mojom.Range selection; +}; + +// Represents how a text client gets focused. Corresponds to +// ui::TextInputClient::FocusReason. +enum FocusReason { + kNone, // Not focused. + kMouse, // User initiated with mouse. + kTouch, // User initiated with touch. + kPen, // User initiated with pen. + kOther, // All other reasons (e.g. system initiated, mouse) +};
diff --git a/ui/base/ime/mojo/ime_types.typemap b/ui/base/ime/mojo/ime_types.typemap index 57f6b1b..ee4d337 100644 --- a/ui/base/ime/mojo/ime_types.typemap +++ b/ui/base/ime/mojo/ime_types.typemap
@@ -4,6 +4,9 @@ mojom = "//ui/base/ime/mojo/ime_types.mojom" public_headers = [ + "//ui/base/ime/composition_text.h", + "//ui/base/ime/ime_text_span.h", + "//ui/base/ime/text_input_client.h", "//ui/base/ime/text_input_mode.h", "//ui/base/ime/text_input_type.h", ] @@ -14,8 +17,16 @@ public_deps = [ "//ui/base/ime:ime_types", ] +deps = [ + "//ui/gfx/range", + "//ui/gfx/range/mojo:struct_traits", +] type_mappings = [ + "ui.mojom.CompositionText=ui::CompositionText", + "ui.mojom.FocusReason=ui::TextInputClient::FocusReason", + "ui.mojom.ImeTextSpan=ui::ImeTextSpan", + "ui.mojom.ImeTextSpanThickness=ui::ImeTextSpan::Thickness", "ui.mojom.TextInputType=ui::TextInputType", "ui.mojom.TextInputMode=ui::TextInputMode", ]
diff --git a/ui/base/ime/mojo/ime_types_struct_traits.cc b/ui/base/ime/mojo/ime_types_struct_traits.cc index eb3df29..3bdd895 100644 --- a/ui/base/ime/mojo/ime_types_struct_traits.cc +++ b/ui/base/ime/mojo/ime_types_struct_traits.cc
@@ -4,6 +4,9 @@ #include "ui/base/ime/mojo/ime_types_struct_traits.h" +#include "mojo/public/cpp/base/string16_mojom_traits.h" +#include "ui/gfx/range/mojo/range_struct_traits.h" + namespace mojo { #define UI_TO_MOJO_TYPE_CASE(name) \ @@ -135,4 +138,154 @@ return false; } +// static +bool StructTraits<ui::mojom::ImeTextSpanDataView, ui::ImeTextSpan>::Read( + ui::mojom::ImeTextSpanDataView data, + ui::ImeTextSpan* out) { + if (data.is_null()) + return false; + if (!data.ReadType(&out->type)) + return false; + out->start_offset = data.start_offset(); + out->end_offset = data.end_offset(); + out->underline_color = data.underline_color(); + if (!data.ReadThickness(&out->thickness)) + return false; + out->background_color = data.background_color(); + out->suggestion_highlight_color = data.suggestion_highlight_color(); + out->remove_on_finish_composing = data.remove_on_finish_composing(); + if (!data.ReadSuggestions(&out->suggestions)) + return false; + return true; +} + +// static +bool StructTraits<ui::mojom::CompositionTextDataView, ui::CompositionText>:: + Read(ui::mojom::CompositionTextDataView data, ui::CompositionText* out) { + return !data.is_null() && data.ReadText(&out->text) && + data.ReadImeTextSpans(&out->ime_text_spans) && + data.ReadSelection(&out->selection); +} + +// static +ui::mojom::FocusReason +EnumTraits<ui::mojom::FocusReason, ui::TextInputClient::FocusReason>::ToMojom( + ui::TextInputClient::FocusReason input) { + switch (input) { + case ui::TextInputClient::FOCUS_REASON_NONE: + return ui::mojom::FocusReason::kNone; + case ui::TextInputClient::FOCUS_REASON_MOUSE: + return ui::mojom::FocusReason::kMouse; + case ui::TextInputClient::FOCUS_REASON_TOUCH: + return ui::mojom::FocusReason::kTouch; + case ui::TextInputClient::FOCUS_REASON_PEN: + return ui::mojom::FocusReason::kPen; + case ui::TextInputClient::FOCUS_REASON_OTHER: + return ui::mojom::FocusReason::kOther; + } + + NOTREACHED(); + return ui::mojom::FocusReason::kNone; +} + +// static +bool EnumTraits<ui::mojom::FocusReason, ui::TextInputClient::FocusReason>:: + FromMojom(ui::mojom::FocusReason input, + ui::TextInputClient::FocusReason* out) { + switch (input) { + case ui::mojom::FocusReason::kNone: + *out = ui::TextInputClient::FOCUS_REASON_NONE; + return true; + case ui::mojom::FocusReason::kMouse: + *out = ui::TextInputClient::FOCUS_REASON_MOUSE; + return true; + case ui::mojom::FocusReason::kTouch: + *out = ui::TextInputClient::FOCUS_REASON_TOUCH; + return true; + case ui::mojom::FocusReason::kPen: + *out = ui::TextInputClient::FOCUS_REASON_PEN; + return true; + case ui::mojom::FocusReason::kOther: + *out = ui::TextInputClient::FOCUS_REASON_OTHER; + return true; + } + + NOTREACHED(); + return false; +} + +// static +ui::mojom::ImeTextSpanType +EnumTraits<ui::mojom::ImeTextSpanType, ui::ImeTextSpan::Type>::ToMojom( + ui::ImeTextSpan::Type ime_text_span_type) { + switch (ime_text_span_type) { + case ui::ImeTextSpan::Type::kComposition: + return ui::mojom::ImeTextSpanType::kComposition; + case ui::ImeTextSpan::Type::kSuggestion: + return ui::mojom::ImeTextSpanType::kSuggestion; + case ui::ImeTextSpan::Type::kMisspellingSuggestion: + return ui::mojom::ImeTextSpanType::kMisspellingSuggestion; + } + + NOTREACHED(); + return ui::mojom::ImeTextSpanType::kComposition; +} + +// static +bool EnumTraits<ui::mojom::ImeTextSpanType, ui::ImeTextSpan::Type>::FromMojom( + ui::mojom::ImeTextSpanType type, + ui::ImeTextSpan::Type* out) { + switch (type) { + case ui::mojom::ImeTextSpanType::kComposition: + *out = ui::ImeTextSpan::Type::kComposition; + return true; + case ui::mojom::ImeTextSpanType::kSuggestion: + *out = ui::ImeTextSpan::Type::kSuggestion; + return true; + case ui::mojom::ImeTextSpanType::kMisspellingSuggestion: + *out = ui::ImeTextSpan::Type::kMisspellingSuggestion; + return true; + } + + NOTREACHED(); + return false; +} + +// static +ui::mojom::ImeTextSpanThickness EnumTraits< + ui::mojom::ImeTextSpanThickness, + ui::ImeTextSpan::Thickness>::ToMojom(ui::ImeTextSpan::Thickness thickness) { + switch (thickness) { + case ui::ImeTextSpan::Thickness::kNone: + return ui::mojom::ImeTextSpanThickness::kNone; + case ui::ImeTextSpan::Thickness::kThin: + return ui::mojom::ImeTextSpanThickness::kThin; + case ui::ImeTextSpan::Thickness::kThick: + return ui::mojom::ImeTextSpanThickness::kThick; + } + + NOTREACHED(); + return ui::mojom::ImeTextSpanThickness::kThin; +} + +// static +bool EnumTraits<ui::mojom::ImeTextSpanThickness, ui::ImeTextSpan::Thickness>:: + FromMojom(ui::mojom::ImeTextSpanThickness input, + ui::ImeTextSpan::Thickness* out) { + switch (input) { + case ui::mojom::ImeTextSpanThickness::kNone: + *out = ui::ImeTextSpan::Thickness::kNone; + return true; + case ui::mojom::ImeTextSpanThickness::kThin: + *out = ui::ImeTextSpan::Thickness::kThin; + return true; + case ui::mojom::ImeTextSpanThickness::kThick: + *out = ui::ImeTextSpan::Thickness::kThick; + return true; + } + + NOTREACHED(); + return false; +} + } // namespace mojo
diff --git a/ui/base/ime/mojo/ime_types_struct_traits.h b/ui/base/ime/mojo/ime_types_struct_traits.h index 6af23bb..dd0dde67 100644 --- a/ui/base/ime/mojo/ime_types_struct_traits.h +++ b/ui/base/ime/mojo/ime_types_struct_traits.h
@@ -7,7 +7,10 @@ #include <vector> +#include "ui/base/ime/composition_text.h" +#include "ui/base/ime/ime_text_span.h" #include "ui/base/ime/mojo/ime_types.mojom.h" +#include "ui/base/ime/text_input_client.h" #include "ui/base/ime/text_input_mode.h" #include "ui/base/ime/text_input_type.h" @@ -25,6 +28,70 @@ static bool FromMojom(ui::mojom::TextInputMode input, ui::TextInputMode* out); }; +template <> +struct StructTraits<ui::mojom::CompositionTextDataView, ui::CompositionText> { + static base::string16 text(const ui::CompositionText& c) { return c.text; } + static ui::ImeTextSpans ime_text_spans(const ui::CompositionText& c) { + return c.ime_text_spans; + } + static gfx::Range selection(const ui::CompositionText& c) { + return c.selection; + } + static bool Read(ui::mojom::CompositionTextDataView data, + ui::CompositionText* out); +}; + +template <> +struct EnumTraits<ui::mojom::FocusReason, ui::TextInputClient::FocusReason> { + static ui::mojom::FocusReason ToMojom(ui::TextInputClient::FocusReason input); + static bool FromMojom(ui::mojom::FocusReason input, + ui::TextInputClient::FocusReason* out); +}; + +template <> +struct StructTraits<ui::mojom::ImeTextSpanDataView, ui::ImeTextSpan> { + static ui::ImeTextSpan::Type type(const ui::ImeTextSpan& c) { return c.type; } + static uint32_t start_offset(const ui::ImeTextSpan& c) { + return c.start_offset; + } + static uint32_t end_offset(const ui::ImeTextSpan& c) { return c.end_offset; } + static uint32_t underline_color(const ui::ImeTextSpan& c) { + return c.underline_color; + } + static ui::ImeTextSpan::Thickness thickness(const ui::ImeTextSpan& i) { + return i.thickness; + } + static uint32_t background_color(const ui::ImeTextSpan& c) { + return c.background_color; + } + static uint32_t suggestion_highlight_color(const ui::ImeTextSpan& c) { + return c.suggestion_highlight_color; + } + static bool remove_on_finish_composing(const ui::ImeTextSpan& c) { + return c.remove_on_finish_composing; + } + static std::vector<std::string> suggestions(const ui::ImeTextSpan& c) { + return c.suggestions; + } + static bool Read(ui::mojom::ImeTextSpanDataView data, ui::ImeTextSpan* out); +}; + +template <> +struct EnumTraits<ui::mojom::ImeTextSpanType, ui::ImeTextSpan::Type> { + static ui::mojom::ImeTextSpanType ToMojom( + ui::ImeTextSpan::Type ime_text_span_type); + static bool FromMojom(ui::mojom::ImeTextSpanType input, + ui::ImeTextSpan::Type* out); +}; + +template <> +struct EnumTraits<ui::mojom::ImeTextSpanThickness, ui::ImeTextSpan::Thickness> { + static ui::mojom::ImeTextSpanThickness ToMojom( + ui::ImeTextSpan::Thickness thickness); + static bool FromMojom(ui::mojom::ImeTextSpanThickness input, + ui::ImeTextSpan::Thickness* out); +}; + } // namespace mojo #endif // UI_BASE_IME_MOJO_IME_TYPES_STRUCT_TRAITS_H_
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn index 7ba4860..a57fa8c 100644 --- a/ui/events/BUILD.gn +++ b/ui/events/BUILD.gn
@@ -571,6 +571,7 @@ "//ui/events/devices", "//ui/events/devices/mojo:test_interfaces", "//ui/events/gestures/blink", + "//ui/events/mojo:interfaces", "//ui/events/platform", "//ui/gfx/geometry/mojo:struct_traits", "//ui/gfx/ipc/geometry",
diff --git a/ui/file_manager/file_manager/foreground/js/actions_controller.js b/ui/file_manager/file_manager/foreground/js/actions_controller.js index c9978e52..53611a1 100644 --- a/ui/file_manager/file_manager/foreground/js/actions_controller.js +++ b/ui/file_manager/file_manager/foreground/js/actions_controller.js
@@ -164,8 +164,9 @@ return; } - const actionsModel = new ActionsModel(this.volumeManager_, this.metadataModel_, - this.shortcutsModel_, this.driveSyncHandler_, this.ui_, entries); + const actionsModel = new ActionsModel( + this.volumeManager_, this.metadataModel_, this.shortcutsModel_, + this.driveSyncHandler_, this.ui_, entries); const initializeAndUpdateUI = /** @type {function(Event=)} */ (opt_event => { @@ -205,14 +206,16 @@ this.updateUI_(); const entry = this.ui_.directoryTree.selectedItem ? - (this.ui_.directoryTree.selectedItem.entry || null) : null; + (this.ui_.directoryTree.selectedItem.entry || null) : + null; if (!entry) { return; } const sequence = ++this.navigationListSequence_; - const actionsModel = new ActionsModel(this.volumeManager_, this.metadataModel_, - this.shortcutsModel_, this.driveSyncHandler_, this.ui_, [entry]); + const actionsModel = new ActionsModel( + this.volumeManager_, this.metadataModel_, this.shortcutsModel_, + this.driveSyncHandler_, this.ui_, [entry]); const initializeAndUpdateUI = /** @type {function(Event=)} */ (opt_event => {
diff --git a/ui/file_manager/file_manager/foreground/js/actions_model.js b/ui/file_manager/file_manager/foreground/js/actions_model.js index c97e7037..9f676723 100644 --- a/ui/file_manager/file_manager/foreground/js/actions_model.js +++ b/ui/file_manager/file_manager/foreground/js/actions_model.js
@@ -6,28 +6,24 @@ * A single action, that can be taken on a set of entries. * @interface */ -function Action() { -} +function Action() {} /** * Executes this action on the set of entries. */ -Action.prototype.execute = () => { -}; +Action.prototype.execute = () => {}; /** * Checks whether this action can execute on the set of entries. * * @return {boolean} True if the function can execute, false if not. */ -Action.prototype.canExecute = () => { -}; +Action.prototype.canExecute = () => {}; /** * @return {?string} */ -Action.prototype.getTitle = () => { -}; +Action.prototype.getTitle = () => {}; /** * @typedef {{ @@ -144,8 +140,8 @@ * @constructor * @struct */ -function DriveToggleOfflineAction(entries, metadataModel, driveSyncHandler, ui, - value, onExecute) { +function DriveToggleOfflineAction( + entries, metadataModel, driveSyncHandler, ui, value, onExecute) { /** * @private {!Array<!Entry>} * @const @@ -192,35 +188,37 @@ * @param {function()} onExecute * @return {DriveToggleOfflineAction} */ -DriveToggleOfflineAction.create = (entries, metadataModel, driveSyncHandler, ui, value, onExecute) => { - if (!loadTimeData.getBoolean('DRIVE_FS_ENABLED')) { - if (entries.some((entry) => entry.isDirectory)) { - return null; - } - } +DriveToggleOfflineAction.create = + (entries, metadataModel, driveSyncHandler, ui, value, onExecute) => { + if (!loadTimeData.getBoolean('DRIVE_FS_ENABLED')) { + if (entries.some((entry) => entry.isDirectory)) { + return null; + } + } - const actionableEntries = entries.filter(entry => { - if (entry.isDirectory && !loadTimeData.getBoolean('DRIVE_FS_ENABLED')) { - return false; - } - const metadata = metadataModel.getCache( - [entry], ['hosted', 'pinned'])[0]; - if (metadata.hosted) { - return false; - } - if (metadata.pinned === value) { - return false; - } - return true; - }); + const actionableEntries = entries.filter(entry => { + if (entry.isDirectory && !loadTimeData.getBoolean('DRIVE_FS_ENABLED')) { + return false; + } + const metadata = + metadataModel.getCache([entry], ['hosted', 'pinned'])[0]; + if (metadata.hosted) { + return false; + } + if (metadata.pinned === value) { + return false; + } + return true; + }); - if (actionableEntries.length === 0) { - return null; - } + if (actionableEntries.length === 0) { + return null; + } - return new DriveToggleOfflineAction(actionableEntries, metadataModel, - driveSyncHandler, ui, value, onExecute); -}; + return new DriveToggleOfflineAction( + actionableEntries, metadataModel, driveSyncHandler, ui, value, + onExecute); + }; /** * @override @@ -244,19 +242,16 @@ } currentEntry = entries.shift(); chrome.fileManagerPrivate.pinDriveFile( - currentEntry, - this.value_, - steps.entryPinned); + currentEntry, this.value_, steps.entryPinned); }, // Check the result of pinning. entryPinned: () => { error = !!chrome.runtime.lastError; if (error && this.value_) { - this.metadataModel_.get([currentEntry], ['size']).then( - results => { - steps.showError(results[0].size); - }); + this.metadataModel_.get([currentEntry], ['size']).then(results => { + steps.showError(results[0].size); + }); return; } this.metadataModel_.notifyEntriesChanged([currentEntry]); @@ -276,9 +271,9 @@ showError: size => { this.ui_.alertDialog.showHtml( str('DRIVE_OUT_OF_SPACE_HEADER'), - strf('DRIVE_OUT_OF_SPACE_MESSAGE', - unescape(currentEntry.name), - util.bytesToString(size)), + strf( + 'DRIVE_OUT_OF_SPACE_MESSAGE', unescape(currentEntry.name), + util.bytesToString(size)), null, null, null); } }; @@ -338,18 +333,19 @@ * @param {function()} onExecute * @return {DriveCreateFolderShortcutAction} */ -DriveCreateFolderShortcutAction.create = (entries, volumeManager, shortcutsModel, onExecute) => { - if (entries.length !== 1 || entries[0].isFile) { - return null; - } - const locationInfo = volumeManager.getLocationInfo(entries[0]); - if (!locationInfo || locationInfo.isSpecialSearchRoot || - locationInfo.isRootEntry) { - return null; - } - return new DriveCreateFolderShortcutAction( - entries[0], shortcutsModel, onExecute); -}; +DriveCreateFolderShortcutAction.create = + (entries, volumeManager, shortcutsModel, onExecute) => { + if (entries.length !== 1 || entries[0].isFile) { + return null; + } + const locationInfo = volumeManager.getLocationInfo(entries[0]); + if (!locationInfo || locationInfo.isSpecialSearchRoot || + locationInfo.isRootEntry) { + return null; + } + return new DriveCreateFolderShortcutAction( + entries[0], shortcutsModel, onExecute); + }; /** * @override @@ -407,14 +403,15 @@ * @param {function()} onExecute * @return {DriveRemoveFolderShortcutAction} */ -DriveRemoveFolderShortcutAction.create = (entries, shortcutsModel, onExecute) => { - if (entries.length !== 1 || entries[0].isFile || - !shortcutsModel.exists(entries[0])) { - return null; - } - return new DriveRemoveFolderShortcutAction( - entries[0], shortcutsModel, onExecute); -}; +DriveRemoveFolderShortcutAction.create = + (entries, shortcutsModel, onExecute) => { + if (entries.length !== 1 || entries[0].isFile || + !shortcutsModel.exists(entries[0])) { + return null; + } + return new DriveRemoveFolderShortcutAction( + entries[0], shortcutsModel, onExecute); + }; /** * @override @@ -571,14 +568,14 @@ * @override */ CustomAction.prototype.execute = function() { - chrome.fileManagerPrivate.executeCustomAction(this.entries_, this.id_, - () => { - if (chrome.runtime.lastError) { - console.error('Failed to execute a custom action because of: ' + - chrome.runtime.lastError.message); - } - this.onExecute_(); - }); + chrome.fileManagerPrivate.executeCustomAction(this.entries_, this.id_, () => { + if (chrome.runtime.lastError) { + console.error( + 'Failed to execute a custom action because of: ' + + chrome.runtime.lastError.message); + } + this.onExecute_(); + }); }; /** @@ -703,109 +700,113 @@ return this.initializePromise_; } - this.initializePromise_ = new Promise((fulfill, reject) => { - if (this.destroyed_) { - reject(); - return; - } - this.initializePromiseReject_ = reject; + this.initializePromise_ = + new Promise((fulfill, reject) => { + if (this.destroyed_) { + reject(); + return; + } + this.initializePromiseReject_ = reject; - const volumeInfo = this.entries_.length >= 1 && - this.volumeManager_.getVolumeInfo(this.entries_[0]); - if (!volumeInfo) { - fulfill({}); - return; - } - // All entries need to be on the same volume to execute ActionsModel - // commands. - // TODO(sashab): Move this to util.js. - for (let i = 1; i < this.entries_.length; i++) { - const volumeInfoToCompare = - this.volumeManager_.getVolumeInfo(this.entries_[i]); - if (!volumeInfoToCompare || - volumeInfoToCompare.volumeId != volumeInfo.volumeId) { - fulfill({}); - return; - } - } - - const actions = {}; - switch (volumeInfo.volumeType) { - // For Drive, actions are constructed directly in the Files app code. - case VolumeManagerCommon.VolumeType.DRIVE: - const shareAction = DriveShareAction.create( - this.entries_, this.metadataModel_, this.volumeManager_, this.ui_); - if (shareAction) { - actions[ActionsModel.CommonActionId.SHARE] = shareAction; + const volumeInfo = this.entries_.length >= 1 && + this.volumeManager_.getVolumeInfo(this.entries_[0]); + if (!volumeInfo) { + fulfill({}); + return; + } + // All entries need to be on the same volume to execute ActionsModel + // commands. + // TODO(sashab): Move this to util.js. + for (let i = 1; i < this.entries_.length; i++) { + const volumeInfoToCompare = + this.volumeManager_.getVolumeInfo(this.entries_[i]); + if (!volumeInfoToCompare || + volumeInfoToCompare.volumeId != volumeInfo.volumeId) { + fulfill({}); + return; + } } - const saveForOfflineAction = DriveToggleOfflineAction.create( - this.entries_, this.metadataModel_, this.driveSyncHandler_, - this.ui_, true, this.invalidate_.bind(this)); - if (saveForOfflineAction) { - actions[ActionsModel.CommonActionId.SAVE_FOR_OFFLINE] = - saveForOfflineAction; - } + const actions = {}; + switch (volumeInfo.volumeType) { + // For Drive, actions are constructed directly in the Files app code. + case VolumeManagerCommon.VolumeType.DRIVE: + const shareAction = DriveShareAction.create( + this.entries_, this.metadataModel_, this.volumeManager_, + this.ui_); + if (shareAction) { + actions[ActionsModel.CommonActionId.SHARE] = shareAction; + } - const offlineNotNecessaryAction = DriveToggleOfflineAction.create( - this.entries_, this.metadataModel_, this.driveSyncHandler_, - this.ui_, false, this.invalidate_.bind(this)); - if (offlineNotNecessaryAction) { - actions[ActionsModel.CommonActionId.OFFLINE_NOT_NECESSARY] = - offlineNotNecessaryAction; - } + const saveForOfflineAction = DriveToggleOfflineAction.create( + this.entries_, this.metadataModel_, this.driveSyncHandler_, + this.ui_, true, this.invalidate_.bind(this)); + if (saveForOfflineAction) { + actions[ActionsModel.CommonActionId.SAVE_FOR_OFFLINE] = + saveForOfflineAction; + } - const createFolderShortcutAction = - DriveCreateFolderShortcutAction.create(this.entries_, - this.volumeManager_, this.shortcutsModel_, - this.invalidate_.bind(this)); - if (createFolderShortcutAction) { - actions[ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT] = - createFolderShortcutAction; - } + const offlineNotNecessaryAction = DriveToggleOfflineAction.create( + this.entries_, this.metadataModel_, this.driveSyncHandler_, + this.ui_, false, this.invalidate_.bind(this)); + if (offlineNotNecessaryAction) { + actions[ActionsModel.CommonActionId.OFFLINE_NOT_NECESSARY] = + offlineNotNecessaryAction; + } - const removeFolderShortcutAction = - DriveRemoveFolderShortcutAction.create(this.entries_, - this.shortcutsModel_, this.invalidate_.bind(this)); - if (removeFolderShortcutAction) { - actions[ActionsModel.InternalActionId.REMOVE_FOLDER_SHORTCUT] = - removeFolderShortcutAction; - } + const createFolderShortcutAction = + DriveCreateFolderShortcutAction.create( + this.entries_, this.volumeManager_, this.shortcutsModel_, + this.invalidate_.bind(this)); + if (createFolderShortcutAction) { + actions[ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT] = + createFolderShortcutAction; + } - const manageInDriveAction = DriveManageAction.create( - this.entries_, this.volumeManager_, this.ui_); - if (manageInDriveAction) { - actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE] = - manageInDriveAction; - } + const removeFolderShortcutAction = + DriveRemoveFolderShortcutAction.create( + this.entries_, this.shortcutsModel_, + this.invalidate_.bind(this)); + if (removeFolderShortcutAction) { + actions[ActionsModel.InternalActionId.REMOVE_FOLDER_SHORTCUT] = + removeFolderShortcutAction; + } - fulfill(actions); - break; + const manageInDriveAction = DriveManageAction.create( + this.entries_, this.volumeManager_, this.ui_); + if (manageInDriveAction) { + actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE] = + manageInDriveAction; + } - // For FSP, fetch custom actions via an API. - case VolumeManagerCommon.VolumeType.PROVIDED: - chrome.fileManagerPrivate.getCustomActions(this.entries_, - customActions => { - if (chrome.runtime.lastError) { - console.error('Failed to fetch custom actions because of: ' + - chrome.runtime.lastError.message); - } else { - customActions.forEach(action => { - actions[action.id] = new CustomAction( - this.entries_, action.id, action.title || null, - this.invalidate_.bind(this)); + fulfill(actions); + break; + + // For FSP, fetch custom actions via an API. + case VolumeManagerCommon.VolumeType.PROVIDED: + chrome.fileManagerPrivate.getCustomActions( + this.entries_, customActions => { + if (chrome.runtime.lastError) { + console.error( + 'Failed to fetch custom actions because of: ' + + chrome.runtime.lastError.message); + } else { + customActions.forEach(action => { + actions[action.id] = new CustomAction( + this.entries_, action.id, action.title || null, + this.invalidate_.bind(this)); + }); + } + fulfill(actions); }); - } - fulfill(actions); - }); - break; + break; - default: - fulfill(actions); - } - }).then(actions => { - this.actions_ = actions; - }); + default: + fulfill(actions); + } + }).then(actions => { + this.actions_ = actions; + }); return this.initializePromise_; };
diff --git a/ui/file_manager/file_manager/foreground/js/actions_model_unittest.js b/ui/file_manager/file_manager/foreground/js/actions_model_unittest.js index 83fa77c0..538b008 100644 --- a/ui/file_manager/file_manager/foreground/js/actions_model_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/actions_model_unittest.js
@@ -127,63 +127,72 @@ canShare: true, }); - let model = new ActionsModel(volumeManager, metadataModel, shortcutsModel, - driveSyncHandler, ui, [driveFileSystem.entries['/test']]); + let model = new ActionsModel( + volumeManager, metadataModel, shortcutsModel, driveSyncHandler, ui, + [driveFileSystem.entries['/test']]); let invalidated = 0; model.addEventListener('invalidated', () => { invalidated++; }); - return reportPromise(model.initialize().then(() => { - const actions = model.getActions(); - assertEquals(3, Object.keys(actions).length); + return reportPromise( + model.initialize() + .then(() => { + const actions = model.getActions(); + assertEquals(3, Object.keys(actions).length); - // 'Share' should be disabled in offline mode. - const shareAction = actions[ActionsModel.CommonActionId.SHARE]; - assertTrue(!!shareAction); - volumeManager.driveConnectionState = { - type: VolumeManagerCommon.DriveConnectionType.OFFLINE - }; - assertFalse(shareAction.canExecute()); + // 'Share' should be disabled in offline mode. + const shareAction = actions[ActionsModel.CommonActionId.SHARE]; + assertTrue(!!shareAction); + volumeManager.driveConnectionState = { + type: VolumeManagerCommon.DriveConnectionType.OFFLINE + }; + assertFalse(shareAction.canExecute()); - // 'Manage in Drive' should be disabled in offline mode. - const manageInDriveAction = - actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; - assertTrue(!!manageInDriveAction); - assertFalse(manageInDriveAction.canExecute()); + // 'Manage in Drive' should be disabled in offline mode. + const manageInDriveAction = + actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; + assertTrue(!!manageInDriveAction); + assertFalse(manageInDriveAction.canExecute()); - // 'Create Shortcut' should be enabled, until it's executed, then disabled. - const createFolderShortcutAction = - actions[ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT]; - assertTrue(!!createFolderShortcutAction); - assertTrue(createFolderShortcutAction.canExecute()); - createFolderShortcutAction.execute(); - assertFalse(createFolderShortcutAction.canExecute()); - assertEquals(1, invalidated); + // 'Create Shortcut' should be enabled, until it's executed, then + // disabled. + const createFolderShortcutAction = + actions[ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT]; + assertTrue(!!createFolderShortcutAction); + assertTrue(createFolderShortcutAction.canExecute()); + createFolderShortcutAction.execute(); + assertFalse(createFolderShortcutAction.canExecute()); + assertEquals(1, invalidated); - // The model is invalidated, as list of actions have changed. Recreated - // the model and check that the actions are updated. - model = new ActionsModel(volumeManager, metadataModel, shortcutsModel, - driveSyncHandler, ui, [driveFileSystem.entries['/test']]); - model.addEventListener('invalidated', () => { - invalidated++; - }); - return model.initialize(); - }).then(() => { - const actions = model.getActions(); - assertEquals(4, Object.keys(actions).length); - assertTrue(!!actions[ActionsModel.CommonActionId.SHARE]); - assertTrue(!!actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]); - assertTrue(!!actions[ActionsModel.InternalActionId.REMOVE_FOLDER_SHORTCUT]); + // The model is invalidated, as list of actions have changed. + // Recreated the model and check that the actions are updated. + model = new ActionsModel( + volumeManager, metadataModel, shortcutsModel, driveSyncHandler, + ui, [driveFileSystem.entries['/test']]); + model.addEventListener('invalidated', () => { + invalidated++; + }); + return model.initialize(); + }) + .then(() => { + const actions = model.getActions(); + assertEquals(4, Object.keys(actions).length); + assertTrue(!!actions[ActionsModel.CommonActionId.SHARE]); + assertTrue( + !!actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]); + assertTrue(!!actions[ActionsModel.InternalActionId + .REMOVE_FOLDER_SHORTCUT]); - // 'Create shortcut' should be disabled. - const createFolderShortcutAction = - actions[ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT]; - assertTrue(!!createFolderShortcutAction); - assertFalse(createFolderShortcutAction.canExecute()); - assertEquals(1, invalidated); - }), callback); + // 'Create shortcut' should be disabled. + const createFolderShortcutAction = + actions[ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT]; + assertTrue(!!createFolderShortcutAction); + assertFalse(createFolderShortcutAction.canExecute()); + assertEquals(1, invalidated); + }), + callback); } /** @@ -198,87 +207,95 @@ pinned: false, }); - let model = new ActionsModel(volumeManager, metadataModel, shortcutsModel, - driveSyncHandler, ui, [driveFileSystem.entries['/test.txt']]); + let model = new ActionsModel( + volumeManager, metadataModel, shortcutsModel, driveSyncHandler, ui, + [driveFileSystem.entries['/test.txt']]); let invalidated = 0; - return reportPromise(model.initialize().then(() => { - const actions = model.getActions(); - assertEquals(3, Object.keys(actions).length); - assertTrue(!!actions[ActionsModel.CommonActionId.SHARE]); + return reportPromise( + model.initialize() + .then(() => { + const actions = model.getActions(); + assertEquals(3, Object.keys(actions).length); + assertTrue(!!actions[ActionsModel.CommonActionId.SHARE]); - // 'Save for Offline' should be enabled. - const saveForOfflineAction = - actions[ActionsModel.CommonActionId.SAVE_FOR_OFFLINE]; - assertTrue(!!saveForOfflineAction); - assertTrue(saveForOfflineAction.canExecute()); + // 'Save for Offline' should be enabled. + const saveForOfflineAction = + actions[ActionsModel.CommonActionId.SAVE_FOR_OFFLINE]; + assertTrue(!!saveForOfflineAction); + assertTrue(saveForOfflineAction.canExecute()); - // 'Manage in Drive' should be enabled. - const manageInDriveAction = - actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; - assertTrue(!!manageInDriveAction); - assertTrue(manageInDriveAction.canExecute()); + // 'Manage in Drive' should be enabled. + const manageInDriveAction = + actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; + assertTrue(!!manageInDriveAction); + assertTrue(manageInDriveAction.canExecute()); - chrome.fileManagerPrivate.pinDriveFile = (entry, pin, callback) => { - metadataModel.properties.pinned = true; - assertEquals(driveFileSystem.entries['/test.txt'], entry); - assertTrue(pin); - callback(); - }; + chrome.fileManagerPrivate.pinDriveFile = (entry, pin, callback) => { + metadataModel.properties.pinned = true; + assertEquals(driveFileSystem.entries['/test.txt'], entry); + assertTrue(pin); + callback(); + }; - // For pinning, invalidating is done asynchronously, so we need to wait - // for it with a promise. - return new Promise((fulfill, reject) => { - model.addEventListener('invalidated', () => { - invalidated++; - fulfill(); - }); - saveForOfflineAction.execute(); - }); - }).then(() => { - assertTrue(metadataModel.properties.pinned); - assertEquals(1, invalidated); + // For pinning, invalidating is done asynchronously, so we need to + // wait for it with a promise. + return new Promise((fulfill, reject) => { + model.addEventListener('invalidated', () => { + invalidated++; + fulfill(); + }); + saveForOfflineAction.execute(); + }); + }) + .then(() => { + assertTrue(metadataModel.properties.pinned); + assertEquals(1, invalidated); - // The model is invalidated, as list of actions have changed. Recreated - // the model and check that the actions are updated. - model = new ActionsModel(volumeManager, metadataModel, shortcutsModel, - driveSyncHandler, ui, [driveFileSystem.entries['/test.txt']]); - return model.initialize(); - }).then(() => { - const actions = model.getActions(); - assertEquals(3, Object.keys(actions).length); - assertTrue(!!actions[ActionsModel.CommonActionId.SHARE]); + // The model is invalidated, as list of actions have changed. + // Recreated the model and check that the actions are updated. + model = new ActionsModel( + volumeManager, metadataModel, shortcutsModel, driveSyncHandler, + ui, [driveFileSystem.entries['/test.txt']]); + return model.initialize(); + }) + .then(() => { + const actions = model.getActions(); + assertEquals(3, Object.keys(actions).length); + assertTrue(!!actions[ActionsModel.CommonActionId.SHARE]); - // 'Offline not Necessary' should be enabled. - const offlineNotNecessaryAction = - actions[ActionsModel.CommonActionId.OFFLINE_NOT_NECESSARY]; - assertTrue(!!offlineNotNecessaryAction); - assertTrue(offlineNotNecessaryAction.canExecute()); + // 'Offline not Necessary' should be enabled. + const offlineNotNecessaryAction = + actions[ActionsModel.CommonActionId.OFFLINE_NOT_NECESSARY]; + assertTrue(!!offlineNotNecessaryAction); + assertTrue(offlineNotNecessaryAction.canExecute()); - // 'Manage in Drive' should be enabled. - const manageInDriveAction = - actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; - assertTrue(!!manageInDriveAction); - assertTrue(manageInDriveAction.canExecute()); + // 'Manage in Drive' should be enabled. + const manageInDriveAction = + actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; + assertTrue(!!manageInDriveAction); + assertTrue(manageInDriveAction.canExecute()); - chrome.fileManagerPrivate.pinDriveFile = (entry, pin, callback) => { - metadataModel.properties.pinned = false; - assertEquals(driveFileSystem.entries['/test.txt'], entry); - assertFalse(pin); - callback(); - }; + chrome.fileManagerPrivate.pinDriveFile = (entry, pin, callback) => { + metadataModel.properties.pinned = false; + assertEquals(driveFileSystem.entries['/test.txt'], entry); + assertFalse(pin); + callback(); + }; - return new Promise((fulfill, reject) => { - model.addEventListener('invalidated', () => { - invalidated++; - fulfill(); - }); - offlineNotNecessaryAction.execute(); - }); - }).then(() => { - assertFalse(metadataModel.properties.pinned); - assertEquals(2, invalidated); - }), callback); + return new Promise((fulfill, reject) => { + model.addEventListener('invalidated', () => { + invalidated++; + fulfill(); + }); + offlineNotNecessaryAction.execute(); + }); + }) + .then(() => { + assertFalse(metadataModel.properties.pinned); + assertEquals(2, invalidated); + }), + callback); } /** @@ -411,63 +428,68 @@ callback([ { id: ActionsModel.CommonActionId.SHARE, - title: 'Share it!' + title: 'Share it!', }, { id: 'some-custom-id', - title: 'Turn into chocolate!' - } + title: 'Turn into chocolate!', + }, ]); }; const metadataModel = new MockMetadataModel(null); - const model = new ActionsModel(volumeManager, metadataModel, shortcutsModel, - driveSyncHandler, ui, [providedFileSystem.entries['/test']]); + const model = new ActionsModel( + volumeManager, metadataModel, shortcutsModel, driveSyncHandler, ui, + [providedFileSystem.entries['/test']]); let invalidated = 0; model.addEventListener('invalidated', () => { invalidated++; }); - return reportPromise(model.initialize().then(() => { - const actions = model.getActions(); - assertEquals(2, Object.keys(actions).length); + return reportPromise( + model.initialize().then(() => { + const actions = model.getActions(); + assertEquals(2, Object.keys(actions).length); - const shareAction = actions[ActionsModel.CommonActionId.SHARE]; - assertTrue(!!shareAction); - // Sharing on FSP is possible even if Drive is offline. Custom actions are - // always executable, as we don't know the actions implementation. - volumeManager.driveConnectionState = { - type: VolumeManagerCommon.DriveConnectionType.OFFLINE - }; - assertTrue(shareAction.canExecute()); - assertEquals('Share it!', shareAction.getTitle()); + const shareAction = actions[ActionsModel.CommonActionId.SHARE]; + assertTrue(!!shareAction); + // Sharing on FSP is possible even if Drive is offline. Custom actions + // are always executable, as we don't know the actions implementation. + volumeManager.driveConnectionState = { + type: VolumeManagerCommon.DriveConnectionType.OFFLINE + }; + assertTrue(shareAction.canExecute()); + assertEquals('Share it!', shareAction.getTitle()); - chrome.fileManagerPrivate.executeCustomAction = (entries, actionId, callback) => { - assertEquals(1, entries.length); - assertEquals(providedFileSystem.entries['/test'], entries[0]); - assertEquals(ActionsModel.CommonActionId.SHARE, actionId); - callback(); - }; - shareAction.execute(); - assertEquals(1, invalidated); + chrome.fileManagerPrivate.executeCustomAction = + (entries, actionId, callback) => { + assertEquals(1, entries.length); + assertEquals(providedFileSystem.entries['/test'], entries[0]); + assertEquals(ActionsModel.CommonActionId.SHARE, actionId); + callback(); + }; + shareAction.execute(); + assertEquals(1, invalidated); - assertTrue(!!actions['some-custom-id']); - assertTrue(actions['some-custom-id'].canExecute()); - assertEquals('Turn into chocolate!', - actions['some-custom-id'].getTitle()); + assertTrue(!!actions['some-custom-id']); + assertTrue(actions['some-custom-id'].canExecute()); + assertEquals( + 'Turn into chocolate!', actions['some-custom-id'].getTitle()); - chrome.fileManagerPrivate.executeCustomAction = (entries, actionId, callback) => { - assertEquals(1, entries.length); - assertEquals(providedFileSystem.entries['/test'], entries[0]); - assertEquals('some-custom-id', actionId); - callback(); - }; + chrome.fileManagerPrivate.executeCustomAction = + (entries, actionId, callback) => { + assertEquals(1, entries.length); + assertEquals(providedFileSystem.entries['/test'], entries[0]); + assertEquals('some-custom-id', actionId); + callback(); + }; - actions['some-custom-id'].execute(); - assertEquals(2, invalidated); - }), callback); + actions['some-custom-id'].execute(); + assertEquals(2, invalidated); + }), + callback); } /** @@ -479,18 +501,21 @@ chrome.fileManagerPrivate.getCustomActions = (entries, callback) => { chrome.runtime.lastError = { - message: 'Failed to fetch custom actions.' + message: 'Failed to fetch custom actions.', }; callback(['error']); }; const metadataModel = new MockMetadataModel(null); - const model = new ActionsModel(volumeManager, metadataModel, shortcutsModel, - driveSyncHandler, ui, [providedFileSystem.entries['/test']]); + const model = new ActionsModel( + volumeManager, metadataModel, shortcutsModel, driveSyncHandler, ui, + [providedFileSystem.entries['/test']]); - return reportPromise(model.initialize().then(() => { - const actions = model.getActions(); - assertEquals(0, Object.keys(actions).length); - }), callback); + return reportPromise( + model.initialize().then(() => { + const actions = model.getActions(); + assertEquals(0, Object.keys(actions).length); + }), + callback); }
diff --git a/ui/file_manager/file_manager/foreground/js/app_state_controller.js b/ui/file_manager/file_manager/foreground/js/app_state_controller.js index 2d31b57c..49649cb 100644 --- a/ui/file_manager/file_manager/foreground/js/app_state_controller.js +++ b/ui/file_manager/file_manager/foreground/js/app_state_controller.js
@@ -62,38 +62,42 @@ AppStateController.prototype.loadInitialViewOptions = function() { // Load initial view option. return new Promise((fulfill, reject) => { - chrome.storage.local.get(this.viewOptionStorageKey_, values => { - if (chrome.runtime.lastError) { - reject('Failed to load view options: ' + - chrome.runtime.lastError.message); - } else { - fulfill(values); - } - }); - }).then(values => { - this.viewOptions_ = {}; - const value = values[this.viewOptionStorageKey_]; - if (!value) { - return; - } - - // Load the global default options. - try { - this.viewOptions_ = JSON.parse(value); - } catch (ignore) {} - - // Override with window-specific options. - if (window.appState && window.appState.viewOptions) { - for (const key in window.appState.viewOptions) { - if (window.appState.viewOptions.hasOwnProperty(key)) { - this.viewOptions_[key] = window.appState.viewOptions[key]; + chrome.storage.local.get(this.viewOptionStorageKey_, values => { + if (chrome.runtime.lastError) { + reject( + 'Failed to load view options: ' + + chrome.runtime.lastError.message); + } else { + fulfill(values); + } + }); + }) + .then(values => { + this.viewOptions_ = {}; + const value = values[this.viewOptionStorageKey_]; + if (!value) { + return; } - } - } - }).catch(error => { - this.viewOptions_ = {}; - console.error(error); - }); + + // Load the global default options. + try { + this.viewOptions_ = JSON.parse(value); + } catch (ignore) { + } + + // Override with window-specific options. + if (window.appState && window.appState.viewOptions) { + for (const key in window.appState.viewOptions) { + if (window.appState.viewOptions.hasOwnProperty(key)) { + this.viewOptions_[key] = window.appState.viewOptions[key]; + } + } + } + }) + .catch(error => { + this.viewOptions_ = {}; + console.error(error); + }); }; /**
diff --git a/ui/file_manager/file_manager/foreground/js/column_visibility_controller.js b/ui/file_manager/file_manager/foreground/js/column_visibility_controller.js index ce80d40f..51349c82 100644 --- a/ui/file_manager/file_manager/foreground/js/column_visibility_controller.js +++ b/ui/file_manager/file_manager/foreground/js/column_visibility_controller.js
@@ -16,7 +16,7 @@ this.directoryModel_ = directoryModel; /** @private {!VolumeManager} */ - this.volumeManager_ = volumeManager; + this.volumeManager_ = volumeManager; /** @private {!FileManagerUI} */ this.ui_ = ui;
diff --git a/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js b/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js index a2ce9e1..be393f1bd 100644 --- a/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js +++ b/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js
@@ -20,15 +20,8 @@ * @struct */ function DialogActionController( - dialogType, - dialogFooter, - directoryModel, - metadataModel, - volumeManager, - fileFilter, - namingController, - fileSelectionHandler, - launchParam) { + dialogType, dialogFooter, directoryModel, metadataModel, volumeManager, + fileFilter, namingController, fileSelectionHandler, launchParam) { /** * @type {!DialogType} * @const @@ -109,8 +102,7 @@ dialogFooter.okButton.addEventListener( 'click', this.processOKAction_.bind(this)); - dialogFooter.cancelButton.addEventListener( - 'click', this.onCancelBound_); + dialogFooter.cancelButton.addEventListener('click', this.onCancelBound_); dialogFooter.newFolderButton.addEventListener( 'click', this.processNewFolderAction_.bind(this)); dialogFooter.fileTypeSelector.addEventListener( @@ -123,8 +115,7 @@ volumeManager.addEventListener( 'drive-connection-changed', this.updateOkButton_.bind(this)); - dialogFooter.initFileTypeFilter( - this.fileTypes_, launchParam.includeAllFiles); + dialogFooter.initFileTypeFilter(this.fileTypes_, launchParam.includeAllFiles); this.onFileTypeFilterChanged_(); this.newFolderCommand_ = @@ -225,7 +216,7 @@ if (this.dialogType_ === DialogType.SELECT_OPEN_MULTI_FILE) { const multipleSelection = { urls: files, - multiple: true + multiple: true, }; this.selectFilesAndClose_(multipleSelection); return; @@ -308,16 +299,13 @@ } if (selection.multiple) { chrome.fileManagerPrivate.selectFiles( - selection.urls, - this.allowedPaths_ === AllowedPaths.NATIVE_PATH, + selection.urls, this.allowedPaths_ === AllowedPaths.NATIVE_PATH, onFileSelected); } else { chrome.fileManagerPrivate.selectFile( - selection.urls[0], - selection.filterIndex, + selection.urls[0], selection.filterIndex, this.dialogType_ !== DialogType.SELECT_SAVEAS_FILE /* for opening */, - this.allowedPaths_ === AllowedPaths.NATIVE_PATH, - onFileSelected); + this.allowedPaths_ === AllowedPaths.NATIVE_PATH, onFileSelected); } }; @@ -428,9 +416,10 @@ DialogActionController.prototype.onFileTypeFilterChanged_ = function() { this.fileFilter_.removeFilter('fileType'); const selectedIndex = this.dialogFooter_.selectedFilterIndex; - if (selectedIndex > 0) { // Specific filter selected. - const regexp = new RegExp('\\.(' + - this.fileTypes_[selectedIndex - 1].extensions.join('|') + ')$', 'i'); + if (selectedIndex > 0) { // Specific filter selected. + const regexp = new RegExp( + '\\.(' + this.fileTypes_[selectedIndex - 1].extensions.join('|') + ')$', + 'i'); const filter = entry => { return entry.isDirectory || regexp.test(entry.name); }; @@ -462,8 +451,7 @@ // input text box. const selection = this.fileSelectionHandler_.selection; if (this.dialogType_ === DialogType.SELECT_SAVEAS_FILE && - selection.totalCount === 1 && - selection.entries[0].isFile && + selection.totalCount === 1 && selection.entries[0].isFile && this.dialogFooter_.filenameInput.value !== selection.entries[0].name) { this.dialogFooter_.filenameInput.value = selection.entries[0].name; } @@ -510,18 +498,14 @@ } if (this.dialogType_ === DialogType.SELECT_OPEN_FILE) { - this.dialogFooter_.okButton.disabled = - selection.directoryCount !== 0 || - selection.fileCount !== 1 || - !this.fileSelectionHandler_.isAvailable(); + this.dialogFooter_.okButton.disabled = selection.directoryCount !== 0 || + selection.fileCount !== 1 || !this.fileSelectionHandler_.isAvailable(); return; } if (this.dialogType_ === DialogType.SELECT_OPEN_MULTI_FILE) { - this.dialogFooter_.okButton.disabled = - selection.directoryCount !== 0 || - selection.fileCount === 0 || - !this.fileSelectionHandler_.isAvailable(); + this.dialogFooter_.okButton.disabled = selection.directoryCount !== 0 || + selection.fileCount === 0 || !this.fileSelectionHandler_.isAvailable(); return; }
diff --git a/ui/file_manager/file_manager/foreground/js/dialog_type.js b/ui/file_manager/file_manager/foreground/js/dialog_type.js index b9ef0b7..b0e4721 100644 --- a/ui/file_manager/file_manager/foreground/js/dialog_type.js +++ b/ui/file_manager/file_manager/foreground/js/dialog_type.js
@@ -38,9 +38,9 @@ */ DialogType.isOpenDialog = type => { return type == DialogType.SELECT_OPEN_FILE || - type == DialogType.SELECT_OPEN_MULTI_FILE || - type == DialogType.SELECT_FOLDER || - type == DialogType.SELECT_UPLOAD_FOLDER; + type == DialogType.SELECT_OPEN_MULTI_FILE || + type == DialogType.SELECT_FOLDER || + type == DialogType.SELECT_UPLOAD_FOLDER; }; /** @@ -49,7 +49,7 @@ */ DialogType.isOpenFileDialog = type => { return type == DialogType.SELECT_OPEN_FILE || - type == DialogType.SELECT_OPEN_MULTI_FILE; + type == DialogType.SELECT_OPEN_MULTI_FILE; }; /** @@ -58,5 +58,5 @@ */ DialogType.isFolderDialog = type => { return type == DialogType.SELECT_FOLDER || - type == DialogType.SELECT_UPLOAD_FOLDER; + type == DialogType.SELECT_UPLOAD_FOLDER; };
diff --git a/ui/file_manager/file_manager/foreground/js/directory_contents.js b/ui/file_manager/file_manager/foreground/js/directory_contents.js index af95c70..192d493 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_contents.js +++ b/ui/file_manager/file_manager/foreground/js/directory_contents.js
@@ -201,8 +201,7 @@ */ scan(entriesCallback, successCallback, errorCallback) { chrome.fileManagerPrivate.searchDriveMetadata( - {query: '', types: this.searchType_, maxResults: 100}, - results => { + {query: '', types: this.searchType_, maxResults: 100}, results => { if (this.cancelled_) { errorCallback(util.createDOMError(util.FileError.ABORT_ERR)); return; @@ -931,25 +930,26 @@ } const chunk = entries.slice(i, i + MAX_CHUNK_SIZE); - prefetchMetadataQueue.run(((chunk, callbackInner) => { - this.prefetchMetadata(chunk, refresh, () => { - if (!prefetchMetadataQueue.isCancelled()) { - if (this.scanCancelled_) { - prefetchMetadataQueue.cancel(); - } - } + prefetchMetadataQueue.run( + ((chunk, callbackInner) => { + this.prefetchMetadata(chunk, refresh, () => { + if (!prefetchMetadataQueue.isCancelled()) { + if (this.scanCancelled_) { + prefetchMetadataQueue.cancel(); + } + } - // Checks if this is the last task. - if (prefetchMetadataQueue.getWaitingTasksCount() === 0 && - prefetchMetadataQueue.getRunningTasksCount() === 1) { - // |callbackOuter| in |finish| must be called before - // |callbackInner|, to prevent double-calling. - finish(); - } + // Checks if this is the last task. + if (prefetchMetadataQueue.getWaitingTasksCount() === 0 && + prefetchMetadataQueue.getRunningTasksCount() === 1) { + // |callbackOuter| in |finish| must be called before + // |callbackInner|, to prevent double-calling. + finish(); + } - callbackInner(); - }); - }).bind(null, chunk)); + callbackInner(); + }); + }).bind(null, chunk)); } }); }
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.js b/ui/file_manager/file_manager/foreground/js/directory_model.js index a3147c8bf..767e989 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_model.js +++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -26,7 +26,8 @@ singleSelection, fileFilter, metadataModel, volumeManager, fileOperationManager) { this.fileListSelection_ = singleSelection ? - new FileListSingleSelectionModel() : new FileListSelectionModel(); + new FileListSingleSelectionModel() : + new FileListSelectionModel(); this.runningScan_ = null; this.pendingScan_ = null; @@ -40,12 +41,12 @@ this.ignoreCurrentDirectoryDeletion_ = false; this.directoryChangeQueue_ = new AsyncUtil.Queue(); - this.rescanAggregator_ = new AsyncUtil.Aggregator( - this.rescanSoon.bind(this, true), 500); + this.rescanAggregator_ = + new AsyncUtil.Aggregator(this.rescanSoon.bind(this, true), 500); this.fileFilter_ = fileFilter; - this.fileFilter_.addEventListener('changed', - this.onFilterChanged_.bind(this)); + this.fileFilter_.addEventListener( + 'changed', this.onFilterChanged_.bind(this)); this.currentFileListContext_ = new FileListContext(fileFilter, metadataModel, volumeManager); @@ -70,11 +71,9 @@ */ this.fileWatcher_ = new FileWatcher(); this.fileWatcher_.addEventListener( - 'watcher-directory-changed', - this.onWatcherDirectoryChanged_.bind(this)); + 'watcher-directory-changed', this.onWatcherDirectoryChanged_.bind(this)); util.addEventListenerToBackgroundComponent( - fileOperationManager, - 'entries-changed', + fileOperationManager, 'entries-changed', this.onEntriesChanged_.bind(this)); /** @private {string} */ @@ -223,31 +222,32 @@ */ DirectoryModel.prototype.updateSelectionAndPublishEvent_ = (selection, updateFunc) => { - // Begin change. - selection.beginChange(); + // Begin change. + selection.beginChange(); - // If dispatchNeeded is true, we should ensure the change event is - // dispatched. - let dispatchNeeded = updateFunc(); + // If dispatchNeeded is true, we should ensure the change event is + // dispatched. + let dispatchNeeded = updateFunc(); - // Check if the change event is dispatched in the endChange function - // or not. - const eventDispatched = () => { - dispatchNeeded = false; - }; - selection.addEventListener('change', eventDispatched); - selection.endChange(); - selection.removeEventListener('change', eventDispatched); + // Check if the change event is dispatched in the endChange function + // or not. + const eventDispatched = () => { + dispatchNeeded = false; + }; + selection.addEventListener('change', eventDispatched); + selection.endChange(); + selection.removeEventListener('change', eventDispatched); - // If the change event have been already dispatched, dispatchNeeded is false. - if (dispatchNeeded) { - const event = new Event('change'); - // The selection status (selected or not) is not changed because - // this event is caused by the change of selected item. - event.changes = []; - selection.dispatchEvent(event); - } -}; + // If the change event have been already dispatched, dispatchNeeded is + // false. + if (dispatchNeeded) { + const event = new Event('change'); + // The selection status (selected or not) is not changed because + // this event is caused by the change of selected item. + event.changes = []; + selection.dispatchEvent(event); + } + }; /** * Sets to ignore current directory deletion. This method is used to prevent @@ -270,8 +270,7 @@ if (!this.ignoreCurrentDirectoryDeletion_) { // If the change is deletion of currentDir, move up to its parent directory. directoryEntry.getDirectory( - directoryEntry.fullPath, {create: false}, () => {}, - () => { + directoryEntry.fullPath, {create: false}, () => {}, () => { const volumeInfo = this.volumeManager_.getVolumeInfo(assert(directoryEntry)); if (volumeInfo) { @@ -293,17 +292,20 @@ } }); - util.URLsToEntries(addedOrUpdatedFileUrls).then(result => { - deletedFileUrls = deletedFileUrls.concat(result.failureUrls); + util.URLsToEntries(addedOrUpdatedFileUrls) + .then(result => { + deletedFileUrls = deletedFileUrls.concat(result.failureUrls); - // Passing the resolved entries and failed URLs as the removed files. - // The URLs are removed files and they chan't be resolved. - this.partialUpdate_(result.entries, deletedFileUrls); - }).catch(error => { - console.error('Error in proceeding the changed event.', error, - 'Fallback to force-refresh'); - this.rescanAggregator_.run(); - }); + // Passing the resolved entries and failed URLs as the removed files. + // The URLs are removed files and they chan't be resolved. + this.partialUpdate_(result.entries, deletedFileUrls); + }) + .catch(error => { + console.error( + 'Error in proceeding the changed event.', error, + 'Fallback to force-refresh'); + this.rescanAggregator_.run(); + }); } else { // Invokes force refresh if the detailed information isn't provided. // This can occur very frequently (e.g. when copying files into Downlaods) @@ -388,7 +390,8 @@ DirectoryModel.prototype.getLeadEntry_ = function() { const index = this.fileListSelection_.leadIndex; return index >= 0 ? - /** @type {Entry} */ (this.getFileList().item(index)) : null; + /** @type {Entry} */ (this.getFileList().item(index)) : + null; }; /** @@ -495,9 +498,8 @@ } }; - this.scan_(dirContents, - refresh, - successCallback, () => {}, () => {}, () => {}); + this.scan_( + dirContents, refresh, successCallback, () => {}, () => {}, () => {}); }; /** @@ -599,8 +601,9 @@ // Clear the table, and start scanning. cr.dispatchSimpleEvent(this, 'scan-started'); fileList.splice(0, fileList.length); - this.scan_(this.currentDirContents_, false, - onDone, onFailed, onUpdated, onCancelled); + this.scan_( + this.currentDirContents_, false, onDone, onFailed, onUpdated, + onCancelled); }; /** @@ -609,8 +612,8 @@ * @param {Array<string>} removedUrls URLs of removed files. * @private */ -DirectoryModel.prototype.partialUpdate_ = - function(changedEntries, removedUrls) { +DirectoryModel.prototype.partialUpdate_ = function( + changedEntries, removedUrls) { // This update should be included in the current running update. if (this.pendingScan_) { return; @@ -620,8 +623,8 @@ // Do update after the current scan is finished. const previousScan = this.runningScan_; const onPreviousScanCompleted = () => { - previousScan.removeEventListener('scan-completed', - onPreviousScanCompleted); + previousScan.removeEventListener( + 'scan-completed', onPreviousScanCompleted); // Run the update asynchronously. Promise.resolve().then(() => { this.partialUpdate_(changedEntries, removedUrls); @@ -634,11 +637,9 @@ const onFinish = () => { this.runningScan_ = null; - this.currentDirContents_.removeEventListener( - 'scan-completed', onCompleted); + this.currentDirContents_.removeEventListener('scan-completed', onCompleted); this.currentDirContents_.removeEventListener('scan-failed', onFailure); - this.currentDirContents_.removeEventListener( - 'scan-cancelled', onCancelled); + this.currentDirContents_.removeEventListener('scan-cancelled', onCancelled); }; const onCompleted = () => { @@ -677,9 +678,8 @@ * @private */ DirectoryModel.prototype.scan_ = function( - dirContents, - refresh, - successCallback, failureCallback, updatedCallback, cancelledCallback) { + dirContents, refresh, successCallback, failureCallback, updatedCallback, + cancelledCallback) { const self = this; /** @@ -708,9 +708,8 @@ // Record metric for Downloads directory. if (!dirContents.isSearch()) { - const locationInfo = - this.volumeManager_.getLocationInfo( - assert(dirContents.getDirectoryEntry())); + const locationInfo = this.volumeManager_.getLocationInfo( + assert(dirContents.getDirectoryEntry())); const volumeInfo = locationInfo && locationInfo.volumeInfo; if (volumeInfo && volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DOWNLOADS && @@ -767,7 +766,8 @@ * @private */ DirectoryModel.prototype.replaceDirectoryContents_ = function(dirContents) { - console.assert(this.currentDirContents_ !== dirContents, + console.assert( + this.currentDirContents_ !== dirContents, 'Give directory contents instance must be different from current one.'); cr.dispatchSimpleEvent(this, 'begin-update-files'); this.updateSelectionAndPublishEvent_(this.fileListSelection_, () => { @@ -793,8 +793,10 @@ if (this.fileListSelection_.selectedIndexes.length == 0 && selectedIndices.length != 0) { const maxIdx = Math.max.apply(null, selectedIndices); - this.selectIndex(Math.min(maxIdx - selectedIndices.length + 2, - this.getFileList().length) - 1); + this.selectIndex( + Math.min( + maxIdx - selectedIndices.length + 2, this.getFileList().length) - + 1); forceChangeEvent = true; } else if (isCheckSelectMode) { // Otherwise, ensure check select mode is retained if it was previously @@ -834,24 +836,26 @@ entries[i].getParent(resolve, reject); })); } - Promise.all(parentPromises).then(parents => { - const entriesToAdd = []; - for (let i = 0; i < parents.length; i++) { - if (!util.isSameEntry(parents[i], this.getCurrentDirEntry())) { - continue; - } - const index = this.findIndexByEntry_(entries[i]); - if (index >= 0) { - this.getFileList().replaceItem( - this.getFileList().item(index), entries[i]); - } else { - entriesToAdd.push(entries[i]); - } - } - this.partialUpdate_(entriesToAdd, []); - }).catch(error => { - console.error(error.stack || error); - }); + Promise.all(parentPromises) + .then(parents => { + const entriesToAdd = []; + for (let i = 0; i < parents.length; i++) { + if (!util.isSameEntry(parents[i], this.getCurrentDirEntry())) { + continue; + } + const index = this.findIndexByEntry_(entries[i]); + if (index >= 0) { + this.getFileList().replaceItem( + this.getFileList().item(index), entries[i]); + } else { + entriesToAdd.push(entries[i]); + } + } + this.partialUpdate_(entriesToAdd, []); + }) + .catch(error => { + console.error(error.stack || error); + }); break; case util.EntryChangedKind.DELETED: @@ -952,28 +956,28 @@ const dirContents = this.currentDirContents_; return new Promise((onFulfilled, onRejected) => { - dirContents.prefetchMetadata( - [newDirectory], false, onFulfilled); - }).then((sequence => { - // If current directory has changed during the prefetch, do not try to - // select new directory. - if (sequence !== this.changeDirectorySequence_) { - return Promise.reject(); - } + dirContents.prefetchMetadata([newDirectory], false, onFulfilled); + }) + .then((sequence => { + // If current directory has changed during the prefetch, do not + // try to select new directory. + if (sequence !== this.changeDirectorySequence_) { + return Promise.reject(); + } - // If target directory is already in the list, just select it. - const existing = this.getFileList().slice().filter(e => { - return e.name === newDirectory.name; - }); - if (existing.length) { - this.selectEntry(newDirectory); - } else { - this.fileListSelection_.beginChange(); - this.getFileList().splice(0, 0, newDirectory); - this.selectEntry(newDirectory); - this.fileListSelection_.endChange(); - } - }).bind(null, this.changeDirectorySequence_)); + // If target directory is already in the list, just select it. + const existing = this.getFileList().slice().filter(e => { + return e.name === newDirectory.name; + }); + if (existing.length) { + this.selectEntry(newDirectory); + } else { + this.fileListSelection_.beginChange(); + this.getFileList().splice(0, 0, newDirectory); + this.selectEntry(newDirectory); + this.fileListSelection_.endChange(); + } + }).bind(null, this.changeDirectorySequence_)); }; /** @@ -1021,9 +1025,9 @@ this.currentDirContents_.cancelScan(); } - this.directoryChangeQueue_.run(((sequence, queueTaskCallback) => { - this.fileWatcher_.changeWatchedDirectory(dirEntry) - .then(() => { + this.directoryChangeQueue_.run( + ((sequence, queueTaskCallback) => { + this.fileWatcher_.changeWatchedDirectory(dirEntry).then(() => { if (this.changeDirectorySequence_ !== sequence) { queueTaskCallback(); return; @@ -1036,27 +1040,24 @@ return; } - const previousDirEntry = - this.currentDirContents_.getDirectoryEntry(); - this.clearAndScan_( - newDirectoryContents, - result => { - // Calls the callback of the method when successful. - if (result && opt_callback) { - opt_callback(); - } + const previousDirEntry = this.currentDirContents_.getDirectoryEntry(); + this.clearAndScan_(newDirectoryContents, result => { + // Calls the callback of the method when successful. + if (result && opt_callback) { + opt_callback(); + } - // Notify that the current task of this.directoryChangeQueue_ - // is completed. - setTimeout(queueTaskCallback, 0); - }); + // Notify that the current task of this.directoryChangeQueue_ + // is completed. + setTimeout(queueTaskCallback, 0); + }); // For tests that open the dialog to empty directories, everything // is loaded at this point. util.testSendMessage('directory-change-complete'); - const previousVolumeInfo = - previousDirEntry ? - this.volumeManager_.getVolumeInfo(previousDirEntry) : null; + const previousVolumeInfo = previousDirEntry ? + this.volumeManager_.getVolumeInfo(previousDirEntry) : + null; // VolumeInfo for dirEntry. const currentVolumeInfo = this.getCurrentVolumeInfo(); const event = new Event('directory-changed'); @@ -1065,7 +1066,7 @@ event.volumeChanged = previousVolumeInfo !== currentVolumeInfo; this.dispatchEvent(event); }); - }).bind(null, this.changeDirectorySequence_)); + }).bind(null, this.changeDirectorySequence_)); }; /** @@ -1114,8 +1115,7 @@ start: function() { if (!this.active_) { - this.dm_.addEventListener('directory-changed', - this.onDirectoryChange_); + this.dm_.addEventListener('directory-changed', this.onDirectoryChange_); this.active_ = true; this.hasChanged = false; } @@ -1123,8 +1123,8 @@ stop: function() { if (this.active_) { - this.dm_.removeEventListener('directory-changed', - this.onDirectoryChange_); + this.dm_.removeEventListener( + 'directory-changed', this.onDirectoryChange_); this.active_ = false; } }, @@ -1281,11 +1281,12 @@ * @return {DirectoryContents} Directory contents. * @private */ -DirectoryModel.prototype.createDirectoryContents_ = - function(context, entry, opt_query) { +DirectoryModel.prototype.createDirectoryContents_ = function( + context, entry, opt_query) { const query = (opt_query || '').trimLeft(); const locationInfo = this.volumeManager_.getLocationInfo(entry); - const canUseDriveSearch = this.volumeManager_.getDriveConnectionState().type !== + const canUseDriveSearch = + this.volumeManager_.getDriveConnectionState().type !== VolumeManagerCommon.DriveConnectionType.OFFLINE && (locationInfo && locationInfo.isDriveBased); @@ -1347,8 +1348,7 @@ } return DirectoryContents.createForDriveMetadataSearch( context, - /** @type {!FakeEntry} */ (entry), - searchType); + /** @type {!FakeEntry} */ (entry), searchType); } // Local fetch or search. return DirectoryContents.createForDirectory( @@ -1383,9 +1383,8 @@ * gets cleared. * TODO(olege): Change callbacks to events. */ -DirectoryModel.prototype.search = function(query, - onSearchRescan, - onClearSearch) { +DirectoryModel.prototype.search = function( + query, onSearchRescan, onClearSearch) { this.lastSearchQuery_ = query; this.clearSearch_(); const currentDirEntry = this.getCurrentDirEntry(); @@ -1395,38 +1394,36 @@ } this.changeDirectorySequence_++; - this.directoryChangeQueue_.run(((sequence, callback) => { - if (this.changeDirectorySequence_ !== sequence) { - callback(); - return; - } + this.directoryChangeQueue_.run( + ((sequence, callback) => { + if (this.changeDirectorySequence_ !== sequence) { + callback(); + return; + } - if (!(query || '').trimLeft()) { - if (this.isSearching()) { + if (!(query || '').trimLeft()) { + if (this.isSearching()) { + const newDirContents = this.createDirectoryContents_( + this.currentFileListContext_, assert(currentDirEntry)); + this.clearAndScan_(newDirContents, callback); + } else { + callback(); + } + return; + } + const newDirContents = this.createDirectoryContents_( - this.currentFileListContext_, - assert(currentDirEntry)); - this.clearAndScan_(newDirContents, - callback); - } else { - callback(); - } - return; - } + this.currentFileListContext_, assert(currentDirEntry), query); + if (!newDirContents) { + callback(); + return; + } - const newDirContents = this.createDirectoryContents_( - this.currentFileListContext_, assert(currentDirEntry), query); - if (!newDirContents) { - callback(); - return; - } - - this.onSearchCompleted_ = onSearchRescan; - this.onClearSearch_ = onClearSearch; - this.addEventListener('scan-completed', this.onSearchCompleted_); - this.clearAndScan_(newDirContents, - callback); - }).bind(null, this.changeDirectorySequence_)); + this.onSearchCompleted_ = onSearchRescan; + this.onClearSearch_ = onClearSearch; + this.addEventListener('scan-completed', this.onSearchCompleted_); + this.clearAndScan_(newDirContents, callback); + }).bind(null, this.changeDirectorySequence_)); }; /**
diff --git a/ui/file_manager/file_manager/foreground/js/directory_tree_naming_controller.js b/ui/file_manager/file_manager/foreground/js/directory_tree_naming_controller.js index e25a8847..d28452b 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_tree_naming_controller.js +++ b/ui/file_manager/file_manager/foreground/js/directory_tree_naming_controller.js
@@ -87,7 +87,6 @@ */ DirectoryTreeNamingController.prototype.attachAndStart = function( directoryItem, isRemovableRoot, volumeInfo) { - this.isRemovableRoot_ = isRemovableRoot; this.volumeInfo_ = this.isRemovableRoot_ ? assert(volumeInfo) : null; @@ -153,13 +152,10 @@ parentEntry, newName, !this.directoryModel_.getFileFilter().isHiddenFilesVisible()); }) - .then( - this.performRename_.bind(this, entry, newName), - errorMessage => { - this.alertDialog_.show( - /** @type {string} */ (errorMessage), - this.detach_.bind(this)); - }); + .then(this.performRename_.bind(this, entry, newName), errorMessage => { + this.alertDialog_.show( + /** @type {string} */ (errorMessage), this.detach_.bind(this)); + }); } }; @@ -171,8 +167,8 @@ */ DirectoryTreeNamingController.prototype.performRename_ = function( entry, newName) { - const renamingCurrentDirectory = util.isSameEntry(entry, - this.directoryModel_.getCurrentDirEntry()); + const renamingCurrentDirectory = + util.isSameEntry(entry, this.directoryModel_.getCurrentDirEntry()); if (renamingCurrentDirectory) { this.directoryModel_.setIgnoringCurrentDirectoryDeletion(true /* ignore */); }
diff --git a/ui/file_manager/file_manager/foreground/js/empty_folder_controller.js b/ui/file_manager/file_manager/foreground/js/empty_folder_controller.js index a7b450a..e5788c9 100644 --- a/ui/file_manager/file_manager/foreground/js/empty_folder_controller.js +++ b/ui/file_manager/file_manager/foreground/js/empty_folder_controller.js
@@ -101,9 +101,7 @@ const query = this.directoryModel_.getLastSearchQuery(); let html = ''; if (query) { - html = strf( - 'SEARCH_NO_MATCHING_FILES_HTML', - util.htmlEscape(query)); + html = strf('SEARCH_NO_MATCHING_FILES_HTML', util.htmlEscape(query)); } else { html = str('EMPTY_FOLDER'); }
diff --git a/ui/file_manager/file_manager/foreground/js/file_list_model.js b/ui/file_manager/file_manager/foreground/js/file_list_model.js index 90f1da5..aff8f98 100644 --- a/ui/file_manager/file_manager/foreground/js/file_list_model.js +++ b/ui/file_manager/file_manager/foreground/js/file_list_model.js
@@ -300,8 +300,9 @@ this.numFiles_++; } - const mimeType = this.metadataModel_.getCache([entry], ['contentMimeType'])[0] - .contentMimeType; + const mimeType = + this.metadataModel_.getCache([entry], ['contentMimeType'])[0] + .contentMimeType; if (FileType.isImage(entry, mimeType) || FileType.isRaw(entry, mimeType)) { this.numImageFiles_++; } @@ -319,8 +320,9 @@ this.numFiles_--; } - const mimeType = this.metadataModel_.getCache([entry], ['contentMimeType'])[0] - .contentMimeType; + const mimeType = + this.metadataModel_.getCache([entry], ['contentMimeType'])[0] + .contentMimeType; if (FileType.isImage(entry, mimeType) || FileType.isRaw(entry, mimeType)) { this.numImageFiles_--; } @@ -441,7 +443,8 @@ return a.isDirectory === this.isDescendingOrder_ ? 1 : -1; } - const properties = this.metadataModel_.getCache([a, b], ['contentMimeType']); + const properties = + this.metadataModel_.getCache([a, b], ['contentMimeType']); const aType = FileListModel.getFileTypeString( FileType.getType(a, properties[0].contentMimeType)); const bType = FileListModel.getFileTypeString(
diff --git a/ui/file_manager/file_manager/foreground/js/file_list_model_unittest.js b/ui/file_manager/file_manager/foreground/js/file_list_model_unittest.js index db0c3b8..8909f42 100644 --- a/ui/file_manager/file_manager/foreground/js/file_list_model_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/file_list_model_unittest.js
@@ -65,61 +65,63 @@ } function testIsImageDominant() { - const fileListModel = new FileListModel(createFakeMetadataModel(TEST_METADATA)); + const fileListModel = + new FileListModel(createFakeMetadataModel(TEST_METADATA)); assertEquals(fileListModel.isImageDominant(), false); // Adding one image. Image should be dominant in this directory (100%). - fileListModel.push({ name: 'c.jpg', isDirectory: false}); + fileListModel.push({name: 'c.jpg', isDirectory: false}); assertEquals(fileListModel.isImageDominant(), true); // Adding a directory shouldn't affect how the image is dominant (still 100%). - fileListModel.push({ name: 'tmp_folder', isDirectory: true}); + fileListModel.push({name: 'tmp_folder', isDirectory: true}); assertEquals(fileListModel.isImageDominant(), true); // Adding a non-image file, which will make the images not dominant (50%); - fileListModel.push({ name: 'a.txt', isDirectory: false}); + fileListModel.push({name: 'a.txt', isDirectory: false}); assertEquals(fileListModel.isImageDominant(), false); // Adding two image. Now 75%(3/4) files are images. Still not dominant. - fileListModel.push({ name: 'c.jpg', isDirectory: false}); - fileListModel.push({ name: 'c.jpg', isDirectory: false}); + fileListModel.push({name: 'c.jpg', isDirectory: false}); + fileListModel.push({name: 'c.jpg', isDirectory: false}); assertEquals(fileListModel.isImageDominant(), false); // Adding one more. Now 80%(4/5) files are images. Reached the threshold. - fileListModel.push({ name: 'c.jpg', isDirectory: false}); + fileListModel.push({name: 'c.jpg', isDirectory: false}); assertEquals(fileListModel.isImageDominant(), true); } function testSortWithFolders() { - const fileListModel = new FileListModel(createFakeMetadataModel(TEST_METADATA)); - fileListModel.push({ name: 'dirA', isDirectory: true }); - fileListModel.push({ name: 'dirB', isDirectory: true }); - fileListModel.push({ name: 'a.txt', isDirectory: false }); - fileListModel.push({ name: 'b.html', isDirectory: false }); - fileListModel.push({ name: 'c.jpg', isDirectory: false }); + const fileListModel = + new FileListModel(createFakeMetadataModel(TEST_METADATA)); + fileListModel.push({name: 'dirA', isDirectory: true}); + fileListModel.push({name: 'dirB', isDirectory: true}); + fileListModel.push({name: 'a.txt', isDirectory: false}); + fileListModel.push({name: 'b.html', isDirectory: false}); + fileListModel.push({name: 'c.jpg', isDirectory: false}); // In following sort tests, note that folders should always be prior to files. fileListModel.sort('name', 'asc'); - assertFileListModelElementNames(fileListModel, - ['dirA', 'dirB', 'a.txt', 'b.html', 'c.jpg']); + assertFileListModelElementNames( + fileListModel, ['dirA', 'dirB', 'a.txt', 'b.html', 'c.jpg']); fileListModel.sort('name', 'desc'); - assertFileListModelElementNames(fileListModel, - ['dirB', 'dirA', 'c.jpg', 'b.html', 'a.txt']); + assertFileListModelElementNames( + fileListModel, ['dirB', 'dirA', 'c.jpg', 'b.html', 'a.txt']); // Sort files by size. Folders should be sorted by their names. fileListModel.sort('size', 'asc'); - assertFileListModelElementNames(fileListModel, - ['dirA', 'dirB', 'b.html', 'a.txt', 'c.jpg']); + assertFileListModelElementNames( + fileListModel, ['dirA', 'dirB', 'b.html', 'a.txt', 'c.jpg']); fileListModel.sort('size', 'desc'); - assertFileListModelElementNames(fileListModel, - ['dirB', 'dirA', 'c.jpg', 'a.txt', 'b.html']); + assertFileListModelElementNames( + fileListModel, ['dirB', 'dirA', 'c.jpg', 'a.txt', 'b.html']); // Sort files by modification. Folders should be sorted by their names. fileListModel.sort('modificationTime', 'asc'); - assertFileListModelElementNames(fileListModel, - ['dirA', 'dirB', 'c.jpg', 'b.html', 'a.txt']); + assertFileListModelElementNames( + fileListModel, ['dirA', 'dirB', 'c.jpg', 'b.html', 'a.txt']); fileListModel.sort('modificationTime', 'desc'); - assertFileListModelElementNames(fileListModel, - ['dirB', 'dirA', 'a.txt', 'b.html', 'c.jpg']); + assertFileListModelElementNames( + fileListModel, ['dirB', 'dirA', 'a.txt', 'b.html', 'c.jpg']); } function testSplice() { @@ -138,9 +140,8 @@ assertEquals(event.newLength, 5); }); - fileListModel.splice(2, 1, - { name: 'p', isDirectory: false }, - { name: 'b', isDirectory: false }); + fileListModel.splice( + 2, 1, {name: 'p', isDirectory: false}, {name: 'b', isDirectory: false}); assertFileListModelElementNames(fileListModel, ['a', 'b', 'd', 'p', 'x']); } @@ -159,9 +160,8 @@ assertEquals(event.newLength, 5); }); - fileListModel.splice(2, 1, - { name: 'p', isDirectory: false }, - { name: 'b', isDirectory: false }); + fileListModel.splice( + 2, 1, {name: 'p', isDirectory: false}, {name: 'b', isDirectory: false}); // If the sort status is not specified, the original order should be kept. // i.e. the 2nd element in the original array, 'x', should be removed, and // 'p' and 'b' should be inserted at the position without changing the order. @@ -204,9 +204,8 @@ assertEquals(event.newLength, 6); }); - fileListModel.splice(2, 0, - { name: 'p', isDirectory: false }, - { name: 'b', isDirectory: false }); - assertFileListModelElementNames(fileListModel, - ['a', 'b', 'd', 'n', 'p', 'x']); + fileListModel.splice( + 2, 0, {name: 'p', isDirectory: false}, {name: 'b', isDirectory: false}); + assertFileListModelElementNames( + fileListModel, ['a', 'b', 'd', 'n', 'p', 'x']); }
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js index 6757f16..9c07fc9 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -580,14 +580,10 @@ assert(this.fileFilter_); this.scanController_ = new ScanController( - this.directoryModel_, - this.ui_.listContainer, - this.spinnerController_, - this.commandHandler_, - this.selectionHandler_); + this.directoryModel_, this.ui_.listContainer, this.spinnerController_, + this.commandHandler_, this.selectionHandler_); this.sortMenuController_ = new SortMenuController( - this.ui_.sortButton, - this.ui_.sortButtonToggleRipple, + this.ui_.sortButton, this.ui_.sortButtonToggleRipple, assert(this.directoryModel_.getFileList())); this.gearMenuController_ = new GearMenuController( this.ui_.gearButton, this.ui_.gearButtonToggleRipple, this.ui_.gearMenu, @@ -597,19 +593,16 @@ this.ui_.selectionMenuButton, util.queryDecoratedElement('#file-context-menu', cr.ui.Menu)); this.toolbarController_ = new ToolbarController( - this.ui_.toolbar, - this.ui_.dialogNavigationList, - this.ui_.listContainer, - assert(this.ui_.locationLine), - this.selectionHandler_, + this.ui_.toolbar, this.ui_.dialogNavigationList, this.ui_.listContainer, + assert(this.ui_.locationLine), this.selectionHandler_, this.directoryModel_); this.emptyFolderController_ = new EmptyFolderController( this.ui_.emptyFolder, this.directoryModel_, this.ui_.alertDialog); this.actionsController_ = new ActionsController( this.volumeManager_, assert(this.metadataModel_), this.directoryModel_, assert(this.folderShortcutsModel_), - this.fileBrowserBackground_.driveSyncHandler, - this.selectionHandler_, assert(this.ui_)); + this.fileBrowserBackground_.driveSyncHandler, this.selectionHandler_, + assert(this.ui_)); this.lastModifiedController_ = new LastModifiedController( this.ui_.listContainer.table, this.directoryModel_); @@ -628,16 +621,15 @@ metadataBoxController, this.dialogType, assert(this.volumeManager_)); if (this.dialogType === DialogType.FULL_PAGE) { - importer.importEnabled().then( - enabled => { - if (enabled) { - this.importController_ = new importer.ImportController( - new importer.RuntimeControllerEnvironment( - this, assert(this.selectionHandler_)), - assert(this.mediaScanner_), assert(this.mediaImportHandler_), - new importer.RuntimeCommandWidget()); - } - }); + importer.importEnabled().then(enabled => { + if (enabled) { + this.importController_ = new importer.ImportController( + new importer.RuntimeControllerEnvironment( + this, assert(this.selectionHandler_)), + assert(this.mediaScanner_), assert(this.mediaImportHandler_), + new importer.RuntimeCommandWidget()); + } + }); } assert(this.fileFilter_); @@ -645,28 +637,19 @@ assert(this.appStateController_); assert(this.taskController_); this.mainWindowComponent_ = new MainWindowComponent( - this.dialogType, - this.ui_, - this.volumeManager_, - this.directoryModel_, - this.fileFilter_, - this.selectionHandler_, - this.namingController_, - this.appStateController_, - this.taskController_); + this.dialogType, this.ui_, this.volumeManager_, this.directoryModel_, + this.fileFilter_, this.selectionHandler_, this.namingController_, + this.appStateController_, this.taskController_); this.initDataTransferOperations_(); this.selectionHandler_.onFileSelectionChanged(); this.ui_.listContainer.endBatchUpdates(); - this.ui_.initBanners( - new Banners( - this.directoryModel_, - this.volumeManager_, - this.document_, - // Whether to show any welcome banner. - this.dialogType === DialogType.FULL_PAGE)); + this.ui_.initBanners(new Banners( + this.directoryModel_, this.volumeManager_, this.document_, + // Whether to show any welcome banner. + this.dialogType === DialogType.FULL_PAGE)); this.ui_.attachFilesTooltip(); @@ -846,7 +829,8 @@ } else { // Used by the select dialog only. const json = location.search ? - JSON.parse(decodeURIComponent(location.search.substr(1))) : {}; + JSON.parse(decodeURIComponent(location.search.substr(1))) : + {}; this.launchParams_ = new LaunchParam(json instanceof Object ? json : {}); } @@ -862,8 +846,8 @@ FileManager.prototype.startInitBackgroundPage_ = function() { return new Promise(resolve => { metrics.startInterval('Load.InitBackgroundPage'); - chrome.runtime.getBackgroundPage(/** @type {function(Window=)} */ ( - opt_backgroundPage => { + chrome.runtime.getBackgroundPage( + /** @type {function(Window=)} */ (opt_backgroundPage => { assert(opt_backgroundPage); this.backgroundPage_ = /** @type {!BackgroundWindow} */ (opt_backgroundPage); @@ -879,10 +863,8 @@ this.fileBrowserBackground_.fileOperationManager; this.mediaImportHandler_ = this.fileBrowserBackground_.mediaImportHandler; - this.mediaScanner_ = - this.fileBrowserBackground_.mediaScanner; - this.historyLoader_ = - this.fileBrowserBackground_.historyLoader; + this.mediaScanner_ = this.fileBrowserBackground_.mediaScanner; + this.historyLoader_ = this.fileBrowserBackground_.historyLoader; this.crostini_ = this.fileBrowserBackground_.crostini; metrics.recordInterval('Load.InitBackgroundPage'); resolve(); @@ -924,13 +906,14 @@ // Record stats of dialog types. New values must NOT be inserted into the // array enumerating the types. It must be in sync with // FileDialogType enum in tools/metrics/histograms/histogram.xml. - metrics.recordEnum('Create', this.dialogType, - [DialogType.SELECT_FOLDER, - DialogType.SELECT_UPLOAD_FOLDER, - DialogType.SELECT_SAVEAS_FILE, - DialogType.SELECT_OPEN_FILE, - DialogType.SELECT_OPEN_MULTI_FILE, - DialogType.FULL_PAGE]); + metrics.recordEnum('Create', this.dialogType, [ + DialogType.SELECT_FOLDER, + DialogType.SELECT_UPLOAD_FOLDER, + DialogType.SELECT_SAVEAS_FILE, + DialogType.SELECT_OPEN_FILE, + DialogType.SELECT_OPEN_MULTI_FILE, + DialogType.FULL_PAGE, + ]); // Create the metadata cache. assert(this.volumeManager_); @@ -964,23 +947,16 @@ const table = queryRequiredElement('.detail-table', dom); FileTable.decorate( - table, - this.metadataModel_, - this.volumeManager_, - this.historyLoader_, + table, this.metadataModel_, this.volumeManager_, this.historyLoader_, this.dialogType == DialogType.FULL_PAGE); const grid = queryRequiredElement('.thumbnail-grid', dom); FileGrid.decorate( - grid, - this.metadataModel_, - this.volumeManager_, - this.historyLoader_); + grid, this.metadataModel_, this.volumeManager_, this.historyLoader_); this.addHistoryObserver_(); this.ui_.initAdditionalUI( - assertInstanceof(table, FileTable), - assertInstanceof(grid, FileGrid), + assertInstanceof(table, FileTable), assertInstanceof(grid, FileGrid), new LocationLine( queryRequiredElement('#location-breadcrumbs', dom), this.volumeManager_)); @@ -1022,14 +998,13 @@ // we want to update grid/list view when it changes. this.historyLoader_.addHistoryLoadedListener( /** - * @param {!importer.ImportHistory} history - * @this {FileManager} - */ + * @param {!importer.ImportHistory} history + * @this {FileManager} + */ history => { this.importHistory_ = history; history.addObserver(this.onHistoryChangedBound_); }); - }; /** @@ -1044,16 +1019,14 @@ util.isChildEntry(event.entry, this.getCurrentDirectoryEntry()) .then( /** - * @param {boolean} isChild - */ + * @param {boolean} isChild + */ isChild => { if (isChild) { this.ui_.listContainer.grid.updateListItemsMetadata( - 'import-history', - [event.entry]); + 'import-history', [event.entry]); this.ui_.listContainer.table.updateListItemsMetadata( - 'import-history', - [event.entry]); + 'import-history', [event.entry]); } }); }; @@ -1063,8 +1036,7 @@ * @private */ FileManager.prototype.initFileList_ = function() { - const singleSelection = - this.dialogType == DialogType.SELECT_OPEN_FILE || + const singleSelection = this.dialogType == DialogType.SELECT_OPEN_FILE || this.dialogType == DialogType.SELECT_FOLDER || this.dialogType == DialogType.SELECT_UPLOAD_FOLDER || this.dialogType == DialogType.SELECT_SAVEAS_FILE; @@ -1076,8 +1048,8 @@ singleSelection, this.fileFilter_, this.metadataModel_, this.volumeManager_, this.fileOperationManager_); - this.folderShortcutsModel_ = new FolderShortcutsDataModel( - this.volumeManager_); + this.folderShortcutsModel_ = + new FolderShortcutsDataModel(this.volumeManager_); assert(this.launchParams_); this.selectionHandler_ = new FileSelectionHandler( @@ -1085,7 +1057,8 @@ assert(this.ui_.listContainer), assert(this.metadataModel_), assert(this.volumeManager_), this.launchParams_.allowedPaths); - this.directoryModel_.getFileListSelection().addEventListener('change', + this.directoryModel_.getFileListSelection().addEventListener( + 'change', this.selectionHandler_.onFileSelectionChanged.bind( this.selectionHandler_)); @@ -1094,8 +1067,7 @@ this.initDirectoryTree_(); this.ui_.listContainer.listThumbnailLoader = new ListThumbnailLoader( - this.directoryModel_, - assert(this.thumbnailModel_), + this.directoryModel_, assert(this.thumbnailModel_), this.volumeManager_); this.ui_.listContainer.dataModel = this.directoryModel_.getFileList(); this.ui_.listContainer.emptyDataModel = @@ -1112,9 +1084,7 @@ // Create metadata update controller. this.metadataUpdateController_ = new MetadataUpdateController( - this.ui_.listContainer, - this.directoryModel_, - this.metadataModel_, + this.ui_.listContainer, this.directoryModel_, this.metadataModel_, this.fileMetadataFormatter_); // Create naming controller. @@ -1132,34 +1102,24 @@ // Create search controller. this.searchController_ = new SearchController( - this.ui_.searchBox, - assert(this.ui_.locationLine), - this.directoryModel_, - this.volumeManager_, - assert(this.taskController_)); + this.ui_.searchBox, assert(this.ui_.locationLine), this.directoryModel_, + this.volumeManager_, assert(this.taskController_)); // Create directory tree naming controller. this.directoryTreeNamingController_ = new DirectoryTreeNamingController( - this.directoryModel_, - assert(this.ui_.directoryTree), + this.directoryModel_, assert(this.ui_.directoryTree), this.ui_.alertDialog); // Create spinner controller. - this.spinnerController_ = new SpinnerController( - this.ui_.listContainer.spinner); + this.spinnerController_ = + new SpinnerController(this.ui_.listContainer.spinner); this.spinnerController_.blink(); // Create dialog action controller. this.dialogActionController_ = new DialogActionController( - this.dialogType, - this.ui_.dialogFooter, - this.directoryModel_, - this.metadataModel_, - this.volumeManager_, - this.fileFilter_, - this.namingController_, - this.selectionHandler_, - this.launchParams_); + this.dialogType, this.ui_.dialogFooter, this.directoryModel_, + this.metadataModel_, this.volumeManager_, this.fileFilter_, + this.namingController_, this.selectionHandler_, this.launchParams_); }; /** @@ -1171,12 +1131,10 @@ const fakeEntriesVisible = this.dialogType !== DialogType.SELECT_SAVEAS_FILE; this.navigationUma_ = new NavigationUma(assert(this.volumeManager_)); - DirectoryTree.decorate(directoryTree, - assert(this.directoryModel_), - assert(this.volumeManager_), - assert(this.metadataModel_), - assert(this.fileOperationManager_), - fakeEntriesVisible); + DirectoryTree.decorate( + directoryTree, assert(this.directoryModel_), + assert(this.volumeManager_), assert(this.metadataModel_), + assert(this.fileOperationManager_), fakeEntriesVisible); directoryTree.dataModel = new NavigationListModel( assert(this.volumeManager_), assert(this.folderShortcutsModel_), fakeEntriesVisible && @@ -1412,8 +1370,7 @@ // a file, or in case of a fallback of the current directory, then try to // resolve again using the target name. queue.run((callback) => { - if (selectionEntry || - !nextCurrentDirEntry || + if (selectionEntry || !nextCurrentDirEntry || !this.launchParams_.targetName) { callback(); return; @@ -1459,9 +1416,7 @@ } // Finish setup current directory. this.finishSetupCurrentDirectory_( - nextCurrentDirEntry, - selectionEntry, - this.launchParams_.targetName); + nextCurrentDirEntry, selectionEntry, this.launchParams_.targetName); callback(); }); }; @@ -1526,8 +1481,7 @@ this.volumeManager_.dispose(); } if (this.fileTransferController_) { - for (let i = 0; - i < this.fileTransferController_.pendingTaskIds.length; + for (let i = 0; i < this.fileTransferController_.pendingTaskIds.length; i++) { const taskId = this.fileTransferController_.pendingTaskIds[i]; const item =
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 f2195dff..4ebba5a 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
@@ -48,8 +48,8 @@ if (element instanceof DirectoryTree) { // element is a DirectoryTree. return element.selectedItem ? [element.selectedItem.entry] : []; - } else if (element instanceof DirectoryItem || - element instanceof ShortcutItem) { + } else if ( + element instanceof DirectoryItem || element instanceof ShortcutItem) { // element are sub items in DirectoryTree. return element.entry ? [element.entry] : []; } else if (element instanceof cr.ui.List) { @@ -81,8 +81,8 @@ } const parentItem = element.selectedItem.parentItem; return parentItem ? parentItem.entry : null; - } else if (element instanceof DirectoryItem || - element instanceof ShortcutItem) { + } else if ( + element instanceof DirectoryItem || element instanceof ShortcutItem) { return element.parentItem ? element.parentItem.entry : null; } else if (element instanceof cr.ui.List) { return directoryModel ? directoryModel.getCurrentDirEntry() : null; @@ -104,8 +104,8 @@ return element.volumeInfo; } if (element instanceof ShortcutItem) { - return element.entry && fileManager.volumeManager.getVolumeInfo( - element.entry); + return element.entry && + fileManager.volumeManager.getVolumeInfo(element.entry); } return null; }; @@ -116,8 +116,9 @@ */ CommandUtil.getCurrentVolumeInfo = fileManager => { const currentDirEntry = fileManager.directoryModel.getCurrentDirEntry(); - return currentDirEntry ? fileManager.volumeManager.getVolumeInfo( - currentDirEntry) : null; + return currentDirEntry ? + fileManager.volumeManager.getVolumeInfo(currentDirEntry) : + null; }; /** @@ -129,8 +130,8 @@ CommandUtil.getEntryFromNavigationModelItem_ = item => { switch (item.type) { case NavigationModelItemType.VOLUME: - return /** @type {!NavigationModelVolumeItem} */ ( - item).volumeInfo.displayRoot; + return /** @type {!NavigationModelVolumeItem} */ (item) + .volumeInfo.displayRoot; case NavigationModelItemType.SHORTCUT: return /** @type {!NavigationModelShortcutItem} */ (item).entry; } @@ -152,12 +153,13 @@ * @param {!Event} event Command event to mark. * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use. */ -CommandUtil.canExecuteVisibleOnDriveInNormalAppModeOnly = (event, fileManager) => { - const enabled = fileManager.directoryModel.isOnDrive() && - !DialogType.isModal(fileManager.dialogType); - event.canExecute = enabled; - event.command.setHidden(!enabled); -}; +CommandUtil.canExecuteVisibleOnDriveInNormalAppModeOnly = + (event, fileManager) => { + const enabled = fileManager.directoryModel.isOnDrive() && + !DialogType.isModal(fileManager.dialogType); + event.canExecute = enabled; + event.command.setHidden(!enabled); + }; /** * Sets as the command as always enabled. @@ -221,8 +223,8 @@ * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use. */ canExecute: function(event, fileManager) { - event.canExecute = index > 0 && - index <= fileManager.directoryTree.items.length; + event.canExecute = + index > 0 && index <= fileManager.directoryTree.items.length; } }); }; @@ -243,7 +245,7 @@ if (!selection.entries[0].isDirectory) { return null; } - return /** @type {!DirectoryEntry} */(selection.entries[0]); + return /** @type {!DirectoryEntry} */ (selection.entries[0]); }; /** @@ -514,8 +516,8 @@ CommandHandler.prototype.shouldIgnoreEvents_ = function() { // Do not handle commands, when a dialog is shown. Do not use querySelector // as it's much slower, and this method is executed often. - const dialogs = this.fileManager_.document.getElementsByClassName( - 'cr-dialog-container'); + const dialogs = + this.fileManager_.document.getElementsByClassName('cr-dialog-container'); if (dialogs.length !== 0 && dialogs[0].classList.contains('shown')) { return true; } @@ -533,8 +535,8 @@ return; } const handler = CommandHandler.COMMANDS_[event.command.id]; - handler.execute.call(/** @type {Command} */ (handler), event, - this.fileManager_); + handler.execute.call( + /** @type {Command} */ (handler), event, this.fileManager_); }; /** @@ -547,8 +549,8 @@ return; } const handler = CommandHandler.COMMANDS_[event.command.id]; - handler.canExecute.call(/** @type {Command} */ (handler), event, - this.fileManager_); + handler.canExecute.call( + /** @type {Command} */ (handler), event, this.fileManager_); }; /** @@ -637,10 +639,10 @@ const volumeType = (event.target instanceof EntryListItem) ? entry.rootType : volumeInfo.volumeType; - event.canExecute = ( - volumeType === VolumeManagerCommon.VolumeType.ARCHIVE || - volumeType === VolumeManagerCommon.VolumeType.REMOVABLE || - volumeType === VolumeManagerCommon.VolumeType.PROVIDED); + event.canExecute = + (volumeType === VolumeManagerCommon.VolumeType.ARCHIVE || + volumeType === VolumeManagerCommon.VolumeType.REMOVABLE || + volumeType === VolumeManagerCommon.VolumeType.PROVIDED); event.command.setHidden(!event.canExecute); switch (volumeType) { @@ -678,8 +680,8 @@ if (volumeInfo) { fileManager.ui.confirmDialog.show( loadTimeData.getString('FORMATTING_WARNING'), - chrome.fileManagerPrivate.formatVolume.bind(null, - volumeInfo.volumeId), + chrome.fileManagerPrivate.formatVolume.bind( + null, volumeInfo.volumeId), null, null); } }, @@ -810,15 +812,17 @@ const index = opt_index || 0; const defaultName = str('DEFAULT_NEW_FOLDER_NAME'); - const newName = index === 0 ? defaultName : - defaultName + ' (' + index + ')'; + const newName = + index === 0 ? defaultName : defaultName + ' (' + index + ')'; return new Promise(parentDirectory.getDirectory.bind( - parentDirectory, newName, {create: false})).then(newEntry => { - return this.generateNewDirectoryName_(parentDirectory, index + 1); - }).catch(() => { - return newName; - }); + parentDirectory, newName, {create: false})) + .then(newEntry => { + return this.generateNewDirectoryName_(parentDirectory, index + 1); + }) + .catch(() => { + return newName; + }); }; /** @@ -877,8 +881,7 @@ * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use. */ canExecute: function(event, fileManager) { - event.canExecute = - fileManager.getCurrentDirectoryEntry() && + event.canExecute = fileManager.getCurrentDirectoryEntry() && (fileManager.dialogType === DialogType.FULL_PAGE); } }); @@ -1102,8 +1105,8 @@ fileManager.directoryModel.getCurrentDirEntry()); // Hide this command if only one folder is selected. - event.command.setHidden(!!CommandUtil.getOnlyOneSelectedDirectory( - fileManager.getSelection())); + event.command.setHidden( + !!CommandUtil.getOnlyOneSelectedDirectory(fileManager.getSelection())); } }); @@ -1309,7 +1312,8 @@ const parentEntry = CommandUtil.getParentEntry(renameTarget, fileManager.directoryModel); const locationInfo = parentEntry ? - fileManager.volumeManager.getLocationInfo(parentEntry) : null; + fileManager.volumeManager.getLocationInfo(parentEntry) : + null; const volumeIsNotReadOnly = !!locationInfo && !locationInfo.isReadOnly; event.canExecute = entries.length === 1 && volumeIsNotReadOnly && CommandUtil.hasCapability(entries, 'canRename'); @@ -1558,7 +1562,7 @@ return; } - event.canExecute = entries.length === 1; + event.canExecute = entries.length === 1; event.command.setHidden(false); } }); @@ -1623,12 +1627,15 @@ * @param {!CommandHandlerDeps} fileManager */ execute: function(event, fileManager) { - const actionsModel = fileManager.actionsController.getActionsModelFor( - event.target); - const saveForOfflineAction = actionsModel ? actionsModel.getAction( - ActionsModel.CommonActionId.SAVE_FOR_OFFLINE) : null; - const offlineNotNeededAction = actionsModel ? actionsModel.getAction( - ActionsModel.CommonActionId.OFFLINE_NOT_NECESSARY) : null; + const actionsModel = + fileManager.actionsController.getActionsModelFor(event.target); + const saveForOfflineAction = actionsModel ? + actionsModel.getAction(ActionsModel.CommonActionId.SAVE_FOR_OFFLINE) : + null; + const offlineNotNeededAction = actionsModel ? + actionsModel.getAction( + ActionsModel.CommonActionId.OFFLINE_NOT_NECESSARY) : + null; // Saving for offline has a priority if both actions are available. const action = saveForOfflineAction || offlineNotNeededAction; if (action) { @@ -1641,12 +1648,15 @@ * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use. */ canExecute: function(event, fileManager) { - const actionsModel = fileManager.actionsController.getActionsModelFor( - event.target); - const saveForOfflineAction = actionsModel ? actionsModel.getAction( - ActionsModel.CommonActionId.SAVE_FOR_OFFLINE) : null; - const offlineNotNeededAction = actionsModel ? actionsModel.getAction( - ActionsModel.CommonActionId.OFFLINE_NOT_NECESSARY) : null; + const actionsModel = + fileManager.actionsController.getActionsModelFor(event.target); + const saveForOfflineAction = actionsModel ? + actionsModel.getAction(ActionsModel.CommonActionId.SAVE_FOR_OFFLINE) : + null; + const offlineNotNeededAction = actionsModel ? + actionsModel.getAction( + ActionsModel.CommonActionId.OFFLINE_NOT_NECESSARY) : + null; const action = saveForOfflineAction || offlineNotNeededAction; event.canExecute = action && action.canExecute(); @@ -1716,7 +1726,8 @@ } event.command.setHidden(false); - const isOnEligibleLocation = CommandHandler.IS_ZIP_ARCHIVER_PACKER_ENABLED_ ? + const isOnEligibleLocation = + CommandHandler.IS_ZIP_ARCHIVER_PACKER_ENABLED_ ? true : !fileManager.directoryModel.isOnDrive() && !fileManager.directoryModel.isOnMTP(); @@ -1739,10 +1750,12 @@ // To toolbar buttons are always related to the file list, even though the // focus is on the navigation list. This assumption will break once we add // Share to the context menu on the navigation list. crbug.com/530418 - const actionsModel = fileManager.actionsController.getActionsModelForContext( - ActionsController.Context.FILE_LIST); - const action = actionsModel ? actionsModel.getAction( - ActionsModel.CommonActionId.SHARE) : null; + const actionsModel = + fileManager.actionsController.getActionsModelForContext( + ActionsController.Context.FILE_LIST); + const action = actionsModel ? + actionsModel.getAction(ActionsModel.CommonActionId.SHARE) : + null; if (action) { action.execute(); } @@ -1752,10 +1765,12 @@ * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use. */ canExecute: function(event, fileManager) { - const actionsModel = fileManager.actionsController.getActionsModelForContext( - ActionsController.Context.FILE_LIST); - const action = actionsModel ? actionsModel.getAction( - ActionsModel.CommonActionId.SHARE) : null; + const actionsModel = + fileManager.actionsController.getActionsModelForContext( + ActionsController.Context.FILE_LIST); + const action = actionsModel ? + actionsModel.getAction(ActionsModel.CommonActionId.SHARE) : + null; event.canExecute = action && action.canExecute(); // If model is not computed yet, then keep the previous visibility to avoid // flickering. @@ -1946,10 +1961,12 @@ * @param {!CommandHandlerDeps} fileManager The file manager instance. */ execute: function(event, fileManager) { - const actionsModel = fileManager.actionsController.getActionsModelFor( - event.target); - const action = actionsModel ? actionsModel.getAction( - ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT) : null; + const actionsModel = + fileManager.actionsController.getActionsModelFor(event.target); + const action = actionsModel ? + actionsModel.getAction( + ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT) : + null; if (action) { action.execute(); } @@ -1959,10 +1976,12 @@ * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use. */ canExecute: function(event, fileManager) { - const actionsModel = fileManager.actionsController.getActionsModelFor( - event.target); - const action = actionsModel ? actionsModel.getAction( - ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT) : null; + const actionsModel = + fileManager.actionsController.getActionsModelFor(event.target); + const action = actionsModel ? + actionsModel.getAction( + ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT) : + null; event.canExecute = action && action.canExecute(); if (actionsModel) { event.command.setHidden(!action); @@ -1980,10 +1999,12 @@ * @param {!CommandHandlerDeps} fileManager The file manager instance. */ execute: function(event, fileManager) { - const actionsModel = fileManager.actionsController.getActionsModelFor( - event.target); - const action = actionsModel ? actionsModel.getAction( - ActionsModel.InternalActionId.REMOVE_FOLDER_SHORTCUT) : null; + const actionsModel = + fileManager.actionsController.getActionsModelFor(event.target); + const action = actionsModel ? + actionsModel.getAction( + ActionsModel.InternalActionId.REMOVE_FOLDER_SHORTCUT) : + null; if (action) { action.execute(); } @@ -1993,10 +2014,12 @@ * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use. */ canExecute: function(event, fileManager) { - const actionsModel = fileManager.actionsController.getActionsModelFor( - event.target); - const action = actionsModel ? actionsModel.getAction( - ActionsModel.InternalActionId.REMOVE_FOLDER_SHORTCUT) : null; + const actionsModel = + fileManager.actionsController.getActionsModelFor(event.target); + const action = actionsModel ? + actionsModel.getAction( + ActionsModel.InternalActionId.REMOVE_FOLDER_SHORTCUT) : + null; event.canExecute = action && action.canExecute(); if (actionsModel) { event.command.setHidden(!action); @@ -2171,14 +2194,13 @@ * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use. */ execute: function(event, fileManager) { - fileManager.ui.suggestAppsDialog.showProviders( - (result, itemId) => { - // If a new provider is installed, then launch it so the configuration - // dialog is shown (if it's available). - if (result === SuggestAppsDialog.Result.SUCCESS) { - fileManager.providersModel.requestMount(assert(itemId)); - } - }); + fileManager.ui.suggestAppsDialog.showProviders((result, itemId) => { + // If a new provider is installed, then launch it so the configuration + // dialog is shown (if it's available). + if (result === SuggestAppsDialog.Result.SUCCESS) { + fileManager.providersModel.requestMount(assert(itemId)); + } + }); }, canExecute: function(event, fileManager) { event.canExecute = fileManager.dialogType === DialogType.FULL_PAGE; @@ -2295,7 +2317,8 @@ const volumeInfo = currentDirEntry && fileManager.volumeManager.getVolumeInfo(currentDirEntry); event.canExecute = volumeInfo && !volumeInfo.watchable; - event.command.setHidden(!event.canExecute || + event.command.setHidden( + !event.canExecute || fileManager.directoryModel.getFileListSelection().getCheckSelectMode()); } }); @@ -2312,35 +2335,40 @@ const entry = fileManager.getSelection().entries[0]; new Promise((resolve, reject) => { entry.file(resolve, reject); - }).then(blob => { - const fileReader = new FileReader(); - return new Promise((resolve, reject) => { - fileReader.onload = () => { - resolve(fileReader.result); - }; - fileReader.onerror = () => { - reject(fileReader.error); - }; - fileReader.readAsArrayBuffer(blob); - }); - }).then((/** @type {!ArrayBuffer} */ arrayBuffer) => { - return new Promise((resolve, reject) => { - chrome.wallpaper.setWallpaper({ - data: arrayBuffer, - layout: chrome.wallpaper.WallpaperLayout.CENTER_CROPPED, - filename: 'wallpaper' - }, () => { - if (chrome.runtime.lastError) { - reject(chrome.runtime.lastError); - }else{ - resolve(null); - } + }) + .then(blob => { + const fileReader = new FileReader(); + return new Promise((resolve, reject) => { + fileReader.onload = () => { + resolve(fileReader.result); + }; + fileReader.onerror = () => { + reject(fileReader.error); + }; + fileReader.readAsArrayBuffer(blob); }); - }); - }).catch(() => { - fileManager.ui.alertDialog.showHtml( - '', str('ERROR_INVALID_WALLPAPER'), null, null, null); - }); + }) + .then((/** @type {!ArrayBuffer} */ arrayBuffer) => { + return new Promise((resolve, reject) => { + chrome.wallpaper.setWallpaper( + { + data: arrayBuffer, + layout: chrome.wallpaper.WallpaperLayout.CENTER_CROPPED, + filename: 'wallpaper' + }, + () => { + if (chrome.runtime.lastError) { + reject(chrome.runtime.lastError); + } else { + resolve(null); + } + }); + }); + }) + .catch(() => { + fileManager.ui.alertDialog.showHtml( + '', str('ERROR_INVALID_WALLPAPER'), null, null, null); + }); }, canExecute: function(event, fileManager) { const entries = fileManager.getSelection().entries;
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks.js b/ui/file_manager/file_manager/foreground/js/file_tasks.js index 8d8ce5de..abb09e5 100644 --- a/ui/file_manager/file_manager/foreground/js/file_tasks.js +++ b/ui/file_manager/file_manager/foreground/js/file_tasks.js
@@ -173,72 +173,66 @@ * @param {!Crostini} crostini * @return {!Promise<!FileTasks>} */ -FileTasks.create = ( - volumeManager, - metadataModel, - directoryModel, - ui, - entries, - mimeTypes, - taskHistory, - namingController, - crostini -) => { - const tasksPromise = new Promise(fulfill => { - // getFileTasks supports only native entries. - entries = entries.filter(util.isNativeEntry); - if (entries.length === 0) { - fulfill([]); - return; - } - chrome.fileManagerPrivate.getFileTasks(entries, taskItems => { - if (chrome.runtime.lastError) { - console.error('Failed to fetch file tasks due to: ' + - chrome.runtime.lastError.message); - Promise.reject(); - return; - } +FileTasks.create = + (volumeManager, metadataModel, directoryModel, ui, entries, mimeTypes, + taskHistory, namingController, crostini) => { + const tasksPromise = new Promise(fulfill => { + // getFileTasks supports only native entries. + entries = entries.filter(util.isNativeEntry); + if (entries.length === 0) { + fulfill([]); + return; + } + chrome.fileManagerPrivate.getFileTasks(entries, taskItems => { + if (chrome.runtime.lastError) { + console.error( + 'Failed to fetch file tasks due to: ' + + chrome.runtime.lastError.message); + Promise.reject(); + return; + } - // Linux package installation is currently only supported for a single - // file which is inside the Linux container, or in a sharable volume. - // TODO(timloh): Instead of filtering these out, we probably should show - // a dialog with an error message, similar to when attempting to run - // Crostini tasks with non-Crostini entries. - if (entries.length !== 1 || - !(FileTasks.isCrostiniEntry(entries[0], volumeManager) || - crostini.canSharePath(entries[0], false /* persist */))) { - taskItems = taskItems.filter(item => { - const taskParts = item.taskId.split('|'); - const appId = taskParts[0]; - const taskType = taskParts[1]; - const actionId = taskParts[2]; - return !( - appId === chrome.runtime.id && taskType === 'app' && - actionId === 'install-linux-package'); + // Linux package installation is currently only supported for a single + // file which is inside the Linux container, or in a shareable volume. + // TODO(timloh): Instead of filtering these out, we probably should + // show a dialog with an error message, similar to when attempting to + // run Crostini tasks with non-Crostini entries. + if (entries.length !== 1 || + !(FileTasks.isCrostiniEntry(entries[0], volumeManager) || + crostini.canSharePath(entries[0], false /* persist */))) { + taskItems = taskItems.filter(item => { + const taskParts = item.taskId.split('|'); + const appId = taskParts[0]; + const taskType = taskParts[1]; + const actionId = taskParts[2]; + return !( + appId === chrome.runtime.id && taskType === 'app' && + actionId === 'install-linux-package'); + }); + } + + // Filters out Pack with Zip Archiver task because it will be + // accessible via 'Zip selection' context menu button + taskItems = taskItems.filter(item => { + return item.taskId !== FileTasks.ZIP_ARCHIVER_ZIP_TASK_ID && + item.taskId !== FileTasks.ZIP_ARCHIVER_ZIP_USING_TMP_TASK_ID; + }); + + fulfill(FileTasks.annotateTasks_(assert(taskItems), entries)); }); - } - - // Filters out Pack with Zip Archiver task because it will be accessible - // via 'Zip selection' context menu button - taskItems = taskItems.filter(item => { - return item.taskId !== FileTasks.ZIP_ARCHIVER_ZIP_TASK_ID && - item.taskId !== FileTasks.ZIP_ARCHIVER_ZIP_USING_TMP_TASK_ID; }); - fulfill(FileTasks.annotateTasks_(assert(taskItems), entries)); - }); - }); + const defaultTaskPromise = tasksPromise.then(tasks => { + return FileTasks.getDefaultTask(tasks, taskHistory); + }); - const defaultTaskPromise = tasksPromise.then(tasks => { - return FileTasks.getDefaultTask(tasks, taskHistory); - }); - - return Promise.all([tasksPromise, defaultTaskPromise]).then(args => { - return new FileTasks( - volumeManager, metadataModel, directoryModel, ui, entries, mimeTypes, - args[0], args[1], taskHistory, namingController, crostini); - }); -}; + return Promise.all([tasksPromise, defaultTaskPromise]).then(args => { + return new FileTasks( + volumeManager, metadataModel, directoryModel, ui, entries, + mimeTypes, args[0], args[1], taskHistory, namingController, + crostini); + }); + }; /** * Obtains the task items. @@ -349,7 +343,10 @@ * @private */ FileTasks.EXTENSIONS_TO_SKIP_SUGGEST_APPS_ = Object.freeze([ - '.crdownload', '.dsc', '.inf', '.crx', + '.crdownload', + '.dsc', + '.inf', + '.crx', ]); /** @@ -383,14 +380,15 @@ * @param {!*} value Enum value. * @param {!Array<*>} values Array of valid values. */ -FileTasks.recordEnumWithOnlineAndOffline_ = (volumeManager, name, value, values) => { - metrics.recordEnum(name, value, values); - if (FileTasks.isOffline_(volumeManager)) { - metrics.recordEnum(name + '.Offline', value, values); - } else { - metrics.recordEnum(name + '.Online', value, values); - } -}; +FileTasks.recordEnumWithOnlineAndOffline_ = + (volumeManager, name, value, values) => { + metrics.recordEnum(name, value, values); + if (FileTasks.isOffline_(volumeManager)) { + metrics.recordEnum(name + '.Offline', value, values); + } else { + metrics.recordEnum(name + '.Online', value, values); + } + }; /** * Records trial of opening file grouped by extensions. @@ -741,8 +739,7 @@ // a task picker to ask the user to choose one. if (nonGenericTasks.length >= 2) { this.showTaskPicker( - this.ui_.defaultTaskPicker, str('OPEN_WITH_BUTTON_LABEL'), - '', task => { + this.ui_.defaultTaskPicker, str('OPEN_WITH_BUTTON_LABEL'), '', task => { this.execute(task); }, FileTasks.TaskPickerType.OpenWith); return; @@ -918,12 +915,11 @@ return okEntriesNum === props.length; }; - const containsDriveEntries = - this.entries_.some(entry => { - const volumeInfo = this.volumeManager_.getVolumeInfo(entry); - return volumeInfo && volumeInfo.volumeType === - VolumeManagerCommon.VolumeType.DRIVE; - }); + const containsDriveEntries = this.entries_.some(entry => { + const volumeInfo = this.volumeManager_.getVolumeInfo(entry); + return volumeInfo && + volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DRIVE; + }); // Availability is not checked for non-Drive files, as availableOffline, nor // availableWhenMetered are not exposed for other types of volumes at this @@ -937,8 +933,8 @@ VolumeManagerCommon.DriveConnectionType.OFFLINE; if (isDriveOffline) { - this.metadataModel_.get(this.entries_, ['availableOffline', 'hosted']).then( - props => { + this.metadataModel_.get(this.entries_, ['availableOffline', 'hosted']) + .then(props => { if (areAll(this.entries_, props, 'availableOffline')) { callback(); return; @@ -952,12 +948,11 @@ 'HOSTED_OFFLINE_MESSAGE' : 'HOSTED_OFFLINE_MESSAGE_PLURAL') : loadTimeData.getStringF( - this.entries_.length === 1 ? - 'OFFLINE_MESSAGE' : - 'OFFLINE_MESSAGE_PLURAL', + this.entries_.length === 1 ? 'OFFLINE_MESSAGE' : + 'OFFLINE_MESSAGE_PLURAL', loadTimeData.getString('OFFLINE_COLUMN_LABEL')), null, null, null); - }); + }); return; } @@ -980,9 +975,8 @@ } this.ui_.confirmDialog.show( loadTimeData.getStringF( - this.entries_.length === 1 ? - 'CONFIRM_MOBILE_DATA_USE' : - 'CONFIRM_MOBILE_DATA_USE_PLURAL', + this.entries_.length === 1 ? 'CONFIRM_MOBILE_DATA_USE' : + 'CONFIRM_MOBILE_DATA_USE_PLURAL', util.bytesToString(sizeToDownload)), callback, null, null); }); @@ -1035,36 +1029,31 @@ const urls = util.entriesToURLs(this.entries_); for (let index = 0; index < urls.length; ++index) { // TODO(mtomasz): Pass Entry instead of URL. - this.volumeManager_.mountArchive( - urls[index], - volumeInfo => { - if (tracker.hasChanged) { + this.volumeManager_.mountArchive(urls[index], volumeInfo => { + if (tracker.hasChanged) { + tracker.stop(); + return; + } + volumeInfo.resolveDisplayRoot( + displayRoot => { + if (tracker.hasChanged) { + tracker.stop(); + return; + } + this.directoryModel_.changeDirectoryEntry(displayRoot); + }, + () => { + console.warn('Failed to resolve the display root after mounting.'); tracker.stop(); - return; - } - volumeInfo.resolveDisplayRoot( - displayRoot => { - if (tracker.hasChanged) { - tracker.stop(); - return; - } - this.directoryModel_.changeDirectoryEntry(displayRoot); - }, - () => { - console.warn( - 'Failed to resolve the display root after mounting.'); - tracker.stop(); - }); - }, - ((url, error) => { - tracker.stop(); - const path = util.extractFilePath(url); - const namePos = path.lastIndexOf('/'); - this.ui_.alertDialog.show( - strf('ARCHIVE_MOUNT_FAILED', path.substr(namePos + 1), error), - null, - null); - }).bind(null, urls[index])); + }); + }, ((url, error) => { + tracker.stop(); + const path = util.extractFilePath(url); + const namePos = path.lastIndexOf('/'); + this.ui_.alertDialog.show( + strf('ARCHIVE_MOUNT_FAILED', path.substr(namePos + 1), error), + null, null); + }).bind(null, urls[index])); } }; @@ -1239,8 +1228,8 @@ for (let index = 0; index < tasks.length; index++) { const task = tasks[index]; if (task === this.defaultTask_) { - const title = task.title + ' ' + - loadTimeData.getString('DEFAULT_TASK_LABEL'); + const title = + task.title + ' ' + loadTimeData.getString('DEFAULT_TASK_LABEL'); items.push(this.createCombobuttonItem_(task, title, true, true)); } else { items.push(this.createCombobuttonItem_(task)); @@ -1294,18 +1283,19 @@ * list. * @private */ -FileTasks.prototype.createCombobuttonItem_ = (task, opt_title, opt_bold, opt_isDefault) => { - return { - type: FileTasks.TaskMenuButtonItemType.RunTask, - label: opt_title || task.label || task.title, - iconUrl: task.iconUrl || '', - iconType: task.iconType || '', - task: task, - bold: opt_bold || false, - isDefault: opt_isDefault || false, - isGenericFileHandler: /** @type {boolean} */ (task.isGenericFileHandler) - }; -}; +FileTasks.prototype.createCombobuttonItem_ = + (task, opt_title, opt_bold, opt_isDefault) => { + return { + type: FileTasks.TaskMenuButtonItemType.RunTask, + label: opt_title || task.label || task.title, + iconUrl: task.iconUrl || '', + iconType: task.iconType || '', + task: task, + bold: opt_bold || false, + isDefault: opt_isDefault || false, + isGenericFileHandler: /** @type {boolean} */ (task.isGenericFileHandler) + }; + }; /** * Shows modal task picker dialog with currently available list of tasks. @@ -1336,13 +1326,9 @@ } } - taskDialog.showDefaultTaskDialog( - title, - message, - items, defaultIdx, - item => { - onSuccess(item.task); - }); + taskDialog.showDefaultTaskDialog(title, message, items, defaultIdx, item => { + onSuccess(item.task); + }); }; /**
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.js b/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.js index 0eed63b..c745ca8 100644 --- a/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.js
@@ -215,8 +215,10 @@ const mockFileSystem = new MockFileSystem('volumeId'); const mockEntry = new MockFileEntry(mockFileSystem, '/test.exe'); - reportPromise(showHtmlOfAlertDialogIsCalled( - [mockEntry], 'test.exe', 'NO_TASK_FOR_EXECUTABLE'), callback); + reportPromise( + showHtmlOfAlertDialogIsCalled( + [mockEntry], 'test.exe', 'NO_TASK_FOR_EXECUTABLE'), + callback); } /** @@ -226,8 +228,9 @@ const mockFileSystem = new MockFileSystem('volumeId'); const mockEntry = new MockFileEntry(mockFileSystem, '/test.dmg'); - reportPromise(showHtmlOfAlertDialogIsCalled( - [mockEntry], 'test.dmg', 'NO_TASK_FOR_DMG'), callback); + reportPromise( + showHtmlOfAlertDialogIsCalled([mockEntry], 'test.dmg', 'NO_TASK_FOR_DMG'), + callback); } /** @@ -237,8 +240,10 @@ const mockFileSystem = new MockFileSystem('volumeId'); const mockEntry = new MockFileEntry(mockFileSystem, '/test.crx'); - reportPromise(showHtmlOfAlertDialogIsCalled( - [mockEntry], 'NO_TASK_FOR_CRX_TITLE', 'NO_TASK_FOR_CRX'), callback); + reportPromise( + showHtmlOfAlertDialogIsCalled( + [mockEntry], 'NO_TASK_FOR_CRX_TITLE', 'NO_TASK_FOR_CRX'), + callback); } /** @@ -248,8 +253,9 @@ const mockFileSystem = new MockFileSystem('volumeId'); const mockEntry = new MockFileEntry(mockFileSystem, '/test.rtf'); - reportPromise(openSuggestAppsDialogIsCalled( - [mockEntry], ['application/rtf']), callback); + reportPromise( + openSuggestAppsDialogIsCalled([mockEntry], ['application/rtf']), + callback); } /** @@ -281,8 +287,7 @@ [mockEntry], ['application/rtf'], mockTaskHistory, fileManager.namingController, fileManager.crostini) .then(tasks => { - tasks.openSuggestAppsDialog( - () => {}, () => {}, () => {}); + tasks.openSuggestAppsDialog(() => {}, () => {}, () => {}); }); }); @@ -396,10 +401,11 @@ }); let executedTask = null; - window.chrome.fileManagerPrivate.executeTask = (taskId, entries, onViewFiles) => { - executedTask = taskId; - onViewFiles('success'); - }; + window.chrome.fileManagerPrivate.executeTask = + (taskId, entries, onViewFiles) => { + executedTask = taskId; + onViewFiles('success'); + }; const mockFileSystem = new MockFileSystem('volumeId'); const mockEntry = new MockFileEntry(mockFileSystem, '/test.tiff'); @@ -467,10 +473,11 @@ }); let executedTask = null; - window.chrome.fileManagerPrivate.executeTask = (taskId, entries, onViewFiles) => { - executedTask = taskId; - onViewFiles('success'); - }; + window.chrome.fileManagerPrivate.executeTask = + (taskId, entries, onViewFiles) => { + executedTask = taskId; + onViewFiles('success'); + }; const mockFileSystem = new MockFileSystem('volumeId'); const mockEntry = new MockFileEntry(mockFileSystem, '/test.zip');
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js index 0d3bd11..947da5a 100644 --- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js +++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
@@ -377,10 +377,12 @@ */ FileTransferController.URLsToEntriesWithAccess = urls => { return new Promise((resolve, reject) => { - chrome.fileManagerPrivate.grantAccess(urls, resolve.bind(null, undefined)); - }).then(() => { - return util.URLsToEntries(urls); - }); + chrome.fileManagerPrivate.grantAccess( + urls, resolve.bind(null, undefined)); + }) + .then(() => { + return util.URLsToEntries(urls); + }); }; /** @@ -406,15 +408,15 @@ * accetps files (putting it into the current directory). * @private */ -FileTransferController.prototype.attachFileListDropTarget_ = - function(list, opt_onlyIntoDirectories) { - list.addEventListener('dragover', this.onDragOver_.bind(this, - !!opt_onlyIntoDirectories, list)); - list.addEventListener('dragenter', - this.onDragEnterFileList_.bind(this, list)); +FileTransferController.prototype.attachFileListDropTarget_ = function( + list, opt_onlyIntoDirectories) { + list.addEventListener( + 'dragover', this.onDragOver_.bind(this, !!opt_onlyIntoDirectories, list)); + list.addEventListener( + 'dragenter', this.onDragEnterFileList_.bind(this, list)); list.addEventListener('dragleave', this.onDragLeave_.bind(this, list)); - list.addEventListener('drop', - this.onDrop_.bind(this, !!opt_onlyIntoDirectories)); + list.addEventListener( + 'drop', this.onDrop_.bind(this, !!opt_onlyIntoDirectories)); }; /** @@ -433,22 +435,19 @@ * @private */ FileTransferController.prototype.attachCopyPasteHandlers_ = function() { - this.document_.addEventListener('beforecopy', - this.onBeforeCutOrCopy_.bind( - this, false /* not move operation */)); - this.document_.addEventListener('copy', - this.onCutOrCopy_.bind( - this, false /* not move operation */)); - this.document_.addEventListener('beforecut', - this.onBeforeCutOrCopy_.bind( - this, true /* move operation */)); - this.document_.addEventListener('cut', - this.onCutOrCopy_.bind( - this, true /* move operation */)); - this.document_.addEventListener('beforepaste', - this.onBeforePaste_.bind(this)); - this.document_.addEventListener('paste', - this.onPaste_.bind(this)); + this.document_.addEventListener( + 'beforecopy', + this.onBeforeCutOrCopy_.bind(this, false /* not move operation */)); + this.document_.addEventListener( + 'copy', this.onCutOrCopy_.bind(this, false /* not move operation */)); + this.document_.addEventListener( + 'beforecut', + this.onBeforeCutOrCopy_.bind(this, true /* move operation */)); + this.document_.addEventListener( + 'cut', this.onCutOrCopy_.bind(this, true /* move operation */)); + this.document_.addEventListener( + 'beforepaste', this.onBeforePaste_.bind(this)); + this.document_.addEventListener('paste', this.onPaste_.bind(this)); }; /** @@ -473,11 +472,11 @@ return; } - this.appendCutOrCopyInfo_(clipboardData, effectAllowed, volumeInfo, + this.appendCutOrCopyInfo_( + clipboardData, effectAllowed, volumeInfo, this.selectionHandler_.selection.entries, !this.selectionHandler_.isAvailable()); - this.appendUriList_(clipboardData, - this.selectionHandler_.selection.entries); + this.appendUriList_(clipboardData, this.selectionHandler_.selection.entries); }; /** @@ -490,27 +489,23 @@ * @param {boolean} missingFileContents * @private */ -FileTransferController.prototype.appendCutOrCopyInfo_ = ( - clipboardData, - effectAllowed, - sourceVolumeInfo, - entries, - missingFileContents -) => { - // Tag to check it's filemanager data. - clipboardData.setData('fs/tag', 'filemanager-data'); - clipboardData.setData('fs/sourceRootURL', - sourceVolumeInfo.fileSystem.root.toURL()); +FileTransferController.prototype.appendCutOrCopyInfo_ = + (clipboardData, effectAllowed, sourceVolumeInfo, entries, + missingFileContents) => { + // Tag to check it's filemanager data. + clipboardData.setData('fs/tag', 'filemanager-data'); + clipboardData.setData( + 'fs/sourceRootURL', sourceVolumeInfo.fileSystem.root.toURL()); - const sourceURLs = util.entriesToURLs(entries); - clipboardData.setData('fs/sources', sourceURLs.join('\n')); + const sourceURLs = util.entriesToURLs(entries); + clipboardData.setData('fs/sources', sourceURLs.join('\n')); - clipboardData.effectAllowed = effectAllowed; - clipboardData.setData('fs/effectallowed', effectAllowed); + clipboardData.effectAllowed = effectAllowed; + clipboardData.setData('fs/effectallowed', effectAllowed); - clipboardData.setData('fs/missingFileContents', - missingFileContents.toString()); -}; + clipboardData.setData( + 'fs/missingFileContents', missingFileContents.toString()); + }; /** * Appends uri-list of |entries| to |clipboardData|. @@ -569,28 +564,29 @@ * @return {string} URL or an empty string (if unknown). * @private */ -FileTransferController.prototype.getSourceRootURL_ = (clipboardData, dragAndDropData) => { - const sourceRootURL = clipboardData.getData('fs/sourceRootURL'); - if (sourceRootURL) { - return sourceRootURL; - } +FileTransferController.prototype.getSourceRootURL_ = + (clipboardData, dragAndDropData) => { + const sourceRootURL = clipboardData.getData('fs/sourceRootURL'); + if (sourceRootURL) { + return sourceRootURL; + } - // |clipboardData| in protected mode. - if (dragAndDropData) { - return dragAndDropData.sourceRootURL; - } + // |clipboardData| in protected mode. + if (dragAndDropData) { + return dragAndDropData.sourceRootURL; + } - // Unknown source. - return ''; -}; + // Unknown source. + return ''; + }; /** * @param {!ClipboardData} clipboardData DataTransfer object from the event. * @return {boolean} Returns true when missing some file contents. * @private */ -FileTransferController.prototype.isMissingFileContents_ = - function(clipboardData) { +FileTransferController.prototype.isMissingFileContents_ = function( + clipboardData) { let data = clipboardData.getData('fs/missingFileContents'); if (!data) { // |clipboardData| in protected mode. @@ -610,8 +606,8 @@ * that need to share. * @private */ -FileTransferController.prototype.getMultiProfileShareEntries_ = - function(entries) { +FileTransferController.prototype.getMultiProfileShareEntries_ = function( + entries) { // Utility function to concat arrays. const concatArrays = arrays => { return Array.prototype.concat.apply([], arrays); @@ -635,16 +631,17 @@ // Check all file entries and keeps only those need sharing operation. const processFileEntries = entries => { return new Promise(callback => { - // Do not use metadata cache here because the urls come from the different - // profile. - chrome.fileManagerPrivate.getEntryProperties( - entries, ['hosted', 'sharedWithMe'], callback); - }).then(metadatas => { - return entries.filter((entry, i) => { - const metadata = metadatas[i]; - return metadata && metadata.hosted && !metadata.sharedWithMe; - }); - }); + // Do not use metadata cache here because the urls come from the + // different profile. + chrome.fileManagerPrivate.getEntryProperties( + entries, ['hosted', 'sharedWithMe'], callback); + }) + .then(metadatas => { + return entries.filter((entry, i) => { + const metadata = metadatas[i]; + return metadata && metadata.hosted && !metadata.sharedWithMe; + }); + }); }; // Check child entries. @@ -655,21 +652,21 @@ // Read entries from DirectoryReader and call processEntries for the chunk // of entries. const readEntries = reader => { - return new Promise(reader.readEntries.bind(reader)).then( - entries => { - if (entries.length > 0) { - return Promise.all( - [processEntries(entries), readEntries(reader)]). - then(concatArrays); - } else { - return []; - } - }, - error => { - console.warn( - 'Error happens while reading directory.', error); - return []; - }); + return new Promise(reader.readEntries.bind(reader)) + .then( + entries => { + if (entries.length > 0) { + return Promise + .all([processEntries(entries), readEntries(reader)]) + .then(concatArrays); + } else { + return []; + } + }, + error => { + console.warn('Error happens while reading directory.', error); + return []; + }); }; // Filter entries that is owned by the current user, and call @@ -689,11 +686,13 @@ FileTransferController.prototype.preparePaste = function( clipboardData, opt_destinationEntry, opt_effect) { const sourceURLs = clipboardData.getData('fs/sources') ? - clipboardData.getData('fs/sources').split('\n') : []; + clipboardData.getData('fs/sources').split('\n') : + []; // effectAllowed set in copy/paste handlers stay uninitialized. DnD handlers // work fine. const effectAllowed = clipboardData.effectAllowed !== 'uninitialized' ? - clipboardData.effectAllowed : clipboardData.getData('fs/effectallowed'); + clipboardData.effectAllowed : + clipboardData.getData('fs/effectallowed'); const destinationEntry = opt_destinationEntry || /** @type {DirectoryEntry} */ (this.directoryModel_.getCurrentDirEntry()); const toMove = util.isDropEffectAllowed(effectAllowed, 'move') && @@ -796,59 +795,59 @@ FileTransferController.URLsToEntriesWithAccess(sourceURLs) .then(/** - * @param {Object} result - */ - result => { - failureUrls = result.failureUrls; - // The promise is not rejected, so it's safe to not remove the - // early progress center item here. - return this.fileOperationManager_.filterSameDirectoryEntry( - result.entries, destinationEntry, toMove); - }) + * @param {Object} result + */ + result => { + failureUrls = result.failureUrls; + // The promise is not rejected, so it's safe to not remove the + // early progress center item here. + return this.fileOperationManager_.filterSameDirectoryEntry( + result.entries, destinationEntry, toMove); + }) .then(/** - * @param {!Array<Entry>} filteredEntries - * @return {!Promise<Array<Entry>>} - */ - filteredEntries => { - entries = filteredEntries; - if (entries.length === 0) { - return Promise.reject('ABORT'); - } + * @param {!Array<Entry>} filteredEntries + * @return {!Promise<Array<Entry>>} + */ + filteredEntries => { + entries = filteredEntries; + if (entries.length === 0) { + return Promise.reject('ABORT'); + } - this.pendingTaskIds.push(taskId); - const item = new ProgressCenterItem(); - item.id = taskId; - if (toMove) { - item.type = ProgressItemType.MOVE; - if (entries.length === 1) { - item.message = strf('MOVE_FILE_NAME', entries[0].name); - } else { - item.message = strf('MOVE_ITEMS_REMAINING', entries.length); - } - } else { - item.type = ProgressItemType.COPY; - if (entries.length === 1) { - item.message = strf('COPY_FILE_NAME', entries[0].name); - } else { - item.message = strf('COPY_ITEMS_REMAINING', entries.length); - } - } - this.progressCenter_.updateItem(item); - // Check if cross share is needed or not. - return this.getMultiProfileShareEntries_(entries); - }) + this.pendingTaskIds.push(taskId); + const item = new ProgressCenterItem(); + item.id = taskId; + if (toMove) { + item.type = ProgressItemType.MOVE; + if (entries.length === 1) { + item.message = strf('MOVE_FILE_NAME', entries[0].name); + } else { + item.message = strf('MOVE_ITEMS_REMAINING', entries.length); + } + } else { + item.type = ProgressItemType.COPY; + if (entries.length === 1) { + item.message = strf('COPY_FILE_NAME', entries[0].name); + } else { + item.message = strf('COPY_ITEMS_REMAINING', entries.length); + } + } + this.progressCenter_.updateItem(item); + // Check if cross share is needed or not. + return this.getMultiProfileShareEntries_(entries); + }) .then(/** - * @param {Array<Entry>} inShareEntries - * @return {!Promise<Array<Entry>>|!Promise<null>} - */ - inShareEntries => { - shareEntries = inShareEntries; - if (shareEntries.length === 0) { - return Promise.resolve(null); - } - return this.multiProfileShareDialog_.showMultiProfileShareDialog( - shareEntries.length > 1); - }) + * @param {Array<Entry>} inShareEntries + * @return {!Promise<Array<Entry>>|!Promise<null>} + */ + inShareEntries => { + shareEntries = inShareEntries; + if (shareEntries.length === 0) { + return Promise.resolve(null); + } + return this.multiProfileShareDialog_.showMultiProfileShareDialog( + shareEntries.length > 1); + }) .then( /** * @param {?string} dialogResult @@ -869,8 +868,7 @@ } return new Promise(fulfill => { chrome.fileManagerPrivate.requestDriveShare( - shareEntries[index], assert(dialogResult), - () => { + shareEntries[index], assert(dialogResult), () => { // TODO(hirono): Check chrome.runtime.lastError // here. fulfill(); @@ -881,28 +879,27 @@ return requestDriveShare(0); }) .then(() => { - // Start the pasting operation. - this.fileOperationManager_.paste( - entries, destinationEntry, toMove, taskId); - this.pendingTaskIds.splice( - this.pendingTaskIds.indexOf(taskId), 1); + // Start the pasting operation. + this.fileOperationManager_.paste( + entries, destinationEntry, toMove, taskId); + this.pendingTaskIds.splice(this.pendingTaskIds.indexOf(taskId), 1); - // Publish source not found error item. - for (let i = 0; i < failureUrls.length; i++) { - const fileName = - decodeURIComponent(failureUrls[i].replace(/^.+\//, '')); - const item = new ProgressCenterItem(); - item.id = 'source-not-found-' + this.sourceNotFoundErrorCount_; - if (toMove) { - item.message = strf('MOVE_SOURCE_NOT_FOUND_ERROR', fileName); - } else { - item.message = strf('COPY_SOURCE_NOT_FOUND_ERROR', fileName); - } - item.state = ProgressItemState.ERROR; - this.progressCenter_.updateItem(item); - this.sourceNotFoundErrorCount_++; - } - }) + // Publish source not found error item. + for (let i = 0; i < failureUrls.length; i++) { + const fileName = + decodeURIComponent(failureUrls[i].replace(/^.+\//, '')); + const item = new ProgressCenterItem(); + item.id = 'source-not-found-' + this.sourceNotFoundErrorCount_; + if (toMove) { + item.message = strf('MOVE_SOURCE_NOT_FOUND_ERROR', fileName); + } else { + item.message = strf('COPY_SOURCE_NOT_FOUND_ERROR', fileName); + } + item.state = ProgressItemState.ERROR; + this.progressCenter_.updateItem(item); + this.sourceNotFoundErrorCount_++; + } + }) .catch(error => { if (error !== 'ABORT') { console.error(error.stack ? error.stack : error); @@ -978,15 +975,10 @@ const srcHeight = Math.min(canvas.height * minScale, thumbnailImage.height); const context = canvas.getContext('2d'); - context.drawImage(thumbnailImage, - (thumbnailImage.width - srcWidth) / 2, - (thumbnailImage.height - srcHeight) / 2, - srcWidth, - srcHeight, - 0, - 0, - canvas.width, - canvas.height); + context.drawImage( + thumbnailImage, (thumbnailImage.width - srcWidth) / 2, + (thumbnailImage.height - srcHeight) / 2, srcWidth, srcHeight, 0, 0, + canvas.width, canvas.height); contents.classList.add('for-image'); contents.appendChild(canvas); return container; @@ -1105,8 +1097,8 @@ * @param {Event} event A dragover event of DOM. * @private */ -FileTransferController.prototype.onDragOver_ = - function(onlyIntoDirectories, list, event) { +FileTransferController.prototype.onDragOver_ = function( + onlyIntoDirectories, list, event) { event.preventDefault(); let entry = this.destinationEntry_; if (!entry && !onlyIntoDirectories) { @@ -1118,7 +1110,7 @@ event.preventDefault(); const label = effectAndLabel.getLabel(); if (!this.dropLabel_) { - this.dropLabel_ = document.querySelector("div#drop-label"); + this.dropLabel_ = document.querySelector('div#drop-label'); } if (label) { this.dropLabel_.innerText = label; @@ -1211,8 +1203,8 @@ if (onlyIntoDirectories && !this.dropTarget_) { return; } - const destinationEntry = this.destinationEntry_ || - this.directoryModel_.getCurrentDirEntry(); + const destinationEntry = + this.destinationEntry_ || this.directoryModel_.getCurrentDirEntry(); if (!this.canPasteOrDrop_(event.dataTransfer, destinationEntry)) { return; } @@ -1346,8 +1338,7 @@ * @private */ FileTransferController.prototype.onCutOrCopy_ = function(isMove, event) { - if (!this.isDocumentWideEvent_() || - !this.canCutOrCopy_(isMove)) { + if (!this.isDocumentWideEvent_() || !this.canCutOrCopy_(isMove)) { return; } @@ -1396,8 +1387,8 @@ this.volumeManager_.getDriveConnectionState().type === VolumeManagerCommon.DriveConnectionType.OFFLINE; - this.appendCutOrCopyInfo_(clipboardData, effectAllowed, volumeInfo, [entry], - missingFileContents); + this.appendCutOrCopyInfo_( + clipboardData, effectAllowed, volumeInfo, [entry], missingFileContents); }; /** @@ -1447,8 +1438,8 @@ return false; } - const metadata = this.metadataModel_.getCache( - [entry], ['canCopy', 'canDelete']); + const metadata = + this.metadataModel_.getCache([entry], ['canCopy', 'canDelete']); assert(metadata.length === 1); if (!isMove) { @@ -1476,7 +1467,7 @@ return false; } - return isMove ? this.canCutOrDrag_() : this.canCopyOrDrag_() ; + return isMove ? this.canCutOrDrag_() : this.canCopyOrDrag_(); }; /** @@ -1564,8 +1555,9 @@ return; } // queryCommandEnabled returns true if event.defaultPrevented is true. - if (this.canPasteOrDrop_(assert(event.clipboardData), - this.directoryModel_.getCurrentDirEntry())) { + if (this.canPasteOrDrop_( + assert(event.clipboardData), + this.directoryModel_.getCurrentDirEntry())) { event.preventDefault(); } }; @@ -1634,8 +1626,8 @@ // should be used. let result; this.simulateCommand_('paste', event => { - result = this.canPasteOrDrop_( - assert(event.clipboardData), destinationEntry); + result = + this.canPasteOrDrop_(assert(event.clipboardData), destinationEntry); }); return result; }; @@ -1771,14 +1763,14 @@ } if (destinationLocationInfo.volumeInfo && destinationLocationInfo.volumeInfo.isReadOnlyRemovableDevice) { - return new DropEffectAndLabel(DropEffectType.NONE, - strf('DEVICE_WRITE_PROTECTED')); + return new DropEffectAndLabel( + DropEffectType.NONE, strf('DEVICE_WRITE_PROTECTED')); } // The disk device is not write-protected but read-only. // Currently, the only remaining possibility is that write access to // removable drives is restricted by device policy. - return new DropEffectAndLabel(DropEffectType.NONE, - strf('DEVICE_ACCESS_RESTRICTED')); + return new DropEffectAndLabel( + DropEffectType.NONE, strf('DEVICE_ACCESS_RESTRICTED')); } const destinationMetadata = this.metadataModel_.getCache([destinationEntry], ['canAddChildren']);
diff --git a/ui/file_manager/file_manager/foreground/js/file_watcher.js b/ui/file_manager/file_manager/foreground/js/file_watcher.js index 6522e29..a393db2b 100644 --- a/ui/file_manager/file_manager/foreground/js/file_watcher.js +++ b/ui/file_manager/file_manager/foreground/js/file_watcher.js
@@ -59,8 +59,7 @@ // When watched directory is deleted by the change in parent directory, // notify it as watcher directory changed. this.watchedDirectoryEntry_.getDirectory( - this.watchedDirectoryEntry_.fullPath, {create: false}, null, - () => { + this.watchedDirectoryEntry_.fullPath, {create: false}, null, () => { fireWatcherDirectoryChanged(null); }); } @@ -95,10 +94,10 @@ // Release the watched directory. if (this.watchedDirectoryEntry_) { chrome.fileManagerPrivate.removeFileWatch( - this.watchedDirectoryEntry_, - result => { + this.watchedDirectoryEntry_, result => { if (chrome.runtime.lastError) { - console.error('Failed to remove the watcher because of: ' + + console.error( + 'Failed to remove the watcher because of: ' + chrome.runtime.lastError.message); } // Even on error reset the watcher locally, so at least the @@ -126,22 +125,19 @@ const setEntryClosure = () => { // Run the tasks in the queue to avoid races. this.queue_.run(callback => { - chrome.fileManagerPrivate.addFileWatch( - entry, - result => { - if (chrome.runtime.lastError) { - // Most probably setting the watcher is not supported on the - // file system type. - console.info('File watchers not supported for: ' + - entry.toURL()); - this.watchedDirectoryEntry_ = null; - fulfill(); - } else { - this.watchedDirectoryEntry_ = assert(entry); - fulfill(); - } - callback(); - }); + chrome.fileManagerPrivate.addFileWatch(entry, result => { + if (chrome.runtime.lastError) { + // Most probably setting the watcher is not supported on the + // file system type. + console.info('File watchers not supported for: ' + entry.toURL()); + this.watchedDirectoryEntry_ = null; + fulfill(); + } else { + this.watchedDirectoryEntry_ = assert(entry); + fulfill(); + } + callback(); + }); }); };
diff --git a/ui/file_manager/file_manager/foreground/js/folder_shortcuts_data_model.js b/ui/file_manager/file_manager/foreground/js/folder_shortcuts_data_model.js index e94d7cf..eed06c0f 100644 --- a/ui/file_manager/file_manager/foreground/js/folder_shortcuts_data_model.js +++ b/ui/file_manager/file_manager/foreground/js/folder_shortcuts_data_model.js
@@ -148,24 +148,24 @@ const group = new AsyncUtil.Group(); list.forEach(function(path) { group.add(((path, callback) => { - const url = - this.lastDriveRootURL_ && this.convertStoredPathToUrl_(path); - if (url && volumeInfo) { - window.webkitResolveLocalFileSystemURL( - url, - entry => { - onResolveSuccess(path, entry); - callback(); - }, - () => { - onResolveFailure(path, url); - callback(); - }); - } else { - onResolveFailure(path, url); - callback(); - } - }).bind(null, path)); + const url = this.lastDriveRootURL_ && + this.convertStoredPathToUrl_(path); + if (url && volumeInfo) { + window.webkitResolveLocalFileSystemURL( + url, + entry => { + onResolveSuccess(path, entry); + callback(); + }, + () => { + onResolveFailure(path, url); + callback(); + }); + } else { + onResolveFailure(path, url); + callback(); + } + }).bind(null, path)); }, this); // Save the model after finishing. @@ -198,7 +198,8 @@ this.queue_.run(callback => { chrome.storage.sync.get(FolderShortcutsDataModel.NAME, value => { if (chrome.runtime.lastError) { - console.error('Failed to load shortcut paths from chrome.storage: ' + + console.error( + 'Failed to load shortcut paths from chrome.storage: ' + chrome.runtime.lastError.message); callback(); return; @@ -341,8 +342,7 @@ addedIndex = this.length; } - this.firePermutedEvent_( - this.calculatePermutation_(oldArray, this.array_)); + this.firePermutedEvent_(this.calculatePermutation_(oldArray, this.array_)); return addedIndex; }, @@ -411,12 +411,12 @@ // TODO(mtomasz): Migrate to URL. const paths = this.array_ - .map(entry => { - return entry.toURL(); - }) - .map(this.convertUrlToStoredPath_.bind(this)) - .concat(Object.keys(this.pendingPaths_)) - .concat(Object.keys(this.unresolvablePaths_)); + .map(entry => { + return entry.toURL(); + }) + .map(this.convertUrlToStoredPath_.bind(this)) + .concat(Object.keys(this.pendingPaths_)) + .concat(Object.keys(this.unresolvablePaths_)); const prefs = {}; prefs[FolderShortcutsDataModel.NAME] = paths; @@ -519,8 +519,8 @@ console.warn(path + ' is neither a drive mount path nor a stored path.'); return null; } - return this.lastDriveRootURL_ + encodeURIComponent( - path.substr(STORED_DRIVE_MOUNT_PATH.length)); + return this.lastDriveRootURL_ + + encodeURIComponent(path.substr(STORED_DRIVE_MOUNT_PATH.length)); }, /** @@ -539,7 +539,7 @@ return null; } - return STORED_DRIVE_MOUNT_PATH + '/' + decodeURIComponent( - url.substr(this.lastDriveRootURL_.length)); + return STORED_DRIVE_MOUNT_PATH + '/' + + decodeURIComponent(url.substr(this.lastDriveRootURL_.length)); }, };
diff --git a/ui/file_manager/file_manager/foreground/js/gear_menu_controller.js b/ui/file_manager/file_manager/foreground/js/gear_menu_controller.js index da44d96b..48ca63b 100644 --- a/ui/file_manager/file_manager/foreground/js/gear_menu_controller.js +++ b/ui/file_manager/file_manager/foreground/js/gear_menu_controller.js
@@ -72,7 +72,7 @@ */ GearMenuController.prototype.onShowGearMenu_ = function() { this.toggleRipple_.activated = true; - this.refreshRemainingSpace_(false); /* Without loading caption. */ + this.refreshRemainingSpace_(false); /* Without loading caption. */ // Update view of drive-related settings. this.commandHandler_.updateAvailability(); @@ -154,9 +154,12 @@ return; } - this.gearMenu_.setSpaceInfo(new Promise(fulfill => { - chrome.fileManagerPrivate.getSizeStats(currentVolumeInfo.volumeId, fulfill); - }), true); + this.gearMenu_.setSpaceInfo( + new Promise(fulfill => { + chrome.fileManagerPrivate.getSizeStats( + currentVolumeInfo.volumeId, fulfill); + }), + true); }; /**
diff --git a/ui/file_manager/file_manager/foreground/js/import_controller.js b/ui/file_manager/file_manager/foreground/js/import_controller.js index 0db814a..8d1a3b01 100644 --- a/ui/file_manager/file_manager/foreground/js/import_controller.js +++ b/ui/file_manager/file_manager/foreground/js/import_controller.js
@@ -32,7 +32,6 @@ */ importer.ImportController = function( environment, scanner, importRunner, commandWidget) { - /** @private {!importer.ControllerEnvironment} */ this.environment_ = environment; @@ -78,14 +77,11 @@ const listener = this.onScanEvent_.bind(this); this.scanner_.addObserver(listener); // Remove the observer when the foreground window is closed. - window.addEventListener( - 'pagehide', - () => { - this.scanner_.removeObserver(listener); - }); + window.addEventListener('pagehide', () => { + this.scanner_.removeObserver(listener); + }); - this.environment_.addWindowCloseListener( - this.onWindowClosing_.bind(this)); + this.environment_.addWindowCloseListener(this.onWindowClosing_.bind(this)); this.environment_.addVolumeUnmountListener( this.onVolumeUnmounted_.bind(this)); @@ -96,14 +92,13 @@ this.environment_.addSelectionChangedListener( this.onSelectionChanged_.bind(this)); - this.commandWidget_.addClickListener( - this.onClick_.bind(this)); + this.commandWidget_.addClickListener(this.onClick_.bind(this)); this.storage_.get(importer.Setting.HAS_COMPLETED_IMPORT, false) .then( /** - * @param {boolean} importCompleted If so, we hide the banner - */ + * @param {boolean} importCompleted If so, we hide the banner + */ importCompleted => { this.commandWidget_.setDetailsBannerVisible(!importCompleted); }); @@ -233,8 +228,8 @@ * @private */ importer.ImportController.prototype.finalizeActiveImport_ = function() { - console.assert(!!this.activeImport_, - 'Cannot finish import when none is running.'); + console.assert( + !!this.activeImport_, 'Cannot finish import when none is running.'); this.previousImport_ = this.activeImport_; this.activeImport_ = null; }; @@ -243,8 +238,7 @@ * Handles button clicks emenating from the panel or toolbar. * @param {!importer.ClickSource} source */ -importer.ImportController.prototype.onClick_ = - function(source) { +importer.ImportController.prototype.onClick_ = function(source) { switch (source) { case importer.ClickSource.MAIN: if (this.lastActivityState_ === importer.ActivityState.READY) { @@ -284,7 +278,8 @@ * @private */ importer.ImportController.prototype.startImportTask_ = function() { - console.assert(!this.activeImport_, + console.assert( + !this.activeImport_, 'Cannot execute while an import task is already active.'); const scan = this.scanManager_.getActiveScan(); @@ -292,15 +287,10 @@ const startDate = new Date(); const importTask = this.importRunner_.importFromScanResult( - scan, - importer.Destination.GOOGLE_DRIVE, + scan, importer.Destination.GOOGLE_DRIVE, this.environment_.getImportDestination(startDate)); - this.activeImport_ = { - scan: scan, - task: importTask, - started: startDate - }; + this.activeImport_ = {scan: scan, task: importTask, started: startDate}; const taskFinished = this.onImportFinished_.bind(this, importTask); importTask.whenFinished.then(taskFinished).catch(taskFinished); }; @@ -402,43 +392,42 @@ VolumeManagerCommon.VolumeType.DRIVE), ]) .then(/** @param {Array<number>} availableSpace in bytes */ - availableSpace => { - // TODO(smckay): We might want to disqualify some small amount of - // local storage in this calculation on the assumption that we - // don't want to completely max out storage...even though synced - // files will eventually be evicted from the cache. - if (availableSpace[0] < opt_scan.getStatistics().sizeBytes) { - // Doesn't fit in local space. - this.updateUi_( - importer.ActivityState.INSUFFICIENT_LOCAL_SPACE, opt_scan, - availableSpace[0]); - return; - } - if (availableSpace[1] !== -1 && - availableSpace[1] < opt_scan.getStatistics().sizeBytes) { - // Could retrieve cloud quota and doesn't fit. - this.updateUi_( - importer.ActivityState.INSUFFICIENT_CLOUD_SPACE, opt_scan, - availableSpace[1]); - return; - } + availableSpace => { + // TODO(smckay): We might want to disqualify some small amount of + // local storage in this calculation on the assumption that we + // don't want to completely max out storage...even though synced + // files will eventually be evicted from the cache. + if (availableSpace[0] < opt_scan.getStatistics().sizeBytes) { + // Doesn't fit in local space. + this.updateUi_( + importer.ActivityState.INSUFFICIENT_LOCAL_SPACE, opt_scan, + availableSpace[0]); + return; + } + if (availableSpace[1] !== -1 && + availableSpace[1] < opt_scan.getStatistics().sizeBytes) { + // Could retrieve cloud quota and doesn't fit. + this.updateUi_( + importer.ActivityState.INSUFFICIENT_CLOUD_SPACE, opt_scan, + availableSpace[1]); + return; + } - // Enough space available! - this.updateUi_( - importer.ActivityState.READY, // to import... - opt_scan); - if (this.isRightAfterPluggingMedia_) { - this.isRightAfterPluggingMedia_ = false; - this.commandWidget_.setDetailsVisible(true); - } - }) + // Enough space available! + this.updateUi_( + importer.ActivityState.READY, // to import... + opt_scan); + if (this.isRightAfterPluggingMedia_) { + this.isRightAfterPluggingMedia_ = false; + this.commandWidget_.setDetailsVisible(true); + } + }) .catch(error => { - // If an error occurs, it will appear to scan forever - hide the - // cloud backup option in that case. - importer.getLogger().catcher('import-controller-check-state')( - error); - this.updateUi_(importer.ActivityState.HIDDEN); - }); + // If an error occurs, it will appear to scan forever - hide the + // cloud backup option in that case. + importer.getLogger().catcher('import-controller-check-state')(error); + this.updateUi_(importer.ActivityState.HIDDEN); + }); }; /** @@ -458,8 +447,7 @@ * @return {boolean} true if the current directory is scan eligible. * @private */ -importer.ImportController.prototype.isCurrentDirectoryScannable_ = - function() { +importer.ImportController.prototype.isCurrentDirectoryScannable_ = function() { const directory = this.environment_.getCurrentDirectory(); return !!directory && importer.isMediaDirectory(directory, this.environment_.volumeManager); @@ -547,14 +535,11 @@ * @struct */ importer.RuntimeCommandWidget = function() { - /** @private {HTMLElement} */ this.detailsPanel_ = /** @type {HTMLElement} */ ( document.querySelector('#cloud-import-details')); this.detailsPanel_.addEventListener( - 'transitionend', - this.onDetailsTransitionEnd_.bind(this), - false); + 'transitionend', this.onDetailsTransitionEnd_.bind(this), false); // Any clicks on document outside of the details panel // result in the panel being hidden. @@ -571,21 +556,21 @@ this.comboButton_ = getRequiredElement('cloud-import-combo-button'); /** @private {!Element} */ - this.mainButton_ = queryRequiredElement( - '#cloud-import-button', this.comboButton_); - this.mainButton_.onclick = this.onButtonClicked_.bind( - this, importer.ClickSource.MAIN); + this.mainButton_ = + queryRequiredElement('#cloud-import-button', this.comboButton_); + this.mainButton_.onclick = + this.onButtonClicked_.bind(this, importer.ClickSource.MAIN); /** @private {!PaperRipple}*/ this.mainButtonRipple_ = - /** @type {!PaperRipple} */ (queryRequiredElement( - '.ripples > paper-ripple', this.comboButton_)); + /** @type {!PaperRipple} */ ( + queryRequiredElement('.ripples > paper-ripple', this.comboButton_)); /** @private {Element} */ - this.sideButton_ = queryRequiredElement( - '#cloud-import-details-button', this.comboButton_); - this.sideButton_.onclick = this.onButtonClicked_.bind( - this, importer.ClickSource.SIDE); + this.sideButton_ = + queryRequiredElement('#cloud-import-details-button', this.comboButton_); + this.sideButton_.onclick = + this.onButtonClicked_.bind(this, importer.ClickSource.SIDE); /** @private {!FilesToggleRipple} */ this.sideButtonRipple_ = @@ -595,24 +580,23 @@ /** @private {Element} */ this.importButton_ = document.querySelector('#cloud-import-details paper-button.import'); - this.importButton_.onclick = this.onButtonClicked_.bind( - this, importer.ClickSource.IMPORT); + this.importButton_.onclick = + this.onButtonClicked_.bind(this, importer.ClickSource.IMPORT); /** @private {Element} */ this.cancelButton_ = document.querySelector('#cloud-import-details paper-button.cancel'); - this.cancelButton_.onclick = this.onButtonClicked_.bind( - this, importer.ClickSource.CANCEL); + this.cancelButton_.onclick = + this.onButtonClicked_.bind(this, importer.ClickSource.CANCEL); /** @private {Element} */ this.statusContent_ = document.querySelector('#cloud-import-details .status .content'); - this.statusContent_.onclick = this.onButtonClicked_.bind( - this, importer.ClickSource.DESTINATION); + this.statusContent_.onclick = + this.onButtonClicked_.bind(this, importer.ClickSource.DESTINATION); /** @private {Element} */ - this.toolbarIcon_ = - document.querySelector('#cloud-import-button iron-icon'); + this.toolbarIcon_ = document.querySelector('#cloud-import-button iron-icon'); this.statusIcon_ = document.querySelector('#cloud-import-details .status iron-icon'); @@ -656,9 +640,8 @@ * @param {!HTMLElement} element * @param {number} timeout In milliseconds. */ -importer.RuntimeCommandWidget.ensureTransitionEndEvent = - (element, timeout) => { - let fired = false; +importer.RuntimeCommandWidget.ensureTransitionEndEvent = (element, timeout) => { + let fired = false; element.addEventListener('transitionend', function f(e) { element.removeEventListener('transitionend', f); fired = true; @@ -672,8 +655,7 @@ }; /** @override */ -importer.RuntimeCommandWidget.prototype.addClickListener = - function(listener) { +importer.RuntimeCommandWidget.prototype.addClickListener = function(listener) { this.clickListener_ = listener; }; @@ -682,8 +664,8 @@ * @param {Event} event Click event. * @private */ -importer.RuntimeCommandWidget.prototype.onButtonClicked_ = - function(source, event) { +importer.RuntimeCommandWidget.prototype.onButtonClicked_ = function( + source, event) { console.assert(!!this.clickListener_, 'Listener not set.'); // Clear focus from the toolbar button after it is clicked. @@ -727,8 +709,8 @@ }; /** @override */ -importer.RuntimeCommandWidget.prototype.setDetailsBannerVisible = - function(visible) { +importer.RuntimeCommandWidget.prototype.setDetailsBannerVisible = function( + visible) { this.detailsBanner_.hidden = !visible; }; @@ -765,14 +747,12 @@ this.detailsPanel_.className = 'hidden'; // transition duration is 200ms. Let's wait for 400ms. importer.RuntimeCommandWidget.ensureTransitionEndEvent( - /** @type {!HTMLElement} */ (this.detailsPanel_), - 400); + /** @type {!HTMLElement} */ (this.detailsPanel_), 400); } }; /** @private */ -importer.RuntimeCommandWidget.prototype.onDetailsTransitionEnd_ = - function() { +importer.RuntimeCommandWidget.prototype.onDetailsTransitionEnd_ = function() { if (this.detailsPanel_.className === 'hidden') { // if we simply make the panel invisible (via opacity) // it'll still be sitting there grabing mouse events @@ -782,8 +762,7 @@ }; /** @private */ -importer.RuntimeCommandWidget.prototype.onDetailsFocusLost_ = - function() { +importer.RuntimeCommandWidget.prototype.onDetailsFocusLost_ = function() { this.setDetailsVisible(false); }; @@ -796,11 +775,11 @@ */ importer.RuntimeCommandWidget.prototype.updateTabindexOfAnchors_ = (root, newTabIndex) => { - const anchors = root.querySelectorAll('a'); - anchors.forEach(element => { - element.tabIndex = newTabIndex; - }); -}; + const anchors = root.querySelectorAll('a'); + anchors.forEach(element => { + element.tabIndex = newTabIndex; + }); + }; /** @override */ importer.RuntimeCommandWidget.prototype.update = function( @@ -816,7 +795,7 @@ photosText = ''; } } - switch(activityState) { + switch (activityState) { case importer.ActivityState.HIDDEN: this.setDetailsVisible(false); @@ -877,10 +856,9 @@ break; case importer.ActivityState.NO_MEDIA: - this.mainButton_.setAttribute('aria-label', str( - 'CLOUD_IMPORT_TOOLTIP_NO_MEDIA')); - this.statusContent_.innerHTML = str( - 'CLOUD_IMPORT_STATUS_NO_MEDIA'); + this.mainButton_.setAttribute( + 'aria-label', str('CLOUD_IMPORT_TOOLTIP_NO_MEDIA')); + this.statusContent_.innerHTML = str('CLOUD_IMPORT_STATUS_NO_MEDIA'); this.comboButton_.hidden = false; this.importButton_.hidden = true; @@ -911,8 +889,8 @@ case importer.ActivityState.SCANNING: console.assert(!!opt_scan, 'Scan not defined, but is required.'); - this.mainButton_.setAttribute('aria-label', str( - 'CLOUD_IMPORT_TOOLTIP_SCANNING')); + this.mainButton_.setAttribute( + 'aria-label', str('CLOUD_IMPORT_TOOLTIP_SCANNING')); this.statusContent_.innerHTML = strf('CLOUD_IMPORT_STATUS_SCANNING', photosText); @@ -949,7 +927,6 @@ * @param {!importer.MediaScanner} scanner */ importer.ScanManager = function(environment, scanner) { - /** @private {!importer.ControllerEnvironment} */ this.environment_ = environment; @@ -1033,7 +1010,8 @@ * @return {!importer.ScanResult} */ importer.ScanManager.prototype.getSelectionScan = function(entries, mode) { - console.assert(!this.selectionScan_, + console.assert( + !this.selectionScan_, 'Cannot create new selection scan with another in the cache.'); this.selectionScan_ = this.scanner_.scanFiles(entries, mode); return this.selectionScan_; @@ -1191,8 +1169,7 @@ }; /** @override */ -importer.RuntimeControllerEnvironment.prototype.getSelection = - function() { +importer.RuntimeControllerEnvironment.prototype.getSelection = function() { return this.fileManager_.getSelection().entries; }; @@ -1203,14 +1180,14 @@ }; /** @override */ -importer.RuntimeControllerEnvironment.prototype.setCurrentDirectory = - function(entry) { +importer.RuntimeControllerEnvironment.prototype.setCurrentDirectory = function( + entry) { this.fileManager_.directoryModel.activateDirectoryEntry(entry); }; /** @override */ -importer.RuntimeControllerEnvironment.prototype.getVolumeInfo = - function(entry) { +importer.RuntimeControllerEnvironment.prototype.getVolumeInfo = function( + entry) { return this.fileManager_.volumeManager.getVolumeInfo(entry); }; @@ -1230,59 +1207,56 @@ const volumeInfo = assert( this.fileManager_.volumeManager.getCurrentProfileVolumeInfo(volumeType)); return new Promise((resolve, reject) => { - chrome.fileManagerPrivate.getSizeStats( - volumeInfo.volumeId, stats => { - if (chrome.runtime.lastError) { - reject( - 'Failed to ascertain available free space: ' + - chrome.runtime.lastError.message); - return; - } - if (!stats) { - resolve(-1); - } - resolve(stats.remainingSize); - }); + chrome.fileManagerPrivate.getSizeStats(volumeInfo.volumeId, stats => { + if (chrome.runtime.lastError) { + reject( + 'Failed to ascertain available free space: ' + + chrome.runtime.lastError.message); + return; + } + if (!stats) { + resolve(-1); + } + resolve(stats.remainingSize); + }); }); }; /** @override */ importer.RuntimeControllerEnvironment.prototype.addWindowCloseListener = listener => { - window.addEventListener('pagehide', listener); -}; + window.addEventListener('pagehide', listener); + }; /** @override */ importer.RuntimeControllerEnvironment.prototype.addVolumeUnmountListener = listener => { - // TODO(smckay): remove listeners when the page is torn down. - chrome.fileManagerPrivate.onMountCompleted.addListener( - /** - * @param {!chrome.fileManagerPrivate.MountCompletedEvent} event - * @this {importer.RuntimeControllerEnvironment} - */ - event => { - if (event.eventType === 'unmount') { - listener(event.volumeMetadata.volumeId); - } - }); -}; + // TODO(smckay): remove listeners when the page is torn down. + chrome.fileManagerPrivate.onMountCompleted.addListener( + /** + * @param {!chrome.fileManagerPrivate.MountCompletedEvent} event + * @this {importer.RuntimeControllerEnvironment} + */ + event => { + if (event.eventType === 'unmount') { + listener(event.volumeMetadata.volumeId); + } + }); + }; /** @override */ importer.RuntimeControllerEnvironment.prototype.addDirectoryChangedListener = function(listener) { // TODO(smckay): remove listeners when the page is torn down. this.fileManager_.directoryModel.addEventListener( - 'directory-changed', - listener); + 'directory-changed', listener); }; /** @override */ importer.RuntimeControllerEnvironment.prototype.addSelectionChangedListener = function(listener) { this.selectionHandler_.addEventListener( - FileSelectionHandler.EventType.CHANGE_THROTTLED, - listener); + FileSelectionHandler.EventType.CHANGE_THROTTLED, listener); }; /** @@ -1292,8 +1266,8 @@ * @param {!DirectoryEntry} directory * @private */ -importer.RuntimeControllerEnvironment.prototype.revealDirectory_ = - function(directory) { +importer.RuntimeControllerEnvironment.prototype.revealDirectory_ = function( + directory) { this.fileManager_.backgroundPage.launcher.launchFileManager( {currentDirectoryURL: directory.toURL()}, /* App ID */ undefined); @@ -1315,16 +1289,13 @@ * @return {!Promise<!DirectoryEntry>} * @private */ -importer.RuntimeControllerEnvironment.prototype.demandCloudFolder_ = - root => { +importer.RuntimeControllerEnvironment.prototype.demandCloudFolder_ = root => { return importer.demandChildDirectory( - root, - str('CLOUD_IMPORT_DESTINATION_FOLDER')); + root, str('CLOUD_IMPORT_DESTINATION_FOLDER')); }; /** @override */ -importer.RuntimeControllerEnvironment.prototype.showImportRoot = - function() { +importer.RuntimeControllerEnvironment.prototype.showImportRoot = function() { return this.getDriveRoot_() .then(this.demandCloudFolder_.bind(this)) .then(this.revealDirectory_.bind(this)) @@ -1332,8 +1303,8 @@ }; /** @override */ -importer.RuntimeControllerEnvironment.prototype.getImportDestination = - function(date) { +importer.RuntimeControllerEnvironment.prototype.getImportDestination = function( + date) { return this.getDriveRoot_() .then(this.demandCloudFolder_.bind(this)) .then( @@ -1343,8 +1314,7 @@ */ root => { return importer.demandChildDirectory( - root, - importer.getDirectoryNameForDate(date)); + root, importer.getDirectoryNameForDate(date)); }) .catch(importer.getLogger().catcher('import-destination-provision')); };
diff --git a/ui/file_manager/file_manager/foreground/js/import_controller_unittest.js b/ui/file_manager/file_manager/foreground/js/import_controller_unittest.js index efadacd..0f8a41a 100644 --- a/ui/file_manager/file_manager/foreground/js/import_controller_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/import_controller_unittest.js
@@ -84,8 +84,7 @@ function testVolumeUnmount_InvalidatesScans(callback) { const controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', + VolumeManagerCommon.VolumeType.MTP, 'mtp-volume', [ '/DCIM/', '/DCIM/photos0/', @@ -93,7 +92,7 @@ '/DCIM/photos0/IMG00002.jpg', '/DCIM/photos1/', '/DCIM/photos1/IMG00001.jpg', - '/DCIM/photos1/IMG00003.jpg' + '/DCIM/photos1/IMG00003.jpg', ], '/DCIM'); @@ -101,31 +100,31 @@ assert(dcim); environment.directoryChangedListener(EMPTY_EVENT); - const promise = widget.updateResolver.promise.then( - () => { - // Reset the promise so we can wait on a second widget update. - widget.resetPromises(); - environment.setCurrentDirectory(nonDcimDirectory); - environment.simulateUnmount(); + const promise = widget.updateResolver.promise + .then(() => { + // Reset the promise so we can wait on a second widget + // update. + widget.resetPromises(); + environment.setCurrentDirectory(nonDcimDirectory); + environment.simulateUnmount(); - dcim = /** @type {!DirectoryEntry} */ (dcim); - environment.setCurrentDirectory(dcim); - environment.directoryChangedListener(EMPTY_EVENT); - // Return the new promise, so subsequent "thens" only - // fire once the widget has been updated again. - return widget.updateResolver.promise; - }).then( - () => { - mediaScanner.assertScanCount(2); - }); + dcim = /** @type {!DirectoryEntry} */ (dcim); + environment.setCurrentDirectory(dcim); + environment.directoryChangedListener(EMPTY_EVENT); + // Return the new promise, so subsequent "thens" only + // fire once the widget has been updated again. + return widget.updateResolver.promise; + }) + .then(() => { + mediaScanner.assertScanCount(2); + }); reportPromise(promise, callback); } function testDirectoryChange_TriggersUpdate(callback) { const controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', + VolumeManagerCommon.VolumeType.MTP, 'mtp-volume', [ '/DCIM/', '/DCIM/photos0/', @@ -139,8 +138,7 @@ function testDirectoryChange_CancelsScan(callback) { const controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', + VolumeManagerCommon.VolumeType.MTP, 'mtp-volume', [ '/DCIM/', '/DCIM/photos0/', @@ -148,30 +146,30 @@ '/DCIM/photos0/IMG00002.jpg', '/DCIM/photos1/', '/DCIM/photos1/IMG00001.jpg', - '/DCIM/photos1/IMG00003.jpg' + '/DCIM/photos1/IMG00003.jpg', ], '/DCIM'); environment.directoryChangedListener(EMPTY_EVENT); - const promise = widget.updateResolver.promise.then( - () => { - // Reset the promise so we can wait on a second widget update. - widget.resetPromises(); - environment.setCurrentDirectory(nonDcimDirectory); - environment.directoryChangedListener(EMPTY_EVENT); - }).then( - () => { - mediaScanner.assertScanCount(1); - mediaScanner.assertLastScanCanceled(); - }); + const promise = widget.updateResolver.promise + .then(() => { + // Reset the promise so we can wait on a second widget + // update. + widget.resetPromises(); + environment.setCurrentDirectory(nonDcimDirectory); + environment.directoryChangedListener(EMPTY_EVENT); + }) + .then(() => { + mediaScanner.assertScanCount(1); + mediaScanner.assertLastScanCanceled(); + }); reportPromise(promise, callback); } function testWindowClose_CancelsScan(callback) { const controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', + VolumeManagerCommon.VolumeType.MTP, 'mtp-volume', [ '/DCIM/', '/DCIM/photos0/', @@ -179,29 +177,29 @@ '/DCIM/photos0/IMG00002.jpg', '/DCIM/photos1/', '/DCIM/photos1/IMG00001.jpg', - '/DCIM/photos1/IMG00003.jpg' + '/DCIM/photos1/IMG00003.jpg', ], '/DCIM'); environment.directoryChangedListener(EMPTY_EVENT); - const promise = widget.updateResolver.promise.then( - () => { - // Reset the promise so we can wait on a second widget update. - widget.resetPromises(); - environment.windowCloseListener(); - }).then( - () => { - mediaScanner.assertScanCount(1); - mediaScanner.assertLastScanCanceled(); - }); + const promise = widget.updateResolver.promise + .then(() => { + // Reset the promise so we can wait on a second widget + // update. + widget.resetPromises(); + environment.windowCloseListener(); + }) + .then(() => { + mediaScanner.assertScanCount(1); + mediaScanner.assertLastScanCanceled(); + }); reportPromise(promise, callback); } function testDirectoryChange_DetailsPanelVisibility_InitialChangeDir(callback) { const controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', + VolumeManagerCommon.VolumeType.MTP, 'mtp-volume', [ '/DCIM/', '/DCIM/photos0/', @@ -222,25 +220,26 @@ environment.directoryChangedListener(event); assertFalse(widget.detailsVisible); - const promise = widget.updateResolver.promise.then(() => { - // "scanning..." - assertFalse(widget.detailsVisible); - widget.resetPromises(); - mediaScanner.finalizeScans(); - return widget.updateResolver.promise; - }).then(() => { - // "ready to update" - // Details should pop up. - assertTrue(widget.detailsVisible); - }); + const promise = widget.updateResolver.promise + .then(() => { + // "scanning..." + assertFalse(widget.detailsVisible); + widget.resetPromises(); + mediaScanner.finalizeScans(); + return widget.updateResolver.promise; + }) + .then(() => { + // "ready to update" + // Details should pop up. + assertTrue(widget.detailsVisible); + }); reportPromise(promise, callback); } function testDirectoryChange_DetailsPanelVisibility_SubsequentChangeDir() { const controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', + VolumeManagerCommon.VolumeType.MTP, 'mtp-volume', [ '/DCIM/', '/DCIM/photos0/', @@ -249,9 +248,8 @@ '/DCIM'); const event = new Event('directory-changed'); - event.newDirEntry = new MockDirectoryEntry( - new MockFileSystem('testFs'), - '/DCIM/'); + event.newDirEntry = + new MockDirectoryEntry(new MockFileSystem('testFs'), '/DCIM/'); // Any previous dir at all will skip the new window logic. event.previousDirEntry = event.newDirEntry; @@ -262,8 +260,7 @@ function testSelectionChange_TriggersUpdate(callback) { const controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', + VolumeManagerCommon.VolumeType.MTP, 'mtp-volume', [ '/DCIM/', '/DCIM/photos0/', @@ -285,8 +282,7 @@ function testFinalizeScans_TriggersUpdate(callback) { const controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', + VolumeManagerCommon.VolumeType.MTP, 'mtp-volume', [ '/DCIM/', '/DCIM/photos0/', @@ -310,8 +306,7 @@ function testClickDestination_ShowsRootPriorToImport(callback) { const controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', + VolumeManagerCommon.VolumeType.MTP, 'mtp-volume', [ '/DCIM/', '/DCIM/photos0/', @@ -325,23 +320,19 @@ } function testClickDestination_ShowsDestinationAfterImportStarted(callback) { - const promise = startImport(importer.ClickSource.MAIN) - .then( - () => { - return mediaImporter.importResolver.promise.then( - () => { - widget.click(importer.ClickSource.DESTINATION); - return environment.showImportDestinationResolver.promise; - }); - }); + const promise = startImport(importer.ClickSource.MAIN).then(() => { + return mediaImporter.importResolver.promise.then(() => { + widget.click(importer.ClickSource.DESTINATION); + return environment.showImportDestinationResolver.promise; + }); + }); reportPromise(promise, callback); } function startImport(clickSource) { const controller = createController( - VolumeManagerCommon.VolumeType.MTP, - 'mtp-volume', + VolumeManagerCommon.VolumeType.MTP, 'mtp-volume', [ '/DCIM/', '/DCIM/photos0/', @@ -360,17 +351,15 @@ // First we need to force the controller into a scanning state. environment.directoryChangedListener(EMPTY_EVENT); - return widget.updateResolver.promise.then( - () => { - widget.resetPromises(); - mediaScanner.finalizeScans(); - return widget.updateResolver.promise.then( - () => { - widget.resetPromises(); - widget.click(clickSource); - return mediaImporter.importResolver.promise; - }); - }); + return widget.updateResolver.promise.then(() => { + widget.resetPromises(); + mediaScanner.finalizeScans(); + return widget.updateResolver.promise.then(() => { + widget.resetPromises(); + widget.click(clickSource); + return mediaImporter.importResolver.promise; + }); + }); } /** @@ -543,26 +532,26 @@ }; /** @override */ -TestControllerEnvironment.prototype.addWindowCloseListener = - function(listener) { +TestControllerEnvironment.prototype.addWindowCloseListener = function( + listener) { this.windowCloseListener = listener; }; /** @override */ -TestControllerEnvironment.prototype.addVolumeUnmountListener = - function(listener) { +TestControllerEnvironment.prototype.addVolumeUnmountListener = function( + listener) { this.volumeUnmountListener = listener; }; /** @override */ -TestControllerEnvironment.prototype.addDirectoryChangedListener = - function(listener) { +TestControllerEnvironment.prototype.addDirectoryChangedListener = function( + listener) { this.directoryChangedListener = listener; }; /** @override */ -TestControllerEnvironment.prototype.addSelectionChangedListener = - function(listener) { +TestControllerEnvironment.prototype.addSelectionChangedListener = function( + listener) { this.selectionChangedListener = listener; };
diff --git a/ui/file_manager/file_manager/foreground/js/launch_param.js b/ui/file_manager/file_manager/foreground/js/launch_param.js index 17990ee..8dc6ee2d 100644 --- a/ui/file_manager/file_manager/foreground/js/launch_param.js +++ b/ui/file_manager/file_manager/foreground/js/launch_param.js
@@ -33,7 +33,8 @@ * @const */ this.currentDirectoryURL = unformatted['currentDirectoryURL'] ? - unformatted['currentDirectoryURL'] : ''; + unformatted['currentDirectoryURL'] : + ''; /** * @type {string} @@ -72,8 +73,7 @@ * @type {!SuggestAppDialogState} * @const */ - this.suggestAppsDialogState = - unformatted['suggestAppsDialogState'] ? + this.suggestAppsDialogState = unformatted['suggestAppsDialogState'] ? unformatted['suggestAppsDialogState'] : { overrideCwsContainerUrlForTest: '',
diff --git a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js index 37fa07c..0198861f 100644 --- a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js +++ b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js
@@ -120,9 +120,9 @@ * @return {number} Number of prefetch requests. * @private */ -ListThumbnailLoader.prototype.getNumOfPrefetch_ = function () { +ListThumbnailLoader.prototype.getNumOfPrefetch_ = function() { switch (/** @type {?ListThumbnailLoader.VolumeType} */ - (this.currentVolumeType_)) { + (this.currentVolumeType_)) { case VolumeManagerCommon.VolumeType.MTP: return 0; case ListThumbnailLoader.TEST_VOLUME_TYPE: @@ -140,7 +140,7 @@ */ ListThumbnailLoader.prototype.getNumOfMaxActiveTasks_ = function() { switch (/** @type {?ListThumbnailLoader.VolumeType} */ - (this.currentVolumeType_)) { + (this.currentVolumeType_)) { case VolumeManagerCommon.VolumeType.MTP: return 1; case ListThumbnailLoader.TEST_VOLUME_TYPE: @@ -258,8 +258,7 @@ // If the entry is a directory, already in cache as valid or fetching, skip. const thumbnail = this.cache_.get(entry.toURL()); - if (entry.isDirectory || - (thumbnail && !thumbnail.outdated) || + if (entry.isDirectory || (thumbnail && !thumbnail.outdated) || this.active_[entry.toURL()]) { this.cursor_++; this.continue_(); @@ -421,53 +420,59 @@ */ ListThumbnailLoader.Task.prototype.fetch = function() { let ioError = false; - return this.thumbnailModel_.get([this.entry_]).then(metadatas => { - // When it failed to read exif header with an IO error, do not generate - // thumbnail at this time since it may success in the second try. If it - // failed to read at 0 byte, it would be an IO error. - if (metadatas[0].thumbnail.urlError && - metadatas[0].thumbnail.urlError.errorDescription === - 'Error: Unexpected EOF @0') { - ioError = true; - return Promise.reject(); - } - return metadatas[0]; - }).then(metadata => { - const loadTargets = [ - ThumbnailLoader.LoadTarget.CONTENT_METADATA, - ThumbnailLoader.LoadTarget.EXTERNAL_METADATA - ]; + return this.thumbnailModel_.get([this.entry_]) + .then(metadatas => { + // When it failed to read exif header with an IO error, do not generate + // thumbnail at this time since it may success in the second try. If it + // failed to read at 0 byte, it would be an IO error. + if (metadatas[0].thumbnail.urlError && + metadatas[0].thumbnail.urlError.errorDescription === + 'Error: Unexpected EOF @0') { + ioError = true; + return Promise.reject(); + } + return metadatas[0]; + }) + .then(metadata => { + const loadTargets = [ + ThumbnailLoader.LoadTarget.CONTENT_METADATA, + ThumbnailLoader.LoadTarget.EXTERNAL_METADATA + ]; - // If the file is on a provided file system which is based on network, then - // don't generate thumbnails from file entry, as it could cause very high - // network traffic. - const volumeInfo = this.volumeManager_.getVolumeInfo(this.entry_); - if (volumeInfo && (volumeInfo.volumeType !== - VolumeManagerCommon.VolumeType.PROVIDED || - volumeInfo.source !== VolumeManagerCommon.Source.NETWORK)) { - loadTargets.push(ThumbnailLoader.LoadTarget.FILE_ENTRY); - } + // If the file is on a provided file system which is based on network, + // then don't generate thumbnails from file entry, as it could cause + // very high network traffic. + const volumeInfo = this.volumeManager_.getVolumeInfo(this.entry_); + if (volumeInfo && + (volumeInfo.volumeType !== + VolumeManagerCommon.VolumeType.PROVIDED || + volumeInfo.source !== VolumeManagerCommon.Source.NETWORK)) { + loadTargets.push(ThumbnailLoader.LoadTarget.FILE_ENTRY); + } - return new this.thumbnailLoaderConstructor_( - this.entry_, ThumbnailLoader.LoaderType.IMAGE, metadata, - undefined /* opt_mediaType */, loadTargets) - .loadAsDataUrl(ThumbnailLoader.FillMode.OVER_FILL); - }).then(result => { - return new ListThumbnailLoader.ThumbnailData( - this.entry_.toURL(), result.data, result.width, result.height); - }).catch(() => { - // If an error happens during generating of a thumbnail, then return - // an empty object, so we don't retry the thumbnail over and over - // again. - const thumbnailData = new ListThumbnailLoader.ThumbnailData( - this.entry_.toURL(), null, null, null); - if (ioError) { - // If fetching a thumbnail from EXIF fails due to an IO error, then try to - // refetch it in the future, but not earlier than in 3 second. - setTimeout(() => { - thumbnailData.outdated = true; - }, ListThumbnailLoader.Task.EXIF_IO_ERROR_DELAY); - } - return thumbnailData; - }); + return new this + .thumbnailLoaderConstructor_( + this.entry_, ThumbnailLoader.LoaderType.IMAGE, metadata, + undefined /* opt_mediaType */, loadTargets) + .loadAsDataUrl(ThumbnailLoader.FillMode.OVER_FILL); + }) + .then(result => { + return new ListThumbnailLoader.ThumbnailData( + this.entry_.toURL(), result.data, result.width, result.height); + }) + .catch(() => { + // If an error happens during generating of a thumbnail, then return + // an empty object, so we don't retry the thumbnail over and over + // again. + const thumbnailData = new ListThumbnailLoader.ThumbnailData( + this.entry_.toURL(), null, null, null); + if (ioError) { + // If fetching a thumbnail from EXIF fails due to an IO error, then + // try to refetch it in the future, but not earlier than in 3 second. + setTimeout(() => { + thumbnailData.outdated = true; + }, ListThumbnailLoader.Task.EXIF_IO_ERROR_DELAY); + } + return thumbnailData; + }); };
diff --git a/ui/message_center/views/message_view_context_menu_controller.cc b/ui/message_center/views/message_view_context_menu_controller.cc index 6d738fc..8b043ca 100644 --- a/ui/message_center/views/message_view_context_menu_controller.cc +++ b/ui/message_center/views/message_view_context_menu_controller.cc
@@ -46,7 +46,7 @@ menu_runner_->RunMenuAt(source->GetWidget()->GetTopLevelWidget(), NULL, gfx::Rect(point, gfx::Size()), - views::MENU_ANCHOR_TOPRIGHT, source_type); + views::MenuAnchorPosition::kTopRight, source_type); } void MessageViewContextMenuController::OnMenuClosed() {
diff --git a/ui/ozone/common/linux/gbm_device.h b/ui/ozone/common/linux/gbm_device.h index 29d9e0a..26402f15 100644 --- a/ui/ozone/common/linux/gbm_device.h +++ b/ui/ozone/common/linux/gbm_device.h
@@ -5,13 +5,14 @@ #ifndef UI_OZONE_COMMON_LINUX_GBM_DEVICE_H_ #define UI_OZONE_COMMON_LINUX_GBM_DEVICE_H_ +#include <gbm.h> +#include <memory> + #include "base/files/file.h" #include "base/macros.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/native_pixmap_handle.h" -#include <gbm.h> - namespace ui { class GbmBuffer;
diff --git a/ui/ozone/common/linux/gbm_wrapper.cc b/ui/ozone/common/linux/gbm_wrapper.cc index ce05d29..a3313f14 100644 --- a/ui/ozone/common/linux/gbm_wrapper.cc +++ b/ui/ozone/common/linux/gbm_wrapper.cc
@@ -5,10 +5,8 @@ #include "ui/ozone/common/linux/gbm_wrapper.h" #include <gbm.h> -#if !defined(MINIGBM) -#include <fcntl.h> -#include <xf86drm.h> -#endif +#include <memory> +#include <utility> #include "base/posix/eintr_wrapper.h" #include "third_party/skia/include/core/SkSurface.h" @@ -17,6 +15,11 @@ #include "ui/ozone/common/linux/gbm_buffer.h" #include "ui/ozone/common/linux/gbm_device.h" +#if !defined(MINIGBM) +#include <fcntl.h> +#include <xf86drm.h> +#endif + namespace gbm_wrapper { namespace {
diff --git a/ui/ozone/common/stub_client_native_pixmap_factory.cc b/ui/ozone/common/stub_client_native_pixmap_factory.cc index f5b33302..15be9b4 100644 --- a/ui/ozone/common/stub_client_native_pixmap_factory.cc +++ b/ui/ozone/common/stub_client_native_pixmap_factory.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> + #include "base/macros.h" #include "ui/gfx/client_native_pixmap_factory.h"
diff --git a/ui/ozone/common/stub_overlay_manager.cc b/ui/ozone/common/stub_overlay_manager.cc index fd15b4e..3717c71 100644 --- a/ui/ozone/common/stub_overlay_manager.cc +++ b/ui/ozone/common/stub_overlay_manager.cc
@@ -3,6 +3,9 @@ // found in the LICENSE file. #include "ui/ozone/common/stub_overlay_manager.h" + +#include <memory> + #include "ui/ozone/public/overlay_candidates_ozone.h" namespace ui {
diff --git a/ui/ozone/common/stub_overlay_manager.h b/ui/ozone/common/stub_overlay_manager.h index 48b37770..77199b7 100644 --- a/ui/ozone/common/stub_overlay_manager.h +++ b/ui/ozone/common/stub_overlay_manager.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_COMMON_STUB_OVERLAY_MANAGER_H_ #define UI_OZONE_COMMON_STUB_OVERLAY_MANAGER_H_ +#include <memory> + #include "base/macros.h" #include "ui/ozone/public/overlay_manager_ozone.h"
diff --git a/ui/ozone/demo/demo_window.cc b/ui/ozone/demo/demo_window.cc index f376744..d21fe30 100644 --- a/ui/ozone/demo/demo_window.cc +++ b/ui/ozone/demo/demo_window.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/demo/demo_window.h" +#include <utility> + #include "base/threading/thread_task_runner_handle.h" #include "ui/events/event.h" #include "ui/events/keycodes/dom/dom_code.h"
diff --git a/ui/ozone/demo/demo_window.h b/ui/ozone/demo/demo_window.h index a0be6aea..9987837 100644 --- a/ui/ozone/demo/demo_window.h +++ b/ui/ozone/demo/demo_window.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_DEMO_DEMO_WINDOW_H_ #define UI_OZONE_DEMO_DEMO_WINDOW_H_ +#include <memory> + #include "base/memory/weak_ptr.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h"
diff --git a/ui/ozone/demo/gl_renderer.cc b/ui/ozone/demo/gl_renderer.cc index cb285e9..b23df5d 100644 --- a/ui/ozone/demo/gl_renderer.cc +++ b/ui/ozone/demo/gl_renderer.cc
@@ -4,6 +4,9 @@ #include "ui/ozone/demo/gl_renderer.h" +#include <memory> +#include <utility> + #include "base/bind.h" #include "base/location.h" #include "base/threading/thread_task_runner_handle.h"
diff --git a/ui/ozone/demo/gl_renderer.h b/ui/ozone/demo/gl_renderer.h index f0b638c1..38c9ec3 100644 --- a/ui/ozone/demo/gl_renderer.h +++ b/ui/ozone/demo/gl_renderer.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_DEMO_GL_RENDERER_H_ #define UI_OZONE_DEMO_GL_RENDERER_H_ +#include <memory> + #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h"
diff --git a/ui/ozone/demo/ozone_demo.cc b/ui/ozone/demo/ozone_demo.cc index c27f416..1ca0578c 100644 --- a/ui/ozone/demo/ozone_demo.cc +++ b/ui/ozone/demo/ozone_demo.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <iostream> +#include <memory> #include "base/at_exit.h" #include "base/command_line.h"
diff --git a/ui/ozone/demo/renderer_factory.h b/ui/ozone/demo/renderer_factory.h index a39a3b4..e2fc9a6 100644 --- a/ui/ozone/demo/renderer_factory.h +++ b/ui/ozone/demo/renderer_factory.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_DEMO_RENDERER_FACTORY_H_ #define UI_OZONE_DEMO_RENDERER_FACTORY_H_ +#include <memory> + #include "ui/gfx/geometry/size.h" #include "ui/gfx/native_widget_types.h"
diff --git a/ui/ozone/demo/simple_renderer_factory.cc b/ui/ozone/demo/simple_renderer_factory.cc index 043583c..8537ed0 100644 --- a/ui/ozone/demo/simple_renderer_factory.cc +++ b/ui/ozone/demo/simple_renderer_factory.cc
@@ -5,6 +5,7 @@ #include "ui/ozone/demo/simple_renderer_factory.h" #include <memory> +#include <utility> #include "base/command_line.h" #include "ui/gl/gl_surface.h"
diff --git a/ui/ozone/demo/simple_renderer_factory.h b/ui/ozone/demo/simple_renderer_factory.h index c28a2ab..3e4e04e 100644 --- a/ui/ozone/demo/simple_renderer_factory.h +++ b/ui/ozone/demo/simple_renderer_factory.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_DEMO_SIMPLE_RENDERER_FACTORY_H_ #define UI_OZONE_DEMO_SIMPLE_RENDERER_FACTORY_H_ +#include <memory> + #include "gpu/vulkan/buildflags.h" #include "ui/ozone/demo/renderer_factory.h" #include "ui/ozone/public/ozone_gpu_test_helper.h"
diff --git a/ui/ozone/demo/skia/skia_demo.cc b/ui/ozone/demo/skia/skia_demo.cc index 98ac14f..053eead 100644 --- a/ui/ozone/demo/skia/skia_demo.cc +++ b/ui/ozone/demo/skia/skia_demo.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <iostream> +#include <memory> #include "base/at_exit.h" #include "base/command_line.h"
diff --git a/ui/ozone/demo/skia/skia_gl_renderer.cc b/ui/ozone/demo/skia/skia_gl_renderer.cc index ad3b596..69b3851 100644 --- a/ui/ozone/demo/skia/skia_gl_renderer.cc +++ b/ui/ozone/demo/skia/skia_gl_renderer.cc
@@ -4,6 +4,9 @@ #include "ui/ozone/demo/skia/skia_gl_renderer.h" +#include <memory> +#include <utility> + #include "base/bind.h" #include "base/command_line.h" #include "base/location.h"
diff --git a/ui/ozone/demo/skia/skia_gl_renderer.h b/ui/ozone/demo/skia/skia_gl_renderer.h index 9419a25..15b818c 100644 --- a/ui/ozone/demo/skia/skia_gl_renderer.h +++ b/ui/ozone/demo/skia/skia_gl_renderer.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_DEMO_SKIA_SKIA_GL_RENDERER_H_ #define UI_OZONE_DEMO_SKIA_SKIA_GL_RENDERER_H_ +#include <memory> + #include "base/containers/queue.h" #include "base/macros.h" #include "base/memory/ref_counted.h"
diff --git a/ui/ozone/demo/skia/skia_renderer_factory.cc b/ui/ozone/demo/skia/skia_renderer_factory.cc index b1037fc..f6062b87b 100644 --- a/ui/ozone/demo/skia/skia_renderer_factory.cc +++ b/ui/ozone/demo/skia/skia_renderer_factory.cc
@@ -5,6 +5,7 @@ #include "ui/ozone/demo/skia/skia_renderer_factory.h" #include <memory> +#include <utility> #include "base/command_line.h" #include "ui/gl/gl_surface.h"
diff --git a/ui/ozone/demo/skia/skia_renderer_factory.h b/ui/ozone/demo/skia/skia_renderer_factory.h index bd14c35..524bbea7 100644 --- a/ui/ozone/demo/skia/skia_renderer_factory.h +++ b/ui/ozone/demo/skia/skia_renderer_factory.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_DEMO_SKIA_SKIA_RENDERER_FACTORY_H_ #define UI_OZONE_DEMO_SKIA_SKIA_RENDERER_FACTORY_H_ +#include <memory> + #include "ui/gfx/geometry/size.h" #include "ui/gfx/native_widget_types.h" #include "ui/ozone/demo/renderer_factory.h"
diff --git a/ui/ozone/demo/skia/skia_surfaceless_gl_renderer.cc b/ui/ozone/demo/skia/skia_surfaceless_gl_renderer.cc index ad361f1..91ff3c6a 100644 --- a/ui/ozone/demo/skia/skia_surfaceless_gl_renderer.cc +++ b/ui/ozone/demo/skia/skia_surfaceless_gl_renderer.cc
@@ -5,6 +5,8 @@ #include "ui/ozone/demo/skia/skia_surfaceless_gl_renderer.h" #include <stddef.h> +#include <memory> +#include <utility> #include "base/bind.h" #include "base/bind_helpers.h"
diff --git a/ui/ozone/demo/software_renderer.cc b/ui/ozone/demo/software_renderer.cc index 232cc67..44e6330 100644 --- a/ui/ozone/demo/software_renderer.cc +++ b/ui/ozone/demo/software_renderer.cc
@@ -4,6 +4,9 @@ #include "ui/ozone/demo/software_renderer.h" +#include <memory> +#include <utility> + #include "base/bind.h" #include "base/trace_event/trace_event.h" #include "third_party/skia/include/core/SkCanvas.h"
diff --git a/ui/ozone/demo/surfaceless_gl_renderer.cc b/ui/ozone/demo/surfaceless_gl_renderer.cc index 4974172..7c7751f4 100644 --- a/ui/ozone/demo/surfaceless_gl_renderer.cc +++ b/ui/ozone/demo/surfaceless_gl_renderer.cc
@@ -5,6 +5,8 @@ #include "ui/ozone/demo/surfaceless_gl_renderer.h" #include <stddef.h> +#include <memory> +#include <utility> #include "base/bind.h" #include "base/bind_helpers.h"
diff --git a/ui/ozone/demo/vulkan_overlay_renderer.cc b/ui/ozone/demo/vulkan_overlay_renderer.cc index 5a544c5..ef9edb3 100644 --- a/ui/ozone/demo/vulkan_overlay_renderer.cc +++ b/ui/ozone/demo/vulkan_overlay_renderer.cc
@@ -5,6 +5,8 @@ #include "ui/ozone/demo/vulkan_overlay_renderer.h" #include <vulkan/vulkan.h> +#include <memory> +#include <utility> #include "base/bind.h" #include "base/location.h"
diff --git a/ui/ozone/demo/vulkan_overlay_renderer.h b/ui/ozone/demo/vulkan_overlay_renderer.h index cc06e66c..c0e4d9a9 100644 --- a/ui/ozone/demo/vulkan_overlay_renderer.h +++ b/ui/ozone/demo/vulkan_overlay_renderer.h
@@ -6,6 +6,7 @@ #define UI_OZONE_DEMO_VULKAN_OVERLAY_RENDERER_H_ #include <vulkan/vulkan.h> +#include <memory> #include "base/macros.h" #include "base/memory/ref_counted.h"
diff --git a/ui/ozone/demo/vulkan_renderer.cc b/ui/ozone/demo/vulkan_renderer.cc index 80dc756..106a88c 100644 --- a/ui/ozone/demo/vulkan_renderer.cc +++ b/ui/ozone/demo/vulkan_renderer.cc
@@ -5,6 +5,8 @@ #include "ui/ozone/demo/vulkan_renderer.h" #include <vulkan/vulkan.h> +#include <memory> +#include <utility> #include "base/bind.h" #include "base/location.h"
diff --git a/ui/ozone/demo/vulkan_renderer.h b/ui/ozone/demo/vulkan_renderer.h index 9432932..b340f14b 100644 --- a/ui/ozone/demo/vulkan_renderer.h +++ b/ui/ozone/demo/vulkan_renderer.h
@@ -6,6 +6,7 @@ #define UI_OZONE_DEMO_VULKAN_RENDERER_H_ #include <vulkan/vulkan.h> +#include <memory> #include "base/macros.h" #include "base/memory/ref_counted.h"
diff --git a/ui/ozone/demo/window_manager.cc b/ui/ozone/demo/window_manager.cc index 219e907..ffea585 100644 --- a/ui/ozone/demo/window_manager.cc +++ b/ui/ozone/demo/window_manager.cc
@@ -4,6 +4,9 @@ #include "ui/ozone/demo/window_manager.h" +#include <memory> +#include <utility> + #include "base/bind.h" #include "base/command_line.h" #include "base/threading/thread_task_runner_handle.h"
diff --git a/ui/ozone/demo/window_manager.h b/ui/ozone/demo/window_manager.h index ae96df0b..a31b01d 100644 --- a/ui/ozone/demo/window_manager.h +++ b/ui/ozone/demo/window_manager.h
@@ -5,6 +5,7 @@ #ifndef UI_OZONE_DEMO_WINDOW_MANAGER_H_ #define UI_OZONE_DEMO_WINDOW_MANAGER_H_ +#include <memory> #include <vector> #include "base/callback.h"
diff --git a/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc b/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc index 532b040..f66e5e9 100644 --- a/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc +++ b/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include <stdint.h> - #include <memory> #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc b/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc index 60c79d0..36fc30b 100644 --- a/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc +++ b/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/cast/client_native_pixmap_factory_cast.h" +#include <memory> + #include "base/logging.h" #include "ui/gfx/buffer_types.h" #include "ui/gfx/client_native_pixmap.h"
diff --git a/ui/ozone/platform/cast/gl_ozone_egl_cast.cc b/ui/ozone/platform/cast/gl_ozone_egl_cast.cc index 6e560e1b..446afea 100644 --- a/ui/ozone/platform/cast/gl_ozone_egl_cast.cc +++ b/ui/ozone/platform/cast/gl_ozone_egl_cast.cc
@@ -6,7 +6,7 @@ #include <EGL/egl.h> #include <dlfcn.h> - +#include <memory> #include <utility> #include "base/command_line.h"
diff --git a/ui/ozone/platform/cast/gl_ozone_egl_cast.h b/ui/ozone/platform/cast/gl_ozone_egl_cast.h index 6a4a1c7..ace0cbc 100644 --- a/ui/ozone/platform/cast/gl_ozone_egl_cast.h +++ b/ui/ozone/platform/cast/gl_ozone_egl_cast.h
@@ -6,7 +6,6 @@ #define UI_OZONE_PLATFORM_CAST_GL_OZONE_EGL_CAST_H_ #include <stdint.h> - #include <memory> #include "base/macros.h"
diff --git a/ui/ozone/platform/cast/gl_surface_cast.cc b/ui/ozone/platform/cast/gl_surface_cast.cc index 3378fd0..d76bfac 100644 --- a/ui/ozone/platform/cast/gl_surface_cast.cc +++ b/ui/ozone/platform/cast/gl_surface_cast.cc
@@ -4,6 +4,7 @@ #include "ui/ozone/platform/cast/gl_surface_cast.h" +#include <memory> #include <string> #include <utility>
diff --git a/ui/ozone/platform/cast/gl_surface_cast.h b/ui/ozone/platform/cast/gl_surface_cast.h index e8d88a6f..e294802 100644 --- a/ui/ozone/platform/cast/gl_surface_cast.h +++ b/ui/ozone/platform/cast/gl_surface_cast.h
@@ -5,6 +5,7 @@ #ifndef UI_OZONE_PLATFORM_CAST_GL_SURFACE_CAST_H_ #define UI_OZONE_PLATFORM_CAST_GL_SURFACE_CAST_H_ +#include <memory> #include <vector> #include "base/macros.h"
diff --git a/ui/ozone/platform/cast/overlay_manager_cast.cc b/ui/ozone/platform/cast/overlay_manager_cast.cc index 6a34f69..940ac23 100644 --- a/ui/ozone/platform/cast/overlay_manager_cast.cc +++ b/ui/ozone/platform/cast/overlay_manager_cast.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/cast/overlay_manager_cast.h" +#include <memory> + #include "ui/ozone/public/overlay_candidates_ozone.h" namespace ui {
diff --git a/ui/ozone/platform/cast/ozone_platform_cast.cc b/ui/ozone/platform/cast/ozone_platform_cast.cc index 594d0e63..5a6d635 100644 --- a/ui/ozone/platform/cast/ozone_platform_cast.cc +++ b/ui/ozone/platform/cast/ozone_platform_cast.cc
@@ -4,6 +4,7 @@ #include "ui/ozone/platform/cast/ozone_platform_cast.h" +#include <memory> #include <utility> #include "base/command_line.h"
diff --git a/ui/ozone/platform/cast/surface_factory_cast.cc b/ui/ozone/platform/cast/surface_factory_cast.cc index 3bca913..107e11a 100644 --- a/ui/ozone/platform/cast/surface_factory_cast.cc +++ b/ui/ozone/platform/cast/surface_factory_cast.cc
@@ -4,6 +4,7 @@ #include "ui/ozone/platform/cast/surface_factory_cast.h" +#include <memory> #include <utility> #include "base/macros.h"
diff --git a/ui/ozone/platform/drm/common/display_types.h b/ui/ozone/platform/drm/common/display_types.h index da8b5c0..c7cb3ef 100644 --- a/ui/ozone/platform/drm/common/display_types.h +++ b/ui/ozone/platform/drm/common/display_types.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_DRM_COMMON_DISPLAY_TYPES_H_ #define UI_OZONE_PLATFORM_DRM_COMMON_DISPLAY_TYPES_H_ +#include <memory> + namespace display { class DisplaySnapshot; } // namespace display @@ -16,4 +18,4 @@ } // namespace ui -#endif // UI_OZONE_PLATFORM_DRM_COMMON_DISPLAY_TYPES_H_ \ No newline at end of file +#endif // UI_OZONE_PLATFORM_DRM_COMMON_DISPLAY_TYPES_H_
diff --git a/ui/ozone/platform/drm/common/drm_overlay_manager.cc b/ui/ozone/platform/drm/common/drm_overlay_manager.cc index 959e0bcd3..57cefd0 100644 --- a/ui/ozone/platform/drm/common/drm_overlay_manager.cc +++ b/ui/ozone/platform/drm/common/drm_overlay_manager.cc
@@ -5,6 +5,7 @@ #include "ui/ozone/platform/drm/common/drm_overlay_manager.h" #include <algorithm> +#include <memory> #include <utility> #include "base/trace_event/trace_event.h"
diff --git a/ui/ozone/platform/drm/common/drm_util.cc b/ui/ozone/platform/drm/common/drm_util.cc index 76a6caf..dd9d0f74 100644 --- a/ui/ozone/platform/drm/common/drm_util.cc +++ b/ui/ozone/platform/drm/common/drm_util.cc
@@ -11,6 +11,7 @@ #include <xf86drm.h> #include <xf86drmMode.h> #include <algorithm> +#include <memory> #include <utility> #include "base/containers/flat_map.h"
diff --git a/ui/ozone/platform/drm/common/drm_util.h b/ui/ozone/platform/drm/common/drm_util.h index e70c23a8..c46941ff 100644 --- a/ui/ozone/platform/drm/common/drm_util.h +++ b/ui/ozone/platform/drm/common/drm_util.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <memory> +#include <utility> #include <vector> #include "base/files/file_path.h"
diff --git a/ui/ozone/platform/drm/gpu/crtc_controller.cc b/ui/ozone/platform/drm/gpu/crtc_controller.cc index aea5c91..d23d0dd6 100644 --- a/ui/ozone/platform/drm/gpu/crtc_controller.cc +++ b/ui/ozone/platform/drm/gpu/crtc_controller.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/drm/gpu/crtc_controller.h" +#include <memory> + #include "base/logging.h" #include "base/time/time.h" #include "ui/gfx/presentation_feedback.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_device.cc b/ui/ozone/platform/drm/gpu/drm_device.cc index 313bf2df..11b699e 100644 --- a/ui/ozone/platform/drm/gpu/drm_device.cc +++ b/ui/ozone/platform/drm/gpu/drm_device.cc
@@ -9,6 +9,7 @@ #include <unistd.h> #include <xf86drm.h> #include <xf86drmMode.h> +#include <memory> #include <utility> #include "base/bind.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_device.h b/ui/ozone/platform/drm/gpu/drm_device.h index 1e62f189..d5ef13b 100644 --- a/ui/ozone/platform/drm/gpu/drm_device.h +++ b/ui/ozone/platform/drm/gpu/drm_device.h
@@ -7,7 +7,7 @@ #include <stddef.h> #include <stdint.h> - +#include <memory> #include <vector> #include "base/callback.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_device_manager.cc b/ui/ozone/platform/drm/gpu/drm_device_manager.cc index 6b3214a..5d879fa 100644 --- a/ui/ozone/platform/drm/gpu/drm_device_manager.cc +++ b/ui/ozone/platform/drm/gpu/drm_device_manager.cc
@@ -4,6 +4,7 @@ #include "ui/ozone/platform/drm/gpu/drm_device_manager.h" +#include <memory> #include <utility> #include "base/file_descriptor_posix.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_display.cc b/ui/ozone/platform/drm/gpu/drm_display.cc index f800442..f5bf25f 100644 --- a/ui/ozone/platform/drm/gpu/drm_display.cc +++ b/ui/ozone/platform/drm/gpu/drm_display.cc
@@ -5,6 +5,7 @@ #include "ui/ozone/platform/drm/gpu/drm_display.h" #include <xf86drmMode.h> +#include <memory> #include "base/stl_util.h" #include "ui/display/types/display_snapshot.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_display.h b/ui/ozone/platform/drm/gpu/drm_display.h index 16f2dae..d0f5911 100644 --- a/ui/ozone/platform/drm/gpu/drm_display.h +++ b/ui/ozone/platform/drm/gpu/drm_display.h
@@ -7,7 +7,7 @@ #include <stddef.h> #include <stdint.h> - +#include <memory> #include <vector> #include "base/macros.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_framebuffer.cc b/ui/ozone/platform/drm/gpu/drm_framebuffer.cc index b632257..e348da1 100644 --- a/ui/ozone/platform/drm/gpu/drm_framebuffer.cc +++ b/ui/ozone/platform/drm/gpu/drm_framebuffer.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/drm/gpu/drm_framebuffer.h" +#include <utility> + #include "ui/ozone/common/linux/drm_util_linux.h" #include "ui/ozone/common/linux/gbm_buffer.h" #include "ui/ozone/platform/drm/common/drm_util.h"
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 232ae76..8ce4812 100644 --- a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc +++ b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc
@@ -5,6 +5,8 @@ #include "ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h" #include <stddef.h> +#include <memory> +#include <utility> #include "ui/display/types/display_mode.h" #include "ui/display/types/display_snapshot.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h index 4a7669fa..40d71dea 100644 --- a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h +++ b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h
@@ -6,7 +6,6 @@ #define UI_OZONE_PLATFORM_DRM_GPU_DRM_GPU_DISPLAY_MANAGER_H_ #include <stdint.h> - #include <memory> #include <vector>
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_plane.cc b/ui/ozone/platform/drm/gpu/drm_overlay_plane.cc index 87fa16d..72a00b7d 100644 --- a/ui/ozone/platform/drm/gpu/drm_overlay_plane.cc +++ b/ui/ozone/platform/drm/gpu/drm_overlay_plane.cc
@@ -5,6 +5,8 @@ #include "ui/ozone/platform/drm/gpu/drm_overlay_plane.h" #include <stddef.h> +#include <memory> +#include <utility> #include "ui/gfx/gpu_fence.h" #include "ui/ozone/platform/drm/gpu/drm_framebuffer.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_plane.h b/ui/ozone/platform/drm/gpu/drm_overlay_plane.h index e0dcf10..1e25e55a 100644 --- a/ui/ozone/platform/drm/gpu/drm_overlay_plane.h +++ b/ui/ozone/platform/drm/gpu/drm_overlay_plane.h
@@ -5,6 +5,7 @@ #ifndef UI_OZONE_PLATFORM_DRM_GPU_DRM_OVERLAY_PLANE_H_ #define UI_OZONE_PLATFORM_DRM_GPU_DRM_OVERLAY_PLANE_H_ +#include <memory> #include <vector> #include "base/bind.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc b/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc index ea0947a..d0fe454 100644 --- a/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc +++ b/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
@@ -5,6 +5,8 @@ #include "ui/ozone/platform/drm/gpu/drm_overlay_validator.h" #include <drm_fourcc.h> +#include <memory> +#include <utility> #include "base/files/platform_file.h" #include "ui/gfx/geometry/size_conversions.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc b/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc index 7aa4285..2f78b21 100644 --- a/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc +++ b/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc
@@ -5,7 +5,6 @@ #include "ui/ozone/platform/drm/gpu/drm_overlay_validator.h" #include <drm_fourcc.h> - #include <memory> #include <utility>
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc index 42cea80..3b53a0d 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.cc +++ b/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -5,6 +5,7 @@ #include "ui/ozone/platform/drm/gpu/drm_thread.h" #include <gbm.h> +#include <memory> #include <utility> #include "base/bind.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.h b/ui/ozone/platform/drm/gpu/drm_thread.h index 47f0937..fb9b070c 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.h +++ b/ui/ozone/platform/drm/gpu/drm_thread.h
@@ -6,7 +6,6 @@ #define UI_OZONE_PLATFORM_DRM_GPU_DRM_THREAD_H_ #include <stdint.h> - #include <memory> #include "base/files/file.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc b/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc index cf65c7bedb..ece302ba 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc +++ b/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h" +#include <utility> + #include "base/bind.h" #include "base/task_runner_util.h" #include "base/threading/thread_task_runner_handle.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc b/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc index 6b0f4b8..aa18dd98 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc +++ b/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
@@ -4,6 +4,7 @@ #include "ui/ozone/platform/drm/gpu/drm_thread_proxy.h" +#include <memory> #include <utility> #include "base/bind.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_window.cc b/ui/ozone/platform/drm/gpu/drm_window.cc index c2aadb9..99688b5 100644 --- a/ui/ozone/platform/drm/gpu/drm_window.cc +++ b/ui/ozone/platform/drm/gpu/drm_window.cc
@@ -6,6 +6,7 @@ #include <stddef.h> #include <stdint.h> +#include <utility> #include "base/macros.h" #include "base/time/time.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_window.h b/ui/ozone/platform/drm/gpu/drm_window.h index ad34c45..f0fbdb1 100644 --- a/ui/ozone/platform/drm/gpu/drm_window.h +++ b/ui/ozone/platform/drm/gpu/drm_window.h
@@ -5,6 +5,7 @@ #ifndef UI_OZONE_PLATFORM_DRM_GPU_DRM_WINDOW_H_ #define UI_OZONE_PLATFORM_DRM_GPU_DRM_WINDOW_H_ +#include <memory> #include <vector> #include "base/macros.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_window_proxy.cc b/ui/ozone/platform/drm/gpu/drm_window_proxy.cc index 8f06b91..45ed5b6 100644 --- a/ui/ozone/platform/drm/gpu/drm_window_proxy.cc +++ b/ui/ozone/platform/drm/gpu/drm_window_proxy.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/drm/gpu/drm_window_proxy.h" +#include <utility> + #include "base/bind.h" #include "base/command_line.h" #include "ui/gfx/gpu_fence.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_window_unittest.cc b/ui/ozone/platform/drm/gpu/drm_window_unittest.cc index 94233bc5..b2a0144 100644 --- a/ui/ozone/platform/drm/gpu/drm_window_unittest.cc +++ b/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
@@ -6,7 +6,6 @@ #include <drm_fourcc.h> #include <stdint.h> - #include <memory> #include <utility> #include <vector>
diff --git a/ui/ozone/platform/drm/gpu/gbm_overlay_surface.cc b/ui/ozone/platform/drm/gpu/gbm_overlay_surface.cc index d8f6f57..fecf60e5 100644 --- a/ui/ozone/platform/drm/gpu/gbm_overlay_surface.cc +++ b/ui/ozone/platform/drm/gpu/gbm_overlay_surface.cc
@@ -5,6 +5,8 @@ #include "ui/ozone/platform/drm/gpu/gbm_overlay_surface.h" #include <unistd.h> +#include <memory> +#include <utility> #include "base/bind.h" #include "base/bind_helpers.h"
diff --git a/ui/ozone/platform/drm/gpu/gbm_pixmap.cc b/ui/ozone/platform/drm/gpu/gbm_pixmap.cc index 17463810..2d80356 100644 --- a/ui/ozone/platform/drm/gpu/gbm_pixmap.cc +++ b/ui/ozone/platform/drm/gpu/gbm_pixmap.cc
@@ -5,6 +5,8 @@ #include "ui/ozone/platform/drm/gpu/gbm_pixmap.h" #include <gbm.h> +#include <memory> +#include <utility> #include "base/logging.h" #include "ui/gfx/gpu_fence.h"
diff --git a/ui/ozone/platform/drm/gpu/gbm_pixmap.h b/ui/ozone/platform/drm/gpu/gbm_pixmap.h index 6646759..60c856c 100644 --- a/ui/ozone/platform/drm/gpu/gbm_pixmap.h +++ b/ui/ozone/platform/drm/gpu/gbm_pixmap.h
@@ -5,6 +5,7 @@ #ifndef UI_OZONE_PLATFORM_DRM_GPU_GBM_BUFFER_H_ #define UI_OZONE_PLATFORM_DRM_GPU_GBM_BUFFER_H_ +#include <memory> #include <vector> #include "ui/gfx/native_pixmap.h"
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc index 55a2d8f..1e4fa9cc 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc +++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
@@ -5,7 +5,7 @@ #include "ui/ozone/platform/drm/gpu/gbm_surface_factory.h" #include <gbm.h> - +#include <memory> #include <utility> #include "base/files/file_path.h"
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.h b/ui/ozone/platform/drm/gpu/gbm_surface_factory.h index 028a168..5d4c822 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.h +++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.h
@@ -6,7 +6,6 @@ #define UI_OZONE_PLATFORM_DRM_GPU_GBM_SURFACE_FACTORY_H_ #include <stdint.h> - #include <map> #include <memory> #include <vector>
diff --git a/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc b/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc index 66d000a..67b9843 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc +++ b/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc
@@ -4,6 +4,7 @@ #include "ui/ozone/platform/drm/gpu/gbm_surfaceless.h" +#include <memory> #include <utility> #include "base/bind.h"
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller.cc b/ui/ozone/platform/drm/gpu/hardware_display_controller.cc index 8dbb15c..828f2e44 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_controller.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_controller.cc
@@ -7,6 +7,7 @@ #include <drm.h> #include <string.h> #include <xf86drm.h> +#include <memory> #include <utility> #include "base/bind.h"
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller.h b/ui/ozone/platform/drm/gpu/hardware_display_controller.h index 1031f12..7e6cb787 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_controller.h +++ b/ui/ozone/platform/drm/gpu/hardware_display_controller.h
@@ -8,7 +8,6 @@ #include <stddef.h> #include <stdint.h> #include <xf86drmMode.h> - #include <map> #include <memory> #include <unordered_map>
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc index 28c210a..d5ba180f3 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
@@ -5,6 +5,8 @@ #include <drm_fourcc.h> #include <stddef.h> #include <stdint.h> +#include <memory> +#include <utility> #include "base/bind.h" #include "base/macros.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 bb8799b..35eb919b 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
@@ -5,8 +5,8 @@ #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h" #include <drm_fourcc.h> - #include <algorithm> +#include <memory> #include <set> #include <utility>
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 45cd06c..f68e178 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <stdint.h> #include <xf86drmMode.h> +#include <memory> #include <vector> #include "base/macros.h"
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc index c1868d0f9..ae429e6 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
@@ -7,6 +7,8 @@ #include <sync/sync.h> #include <xf86drm.h> #include <xf86drmMode.h> +#include <memory> +#include <utility> #include "base/bind.h" #include "base/files/platform_file.h"
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h index b319614..c259643 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h
@@ -6,6 +6,7 @@ #define UI_OZONE_PLATFORM_DRM_GPU_HARDWARE_DISPLAY_PLANE_MANAGER_ATOMIC_H_ #include <stdint.h> +#include <memory> #include "base/macros.h" #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h"
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc index 498aec5..136f991 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
@@ -6,6 +6,8 @@ #include <errno.h> #include <sync/sync.h> +#include <memory> +#include <utility> #include "base/bind.h" #include "base/posix/eintr_wrapper.h"
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h index a40413f..3843560 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h
@@ -6,6 +6,7 @@ #define UI_OZONE_PLATFORM_DRM_GPU_HARDWARE_DISPLAY_PLANE_MANAGER_LEGACY_H_ #include <stdint.h> +#include <memory> #include "base/macros.h" #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h"
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc index 8c2a3d2..cfd0930 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
@@ -5,8 +5,8 @@ #include <drm_fourcc.h> #include <stdint.h> #include <unistd.h> - #include <memory> +#include <utility> #include "base/bind.h" #include "base/files/file_util.h"
diff --git a/ui/ozone/platform/drm/gpu/mock_drm_device.cc b/ui/ozone/platform/drm/gpu/mock_drm_device.cc index e9dfffb..38cc4f3 100644 --- a/ui/ozone/platform/drm/gpu/mock_drm_device.cc +++ b/ui/ozone/platform/drm/gpu/mock_drm_device.cc
@@ -5,6 +5,8 @@ #include "ui/ozone/platform/drm/gpu/mock_drm_device.h" #include <xf86drm.h> +#include <memory> +#include <utility> #include "base/logging.h" #include "base/stl_util.h"
diff --git a/ui/ozone/platform/drm/gpu/mock_drm_device.h b/ui/ozone/platform/drm/gpu/mock_drm_device.h index 64279da..ab824d5 100644 --- a/ui/ozone/platform/drm/gpu/mock_drm_device.h +++ b/ui/ozone/platform/drm/gpu/mock_drm_device.h
@@ -8,8 +8,8 @@ #include <drm_mode.h> #include <stddef.h> #include <stdint.h> - #include <map> +#include <memory> #include <set> #include <vector>
diff --git a/ui/ozone/platform/drm/gpu/mock_gbm_device.cc b/ui/ozone/platform/drm/gpu/mock_gbm_device.cc index 713478e2..20d6f1f 100644 --- a/ui/ozone/platform/drm/gpu/mock_gbm_device.cc +++ b/ui/ozone/platform/drm/gpu/mock_gbm_device.cc
@@ -6,6 +6,8 @@ #include <drm_fourcc.h> #include <xf86drm.h> +#include <memory> +#include <utility> #include "base/logging.h" #include "base/numerics/safe_math.h"
diff --git a/ui/ozone/platform/drm/gpu/page_flip_request.cc b/ui/ozone/platform/drm/gpu/page_flip_request.cc index 7f37668f..b863742b 100644 --- a/ui/ozone/platform/drm/gpu/page_flip_request.cc +++ b/ui/ozone/platform/drm/gpu/page_flip_request.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/drm/gpu/page_flip_request.h" +#include <utility> + #include "base/bind.h" #include "ui/gfx/presentation_feedback.h"
diff --git a/ui/ozone/platform/drm/gpu/proxy_helpers.cc b/ui/ozone/platform/drm/gpu/proxy_helpers.cc index 72dca98..603b3bc 100644 --- a/ui/ozone/platform/drm/gpu/proxy_helpers.cc +++ b/ui/ozone/platform/drm/gpu/proxy_helpers.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/drm/gpu/proxy_helpers.h" +#include <utility> + #include "base/synchronization/waitable_event.h" namespace ui {
diff --git a/ui/ozone/platform/drm/gpu/proxy_helpers.h b/ui/ozone/platform/drm/gpu/proxy_helpers.h index 8f7c326..b0d8a52 100644 --- a/ui/ozone/platform/drm/gpu/proxy_helpers.h +++ b/ui/ozone/platform/drm/gpu/proxy_helpers.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_DRM_GPU_PROXY_HELPERS_H_ #define UI_OZONE_PLATFORM_DRM_GPU_PROXY_HELPERS_H_ +#include <utility> + #include "base/bind.h" #include "base/location.h" #include "base/memory/ref_counted.h"
diff --git a/ui/ozone/platform/drm/gpu/proxy_helpers_unittest.cc b/ui/ozone/platform/drm/gpu/proxy_helpers_unittest.cc index 9831443..b96b390 100644 --- a/ui/ozone/platform/drm/gpu/proxy_helpers_unittest.cc +++ b/ui/ozone/platform/drm/gpu/proxy_helpers_unittest.cc
@@ -4,6 +4,9 @@ #include "ui/ozone/platform/drm/gpu/proxy_helpers.h" +#include <memory> +#include <utility> + #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h"
diff --git a/ui/ozone/platform/drm/gpu/screen_manager.cc b/ui/ozone/platform/drm/gpu/screen_manager.cc index 5fe1773..894283b 100644 --- a/ui/ozone/platform/drm/gpu/screen_manager.cc +++ b/ui/ozone/platform/drm/gpu/screen_manager.cc
@@ -5,7 +5,7 @@ #include "ui/ozone/platform/drm/gpu/screen_manager.h" #include <xf86drmMode.h> - +#include <memory> #include <utility> #include "base/files/platform_file.h"
diff --git a/ui/ozone/platform/drm/gpu/screen_manager.h b/ui/ozone/platform/drm/gpu/screen_manager.h index e5c2760d..9b1aeb2e 100644 --- a/ui/ozone/platform/drm/gpu/screen_manager.h +++ b/ui/ozone/platform/drm/gpu/screen_manager.h
@@ -6,7 +6,7 @@ #define UI_OZONE_PLATFORM_DRM_GPU_SCREEN_MANAGER_H_ #include <stdint.h> - +#include <memory> #include <unordered_map> #include "base/macros.h"
diff --git a/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc b/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc index 4deec5b..c4d137db 100644 --- a/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc +++ b/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
@@ -5,7 +5,7 @@ #include <drm_fourcc.h> #include <stddef.h> #include <stdint.h> - +#include <memory> #include <utility> #include "base/bind_helpers.h"
diff --git a/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.cc b/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.cc index 21e13af..6564a885 100644 --- a/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.cc +++ b/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.h" +#include <memory> + #include "base/files/file_path.h" #include "base/native_library.h" #include "gpu/vulkan/vulkan_function_pointers.h"
diff --git a/ui/ozone/platform/drm/host/drm_cursor.cc b/ui/ozone/platform/drm/host/drm_cursor.cc index 3b8e789..8e420a59 100644 --- a/ui/ozone/platform/drm/host/drm_cursor.cc +++ b/ui/ozone/platform/drm/host/drm_cursor.cc
@@ -4,6 +4,9 @@ #include "ui/ozone/platform/drm/host/drm_cursor.h" +#include <memory> +#include <utility> + #include "base/trace_event/trace_event.h" #include "ui/gfx/geometry/point_conversions.h" #include "ui/ozone/platform/drm/host/drm_window_host.h"
diff --git a/ui/ozone/platform/drm/host/drm_device_connector.cc b/ui/ozone/platform/drm/host/drm_device_connector.cc index 2da65e7..d207dbe1 100644 --- a/ui/ozone/platform/drm/host/drm_device_connector.cc +++ b/ui/ozone/platform/drm/host/drm_device_connector.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/drm/host/drm_device_connector.h" +#include <utility> + #include "base/bind.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/cpp/system/message_pipe.h"
diff --git a/ui/ozone/platform/drm/host/drm_display_host.cc b/ui/ozone/platform/drm/host/drm_display_host.cc index 78271ca..a0bcdbc 100644 --- a/ui/ozone/platform/drm/host/drm_display_host.cc +++ b/ui/ozone/platform/drm/host/drm_display_host.cc
@@ -4,6 +4,9 @@ #include "ui/ozone/platform/drm/host/drm_display_host.h" +#include <memory> +#include <utility> + #include "base/bind.h" #include "base/location.h" #include "base/threading/thread_task_runner_handle.h"
diff --git a/ui/ozone/platform/drm/host/drm_display_host_manager.cc b/ui/ozone/platform/drm/host/drm_display_host_manager.cc index d339e42..666b731 100644 --- a/ui/ozone/platform/drm/host/drm_display_host_manager.cc +++ b/ui/ozone/platform/drm/host/drm_display_host_manager.cc
@@ -7,7 +7,7 @@ #include <fcntl.h> #include <stddef.h> #include <xf86drm.h> - +#include <memory> #include <utility> #include "base/bind.h"
diff --git a/ui/ozone/platform/drm/host/drm_display_host_manager.h b/ui/ozone/platform/drm/host/drm_display_host_manager.h index 50fc27d9..2d211b0 100644 --- a/ui/ozone/platform/drm/host/drm_display_host_manager.h +++ b/ui/ozone/platform/drm/host/drm_display_host_manager.h
@@ -6,7 +6,6 @@ #define UI_OZONE_PLATFORM_DRM_HOST_DRM_DISPLAY_HOST_MANAGER_H_ #include <stdint.h> - #include <map> #include <memory>
diff --git a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc index e4677fb81..4e353fb4 100644 --- a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc +++ b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
@@ -5,6 +5,7 @@ #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h" #include <stddef.h> +#include <utility> #include "base/bind.h" #include "base/command_line.h"
diff --git a/ui/ozone/platform/drm/host/drm_native_display_delegate.cc b/ui/ozone/platform/drm/host/drm_native_display_delegate.cc index 61d507f1..54ecf76 100644 --- a/ui/ozone/platform/drm/host/drm_native_display_delegate.cc +++ b/ui/ozone/platform/drm/host/drm_native_display_delegate.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/drm/host/drm_native_display_delegate.h" +#include <utility> + #include "ui/display/types/display_snapshot.h" #include "ui/display/types/native_display_observer.h" #include "ui/ozone/platform/drm/host/drm_display_host.h"
diff --git a/ui/ozone/platform/drm/host/host_cursor_proxy.cc b/ui/ozone/platform/drm/host/host_cursor_proxy.cc index 2a6e342..766980d 100644 --- a/ui/ozone/platform/drm/host/host_cursor_proxy.cc +++ b/ui/ozone/platform/drm/host/host_cursor_proxy.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/drm/host/host_cursor_proxy.h" +#include <utility> + #include "services/service_manager/public/cpp/connector.h" #include "services/ws/public/mojom/constants.mojom.h" #include "ui/ozone/public/gpu_platform_support_host.h"
diff --git a/ui/ozone/platform/drm/host/host_drm_device.cc b/ui/ozone/platform/drm/host/host_drm_device.cc index a82b7e9c..4ff514f 100644 --- a/ui/ozone/platform/drm/host/host_drm_device.cc +++ b/ui/ozone/platform/drm/host/host_drm_device.cc
@@ -4,6 +4,9 @@ #include "ui/ozone/platform/drm/host/host_drm_device.h" +#include <memory> +#include <utility> + #include "base/bind.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h"
diff --git a/ui/ozone/platform/drm/host/host_drm_device.h b/ui/ozone/platform/drm/host/host_drm_device.h index 30f61c1..7c518779 100644 --- a/ui/ozone/platform/drm/host/host_drm_device.h +++ b/ui/ozone/platform/drm/host/host_drm_device.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_DRM_HOST_HOST_DRM_DEVICE_H_ #define UI_OZONE_PLATFORM_DRM_HOST_HOST_DRM_DEVICE_H_ +#include <memory> + #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h"
diff --git a/ui/ozone/platform/drm/ozone_platform_gbm.cc b/ui/ozone/platform/drm/ozone_platform_gbm.cc index bdaa1a2..858c141 100644 --- a/ui/ozone/platform/drm/ozone_platform_gbm.cc +++ b/ui/ozone/platform/drm/ozone_platform_gbm.cc
@@ -7,7 +7,6 @@ #include <gbm.h> #include <stdlib.h> #include <xf86drm.h> - #include <memory> #include <utility>
diff --git a/ui/ozone/platform/headless/headless_native_display_delegate.cc b/ui/ozone/platform/headless/headless_native_display_delegate.cc index a4ca1d32..adb1175 100644 --- a/ui/ozone/platform/headless/headless_native_display_delegate.cc +++ b/ui/ozone/platform/headless/headless_native_display_delegate.cc
@@ -4,6 +4,9 @@ #include "ui/ozone/platform/headless/headless_native_display_delegate.h" +#include <memory> +#include <utility> + #include "ui/display/types/display_snapshot.h" #include "ui/display/types/native_display_observer.h"
diff --git a/ui/ozone/platform/headless/headless_native_display_delegate.h b/ui/ozone/platform/headless/headless_native_display_delegate.h index 37ac5ba..1cd9402a 100644 --- a/ui/ozone/platform/headless/headless_native_display_delegate.h +++ b/ui/ozone/platform/headless/headless_native_display_delegate.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_HEADLESS_HEADLESS_NATIVE_DISPLAY_DELEGATE_H_ #define UI_OZONE_PLATFORM_HEADLESS_HEADLESS_NATIVE_DISPLAY_DELEGATE_H_ +#include <memory> + #include "base/observer_list.h" #include "ui/display/types/native_display_delegate.h"
diff --git a/ui/ozone/platform/headless/headless_surface_factory.cc b/ui/ozone/platform/headless/headless_surface_factory.cc index d1ef15f..3c3a0b75 100644 --- a/ui/ozone/platform/headless/headless_surface_factory.cc +++ b/ui/ozone/platform/headless/headless_surface_factory.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/headless/headless_surface_factory.h" +#include <memory> + #include "base/bind.h" #include "base/files/file_util.h" #include "base/location.h"
diff --git a/ui/ozone/platform/headless/ozone_platform_headless.cc b/ui/ozone/platform/headless/ozone_platform_headless.cc index 3e22233..85279dd 100644 --- a/ui/ozone/platform/headless/ozone_platform_headless.cc +++ b/ui/ozone/platform/headless/ozone_platform_headless.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/headless/ozone_platform_headless.h" +#include <memory> + #include "base/command_line.h" #include "base/files/file_path.h" #include "base/macros.h"
diff --git a/ui/ozone/platform/magma/ozone_platform_magma.cc b/ui/ozone/platform/magma/ozone_platform_magma.cc index f5467a4..40c6b82 100644 --- a/ui/ozone/platform/magma/ozone_platform_magma.cc +++ b/ui/ozone/platform/magma/ozone_platform_magma.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/magma/ozone_platform_magma.h" +#include <memory> + #include "base/command_line.h" #include "base/files/file_path.h" #include "base/macros.h"
diff --git a/ui/ozone/platform/scenic/scenic_gpu_host.cc b/ui/ozone/platform/scenic/scenic_gpu_host.cc index 758de96..9e9925e 100644 --- a/ui/ozone/platform/scenic/scenic_gpu_host.cc +++ b/ui/ozone/platform/scenic/scenic_gpu_host.cc
@@ -5,6 +5,7 @@ #include "ui/ozone/platform/scenic/scenic_gpu_host.h" #include <inttypes.h> +#include <utility> #include "base/bind.h" #include "base/callback.h"
diff --git a/ui/ozone/platform/scenic/scenic_surface_factory.cc b/ui/ozone/platform/scenic/scenic_surface_factory.cc index 8187064..f559780 100644 --- a/ui/ozone/platform/scenic/scenic_surface_factory.cc +++ b/ui/ozone/platform/scenic/scenic_surface_factory.cc
@@ -5,6 +5,7 @@ #include "ui/ozone/platform/scenic/scenic_surface_factory.h" #include <lib/zx/event.h> +#include <memory> #include "base/bind.h" #include "base/fuchsia/fuchsia_logging.h"
diff --git a/ui/ozone/platform/scenic/scenic_window_canvas.cc b/ui/ozone/platform/scenic/scenic_window_canvas.cc index 1559148..9f8d43e3d 100644 --- a/ui/ozone/platform/scenic/scenic_window_canvas.cc +++ b/ui/ozone/platform/scenic/scenic_window_canvas.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/scenic/scenic_window_canvas.h" +#include <memory> + #include "base/fuchsia/fuchsia_logging.h" #include "base/memory/read_only_shared_memory_region.h" #include "base/memory/writable_shared_memory_region.h"
diff --git a/ui/ozone/platform/scenic/scenic_window_canvas.h b/ui/ozone/platform/scenic/scenic_window_canvas.h index f385a96..237e621a 100644 --- a/ui/ozone/platform/scenic/scenic_window_canvas.h +++ b/ui/ozone/platform/scenic/scenic_window_canvas.h
@@ -6,6 +6,7 @@ #define UI_OZONE_PLATFORM_SCENIC_SCENIC_WINDOW_CANVAS_H_ #include <lib/ui/scenic/cpp/resources.h> +#include <memory> #include "base/macros.h" #include "base/memory/shared_memory_mapping.h"
diff --git a/ui/ozone/platform/scenic/scenic_window_manager.cc b/ui/ozone/platform/scenic/scenic_window_manager.cc index aeabc0ee..da55cee 100644 --- a/ui/ozone/platform/scenic/scenic_window_manager.cc +++ b/ui/ozone/platform/scenic/scenic_window_manager.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/scenic/scenic_window_manager.h" +#include <memory> + #include "base/fuchsia/fuchsia_logging.h" #include "base/fuchsia/service_directory_client.h" #include "ui/ozone/platform/scenic/ozone_platform_scenic.h"
diff --git a/ui/ozone/platform/scenic/vulkan_implementation_scenic.cc b/ui/ozone/platform/scenic/vulkan_implementation_scenic.cc index 72184009..e82f0b3 100644 --- a/ui/ozone/platform/scenic/vulkan_implementation_scenic.cc +++ b/ui/ozone/platform/scenic/vulkan_implementation_scenic.cc
@@ -8,6 +8,7 @@ #include <lib/ui/scenic/cpp/session.h> #include <lib/zx/channel.h> #include <vulkan/vulkan.h> +#include <memory> #include "base/bind_helpers.h" #include "base/files/file_path.h"
diff --git a/ui/ozone/platform/wayland/gl_surface_wayland.cc b/ui/ozone/platform/wayland/gl_surface_wayland.cc index 5827383e..1c65f6d 100644 --- a/ui/ozone/platform/wayland/gl_surface_wayland.cc +++ b/ui/ozone/platform/wayland/gl_surface_wayland.cc
@@ -5,7 +5,7 @@ #include "ui/ozone/platform/wayland/gl_surface_wayland.h" #include <wayland-egl.h> - +#include <memory> #include <utility> #include "third_party/khronos/EGL/egl.h"
diff --git a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc index c2c1ea08..ca6ccf6 100644 --- a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc +++ b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc
@@ -7,6 +7,7 @@ #include <drm_fourcc.h> #include <gbm.h> #include <xf86drmMode.h> +#include <memory> #include "base/files/platform_file.h" #include "base/logging.h"
diff --git a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h index 3c191cee..3f43538b 100644 --- a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h +++ b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h
@@ -5,6 +5,7 @@ #ifndef UI_OZONE_PLATFORM_WAYLAND_GPU_GBM_PIXMAP_WAYLAND_H_ #define UI_OZONE_PLATFORM_WAYLAND_GPU_GBM_PIXMAP_WAYLAND_H_ +#include <memory> #include <vector> #include "base/files/scoped_file.h"
diff --git a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc index 175f0b6..49d2938 100644 --- a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc +++ b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h" +#include <memory> + #include "base/bind.h" #include "base/task/post_task.h" #include "base/trace_event/trace_event.h"
diff --git a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h index 6870debb..f86dd4b0 100644 --- a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h +++ b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_WAYLAND_GPU_GBM_SURFACELESS_WAYLAND_H_ #define UI_OZONE_PLATFORM_WAYLAND_GPU_GBM_SURFACELESS_WAYLAND_H_ +#include <memory> + #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "ui/gfx/native_widget_types.h"
diff --git a/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc b/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc index a281d5b..a8fb25a 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc +++ b/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc
@@ -4,6 +4,7 @@ #include "ui/ozone/platform/wayland/gpu/wayland_canvas_surface.h" +#include <memory> #include <utility> #include "base/files/scoped_file.h"
diff --git a/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h b/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h index 2790987..13a8d04 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h +++ b/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_WAYLAND_GPU_WAYLAND_CONNECTION_PROXY_H_ #define UI_OZONE_PLATFORM_WAYLAND_GPU_WAYLAND_CONNECTION_PROXY_H_ +#include <memory> + #include "base/macros.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/thread_checker.h"
diff --git a/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc b/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc index e92e077..99e8a3e 100644 --- a/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc +++ b/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc
@@ -7,6 +7,7 @@ #include <stdlib.h> #include <sys/socket.h> #include <wayland-server.h> +#include <memory> #include "base/bind.h" #include "base/files/file_util.h"
diff --git a/ui/ozone/platform/wayland/test/test_wayland_server_thread.h b/ui/ozone/platform/wayland/test/test_wayland_server_thread.h index 24c00bf5..fddd426d 100644 --- a/ui/ozone/platform/wayland/test/test_wayland_server_thread.h +++ b/ui/ozone/platform/wayland/test/test_wayland_server_thread.h
@@ -7,7 +7,6 @@ #include <memory> #include <vector> - #include <wayland-server-core.h> #include "base/message_loop/message_pump_libevent.h"
diff --git a/ui/ozone/platform/wayland/wayland_buffer_fuzzer.cc b/ui/ozone/platform/wayland/wayland_buffer_fuzzer.cc index f10f9336..117208c 100644 --- a/ui/ozone/platform/wayland/wayland_buffer_fuzzer.cc +++ b/ui/ozone/platform/wayland/wayland_buffer_fuzzer.cc
@@ -8,7 +8,6 @@ #include <drm_fourcc.h> #include <stddef.h> #include <stdint.h> - #include <memory> #include <vector>
diff --git a/ui/ozone/platform/wayland/wayland_buffer_manager.cc b/ui/ozone/platform/wayland/wayland_buffer_manager.cc index 862989e1..7b0bf9a 100644 --- a/ui/ozone/platform/wayland/wayland_buffer_manager.cc +++ b/ui/ozone/platform/wayland/wayland_buffer_manager.cc
@@ -7,6 +7,7 @@ #include <drm_fourcc.h> #include <linux-dmabuf-unstable-v1-client-protocol.h> #include <presentation-time-client-protocol.h> +#include <memory> #include "base/trace_event/trace_event.h" #include "ui/ozone/common/linux/drm_util_linux.h"
diff --git a/ui/ozone/platform/wayland/wayland_buffer_manager.h b/ui/ozone/platform/wayland/wayland_buffer_manager.h index 50e44bb..0c33947e 100644 --- a/ui/ozone/platform/wayland/wayland_buffer_manager.h +++ b/ui/ozone/platform/wayland/wayland_buffer_manager.h
@@ -6,6 +6,7 @@ #define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_BUFFER_MANAGER_H_ #include <map> +#include <memory> #include <vector> #include "base/containers/flat_map.h"
diff --git a/ui/ozone/platform/wayland/wayland_connection.cc b/ui/ozone/platform/wayland/wayland_connection.cc index bbcb18e..ca36a1be 100644 --- a/ui/ozone/platform/wayland/wayland_connection.cc +++ b/ui/ozone/platform/wayland/wayland_connection.cc
@@ -6,6 +6,7 @@ #include <xdg-shell-unstable-v5-client-protocol.h> #include <xdg-shell-unstable-v6-client-protocol.h> +#include <memory> #include <algorithm> #include <utility>
diff --git a/ui/ozone/platform/wayland/wayland_cursor.cc b/ui/ozone/platform/wayland/wayland_cursor.cc index 725e70c..deb8641 100644 --- a/ui/ozone/platform/wayland/wayland_cursor.cc +++ b/ui/ozone/platform/wayland/wayland_cursor.cc
@@ -4,6 +4,9 @@ #include "ui/ozone/platform/wayland/wayland_cursor.h" +#include <memory> +#include <vector> + #include "base/memory/shared_memory.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/skia_util.h"
diff --git a/ui/ozone/platform/wayland/wayland_data_device.cc b/ui/ozone/platform/wayland/wayland_data_device.cc index ab5df3f4..dfe42f2 100644 --- a/ui/ozone/platform/wayland/wayland_data_device.cc +++ b/ui/ozone/platform/wayland/wayland_data_device.cc
@@ -4,6 +4,7 @@ #include "ui/ozone/platform/wayland/wayland_data_device.h" +#include <memory> #include <utility> #include "base/bind.h"
diff --git a/ui/ozone/platform/wayland/wayland_data_device_unittest.cc b/ui/ozone/platform/wayland/wayland_data_device_unittest.cc index b09b8cb..50c4d7e 100644 --- a/ui/ozone/platform/wayland/wayland_data_device_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_data_device_unittest.cc
@@ -4,6 +4,8 @@ #include <wayland-server.h> +#include <memory> + #include "base/bind.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/dragdrop/drag_drop_types.h"
diff --git a/ui/ozone/platform/wayland/wayland_input_method_context_factory.cc b/ui/ozone/platform/wayland/wayland_input_method_context_factory.cc index 2b8349a..7537f27e 100644 --- a/ui/ozone/platform/wayland/wayland_input_method_context_factory.cc +++ b/ui/ozone/platform/wayland/wayland_input_method_context_factory.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/wayland/wayland_input_method_context_factory.h" +#include <memory> + #include "base/bind.h" #include "ui/ozone/platform/wayland/wayland_connection.h" #include "ui/ozone/platform/wayland/wayland_input_method_context.h"
diff --git a/ui/ozone/platform/wayland/wayland_input_method_context_factory.h b/ui/ozone/platform/wayland/wayland_input_method_context_factory.h index 413f3a4..23bd695 100644 --- a/ui/ozone/platform/wayland/wayland_input_method_context_factory.h +++ b/ui/ozone/platform/wayland/wayland_input_method_context_factory.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_WAYLAND_WAYLAND_INPUT_METHOD_CONTEXT_FACTORY_H_ #define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_INPUT_METHOD_CONTEXT_FACTORY_H_ +#include <memory> + #include "base/macros.h" #include "ui/base/ime/linux/linux_input_method_context_factory.h"
diff --git a/ui/ozone/platform/wayland/wayland_input_method_context_unittest.cc b/ui/ozone/platform/wayland/wayland_input_method_context_unittest.cc index 08bf4b7..83ca9f2b 100644 --- a/ui/ozone/platform/wayland/wayland_input_method_context_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_input_method_context_unittest.cc
@@ -4,6 +4,7 @@ #include <text-input-unstable-v1-server-protocol.h> #include <wayland-server.h> +#include <memory> #include "mojo/public/cpp/bindings/binding.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/ui/ozone/platform/wayland/wayland_keyboard_unittest.cc b/ui/ozone/platform/wayland/wayland_keyboard_unittest.cc index 7d85608..3e7abb0 100644 --- a/ui/ozone/platform/wayland/wayland_keyboard_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_keyboard_unittest.cc
@@ -4,6 +4,7 @@ #include <linux/input.h> #include <wayland-server.h> +#include <memory> #include "base/test/test_mock_time_task_runner.h" #include "base/timer/timer.h"
diff --git a/ui/ozone/platform/wayland/wayland_object.h b/ui/ozone/platform/wayland/wayland_object.h index f7f7fd3..cdae701b 100644 --- a/ui/ozone/platform/wayland/wayland_object.h +++ b/ui/ozone/platform/wayland/wayland_object.h
@@ -6,7 +6,6 @@ #define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_OBJECT_H_ #include <wayland-client-core.h> - #include <memory> struct wl_buffer;
diff --git a/ui/ozone/platform/wayland/wayland_output_manager.cc b/ui/ozone/platform/wayland/wayland_output_manager.cc index 992d0c3..a7f6e44 100644 --- a/ui/ozone/platform/wayland/wayland_output_manager.cc +++ b/ui/ozone/platform/wayland/wayland_output_manager.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/wayland/wayland_output_manager.h" +#include <memory> + #include "ui/ozone/platform/wayland/wayland_connection.h" #include "ui/ozone/platform/wayland/wayland_output.h"
diff --git a/ui/ozone/platform/wayland/wayland_pointer.h b/ui/ozone/platform/wayland/wayland_pointer.h index 109d08d..070e0b62 100644 --- a/ui/ozone/platform/wayland/wayland_pointer.h +++ b/ui/ozone/platform/wayland/wayland_pointer.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_WAYLAND_WAYLAND_POINTER_H_ #define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_POINTER_H_ +#include <memory> + #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "ui/events/ozone/evdev/event_dispatch_callback.h"
diff --git a/ui/ozone/platform/wayland/wayland_pointer_unittest.cc b/ui/ozone/platform/wayland/wayland_pointer_unittest.cc index 49dcfe7..3b3aa896 100644 --- a/ui/ozone/platform/wayland/wayland_pointer_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_pointer_unittest.cc
@@ -4,6 +4,7 @@ #include <linux/input.h> #include <wayland-server.h> +#include <memory> #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ui/ozone/platform/wayland/wayland_screen_unittest.cc b/ui/ozone/platform/wayland/wayland_screen_unittest.cc index a6513be6..e081590a 100644 --- a/ui/ozone/platform/wayland/wayland_screen_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_screen_unittest.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include <memory> - #include <wayland-server.h> #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ui/ozone/platform/wayland/wayland_surface_factory.h b/ui/ozone/platform/wayland/wayland_surface_factory.h index 2f5ab3a..be0bf798 100644 --- a/ui/ozone/platform/wayland/wayland_surface_factory.h +++ b/ui/ozone/platform/wayland/wayland_surface_factory.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_WAYLAND_WAYLAND_SURFACE_FACTORY_H_ #define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_SURFACE_FACTORY_H_ +#include <memory> + #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h"
diff --git a/ui/ozone/platform/wayland/wayland_surface_factory_unittest.cc b/ui/ozone/platform/wayland/wayland_surface_factory_unittest.cc index 87861f46..f040c66 100644 --- a/ui/ozone/platform/wayland/wayland_surface_factory_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_surface_factory_unittest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> #include <utility> #include "base/run_loop.h"
diff --git a/ui/ozone/platform/wayland/wayland_test.h b/ui/ozone/platform/wayland/wayland_test.h index 625d7e60a..2c83f37 100644 --- a/ui/ozone/platform/wayland/wayland_test.h +++ b/ui/ozone/platform/wayland/wayland_test.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_WAYLAND_WAYLAND_TEST_H_ #define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_TEST_H_ +#include <memory> + #include "base/message_loop/message_loop.h" #include "base/test/scoped_task_environment.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ui/ozone/platform/wayland/wayland_touch_unittest.cc b/ui/ozone/platform/wayland/wayland_touch_unittest.cc index 831dd903..9a64f9c 100644 --- a/ui/ozone/platform/wayland/wayland_touch_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_touch_unittest.cc
@@ -4,6 +4,7 @@ #include <linux/input.h> #include <wayland-server.h> +#include <memory> #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ui/ozone/platform/wayland/wayland_window.cc b/ui/ozone/platform/wayland/wayland_window.cc index 7b65895..f0ae1a0 100644 --- a/ui/ozone/platform/wayland/wayland_window.cc +++ b/ui/ozone/platform/wayland/wayland_window.cc
@@ -4,9 +4,8 @@ #include "ui/ozone/platform/wayland/wayland_window.h" -#include <memory> - #include <wayland-client.h> +#include <memory> #include "base/bind.h" #include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
diff --git a/ui/ozone/platform/wayland/wayland_window.h b/ui/ozone/platform/wayland/wayland_window.h index 4c7271d..94c3a60 100644 --- a/ui/ozone/platform/wayland/wayland_window.h +++ b/ui/ozone/platform/wayland/wayland_window.h
@@ -5,6 +5,7 @@ #ifndef UI_OZONE_PLATFORM_WAYLAND_WAYLAND_WINDOW_H_ #define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_WINDOW_H_ +#include <memory> #include <set> #include <vector>
diff --git a/ui/ozone/platform/wayland/xdg_popup_wrapper_v6.cc b/ui/ozone/platform/wayland/xdg_popup_wrapper_v6.cc index 38b274f..866133e 100644 --- a/ui/ozone/platform/wayland/xdg_popup_wrapper_v6.cc +++ b/ui/ozone/platform/wayland/xdg_popup_wrapper_v6.cc
@@ -5,6 +5,7 @@ #include "ui/ozone/platform/wayland/xdg_popup_wrapper_v6.h" #include <xdg-shell-unstable-v6-client-protocol.h> +#include <memory> #include "ui/events/event_constants.h" #include "ui/gfx/geometry/rect.h"
diff --git a/ui/ozone/platform/wayland/xdg_popup_wrapper_v6.h b/ui/ozone/platform/wayland/xdg_popup_wrapper_v6.h index 4e43d2dd..cd56eeff 100644 --- a/ui/ozone/platform/wayland/xdg_popup_wrapper_v6.h +++ b/ui/ozone/platform/wayland/xdg_popup_wrapper_v6.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_WAYLAND_XDG_POPUP_WRAPPER_V6_H_ #define UI_OZONE_PLATFORM_WAYLAND_XDG_POPUP_WRAPPER_V6_H_ +#include <memory> + #include "ui/ozone/platform/wayland/xdg_popup_wrapper.h" namespace ui {
diff --git a/ui/ozone/platform/windows/ozone_platform_windows.cc b/ui/ozone/platform/windows/ozone_platform_windows.cc index 8346924..7b0a5982 100644 --- a/ui/ozone/platform/windows/ozone_platform_windows.cc +++ b/ui/ozone/platform/windows/ozone_platform_windows.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/windows/ozone_platform_windows.h" +#include <memory> + #include "base/command_line.h" #include "base/files/file_path.h" #include "base/macros.h"
diff --git a/ui/ozone/platform/x11/x11_screen_ozone.h b/ui/ozone/platform/x11/x11_screen_ozone.h index cd16a1c9..5acf82a2 100644 --- a/ui/ozone/platform/x11/x11_screen_ozone.h +++ b/ui/ozone/platform/x11/x11_screen_ozone.h
@@ -5,6 +5,7 @@ #ifndef UI_OZONE_PLATFORM_X11_X11_SCREEN_OZONE_H_ #define UI_OZONE_PLATFORM_X11_X11_SCREEN_OZONE_H_ +#include <memory> #include <vector> #include "base/macros.h"
diff --git a/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc b/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc index 6086f084..250da19 100644 --- a/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc +++ b/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/x11/x11_screen_ozone.h" +#include <memory> + #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/display.h"
diff --git a/ui/ozone/platform/x11/x11_surface_factory.cc b/ui/ozone/platform/x11/x11_surface_factory.cc index 74aa63ce..6011ca12 100644 --- a/ui/ozone/platform/x11/x11_surface_factory.cc +++ b/ui/ozone/platform/x11/x11_surface_factory.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/x11/x11_surface_factory.h" +#include <memory> + #include "gpu/vulkan/buildflags.h" #include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11_types.h"
diff --git a/ui/ozone/platform/x11/x11_window_ozone_unittest.cc b/ui/ozone/platform/x11/x11_window_ozone_unittest.cc index 2a74570..2484f518 100644 --- a/ui/ozone/platform/x11/x11_window_ozone_unittest.cc +++ b/ui/ozone/platform/x11/x11_window_ozone_unittest.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/x11/x11_window_ozone.h" +#include <memory> + #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ui/ozone/platform_object_internal.h b/ui/ozone/platform_object_internal.h index bcf1b46..c548931c 100644 --- a/ui/ozone/platform_object_internal.h +++ b/ui/ozone/platform_object_internal.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_OBJECT_INTERNAL_H_ #define UI_OZONE_PLATFORM_OBJECT_INTERNAL_H_ +#include <memory> + #include "base/memory/ptr_util.h" #include "ui/ozone/ozone_export.h" #include "ui/ozone/platform_constructor_list.h"
diff --git a/ui/ozone/public/client_native_pixmap_factory_ozone.cc b/ui/ozone/public/client_native_pixmap_factory_ozone.cc index 7d6428b..c118a31 100644 --- a/ui/ozone/public/client_native_pixmap_factory_ozone.cc +++ b/ui/ozone/public/client_native_pixmap_factory_ozone.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/public/client_native_pixmap_factory_ozone.h" +#include <memory> + #include "base/trace_event/trace_event.h" #include "ui/ozone/platform_object.h" #include "ui/ozone/platform_selection.h"
diff --git a/ui/ozone/public/client_native_pixmap_factory_ozone.h b/ui/ozone/public/client_native_pixmap_factory_ozone.h index 744e868a..a152589 100644 --- a/ui/ozone/public/client_native_pixmap_factory_ozone.h +++ b/ui/ozone/public/client_native_pixmap_factory_ozone.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PUBLIC_CLIENT_NATIVE_PIXMAP_FACTORY_OZONE_H_ #define UI_OZONE_PUBLIC_CLIENT_NATIVE_PIXMAP_FACTORY_OZONE_H_ +#include <memory> + #include "ui/gfx/client_native_pixmap_factory.h" #include "ui/ozone/ozone_export.h"
diff --git a/ui/ozone/public/input_controller.cc b/ui/ozone/public/input_controller.cc index 4ba1521c..daacfbb44 100644 --- a/ui/ozone/public/input_controller.cc +++ b/ui/ozone/public/input_controller.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/public/input_controller.h" +#include <memory> + #include "base/callback.h" #include "base/logging.h" #include "base/macros.h"
diff --git a/ui/ozone/public/overlay_plane.cc b/ui/ozone/public/overlay_plane.cc index ddc0abbb..35cd261 100644 --- a/ui/ozone/public/overlay_plane.cc +++ b/ui/ozone/public/overlay_plane.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/public/overlay_plane.h" +#include <memory> + namespace ui { OverlayPlane::OverlayPlane() {}
diff --git a/ui/ozone/public/overlay_plane.h b/ui/ozone/public/overlay_plane.h index c1b5e8d2..9689177 100644 --- a/ui/ozone/public/overlay_plane.h +++ b/ui/ozone/public/overlay_plane.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PUBLIC_OVERLAY_PLANE_H_ #define UI_OZONE_PUBLIC_OVERLAY_PLANE_H_ +#include <memory> + #include "base/macros.h" #include "base/memory/ref_counted.h" #include "ui/gfx/geometry/rect.h"
diff --git a/ui/ozone/public/ozone_platform.cc b/ui/ozone/public/ozone_platform.cc index e3c40bec..787f3fa 100644 --- a/ui/ozone/public/ozone_platform.cc +++ b/ui/ozone/public/ozone_platform.cc
@@ -4,6 +4,7 @@ #include "ui/ozone/public/ozone_platform.h" +#include <memory> #include <utility> #include "base/logging.h"
diff --git a/ui/ozone/public/surface_factory_ozone.cc b/ui/ozone/public/surface_factory_ozone.cc index a12ec48..faa7bb6 100644 --- a/ui/ozone/public/surface_factory_ozone.cc +++ b/ui/ozone/public/surface_factory_ozone.cc
@@ -5,6 +5,7 @@ #include "ui/ozone/public/surface_factory_ozone.h" #include <stdlib.h> +#include <memory> #include "base/command_line.h" #include "gpu/vulkan/buildflags.h"
diff --git a/ui/ozone/public/surface_factory_ozone.h b/ui/ozone/public/surface_factory_ozone.h index 6ac0ea49..16758eb 100644 --- a/ui/ozone/public/surface_factory_ozone.h +++ b/ui/ozone/public/surface_factory_ozone.h
@@ -6,7 +6,6 @@ #define UI_OZONE_PUBLIC_SURFACE_FACTORY_OZONE_H_ #include <stdint.h> - #include <memory> #include <vector>
diff --git a/ui/ozone/public/swap_completion_callback.h b/ui/ozone/public/swap_completion_callback.h index c5be525..367e306 100644 --- a/ui/ozone/public/swap_completion_callback.h +++ b/ui/ozone/public/swap_completion_callback.h
@@ -6,6 +6,7 @@ #define UI_OZONE_PUBLIC_SWAP_COMPLETION_CALLBACK_H_ #include <memory> + #include "base/callback.h" #include "ui/gfx/swap_result.h"
diff --git a/ui/views/controls/combobox/combobox.cc b/ui/views/controls/combobox/combobox.cc index 9fc8f31..899aaa0c 100644 --- a/ui/views/controls/combobox/combobox.cc +++ b/ui/views/controls/combobox/combobox.cc
@@ -633,8 +633,8 @@ base::BindRepeating(&Combobox::OnMenuClosed, base::Unretained(this), original_state)); } - menu_runner_->RunMenuAt(GetWidget(), nullptr, bounds, MENU_ANCHOR_TOPLEFT, - source_type); + menu_runner_->RunMenuAt(GetWidget(), nullptr, bounds, + MenuAnchorPosition::kTopLeft, source_type); } void Combobox::OnMenuClosed(Button::ButtonState original_button_state) {
diff --git a/ui/views/controls/editable_combobox/editable_combobox.cc b/ui/views/controls/editable_combobox/editable_combobox.cc index b30fd95c..1e58fb4c 100644 --- a/ui/views/controls/editable_combobox/editable_combobox.cc +++ b/ui/views/controls/editable_combobox/editable_combobox.cc
@@ -350,8 +350,8 @@ menu_model_.get(), MenuRunner::EDITABLE_COMBOBOX, base::BindRepeating(&EditableCombobox::OnMenuClosed, base::Unretained(this))); - menu_runner_->RunMenuAt(GetWidget(), nullptr, bounds, MENU_ANCHOR_TOPLEFT, - source_type); + menu_runner_->RunMenuAt(GetWidget(), nullptr, bounds, + MenuAnchorPosition::kTopLeft, source_type); } } // namespace views
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc index fe30059d..09c24be 100644 --- a/ui/views/controls/label.cc +++ b/ui/views/controls/label.cc
@@ -656,7 +656,7 @@ MenuRunner::HAS_MNEMONICS | MenuRunner::CONTEXT_MENU); context_menu_runner_->RunMenuAt(GetWidget(), nullptr, gfx::Rect(point, gfx::Size()), - MENU_ANCHOR_TOPLEFT, source_type); + MenuAnchorPosition::kTopLeft, source_type); } bool Label::GetWordLookupDataAtPoint(const gfx::Point& point,
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index 6ae1820..c7aa2fec 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -408,7 +408,7 @@ : item(nullptr), hot_button(nullptr), submenu_open(false), - anchor(MENU_ANCHOR_TOPLEFT), + anchor(MenuAnchorPosition::kTopLeft), context_menu(false) {} MenuController::State::State(const State& other) = default; @@ -1595,11 +1595,11 @@ pending_state_.initial_bounds = bounds; // Reverse anchor position for RTL languages. - if (base::i18n::IsRTL() && - (position == MENU_ANCHOR_TOPRIGHT || position == MENU_ANCHOR_TOPLEFT)) { - pending_state_.anchor = position == MENU_ANCHOR_TOPRIGHT - ? MENU_ANCHOR_TOPLEFT - : MENU_ANCHOR_TOPRIGHT; + if (base::i18n::IsRTL() && (position == MenuAnchorPosition::kTopRight || + position == MenuAnchorPosition::kTopLeft)) { + pending_state_.anchor = position == MenuAnchorPosition::kTopRight + ? MenuAnchorPosition::kTopLeft + : MenuAnchorPosition::kTopRight; } else { pending_state_.anchor = position; } @@ -2210,20 +2210,20 @@ const int vertically_centered = anchor_bounds.y() + (anchor_bounds.height() - menu_bounds.height()) / 2; - if (state_.anchor == MENU_ANCHOR_TOPRIGHT) { + if (state_.anchor == MenuAnchorPosition::kTopRight) { // Move the menu so that its right edge is aligned with the anchor // bounds right edge. menu_bounds.set_x(anchor_bounds.right() - menu_bounds.width()); - } else if (state_.anchor == MENU_ANCHOR_BOTTOMCENTER) { + } else if (state_.anchor == MenuAnchorPosition::kBottomCenter) { // Try to fit the menu above the anchor bounds. If it doesn't fit, place // it below. menu_bounds.set_x(horizontally_centered); menu_bounds.set_y(above_anchor - kTouchYPadding); if (menu_bounds.y() < monitor_bounds.y()) menu_bounds.set_y(anchor_bounds.y() + kTouchYPadding); - } else if (state_.anchor == MENU_ANCHOR_FIXED_BOTTOMCENTER) { + } else if (state_.anchor == MenuAnchorPosition::kFixedBottomCenter) { menu_bounds.set_x(horizontally_centered); - } else if (state_.anchor == MENU_ANCHOR_FIXED_SIDECENTER) { + } else if (state_.anchor == MenuAnchorPosition::kSideCenter) { menu_bounds.set_y(vertically_centered); } @@ -2265,7 +2265,7 @@ const int right_of_anchor = anchor_bounds.right(); menu_bounds.set_y(monitor_bounds.bottom() - menu_bounds.height()); - if (state_.anchor == MENU_ANCHOR_TOPLEFT) { + if (state_.anchor == MenuAnchorPosition::kTopLeft) { // Prefer menu to right of anchor bounds but move it to left if it // doesn't fit. menu_bounds.set_x(right_of_anchor); @@ -2330,19 +2330,19 @@ int max_height = monitor_bounds.height(); // In case of bubbles, the maximum width is limited by the space // between the display corner and the target area + the tip size. - if (state_.anchor == MENU_ANCHOR_BUBBLE_LEFT) { + if (state_.anchor == MenuAnchorPosition::kBubbleLeft) { max_width = anchor_bounds.x() - monitor_bounds.x() + kBubbleTipSizeLeftRight; - } else if (state_.anchor == MENU_ANCHOR_BUBBLE_RIGHT) { + } else if (state_.anchor == MenuAnchorPosition::kBubbleRight) { max_width = monitor_bounds.right() - anchor_bounds.right() + kBubbleTipSizeLeftRight; - } else if (state_.anchor == MENU_ANCHOR_BUBBLE_ABOVE) { + } else if (state_.anchor == MenuAnchorPosition::kBubbleAbove) { max_height = anchor_bounds.y() - monitor_bounds.y() + kBubbleTipSizeTopBottom; - } else if (state_.anchor == MENU_ANCHOR_BUBBLE_BELOW) { + } else if (state_.anchor == MenuAnchorPosition::kBubbleBelow) { max_height = monitor_bounds.bottom() - anchor_bounds.bottom() + kBubbleTipSizeTopBottom; - } else if (state_.anchor == MENU_ANCHOR_BUBBLE_TOUCHABLE_ABOVE) { + } else if (state_.anchor == MenuAnchorPosition::kBubbleTouchableAbove) { // Don't consider |border_and_shadow_insets| because when the max size // is enforced, the scroll view is shown and the md shadows are not // applied. @@ -2360,9 +2360,9 @@ menu_size.set_width(std::min( menu_size.width(), item->GetDelegate()->GetMaxWidthForMenu(item))); - if (state_.anchor == MENU_ANCHOR_BUBBLE_ABOVE || - state_.anchor == MENU_ANCHOR_BUBBLE_BELOW) { - if (state_.anchor == MENU_ANCHOR_BUBBLE_ABOVE) + if (state_.anchor == MenuAnchorPosition::kBubbleAbove || + state_.anchor == MenuAnchorPosition::kBubbleBelow) { + if (state_.anchor == MenuAnchorPosition::kBubbleAbove) y = anchor_bounds.y() - menu_size.height() + kBubbleTipSizeTopBottom; else y = anchor_bounds.bottom() - kBubbleTipSizeTopBottom; @@ -2373,9 +2373,9 @@ monitor_bounds.right() - menu_size.width()); submenu->GetScrollViewContainer()->SetBubbleArrowOffset( menu_size.width() / 2 - x + x_old); - } else if (state_.anchor == MENU_ANCHOR_BUBBLE_LEFT || - state_.anchor == MENU_ANCHOR_BUBBLE_RIGHT) { - if (state_.anchor == MENU_ANCHOR_BUBBLE_RIGHT) + } else if (state_.anchor == MenuAnchorPosition::kBubbleLeft || + state_.anchor == MenuAnchorPosition::kBubbleRight) { + if (state_.anchor == MenuAnchorPosition::kBubbleRight) x = anchor_bounds.right() - kBubbleTipSizeLeftRight; else x = anchor_bounds.x() - menu_size.width() + kBubbleTipSizeLeftRight; @@ -2386,7 +2386,7 @@ monitor_bounds.bottom() - menu_size.height()); submenu->GetScrollViewContainer()->SetBubbleArrowOffset( menu_size.height() / 2 - y + y_old); - } else if (state_.anchor == MENU_ANCHOR_BUBBLE_TOUCHABLE_ABOVE) { + } else if (state_.anchor == MenuAnchorPosition::kBubbleTouchableAbove) { // Align the left edges of the menu and anchor, and the bottom of the menu // with the top of the anchor. x = std::max(monitor_bounds.x(), @@ -2405,7 +2405,7 @@ y = anchor_bounds.bottom() - border_and_shadow_insets.top() + menu_config.touchable_anchor_offset; } - } else if (state_.anchor == MENU_ANCHOR_BUBBLE_TOUCHABLE_LEFT) { + } else if (state_.anchor == MenuAnchorPosition::kBubbleTouchableLeft) { // Align the right of the menu with the left of the anchor, and the top of // the menu with the top of the anchor. x = anchor_bounds.x() - menu_size.width() + @@ -2425,7 +2425,7 @@ if (y < monitor_bounds.y()) y = monitor_bounds.y(); } - } else if (state_.anchor == MENU_ANCHOR_BUBBLE_TOUCHABLE_RIGHT) { + } else if (state_.anchor == MenuAnchorPosition::kBubbleTouchableRight) { // Align the left of the menu with the right of the anchor, and the top of // the menu with the top of the anchor. x = anchor_bounds.right() - border_and_shadow_insets.left() +
diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc index c1ac0e8..1d369d1 100644 --- a/ui/views/controls/menu/menu_controller_unittest.cc +++ b/ui/views/controls/menu/menu_controller_unittest.cc
@@ -312,7 +312,7 @@ gfx::Rect anchor_bounds = gfx::Rect(500, 500, 10, 10); gfx::Rect monitor_bounds = gfx::Rect(0, 0, 1000, 1000); gfx::Size menu_size = gfx::Size(100, 100); - MenuAnchorPosition menu_anchor = MENU_ANCHOR_TOPLEFT; + MenuAnchorPosition menu_anchor = MenuAnchorPosition::kTopLeft; MenuItemView::MenuPosition menu_position = MenuItemView::POSITION_BEST_FIT; }; @@ -800,7 +800,7 @@ event_generator()->ReleaseTouchId(0); menu_controller()->Run(owner(), nullptr, menu_item(), gfx::Rect(), - MENU_ANCHOR_TOPLEFT, false, false); + MenuAnchorPosition::kTopLeft, false, false); MenuControllerTest::ReleaseTouchId(1); TestAsyncEscapeKey(); @@ -1173,7 +1173,7 @@ MenuController* controller = menu_controller(); controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), - MENU_ANCHOR_TOPLEFT, false, false); + MenuAnchorPosition::kTopLeft, false, false); // |button2| should stay in hot-tracked state but menu controller should not // track it anymore (preventing resetting hot-tracked state when changing @@ -1200,7 +1200,7 @@ MenuController* controller = menu_controller(); controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), - MENU_ANCHOR_TOPLEFT, false, false); + MenuAnchorPosition::kTopLeft, false, false); TestMenuControllerDelegate* delegate = menu_controller_delegate(); EXPECT_EQ(0, delegate->on_menu_closed_called()); @@ -1221,7 +1221,7 @@ MenuController* controller = menu_controller(); controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), - MENU_ANCHOR_TOPLEFT, false, false); + MenuAnchorPosition::kTopLeft, false, false); TestMenuControllerDelegate* delegate = menu_controller_delegate(); EXPECT_EQ(0, delegate->on_menu_closed_called()); @@ -1246,7 +1246,7 @@ EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), - MENU_ANCHOR_TOPLEFT, false, false); + MenuAnchorPosition::kTopLeft, false, false); controller->CancelAll(); EXPECT_EQ(delegate, GetCurrentDelegate()); @@ -1361,7 +1361,7 @@ // Nested run controller->AddNestedDelegate(nested_delegate.get()); controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), - MENU_ANCHOR_TOPLEFT, false, false); + MenuAnchorPosition::kTopLeft, false, false); controller->CancelAll(); EXPECT_EQ(1, delegate->on_menu_closed_called()); @@ -1374,7 +1374,7 @@ MenuController* controller = menu_controller(); MenuItemView* item = menu_item(); controller->Run(owner(), nullptr, item, gfx::Rect(), - MENU_ANCHOR_FIXED_BOTTOMCENTER, false, false); + MenuAnchorPosition::kFixedBottomCenter, false, false); SubmenuView* sub_menu = item->GetSubmenu(); sub_menu->ShowAt(owner(), gfx::Rect(0, 0, 100, 100), true); @@ -1456,8 +1456,8 @@ EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); MenuItemView* item = menu_item(); - controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT, - false, false); + controller->Run(owner(), nullptr, item, gfx::Rect(), + MenuAnchorPosition::kTopLeft, false, false); // Show a sub menu to target with a pointer selection. However have the event // occur outside of the bounds of the entire menu. @@ -1524,8 +1524,8 @@ EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); MenuItemView* item = menu_item(); - controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT, - false, false); + controller->Run(owner(), nullptr, item, gfx::Rect(), + MenuAnchorPosition::kTopLeft, false, false); // Show a sub menu to target with a pointer selection. However have the event // occur outside of the bounds of the entire menu. @@ -1561,8 +1561,8 @@ EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); MenuItemView* item = menu_item(); - controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT, - false, false); + controller->Run(owner(), nullptr, item, gfx::Rect(), + MenuAnchorPosition::kTopLeft, false, false); // Show a sub menu to target with a tap event. SubmenuView* sub_menu = item->GetSubmenu(); @@ -1664,7 +1664,7 @@ EXPECT_EQ(expected, CalculateMenuBounds(options)); // Fits on both sides, prefer left -> placed left. - options.menu_anchor = MENU_ANCHOR_TOPRIGHT; + options.menu_anchor = MenuAnchorPosition::kTopRight; options.anchor_bounds = gfx::Rect(options.menu_size.width(), options.menu_size.height() / 2, 0, 0); options.monitor_bounds = @@ -1693,13 +1693,13 @@ MenuBoundsOptions options; gfx::Rect expected; - options.menu_anchor = MENU_ANCHOR_TOPLEFT; + options.menu_anchor = MenuAnchorPosition::kTopLeft; expected = gfx::Rect(options.anchor_bounds.x(), options.anchor_bounds.bottom(), options.menu_size.width(), options.menu_size.height()); EXPECT_EQ(expected, CalculateMenuBounds(options)); - options.menu_anchor = MENU_ANCHOR_TOPRIGHT; + options.menu_anchor = MenuAnchorPosition::kTopRight; expected = gfx::Rect(options.anchor_bounds.right() - options.menu_size.width(), options.anchor_bounds.bottom(), options.menu_size.width(), @@ -1707,7 +1707,7 @@ EXPECT_EQ(expected, CalculateMenuBounds(options)); // Menu will be placed above or below with an offset. - options.menu_anchor = MENU_ANCHOR_BOTTOMCENTER; + options.menu_anchor = MenuAnchorPosition::kBottomCenter; const int kTouchYPadding = 15; // Menu fits above -> placed above. @@ -1729,7 +1729,7 @@ EXPECT_EQ(expected, CalculateMenuBounds(options)); // Assumes anchor bounds is at the bottom of screen. - options.menu_anchor = MENU_ANCHOR_FIXED_BOTTOMCENTER; + options.menu_anchor = MenuAnchorPosition::kFixedBottomCenter; options.anchor_bounds = gfx::Rect(options.menu_size.width(), options.menu_size.height(), 0, 0); options.monitor_bounds = gfx::Rect(0, 0, options.menu_size.width() * 2, @@ -1742,7 +1742,7 @@ EXPECT_EQ(expected, CalculateMenuBounds(options)); // Assumes anchor bounds is on left/right edge of screen. - options.menu_anchor = MENU_ANCHOR_FIXED_SIDECENTER; + options.menu_anchor = MenuAnchorPosition::kSideCenter; options.monitor_bounds = gfx::Rect(0, 0, options.menu_size.width(), options.menu_size.height() * 2); options.anchor_bounds = @@ -1794,16 +1794,16 @@ // Test that menus show up on screen with non-zero sized anchors. TEST_F(MenuControllerTest, TestMenuFitsOnScreen) { - TestMenuFitsOnScreen(MENU_ANCHOR_BUBBLE_TOUCHABLE_ABOVE); - TestMenuFitsOnScreen(MENU_ANCHOR_BUBBLE_TOUCHABLE_LEFT); - TestMenuFitsOnScreen(MENU_ANCHOR_BUBBLE_TOUCHABLE_RIGHT); + TestMenuFitsOnScreen(MenuAnchorPosition::kBubbleTouchableAbove); + TestMenuFitsOnScreen(MenuAnchorPosition::kBubbleTouchableLeft); + TestMenuFitsOnScreen(MenuAnchorPosition::kBubbleTouchableRight); } // Test that menus show up on screen with zero sized anchors. TEST_F(MenuControllerTest, TestMenuFitsOnScreenSmallAnchor) { - TestMenuFitsOnScreenSmallAnchor(MENU_ANCHOR_BUBBLE_TOUCHABLE_ABOVE); - TestMenuFitsOnScreenSmallAnchor(MENU_ANCHOR_BUBBLE_TOUCHABLE_LEFT); - TestMenuFitsOnScreenSmallAnchor(MENU_ANCHOR_BUBBLE_TOUCHABLE_RIGHT); + TestMenuFitsOnScreenSmallAnchor(MenuAnchorPosition::kBubbleTouchableAbove); + TestMenuFitsOnScreenSmallAnchor(MenuAnchorPosition::kBubbleTouchableLeft); + TestMenuFitsOnScreenSmallAnchor(MenuAnchorPosition::kBubbleTouchableRight); } // Test that a menu that was originally drawn below the anchor does not get @@ -1857,7 +1857,7 @@ gfx::Point location(item_size.width() / 2, item_size.height() / 2); GetRootWindow(owner())->MoveCursorTo(location); menu_controller()->Run(owner(), nullptr, menu_item.get(), gfx::Rect(), - MENU_ANCHOR_TOPLEFT, false, false); + MenuAnchorPosition::kTopLeft, false, false); EXPECT_EQ(0, pending_state_item()->GetCommand()); @@ -1883,7 +1883,7 @@ ExitMenuRun(); MenuController* controller = menu_controller(); controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), - MENU_ANCHOR_TOPLEFT, false, false); + MenuAnchorPosition::kTopLeft, false, false); EXPECT_EQ(MenuController::EXIT_NONE, controller->exit_type()); ui::CancelModeEvent cancel_event; event_generator()->Dispatch(&cancel_event); @@ -1902,7 +1902,7 @@ ExitMenuRun(); MenuController* controller = menu_controller(); controller->Run(nullptr, nullptr, menu_item(), gfx::Rect(), - MENU_ANCHOR_TOPLEFT, false, false); + MenuAnchorPosition::kTopLeft, false, false); } // Tests that if a MenuController is destroying during drag/drop, and another @@ -1940,7 +1940,7 @@ ExitMenuRun(); MenuController* controller = menu_controller(); controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), - MENU_ANCHOR_TOPLEFT, false, false); + MenuAnchorPosition::kTopLeft, false, false); TestDestroyedDuringViewsRelease(); } @@ -1992,8 +1992,8 @@ std::make_unique<TestMenuControllerDelegate>(); controller->AddNestedDelegate(nested_controller_delegate_1.get()); controller->Run(owner(), nullptr, nested_menu_item_1.get(), - gfx::Rect(150, 50, 100, 100), MENU_ANCHOR_TOPLEFT, true, - false); + gfx::Rect(150, 50, 100, 100), MenuAnchorPosition::kTopLeft, + true, false); SubmenuView* nested_menu_submenu = nested_menu_item_1->GetSubmenu(); nested_menu_submenu->SetBounds(0, 0, 100, 100); @@ -2043,8 +2043,8 @@ std::make_unique<TestMenuControllerDelegate>(); controller->AddNestedDelegate(nested_controller_delegate_2.get()); controller->Run(owner(), nullptr, nested_menu_item_2.get(), - gfx::Rect(150, 50, 100, 100), MENU_ANCHOR_TOPLEFT, true, - false); + gfx::Rect(150, 50, 100, 100), MenuAnchorPosition::kTopLeft, + true, false); // The escape key should only close the nested menu. SelectByChar should not // crash. @@ -2113,7 +2113,7 @@ canceling_view->SetBoundsRect(item->bounds()); controller->Run(owner(), nullptr, item.get(), item->bounds(), - MENU_ANCHOR_TOPLEFT, false, false); + MenuAnchorPosition::kTopLeft, false, false); sub_menu->ShowAt(owner(), item->bounds(), true); // Simulate a mouse press in the middle of the |closing_widget|. @@ -2314,7 +2314,7 @@ MenuController* controller = menu_controller(); controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), - MENU_ANCHOR_TOPLEFT, false, false); + MenuAnchorPosition::kTopLeft, false, false); TestMenuControllerDelegate* delegate = menu_controller_delegate(); EXPECT_EQ(0, delegate->on_menu_closed_called());
diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc index 74d5bca..ffd40f6 100644 --- a/ui/views/controls/menu/menu_item_view.cc +++ b/ui/views/controls/menu/menu_item_view.cc
@@ -220,13 +220,13 @@ // static bool MenuItemView::IsBubble(MenuAnchorPosition anchor) { - return anchor == MENU_ANCHOR_BUBBLE_LEFT || - anchor == MENU_ANCHOR_BUBBLE_RIGHT || - anchor == MENU_ANCHOR_BUBBLE_ABOVE || - anchor == MENU_ANCHOR_BUBBLE_BELOW || - anchor == MENU_ANCHOR_BUBBLE_TOUCHABLE_ABOVE || - anchor == MENU_ANCHOR_BUBBLE_TOUCHABLE_LEFT || - anchor == MENU_ANCHOR_BUBBLE_TOUCHABLE_RIGHT; + return anchor == MenuAnchorPosition::kBubbleLeft || + anchor == MenuAnchorPosition::kBubbleRight || + anchor == MenuAnchorPosition::kBubbleAbove || + anchor == MenuAnchorPosition::kBubbleBelow || + anchor == MenuAnchorPosition::kBubbleTouchableAbove || + anchor == MenuAnchorPosition::kBubbleTouchableLeft || + anchor == MenuAnchorPosition::kBubbleTouchableRight; } // static
diff --git a/ui/views/controls/menu/menu_item_view_unittest.cc b/ui/views/controls/menu/menu_item_view_unittest.cc index 792f2bd..5ab6170 100644 --- a/ui/views/controls/menu/menu_item_view_unittest.cc +++ b/ui/views/controls/menu/menu_item_view_unittest.cc
@@ -316,7 +316,8 @@ AddItem("Minor text and icon", base::ASCIIToUTF16("minor text"), &views::kMenuCheckIcon); - menu_runner()->RunMenuAt(widget(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, + menu_runner()->RunMenuAt(widget(), nullptr, gfx::Rect(), + MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_KEYBOARD); SkBitmap bitmap;
diff --git a/ui/views/controls/menu/menu_runner.cc b/ui/views/controls/menu/menu_runner.cc index b0a2f3d..a34f7ae 100644 --- a/ui/views/controls/menu/menu_runner.cc +++ b/ui/views/controls/menu/menu_runner.cc
@@ -58,11 +58,11 @@ case ui::MENU_SOURCE_NONE: case ui::MENU_SOURCE_KEYBOARD: case ui::MENU_SOURCE_MOUSE: - anchor = MENU_ANCHOR_TOPLEFT; + anchor = MenuAnchorPosition::kTopLeft; break; case ui::MENU_SOURCE_TOUCH: case ui::MENU_SOURCE_TOUCH_EDIT_MENU: - anchor = MENU_ANCHOR_BOTTOMCENTER; + anchor = MenuAnchorPosition::kBottomCenter; break; default: break;
diff --git a/ui/views/controls/menu/menu_runner_cocoa_unittest.mm b/ui/views/controls/menu/menu_runner_cocoa_unittest.mm index 4f9dd1e..f6e98da 100644 --- a/ui/views/controls/menu/menu_runner_cocoa_unittest.mm +++ b/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
@@ -148,8 +148,8 @@ base::Unretained(this), std::move(callback))); } - runner_->RunMenuAt(parent_, nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, - MenuRunner::CONTEXT_MENU); + runner_->RunMenuAt(parent_, nullptr, gfx::Rect(), + MenuAnchorPosition::kTopLeft, MenuRunner::CONTEXT_MENU); MaybeRunAsync(); } @@ -168,7 +168,7 @@ menu_->set_menu_open_callback(std::move(callback)); } - runner_->RunMenuAt(parent_, nullptr, anchor, MENU_ANCHOR_TOPLEFT, + runner_->RunMenuAt(parent_, nullptr, anchor, MenuAnchorPosition::kTopLeft, MenuRunner::COMBOBOX); MaybeRunAsync(); }
diff --git a/ui/views/controls/menu/menu_runner_impl_cocoa.mm b/ui/views/controls/menu/menu_runner_impl_cocoa.mm index 8743751..9fe4eca 100644 --- a/ui/views/controls/menu/menu_runner_impl_cocoa.mm +++ b/ui/views/controls/menu/menu_runner_impl_cocoa.mm
@@ -74,7 +74,8 @@ // When the actual menu width is larger than the anchor, right alignment // should be respected. if (actual_menu_width > rect.size.width && - position == views::MENU_ANCHOR_TOPRIGHT && !base::i18n::IsRTL()) { + position == views::MenuAnchorPosition::kTopRight && + !base::i18n::IsRTL()) { int width_diff = actual_menu_width - rect.size.width; rect.origin.x -= width_diff; }
diff --git a/ui/views/controls/menu/menu_runner_unittest.cc b/ui/views/controls/menu/menu_runner_unittest.cc index 7c5a7ac..9e4e124 100644 --- a/ui/views/controls/menu/menu_runner_unittest.cc +++ b/ui/views/controls/menu/menu_runner_unittest.cc
@@ -129,7 +129,7 @@ TEST_F(MenuRunnerTest, AsynchronousRun) { InitMenuRunner(0); MenuRunner* runner = menu_runner(); - runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, + runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_NONE); EXPECT_TRUE(runner->IsRunning()); @@ -145,7 +145,7 @@ TEST_F(MenuRunnerTest, AsynchronousKeyEventHandling) { InitMenuRunner(0); MenuRunner* runner = menu_runner(); - runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, + runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_NONE); EXPECT_TRUE(runner->IsRunning()); @@ -166,7 +166,7 @@ views::test::DisableMenuClosureAnimations(); InitMenuRunner(0); MenuRunner* runner = menu_runner(); - runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, + runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_NONE); EXPECT_TRUE(runner->IsRunning()); @@ -190,7 +190,7 @@ views::test::DisableMenuClosureAnimations(); InitMenuRunner(0); MenuRunner* runner = menu_runner(); - runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, + runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_NONE); EXPECT_TRUE(runner->IsRunning()); @@ -212,8 +212,8 @@ InitMenuRunner(MenuRunner::HAS_MNEMONICS | MenuRunner::SHOULD_SHOW_MNEMONICS); - menu_runner()->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, - ui::MENU_SOURCE_NONE); + menu_runner()->RunMenuAt(owner(), nullptr, gfx::Rect(), + MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_NONE); EXPECT_TRUE(menu_item_view()->show_mnemonics()); } @@ -224,8 +224,8 @@ InitMenuRunner(MenuRunner::HAS_MNEMONICS); - menu_runner()->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, - ui::MENU_SOURCE_NONE); + menu_runner()->RunMenuAt(owner(), nullptr, gfx::Rect(), + MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_NONE); EXPECT_FALSE(menu_item_view()->show_mnemonics()); } @@ -248,7 +248,7 @@ menu_item_view()->AppendMenuItemWithLabel(3, base::ASCIIToUTF16("One Two")); MenuRunner* runner = menu_runner(); - runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, + runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_NONE); EXPECT_TRUE(runner->IsRunning()); @@ -291,7 +291,7 @@ InitMenuRunner(0); MenuRunner* runner = menu_runner(); - runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, + runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_NONE); EXPECT_TRUE(runner->IsRunning()); @@ -315,7 +315,7 @@ TEST_F(MenuRunnerTest, NestingDuringDrag) { InitMenuRunner(MenuRunner::FOR_DROP); MenuRunner* runner = menu_runner(); - runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, + runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_NONE); EXPECT_TRUE(runner->IsRunning()); @@ -323,8 +323,8 @@ MenuItemView* nested_menu = new MenuItemView(nested_delegate.get()); std::unique_ptr<MenuRunner> nested_runner( new MenuRunner(nested_menu, MenuRunner::IS_NESTED)); - nested_runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, - ui::MENU_SOURCE_NONE); + nested_runner->RunMenuAt(owner(), nullptr, gfx::Rect(), + MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_NONE); EXPECT_TRUE(nested_runner->IsRunning()); EXPECT_FALSE(runner->IsRunning()); TestMenuDelegate* delegate = menu_delegate(); @@ -345,8 +345,8 @@ // ui::EventHandler: void OnMouseEvent(ui::MouseEvent* event) override { if (event->type() == ui::ET_MOUSE_PRESSED) { - runner_->RunMenuAt(owner_, nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, - ui::MENU_SOURCE_NONE); + runner_->RunMenuAt(owner_, nullptr, gfx::Rect(), + MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_NONE); event->SetHandled(); } } @@ -490,7 +490,8 @@ TEST_F(MenuRunnerImplTest, NestedMenuRunnersDestroyedOutOfOrder) { internal::MenuRunnerImpl* menu_runner = new internal::MenuRunnerImpl(menu_item_view()); - menu_runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, 0); + menu_runner->RunMenuAt(owner(), nullptr, gfx::Rect(), + MenuAnchorPosition::kTopLeft, 0); std::unique_ptr<TestMenuDelegate> menu_delegate2(new TestMenuDelegate); MenuItemView* menu_item_view2 = new MenuItemView(menu_delegate2.get()); @@ -498,8 +499,8 @@ internal::MenuRunnerImpl* menu_runner2 = new internal::MenuRunnerImpl(menu_item_view2); - menu_runner2->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, - MenuRunner::IS_NESTED); + menu_runner2->RunMenuAt(owner(), nullptr, gfx::Rect(), + MenuAnchorPosition::kTopLeft, MenuRunner::IS_NESTED); // Hide the controller so we can test out of order destruction. MenuControllerTestApi menu_controller; @@ -521,7 +522,8 @@ TEST_F(MenuRunnerImplTest, MenuRunnerDestroyedWithNoActiveController) { internal::MenuRunnerImpl* menu_runner = new internal::MenuRunnerImpl(menu_item_view()); - menu_runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, 0); + menu_runner->RunMenuAt(owner(), nullptr, gfx::Rect(), + MenuAnchorPosition::kTopLeft, 0); // Hide the menu, and clear its item selection state. MenuControllerTestApi menu_controller; @@ -534,8 +536,8 @@ internal::MenuRunnerImpl* menu_runner2 = new internal::MenuRunnerImpl(menu_item_view2); - menu_runner2->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, - MenuRunner::FOR_DROP); + menu_runner2->RunMenuAt(owner(), nullptr, gfx::Rect(), + MenuAnchorPosition::kTopLeft, MenuRunner::FOR_DROP); EXPECT_NE(menu_controller.controller(), MenuController::GetActiveInstance()); menu_controller.SetShowing(true); @@ -595,7 +597,8 @@ TEST_F(MenuRunnerDestructionTest, MenuRunnerDestroyedDuringReleaseRef) { internal::MenuRunnerImpl* menu_runner = new internal::MenuRunnerImpl(menu_item_view()); - menu_runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT, 0); + menu_runner->RunMenuAt(owner(), nullptr, gfx::Rect(), + MenuAnchorPosition::kTopLeft, 0); views_delegate()->set_menu_runner(menu_runner);
diff --git a/ui/views/controls/menu/menu_scroll_view_container.cc b/ui/views/controls/menu/menu_scroll_view_container.cc index 43752f5..17d6d7d3 100644 --- a/ui/views/controls/menu/menu_scroll_view_container.cc +++ b/ui/views/controls/menu/menu_scroll_view_container.cc
@@ -357,17 +357,17 @@ BubbleBorder::Arrow MenuScrollViewContainer::BubbleBorderTypeFromAnchor( MenuAnchorPosition anchor) { switch (anchor) { - case MENU_ANCHOR_BUBBLE_LEFT: + case MenuAnchorPosition::kBubbleLeft: return BubbleBorder::RIGHT_CENTER; - case MENU_ANCHOR_BUBBLE_RIGHT: + case MenuAnchorPosition::kBubbleRight: return BubbleBorder::LEFT_CENTER; - case MENU_ANCHOR_BUBBLE_ABOVE: + case MenuAnchorPosition::kBubbleAbove: return BubbleBorder::BOTTOM_CENTER; - case MENU_ANCHOR_BUBBLE_BELOW: + case MenuAnchorPosition::kBubbleBelow: return BubbleBorder::TOP_CENTER; - case MENU_ANCHOR_BUBBLE_TOUCHABLE_ABOVE: - case MENU_ANCHOR_BUBBLE_TOUCHABLE_LEFT: - case MENU_ANCHOR_BUBBLE_TOUCHABLE_RIGHT: + case MenuAnchorPosition::kBubbleTouchableAbove: + case MenuAnchorPosition::kBubbleTouchableLeft: + case MenuAnchorPosition::kBubbleTouchableRight: return BubbleBorder::FLOAT; default: return BubbleBorder::NONE;
diff --git a/ui/views/controls/menu/menu_types.h b/ui/views/controls/menu/menu_types.h index d8419e6..c61b976 100644 --- a/ui/views/controls/menu/menu_types.h +++ b/ui/views/controls/menu/menu_types.h
@@ -11,21 +11,19 @@ // position will be used if base::i18n:IsRTL() is true. The BUBBLE flags are // used when the menu should get enclosed by a bubble. The Fixed flags are // used for the menus that have a fixed anchor position. -enum MenuAnchorPosition { - MENU_ANCHOR_TOPLEFT, - MENU_ANCHOR_TOPRIGHT, - MENU_ANCHOR_BOTTOMCENTER, - MENU_ANCHOR_FIXED_BOTTOMCENTER, - MENU_ANCHOR_FIXED_SIDECENTER, - MENU_ANCHOR_BUBBLE_LEFT, - MENU_ANCHOR_BUBBLE_RIGHT, - MENU_ANCHOR_BUBBLE_ABOVE, - MENU_ANCHOR_BUBBLE_BELOW, - MENU_ANCHOR_BUBBLE_TOUCHABLE_ABOVE, - MENU_ANCHOR_BUBBLE_TOUCHABLE_LEFT, - MENU_ANCHOR_BUBBLE_TOUCHABLE_RIGHT, - // Keep this the last item. - MENU_ANCHOR_POSITION_LAST +enum class MenuAnchorPosition { + kTopLeft, + kTopRight, + kBottomCenter, + kFixedBottomCenter, + kSideCenter, + kBubbleLeft, + kBubbleRight, + kBubbleAbove, + kBubbleBelow, + kBubbleTouchableAbove, + kBubbleTouchableLeft, + kBubbleTouchableRight, }; } // namespace views
diff --git a/ui/views/controls/scrollbar/base_scroll_bar.cc b/ui/views/controls/scrollbar/base_scroll_bar.cc index c33458c..bb31c72d 100644 --- a/ui/views/controls/scrollbar/base_scroll_bar.cc +++ b/ui/views/controls/scrollbar/base_scroll_bar.cc
@@ -301,7 +301,7 @@ menu_model_.get(), MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU); menu_runner_->RunMenuAt(GetWidget(), nullptr, gfx::Rect(p, gfx::Size()), - MENU_ANCHOR_TOPLEFT, source_type); + MenuAnchorPosition::kTopLeft, source_type); } ///////////////////////////////////////////////////////////////////////////////
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index 4a793b66..38095214 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -1196,7 +1196,7 @@ UpdateContextMenu(); context_menu_runner_->RunMenuAt(GetWidget(), nullptr, gfx::Rect(point, gfx::Size()), - MENU_ANCHOR_TOPLEFT, source_type); + MenuAnchorPosition::kTopLeft, source_type); } ////////////////////////////////////////////////////////////////////////////////
diff --git a/ui/views/examples/checkbox_example.cc b/ui/views/examples/checkbox_example.cc index d7f9670..422dd37 100644 --- a/ui/views/examples/checkbox_example.cc +++ b/ui/views/examples/checkbox_example.cc
@@ -13,8 +13,7 @@ namespace views { namespace examples { -CheckboxExample::CheckboxExample() : ExampleBase("Checkbox"), count_(0) { -} +CheckboxExample::CheckboxExample() : ExampleBase("Checkbox") {} CheckboxExample::~CheckboxExample() = default;
diff --git a/ui/views/examples/checkbox_example.h b/ui/views/examples/checkbox_example.h index 9e10134..2a88f5ad 100644 --- a/ui/views/examples/checkbox_example.h +++ b/ui/views/examples/checkbox_example.h
@@ -29,9 +29,9 @@ void ButtonPressed(Button* sender, const ui::Event& event) override; // The only control in this test. - Checkbox* button_; + Checkbox* button_ = nullptr; - int count_; + int count_ = 0; DISALLOW_COPY_AND_ASSIGN(CheckboxExample); };
diff --git a/ui/views/examples/label_example.cc b/ui/views/examples/label_example.cc index 108d29e..ba39175 100644 --- a/ui/views/examples/label_example.cc +++ b/ui/views/examples/label_example.cc
@@ -56,14 +56,7 @@ } // namespace -LabelExample::LabelExample() - : ExampleBase("Label"), - textfield_(nullptr), - alignment_(nullptr), - elide_behavior_(nullptr), - multiline_(nullptr), - shadows_(nullptr), - custom_label_(nullptr) {} +LabelExample::LabelExample() : ExampleBase("Label") {} LabelExample::~LabelExample() = default;
diff --git a/ui/views/examples/label_example.h b/ui/views/examples/label_example.h index da35611..a6c67e6 100644 --- a/ui/views/examples/label_example.h +++ b/ui/views/examples/label_example.h
@@ -50,15 +50,15 @@ const char** strings, int count); - Textfield* textfield_; - Combobox* alignment_; - Combobox* elide_behavior_; - Checkbox* multiline_; - Checkbox* shadows_; - Checkbox* selectable_; - Label* custom_label_; + Textfield* textfield_ = nullptr; + Combobox* alignment_ = nullptr; + Combobox* elide_behavior_ = nullptr; + Checkbox* multiline_ = nullptr; + Checkbox* shadows_ = nullptr; + Checkbox* selectable_ = nullptr; + Label* custom_label_ = nullptr; - DISALLOW_COPY_AND_ASSIGN(LabelExample); + DISALLOW_COPY_AND_ASSIGN(LabelExample); }; } // namespace examples
diff --git a/ui/views/examples/menu_example.cc b/ui/views/examples/menu_example.cc index 289affcd..7a8c555 100644 --- a/ui/views/examples/menu_example.cc +++ b/ui/views/examples/menu_example.cc
@@ -52,7 +52,7 @@ std::unique_ptr<ui::SimpleMenuModel> submenu_; std::set<int> checked_fruits_; - int current_encoding_command_id_; + int current_encoding_command_id_ = COMMAND_SELECT_ASCII; DISALLOW_COPY_AND_ASSIGN(ExampleMenuModel); }; @@ -78,9 +78,7 @@ // ExampleMenuModel --------------------------------------------------------- -ExampleMenuModel::ExampleMenuModel() - : ui::SimpleMenuModel(this), - current_encoding_command_id_(COMMAND_SELECT_ASCII) { +ExampleMenuModel::ExampleMenuModel() : ui::SimpleMenuModel(this) { AddItem(COMMAND_DO_SOMETHING, ASCIIToUTF16("Do Something")); AddSeparator(ui::NORMAL_SEPARATOR); AddRadioItem(COMMAND_SELECT_ASCII, ASCIIToUTF16("ASCII"), @@ -183,8 +181,8 @@ std::make_unique<MenuRunner>(GetMenuModel(), MenuRunner::HAS_MNEMONICS); menu_runner_->RunMenuAt(source->GetWidget()->GetTopLevelWidget(), this, - gfx::Rect(point, gfx::Size()), MENU_ANCHOR_TOPRIGHT, - ui::MENU_SOURCE_NONE); + gfx::Rect(point, gfx::Size()), + MenuAnchorPosition::kTopRight, ui::MENU_SOURCE_NONE); } ui::SimpleMenuModel* ExampleMenuButton::GetMenuModel() {
diff --git a/ui/views/examples/multiline_example.cc b/ui/views/examples/multiline_example.cc index e77367a..3517a36 100644 --- a/ui/views/examples/multiline_example.cc +++ b/ui/views/examples/multiline_example.cc
@@ -121,13 +121,7 @@ DISALLOW_COPY_AND_ASSIGN(RenderTextView); }; -MultilineExample::MultilineExample() - : ExampleBase("Multiline RenderText"), - render_text_view_(nullptr), - label_(nullptr), - textfield_(nullptr), - label_checkbox_(nullptr), - elision_checkbox_(nullptr) {} +MultilineExample::MultilineExample() : ExampleBase("Multiline RenderText") {} MultilineExample::~MultilineExample() = default;
diff --git a/ui/views/examples/multiline_example.h b/ui/views/examples/multiline_example.h index 4bb5b61f..7bcdbe9 100644 --- a/ui/views/examples/multiline_example.h +++ b/ui/views/examples/multiline_example.h
@@ -38,15 +38,15 @@ void ContentsChanged(Textfield* sender, const base::string16& new_contents) override; - RenderTextView* render_text_view_; - Label* label_; - Textfield* textfield_; + RenderTextView* render_text_view_ = nullptr; + Label* label_ = nullptr; + Textfield* textfield_ = nullptr; // Checkbox to enable and disable text rendering in |label_|. - Checkbox* label_checkbox_; + Checkbox* label_checkbox_ = nullptr; // Checkbox to toggle text elision in |render_text_view_|. - Checkbox* elision_checkbox_; + Checkbox* elision_checkbox_ = nullptr; DISALLOW_COPY_AND_ASSIGN(MultilineExample); };
diff --git a/ui/views/examples/progress_bar_example.cc b/ui/views/examples/progress_bar_example.cc index 8fe33df..27d48ba 100644 --- a/ui/views/examples/progress_bar_example.cc +++ b/ui/views/examples/progress_bar_example.cc
@@ -25,12 +25,7 @@ namespace views { namespace examples { -ProgressBarExample::ProgressBarExample() - : ExampleBase("Progress Bar"), - minus_button_(nullptr), - plus_button_(nullptr), - progress_bar_(nullptr), - current_percent_(0.0) {} +ProgressBarExample::ProgressBarExample() : ExampleBase("Progress Bar") {} ProgressBarExample::~ProgressBarExample() = default;
diff --git a/ui/views/examples/progress_bar_example.h b/ui/views/examples/progress_bar_example.h index bf5fd90..a38751bd 100644 --- a/ui/views/examples/progress_bar_example.h +++ b/ui/views/examples/progress_bar_example.h
@@ -27,10 +27,10 @@ // ButtonListener: void ButtonPressed(Button* button, const ui::Event& event) override; - Button* minus_button_; - Button* plus_button_; - ProgressBar* progress_bar_; - double current_percent_; + Button* minus_button_ = nullptr; + Button* plus_button_ = nullptr; + ProgressBar* progress_bar_ = nullptr; + double current_percent_ = 0.0; DISALLOW_COPY_AND_ASSIGN(ProgressBarExample); };
diff --git a/ui/views/examples/slider_example.cc b/ui/views/examples/slider_example.cc index 0509e85..edc6f84 100644 --- a/ui/views/examples/slider_example.cc +++ b/ui/views/examples/slider_example.cc
@@ -15,8 +15,7 @@ namespace views { namespace examples { -SliderExample::SliderExample() - : ExampleBase("Slider"), slider_(nullptr), label_(nullptr) {} +SliderExample::SliderExample() : ExampleBase("Slider") {} SliderExample::~SliderExample() = default;
diff --git a/ui/views/examples/slider_example.h b/ui/views/examples/slider_example.h index 7f339d9a..4f7f57c 100644 --- a/ui/views/examples/slider_example.h +++ b/ui/views/examples/slider_example.h
@@ -30,8 +30,8 @@ float old_value, SliderChangeReason reason) override; - Slider* slider_; - Label* label_; + Slider* slider_ = nullptr; + Label* label_ = nullptr; DISALLOW_COPY_AND_ASSIGN(SliderExample); };
diff --git a/ui/views/examples/table_example.cc b/ui/views/examples/table_example.cc index 72985b1..0a763f0 100644 --- a/ui/views/examples/table_example.cc +++ b/ui/views/examples/table_example.cc
@@ -32,7 +32,7 @@ } // namespace -TableExample::TableExample() : ExampleBase("Table"), table_(nullptr) {} +TableExample::TableExample() : ExampleBase("Table") {} TableExample::~TableExample() { // Delete the view before the model.
diff --git a/ui/views/examples/table_example.h b/ui/views/examples/table_example.h index 604b49f..36b443c 100644 --- a/ui/views/examples/table_example.h +++ b/ui/views/examples/table_example.h
@@ -58,12 +58,12 @@ private: // The table to be tested. - TableView* table_; + TableView* table_ = nullptr; - Checkbox* column1_visible_checkbox_; - Checkbox* column2_visible_checkbox_; - Checkbox* column3_visible_checkbox_; - Checkbox* column4_visible_checkbox_; + Checkbox* column1_visible_checkbox_ = nullptr; + Checkbox* column2_visible_checkbox_ = nullptr; + Checkbox* column3_visible_checkbox_ = nullptr; + Checkbox* column4_visible_checkbox_ = nullptr; SkBitmap icon1_; SkBitmap icon2_;
diff --git a/ui/views/examples/text_example.cc b/ui/views/examples/text_example.cc index b999289..f1cb5f5 100644 --- a/ui/views/examples/text_example.cc +++ b/ui/views/examples/text_example.cc
@@ -76,11 +76,7 @@ // TextExample's content view, which draws stylized string. class TextExample::TextExampleView : public View { public: - TextExampleView() - : text_(base::ASCIIToUTF16(kShortText)), - flags_(0), - elide_(gfx::NO_ELIDE) { - } + TextExampleView() : text_(base::ASCIIToUTF16(kShortText)) {} void OnPaint(gfx::Canvas* canvas) override { View::OnPaint(canvas); @@ -121,10 +117,10 @@ base::string16 text_; // Text flags for passing to |DrawStringRect()|. - int flags_; + int flags_ = 0; // The eliding, fading, or truncating behavior. - gfx::ElideBehavior elide_; + gfx::ElideBehavior elide_ = gfx::NO_ELIDE; DISALLOW_COPY_AND_ASSIGN(TextExampleView); };
diff --git a/ui/views/examples/textfield_example.cc b/ui/views/examples/textfield_example.cc index 7b4f353..b7a0290 100644 --- a/ui/views/examples/textfield_example.cc +++ b/ui/views/examples/textfield_example.cc
@@ -23,19 +23,7 @@ namespace views { namespace examples { -TextfieldExample::TextfieldExample() - : ExampleBase("Textfield"), - name_(nullptr), - password_(nullptr), - disabled_(nullptr), - read_only_(nullptr), - invalid_(nullptr), - rtl_(nullptr), - show_password_(nullptr), - clear_all_(nullptr), - append_(nullptr), - set_(nullptr), - set_style_(nullptr) {} +TextfieldExample::TextfieldExample() : ExampleBase("Textfield") {} TextfieldExample::~TextfieldExample() = default;
diff --git a/ui/views/examples/textfield_example.h b/ui/views/examples/textfield_example.h index b2b5fd4a..9ea0144 100644 --- a/ui/views/examples/textfield_example.h +++ b/ui/views/examples/textfield_example.h
@@ -42,20 +42,20 @@ void ButtonPressed(Button* sender, const ui::Event& event) override; // Textfields for name and password. - Textfield* name_; - Textfield* password_; - Textfield* disabled_; - Textfield* read_only_; - Textfield* invalid_; - Textfield* rtl_; + Textfield* name_ = nullptr; + Textfield* password_ = nullptr; + Textfield* disabled_ = nullptr; + Textfield* read_only_ = nullptr; + Textfield* invalid_ = nullptr; + Textfield* rtl_ = nullptr; // Various buttons to control textfield. - LabelButton* show_password_; - LabelButton* set_background_; - LabelButton* clear_all_; - LabelButton* append_; - LabelButton* set_; - LabelButton* set_style_; + LabelButton* show_password_ = nullptr; + LabelButton* set_background_ = nullptr; + LabelButton* clear_all_ = nullptr; + LabelButton* append_ = nullptr; + LabelButton* set_ = nullptr; + LabelButton* set_style_ = nullptr; DISALLOW_COPY_AND_ASSIGN(TextfieldExample); };
diff --git a/ui/views/examples/throbber_example.cc b/ui/views/examples/throbber_example.cc index 87a88f1..845ad359 100644 --- a/ui/views/examples/throbber_example.cc +++ b/ui/views/examples/throbber_example.cc
@@ -16,7 +16,7 @@ class ThrobberView : public View { public: - ThrobberView() : throbber_(new Throbber()), is_checked_(false) { + ThrobberView() : throbber_(new Throbber()) { AddChildView(throbber_); throbber_->Start(); } @@ -49,7 +49,7 @@ private: Throbber* throbber_; - bool is_checked_; + bool is_checked_ = false; DISALLOW_COPY_AND_ASSIGN(ThrobberView); };
diff --git a/ui/views/examples/toggle_button_example.cc b/ui/views/examples/toggle_button_example.cc index 07da23c..adf5d9e 100644 --- a/ui/views/examples/toggle_button_example.cc +++ b/ui/views/examples/toggle_button_example.cc
@@ -13,8 +13,7 @@ namespace views { namespace examples { -ToggleButtonExample::ToggleButtonExample() - : ExampleBase("Toggle button"), button_(nullptr), count_(0) {} +ToggleButtonExample::ToggleButtonExample() : ExampleBase("Toggle button") {} ToggleButtonExample::~ToggleButtonExample() = default;
diff --git a/ui/views/examples/toggle_button_example.h b/ui/views/examples/toggle_button_example.h index 50c4b9f..90a5891 100644 --- a/ui/views/examples/toggle_button_example.h +++ b/ui/views/examples/toggle_button_example.h
@@ -29,9 +29,9 @@ void ButtonPressed(Button* sender, const ui::Event& event) override; // The only control in this test. - ToggleButton* button_; + ToggleButton* button_ = nullptr; - int count_; + int count_ = 0; DISALLOW_COPY_AND_ASSIGN(ToggleButtonExample); };
diff --git a/ui/views/examples/tree_view_example.cc b/ui/views/examples/tree_view_example.cc index 114841c94..1ec82dac 100644 --- a/ui/views/examples/tree_view_example.cc +++ b/ui/views/examples/tree_view_example.cc
@@ -168,7 +168,7 @@ std::make_unique<MenuRunner>(context_menu_model_.get(), 0); context_menu_runner_->RunMenuAt(source->GetWidget(), nullptr, gfx::Rect(point, gfx::Size()), - MENU_ANCHOR_TOPLEFT, source_type); + MenuAnchorPosition::kTopLeft, source_type); } bool TreeViewExample::IsCommandIdChecked(int command_id) const {
diff --git a/ui/views/examples/vector_example.cc b/ui/views/examples/vector_example.cc index 6d495db..e05e8f6 100644 --- a/ui/views/examples/vector_example.cc +++ b/ui/views/examples/vector_example.cc
@@ -39,11 +39,7 @@ color_input_(new Textfield()), file_chooser_(new Textfield()), file_go_button_( - MdTextButton::Create(this, base::ASCIIToUTF16("Render"))), - // 36dp is one of the natural sizes for MD icons, and corresponds - // roughly to a 32dp usable area. - size_(36), - color_(SK_ColorRED) { + MdTextButton::Create(this, base::ASCIIToUTF16("Render"))) { AddChildView(size_input_); AddChildView(color_input_); @@ -131,6 +127,11 @@ Layout(); } + // 36dp is one of the natural sizes for MD icons, and corresponds roughly to a + // 32dp usable area. + int size_ = 36; + SkColor color_ = SK_ColorRED; + ImageView* image_view_; View* image_view_container_; Textfield* size_input_; @@ -139,9 +140,6 @@ Button* file_go_button_; std::string contents_; - int size_; - SkColor color_; - DISALLOW_COPY_AND_ASSIGN(VectorIconGallery); };
diff --git a/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js b/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js index 55ce7a8..c23d6435 100644 --- a/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js +++ b/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js
@@ -388,6 +388,23 @@ }; /** + * Determines whether the provided properties represent a connecting/connected + * network. + * @param {!CrOnc.NetworkProperties|undefined} properties + * @return {boolean} Whether the properties provided indicate that the network + * is connecting or connected. + */ +CrOnc.isConnectingOrConnected = function(properties) { + if (!properties) { + return false; + } + + const connectionState = properties.ConnectionState; + return connectionState == CrOnc.ConnectionState.CONNECTED || + connectionState == CrOnc.ConnectionState.CONNECTING; +}; + +/** * Gets the SignalStrength value from |properties| based on properties.Type. * @param {!CrOnc.NetworkProperties|!CrOnc.NetworkStateProperties|undefined} * properties The ONC network properties or state properties.