diff --git a/.gitignore b/.gitignore index 93b62c81..99a2ddfa 100644 --- a/.gitignore +++ b/.gitignore
@@ -166,7 +166,8 @@ /chromecast/internal /chromeos/assistant/internal /chromeos/profiles/chromeos.orderfile.txt -/chromeos/profiles/orderfile.local.txt +/chromeos/profiles/*.local.txt +/chromeos/profiles/*.afdo.prof /cipd_cache/ /clank /cloud_print/cloud_print_version_resources.xml
diff --git a/BUILD.gn b/BUILD.gn index fd1c723..9a9ef733 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -321,6 +321,7 @@ "//content/public/android:content_junit_tests", "//content/shell/android:content_shell_apk", "//device:device_junit_tests", + "//weblayer/shell/android:weblayer_demo_apk", "//weblayer/shell/android:weblayer_shell_apk", # TODO(https://crbug.com/879065): remove once tests have been migrated to
diff --git a/DEPS b/DEPS index a36f258..849c868b 100644 --- a/DEPS +++ b/DEPS
@@ -162,7 +162,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '932a2c0e3bb614c77bd4293f56bb5619f902e507', + 'skia_revision': '0033008d95ac6deb3cc43203fda5313b30ae1cf1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -178,7 +178,7 @@ # 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': '860369fc431e8510f974799961083b42d01cfa8b', + 'swiftshader_revision': '61a2765940a72891baa108e2815da6c21f7f3218', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -213,7 +213,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': '99f23d6ff2203966d210bccd49eacc62a20328f9', + 'freetype_revision': '04ebb2a000ee40df2a9900198ec62d79af745b1f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling HarfBuzz # and whatever else without interference from each other. @@ -853,7 +853,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '818d963727de2aa9d1b7252e9657d425ec856001', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '7fd753567d3cac55292131dcf0c3094f0532dcda', 'condition': 'checkout_linux', }, @@ -878,7 +878,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '2c210a490857380a93f8308dd504aeb1ef759d38', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6f9a0238ce40b6af186aac520c3b87ffa9a8be3b', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1257,7 +1257,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'e7a75776335a1735f41268a150193c67fc964bcd', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '5b12fdd2a7ac6d8a9a61013b855ace3766393934', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1425,7 +1425,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'abaae129d9a0c6e1e092067e0b105475df43352e', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '809198edfff416fce8d75b574a43afab5e67b1cd', + Var('webrtc_git') + '/src.git' + '@' + '86314cfb5dc09bba15a1607585e9ddd544078ac5', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1487,7 +1487,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ea5731baa00cf8b8e3041795ccaa13f419b41699', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@95dfac5bc3249a5a17961b41c3082cb30b9f469b', 'condition': 'checkout_src_internal', }, @@ -3681,6 +3681,43 @@ '--gs_url_base=chromeos-prebuilt/afdo-job/orderfiles/vetted', ], }, + # Download AFDO profiles for Chrome OS for each architecture. + { + 'name': 'Fetch Chrome OS AFDO profiles (silvermont)', + 'pattern': '.', + 'condition': 'checkout_chromeos or checkout_simplechrome', + 'action': [ 'vpython', + 'src/tools/download_cros_provided_profile.py', + '--newest_state=src/chromeos/profiles/silvermont.afdo.newest.txt', + '--local_state=src/chromeos/profiles/silvermont.afdo.local.txt', + '--output_name=src/chromeos/profiles/silvermont.afdo.prof', + '--gs_url_base=chromeos-prebuilt/afdo-job/vetted/release', + ], + }, + { + 'name': 'Fetch Chrome OS AFDO profiles (airmont)', + 'pattern': '.', + 'condition': 'checkout_chromeos or checkout_simplechrome', + 'action': [ 'vpython', + 'src/tools/download_cros_provided_profile.py', + '--newest_state=src/chromeos/profiles/airmont.afdo.newest.txt', + '--local_state=src/chromeos/profiles/airmont.afdo.local.txt', + '--output_name=src/chromeos/profiles/airmont.afdo.prof', + '--gs_url_base=chromeos-prebuilt/afdo-job/vetted/release', + ], + }, + { + 'name': 'Fetch Chrome OS AFDO profiles (broadwell)', + 'pattern': '.', + 'condition': 'checkout_chromeos or checkout_simplechrome', + 'action': [ 'vpython', + 'src/tools/download_cros_provided_profile.py', + '--newest_state=src/chromeos/profiles/broadwell.afdo.newest.txt', + '--local_state=src/chromeos/profiles/broadwell.afdo.local.txt', + '--output_name=src/chromeos/profiles/broadwell.afdo.prof', + '--gs_url_base=chromeos-prebuilt/afdo-job/vetted/release', + ], + }, { # Pull doclava binaries if building for Android. 'name': 'doclava',
diff --git a/ash/app_list/views/search_result_tile_item_list_view.cc b/ash/app_list/views/search_result_tile_item_list_view.cc index 9103523..1efe799 100644 --- a/ash/app_list/views/search_result_tile_item_list_view.cc +++ b/ash/app_list/views/search_result_tile_item_list_view.cc
@@ -212,7 +212,7 @@ FROM_HERE, base::TimeDelta::FromMilliseconds(kPlayStoreImpressionDelayInMs), this, &SearchResultTileItemListView::OnPlayStoreImpressionTimer); - } else { + } else if (!found_playstore_results) { playstore_impression_timer_.Stop(); } @@ -347,6 +347,11 @@ playstore_app_num, max_search_result_tiles_); } +void SearchResultTileItemListView::CleanUpOnViewHide() { + playstore_impression_timer_.Stop(); + recent_playstore_query_.clear(); +} + bool SearchResultTileItemListView::OnKeyPressed(const ui::KeyEvent& event) { // Let the FocusManager handle Left/Right keys. if (!IsUnhandledUpDownKeyEvent(event)) @@ -397,8 +402,6 @@ view_delegate()->OnSearchResultVisibilityChanged(result->id(), shown()); } } - if (!shown()) - playstore_impression_timer_.Stop(); } void SearchResultTileItemListView::VisibilityChanged(View* starting_from, @@ -410,7 +413,7 @@ return; } - playstore_impression_timer_.Stop(); + CleanUpOnViewHide(); for (const auto* tile_view : tile_views_) { SearchResult* result = tile_view->result();
diff --git a/ash/app_list/views/search_result_tile_item_list_view.h b/ash/app_list/views/search_result_tile_item_list_view.h index 4c1cb59..27f380e 100644 --- a/ash/app_list/views/search_result_tile_item_list_view.h +++ b/ash/app_list/views/search_result_tile_item_list_view.h
@@ -62,6 +62,10 @@ void OnPlayStoreImpressionTimer(); + // Cleans up when the view is hid due to closing the suggestion widow + // or closing the launcher. + void CleanUpOnViewHide(); + std::vector<SearchResultTileItemView*> tile_views_; std::vector<views::Separator*> separator_views_;
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index d3867a4..09513a99 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -90,6 +90,9 @@ const base::Feature kEnableBackgroundBlur{"EnableBackgroundBlur", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSwipingFromLeftEdgeToGoBack{ + "SwipingFromLeftEdgeToGoBack", base::FEATURE_DISABLED_BY_DEFAULT}; + bool IsHideArcMediaNotificationsEnabled() { return base::FeatureList::IsEnabled(kMediaSessionNotification) && base::FeatureList::IsEnabled(kHideArcMediaNotifications); @@ -167,5 +170,9 @@ return base::FeatureList::IsEnabled(kEnableBackgroundBlur); } +bool IsSwipingFromLeftEdgeToGoBackEnabled() { + return base::FeatureList::IsEnabled(kSwipingFromLeftEdgeToGoBack); +} + } // namespace features } // namespace ash
diff --git a/ash/public/cpp/ash_features.h b/ash/public/cpp/ash_features.h index 1b3d57b..50ab4d6 100644 --- a/ash/public/cpp/ash_features.h +++ b/ash/public/cpp/ash_features.h
@@ -115,6 +115,10 @@ // the UnifiedSystemTrayView. ASH_PUBLIC_EXPORT extern const base::Feature kUnifiedMessageCenterRefactor; +// Enables going back to previous page while swiping from the left edge of the +// display. Only for tablet mode. +ASH_PUBLIC_EXPORT extern const base::Feature kSwipingFromLeftEdgeToGoBack; + ASH_PUBLIC_EXPORT bool IsHideArcMediaNotificationsEnabled(); ASH_PUBLIC_EXPORT bool IsKeyboardShortcutViewerAppEnabled(); @@ -151,6 +155,8 @@ ASH_PUBLIC_EXPORT bool IsBackgroundBlurEnabled(); +ASH_PUBLIC_EXPORT bool IsSwipingFromLeftEdgeToGoBackEnabled(); + } // namespace features } // namespace ash
diff --git a/ash/shelf/shelf_tooltip_manager_unittest.cc b/ash/shelf/shelf_tooltip_manager_unittest.cc index af60328..bc0d0d47 100644 --- a/ash/shelf/shelf_tooltip_manager_unittest.cc +++ b/ash/shelf/shelf_tooltip_manager_unittest.cc
@@ -183,6 +183,7 @@ generator->MoveMouseTo(shelf_bounds.CenterPoint()); generator->PressLeftButton(); EXPECT_FALSE(tooltip_manager_->IsVisible()); + generator->ReleaseLeftButton(); // Should hide for touch events in the shelf. ShowTooltipForFirstAppIcon();
diff --git a/ash/shelf/shelf_widget_unittest.cc b/ash/shelf/shelf_widget_unittest.cc index 1d5729f..bf7e41b 100644 --- a/ash/shelf/shelf_widget_unittest.cc +++ b/ash/shelf/shelf_widget_unittest.cc
@@ -152,7 +152,7 @@ const int nav_width = shelf_widget->navigation_widget()->GetWindowBoundsInScreen().width(); const int hotseat_width = - GetPrimaryShelf()->GetShelfViewForTesting()->width(); + shelf_widget->hotseat_widget()->GetWindowBoundsInScreen().width(); const int margins = ShelfConfig::Get()->home_button_edge_spacing() + ShelfConfig::Get()->app_icon_group_margin(); EXPECT_EQ(status_width, total_width - nav_width - hotseat_width - margins);
diff --git a/ash/shell/content/test/ash_content_perf_test_launcher.cc b/ash/shell/content/test/ash_content_perf_test_launcher.cc index fb68206..947b77ff 100644 --- a/ash/shell/content/test/ash_content_perf_test_launcher.cc +++ b/ash/shell/content/test/ash_content_perf_test_launcher.cc
@@ -34,10 +34,9 @@ protected: // content::ContentTestSuiteBase: void Initialize() override { - // Browser tests are expected not to tear-down various globals and may - // complete with the thread priority being above NORMAL. + // Browser tests are expected not to tear-down various globals. (Must run + // before the base class is initialized.) base::TestSuite::DisableCheckForLeakedGlobals(); - base::TestSuite::DisableCheckForThreadPriorityAtTestEnd(); ContentTestSuiteBase::Initialize(); ui_controls::InstallUIControlsAura(ash::test::CreateAshUIControls()); }
diff --git a/ash/wm/overview/overview_constants.h b/ash/wm/overview/overview_constants.h index 0ea40491..e9f4d1f 100644 --- a/ash/wm/overview/overview_constants.h +++ b/ash/wm/overview/overview_constants.h
@@ -37,7 +37,8 @@ // Amount of time we wait to unpause the occlusion tracker after a overview item // is finished dragging. Waits a bit longer than the overview item animation. -constexpr int kOcclusionPauseDurationForDragMs = 300; +constexpr base::TimeDelta kOcclusionPauseDurationForDrag = + base::TimeDelta::FromMilliseconds(300); } // namespace ash
diff --git a/ash/wm/overview/overview_controller.cc b/ash/wm/overview/overview_controller.cc index f68f158..0287b8cb 100644 --- a/ash/wm/overview/overview_controller.cc +++ b/ash/wm/overview/overview_controller.cc
@@ -54,11 +54,13 @@ // It can take up to two frames until the frame created in the UI thread that // triggered animation observer is drawn. Wait 50ms in attempt to let its draw // and swap finish. -constexpr int kOcclusionPauseDurationForStartMs = 50; +constexpr base::TimeDelta kOcclusionPauseDurationForStart = + base::TimeDelta::FromMilliseconds(50); // Wait longer when exiting overview mode in case when a user may re-enter // overview mode immediately, contents are ready. -constexpr int kOcclusionPauseDurationForEndMs = 500; +constexpr base::TimeDelta kOcclusionPauseDurationForEnd = + base::TimeDelta::FromMilliseconds(500); bool IsWallpaperChangeAllowed() { return !g_disable_wallpaper_change_for_tests && @@ -255,7 +257,7 @@ }; OverviewController::OverviewController() - : occlusion_pause_duration_for_end_ms_(kOcclusionPauseDurationForEndMs), + : occlusion_pause_duration_for_end_(kOcclusionPauseDurationForEnd), overview_wallpaper_controller_( std::make_unique<OverviewWallpaperController>()), delayed_animation_task_delay_(kTransition) { @@ -426,12 +428,11 @@ std::make_unique<aura::WindowOcclusionTracker::ScopedPause>(); } -void OverviewController::UnpauseOcclusionTracker(int delay) { +void OverviewController::UnpauseOcclusionTracker(base::TimeDelta delay) { reset_pauser_task_.Reset(base::BindOnce(&OverviewController::ResetPauser, weak_ptr_factory_.GetWeakPtr())); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, reset_pauser_task_.callback(), - base::TimeDelta::FromMilliseconds(delay)); + FROM_HERE, reset_pauser_task_.callback(), delay); } void OverviewController::AddObserver(OverviewObserver* observer) { @@ -738,7 +739,7 @@ overview_session_->OnStartingAnimationComplete(canceled, should_focus_overview_); } - UnpauseOcclusionTracker(kOcclusionPauseDurationForStartMs); + UnpauseOcclusionTracker(kOcclusionPauseDurationForStart); TRACE_EVENT_ASYNC_END1("ui", "OverviewController::EnterOverview", this, "canceled", canceled); } @@ -752,7 +753,7 @@ for (auto& observer : observers_) observer.OnOverviewModeEndingAnimationComplete(canceled); - UnpauseOcclusionTracker(occlusion_pause_duration_for_end_ms_); + UnpauseOcclusionTracker(occlusion_pause_duration_for_end_); TRACE_EVENT_ASYNC_END1("ui", "OverviewController::ExitOverview", this, "canceled", canceled); }
diff --git a/ash/wm/overview/overview_controller.h b/ash/wm/overview/overview_controller.h index 05e5aed8..8b60f57 100644 --- a/ash/wm/overview/overview_controller.h +++ b/ash/wm/overview/overview_controller.h
@@ -63,7 +63,7 @@ // Pause or unpause the occlusion tracker. Resets the unpause delay if we were // already in the process of unpausing. void PauseOcclusionTracker(); - void UnpauseOcclusionTracker(int delay); + void UnpauseOcclusionTracker(base::TimeDelta delay); void AddObserver(OverviewObserver* observer); void RemoveObserver(OverviewObserver* observer); @@ -93,8 +93,8 @@ OverviewSession* overview_session() { return overview_session_.get(); } - void set_occlusion_pause_duration_for_end_ms_for_test(int duration) { - occlusion_pause_duration_for_end_ms_ = duration; + void set_occlusion_pause_duration_for_end_for_test(base::TimeDelta duration) { + occlusion_pause_duration_for_end_ = duration; } void set_delayed_animation_task_delay_for_test(base::TimeDelta delta) { delayed_animation_task_delay_ = delta; @@ -154,7 +154,7 @@ std::unique_ptr<OverviewSession> overview_session_; base::Time last_overview_session_time_; - int occlusion_pause_duration_for_end_ms_; + base::TimeDelta occlusion_pause_duration_for_end_; // Handles blurring and dimming of the wallpaper when entering or exiting // overview mode. Animates the blurring and dimming if necessary.
diff --git a/ash/wm/overview/overview_controller_unittest.cc b/ash/wm/overview/overview_controller_unittest.cc index 0447249..9765480 100644 --- a/ash/wm/overview/overview_controller_unittest.cc +++ b/ash/wm/overview/overview_controller_unittest.cc
@@ -293,7 +293,8 @@ Shell::Get() ->overview_controller() - ->set_occlusion_pause_duration_for_end_ms_for_test(100); + ->set_occlusion_pause_duration_for_end_for_test( + base::TimeDelta::FromMilliseconds(100)); TestOverviewObserver observer(/*should_monitor_animation_state = */ true); ui::ScopedAnimationDurationScaleMode non_zero( ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index eed44aa..a079bfb 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -80,7 +80,11 @@ // Wait a while before unpausing the occlusion tracker after a scroll has // completed as the user may start another scroll. -constexpr int kOcclusionUnpauseDurationForScrollMs = 500; +constexpr base::TimeDelta kOcclusionUnpauseDurationForScroll = + base::TimeDelta::FromMilliseconds(500); + +constexpr base::TimeDelta kOcclusionUnpauseDurationForRotation = + base::TimeDelta::FromMilliseconds(300); // Histogram names for overview enter/exit smoothness in clamshell, // tablet mode and splitview. @@ -630,10 +634,11 @@ void OverviewGrid::SetBoundsAndUpdatePositions( const gfx::Rect& bounds_in_screen, - const base::flat_set<OverviewItem*>& ignored_items) { + const base::flat_set<OverviewItem*>& ignored_items, + bool animate) { bounds_ = bounds_in_screen; MaybeUpdateDesksWidgetBounds(); - PositionWindows(/*animate=*/true, ignored_items); + PositionWindows(animate, ignored_items); } void OverviewGrid::RearrangeDuringDrag(aura::Window* dragged_window, @@ -662,7 +667,8 @@ ignored_items.insert(dragged_item); if (drop_target && !wanted_drop_target_visibility) ignored_items.insert(drop_target); - SetBoundsAndUpdatePositions(wanted_grid_bounds, ignored_items); + SetBoundsAndUpdatePositions(wanted_grid_bounds, ignored_items, + /*animate=*/true); } } @@ -803,7 +809,8 @@ // be updated based on the preview area during drag, but the window finally // didn't be snapped to the preview area. SetBoundsAndUpdatePositions( - GetGridBoundsInScreenAfterDragging(dragged_window), /*ignored_items=*/{}); + GetGridBoundsInScreenAfterDragging(dragged_window), /*ignored_items=*/{}, + /*animate=*/true); } bool OverviewGrid::IsDropTargetWindow(aura::Window* window) const { @@ -914,6 +921,8 @@ } void OverviewGrid::OnScreenCopiedBeforeRotation() { + Shell::Get()->overview_controller()->PauseOcclusionTracker(); + for (auto& window : window_list()) { window->set_disable_mask(true); window->UpdateRoundedCornersAndShadow(); @@ -927,6 +936,8 @@ for (auto& window : window_list()) window->set_disable_mask(false); Shell::Get()->overview_controller()->DelayedUpdateRoundedCornersAndShadow(); + Shell::Get()->overview_controller()->UnpauseOcclusionTracker( + kOcclusionUnpauseDurationForRotation); } void OverviewGrid::OnWallpaperChanging() { @@ -1417,7 +1428,7 @@ void OverviewGrid::EndScroll() { Shell::Get()->overview_controller()->UnpauseOcclusionTracker( - kOcclusionUnpauseDurationForScrollMs); + kOcclusionUnpauseDurationForScroll); items_scrolling_bounds_.clear(); presentation_time_recorder_.reset();
diff --git a/ash/wm/overview/overview_grid.h b/ash/wm/overview/overview_grid.h index a23b276..69ec63d 100644 --- a/ash/wm/overview/overview_grid.h +++ b/ash/wm/overview/overview_grid.h
@@ -126,7 +126,8 @@ // except windows in |ignored_items|. void SetBoundsAndUpdatePositions( const gfx::Rect& bounds_in_screen, - const base::flat_set<OverviewItem*>& ignored_items); + const base::flat_set<OverviewItem*>& ignored_items, + bool animate); // Updates overview bounds and hides the drop target when a preview area is // shown.
diff --git a/ash/wm/overview/overview_item.cc b/ash/wm/overview/overview_item.cc index 80ef5576e4..cc93b46 100644 --- a/ash/wm/overview/overview_item.cc +++ b/ash/wm/overview/overview_item.cc
@@ -920,7 +920,7 @@ if (is_being_dragged_) { Shell::Get()->overview_controller()->UnpauseOcclusionTracker( - kOcclusionPauseDurationForDragMs); + kOcclusionPauseDurationForDrag); } }
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc index 5d7dfc0b..54fd8ec 100644 --- a/ash/wm/overview/overview_session.cc +++ b/ash/wm/overview/overview_session.cc
@@ -977,7 +977,7 @@ grid->SetBoundsAndUpdatePositions( GetGridBoundsInScreen(const_cast<aura::Window*>(grid->root_window()), /*divider_changed=*/true), - /*ignored_items=*/{}); + /*ignored_items=*/{}, /*animate=*/true); } PositionWindows(/*animate=*/false); UpdateNoWindowsWidget(); @@ -1063,9 +1063,8 @@ grid->SetBoundsAndUpdatePositions( GetGridBoundsInScreen(const_cast<aura::Window*>(grid->root_window()), /*divider_changed=*/false), - /*ignored_items=*/{}); + /*ignored_items=*/{}, /*animate=*/false); } - PositionWindows(/*animate=*/false); UpdateNoWindowsWidget(); if (split_view_drag_indicators_) split_view_drag_indicators_->OnDisplayBoundsChanged();
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc index 8741b97..6ab063bc 100644 --- a/ash/wm/overview/overview_window_drag_controller.cc +++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -65,7 +65,7 @@ void UnpauseOcclusionTracker() { Shell::Get()->overview_controller()->UnpauseOcclusionTracker( - kOcclusionPauseDurationForDragMs); + kOcclusionPauseDurationForDrag); } // Returns the scaled-down size of the dragged item that should be used when
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc index 4e88482..746872a 100644 --- a/ash/wm/splitview/split_view_controller_unittest.cc +++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -15,6 +15,7 @@ #include "ash/display/screen_orientation_controller_test_api.h" #include "ash/magnifier/docked_magnifier_controller_impl.h" #include "ash/public/cpp/app_types.h" +#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/fps_counter.h" #include "ash/public/cpp/presentation_time_recorder.h" #include "ash/public/cpp/window_properties.h" @@ -49,6 +50,7 @@ #include "ash/wm/wm_event.h" #include "base/stl_util.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/test/test_windows.h" @@ -4141,6 +4143,57 @@ EXPECT_FALSE(Shell::Get()->overview_controller()->InOverviewSession()); } +class SplitViewTabDraggingTestWithClamshellSupport + : public SplitViewTabDraggingTest { + public: + SplitViewTabDraggingTestWithClamshellSupport() = default; + ~SplitViewTabDraggingTestWithClamshellSupport() override = default; + + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature( + ash::features::kDragToSnapInClamshellMode); + SplitViewTabDraggingTest::SetUp(); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; + + DISALLOW_COPY_AND_ASSIGN(SplitViewTabDraggingTestWithClamshellSupport); +}; + +TEST_F(SplitViewTabDraggingTestWithClamshellSupport, + DragTabFromSnappedWindowToOverviewAndThenExitTablet) { + // Snap a browser window in split view. + std::unique_ptr<aura::Window> snapped_window( + CreateWindowWithType(gfx::Rect(), AppType::BROWSER)); + ToggleOverview(); + split_view_controller()->SnapWindow(snapped_window.get(), + SplitViewController::LEFT); + + // Drag a tab out of the browser window and into overview. + std::unique_ptr<aura::Window> dragged_tab( + CreateWindowWithType(gfx::Rect(), AppType::BROWSER)); + std::unique_ptr<WindowResizer> resizer = + StartDrag(dragged_tab.get(), snapped_window.get()); + DragWindowTo(resizer.get(), + gfx::ToEnclosingRect( + Shell::Get() + ->overview_controller() + ->overview_session() + ->GetGridWithRootWindow(snapped_window->GetRootWindow()) + ->GetDropTarget() + ->target_bounds()) + .CenterPoint()); + CompleteDrag(std::move(resizer)); + EXPECT_TRUE(dragged_tab->GetProperty(kIsShowingInOverviewKey)); + + // Switch to clamshell mode and check that |snapped_window| keeps its snapped + // window state. + Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false); + EXPECT_EQ(WindowStateType::kLeftSnapped, + WindowState::Get(snapped_window.get())->GetStateType()); +} + class TestWindowDelegateWithWidget : public views::WidgetDelegate { public: TestWindowDelegateWithWidget(bool can_activate)
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager.cc b/ash/wm/tablet_mode/tablet_mode_window_manager.cc index 7d2ad60..8e5a3a5 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_manager.cc
@@ -42,7 +42,7 @@ // This function is called to check if window[i] is eligible to be carried over // to split view mode during clamshell <-> tablet mode transition or multi-user // switch transition. Returns true if windows[i] exists, can snap in split view, -// is not showing in overview, and is not ARC window. +// and is not an ARC window. // TODO(xdai): Make it work for ARC windows. (see // https://crbug.com/922282 and // https://buganizer.corp.google.com/issues/123432223). @@ -50,7 +50,6 @@ const MruWindowTracker::WindowList& windows, size_t i) { return windows.size() > i && CanSnapInSplitview(windows[i]) && - !windows[i]->GetProperty(kIsShowingInOverviewKey) && static_cast<ash::AppType>(windows[i]->GetProperty( aura::client::kAppType)) != AppType::ARC_APP; } @@ -61,11 +60,17 @@ base::flat_map<aura::Window*, WindowStateType> GetCarryOverWindowsInSplitView() { base::flat_map<aura::Window*, WindowStateType> windows; - // Check the topmost window and the second topmost's window state to see if - // they are eligible to be carried over to splitscreen. A window must meet + // Check the states of the topmost two non-overview windows to see if they are + // eligible to be carried over to splitscreen. A window must meet // IsCarryOverCandidateForSplitView() to be carried over to splitscreen. MruWindowTracker::WindowList mru_windows = Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kActiveDesk); + mru_windows.erase( + std::remove_if(mru_windows.begin(), mru_windows.end(), + [](aura::Window* window) { + return window->GetProperty(kIsShowingInOverviewKey); + }), + mru_windows.end()); if (IsCarryOverCandidateForSplitView(mru_windows, 0u)) { if (WindowState::Get(mru_windows[0])->GetStateType() == WindowStateType::kLeftSnapped) {
diff --git a/ash/wm/toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc index 30292a1..b690b54 100644 --- a/ash/wm/toplevel_window_event_handler.cc +++ b/ash/wm/toplevel_window_event_handler.cc
@@ -5,6 +5,7 @@ #include "ash/wm/toplevel_window_event_handler.h" #include "ash/public/cpp/app_types.h" +#include "ash/public/cpp/ash_features.h" #include "ash/shell.h" #include "ash/wm/resize_shadow_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" @@ -37,6 +38,10 @@ // window from the top of the screen in tablet mode. constexpr int kDragStartTopEdgeInset = 8; +// How many dips are reserved for gesture events to start swiping to previous +// page from the left edge of the screen in tablet mode. +constexpr int kStartGoingBackLeftEdgeInset = 16; + // Returns whether |window| can be moved via a two finger drag given // the hittest results of the two fingers. bool CanStartTwoFingerMove(aura::Window* window, @@ -94,6 +99,35 @@ run_loop->Quit(); } +// True if we can start swiping from left edge to go to previous page. +bool CanStartGoingBack() { + if (!features::IsSwipingFromLeftEdgeToGoBackEnabled()) + return false; + + if (!Shell::Get()->tablet_mode_controller()->InTabletMode()) + return false; + + return true; +} + +// True if |event| is scrolling away from the restricted left area of the +// display. +bool StartedAwayFromLeftArea(ui::GestureEvent* event) { + if (event->details().scroll_x_hint() < 0) + return false; + + const gfx::Point location_in_screen = + event->target()->GetScreenLocation(*event); + const gfx::Rect work_area_bounds = + display::Screen::GetScreen() + ->GetDisplayNearestWindow(static_cast<aura::Window*>(event->target())) + .work_area(); + + gfx::Rect hit_bounds_in_screen(work_area_bounds); + hit_bounds_in_screen.set_width(kStartGoingBackLeftEdgeInset); + return hit_bounds_in_screen.Contains(location_in_screen); +} + } // namespace // ScopedWindowResizer --------------------------------------------------------- @@ -264,6 +298,11 @@ } void ToplevelWindowEventHandler::OnGestureEvent(ui::GestureEvent* event) { + if (HandleGoingBackFromLeftEdge(event)) { + event->StopPropagation(); + return; + } + aura::Window* target = static_cast<aura::Window*>(event->target()); int component = window_util::GetNonClientComponent(target, event->location()); gfx::Point event_location = event->location(); @@ -796,4 +835,47 @@ gesture_target_->AddObserver(this); } +bool ToplevelWindowEventHandler::HandleGoingBackFromLeftEdge( + ui::GestureEvent* event) { + if (!CanStartGoingBack()) + return false; + + switch (event->type()) { + case ui::ET_GESTURE_SCROLL_BEGIN: + going_back_started_ = StartedAwayFromLeftArea(event); + if (going_back_started_) + return true; + break; + case ui::ET_GESTURE_SCROLL_UPDATE: + if (!going_back_started_) + break; + // TODO(crbug.com/1002733): Update the arrow animation. + return true; + case ui::ET_GESTURE_SCROLL_END: + if (!going_back_started_) + break; + if (event->location().x() >= kSwipingDistanceForGoingBack) { + aura::Window* root_window = + window_util::GetRootWindowAt(event->location()); + ui::KeyEvent press_key_event(ui::ET_KEY_PRESSED, ui::VKEY_BROWSER_BACK, + ui::EF_NONE); + ignore_result( + root_window->GetHost()->SendEventToSink(&press_key_event)); + ui::KeyEvent release_key_event(ui::ET_KEY_RELEASED, + ui::VKEY_BROWSER_BACK, ui::EF_NONE); + ignore_result( + root_window->GetHost()->SendEventToSink(&release_key_event)); + } else { + // TODO(crbug.com/1002733): Revert going back animation. + } + going_back_started_ = false; + return true; + // TODO(crbug.com/1002733): Add support for fling event. + default: + break; + } + + return false; +} + } // namespace ash
diff --git a/ash/wm/toplevel_window_event_handler.h b/ash/wm/toplevel_window_event_handler.h index b3a85f0..d15e39e 100644 --- a/ash/wm/toplevel_window_event_handler.h +++ b/ash/wm/toplevel_window_event_handler.h
@@ -43,6 +43,9 @@ public ui::EventHandler, public ::wm::WindowMoveClient { public: + // The distance for swiping from left edge to go previous page. + static constexpr int kSwipingDistanceForGoingBack = 80; + // Describes what triggered ending the drag. enum class DragResult { // The drag successfully completed. @@ -157,6 +160,9 @@ void UpdateGestureTarget(aura::Window* window, const gfx::Point& location = gfx::Point()); + // True if the event is handled for swiping to previous page. + bool HandleGoingBackFromLeftEdge(ui::GestureEvent* event); + // The hittest result for the first finger at the time that it initially // touched the screen. |first_finger_hittest_| is one of ui/base/hit_test.h int first_finger_hittest_; @@ -178,6 +184,9 @@ // Are we running a nested run loop from RunMoveLoop(). bool in_move_loop_ = false; + // True if swiping from left edge to go to previous page is in progress. + bool going_back_started_ = false; + base::WeakPtrFactory<ToplevelWindowEventHandler> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(ToplevelWindowEventHandler);
diff --git a/ash/wm/toplevel_window_event_handler_unittest.cc b/ash/wm/toplevel_window_event_handler_unittest.cc index 2044b5b..334611c 100644 --- a/ash/wm/toplevel_window_event_handler_unittest.cc +++ b/ash/wm/toplevel_window_event_handler_unittest.cc
@@ -4,9 +4,11 @@ #include "ash/wm/toplevel_window_event_handler.h" +#include "ash/accelerators/accelerator_controller_impl.h" #include "ash/display/screen_orientation_controller.h" #include "ash/display/screen_orientation_controller_test_api.h" #include "ash/public/cpp/app_types.h" +#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/root_window_controller.h" #include "ash/shell.h" @@ -29,6 +31,7 @@ #include "base/bind.h" #include "base/compiler_specific.h" #include "base/run_loop.h" +#include "base/test/scoped_feature_list.h" #include "base/threading/thread_task_runner_handle.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/client/aura_constants.h" @@ -37,6 +40,8 @@ #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_observer.h" +#include "ui/base/accelerators/accelerator.h" +#include "ui/base/accelerators/test_accelerator_target.h" #include "ui/base/hit_test.h" #include "ui/display/display_layout_builder.h" #include "ui/display/manager/display_manager.h" @@ -1006,6 +1011,51 @@ EXPECT_EQ("10,11 100x100", window1->bounds().ToString()); } +TEST_F(ToplevelWindowEventHandlerTest, SwipingFromLeftEdgeToGoBack) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + ash::features::kSwipingFromLeftEdgeToGoBack); + std::unique_ptr<aura::Window> w1 = CreateTestWindow(); + TabletModeControllerTestApi().EnterTabletMode(); + + AcceleratorControllerImpl* controller = + Shell::Get()->accelerator_controller(); + + // Register an accelerator that looks for back presses. + ui::Accelerator accelerator_back_press(ui::VKEY_BROWSER_BACK, ui::EF_NONE); + accelerator_back_press.set_key_state(ui::Accelerator::KeyState::PRESSED); + ui::TestAcceleratorTarget target_back_press; + controller->Register({accelerator_back_press}, &target_back_press); + + // Register an accelerator that looks for back releases. + ui::Accelerator accelerator_back_release(ui::VKEY_BROWSER_BACK, ui::EF_NONE); + accelerator_back_release.set_key_state(ui::Accelerator::KeyState::RELEASED); + ui::TestAcceleratorTarget target_back_release; + controller->Register({accelerator_back_release}, &target_back_release); + + // Tests that swiping from the left less than |kSwipingDistanceForGoingBack| + // should not go to previous page. + ui::test::EventGenerator* generator = GetEventGenerator(); + const gfx::Point start(0, 100); + generator->GestureScrollSequence( + start, + gfx::Point(ToplevelWindowEventHandler::kSwipingDistanceForGoingBack - 10, + 100), + base::TimeDelta::FromMilliseconds(100), 3); + EXPECT_EQ(0, target_back_press.accelerator_count()); + EXPECT_EQ(0, target_back_release.accelerator_count()); + + // Tests that swiping from the left more than |kSwipingDistanceForGoingBack| + // should go to previous page. + generator->GestureScrollSequence( + start, + gfx::Point(ToplevelWindowEventHandler::kSwipingDistanceForGoingBack + 10, + 100), + base::TimeDelta::FromMilliseconds(100), 3); + EXPECT_EQ(1, target_back_press.accelerator_count()); + EXPECT_EQ(1, target_back_release.accelerator_count()); +} + namespace { void SendMouseReleaseAndReleaseCapture(ui::test::EventGenerator* generator,
diff --git a/base/android/java/src/org/chromium/base/LifetimeAssert.java b/base/android/java/src/org/chromium/base/LifetimeAssert.java index 61bd17f5..c85d22be 100644 --- a/base/android/java/src/org/chromium/base/LifetimeAssert.java +++ b/base/android/java/src/org/chromium/base/LifetimeAssert.java
@@ -6,6 +6,8 @@ import androidx.annotation.VisibleForTesting; +import org.chromium.base.annotations.CheckDiscard; + import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; import java.util.Collections; @@ -26,6 +28,7 @@ * } * } */ +@CheckDiscard public class LifetimeAssert { interface TestHook { void onCleaned(WrappedReference ref, String msg);
diff --git a/base/task/promise/dependent_list.h b/base/task/promise/dependent_list.h index 020bdbfc..3245c1c 100644 --- a/base/task/promise/dependent_list.h +++ b/base/task/promise/dependent_list.h
@@ -59,7 +59,7 @@ // Align Node on an 8-byte boundary to ensure the first 3 bits are 0 and can // be used to store additional state (see static_asserts below). - class BASE_EXPORT alignas(8) Node { + class BASE_EXPORT ALIGNAS(8) Node { public: Node(); explicit Node(Node&& other) noexcept;
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index fb9a444..3b1de80 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc
@@ -37,7 +37,6 @@ #include "base/test/multiprocess_test.h" #include "base/test/test_switches.h" #include "base/test/test_timeouts.h" -#include "base/threading/platform_thread.h" #include "base/time/time.h" #include "build/build_config.h" #include "testing/gmock/include/gmock/gmock.h" @@ -189,31 +188,6 @@ }; #endif // !defined(OS_IOS) -class CheckThreadPriority : public testing::EmptyTestEventListener { - public: - CheckThreadPriority(bool check_thread_priority_at_test_end) - : check_thread_priority_at_test_end_(check_thread_priority_at_test_end) { - CHECK_EQ(base::PlatformThread::GetCurrentThreadPriority(), - base::ThreadPriority::NORMAL); - } - - void OnTestStart(const testing::TestInfo& test) override { - EXPECT_EQ(base::PlatformThread::GetCurrentThreadPriority(), - base::ThreadPriority::NORMAL); - } - void OnTestEnd(const testing::TestInfo& test) override { - if (check_thread_priority_at_test_end_) { - EXPECT_EQ(base::PlatformThread::GetCurrentThreadPriority(), - base::ThreadPriority::NORMAL); - } - } - - private: - const bool check_thread_priority_at_test_end_; - - DISALLOW_COPY_AND_ASSIGN(CheckThreadPriority); -}; - const std::string& GetProfileName() { static const NoDestructor<std::string> profile_name([]() { const CommandLine& command_line = *CommandLine::ForCurrentProcess(); @@ -407,11 +381,6 @@ check_for_process_priority_ = false; } -void TestSuite::DisableCheckForThreadPriorityAtTestEnd() { - DCHECK(!is_initialized_); - check_for_thread_priority_at_test_end_ = false; -} - void TestSuite::UnitTestAssertHandler(const char* file, int line, const StringPiece summary, @@ -602,8 +571,6 @@ if (check_for_process_priority_) listeners.Append(new CheckProcessPriority); #endif - listeners.Append( - new CheckThreadPriority(check_for_thread_priority_at_test_end_)); AddTestLauncherResultPrinter();
diff --git a/base/test/test_suite.h b/base/test/test_suite.h index 0565c5e..6e1e750 100644 --- a/base/test/test_suite.h +++ b/base/test/test_suite.h
@@ -46,10 +46,6 @@ // Disables checks for process priority. Most tests should not use this. void DisableCheckForProcessPriority(); - // Disables checks for thread priority at test end. This may be used for tests - // that each run in their own process. - void DisableCheckForThreadPriorityAtTestEnd(); - // Disables checks for certain global objects being leaked across tests. void DisableCheckForLeakedGlobals(); @@ -98,7 +94,6 @@ bool check_for_leaked_globals_ = true; bool check_for_process_priority_ = true; - bool check_for_thread_priority_at_test_end_ = true; bool is_initialized_ = false;
diff --git a/base/unguessable_token.h b/base/unguessable_token.h index 222177a9..895dbc46 100644 --- a/base/unguessable_token.h +++ b/base/unguessable_token.h
@@ -20,26 +20,30 @@ struct UnguessableTokenHash; // UnguessableToken is, like Token, a randomly chosen 128-bit value. Unlike -// Token however, a new UnguessableToken must always be generated at runtime -// from a cryptographically strong random source (or copied or serialized and +// Token, a new UnguessableToken is always generated at runtime from a +// cryptographically strong random source (or copied or serialized and // deserialized from another such UnguessableToken). It can be used as part of a // larger aggregate type, or as an ID in and of itself. // -// UnguessableToken can be used to implement "Capability-Based Security". -// In other words, UnguessableToken can be used when the resource associated -// with the ID needs to be protected against manipulation by other untrusted -// agents in the system, and there is no other convenient way to verify the -// authority of the agent to do so (because the resource is part of a table -// shared across processes, for instance). In such a scheme, knowledge of the -// token value in and of itself is sufficient proof of authority to carry out -// an operation against the associated resource. +// An UnguessableToken is a strong *bearer token*. Bearer tokens are like HTTP +// cookies: if a caller has the token, the callee thereby considers the caller +// authorized to request the operation the callee performs. +// +// UnguessableToken can be used when the resource associated with the ID needs +// to be protected against manipulation by other untrusted agents in the system, +// and there is no other convenient way to verify the authority of the agent to +// do so (because the resource is part of a table shared across processes, for +// instance). In such a scheme, knowledge of the token value in and of itself is +// sufficient proof of authority to carry out an operation on the associated +// resource. // // Use Create() for creating new UnguessableTokens. // // NOTE: It is illegal to send empty UnguessableTokens across processes, and -// sending/receiving empty tokens should be treated as a security issue. -// If there is a valid scenario for sending "no token" across processes, -// base::Optional should be used instead of an empty token. +// sending/receiving empty tokens should be treated as a security issue. If +// there is a valid scenario for sending "no token" across processes, use +// base::Optional instead of an empty token. + class BASE_EXPORT UnguessableToken { public: // Create a unique UnguessableToken.
diff --git a/cc/benchmarks/invalidation_benchmark.cc b/cc/benchmarks/invalidation_benchmark.cc index 8df14b6..39309d3a 100644 --- a/cc/benchmarks/invalidation_benchmark.cc +++ b/cc/benchmarks/invalidation_benchmark.cc
@@ -63,9 +63,8 @@ InvalidationBenchmark::~InvalidationBenchmark() = default; void InvalidationBenchmark::DidUpdateLayers(LayerTreeHost* layer_tree_host) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - layer_tree_host, - [this](Layer* layer) { layer->RunMicroBenchmark(this); }); + for (auto* layer : *layer_tree_host) + layer->RunMicroBenchmark(this); } void InvalidationBenchmark::RunOnLayer(PictureLayer* layer) {
diff --git a/cc/benchmarks/rasterize_and_record_benchmark.cc b/cc/benchmarks/rasterize_and_record_benchmark.cc index 61bc655..2fa6600 100644 --- a/cc/benchmarks/rasterize_and_record_benchmark.cc +++ b/cc/benchmarks/rasterize_and_record_benchmark.cc
@@ -86,9 +86,8 @@ void RasterizeAndRecordBenchmark::DidUpdateLayers( LayerTreeHost* layer_tree_host) { layer_tree_host_ = layer_tree_host; - LayerTreeHostCommon::CallFunctionForEveryLayer( - layer_tree_host_, - [this](Layer* layer) { layer->RunMicroBenchmark(this); }); + for (auto* layer : *layer_tree_host) + layer->RunMicroBenchmark(this); DCHECK(!results_.get()); results_ = base::WrapUnique(new base::DictionaryValue);
diff --git a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc index 93b5d5d..89946a0 100644 --- a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc +++ b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
@@ -146,11 +146,10 @@ void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit( LayerTreeHostImpl* host) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - host->active_tree(), [this](LayerImpl* layer) { - rasterize_results_.total_layers++; - layer->RunMicroBenchmark(this); - }); + for (auto* layer : *host->active_tree()) { + rasterize_results_.total_layers++; + layer->RunMicroBenchmark(this); + } std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue()); result->SetDouble("rasterize_time_ms",
diff --git a/cc/layers/effect_tree_layer_list_iterator.cc b/cc/layers/effect_tree_layer_list_iterator.cc index dad09611..9270f7d 100644 --- a/cc/layers/effect_tree_layer_list_iterator.cc +++ b/cc/layers/effect_tree_layer_list_iterator.cc
@@ -9,17 +9,16 @@ EffectTreeLayerListIterator::EffectTreeLayerListIterator( LayerTreeImpl* layer_tree_impl) : state_(EffectTreeLayerListIterator::State::END), + layer_list_iterator_(layer_tree_impl->rbegin()), current_effect_tree_index_(EffectTree::kInvalidNodeId), next_effect_tree_index_(EffectTree::kInvalidNodeId), lowest_common_effect_tree_ancestor_index_(EffectTree::kInvalidNodeId), layer_tree_impl_(layer_tree_impl), effect_tree_(&layer_tree_impl->property_trees()->effect_tree) { - layer_list_iterator_ = layer_tree_impl->rbegin(); - // Find the front-most drawn layer. while (layer_list_iterator_ != layer_tree_impl->rend() && !(*layer_list_iterator_)->contributes_to_drawn_render_surface()) { - layer_list_iterator_++; + ++layer_list_iterator_; } // If there are no drawn layers, start at the root render surface, if it @@ -46,10 +45,10 @@ switch (state_) { case State::LAYER: // Find the next drawn layer. - layer_list_iterator_++; + ++layer_list_iterator_; while (layer_list_iterator_ != layer_tree_impl_->rend() && !(*layer_list_iterator_)->contributes_to_drawn_render_surface()) { - layer_list_iterator_++; + ++layer_list_iterator_; } if (layer_list_iterator_ == layer_tree_impl_->rend()) { next_effect_tree_index_ = EffectTree::kInvalidNodeId;
diff --git a/cc/layers/effect_tree_layer_list_iterator.h b/cc/layers/effect_tree_layer_list_iterator.h index c9991638..577e14b5 100644 --- a/cc/layers/effect_tree_layer_list_iterator.h +++ b/cc/layers/effect_tree_layer_list_iterator.h
@@ -99,7 +99,7 @@ // When in state LAYER, this is the layer that's currently being visited. // Otherwise, this is the layer that will be visited the next time we're in // state LAYER. - LayerImplList::reverse_iterator layer_list_iterator_; + LayerTreeImpl::const_reverse_iterator layer_list_iterator_; // When in state LAYER, this is the render target effect tree index for the // currently visited layer. Otherwise, this is the the effect tree index of
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 5e5374e..f92363d 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -62,7 +62,6 @@ SkColor background_color; FilterOperations filters[2]; base::Optional<gfx::RRectF> backdrop_filter_bounds; - ElementId backdrop_mask_element_id; gfx::PointF filters_origin; float backdrop_filter_quality; gfx::RoundedCornersF corner_radii; @@ -164,10 +163,6 @@ // Remove the parent reference from all children and dependents. RemoveAllChildren(); - if (inputs_.mask_layer.get()) { - DCHECK_EQ(this, inputs_.mask_layer->parent()); - inputs_.mask_layer->RemoveFromParent(); - } } void Layer::SetLayerTreeHost(LayerTreeHost* host) { @@ -212,9 +207,6 @@ for (size_t i = 0; i < inputs_.children.size(); ++i) inputs_.children[i]->SetLayerTreeHost(host); - if (inputs_.mask_layer.get()) - inputs_.mask_layer->SetLayerTreeHost(host); - if (host && !host->IsUsingLayerLists() && host->mutator_host()->IsElementAnimating(element_id())) { host->SetNeedsCommit(); @@ -288,6 +280,11 @@ child->SetSubtreePropertyChanged(); index = std::min(index, inputs_.children.size()); + if (inputs_.mask_layer && index && index == inputs_.children.size()) { + // Ensure that the mask layer is always the last child. + DCHECK_EQ(inputs_.mask_layer, inputs_.children.back().get()); + index--; + } inputs_.children.insert(inputs_.children.begin() + index, child); SetNeedsFullTreeSync(); } @@ -295,16 +292,12 @@ void Layer::RemoveFromParent() { DCHECK(IsPropertyChangeAllowed()); if (parent_) - parent_->RemoveChildOrDependent(this); + parent_->RemoveChild(this); } -void Layer::RemoveChildOrDependent(Layer* child) { - if (inputs_.mask_layer.get() == child) { - inputs_.mask_layer->SetParent(nullptr); +void Layer::RemoveChild(Layer* child) { + if (child == inputs_.mask_layer) inputs_.mask_layer = nullptr; - SetNeedsFullTreeSync(); - return; - } for (auto iter = inputs_.children.begin(); iter != inputs_.children.end(); ++iter) { @@ -377,7 +370,7 @@ // Rounded corner clipping, bounds clipping and mask clipping can result in // new areas of subtrees being exposed on a bounds change. Ensure the damaged // areas are updated. - if (masks_to_bounds() || inputs_.mask_layer.get() || HasRoundedCorner()) { + if (masks_to_bounds() || IsMaskedByChild() || HasRoundedCorner()) { SetSubtreePropertyChanged(); SetPropertyTreesNeedRebuild(); } @@ -588,7 +581,8 @@ // Layer needs to clip to its bounds as well apply a clip rect. Intersect the // two to get the effective clip. - if (masks_to_bounds() || mask_layer() || filters().HasFilterThatMovesPixels()) + if (masks_to_bounds() || IsMaskedByChild() || + filters().HasFilterThatMovesPixels()) return gfx::IntersectRects(layer_bounds, clip_rect_f); // Clip rect is the only clip effecting the layer. @@ -597,25 +591,27 @@ void Layer::SetMaskLayer(scoped_refptr<PictureLayer> mask_layer) { DCHECK(IsPropertyChangeAllowed()); - if (inputs_.mask_layer.get() == mask_layer) - return; DCHECK(!layer_tree_host_ || !layer_tree_host_->IsUsingLayerLists()); - if (inputs_.mask_layer.get()) { + if (inputs_.mask_layer == mask_layer) + return; + if (inputs_.mask_layer) { DCHECK_EQ(this, inputs_.mask_layer->parent()); inputs_.mask_layer->RemoveFromParent(); } - inputs_.mask_layer = mask_layer; - if (inputs_.mask_layer.get()) { + // Clear mask_layer first and set it later because InsertChild() checks it to + // ensure the mask layer is the last child. + inputs_.mask_layer = nullptr; + if (mask_layer) { // The mask layer should not have any children. - DCHECK(inputs_.mask_layer->children().empty()); + DCHECK(mask_layer->children().empty()); - inputs_.mask_layer->RemoveFromParent(); - DCHECK(!inputs_.mask_layer->parent()); - inputs_.mask_layer->SetParent(this); - inputs_.mask_layer->set_is_mask(); + mask_layer->SetIsDrawable(true); + mask_layer->SetBlendMode(SkBlendMode::kDstIn); + mask_layer->SetIsMask(true); + AddChild(mask_layer); } + inputs_.mask_layer = mask_layer.get(); SetSubtreePropertyChanged(); - SetNeedsFullTreeSync(); } void Layer::SetFilters(const FilterOperations& filters) { @@ -1391,6 +1387,9 @@ "Layer::PushPropertiesTo"); DCHECK(layer_tree_host_); + if (inputs_.mask_layer) + DCHECK_EQ(bounds(), inputs_.mask_layer->bounds()); + // The element id should be set first because other setters may // depend on it. Referencing element id on a layer is // deprecated. http://crbug.com/709137 @@ -1469,9 +1468,6 @@ needs_show_scrollbars_ = false; subtree_property_changed_ = false; inputs_.update_rect = gfx::Rect(); - - if (mask_layer()) - DCHECK_EQ(bounds().ToString(), mask_layer()->bounds().ToString()); } void Layer::TakeCopyRequests(
diff --git a/cc/layers/layer.h b/cc/layers/layer.h index 326e50c7..a9aaa92 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h
@@ -203,7 +203,7 @@ // for each matching pixel. // This is for layer tree mode only. void SetMaskLayer(scoped_refptr<PictureLayer> mask_layer); - PictureLayer* mask_layer() { return inputs_.mask_layer.get(); } + bool IsMaskedByChild() const { return !!inputs_.mask_layer; } // Marks the |dirty_rect| as being changed, which will cause a commit and // the compositor to submit a new frame with a damage rect that includes the @@ -295,10 +295,6 @@ return inputs_.backdrop_filter_bounds; } - const ElementId backdrop_mask_element_id() const { - return inputs_.backdrop_mask_element_id; - } - void SetBackdropFilterQuality(const float quality); float backdrop_filter_quality() const { return inputs_.backdrop_filter_quality; @@ -837,7 +833,7 @@ void SetParent(Layer* layer); // This should only be called from RemoveFromParent(). - void RemoveChildOrDependent(Layer* child); + void RemoveChild(Layer* child); // When we detach or attach layer to new LayerTreeHost, all property trees' // indices becomes invalid. @@ -867,7 +863,9 @@ gfx::Size bounds; gfx::Rect clip_rect; - scoped_refptr<PictureLayer> mask_layer; + // If not null, points to one of child layers which is set as mask layer + // by SetMaskLayer(). + Layer* mask_layer; int layer_id; @@ -925,7 +923,6 @@ FilterOperations filters; FilterOperations backdrop_filters; base::Optional<gfx::RRectF> backdrop_filter_bounds; - ElementId backdrop_mask_element_id; gfx::PointF filters_origin; float backdrop_filter_quality;
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index 89c23a3..0f324e7 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc
@@ -288,6 +288,7 @@ EXPECT_SET_NEEDS_COMMIT(1, top->SetBounds(arbitrary_size)); EXPECT_SET_NEEDS_COMMIT(0, mask_layer1->SetBounds(arbitrary_size)); EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1); + EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetMaskLayer(mask_layer1)); // Set up the impl layers after the full tree is constructed, including the @@ -497,6 +498,69 @@ EXPECT_SET_NEEDS_FULL_TREE_SYNC(AtLeast(1), child->RemoveFromParent()); } +TEST_F(LayerTest, SetMaskLayer) { + scoped_refptr<Layer> parent = Layer::Create(); + FakeContentLayerClient client; + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + + parent->SetMaskLayer(mask); + ASSERT_EQ(1u, parent->children().size()); + EXPECT_EQ(parent.get(), mask->parent()); + EXPECT_EQ(mask.get(), parent->children()[0]); + EXPECT_TRUE(parent->IsMaskedByChild()); + + parent->SetMaskLayer(mask); + ASSERT_EQ(1u, parent->children().size()); + EXPECT_EQ(parent.get(), mask->parent()); + EXPECT_EQ(mask.get(), parent->children()[0]); + EXPECT_TRUE(parent->IsMaskedByChild()); + + scoped_refptr<PictureLayer> mask2 = PictureLayer::Create(&client); + parent->SetMaskLayer(mask2); + EXPECT_FALSE(mask->parent()); + ASSERT_EQ(1u, parent->children().size()); + EXPECT_EQ(parent.get(), mask2->parent()); + EXPECT_EQ(mask2.get(), parent->children()[0]); + EXPECT_TRUE(parent->IsMaskedByChild()); + + parent->SetMaskLayer(nullptr); + EXPECT_EQ(0u, parent->children().size()); + EXPECT_FALSE(mask2->parent()); + EXPECT_FALSE(parent->IsMaskedByChild()); +} + +TEST_F(LayerTest, RemoveMaskLayerFromParent) { + scoped_refptr<Layer> parent = Layer::Create(); + FakeContentLayerClient client; + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + + parent->SetMaskLayer(mask); + mask->RemoveFromParent(); + EXPECT_EQ(0u, parent->children().size()); + EXPECT_FALSE(mask->parent()); + EXPECT_FALSE(parent->IsMaskedByChild()); + + scoped_refptr<PictureLayer> mask2 = PictureLayer::Create(&client); + parent->SetMaskLayer(mask2); + EXPECT_TRUE(parent->IsMaskedByChild()); +} + +TEST_F(LayerTest, AddChildAfterSetMaskLayer) { + scoped_refptr<Layer> parent = Layer::Create(); + FakeContentLayerClient client; + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + parent->SetMaskLayer(mask); + EXPECT_TRUE(parent->IsMaskedByChild()); + + parent->AddChild(Layer::Create()); + EXPECT_EQ(mask.get(), parent->children().back().get()); + EXPECT_TRUE(parent->IsMaskedByChild()); + + parent->InsertChild(Layer::Create(), parent->children().size()); + EXPECT_EQ(mask.get(), parent->children().back().get()); + EXPECT_TRUE(parent->IsMaskedByChild()); +} + TEST_F(LayerTest, AddSameChildTwice) { EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1)); @@ -948,6 +1012,7 @@ EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetHideLayerAndSubtree(true)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetElementId(ElementId(2))); + EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, test_layer->SetMaskLayer(mask_layer1)); // The above tests should not have caused a change to the needs_display flag. @@ -1096,9 +1161,6 @@ for (size_t i = 0; i < layer->children().size(); ++i) AssertLayerTreeHostMatchesForSubtree(layer->children()[i].get(), host); - - if (layer->mask_layer()) - AssertLayerTreeHostMatchesForSubtree(layer->mask_layer(), host); } class LayerLayerTreeHostTest : public testing::Test {}; @@ -1941,9 +2003,5 @@ EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id)); } -TEST(A, B) { - LOG(ERROR) << sizeof(Layer); -} - } // namespace } // namespace cc
diff --git a/cc/layers/mirror_layer_impl.cc b/cc/layers/mirror_layer_impl.cc index 80363cd0..7a916bf 100644 --- a/cc/layers/mirror_layer_impl.cc +++ b/cc/layers/mirror_layer_impl.cc
@@ -55,8 +55,7 @@ auto* quad = render_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>(); quad->SetNew(shared_quad_state, content_rect, unoccluded_content_rect, mirrored_layer_id_, mask_resource_id, mask_uv_rect, - mask_texture_size, /*mask_applies_to_backdrop=*/false, - mirrored_effect_node->surface_contents_scale, + mask_texture_size, mirrored_effect_node->surface_contents_scale, mirrored_effect_node->filters_origin, gfx::RectF(gfx::Rect(content_rect.size())), !layer_tree_impl()->settings().enable_edge_anti_aliasing, 0.f);
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc index 7206fd0..5f08cf3 100644 --- a/cc/layers/picture_layer.cc +++ b/cc/layers/picture_layer.cc
@@ -53,11 +53,6 @@ PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer); - // This is before Layer::PushPropertiesTo() because PictureLayerImpl requires - // that is_mask flag can change only when the layer is just created before - // any property tree state is assigned. - layer_impl->SetIsMask(is_mask()); - Layer::PushPropertiesTo(base_layer); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "PictureLayer::PushPropertiesTo"); @@ -69,6 +64,9 @@ layer_impl->set_gpu_raster_max_texture_size( layer_tree_host()->device_viewport_rect().size()); + layer_impl->SetIsMask(is_mask()); + layer_impl->SetIsBackdropFilterMask(is_backdrop_filter_mask()); + // TODO(enne): http://crbug.com/918126 debugging CHECK(this); if (!recording_source_) { @@ -234,6 +232,23 @@ return picture_layer_inputs_.client && Layer::HasDrawableContent(); } +void PictureLayer::SetIsMask(bool is_mask) { + if (picture_layer_inputs_.is_mask == is_mask) + return; + + picture_layer_inputs_.is_mask = is_mask; + SetNeedsCommit(); +} + +void PictureLayer::SetIsBackdropFilterMask(bool is_backdrop_filter_mask) { + if (picture_layer_inputs_.is_backdrop_filter_mask == is_backdrop_filter_mask) + return; + + DCHECK(!is_backdrop_filter_mask || is_mask()); + picture_layer_inputs_.is_backdrop_filter_mask = is_backdrop_filter_mask; + SetNeedsCommit(); +} + void PictureLayer::RunMicroBenchmark(MicroBenchmark* benchmark) { benchmark->RunOnLayer(this); }
diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h index cb9d1bf..0838827 100644 --- a/cc/layers/picture_layer.h +++ b/cc/layers/picture_layer.h
@@ -37,9 +37,16 @@ return picture_layer_inputs_.transformed_rasterization_allowed; } - void set_is_mask() { picture_layer_inputs_.is_mask = true; } + // TODO(crbug.com/1003414): Remove this flag when we tile mask layers (except + // for backdrop filter masks) normally. + void SetIsMask(bool is_mask); bool is_mask() const { return picture_layer_inputs_.is_mask; } + void SetIsBackdropFilterMask(bool is_backdrop_filter_mask); + bool is_backdrop_filter_mask() const { + return picture_layer_inputs_.is_backdrop_filter_mask; + } + // Layer interface. std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void SetLayerTreeHost(LayerTreeHost* host) override; @@ -71,6 +78,7 @@ bool nearest_neighbor = false; bool transformed_rasterization_allowed = false; bool is_mask = false; + bool is_backdrop_filter_mask = false; gfx::Rect recorded_viewport; scoped_refptr<DisplayItemList> display_list; size_t painter_reported_memory_usage = 0;
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 7483549..0bb56d2 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -92,6 +92,7 @@ raster_contents_scale_(0.f), low_res_raster_contents_scale_(0.f), is_mask_(false), + is_backdrop_filter_mask_(false), was_screen_space_transform_animating_(false), only_used_low_res_last_append_quads_(false), nearest_neighbor_(false), @@ -125,15 +126,6 @@ UnregisterAnimatedImages(); } -void PictureLayerImpl::SetIsMask(bool is_mask) { - if (is_mask_ == is_mask) - return; - - // This flag can't be set after property trees have been updated. - DCHECK_EQ(effect_tree_index(), EffectTree::kInvalidNodeId); - is_mask_ = is_mask; -} - const char* PictureLayerImpl::LayerTypeAsString() const { return "cc::PictureLayerImpl"; } @@ -146,10 +138,6 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer); - // This is before LayerImpl::PushPropertiesTo() because PictureLayerImpl - // requires that is_mask flag can change only when the layer is just created - // before any property tree state is assigned. - layer_impl->SetIsMask(is_mask()); LayerImpl::PushPropertiesTo(base_layer); @@ -165,6 +153,8 @@ layer_impl->SetNearestNeighbor(nearest_neighbor_); layer_impl->SetUseTransformedRasterization(use_transformed_rasterization_); + layer_impl->SetIsMask(is_mask_); + layer_impl->SetIsBackdropFilterMask(is_backdrop_filter_mask_); // Solid color layers have no tilings. DCHECK(!raster_source_->IsSolidColor() || tilings_->num_tilings() == 0); @@ -197,6 +187,13 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass, AppendQuadsData* append_quads_data) { + // RenderSurfaceImpl::AppendQuads sets mask properties in the DrawQuad for + // the masked surface, which will apply to both the backdrop filter and the + // contents of the masked surface, so we should not quad of the mask layer + // in DstIn blend mode. + if (is_backdrop_filter_mask_) + return; + // The bounds and the pile size may differ if the pile wasn't updated (ie. // PictureLayer::Update didn't happen). In that case the pile will be empty. DCHECK(raster_source_->GetSize().IsEmpty() ||
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h index f76ff2cf..aafc8dd6 100644 --- a/cc/layers/picture_layer_impl.h +++ b/cc/layers/picture_layer_impl.h
@@ -43,9 +43,17 @@ PictureLayerImpl& operator=(const PictureLayerImpl&) = delete; - void SetIsMask(bool is_mask); + // TODO(crbug.com/1003414): Remove this flag when we tile mask layers (except + // for backdrop filter masks) normally. + void SetIsMask(bool is_mask) { is_mask_ = is_mask; } bool is_mask() const { return is_mask_; } + void SetIsBackdropFilterMask(bool is_backdrop_filter_mask) { + DCHECK(!is_backdrop_filter_mask || is_mask_); + is_backdrop_filter_mask_ = is_backdrop_filter_mask; + } + bool is_backdrop_filter_mask() const { return is_backdrop_filter_mask_; } + // LayerImpl overrides. const char* LayerTypeAsString() const override; std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; @@ -222,6 +230,7 @@ float low_res_raster_contents_scale_; bool is_mask_ : 1; + bool is_backdrop_filter_mask_ : 1; bool was_screen_space_transform_animating_ : 1; bool only_used_low_res_last_append_quads_ : 1;
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 8ea26c90..4afc2f7 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -1159,10 +1159,9 @@ // Mask layers dont create low res since they always fit on one tile. CreateEffectNode(pending_layer()); - auto* mask = AddMaskLayer<FakePictureLayerImpl>( - host_impl()->pending_tree(), pending_layer(), pending_raster_source); - mask->SetBounds(layer_bounds); - mask->SetDrawsContent(true); + auto* mask = AddLayer<FakePictureLayerImpl>(host_impl()->pending_tree(), + pending_raster_source); + SetupMaskProperties(pending_layer(), mask); UpdateDrawProperties(host_impl()->pending_tree()); @@ -1188,10 +1187,9 @@ SetupPendingTree(valid_raster_source); CreateEffectNode(pending_layer()); - auto* pending_mask = AddMaskLayer<FakePictureLayerImpl>( - host_impl()->pending_tree(), pending_layer(), valid_raster_source); - pending_mask->SetBounds(layer_bounds); - pending_mask->SetDrawsContent(true); + auto* pending_mask = AddLayer<FakePictureLayerImpl>( + host_impl()->pending_tree(), valid_raster_source); + SetupMaskProperties(pending_layer(), pending_mask); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); UpdateDrawProperties(host_impl()->pending_tree()); @@ -1315,10 +1313,9 @@ SetupPendingTree(valid_raster_source); CreateEffectNode(pending_layer()); - auto* pending_mask = AddMaskLayer<FakePictureLayerImpl>( - host_impl()->pending_tree(), pending_layer(), valid_raster_source); - pending_mask->SetBounds(layer_bounds); - pending_mask->SetDrawsContent(true); + auto* pending_mask = AddLayer<FakePictureLayerImpl>( + host_impl()->pending_tree(), valid_raster_source); + SetupMaskProperties(pending_layer(), pending_mask); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); UpdateDrawProperties(host_impl()->pending_tree());
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc index 0e81947..464eaf40 100644 --- a/cc/layers/render_surface_impl.cc +++ b/cc/layers/render_surface_impl.cc
@@ -121,11 +121,6 @@ layer_tree_impl_ ? layer_tree_impl_->device_scale_factor() : 1); } -LayerImpl* RenderSurfaceImpl::MaskLayer() { - int mask_layer_id = OwningEffectNode()->mask_layer_id; - return layer_tree_impl_->LayerById(mask_layer_id); -} - LayerImpl* RenderSurfaceImpl::BackdropMaskLayer() const { ElementId mask_element_id = OwningEffectNode()->backdrop_mask_element_id; if (!mask_element_id) @@ -133,10 +128,6 @@ return layer_tree_impl_->LayerByElementId(mask_element_id); } -bool RenderSurfaceImpl::HasMask() const { - return OwningEffectNode()->mask_layer_id != Layer::INVALID_ID; -} - bool RenderSurfaceImpl::HasMaskingContributingSurface() const { return OwningEffectNode()->has_masking_child; } @@ -423,14 +414,7 @@ GetDebugBorderWidth()); } - DCHECK(!(MaskLayer() && BackdropMaskLayer())) - << "Can't support both a mask_layer and a backdrop_mask_layer"; - bool mask_applies_to_backdrop = BackdropMaskLayer(); - PictureLayerImpl* mask_layer = - mask_applies_to_backdrop - ? static_cast<PictureLayerImpl*>(BackdropMaskLayer()) - : static_cast<PictureLayerImpl*>(MaskLayer()); - + LayerImpl* mask_layer = BackdropMaskLayer(); viz::ResourceId mask_resource_id = 0; gfx::Size mask_texture_size; gfx::RectF mask_uv_rect; @@ -455,10 +439,14 @@ gfx::SizeF unclipped_mask_target_size = gfx::ScaleSize(gfx::SizeF(mask_layer->bounds()), surface_contents_scale.x(), surface_contents_scale.y()); + gfx::Vector2dF mask_offset = gfx::ScaleVector2d( + mask_layer->offset_to_transform_parent(), surface_contents_scale.x(), + surface_contents_scale.y()); // Convert content_rect from target space to normalized mask UV space. // Where |unclipped_mask_target_size| maps to |mask_uv_size|. mask_uv_rect = gfx::ScaleRect( - gfx::RectF(content_rect()), + // Translate content_rect into mask resource's space. + gfx::RectF(content_rect()) - mask_offset, mask_uv_size.width() / unclipped_mask_target_size.width(), mask_uv_size.height() / unclipped_mask_target_size.height()); } @@ -467,8 +455,7 @@ auto* quad = render_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>(); quad->SetNew(shared_quad_state, content_rect(), unoccluded_content_rect, id(), mask_resource_id, mask_uv_rect, mask_texture_size, - mask_applies_to_backdrop, surface_contents_scale, - FiltersOrigin(), tex_coord_rect, + surface_contents_scale, FiltersOrigin(), tex_coord_rect, !layer_tree_impl_->settings().enable_edge_anti_aliasing, OwningEffectNode()->backdrop_filter_quality); }
diff --git a/cc/layers/render_surface_impl.h b/cc/layers/render_surface_impl.h index 38fcaea8..545c840 100644 --- a/cc/layers/render_surface_impl.h +++ b/cc/layers/render_surface_impl.h
@@ -154,8 +154,6 @@ uint64_t id() const { return stable_id_; } - LayerImpl* MaskLayer(); - bool HasMask() const; bool HasMaskingContributingSurface() const; const FilterOperations& Filters() const;
diff --git a/cc/layers/render_surface_impl_unittest.cc b/cc/layers/render_surface_impl_unittest.cc index 0e69bc4d..8bcdb89 100644 --- a/cc/layers/render_surface_impl_unittest.cc +++ b/cc/layers/render_surface_impl_unittest.cc
@@ -87,12 +87,10 @@ CreateTransformNode(surface).local = scale; CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; - auto* mask_layer = - impl.AddMaskLayer<FakeMaskLayerImpl>(surface, raster_source); + auto* mask_layer = impl.AddLayer<FakeMaskLayerImpl>(raster_source); mask_layer->set_resource_size( gfx::ScaleToCeiledSize(layer_size, scale_factor)); - mask_layer->SetDrawsContent(true); - mask_layer->SetBounds(layer_size); + SetupMaskProperties(surface, mask_layer); auto* child = impl.AddLayer<LayerImpl>(); child->SetDrawsContent(true); @@ -118,8 +116,10 @@ DCHECK(render_pass->quad_list.front()); const viz::RenderPassDrawQuad* quad = viz::RenderPassDrawQuad::MaterialCast(render_pass->quad_list.front()); - EXPECT_EQ(gfx::RectF(0, 0, 1, 1), quad->mask_uv_rect); + // Mask layers don't use quad's mask functionality. + EXPECT_EQ(gfx::RectF(), quad->mask_uv_rect); EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), quad->filters_scale); + EXPECT_EQ(0u, quad->mask_resource_id()); } TEST(RenderSurfaceLayerImplTest, ResourcelessAppendQuadsSkipMask) {
diff --git a/cc/layers/render_surface_unittest.cc b/cc/layers/render_surface_unittest.cc index 3544436..723d930 100644 --- a/cc/layers/render_surface_unittest.cc +++ b/cc/layers/render_surface_unittest.cc
@@ -221,16 +221,15 @@ CopyProperties(root, layer); CreateEffectNode(layer); - auto* mask_layer = - impl.AddMaskLayer<FakePictureLayerImplForRenderSurfaceTest>(layer); + auto* mask_layer = impl.AddLayer<FakePictureLayerImplForRenderSurfaceTest>(); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(mask_layer->bounds())); mask_layer->SetRasterSourceOnActive(raster_source, Region()); - mask_layer->SetDrawsContent(true); std::vector<gfx::Rect> quad_rects; quad_rects.push_back(gfx::Rect(0, 0, 100, 100)); quad_rects.push_back(gfx::Rect(100, 0, 100, 100)); mask_layer->SetQuadRectsForTesting(quad_rects); + SetupMaskProperties(layer, mask_layer); UpdateDrawProperties(impl.host_impl()->active_tree());
diff --git a/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc b/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc index 48ec0281..b80ed04 100644 --- a/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc +++ b/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc
@@ -289,15 +289,15 @@ quad3_root_1->SetNew(shared_quad_state3_root, /*rect=*/rect3_root, /*visible_rect=*/rect3_root, /*render_pass_id=*/3, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); auto* quad3_root_2 = pass3_root->quad_list.AllocateAndConstruct<viz::RenderPassDrawQuad>(); quad3_root_2->SetNew(shared_quad_state3_root, /*rect=*/rect3_root, /*visible_rect=*/rect3_root, /*render_pass_id=*/4, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); pass_list.push_back(std::move(pass3_root)); SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false); @@ -393,15 +393,15 @@ quad2_root_1->SetNew(shared_quad_state2_root, /*rect=*/rect2_root, /*visible_rect=*/rect2_root, /*render_pass_id=*/2, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); auto* quad2_root_2 = pass2_root->quad_list.AllocateAndConstruct<viz::RenderPassDrawQuad>(); quad2_root_2->SetNew(shared_quad_state2_root, /*rect=*/rect2_root, /*visible_rect=*/rect2_root, /*render_pass_id=*/3, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); pass_list.push_back(std::move(pass2_root)); SendRenderPassList(&pass_list, /*hit_test_data_changed=*/true);
diff --git a/cc/test/layer_test_common.h b/cc/test/layer_test_common.h index 38ca9ec9..a538cc01 100644 --- a/cc/test/layer_test_common.h +++ b/cc/test/layer_test_common.h
@@ -85,27 +85,6 @@ std::forward<Args>(args)...); } - template <typename T, typename... Args> - T* AddMaskLayer(LayerImpl* origin, Args&&... args) { - static_assert(std::is_base_of<PictureLayerImpl, T>::value, ""); - std::unique_ptr<T> layer = - T::Create(host_impl()->active_tree(), layer_impl_id_++, - std::forward<Args>(args)...); - layer->SetBounds(origin->bounds()); - layer->SetIsMask(true); - T* ptr = layer.get(); - host_impl()->active_tree()->AddMaskLayer(std::move(layer)); - if (host_impl()->active_tree()->settings().use_layer_lists) { - auto* origin_effect = GetEffectNode(origin); - origin_effect->render_surface_reason = RenderSurfaceReason::kMask; - origin_effect->is_masked = true; - origin_effect->mask_layer_id = ptr->id(); - ptr->SetOffsetToTransformParent(origin->offset_to_transform_parent()); - CopyProperties(origin, ptr); - } - return ptr; - } - void CalcDrawProps(const gfx::Size& viewport_size); void AppendQuadsWithOcclusion(LayerImpl* layer_impl, const gfx::Rect& occluded);
diff --git a/cc/test/property_tree_test_utils.cc b/cc/test/property_tree_test_utils.cc index 0d5159a..293cfb75 100644 --- a/cc/test/property_tree_test_utils.cc +++ b/cc/test/property_tree_test_utils.cc
@@ -146,6 +146,28 @@ return *node; } +template <typename LayerType, typename MaskLayerType> +void SetupMaskPropertiesInternal(LayerType* masked_layer, + MaskLayerType* mask_layer) { + mask_layer->SetIsMask(true); + if (!GetEffectNode(masked_layer)->backdrop_filters.IsEmpty()) + mask_layer->SetIsBackdropFilterMask(true); + mask_layer->SetBounds(masked_layer->bounds()); + auto* masked_effect = GetEffectNode(masked_layer); + masked_effect->render_surface_reason = RenderSurfaceReason::kMask; + masked_effect->has_masking_child = true; + if (!masked_effect->backdrop_filters.IsEmpty()) { + if (!mask_layer->element_id()) + mask_layer->SetElementId(LayerIdToElementIdForTesting(mask_layer->id())); + masked_effect->backdrop_mask_element_id = mask_layer->element_id(); + } + + CopyProperties(masked_layer, mask_layer); + mask_layer->SetOffsetToTransformParent( + masked_layer->offset_to_transform_parent()); + CreateEffectNode(mask_layer).blend_mode = SkBlendMode::kDstIn; +} + template <typename LayerType> void SetScrollOffsetInternal(LayerType* layer, const gfx::ScrollOffset& scroll_offset) { @@ -253,6 +275,17 @@ return CreateScrollNodeInternal(layer, parent_id); } +void SetupMaskProperties(Layer* masked_layer, PictureLayer* mask_layer) { + mask_layer->SetIsDrawable(true); + SetupMaskPropertiesInternal(masked_layer, mask_layer); +} + +void SetupMaskProperties(LayerImpl* masked_layer, + PictureLayerImpl* mask_layer) { + mask_layer->SetDrawsContent(true); + SetupMaskPropertiesInternal(masked_layer, mask_layer); +} + void SetScrollOffset(Layer* layer, const gfx::ScrollOffset& scroll_offset) { layer->SetScrollOffset(scroll_offset); SetScrollOffsetInternal(layer, scroll_offset);
diff --git a/cc/test/property_tree_test_utils.h b/cc/test/property_tree_test_utils.h index 295d5c3..1f803c4 100644 --- a/cc/test/property_tree_test_utils.h +++ b/cc/test/property_tree_test_utils.h
@@ -17,6 +17,8 @@ class Layer; class LayerImpl; +class PictureLayer; +class PictureLayerImpl; // Sets up properties that apply to the root layer. void SetupRootProperties(Layer* root); @@ -50,6 +52,9 @@ ScrollNode& CreateScrollNode(LayerImpl*, int parent_id = ScrollTree::kInvalidNodeId); +void SetupMaskProperties(LayerImpl* masked_layer, PictureLayerImpl* mask_layer); +void SetupMaskProperties(Layer* masked_layer, PictureLayer* mask_layer); + template <typename LayerType> TransformNode* GetTransformNode(const LayerType* layer) { return GetPropertyTrees(layer)->transform_tree.Node(
diff --git a/cc/test/render_pass_test_utils.cc b/cc/test/render_pass_test_utils.cc index 6ff1bf3..924bc79a 100644 --- a/cc/test/render_pass_test_utils.cc +++ b/cc/test/render_pass_test_utils.cc
@@ -117,8 +117,8 @@ SkBlendMode::kSrcOver, 0); auto* quad = to_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>(); quad->SetNew(shared_state, output_rect, output_rect, contributing_pass->id, 0, - gfx::RectF(), gfx::Size(), false, gfx::Vector2dF(), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(), + gfx::RectF(), false, 1.0f); return quad; } @@ -136,7 +136,7 @@ gfx::Size arbitrary_nonzero_size(1, 1); quad->SetNew(shared_state, output_rect, output_rect, contributing_pass->id, mask_resource_id, gfx::RectF(output_rect), - arbitrary_nonzero_size, false, gfx::Vector2dF(), gfx::PointF(), + arbitrary_nonzero_size, gfx::Vector2dF(), gfx::PointF(), gfx::RectF(), false, 1.0f); } @@ -188,8 +188,8 @@ to_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>(); render_pass_quad->SetNew(shared_state, rect, visible_rect, child_pass_id, resource5, gfx::RectF(rect), gfx::Size(73, 26), - false, gfx::Vector2dF(), gfx::PointF(), - gfx::RectF(), false, 1.0f); + gfx::Vector2dF(), gfx::PointF(), gfx::RectF(), + false, 1.0f); } auto* solid_color_quad = @@ -364,8 +364,8 @@ to_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>(); render_pass_quad->SetNew(shared_state, rect, visible_rect, child_pass_id, mapped_resource5, gfx::RectF(rect), - gfx::Size(73, 26), false, gfx::Vector2dF(), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Size(73, 26), gfx::Vector2dF(), gfx::PointF(), + gfx::RectF(), false, 1.0f); } viz::SolidColorDrawQuad* solid_color_quad =
diff --git a/cc/test/test_layer_tree_host_base.h b/cc/test/test_layer_tree_host_base.h index 2e8e086..3e76715 100644 --- a/cc/test/test_layer_tree_host_base.h +++ b/cc/test/test_layer_tree_host_base.h
@@ -72,25 +72,6 @@ return result; } - template <typename T, typename... Args> - T* AddMaskLayer(LayerTreeImpl* layer_tree_impl, - LayerImpl* masked_layer, - Args&&... args) { - static_assert(std::is_base_of<PictureLayerImpl, T>::value, ""); - std::unique_ptr<T> mask = T::Create(layer_tree_impl, next_layer_id_++, - std::forward<Args>(args)...); - T* result = mask.get(); - layer_tree_impl->AddMaskLayer(std::move(mask)); - result->SetIsMask(true); - CopyProperties(masked_layer, result); - auto* masked_effect = GetEffectNode(masked_layer); - masked_effect->render_surface_reason = RenderSurfaceReason::kMask; - masked_effect->mask_layer_id = result->id(); - masked_effect->is_masked = true; - GetPropertyTrees(masked_layer)->effect_tree.AddMaskLayerId(result->id()); - return result; - } - int root_id() const { return root_id_; } private:
diff --git a/cc/trees/damage_tracker.cc b/cc/trees/damage_tracker.cc index 85e9cd7..5f8642e7 100644 --- a/cc/trees/damage_tracker.cc +++ b/cc/trees/damage_tracker.cc
@@ -170,8 +170,6 @@ // These functions cannot be bypassed with early-exits, even if we know what // the damage will be for this frame, because we need to update the damage // tracker state to correctly track the next frame. - DamageAccumulator damage_from_surface_mask = - TrackDamageFromSurfaceMask(render_surface->MaskLayer()); DamageAccumulator damage_from_leftover_rects = TrackDamageFromLeftoverRects(); // True if any layer is removed. has_damage_from_contributing_content_ |= @@ -185,7 +183,6 @@ } else { // TODO(shawnsingh): can we clamp this damage to the surface's content rect? // (affects performance, but not correctness) - damage_for_this_update_.Union(damage_from_surface_mask); damage_for_this_update_.Union(damage_from_leftover_rects); gfx::Rect damage_rect; @@ -239,24 +236,6 @@ return *it; } -DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromSurfaceMask( - LayerImpl* target_surface_mask_layer) { - DamageAccumulator damage; - - if (!target_surface_mask_layer) - return damage; - - // Currently, if there is any change to the mask, we choose to damage the - // entire surface. This could potentially be optimized later, but it is not - // expected to be a common case. - if (target_surface_mask_layer->LayerPropertyChanged() || - !target_surface_mask_layer->update_rect().IsEmpty()) { - damage.Union(gfx::Rect(target_surface_mask_layer->bounds())); - } - - return damage; -} - void DamageTracker::PrepareForUpdate() { mailboxId_++; damage_for_this_update_ = DamageAccumulator();
diff --git a/cc/trees/damage_tracker.h b/cc/trees/damage_tracker.h index 1851a09..7edeac4 100644 --- a/cc/trees/damage_tracker.h +++ b/cc/trees/damage_tracker.h
@@ -91,8 +91,6 @@ int bottom_ = 0; }; - DamageAccumulator TrackDamageFromSurfaceMask( - LayerImpl* target_surface_mask_layer); DamageAccumulator TrackDamageFromLeftoverRects(); // These helper functions are used only during UpdateDamageTracking().
diff --git a/cc/trees/damage_tracker_unittest.cc b/cc/trees/damage_tracker_unittest.cc index 4914301..b65674e 100644 --- a/cc/trees/damage_tracker_unittest.cc +++ b/cc/trees/damage_tracker_unittest.cc
@@ -10,6 +10,8 @@ #include "cc/layers/layer_impl.h" #include "cc/paint/filter_operation.h" #include "cc/paint/filter_operations.h" +#include "cc/test/fake_picture_layer_impl.h" +#include "cc/test/fake_raster_source.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/layer_test_common.h" #include "cc/trees/layer_tree_host_common.h" @@ -73,6 +75,7 @@ LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(500, 500)); + root->layer_tree_impl()->SetDeviceViewportRect(gfx::Rect(root->bounds())); root->SetDrawsContent(true); SetupRootProperties(root); @@ -99,6 +102,7 @@ LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(500, 500)); + root->layer_tree_impl()->SetDeviceViewportRect(gfx::Rect(root->bounds())); root->SetDrawsContent(true); SetupRootProperties(root); @@ -165,10 +169,13 @@ // 3. resetting all update_rects and property_changed flags for all layers // and surfaces. - ExecuteCalculateDrawProperties(root, device_scale_factor); + root->layer_tree_impl()->SetDeviceScaleFactor(device_scale_factor); + root->layer_tree_impl()->set_needs_update_draw_properties(); + UpdateDrawProperties(root->layer_tree_impl()); - DamageTracker::UpdateDamageTracking(root->layer_tree_impl(), - *render_surface_list_impl()); + DamageTracker::UpdateDamageTracking( + root->layer_tree_impl(), + root->layer_tree_impl()->GetRenderSurfaceList()); root->layer_tree_impl()->ResetAllChangeTracking(); } @@ -1561,7 +1568,12 @@ // Set up the mask layer. CreateEffectNode(child); - LayerImpl* mask_layer = AddMaskLayer<PictureLayerImpl>(child); + auto* mask_layer = AddLayer<FakePictureLayerImpl>(); + SetupMaskProperties(child, mask_layer); + Region empty_invalidation; + mask_layer->UpdateRasterSource( + FakeRasterSource::CreateFilled(child->bounds()), &empty_invalidation, + nullptr, nullptr); // Add opacity and a grand_child so that the render surface persists even // after we remove the mask. @@ -1572,22 +1584,28 @@ grand_child->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f)); EmulateDrawingOneFrame(root); - // CASE 1: the update_rect on a mask layer should damage the entire target - // surface. + EXPECT_EQ(2, GetRenderSurface(root)->num_contributors()); + EXPECT_TRUE(root->contributes_to_drawn_render_surface()); + EXPECT_EQ(3, GetRenderSurface(child)->num_contributors()); + EXPECT_TRUE(child->contributes_to_drawn_render_surface()); + EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(mask_layer)); + EXPECT_TRUE(mask_layer->contributes_to_drawn_render_surface()); + + // CASE 1: the update_rect on a mask layer should damage the rect. ClearDamageForAllSurfaces(root); mask_layer->SetUpdateRect(gfx::Rect(1, 2, 3, 4)); EmulateDrawingOneFrame(root); gfx::Rect child_damage_rect; EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); - EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(1, 2, 3, 4), child_damage_rect); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child) - ->damage_tracker() - ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); // CASE 2: a property change on the mask layer should damage the entire // target surface. @@ -1607,14 +1625,14 @@ EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); - EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(30, 30), child_damage_rect); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child) - ->damage_tracker() - ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); // CASE 3: removing the mask also damages the entire target surface. // @@ -1629,9 +1647,17 @@ // Then test mask removal. ClearDamageForAllSurfaces(root); - GetEffectNode(child)->is_masked = false; - GetEffectNode(child)->mask_layer_id = -1; - child->NoteLayerPropertyChanged(); + auto layers = + root->layer_tree_impl()->DetachLayersKeepingRootLayerForTesting(); + ASSERT_EQ(layers[1].get(), child); + root->layer_tree_impl()->AddLayer(std::move(layers[1])); + ASSERT_EQ(layers[2].get(), mask_layer); + ASSERT_EQ(layers[3].get(), grand_child); + root->layer_tree_impl()->AddLayer(std::move(layers[3])); + CopyProperties(root, child); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(child, grand_child); + EmulateDrawingOneFrame(root); // Sanity check that a render surface still exists. @@ -1639,7 +1665,7 @@ EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); - EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(30, 30), child_damage_rect); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker()
diff --git a/cc/trees/debug_rect_history.cc b/cc/trees/debug_rect_history.cc index 07e6bd17..77917aa 100644 --- a/cc/trees/debug_rect_history.cc +++ b/cc/trees/debug_rect_history.cc
@@ -137,9 +137,8 @@ } void DebugRectHistory::SaveTouchEventHandlerRects(LayerTreeImpl* tree_impl) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - tree_impl, - [this](LayerImpl* layer) { SaveTouchEventHandlerRectsCallback(layer); }); + for (auto* layer : *tree_impl) + SaveTouchEventHandlerRectsCallback(layer); } void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) { @@ -177,9 +176,8 @@ } void DebugRectHistory::SaveScrollEventHandlerRects(LayerTreeImpl* tree_impl) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - tree_impl, - [this](LayerImpl* layer) { SaveScrollEventHandlerRectsCallback(layer); }); + for (auto* layer : *tree_impl) + SaveScrollEventHandlerRectsCallback(layer); } void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) { @@ -193,9 +191,8 @@ } void DebugRectHistory::SaveNonFastScrollableRects(LayerTreeImpl* tree_impl) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - tree_impl, - [this](LayerImpl* layer) { SaveNonFastScrollableRectsCallback(layer); }); + for (auto* layer : *tree_impl) + SaveNonFastScrollableRectsCallback(layer); } void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) {
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc index a2dc10f8..aede10a6c 100644 --- a/cc/trees/draw_property_utils.cc +++ b/cc/trees/draw_property_utils.cc
@@ -798,14 +798,6 @@ if (LayerNeedsUpdate(layer, layer_is_drawn, property_trees)) { update_layer_list->push_back(layer); } - - // Append mask layers to the update layer list. They don't have valid - // visible rects, so need to get added after the above calculation. - if (PictureLayer* mask_layer = layer->mask_layer()) { - // Layers with empty bounds should never be painted, including masks. - if (!mask_layer->bounds().IsEmpty()) - update_layer_list->push_back(mask_layer); - } } }
diff --git a/cc/trees/effect_node.cc b/cc/trees/effect_node.cc index 0b0a525..0336613 100644 --- a/cc/trees/effect_node.cc +++ b/cc/trees/effect_node.cc
@@ -31,7 +31,6 @@ is_currently_animating_backdrop_filter(false), is_currently_animating_opacity(false), has_masking_child(false), - is_masked(false), effect_changed(false), subtree_has_copy_request(false), is_fast_rounded_corner(false), @@ -39,7 +38,6 @@ transform_id(0), clip_id(0), target_id(1), - mask_layer_id(Layer::INVALID_ID), closest_ancestor_with_cached_render_surface_id(-1), closest_ancestor_with_copy_request_id(-1) {} @@ -82,11 +80,10 @@ is_currently_animating_opacity == other.is_currently_animating_opacity && has_masking_child == other.has_masking_child && - is_masked == other.is_masked && effect_changed == other.effect_changed && subtree_has_copy_request == other.subtree_has_copy_request && transform_id == other.transform_id && clip_id == other.clip_id && - target_id == other.target_id && mask_layer_id == other.mask_layer_id && + target_id == other.target_id && closest_ancestor_with_cached_render_surface_id == other.closest_ancestor_with_cached_render_surface_id && closest_ancestor_with_copy_request_id == @@ -170,7 +167,6 @@ value->SetBoolean("has_potential_opacity_animation", has_potential_opacity_animation); value->SetBoolean("has_masking_child", has_masking_child); - value->SetBoolean("is_masked", is_masked); value->SetBoolean("effect_changed", effect_changed); value->SetBoolean("subtree_has_copy_request", subtree_has_copy_request); value->SetString("render_surface_reason", @@ -178,7 +174,6 @@ value->SetInteger("transform_id", transform_id); value->SetInteger("clip_id", clip_id); value->SetInteger("target_id", target_id); - value->SetInteger("mask_layer_id", mask_layer_id); value->SetInteger("closest_ancestor_with_cached_render_surface_id", closest_ancestor_with_cached_render_surface_id); value->SetInteger("closest_ancestor_with_copy_request_id",
diff --git a/cc/trees/effect_node.h b/cc/trees/effect_node.h index 51cf4d34..1b5df24 100644 --- a/cc/trees/effect_node.h +++ b/cc/trees/effect_node.h
@@ -116,8 +116,6 @@ bool is_currently_animating_opacity : 1; // Whether this node has a child node with kDstIn blend mode. bool has_masking_child : 1; - // Whether this node has a mask. This bit is not used when using layer lists. - bool is_masked : 1; // Whether this node's effect has been changed since the last // frame. Needed in order to compute damage rect. bool effect_changed : 1; @@ -138,9 +136,6 @@ // This is the id of the ancestor effect node that induces a // RenderSurfaceImpl. int target_id; - // The layer id of the mask layer, if any, to apply to this effect - // node's content when rendering to a surface. - int mask_layer_id; int closest_ancestor_with_cached_render_surface_id; int closest_ancestor_with_copy_request_id;
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index a480efec..a42af87b 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -443,8 +443,8 @@ // PushPropertiesTo() propagates layer debug info to the impl side -- // otherwise this won't happen for the layers that remain unchanged since // tracing started. - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](Layer* layer) { layer->SetNeedsPushProperties(); }); + for (auto* layer : *this) + layer->SetNeedsPushProperties(); } for (Layer* layer : LayersThatShouldPushProperties()) @@ -1162,8 +1162,8 @@ old_properties == EventListenerProperties::kBlockingAndPassive; if (old_property_is_blocking != new_property_is_blocking) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](Layer* layer) { layer->SetNeedsPushProperties(); }); + for (auto* layer : *this) + layer->SetNeedsPushProperties(); } } @@ -1311,8 +1311,8 @@ return; raster_color_space_id_ = gfx::ColorSpace::GetNextId(); raster_color_space_ = raster_color_space; - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](Layer* layer) { layer->SetNeedsDisplay(); }); + for (auto* layer : *this) + layer->SetNeedsDisplay(); } void LayerTreeHost::SetExternalPageScaleFactor( @@ -1674,12 +1674,9 @@ mutator_host_->UpdateRegisteredElementIds(ElementListType::ACTIVE); } -static void SetElementIdForTesting(Layer* layer) { - layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); -} - void LayerTreeHost::SetElementIdsForTesting() { - LayerTreeHostCommon::CallFunctionForEveryLayer(this, SetElementIdForTesting); + for (auto* layer : *this) + layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); } void LayerTreeHost::BuildPropertyTreesForTesting() {
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc index 86e02f9..89f3bf88 100644 --- a/cc/trees/layer_tree_host_common.cc +++ b/cc/trees/layer_tree_host_common.cc
@@ -169,23 +169,6 @@ ScrollAndScaleSet::~ScrollAndScaleSet() = default; -static inline void SetMaskLayersContributeToDrawnRenderSurface( - RenderSurfaceImpl* surface, - PropertyTrees* property_trees) { - LayerImpl* mask_layer = surface->MaskLayer(); - if (mask_layer) { - mask_layer->set_contributes_to_drawn_render_surface(true); - draw_property_utils::ComputeMaskDrawProperties(mask_layer, property_trees); - } -} - -static inline void ClearMaskLayersContributeToDrawnRenderSurface( - RenderSurfaceImpl* surface) { - LayerImpl* mask_layer = surface->MaskLayer(); - if (mask_layer) - mask_layer->set_contributes_to_drawn_render_surface(false); -} - static float TranslationFromActiveTreeLayerScreenSpaceTransform( LayerImpl* pending_tree_layer) { LayerTreeImpl* layer_tree_impl = pending_tree_layer->layer_tree_impl(); @@ -329,7 +312,6 @@ if (RenderSurfaceImpl* render_surface = effect_tree.GetRenderSurface(i)) { render_surface->set_is_render_surface_list_member(false); render_surface->reset_num_contributors(); - ClearMaskLayersContributeToDrawnRenderSurface(render_surface); } } @@ -434,7 +416,6 @@ target_surface->decrement_num_contributors(); continue; } - SetMaskLayersContributeToDrawnRenderSurface(surface, property_trees); final_surface_list->push_back(surface); } if (removed_surface) {
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h index 9657c46..a12c014 100644 --- a/cc/trees/layer_tree_host_common.h +++ b/cc/trees/layer_tree_host_common.h
@@ -123,14 +123,6 @@ static void CalculateDrawPropertiesForTesting( CalcDrawPropsImplInputsForTesting* inputs); - template <typename Function> - static void CallFunctionForEveryLayer(LayerTreeHost* host, - const Function& function); - - template <typename Function> - static void CallFunctionForEveryLayer(LayerTreeImpl* layer, - const Function& function); - struct CC_EXPORT ScrollUpdateInfo { ElementId element_id; gfx::ScrollOffset scroll_delta; @@ -198,27 +190,6 @@ ManipulationInfo manipulation_info; }; -template <typename Function> -void LayerTreeHostCommon::CallFunctionForEveryLayer(LayerTreeHost* host, - const Function& function) { - for (auto* layer : *host) { - function(layer); - if (PictureLayer* mask_layer = layer->mask_layer()) - function(mask_layer); - } -} - -template <typename Function> -void LayerTreeHostCommon::CallFunctionForEveryLayer(LayerTreeImpl* tree_impl, - const Function& function) { - for (auto* layer : *tree_impl) - function(layer); - - for (int id : tree_impl->property_trees()->effect_tree.mask_layer_ids()) { - function(tree_impl->LayerById(id)); - } -} - CC_EXPORT PropertyTrees* GetPropertyTrees(const Layer* layer); CC_EXPORT PropertyTrees* GetPropertyTrees(const LayerImpl* layer);
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index b34f461..98e11ff2 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -3043,13 +3043,17 @@ // surface_child's contents. Occlusion actual_occlusion = GetRenderSurfaceImpl(surface_child)->occlusion_in_content_space(); - Occlusion expected_occlusion(translate, SimpleEnclosedRegion(gfx::Rect()), + Occlusion expected_occlusion(translate, SimpleEnclosedRegion(), SimpleEnclosedRegion(gfx::Rect(200, 200))); EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion)); - // Mask layer should have the same occlusion. + // Mask layer's occlusion is different because we create transform and render + // surface for it in layer tree mode. actual_occlusion = ImplOf(surface_child_mask)->draw_properties().occlusion_in_content_space; + expected_occlusion = Occlusion( + gfx::Transform(), SimpleEnclosedRegion(gfx::Rect(-20, -20, 200, 200)), + SimpleEnclosedRegion()); EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion)); } @@ -3795,10 +3799,10 @@ // the preserve-3d transform style. Instead, an example of when a surface // would be created with preserve-3d is when there is a mask layer. FakeContentLayerClient client; - auto dummy_mask_layer1 = PictureLayer::Create(&client); - front_facing_surface->SetMaskLayer(dummy_mask_layer1); - auto dummy_mask_layer2 = PictureLayer::Create(&client); - back_facing_surface->SetMaskLayer(dummy_mask_layer2); + auto front_facing_mask = PictureLayer::Create(&client); + front_facing_surface->SetMaskLayer(front_facing_mask); + auto back_facing_mask = PictureLayer::Create(&client); + back_facing_surface->SetMaskLayer(back_facing_mask); // Nothing is double-sided front_facing_child->SetDoubleSided(false); @@ -3819,8 +3823,8 @@ back_facing_child_of_front_facing_surface->SetIsDrawable(true); front_facing_child_of_back_facing_surface->SetIsDrawable(true); back_facing_child_of_back_facing_surface->SetIsDrawable(true); - dummy_mask_layer1->SetIsDrawable(true); - dummy_mask_layer2->SetIsDrawable(true); + front_facing_mask->SetIsDrawable(true); + back_facing_mask->SetIsDrawable(true); gfx::Transform backface_matrix; backface_matrix.Translate(50.0, 50.0); @@ -3836,8 +3840,8 @@ back_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); front_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); back_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); - dummy_mask_layer1->SetBounds(gfx::Size(100, 100)); - dummy_mask_layer2->SetBounds(gfx::Size(100, 100)); + front_facing_mask->SetBounds(gfx::Size(100, 100)); + back_facing_mask->SetBounds(gfx::Size(100, 100)); back_facing_child->SetTransform(backface_matrix); back_facing_surface->SetTransform(backface_matrix); @@ -3881,10 +3885,11 @@ EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_back_facing_surface), GetRenderSurfaceImpl(back_facing_surface)); - EXPECT_EQ(3u, update_layer_impl_list().size()); + EXPECT_EQ(4u, update_layer_impl_list().size()); EXPECT_TRUE(UpdateLayerImplListContains(front_facing_child->id())); EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); + EXPECT_TRUE(UpdateLayerImplListContains(front_facing_mask->id())); EXPECT_TRUE(UpdateLayerImplListContains( front_facing_child_of_front_facing_surface->id())); } @@ -6826,9 +6831,6 @@ if (it.state() != EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) continue; - - if (it.current_render_surface()->MaskLayer()) - drawn_layers->insert(it.current_render_surface()->MaskLayer()); } } @@ -6975,11 +6977,13 @@ EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); - EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface()); + // Mask layer has its own render surface in layer tree mode. + EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface()); expected.clear(); + expected.insert(ImplOf(mask)); actual.clear(); GatherDrawnLayers(host_impl()->active_tree(), &actual); EXPECT_EQ(expected, actual); @@ -8643,7 +8647,8 @@ root->SetIsDrawable(true); child->SetTransform(transform); child->SetBounds(gfx::Size(30, 30)); - child->SetIsDrawable(false); + child->SetIsDrawable(true); + child->SetOpacity(0.f); mask->SetBounds(gfx::Size(30, 30)); CommitAndActivate(); @@ -8652,13 +8657,14 @@ // mask doesn't contribute to a drawn render surface. This means it has an // empty visible rect, but its screen space transform can still be computed // correctly on-demand. + EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface()); EXPECT_EQ(gfx::Rect(), ImplOf(mask)->visible_layer_rect()); EXPECT_TRANSFORMATION_MATRIX_EQ(transform, ImplOf(mask)->ScreenSpaceTransform()); // Make the child's render surface have contributing content. - child->SetIsDrawable(true); + child->SetOpacity(1.f); CommitAndActivate(); EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); EXPECT_EQ(gfx::Rect(30, 30), ImplOf(mask)->visible_layer_rect()); @@ -8671,6 +8677,17 @@ EXPECT_TRANSFORMATION_MATRIX_EQ(transform, ImplOf(mask)->ScreenSpaceTransform()); EXPECT_EQ(gfx::Rect(20, 20), ImplOf(mask)->visible_layer_rect()); + + // For now SetIsDrawable of masked layer doesn't affect draw properties of + // the mask layer because it doesn't affect property trees. + child->SetIsDrawable(false); + CommitAndActivate(); + EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); + + // SetIsDrawable of mask layer itself affects its draw properties. + mask->SetIsDrawable(false); + CommitAndActivate(); + EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface()); } TEST_F(LayerTreeHostCommonTest,
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 343e0ea..25ea491c 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -2326,11 +2326,11 @@ TRACE_EVENT_IS_NEW_TRACE(&is_new_trace); if (is_new_trace) { if (pending_tree_) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - pending_tree(), [](LayerImpl* layer) { layer->DidBeginTracing(); }); + for (auto* layer : *pending_tree_) + layer->DidBeginTracing(); } - LayerTreeHostCommon::CallFunctionForEveryLayer( - active_tree(), [](LayerImpl* layer) { layer->DidBeginTracing(); }); + for (auto* layer : *active_tree_) + layer->DidBeginTracing(); } {
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 90bca1a0..58266ffa1 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -11722,11 +11722,8 @@ std::unique_ptr<FakePictureLayerImpl> mask_layer = FakePictureLayerImpl::Create(pending_tree, next_layer_id_++); FakePictureLayerImpl* raw_mask_layer = mask_layer.get(); - pending_tree->AddMaskLayer(std::move(mask_layer)); - GetEffectNode(pending_layer)->mask_layer_id = raw_mask_layer->id(); - GetEffectNode(pending_layer)->is_masked = true; - GetPropertyTrees(pending_layer) - ->effect_tree.AddMaskLayerId(raw_mask_layer->id()); + SetupMaskProperties(pending_layer, raw_mask_layer); + pending_tree->AddLayer(std::move(mask_layer)); EXPECT_EQ(1u, pending_layer->did_become_active_call_count()); EXPECT_EQ(0u, raw_mask_layer->did_become_active_call_count());
diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc index c38c6c4..2f185f8 100644 --- a/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -526,41 +526,59 @@ gfx::Size bounds_; }; -using LayerTreeHostMasksForBackdropFiltersPixelTest = - ParameterizedPixelResourceTest; +class LayerTreeHostMasksForBackdropFiltersPixelTest + : public ParameterizedPixelResourceTest { + protected: + LayerTreeHostMasksForBackdropFiltersPixelTest() + : bounds_(100, 100), + picture_client_(bounds_, SK_ColorGREEN, true), + mask_client_(bounds_) { + SetUseLayerLists(); + } + + // Setup three layers for testing masks: a white background, a green layer, + // and a mask layer with kDstIn blend mode. + void SetupTree() override { + SetInitialRootBounds(bounds_); + ParameterizedPixelResourceTest::SetupTree(); + + Layer* root = layer_tree_host()->root_layer(); + + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(bounds_), SK_ColorWHITE); + CopyProperties(root, background.get()); + root->AddChild(background); + + scoped_refptr<PictureLayer> picture = + PictureLayer::Create(&picture_client_); + picture->SetBounds(bounds_); + picture->SetIsDrawable(true); + CopyProperties(background.get(), picture.get()); + root->AddChild(picture); + + scoped_refptr<SolidColorLayer> blur = + CreateSolidColorLayer(gfx::Rect(bounds_), SK_ColorTRANSPARENT); + CopyProperties(background.get(), blur.get()); + CreateEffectNode(blur.get()) + .backdrop_filters.Append(FilterOperation::CreateGrayscaleFilter(1.0)); + root->AddChild(blur); + + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client_); + SetupMaskProperties(blur.get(), mask.get()); + + root->AddChild(mask); + } + + const gfx::Size bounds_; + CheckerContentLayerClient picture_client_; + CircleContentLayerClient mask_client_; +}; INSTANTIATE_TEST_SUITE_P(PixelResourceTest, LayerTreeHostMasksForBackdropFiltersPixelTest, ::testing::ValuesIn(kTestCases)); -TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, - MaskOfLayerWithBackdropFilter) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(100, 100), SK_ColorWHITE); - - gfx::Size picture_bounds(100, 100); - CheckerContentLayerClient picture_client(picture_bounds, SK_ColorGREEN, true); - scoped_refptr<PictureLayer> picture = PictureLayer::Create(&picture_client); - picture->SetBounds(picture_bounds); - picture->SetIsDrawable(true); - - scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayer( - gfx::Rect(100, 100), SK_ColorTRANSPARENT); - background->AddChild(picture); - background->AddChild(blur); - - FilterOperations filters; - filters.Append(FilterOperation::CreateGrayscaleFilter(1.0)); - blur->SetBackdropFilters(filters); - blur->ClearBackdropFilterBounds(); - - gfx::Size mask_bounds(100, 100); - CircleContentLayerClient mask_client(mask_bounds); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - blur->SetMaskLayer(mask); - +TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, Test) { base::FilePath image_name = (raster_type() == GPU) ? base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter_gpu.png")) @@ -580,10 +598,10 @@ large_error_allowed, small_error_allowed); } - RunPixelResourceTest(background, image_name); + RunPixelResourceTestWithLayerList(image_name); } -TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, MaskOfLayerWithBlend) { +TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayerWithBlend) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(128, 128), SK_ColorWHITE); @@ -997,43 +1015,64 @@ RunPixelResourceTest(root, image_name); } -TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, - MaskOfLayerWithBackdropFilterAndBlend) { - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(128, 128), SK_ColorWHITE); +class LayerTreeHostMasksForBackdropFiltersAndBlendPixelTest + : public ParameterizedPixelResourceTest { + protected: + LayerTreeHostMasksForBackdropFiltersAndBlendPixelTest() + : bounds_(128, 128), + picture_client_vertical_(bounds_, SK_ColorGREEN, true), + picture_client_horizontal_(bounds_, SK_ColorMAGENTA, false), + mask_client_(bounds_) { + SetUseLayerLists(); + } - gfx::Size picture_bounds(128, 128); - CheckerContentLayerClient picture_client_vertical(picture_bounds, - SK_ColorGREEN, true); - scoped_refptr<PictureLayer> picture_vertical = - PictureLayer::Create(&picture_client_vertical); - picture_vertical->SetBounds(picture_bounds); - picture_vertical->SetIsDrawable(true); + void SetupTree() override { + SetInitialRootBounds(bounds_); + ParameterizedPixelResourceTest::SetupTree(); - CheckerContentLayerClient picture_client_horizontal(picture_bounds, - SK_ColorMAGENTA, false); - scoped_refptr<PictureLayer> picture_horizontal = - PictureLayer::Create(&picture_client_horizontal); - picture_horizontal->SetBounds(picture_bounds); - picture_horizontal->SetIsDrawable(true); - picture_horizontal->SetContentsOpaque(false); - picture_horizontal->SetBlendMode(SkBlendMode::kMultiply); + Layer* root = layer_tree_host()->root_layer(); - FilterOperations filters; - filters.Append(FilterOperation::CreateGrayscaleFilter(1.0)); - picture_horizontal->SetBackdropFilters(filters); - picture_horizontal->ClearBackdropFilterBounds(); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(bounds_), SK_ColorWHITE); + CopyProperties(root, background.get()); + root->AddChild(background); - background->AddChild(picture_vertical); - background->AddChild(picture_horizontal); + scoped_refptr<PictureLayer> picture_vertical = + PictureLayer::Create(&picture_client_vertical_); + picture_vertical->SetBounds(bounds_); + picture_vertical->SetIsDrawable(true); + CopyProperties(background.get(), picture_vertical.get()); + root->AddChild(picture_vertical); - gfx::Size mask_bounds(128, 128); - CircleContentLayerClient mask_client(mask_bounds); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - picture_horizontal->SetMaskLayer(mask); + scoped_refptr<PictureLayer> picture_horizontal = + PictureLayer::Create(&picture_client_horizontal_); + picture_horizontal->SetBounds(bounds_); + picture_horizontal->SetIsDrawable(true); + picture_horizontal->SetContentsOpaque(false); + CopyProperties(background.get(), picture_horizontal.get()); + auto& effect_node = CreateEffectNode(picture_horizontal.get()); + effect_node.backdrop_filters.Append( + FilterOperation::CreateGrayscaleFilter(1.0)); + effect_node.blend_mode = SkBlendMode::kMultiply; + root->AddChild(picture_horizontal); + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client_); + mask->SetBounds(bounds_); + SetupMaskProperties(picture_horizontal.get(), mask.get()); + root->AddChild(mask); + } + + const gfx::Size bounds_; + CheckerContentLayerClient picture_client_vertical_; + CheckerContentLayerClient picture_client_horizontal_; + CircleContentLayerClient mask_client_; +}; + +INSTANTIATE_TEST_SUITE_P(PixelResourceTest, + LayerTreeHostMasksForBackdropFiltersAndBlendPixelTest, + ::testing::ValuesIn(kTestCases)); + +TEST_P(LayerTreeHostMasksForBackdropFiltersAndBlendPixelTest, Test) { base::FilePath result_path( FILE_PATH_LITERAL("mask_of_backdrop_filter_and_blend_.png")); if (raster_type() != GPU) { @@ -1041,7 +1080,7 @@ } else { result_path = result_path.InsertBeforeExtensionASCII(GetRendererSuffix()); } - RunPixelResourceTest(background, result_path); + RunPixelResourceTestWithLayerList(result_path); } } // namespace
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 81dc18b..2d8e322 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -2151,10 +2151,12 @@ void SetupTree() override { scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(gfx::Size(10, 10)); + // child_layer_ is not drawable. child_layer_ = base::MakeRefCounted<UpdateCountingLayer>(&client_); child_layer_->SetBounds(gfx::Size(10, 10)); mask_layer_ = base::MakeRefCounted<UpdateCountingLayer>(&client_); mask_layer_->SetBounds(gfx::Size(10, 10)); + mask_layer_->SetIsDrawable(true); child_layer_->SetMaskLayer(mask_layer_); root->AddChild(child_layer_); layer_tree_host()->SetRootLayer(root); @@ -2170,8 +2172,8 @@ switch (layer_tree_host()->SourceFrameNumber()) { case 1: // Root and mask layer should have the same source frame number as they - // will be in the layer update list but the child is not as it has empty - // bounds. + // will be in the layer update list but the child is not as it doesn't + // draw content. EXPECT_EQ(mask_layer_->update_count(), 1); EXPECT_EQ(child_layer_->update_count(), 0); @@ -2182,17 +2184,22 @@ } void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { + auto* mask_surface = + GetRenderSurface(impl->sync_tree()->LayerById(mask_layer_->id())); + auto* root_surface = + GetRenderSurface(impl->sync_tree()->root_layer_for_testing()); + ASSERT_TRUE(mask_surface); switch (index_) { - case 0: + case 0: { index_++; - EXPECT_FALSE( - GetRenderSurface(impl->sync_tree()->root_layer_for_testing()) - ->MaskLayer()); + auto* child_surface = + GetRenderSurface(impl->sync_tree()->LayerById(child_layer_->id())); + EXPECT_EQ(child_surface, mask_surface->render_target()); + EXPECT_NE(child_surface, root_surface); break; + } case 1: - EXPECT_TRUE( - GetRenderSurface(impl->sync_tree()->root_layer_for_testing()) - ->MaskLayer()); + EXPECT_EQ(mask_surface->render_target(), root_surface); EndTest(); break; } @@ -7554,14 +7561,12 @@ void BeginTest() override { PostSetNeedsCommitToMainThread(); } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - LayerTreeHostCommon::CallFunctionForEveryLayer( - host_impl->sync_tree(), [this](LayerImpl* layer) { - const std::vector<int>& list = - layer->IsAffectedByPageScale() - ? this->affected_by_page_scale_ - : this->not_affected_by_page_scale_; - EXPECT_TRUE(base::Contains(list, layer->id())); - }); + for (auto* layer : *host_impl->sync_tree()) { + const std::vector<int>& list = layer->IsAffectedByPageScale() + ? this->affected_by_page_scale_ + : this->not_affected_by_page_scale_; + EXPECT_TRUE(base::Contains(list, layer->id())); + } EndTest(); }
diff --git a/cc/trees/layer_tree_host_unittest_masks.cc b/cc/trees/layer_tree_host_unittest_masks.cc index 41a9958..665af89d 100644 --- a/cc/trees/layer_tree_host_unittest_masks.cc +++ b/cc/trees/layer_tree_host_unittest_masks.cc
@@ -75,7 +75,7 @@ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -90,11 +90,13 @@ gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect( render_pass_quad->shared_quad_state->quad_to_target_transform, render_pass_quad->rect); - EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), - rect_in_target_space.ToString()); - EXPECT_EQ(gfx::ScaleRect(gfx::RectF(50.f, 50.f, 50.f, 50.f), 1.f / 100.f) - .ToString(), - render_pass_quad->mask_uv_rect.ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 50, 50), rect_in_target_space); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); EndTest(); return draw_result; } @@ -106,6 +108,92 @@ SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin); +class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOriginWithLayerList + : public LayerTreeTest { + protected: + LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOriginWithLayerList() { + SetUseLayerLists(); + } + + void SetupTree() override { + // The masked layer has bounds 50x50, but it has a child that causes + // the surface bounds to be larger. It also has a parent that clips the + // masked layer and its surface. + + SetInitialRootBounds(gfx::Size(100, 100)); + LayerTreeTest::SetupTree(); + + Layer* root = layer_tree_host()->root_layer(); + + gfx::Size layer_size(100, 100); + SetupViewport(root, gfx::Size(50, 50), layer_size); + + auto* container = layer_tree_host()->outer_viewport_container_layer(); + auto* scroll = layer_tree_host()->outer_viewport_scroll_layer(); + container->SetMasksToBounds(true); + CreateClipNode(container); + scroll->SetClipTreeIndex(container->clip_tree_index()); + SetScrollOffset(scroll, gfx::ScrollOffset(50, 50)); + + client_.set_bounds(root->bounds()); + auto content_layer = FakePictureLayer::Create(&client_); + content_layer->SetBounds(layer_size); + CopyProperties(scroll, content_layer.get()); + root->AddChild(content_layer); + + std::unique_ptr<RecordingSource> recording_source = + FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100)); + PaintFlags paint1, paint2; + static_cast<FakeRecordingSource*>(recording_source.get()) + ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1); + static_cast<FakeRecordingSource*>(recording_source.get()) + ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2); + client_.set_fill_with_nonsolid_color(true); + static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord(); + + auto mask_layer = FakePictureLayer::CreateWithRecordingSource( + &client_, std::move(recording_source)); + SetupMaskProperties(content_layer.get(), mask_layer.get()); + root->AddChild(mask_layer); + + mask_layer_id_ = mask_layer->id(); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { + EXPECT_EQ(1u, frame_data->render_passes.size()); + viz::RenderPass* pass = frame_data->render_passes.back().get(); + EXPECT_EQ(3u, pass->quad_list.size()); + + // There's a solid color quad under everything. + EXPECT_EQ(viz::DrawQuad::Material::kSolidColor, + pass->quad_list.back()->material); + + EXPECT_EQ(viz::DrawQuad::Material::kTiledContent, + pass->quad_list.ElementAt(1)->material); + + auto* mask_quad = pass->quad_list.front(); + EXPECT_EQ(viz::DrawQuad::Material::kTiledContent, mask_quad->material); + gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect( + mask_quad->shared_quad_state->quad_to_target_transform, + mask_quad->rect); + EXPECT_EQ(gfx::Rect(0, 0, 50, 50), rect_in_target_space); + // We use kDstIn blend mode for mask. + EXPECT_EQ(SkBlendMode::kDstIn, mask_quad->shared_quad_state->blend_mode); + EndTest(); + return draw_result; + } + + int mask_layer_id_; + FakeContentLayerClient client_; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOriginWithLayerList); + class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { protected: void SetupTree() override { @@ -173,7 +261,7 @@ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -191,13 +279,12 @@ render_pass_quad->rect); EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(), rect_in_target_space.ToString()); - // The masked layer is 50x50, but the surface size is 10x20. So the texture - // coords in the mask are scaled by 10/50 and 20/50. - // The surface is clipped to (20,10) so the mask texture coords are offset - // by 20/50 and 10/50 - EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f) - .ToString(), - render_pass_quad->mask_uv_rect.ToString()); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); EndTest(); return draw_result; } @@ -285,7 +372,7 @@ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -309,13 +396,12 @@ render_pass_quad->visible_rect); EXPECT_EQ(gfx::Rect(20, 10, 20, 40).ToString(), visible_rect_in_target_space.ToString()); - // The masked layer is 50x50, but the surface size is 10x20. So the texture - // coords in the mask are scaled by 10/50 and 20/50. - // The surface is clipped to (20,10) so the mask texture coords are offset - // by 20/50 and 10/50 - EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f) - .ToString(), - render_pass_quad->mask_uv_rect.ToString()); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); EndTest(); return draw_result; } @@ -383,7 +469,7 @@ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -398,22 +484,25 @@ gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect( render_pass_quad->shared_quad_state->quad_to_target_transform, render_pass_quad->rect); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); + switch (host_impl->active_tree()->source_frame_number()) { case 0: // Check that the tree scaling is correctly taken into account for the // mask, that should fully map onto the quad. EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), rect_in_target_space.ToString()); - EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); break; case 1: // Applying a DSF should change the render surface size, but won't // affect which part of the mask is used. EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(), rect_in_target_space.ToString()); - EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); EndTest(); break; } @@ -484,7 +573,7 @@ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -499,9 +588,12 @@ viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front()); EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), render_pass_quad->rect.ToString()); - // The mask layer is 100x100, but is backed by a 120x150 image. - EXPECT_EQ(gfx::RectF(0.0f, 0.0f, 100.f / 120.0f, 100.f / 150.0f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); EndTest(); return draw_result; }
diff --git a/cc/trees/layer_tree_host_unittest_occlusion.cc b/cc/trees/layer_tree_host_unittest_occlusion.cc index 244eb6f..47fb835 100644 --- a/cc/trees/layer_tree_host_unittest_occlusion.cc +++ b/cc/trees/layer_tree_host_unittest_occlusion.cc
@@ -148,10 +148,10 @@ make_surface_bigger->SetIsDrawable(true); child_->AddChild(make_surface_bigger); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client_); - mask->SetBounds(gfx::Size(30, 40)); - mask->SetIsDrawable(true); - child_->SetMaskLayer(mask); + mask_ = PictureLayer::Create(&client_); + mask_->SetBounds(gfx::Size(30, 40)); + mask_->SetIsDrawable(true); + child_->SetMaskLayer(mask_); scoped_refptr<Layer> child2 = Layer::Create(); child2->SetBounds(gfx::Size(10, 12)); @@ -170,28 +170,42 @@ void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer_for_testing(); LayerImpl* child = impl->active_tree()->LayerById(child_->id()); - RenderSurfaceImpl* surface = GetRenderSurface(child); - LayerImpl* mask = surface->MaskLayer(); + RenderSurfaceImpl* child_surface = GetRenderSurface(child); + LayerImpl* mask = impl->active_tree()->LayerById(mask_->id()); + RenderSurfaceImpl* mask_surface = GetRenderSurface(mask); // Verify the draw properties are valid. EXPECT_TRUE(root->contributes_to_drawn_render_surface()); EXPECT_TRUE(child->contributes_to_drawn_render_surface()); - EXPECT_TRUE(GetRenderSurface(child)); - EXPECT_EQ(GetRenderSurface(child), child->render_target()); + EXPECT_TRUE(mask->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child_surface); + EXPECT_EQ(child_surface, child->render_target()); - gfx::Transform transform = surface->draw_transform(); + gfx::Transform transform = child_surface->draw_transform(); transform.PreconcatTransform(child->DrawTransform()); - EXPECT_OCCLUSION_EQ( Occlusion(transform, SimpleEnclosedRegion(), SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))), - mask->draw_properties().occlusion_in_content_space); + child_surface->occlusion_in_content_space()); + + // Mask layer has its own transform and render surface in layer tree mode. + EXPECT_NE(child_surface, mask_surface); + EXPECT_OCCLUSION_EQ( + Occlusion(transform, SimpleEnclosedRegion(), + SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))), + mask_surface->occlusion_in_content_space()); + + EXPECT_OCCLUSION_EQ(Occlusion(gfx::Transform(), + SimpleEnclosedRegion(gfx::Rect(3, 4, 10, 10)), + SimpleEnclosedRegion()), + mask->draw_properties().occlusion_in_content_space); EndTest(); } private: FakeContentLayerClient client_; scoped_refptr<Layer> child_; + scoped_refptr<PictureLayer> mask_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestDrawPropertiesOnMask); @@ -208,21 +222,21 @@ gfx::Transform scale; scale.Scale(2, 2); - child_ = Layer::Create(); - child_->SetBounds(gfx::Size(30, 40)); - child_->SetTransform(scale); - root->AddChild(child_); + scoped_refptr<Layer> child = Layer::Create(); + child->SetBounds(gfx::Size(30, 40)); + child->SetTransform(scale); + root->AddChild(child); scoped_refptr<Layer> grand_child = Layer::Create(); grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetPosition(gfx::PointF(-10.f, -15.f)); grand_child->SetIsDrawable(true); - child_->AddChild(grand_child); + child->AddChild(grand_child); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client_); - mask->SetBounds(gfx::Size(30, 40)); - mask->SetIsDrawable(true); - child_->SetMaskLayer(mask); + mask_ = PictureLayer::Create(&client_); + mask_->SetBounds(gfx::Size(30, 40)); + mask_->SetIsDrawable(true); + child->SetMaskLayer(mask_); scoped_refptr<Layer> child2 = Layer::Create(); child2->SetBounds(gfx::Size(10, 11)); @@ -239,22 +253,21 @@ void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* child = impl->active_tree()->LayerById(child_->id()); - LayerImpl* mask = GetRenderSurface(child)->MaskLayer(); + LayerImpl* mask = impl->active_tree()->LayerById(mask_->id()); gfx::Transform scale; scale.Scale(2, 2); EXPECT_OCCLUSION_EQ( - Occlusion(scale, SimpleEnclosedRegion(), - SimpleEnclosedRegion(gfx::Rect(13, 15, 10, 11))), + Occlusion(scale, SimpleEnclosedRegion(gfx::Rect(13, 15, 10, 11)), + SimpleEnclosedRegion()), mask->draw_properties().occlusion_in_content_space); EndTest(); } private: FakeContentLayerClient client_; - scoped_refptr<Layer> child_; + scoped_refptr<PictureLayer> mask_; }; SINGLE_AND_MULTI_THREAD_TEST_F(
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index a64f3c6..49956bd 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -151,7 +151,6 @@ // Need to explicitly clear the tree prior to destroying this so that // the LayerTreeImpl pointer is still valid in the LayerImpl dtor. DCHECK(LayerListIsEmpty()); - DCHECK(layers_.empty()); } void LayerTreeImpl::Shutdown() { @@ -159,26 +158,25 @@ BreakSwapPromises(IsActiveTree() ? SwapPromise::SWAP_FAILS : SwapPromise::ACTIVATION_FAILS); DCHECK(LayerListIsEmpty()); - DCHECK(layers_.empty()); } void LayerTreeImpl::ReleaseResources() { - for (auto& layer : layers_) + for (auto* layer : *this) layer->ReleaseResources(); } void LayerTreeImpl::OnPurgeMemory() { - for (auto& layer : layers_) + for (auto* layer : *this) layer->OnPurgeMemory(); } void LayerTreeImpl::ReleaseTileResources() { - for (auto& layer : layers_) + for (auto* layer : *this) layer->ReleaseTileResources(); } void LayerTreeImpl::RecreateTileResources() { - for (auto& layer : layers_) + for (auto* layer : *this) layer->RecreateTileResources(); } @@ -436,7 +434,7 @@ } bool LayerTreeImpl::IsRootLayer(const LayerImpl* layer) const { - return layer_list_.empty() ? false : layer_list_[0] == layer; + return !layer_list_.empty() && layer_list_[0].get() == layer; } gfx::ScrollOffset LayerTreeImpl::TotalScrollOffset() const { @@ -468,10 +466,9 @@ } OwnedLayerImplList LayerTreeImpl::DetachLayers() { - layer_list_.clear(); render_surface_list_.clear(); set_needs_update_draw_properties(); - return std::move(layers_); + return std::move(layer_list_); } OwnedLayerImplList LayerTreeImpl::DetachLayersKeepingRootLayerForTesting() { @@ -647,10 +644,9 @@ } void LayerTreeImpl::HandleScrollbarShowRequestsFromMain() { - LayerTreeHostCommon::CallFunctionForEveryLayer(this, [this]( - LayerImpl* layer) { + for (auto* layer : *this) { if (!layer->needs_show_scrollbars()) - return; + continue; ScrollbarAnimationController* controller = host_impl_->ScrollbarAnimationControllerForElementId( layer->element_id()); @@ -658,7 +654,7 @@ controller->DidRequestShowFromMainThread(); layer->set_needs_show_scrollbars(false); } - }); + } } void LayerTreeImpl::MoveChangeTrackingToLayers() { @@ -683,30 +679,6 @@ layer->ResetRasterScale(); } -LayerImplList::const_iterator LayerTreeImpl::begin() const { - return layer_list_.cbegin(); -} - -LayerImplList::const_iterator LayerTreeImpl::end() const { - return layer_list_.cend(); -} - -LayerImplList::const_reverse_iterator LayerTreeImpl::rbegin() const { - return layer_list_.crbegin(); -} - -LayerImplList::const_reverse_iterator LayerTreeImpl::rend() const { - return layer_list_.crend(); -} - -LayerImplList::reverse_iterator LayerTreeImpl::rbegin() { - return layer_list_.rbegin(); -} - -LayerImplList::reverse_iterator LayerTreeImpl::rend() { - return layer_list_.rend(); -} - bool LayerTreeImpl::IsElementInPropertyTree(ElementId element_id) const { return property_trees()->HasElement(element_id); } @@ -1300,7 +1272,7 @@ // For unit tests, we use the layer's id as its element id. void LayerTreeImpl::SetElementIdsForTesting() { - for (auto& layer : layers_) { + for (auto* layer : *this) { if (!layer->element_id()) layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); } @@ -1344,7 +1316,7 @@ // calculations except when this function is explicitly passed a flag asking // us to skip it. LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( - layer_list_[0], GetDeviceViewport(), host_impl_->DrawTransform(), + layer_list_[0].get(), GetDeviceViewport(), host_impl_->DrawTransform(), device_scale_factor(), current_page_scale_factor(), PageScaleLayer(), InnerViewportScrollLayer(), OuterViewportScrollLayer(), elastic_overscroll()->Current(IsActiveTree()), @@ -1405,14 +1377,6 @@ occlusion_tracker.GetCurrentOcclusionForContributingSurface( draw_transform); render_surface->set_occlusion_in_content_space(occlusion); - // Masks are used to draw the contributing surface, so should have - // the same occlusion as the surface (nothing inside the surface - // occludes them). - if (LayerImpl* mask = render_surface->MaskLayer()) { - mask->draw_properties().occlusion_in_content_space = - occlusion_tracker.GetCurrentOcclusionForContributingSurface( - draw_transform * render_surface->SurfaceScale()); - } } occlusion_tracker.LeaveLayer(it); @@ -1501,11 +1465,11 @@ // TODO(masonfreed): If this shows up on profiles, this could use // a layer_element_map_ approach similar to LayerById(). LayerImpl* LayerTreeImpl::LayerByElementId(ElementId element_id) const { - auto it = std::find_if(layer_list_.rbegin(), layer_list_.rend(), - [&element_id](LayerImpl* layer_impl) { - return layer_impl->element_id() == element_id; - }); - if (it == layer_list_.rend()) + auto it = + std::find_if(rbegin(), rend(), [&element_id](LayerImpl* layer_impl) { + return layer_impl->element_id() == element_id; + }); + if (it == rend()) return nullptr; return *it; } @@ -1556,19 +1520,9 @@ } void LayerTreeImpl::AddLayer(std::unique_ptr<LayerImpl> layer) { - DCHECK(!base::Contains(layer_list_, layer.get())); - layer_list_.push_back(layer.get()); - AddOwnedLayer(std::move(layer)); -} - -void LayerTreeImpl::AddMaskLayer(std::unique_ptr<LayerImpl> layer) { - AddOwnedLayer(std::move(layer)); -} - -void LayerTreeImpl::AddOwnedLayer(std::unique_ptr<LayerImpl> layer) { - DCHECK(!base::Contains(layers_, layer)); DCHECK(layer); - layers_.push_back(std::move(layer)); + DCHECK(!base::Contains(layer_list_, layer)); + layer_list_.push_back(std::move(layer)); set_needs_update_draw_properties(); } @@ -1586,7 +1540,7 @@ // if we were in a good state. host_impl_->ResetRequiresHighResToDraw(); - for (auto& layer : layers_) + for (auto* layer : *this) layer->DidBecomeActive(); for (const auto& swap_promise : swap_promise_list_) @@ -1752,11 +1706,10 @@ void LayerTreeImpl::GetAllPrioritizedTilesForTracing( std::vector<PrioritizedTile>* prioritized_tiles) const { - for (auto it = layer_list_.rbegin(); it != layer_list_.rend(); ++it) { - LayerImpl* layer_impl = *it; - if (!layer_impl->contributes_to_drawn_render_surface()) + for (auto* layer : base::Reversed(*this)) { + if (!layer->contributes_to_drawn_render_surface()) continue; - layer_impl->GetAllPrioritizedTilesForTracing(prioritized_tiles); + layer->GetAllPrioritizedTilesForTracing(prioritized_tiles); } } @@ -1766,10 +1719,10 @@ state->SetInteger("source_frame_number", source_frame_number_); state->BeginArray("render_surface_layer_list"); - for (auto it = layer_list_.rbegin(); it != layer_list_.rend(); ++it) { - if (!(*it)->contributes_to_drawn_render_surface()) + for (auto* layer : base::Reversed(*this)) { + if (layer->contributes_to_drawn_render_surface()) continue; - viz::TracedValue::AppendIDRef(*it, state); + viz::TracedValue::AppendIDRef(layer, state); } state->EndArray(); @@ -2177,11 +2130,12 @@ float distance_to_intersection = 0.f; bool hit = false; - if (layer->Is3dSorted()) + if (layer->Is3dSorted()) { hit = PointHitsLayer(layer, screen_space_point, &distance_to_intersection); - else + } else { hit = PointHitsLayer(layer, screen_space_point, nullptr); + } if (!hit) continue; @@ -2219,7 +2173,7 @@ return nullptr; FindClosestMatchingLayerState state; - LayerImpl* root_layer = layer_list_[0]; + LayerImpl* root_layer = layer_list_[0].get(); FindClosestMatchingLayer(screen_space_point, root_layer, HitTestScrollingLayerOrScrollbarFunctor(), &state); return state.closest_match; @@ -2236,7 +2190,7 @@ if (!UpdateDrawProperties()) return nullptr; FindClosestMatchingLayerState state; - FindClosestMatchingLayer(screen_space_point, layer_list_[0], + FindClosestMatchingLayer(screen_space_point, layer_list_[0].get(), HitTestVisibleScrollableOrTouchableFunctor(), &state); return state.closest_match; @@ -2269,7 +2223,8 @@ if (!UpdateDrawProperties()) return nullptr; FindClosestMatchingLayerState state; - FindClosestMatchingLayer(screen_space_point, layer_list_[0], func, &state); + FindClosestMatchingLayer(screen_space_point, layer_list_[0].get(), func, + &state); return state.closest_match; } @@ -2438,7 +2393,7 @@ void LayerTreeImpl::ResetAllChangeTracking() { layers_that_should_push_properties_.clear(); // Iterate over all layers, including masks. - for (auto& layer : layers_) + for (auto* layer : *this) layer->ResetChangeTracking(); property_trees_.ResetAllChangeTracking(); }
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index e96cdd1..4d28bc6 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h
@@ -163,7 +163,7 @@ // Other public methods // --------------------------------------------------------------------------- LayerImpl* root_layer_for_testing() { - return layer_list_.empty() ? nullptr : layer_list_[0]; + return layer_list_.empty() ? nullptr : layer_list_[0].get(); } const RenderSurfaceImpl* RootRenderSurface() const; bool LayerListIsEmpty() const; @@ -191,12 +191,35 @@ void ForceRecalculateRasterScales(); - LayerImplList::const_iterator begin() const; - LayerImplList::const_iterator end() const; - LayerImplList::const_reverse_iterator rbegin() const; - LayerImplList::const_reverse_iterator rend() const; - LayerImplList::reverse_iterator rbegin(); - LayerImplList::reverse_iterator rend(); + // Adapts an iterator of std::unique_ptr<LayerImpl> to an iterator of + // LayerImpl*. + template <typename Iterator> + class IteratorAdapter { + public: + explicit IteratorAdapter(Iterator it) : it_(it) {} + bool operator==(IteratorAdapter o) const { return it_ == o.it_; } + bool operator!=(IteratorAdapter o) const { return !(*this == o); } + LayerImpl* operator*() const { return it_->get(); } + LayerImpl* operator->() const { return it_->get(); } + IteratorAdapter& operator++() { + ++it_; + return *this; + } + + private: + Iterator it_; + }; + using const_iterator = IteratorAdapter<OwnedLayerImplList::const_iterator>; + using const_reverse_iterator = + IteratorAdapter<OwnedLayerImplList::const_reverse_iterator>; + const_iterator begin() const { return const_iterator(layer_list_.cbegin()); } + const_iterator end() const { return const_iterator(layer_list_.cend()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(layer_list_.crbegin()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(layer_list_.crend()); + } void SetTransformMutated(ElementId element_id, const gfx::Transform& transform); @@ -485,11 +508,6 @@ // Append a layer to the list. void AddLayer(std::unique_ptr<LayerImpl> layer); - // Mask layer is special: it's managed by LayerTreeImpl (in layers_), but - // not in layer_list_. TODO(wangxianzhu): Remove this when we switch ui - // compositor to property based masks. - void AddMaskLayer(std::unique_ptr<LayerImpl> mask_layer); - size_t NumLayers(); void DidBecomeActive(); @@ -678,8 +696,6 @@ private: friend class LayerTreeHost; - void AddOwnedLayer(std::unique_ptr<LayerImpl> layer); - TransformNode* PageScaleTransformNode(); void UpdatePageScaleNode(); @@ -725,13 +741,9 @@ // TODO(wangxianzhu): Combine layers_ and layer_list_ when we remove // support of mask layers. - // Contains all managed layers, including layers in layer_list_ and mask - // layers. - OwnedLayerImplList layers_; - // Maps from layer id to layer (for each layer in layers_). + OwnedLayerImplList layer_list_; + // Maps from layer id to layer. LayerImplMap layer_id_map_; - // Contains non-mask layers, sorted in draw order. - LayerImplList layer_list_; // Set of layers that need to push properties. base::flat_set<LayerImpl*> layers_that_should_push_properties_;
diff --git a/cc/trees/occlusion_tracker.cc b/cc/trees/occlusion_tracker.cc index e4da0f3f..363461f 100644 --- a/cc/trees/occlusion_tracker.cc +++ b/cc/trees/occlusion_tracker.cc
@@ -196,8 +196,7 @@ // If the occlusion within the surface can not be applied to things outside of // the surface's subtree, then clear the occlusion here so it won't be used. - if (finished_target_surface->HasMask() || - finished_target_surface->HasMaskingContributingSurface() || + if (finished_target_surface->HasMaskingContributingSurface() || finished_target_surface->draw_opacity() < 1 || !finished_target_surface->UsesDefaultBlendMode() || target_is_only_for_copy_request_or_force_render_surface ||
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc index f8264369..7e4aa2da 100644 --- a/cc/trees/property_tree.cc +++ b/cc/trees/property_tree.cc
@@ -708,7 +708,6 @@ void EffectTree::clear() { PropertyTree<EffectNode>::clear(); - mask_layer_ids_.clear(); render_surfaces_.clear(); render_surfaces_.push_back(nullptr); @@ -1024,10 +1023,6 @@ return id_1; } -void EffectTree::AddMaskLayerId(int id) { - mask_layer_ids_.push_back(id); -} - bool EffectTree::ContributesToDrawnSurface(int id) { // All drawn nodes contribute to drawn surface. // Exception : Nodes that are hidden and are drawn only for the sake of @@ -1138,7 +1133,7 @@ for (; effect_node->id != kContentsRootNodeId; effect_node = Node(effect_node->parent_id)) { if (!effect_node->rounded_corner_bounds.IsEmpty() || - effect_node->has_masking_child || effect_node->is_masked) + effect_node->has_masking_child) return true; } return false; @@ -1176,7 +1171,6 @@ EffectTree& EffectTree::operator=(const EffectTree& from) { PropertyTree::operator=(from); render_surfaces_.resize(size()); - mask_layer_ids_ = from.mask_layer_ids_; // copy_requests_ are omitted here, since these need to be moved rather // than copied or assigned. @@ -1184,8 +1178,7 @@ } bool EffectTree::operator==(const EffectTree& other) const { - return PropertyTree::operator==(other) && - mask_layer_ids_ == other.mask_layer_ids_; + return PropertyTree::operator==(other); } ScrollTree::ScrollTree()
diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h index 19a905e..01b096e 100644 --- a/cc/trees/property_tree.h +++ b/cc/trees/property_tree.h
@@ -325,9 +325,6 @@ // surface. int LowestCommonAncestorWithRenderSurface(int id_1, int id_2) const; - void AddMaskLayerId(int id); - const std::vector<int>& mask_layer_ids() const { return mask_layer_ids_; } - RenderSurfaceImpl* GetRenderSurface(int id) { return render_surfaces_[id].get(); } @@ -371,9 +368,6 @@ std::unordered_multimap<int, std::unique_ptr<viz::CopyOutputRequest>> copy_requests_; - // Unsorted list of all mask layer ids that effect nodes refer to. - std::vector<int> mask_layer_ids_; - // Indexed by node id. std::vector<std::unique_ptr<RenderSurfaceImpl>> render_surfaces_; };
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index e8c70c2..5cb5415 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc
@@ -167,7 +167,7 @@ // ------------------------------------------------------------------- bool LayerClipsSubtreeToItsBounds(Layer* layer) { - return layer->masks_to_bounds() || layer->mask_layer(); + return layer->masks_to_bounds() || layer->IsMaskedByChild(); } bool LayerClipsSubtree(Layer* layer) { @@ -350,22 +350,18 @@ if (is_root) return RenderSurfaceReason::kRoot; - // If the layer uses a mask. - if (layer->mask_layer()) { + if (layer->IsMaskedByChild()) { return RenderSurfaceReason::kMask; } - // If the layer uses trilinear filtering. if (layer->trilinear_filtering()) { return RenderSurfaceReason::kTrilinearFiltering; } - // If the layer uses a CSS filter. if (!layer->filters().IsEmpty()) { return RenderSurfaceReason::kFilter; } - // If the layer uses a CSS backdrop-filter. if (!layer->backdrop_filters().IsEmpty()) { return RenderSurfaceReason::kBackdropFilter; } @@ -521,7 +517,6 @@ node->backdrop_filters = layer->backdrop_filters(); node->backdrop_filter_bounds = layer->backdrop_filter_bounds(); node->backdrop_filter_quality = layer->backdrop_filter_quality(); - node->backdrop_mask_element_id = layer->backdrop_mask_element_id(); node->filters_origin = layer->filters_origin(); node->trilinear_filtering = layer->trilinear_filtering(); node->has_potential_opacity_animation = has_potential_opacity_animation; @@ -543,12 +538,6 @@ ? node_id : data_from_ancestor.closest_ancestor_with_copy_request; - if (layer->mask_layer()) { - node->mask_layer_id = layer->mask_layer()->id(); - effect_tree_.AddMaskLayerId(node->mask_layer_id); - node->is_masked = true; - } - if (layer->HasRoundedCorner()) { // This is currently in the local space of the layer and hence in an invalid // space. Once we have the associated transform node for this effect node, @@ -786,17 +775,6 @@ created_render_surface = UpdateRenderSurfaceIfNeeded( data_from_parent.effect_tree_parent, &data_for_children, subtree_has_rounded_corner, created_transform_node); - - if (layer->mask_layer()) { - layer->mask_layer()->set_property_tree_sequence_number( - property_trees_.sequence_number); - layer->mask_layer()->SetOffsetToTransformParent( - layer->offset_to_transform_parent()); - layer->mask_layer()->SetTransformTreeIndex(layer->transform_tree_index()); - layer->mask_layer()->SetClipTreeIndex(layer->clip_tree_index()); - layer->mask_layer()->SetEffectTreeIndex(layer->effect_tree_index()); - layer->mask_layer()->SetScrollTreeIndex(layer->scroll_tree_index()); - } } void PropertyTreeBuilderContext::BuildPropertyTrees() {
diff --git a/cc/trees/tree_synchronizer.cc b/cc/trees/tree_synchronizer.cc index 6d2bab4a..0419820 100644 --- a/cc/trees/tree_synchronizer.cc +++ b/cc/trees/tree_synchronizer.cc
@@ -103,12 +103,6 @@ } PushLayerList(&old_layer_map, source_tree, tree_impl); - - for (int id : property_trees->effect_tree.mask_layer_ids()) { - std::unique_ptr<LayerImpl> layer_impl(ReuseOrCreateLayerImpl( - &old_layer_map, source_tree->LayerById(id), tree_impl)); - tree_impl->AddMaskLayer(std::move(layer_impl)); - } } } // namespace
diff --git a/cc/trees/tree_synchronizer_unittest.cc b/cc/trees/tree_synchronizer_unittest.cc index 0869072..b383409 100644 --- a/cc/trees/tree_synchronizer_unittest.cc +++ b/cc/trees/tree_synchronizer_unittest.cc
@@ -109,16 +109,6 @@ EXPECT_EQ(layer->non_fast_scrollable_region(), layer_impl->non_fast_scrollable_region()); - - const EffectTree& effect_tree = tree_impl->property_trees()->effect_tree; - if (layer->mask_layer()) { - SCOPED_TRACE("mask_layer"); - int mask_layer_id = layer->mask_layer()->id(); - EXPECT_TRUE(tree_impl->LayerById(mask_layer_id)); - EXPECT_EQ( - mask_layer_id, - effect_tree.Node(layer_impl->effect_tree_index())->mask_layer_id); - } } }
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index a1cca37..cd3c295b 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -1780,14 +1780,18 @@ } } -monochrome_public_apk_or_module_tmpl("monochrome_public_apk") { - version_code = monochrome_version_code - version_name = chrome_version_name - apk_name = "MonochromePublic" - target_type = "android_apk" -} - if (public_android_sdk) { + # Can't defined monochrome_public_apk without public_android_sdk or else the + # shared_resources_whitelist_target will not be applied, and R8 -checkdiscards + # will fail. + # https://crbug.com/1000763 + monochrome_public_apk_or_module_tmpl("monochrome_public_apk") { + version_code = monochrome_version_code + version_name = chrome_version_name + apk_name = "MonochromePublic" + target_type = "android_apk" + } + trichrome_library_apk_tmpl("trichrome_library_apk") { apk_name = "TrichromeLibrary" android_manifest = trichrome_library_android_manifest @@ -2140,11 +2144,13 @@ android_test_apk_name = "ChromeSmokeTest" } -instrumentation_test_runner("monochrome_public_smoke_test") { - apk_under_test = ":monochrome_public_apk" - android_test_apk = ":chrome_smoke_test_apk" - android_test_apk_name = "ChromeSmokeTest" - never_incremental = true +if (public_android_sdk) { + instrumentation_test_runner("monochrome_public_smoke_test") { + apk_under_test = ":monochrome_public_apk" + android_test_apk = ":chrome_smoke_test_apk" + android_test_apk_name = "ChromeSmokeTest" + never_incremental = true + } } android_test_apk("chrome_bundle_smoke_test_apk") { @@ -2196,7 +2202,7 @@ extra_args = _bundle_smoke_test_extra_args } -if (defined(expected_static_initializer_count)) { +if (public_android_sdk && defined(expected_static_initializer_count)) { action_with_pydeps("monochrome_static_initializers") { script = "//build/android/gyp/assert_static_initializers.py" inputs = [
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index f1b2f69..5f80686 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -1827,24 +1827,14 @@ "java/src/org/chromium/chrome/browser/widget/ThumbnailProvider.java", "java/src/org/chromium/chrome/browser/widget/ThumbnailProviderImpl.java", "java/src/org/chromium/chrome/browser/widget/ThumbnailStorageDelegate.java", - "java/src/org/chromium/chrome/browser/widget/TintedDrawable.java", "java/src/org/chromium/chrome/browser/widget/ViewHighlighter.java", "java/src/org/chromium/chrome/browser/widget/ViewResourceFrameLayout.java", - "java/src/org/chromium/chrome/browser/widget/animation/AnimatorProperties.java", - "java/src/org/chromium/chrome/browser/widget/animation/CancelAwareAnimatorListener.java", - "java/src/org/chromium/chrome/browser/widget/animation/FocusAnimator.java", "java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java", "java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java", "java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserver.java", "java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetSwipeDetector.java", "java/src/org/chromium/chrome/browser/widget/bottomsheet/EmptyBottomSheetObserver.java", "java/src/org/chromium/chrome/browser/widget/bottomsheet/TouchRestrictingFrameLayout.java", - "java/src/org/chromium/chrome/browser/widget/displaystyle/DisplayStyleObserver.java", - "java/src/org/chromium/chrome/browser/widget/displaystyle/DisplayStyleObserverAdapter.java", - "java/src/org/chromium/chrome/browser/widget/displaystyle/HorizontalDisplayStyle.java", - "java/src/org/chromium/chrome/browser/widget/displaystyle/UiConfig.java", - "java/src/org/chromium/chrome/browser/widget/displaystyle/VerticalDisplayStyle.java", - "java/src/org/chromium/chrome/browser/widget/displaystyle/ViewResizer.java", "java/src/org/chromium/chrome/browser/widget/dragreorder/DragReorderableListAdapter.java", "java/src/org/chromium/chrome/browser/widget/dragreorder/DragStateDelegate.java", "java/src/org/chromium/chrome/browser/widget/prefeditor/Completable.java",
diff --git a/chrome/android/features/autofill_assistant/BUILD.gn b/chrome/android/features/autofill_assistant/BUILD.gn index de70446..9e474f15 100644 --- a/chrome/android/features/autofill_assistant/BUILD.gn +++ b/chrome/android/features/autofill_assistant/BUILD.gn
@@ -34,6 +34,7 @@ "//chrome/android:chrome_java", "//chrome/android:chrome_public_java", "//chrome/android/public/profiles:java", + "//chrome/browser/ui/android/widget:java", "//chrome/lib/image_fetcher/public/android:java", "//components/policy/android:policy_java", "//components/signin/core/browser/android:java",
diff --git a/chrome/android/features/autofill_assistant/java/DEPS b/chrome/android/features/autofill_assistant/java/DEPS index c3de06b..3db3194 100644 --- a/chrome/android/features/autofill_assistant/java/DEPS +++ b/chrome/android/features/autofill_assistant/java/DEPS
@@ -1,4 +1,5 @@ include_rules = [ "+chrome/lib/image_fetcher", + "+chrome/browser/ui/android/widget", "+content/public/android/java/src/org/chromium/content_public/browser", ]
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantVerticalExpander.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantVerticalExpander.java index c9ea331..6608f71 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantVerticalExpander.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantVerticalExpander.java
@@ -17,7 +17,7 @@ import org.chromium.base.Callback; import org.chromium.chrome.autofill_assistant.R; -import org.chromium.chrome.browser.widget.TintedDrawable; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; /** * This class provides a vertical expander widget, which allows to toggle between a collapsed and an
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java index 91ee1f9..81912ef 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
@@ -150,8 +150,7 @@ return new BottomSheetController(activity, activity.getLifecycleDispatcher(), activity.getActivityTabProvider(), activity.getScrim(), bottomSheet, - activity.getCompositorViewHolder().getLayoutManager().getOverlayPanelManager(), - /* suppressSheetForContextualSearch= */ false); + activity.getCompositorViewHolder().getLayoutManager().getOverlayPanelManager()); } /**
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index ed90a64a..a163a61 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -146,6 +146,7 @@ "//chrome/android/features/start_surface/internal:java", "//chrome/android/public/profiles:java", "//chrome/app:java_strings_grd", + "//chrome/browser/ui/android/widget:java", "//chrome/lib/lifecycle/public/android:java", "//chrome/lib/util/public/android:java", "//components/embedder_support/android:web_contents_delegate_java",
diff --git a/chrome/android/features/tab_ui/java/DEPS b/chrome/android/features/tab_ui/java/DEPS index af7fdd5..af94253 100644 --- a/chrome/android/features/tab_ui/java/DEPS +++ b/chrome/android/features/tab_ui/java/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+chrome/lib/lifecycle/public/android/java/src/org/chromium/chrome/browser/lifecycle", + "+chrome/browser/ui/android/widget", "+components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement", "+components/module_installer",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorToolbar.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorToolbar.java index 6171fbf5..467e3f2 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorToolbar.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorToolbar.java
@@ -11,8 +11,8 @@ import android.util.AttributeSet; import android.widget.Button; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.widget.NumberRollView; -import org.chromium.chrome.browser.widget.TintedDrawable; import org.chromium.chrome.browser.widget.selection.SelectableListToolbar; import org.chromium.chrome.tab_ui.R;
diff --git a/chrome/android/feed/core/DEPS b/chrome/android/feed/core/DEPS index 49d9287..1aacfe85 100644 --- a/chrome/android/feed/core/DEPS +++ b/chrome/android/feed/core/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+chrome/lib/lifecycle/public", + "+chrome/browser/ui/android/widget", "+components/background_task_scheduler", "+components/feature_engagement", "+components/feed",
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedContentBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedContentBridge.java index 03eef13d..5eb7bbf8 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedContentBridge.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedContentBridge.java
@@ -15,6 +15,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.profiles.Profile; import java.util.HashMap; @@ -35,7 +36,7 @@ * @param profile {@link Profile} of the user we are rendering the Feed for. */ public FeedContentBridge(Profile profile) { - mNativeFeedContentBridge = nativeInit(profile); + mNativeFeedContentBridge = FeedContentBridgeJni.get().init(FeedContentBridge.this, profile); } /** @@ -48,7 +49,7 @@ /** Cleans up native half of this bridge. */ public void destroy() { assert mNativeFeedContentBridge != 0; - nativeDestroy(mNativeFeedContentBridge); + FeedContentBridgeJni.get().destroy(mNativeFeedContentBridge, FeedContentBridge.this); mNativeFeedContentBridge = 0; } @@ -56,54 +57,62 @@ Callback<Void> failureCallback) { assert mNativeFeedContentBridge != 0; String[] keysArray = keys.toArray(new String[keys.size()]); - nativeLoadContent(mNativeFeedContentBridge, keysArray, successCallback, failureCallback); + FeedContentBridgeJni.get().loadContent(mNativeFeedContentBridge, FeedContentBridge.this, + keysArray, successCallback, failureCallback); } public void loadContentByPrefix(String prefix, Callback<Map<String, byte[]>> successCallback, Callback<Void> failureCallback) { assert mNativeFeedContentBridge != 0; - nativeLoadContentByPrefix( - mNativeFeedContentBridge, prefix, successCallback, failureCallback); + FeedContentBridgeJni.get().loadContentByPrefix(mNativeFeedContentBridge, + FeedContentBridge.this, prefix, successCallback, failureCallback); } public void loadAllContentKeys( Callback<String[]> successCallback, Callback<Void> failureCallback) { assert mNativeFeedContentBridge != 0; - nativeLoadAllContentKeys(mNativeFeedContentBridge, successCallback, failureCallback); + FeedContentBridgeJni.get().loadAllContentKeys( + mNativeFeedContentBridge, FeedContentBridge.this, successCallback, failureCallback); } public void commitContentMutation(ContentMutation contentMutation, Callback<Boolean> callback) { assert mNativeFeedContentBridge != 0; - nativeCreateContentMutation(mNativeFeedContentBridge); + FeedContentBridgeJni.get().createContentMutation( + mNativeFeedContentBridge, FeedContentBridge.this); for (ContentOperation operation : contentMutation.getOperations()) { switch (operation.getType()) { case Type.UPSERT: Upsert upsert = (Upsert) operation; - nativeAppendUpsertOperation( - mNativeFeedContentBridge, upsert.getKey(), upsert.getValue()); + FeedContentBridgeJni.get().appendUpsertOperation(mNativeFeedContentBridge, + FeedContentBridge.this, upsert.getKey(), upsert.getValue()); break; case Type.DELETE: Delete delete = (Delete) operation; - nativeAppendDeleteOperation(mNativeFeedContentBridge, delete.getKey()); + FeedContentBridgeJni.get().appendDeleteOperation( + mNativeFeedContentBridge, FeedContentBridge.this, delete.getKey()); break; case Type.DELETE_BY_PREFIX: DeleteByPrefix deleteByPrefix = (DeleteByPrefix) operation; - nativeAppendDeleteByPrefixOperation( - mNativeFeedContentBridge, deleteByPrefix.getPrefix()); + FeedContentBridgeJni.get().appendDeleteByPrefixOperation( + mNativeFeedContentBridge, FeedContentBridge.this, + deleteByPrefix.getPrefix()); break; case Type.DELETE_ALL: - nativeAppendDeleteAllOperation(mNativeFeedContentBridge); + FeedContentBridgeJni.get().appendDeleteAllOperation( + mNativeFeedContentBridge, FeedContentBridge.this); break; default: // Operation type is not supported, therefore failing immediately. assert false : "Unsupported type of operation."; - nativeDeleteContentMutation(mNativeFeedContentBridge); + FeedContentBridgeJni.get().deleteContentMutation( + mNativeFeedContentBridge, FeedContentBridge.this); callback.onResult(false); return; } } - nativeCommitContentMutation(mNativeFeedContentBridge, callback); + FeedContentBridgeJni.get().commitContentMutation( + mNativeFeedContentBridge, FeedContentBridge.this, callback); } @CalledByNative @@ -116,22 +125,27 @@ return valueMap; } - private native long nativeInit(Profile profile); - private native void nativeDestroy(long nativeFeedContentBridge); - private native void nativeLoadContent(long nativeFeedContentBridge, String[] keys, - Callback<Map<String, byte[]>> successCallback, Callback<Void> failureCallback); - private native void nativeLoadContentByPrefix(long nativeFeedContentBridge, String prefix, - Callback<Map<String, byte[]>> successCallback, Callback<Void> failureCallback); - private native void nativeLoadAllContentKeys(long nativeFeedContentBridge, - Callback<String[]> successCallback, Callback<Void> failureCallback); - private native void nativeCommitContentMutation( - long nativeFeedContentBridge, Callback<Boolean> callback); - private native void nativeCreateContentMutation(long nativeFeedContentBridge); - private native void nativeDeleteContentMutation(long nativeFeedContentBridge); - private native void nativeAppendDeleteOperation(long nativeFeedContentBridge, String key); - private native void nativeAppendDeleteByPrefixOperation( - long nativeFeedContentBridge, String prefix); - private native void nativeAppendUpsertOperation( - long nativeFeedContentBridge, String key, byte[] data); - private native void nativeAppendDeleteAllOperation(long nativeFeedContentBridge); + @NativeMethods + interface Natives { + long init(FeedContentBridge caller, Profile profile); + void destroy(long nativeFeedContentBridge, FeedContentBridge caller); + void loadContent(long nativeFeedContentBridge, FeedContentBridge caller, String[] keys, + Callback<Map<String, byte[]>> successCallback, Callback<Void> failureCallback); + void loadContentByPrefix(long nativeFeedContentBridge, FeedContentBridge caller, + String prefix, Callback<Map<String, byte[]>> successCallback, + Callback<Void> failureCallback); + void loadAllContentKeys(long nativeFeedContentBridge, FeedContentBridge caller, + Callback<String[]> successCallback, Callback<Void> failureCallback); + void commitContentMutation( + long nativeFeedContentBridge, FeedContentBridge caller, Callback<Boolean> callback); + void createContentMutation(long nativeFeedContentBridge, FeedContentBridge caller); + void deleteContentMutation(long nativeFeedContentBridge, FeedContentBridge caller); + void appendDeleteOperation( + long nativeFeedContentBridge, FeedContentBridge caller, String key); + void appendDeleteByPrefixOperation( + long nativeFeedContentBridge, FeedContentBridge caller, String prefix); + void appendUpsertOperation( + long nativeFeedContentBridge, FeedContentBridge caller, String key, byte[] data); + void appendDeleteAllOperation(long nativeFeedContentBridge, FeedContentBridge caller); + } }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedJournalBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedJournalBridge.java index c8de06b..f99d372 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedJournalBridge.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedJournalBridge.java
@@ -13,6 +13,7 @@ import org.chromium.base.Callback; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.profiles.Profile; /** @@ -30,7 +31,7 @@ */ public FeedJournalBridge(Profile profile) { - mNativeFeedJournalBridge = nativeInit(profile); + mNativeFeedJournalBridge = FeedJournalBridgeJni.get().init(FeedJournalBridge.this, profile); } /** @@ -42,7 +43,7 @@ /** Cleans up native half of this bridge. */ public void destroy() { assert mNativeFeedJournalBridge != 0; - nativeDestroy(mNativeFeedJournalBridge); + FeedJournalBridgeJni.get().destroy(mNativeFeedJournalBridge, FeedJournalBridge.this); mNativeFeedJournalBridge = 0; } @@ -50,7 +51,8 @@ public void loadJournal(String journalName, Callback<byte[][]> successCallback, Callback<Void> failureCallback) { assert mNativeFeedJournalBridge != 0; - nativeLoadJournal(mNativeFeedJournalBridge, journalName, successCallback, failureCallback); + FeedJournalBridgeJni.get().loadJournal(mNativeFeedJournalBridge, FeedJournalBridge.this, + journalName, successCallback, failureCallback); } /** @@ -62,68 +64,82 @@ public void commitJournalMutation(JournalMutation mutation, Callback<Boolean> callback) { assert mNativeFeedJournalBridge != 0; - nativeStartJournalMutation(mNativeFeedJournalBridge, mutation.getJournalName()); + FeedJournalBridgeJni.get().startJournalMutation( + mNativeFeedJournalBridge, FeedJournalBridge.this, mutation.getJournalName()); for (JournalOperation operation : mutation.getOperations()) { switch (operation.getType()) { case Type.APPEND: Append append = (Append) operation; - nativeAddAppendOperation(mNativeFeedJournalBridge, append.getValue()); + FeedJournalBridgeJni.get().addAppendOperation( + mNativeFeedJournalBridge, FeedJournalBridge.this, append.getValue()); break; case Type.COPY: Copy copy = (Copy) operation; - nativeAddCopyOperation(mNativeFeedJournalBridge, copy.getToJournalName()); + FeedJournalBridgeJni.get().addCopyOperation(mNativeFeedJournalBridge, + FeedJournalBridge.this, copy.getToJournalName()); break; case Type.DELETE: - nativeAddDeleteOperation(mNativeFeedJournalBridge); + FeedJournalBridgeJni.get().addDeleteOperation( + mNativeFeedJournalBridge, FeedJournalBridge.this); break; default: // Operation type is not supported, therefore failing immediately. assert false : "Unsupported type of operation."; - nativeDeleteJournalMutation(mNativeFeedJournalBridge); + FeedJournalBridgeJni.get().deleteJournalMutation( + mNativeFeedJournalBridge, FeedJournalBridge.this); callback.onResult(false); return; } } - nativeCommitJournalMutation(mNativeFeedJournalBridge, callback); + FeedJournalBridgeJni.get().commitJournalMutation( + mNativeFeedJournalBridge, FeedJournalBridge.this, callback); } /** Determines whether a journal exists and asynchronously responds. */ public void doesJournalExist( String journalName, Callback<Boolean> successCallback, Callback<Void> failureCallback) { assert mNativeFeedJournalBridge != 0; - nativeDoesJournalExist( - mNativeFeedJournalBridge, journalName, successCallback, failureCallback); + FeedJournalBridgeJni.get().doesJournalExist(mNativeFeedJournalBridge, + FeedJournalBridge.this, journalName, successCallback, failureCallback); } /** Asynchronously retrieve a list of all current journals' name. */ public void loadAllJournalKeys( Callback<String[]> successCallback, Callback<Void> failureCallback) { assert mNativeFeedJournalBridge != 0; - nativeLoadAllJournalKeys(mNativeFeedJournalBridge, successCallback, failureCallback); + FeedJournalBridgeJni.get().loadAllJournalKeys( + mNativeFeedJournalBridge, FeedJournalBridge.this, successCallback, failureCallback); } /** Delete all journals. Reports success or failure. */ public void deleteAllJournals(Callback<Boolean> callback) { assert mNativeFeedJournalBridge != 0; - nativeDeleteAllJournals(mNativeFeedJournalBridge, callback); + FeedJournalBridgeJni.get().deleteAllJournals( + mNativeFeedJournalBridge, FeedJournalBridge.this, callback); } - private native long nativeInit(Profile profile); - private native void nativeDestroy(long nativeFeedJournalBridge); - private native void nativeLoadJournal(long nativeFeedJournalBridge, String journalName, - Callback<byte[][]> successCallback, Callback<Void> failureCallback); - private native void nativeCommitJournalMutation( - long nativeFeedJournalBridge, Callback<Boolean> callback); - private native void nativeStartJournalMutation( - long nativeFeedJournalBridge, String journalName); - private native void nativeDeleteJournalMutation(long nativeFeedJournalBridge); - private native void nativeAddAppendOperation(long nativeFeedJournalBridge, byte[] value); - private native void nativeAddCopyOperation(long nativeFeedJournalBridge, String toJournalName); - private native void nativeAddDeleteOperation(long nativeFeedJournalBridge); - private native void nativeDoesJournalExist(long nativeFeedJournalBridge, String journalName, - Callback<Boolean> successCallback, Callback<Void> failureCallback); - private native void nativeLoadAllJournalKeys(long nativeFeedJournalBridge, - Callback<String[]> successCallback, Callback<Void> failureCallback); - private native void nativeDeleteAllJournals( - long nativeFeedJournalBridge, Callback<Boolean> callback); + @NativeMethods + interface Natives { + long init(FeedJournalBridge caller, Profile profile); + void destroy(long nativeFeedJournalBridge, FeedJournalBridge caller); + void loadJournal(long nativeFeedJournalBridge, FeedJournalBridge caller, String journalName, + Callback<byte[][]> successCallback, Callback<Void> failureCallback); + void commitJournalMutation( + long nativeFeedJournalBridge, FeedJournalBridge caller, Callback<Boolean> callback); + void startJournalMutation( + long nativeFeedJournalBridge, FeedJournalBridge caller, String journalName); + void deleteJournalMutation(long nativeFeedJournalBridge, FeedJournalBridge caller); + void addAppendOperation( + long nativeFeedJournalBridge, FeedJournalBridge caller, byte[] value); + void addCopyOperation( + long nativeFeedJournalBridge, FeedJournalBridge caller, String toJournalName); + void addDeleteOperation(long nativeFeedJournalBridge, FeedJournalBridge caller); + void doesJournalExist(long nativeFeedJournalBridge, FeedJournalBridge caller, + String journalName, Callback<Boolean> successCallback, + Callback<Void> failureCallback); + void loadAllJournalKeys(long nativeFeedJournalBridge, FeedJournalBridge caller, + Callback<String[]> successCallback, Callback<Void> failureCallback); + void deleteAllJournals( + long nativeFeedJournalBridge, FeedJournalBridge caller, Callback<Boolean> callback); + } }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLifecycleBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLifecycleBridge.java index bfc9d62..7ee6596 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLifecycleBridge.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLifecycleBridge.java
@@ -7,6 +7,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.profiles.Profile; /** @@ -23,7 +24,7 @@ * @param profile Profile of the user whose lifecycle events we care about. */ public FeedLifecycleBridge(Profile profile) { - mNativeBridge = nativeInit(profile); + mNativeBridge = FeedLifecycleBridgeJni.get().init(FeedLifecycleBridge.this, profile); } /* @@ -31,7 +32,7 @@ */ public void destroy() { assert mNativeBridge != 0; - nativeDestroy(mNativeBridge); + FeedLifecycleBridgeJni.get().destroy(mNativeBridge, FeedLifecycleBridge.this); mNativeBridge = 0; } @@ -53,6 +54,9 @@ } } - private native long nativeInit(Profile profile); - private native void nativeDestroy(long nativeFeedLifecycleBridge); + @NativeMethods + interface Natives { + long init(FeedLifecycleBridge caller, Profile profile); + void destroy(long nativeFeedLifecycleBridge, FeedLifecycleBridge caller); + } } \ No newline at end of file
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java index 769a101..5ce2508 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java
@@ -21,6 +21,7 @@ import com.google.search.now.ui.action.FeedActionProto; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.ntp.NewTabPageUma; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.ui.mojom.WindowOpenDisposition; @@ -43,7 +44,7 @@ * @param profile {@link Profile} of the user we are rendering the Feed for. */ public FeedLoggingBridge(Profile profile) { - mNativeFeedLoggingBridge = nativeInit(profile); + mNativeFeedLoggingBridge = FeedLoggingBridgeJni.get().init(FeedLoggingBridge.this, profile); } /** Cleans up native half of this bridge. */ @@ -52,7 +53,7 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeDestroy(mNativeFeedLoggingBridge); + FeedLoggingBridgeJni.get().destroy(mNativeFeedLoggingBridge, FeedLoggingBridge.this); mNativeFeedLoggingBridge = 0; } @@ -62,7 +63,8 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeOnContentViewed(mNativeFeedLoggingBridge, data.getPositionInStream(), + FeedLoggingBridgeJni.get().onContentViewed(mNativeFeedLoggingBridge, FeedLoggingBridge.this, + data.getPositionInStream(), TimeUnit.SECONDS.toMillis(data.getPublishedTimeSeconds()), TimeUnit.SECONDS.toMillis(data.getTimeContentBecameAvailable()), data.getScore(), data.isAvailableOffline()); @@ -74,8 +76,9 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeOnContentDismissed(mNativeFeedLoggingBridge, data.getPositionInStream(), - data.getRepresentationUri(), wasCommitted); + FeedLoggingBridgeJni.get().onContentDismissed(mNativeFeedLoggingBridge, + FeedLoggingBridge.this, data.getPositionInStream(), data.getRepresentationUri(), + wasCommitted); } @Override @@ -84,7 +87,8 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeOnContentSwiped(mNativeFeedLoggingBridge); + FeedLoggingBridgeJni.get().onContentSwiped( + mNativeFeedLoggingBridge, FeedLoggingBridge.this); } @Override @@ -102,7 +106,7 @@ if (mNativeFeedLoggingBridge == 0) return; recordUserAction(actionType); - nativeOnClientAction(mNativeFeedLoggingBridge, + FeedLoggingBridgeJni.get().onClientAction(mNativeFeedLoggingBridge, FeedLoggingBridge.this, feedActionToWindowOpenDisposition(actionType), data.getPositionInStream(), TimeUnit.SECONDS.toMillis(data.getPublishedTimeSeconds()), data.getScore(), data.isAvailableOffline()); @@ -114,7 +118,8 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeOnContentContextMenuOpened(mNativeFeedLoggingBridge, data.getPositionInStream(), + FeedLoggingBridgeJni.get().onContentContextMenuOpened(mNativeFeedLoggingBridge, + FeedLoggingBridge.this, data.getPositionInStream(), TimeUnit.SECONDS.toMillis(data.getPublishedTimeSeconds()), data.getScore()); } @@ -124,7 +129,8 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeOnMoreButtonViewed(mNativeFeedLoggingBridge, position); + FeedLoggingBridgeJni.get().onMoreButtonViewed( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, position); } @Override @@ -133,7 +139,8 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeOnMoreButtonClicked(mNativeFeedLoggingBridge, position); + FeedLoggingBridgeJni.get().onMoreButtonClicked( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, position); } @Override @@ -144,12 +151,12 @@ // TODO(crbug.com/935602): Fail to compile when new values are added to NotInterestedInData. if (interestType == FeedActionProto.NotInterestedInData.RecordedInterestType.TOPIC_VALUE) { - nativeOnNotInterestedInTopic( - mNativeFeedLoggingBridge, data.getPositionInStream(), wasCommitted); + FeedLoggingBridgeJni.get().onNotInterestedInTopic(mNativeFeedLoggingBridge, + FeedLoggingBridge.this, data.getPositionInStream(), wasCommitted); } else if (interestType == FeedActionProto.NotInterestedInData.RecordedInterestType.SOURCE_VALUE) { - nativeOnNotInterestedInSource( - mNativeFeedLoggingBridge, data.getPositionInStream(), wasCommitted); + FeedLoggingBridgeJni.get().onNotInterestedInSource(mNativeFeedLoggingBridge, + FeedLoggingBridge.this, data.getPositionInStream(), wasCommitted); } } @@ -159,7 +166,8 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeOnOpenedWithContent(mNativeFeedLoggingBridge, timeToPopulateMs, contentCount); + FeedLoggingBridgeJni.get().onOpenedWithContent( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, timeToPopulateMs, contentCount); } @Override @@ -168,7 +176,8 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeOnOpenedWithNoImmediateContent(mNativeFeedLoggingBridge); + FeedLoggingBridgeJni.get().onOpenedWithNoImmediateContent( + mNativeFeedLoggingBridge, FeedLoggingBridge.this); } @Override @@ -177,7 +186,8 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeOnOpenedWithNoContent(mNativeFeedLoggingBridge); + FeedLoggingBridgeJni.get().onOpenedWithNoContent( + mNativeFeedLoggingBridge, FeedLoggingBridge.this); } @Override @@ -186,7 +196,8 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeOnSpinnerStarted(mNativeFeedLoggingBridge, spinnerType); + FeedLoggingBridgeJni.get().onSpinnerStarted( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, spinnerType); } @Override @@ -195,7 +206,8 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeOnSpinnerFinished(mNativeFeedLoggingBridge, timeShownMs, spinnerType); + FeedLoggingBridgeJni.get().onSpinnerFinished( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, timeShownMs, spinnerType); } @Override @@ -204,8 +216,8 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeOnSpinnerDestroyedWithoutCompleting( - mNativeFeedLoggingBridge, timeShownMs, spinnerType); + FeedLoggingBridgeJni.get().onSpinnerDestroyedWithoutCompleting( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, timeShownMs, spinnerType); } @Override @@ -215,59 +227,66 @@ for (int i = 0; i < pietErrorCodes.size(); ++i) { pietErrorCodesArray[i] = pietErrorCodes.get(i); } - nativeOnPietFrameRenderingEvent(mNativeFeedLoggingBridge, pietErrorCodesArray); + FeedLoggingBridgeJni.get().onPietFrameRenderingEvent( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, pietErrorCodesArray); } @Override public void onVisualElementClicked(ElementLoggingData data, int elementType) { if (mNativeFeedLoggingBridge == 0) return; - nativeOnVisualElementClicked(mNativeFeedLoggingBridge, elementType, - data.getPositionInStream(), + FeedLoggingBridgeJni.get().onVisualElementClicked(mNativeFeedLoggingBridge, + FeedLoggingBridge.this, elementType, data.getPositionInStream(), TimeUnit.SECONDS.toMillis(data.getTimeContentBecameAvailable())); } @Override public void onVisualElementViewed(ElementLoggingData data, int elementType) { if (mNativeFeedLoggingBridge == 0) return; - nativeOnVisualElementViewed(mNativeFeedLoggingBridge, elementType, - data.getPositionInStream(), + FeedLoggingBridgeJni.get().onVisualElementViewed(mNativeFeedLoggingBridge, + FeedLoggingBridge.this, elementType, data.getPositionInStream(), TimeUnit.SECONDS.toMillis(data.getTimeContentBecameAvailable())); } @Override public void onInternalError(@InternalFeedError int internalError) { if (mNativeFeedLoggingBridge == 0) return; - nativeOnInternalError(mNativeFeedLoggingBridge, internalError); + FeedLoggingBridgeJni.get().onInternalError( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, internalError); } @Override public void onTokenCompleted(boolean wasSynthetic, int contentCount, int tokenCount) { if (mNativeFeedLoggingBridge == 0) return; - nativeOnTokenCompleted(mNativeFeedLoggingBridge, wasSynthetic, contentCount, tokenCount); + FeedLoggingBridgeJni.get().onTokenCompleted(mNativeFeedLoggingBridge, + FeedLoggingBridge.this, wasSynthetic, contentCount, tokenCount); } @Override public void onTokenFailedToComplete(boolean wasSynthetic, int failureCount) { if (mNativeFeedLoggingBridge == 0) return; - nativeOnTokenFailedToComplete(mNativeFeedLoggingBridge, wasSynthetic, failureCount); + FeedLoggingBridgeJni.get().onTokenFailedToComplete( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, wasSynthetic, failureCount); } @Override public void onServerRequest(@RequestReason int requestReason) { if (mNativeFeedLoggingBridge == 0) return; - nativeOnServerRequest(mNativeFeedLoggingBridge, requestReason); + FeedLoggingBridgeJni.get().onServerRequest( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, requestReason); } @Override public void onZeroStateShown(@ZeroStateShowReason int zeroStateShowReason) { if (mNativeFeedLoggingBridge == 0) return; - nativeOnZeroStateShown(mNativeFeedLoggingBridge, zeroStateShowReason); + FeedLoggingBridgeJni.get().onZeroStateShown( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, zeroStateShowReason); } @Override public void onZeroStateRefreshCompleted(int newContentCount, int newTokenCount) { if (mNativeFeedLoggingBridge == 0) return; - nativeOnZeroStateRefreshCompleted(mNativeFeedLoggingBridge, newContentCount, newTokenCount); + FeedLoggingBridgeJni.get().onZeroStateRefreshCompleted( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, newContentCount, newTokenCount); } @Override @@ -284,7 +303,8 @@ @Override public void onTaskFinished(@Task int task, int delayTime, int taskTime) { if (mNativeFeedLoggingBridge == 0) return; - nativeOnTaskFinished(mNativeFeedLoggingBridge, task, delayTime, taskTime); + FeedLoggingBridgeJni.get().onTaskFinished( + mNativeFeedLoggingBridge, FeedLoggingBridge.this, task, delayTime, taskTime); } /** @@ -299,8 +319,8 @@ // methods. This method is called by objects not controlled by Feed lifetimes, and destroy() // may have already been called if Feed is disabled by policy. if (mNativeFeedLoggingBridge != 0) { - nativeOnContentTargetVisited( - mNativeFeedLoggingBridge, visitTimeMs, isOffline, returnToNtp); + FeedLoggingBridgeJni.get().onContentTargetVisited(mNativeFeedLoggingBridge, + FeedLoggingBridge.this, visitTimeMs, isOffline, returnToNtp); } } @@ -346,7 +366,8 @@ // See https://crbug.com/901414. if (mNativeFeedLoggingBridge == 0) return; - nativeReportScrolledAfterOpen(mNativeFeedLoggingBridge); + FeedLoggingBridgeJni.get().reportScrolledAfterOpen( + mNativeFeedLoggingBridge, FeedLoggingBridge.this); } /** @@ -374,53 +395,61 @@ public void onScrolled(int dx, int dy) {} } - private native long nativeInit(Profile profile); - private native void nativeDestroy(long nativeFeedLoggingBridge); - private native void nativeOnContentViewed(long nativeFeedLoggingBridge, int position, - long publishedTimeMs, long timeContentBecameAvailableMs, float score, - boolean isAvailableOffline); - private native void nativeOnContentDismissed( - long nativeFeedLoggingBridge, int position, String uri, boolean wasCommitted); - private native void nativeOnContentSwiped(long nativeFeedLoggingBridge); - private native void nativeOnClientAction(long nativeFeedLoggingBridge, - int windowOpenDisposition, int position, long publishedTimeMs, float score, - boolean isAvailableOffline); - private native void nativeOnContentContextMenuOpened( - long nativeFeedLoggingBridge, int position, long publishedTimeMs, float score); - private native void nativeOnMoreButtonViewed(long nativeFeedLoggingBridge, int position); - private native void nativeOnMoreButtonClicked(long nativeFeedLoggingBridge, int position); - private native void nativeOnNotInterestedInSource( - long nativeFeedLoggingBridge, int position, boolean wasCommitted); - private native void nativeOnNotInterestedInTopic( - long nativeFeedLoggingBridge, int position, boolean wasCommitted); - private native void nativeOnOpenedWithContent( - long nativeFeedLoggingBridge, int timeToPopulateMs, int contentCount); - private native void nativeOnOpenedWithNoImmediateContent(long nativeFeedLoggingBridge); - private native void nativeOnOpenedWithNoContent(long nativeFeedLoggingBridge); - private native void nativeOnSpinnerStarted(long nativeFeedLoggingBridge, int spinnerType); - private native void nativeOnSpinnerFinished( - long nativeFeedLoggingBridge, long spinnerShownTimeMs, int spinnerType); - private native void nativeOnSpinnerDestroyedWithoutCompleting( - long nativeFeedLoggingBridge, long spinnerShownTimeMs, int spinnerType); - private native void nativeOnPietFrameRenderingEvent( - long nativeFeedLoggingBridge, int[] pietErrorCodes); - private native void nativeOnVisualElementClicked(long nativeFeedLoggingBridge, int elementType, - int position, long timeContentBecameAvailableMs); - private native void nativeOnVisualElementViewed(long nativeFeedLoggingBridge, int elementType, - int position, long timeContentBecameAvailableMs); - private native void nativeOnInternalError(long nativeFeedLoggingBridge, int internalError); - private native void nativeOnTokenCompleted( - long nativeFeedLoggingBridge, boolean wasSynthetic, int contentCount, int tokenCount); - private native void nativeOnTokenFailedToComplete( - long nativeFeedLoggingBridge, boolean wasSynthetic, int failureCount); - private native void nativeOnServerRequest(long nativeFeedLoggingBridge, int requestReason); - private native void nativeOnZeroStateShown( - long nativeFeedLoggingBridge, int zeroStateShowReason); - private native void nativeOnZeroStateRefreshCompleted( - long nativeFeedLoggingBridge, int newContentCount, int newTokenCount); - private native void nativeOnTaskFinished( - long nativeFeedLoggingBridge, int task, int delayTimeMs, int taskTimeMs); - private native void nativeOnContentTargetVisited( - long nativeFeedLoggingBridge, long visitTimeMs, boolean isOffline, boolean returnToNtp); - private native void nativeReportScrolledAfterOpen(long nativeFeedLoggingBridge); + @NativeMethods + interface Natives { + long init(FeedLoggingBridge caller, Profile profile); + void destroy(long nativeFeedLoggingBridge, FeedLoggingBridge caller); + void onContentViewed(long nativeFeedLoggingBridge, FeedLoggingBridge caller, int position, + long publishedTimeMs, long timeContentBecameAvailableMs, float score, + boolean isAvailableOffline); + void onContentDismissed(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + int position, String uri, boolean wasCommitted); + void onContentSwiped(long nativeFeedLoggingBridge, FeedLoggingBridge caller); + void onClientAction(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + int windowOpenDisposition, int position, long publishedTimeMs, float score, + boolean isAvailableOffline); + void onContentContextMenuOpened(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + int position, long publishedTimeMs, float score); + void onMoreButtonViewed( + long nativeFeedLoggingBridge, FeedLoggingBridge caller, int position); + void onMoreButtonClicked( + long nativeFeedLoggingBridge, FeedLoggingBridge caller, int position); + void onNotInterestedInSource(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + int position, boolean wasCommitted); + void onNotInterestedInTopic(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + int position, boolean wasCommitted); + void onOpenedWithContent(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + int timeToPopulateMs, int contentCount); + void onOpenedWithNoImmediateContent(long nativeFeedLoggingBridge, FeedLoggingBridge caller); + void onOpenedWithNoContent(long nativeFeedLoggingBridge, FeedLoggingBridge caller); + void onSpinnerStarted( + long nativeFeedLoggingBridge, FeedLoggingBridge caller, int spinnerType); + void onSpinnerFinished(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + long spinnerShownTimeMs, int spinnerType); + void onSpinnerDestroyedWithoutCompleting(long nativeFeedLoggingBridge, + FeedLoggingBridge caller, long spinnerShownTimeMs, int spinnerType); + void onPietFrameRenderingEvent( + long nativeFeedLoggingBridge, FeedLoggingBridge caller, int[] pietErrorCodes); + void onVisualElementClicked(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + int elementType, int position, long timeContentBecameAvailableMs); + void onVisualElementViewed(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + int elementType, int position, long timeContentBecameAvailableMs); + void onInternalError( + long nativeFeedLoggingBridge, FeedLoggingBridge caller, int internalError); + void onTokenCompleted(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + boolean wasSynthetic, int contentCount, int tokenCount); + void onTokenFailedToComplete(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + boolean wasSynthetic, int failureCount); + void onServerRequest( + long nativeFeedLoggingBridge, FeedLoggingBridge caller, int requestReason); + void onZeroStateShown( + long nativeFeedLoggingBridge, FeedLoggingBridge caller, int zeroStateShowReason); + void onZeroStateRefreshCompleted(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + int newContentCount, int newTokenCount); + void onTaskFinished(long nativeFeedLoggingBridge, FeedLoggingBridge caller, int task, + int delayTimeMs, int taskTimeMs); + void onContentTargetVisited(long nativeFeedLoggingBridge, FeedLoggingBridge caller, + long visitTimeMs, boolean isOffline, boolean returnToNtp); + void reportScrolledAfterOpen(long nativeFeedLoggingBridge, FeedLoggingBridge caller); + } }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNetworkBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNetworkBridge.java index dda572cb..a3d4aff 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNetworkBridge.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNetworkBridge.java
@@ -12,6 +12,7 @@ import org.chromium.base.Callback; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.profiles.Profile; /** @@ -28,7 +29,7 @@ * @param profile Profile of the user we are rendering the Feed for. */ public FeedNetworkBridge(Profile profile) { - mNativeBridge = nativeInit(profile); + mNativeBridge = FeedNetworkBridgeJni.get().init(FeedNetworkBridge.this, profile); } /* @@ -36,7 +37,7 @@ */ public void destroy() { assert mNativeBridge != 0; - nativeDestroy(mNativeBridge); + FeedNetworkBridgeJni.get().destroy(mNativeBridge, FeedNetworkBridge.this); mNativeBridge = 0; } @@ -45,8 +46,8 @@ if (mNativeBridge == 0) { responseConsumer.accept(createHttpResponse(500, new byte[0])); } else { - nativeSendNetworkRequest(mNativeBridge, request.getUri().toString(), - request.getMethod(), request.getBody(), + FeedNetworkBridgeJni.get().sendNetworkRequest(mNativeBridge, FeedNetworkBridge.this, + request.getUri().toString(), request.getMethod(), request.getBody(), result -> responseConsumer.accept(result)); } } @@ -57,7 +58,7 @@ // See https://crbug.com/901414. if (mNativeBridge == 0) return; - nativeCancelRequests(mNativeBridge); + FeedNetworkBridgeJni.get().cancelRequests(mNativeBridge, FeedNetworkBridge.this); } @CalledByNative @@ -65,9 +66,12 @@ return new HttpResponse(code, body); } - private native long nativeInit(Profile profile); - private native void nativeDestroy(long nativeFeedNetworkBridge); - private native void nativeSendNetworkRequest(long nativeFeedNetworkBridge, String url, - String requestType, byte[] body, Callback<HttpResponse> resultCallback); - private native void nativeCancelRequests(long nativeFeedNetworkBridge); + @NativeMethods + interface Natives { + long init(FeedNetworkBridge caller, Profile profile); + void destroy(long nativeFeedNetworkBridge, FeedNetworkBridge caller); + void sendNetworkRequest(long nativeFeedNetworkBridge, FeedNetworkBridge caller, String url, + String requestType, byte[] body, Callback<HttpResponse> resultCallback); + void cancelRequests(long nativeFeedNetworkBridge, FeedNetworkBridge caller); + } }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedOfflineBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedOfflineBridge.java index f0bd865..ffb2094 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedOfflineBridge.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedOfflineBridge.java
@@ -13,6 +13,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.profiles.Profile; import java.util.ArrayList; @@ -42,7 +43,7 @@ * @param knownContent Interface to access information about the Feed's articles. */ public FeedOfflineBridge(Profile profile, KnownContent knownContent) { - mNativeBridge = nativeInit(profile); + mNativeBridge = FeedOfflineBridgeJni.get().init(FeedOfflineBridge.this, profile); mKnownContentApi = knownContent; mKnownContentApi.addListener(this); } @@ -50,7 +51,7 @@ @Override public void destroy() { assert mNativeBridge != 0; - nativeDestroy(mNativeBridge); + FeedOfflineBridgeJni.get().destroy(mNativeBridge, FeedOfflineBridge.this); mNativeBridge = 0; mKnownContentApi.removeListener(this); } @@ -60,7 +61,8 @@ if (mNativeBridge == 0) { return 0L; } else { - return (Long) nativeGetOfflineId(mNativeBridge, url); + return (Long) FeedOfflineBridgeJni.get().getOfflineId( + mNativeBridge, FeedOfflineBridge.this, url); } } @@ -71,7 +73,8 @@ urlListConsumer.accept(Collections.emptyList()); } else { String[] urlsArray = urlsToRetrieve.toArray(new String[urlsToRetrieve.size()]); - nativeGetOfflineStatus(mNativeBridge, urlsArray, + FeedOfflineBridgeJni.get().getOfflineStatus(mNativeBridge, FeedOfflineBridge.this, + urlsArray, (String[] urlsAsArray) -> urlListConsumer.accept(Arrays.asList(urlsAsArray))); } } @@ -88,7 +91,7 @@ if (mNativeBridge != 0) { mListeners.remove(offlineStatusListener); if (mListeners.isEmpty()) { - nativeOnNoListeners(mNativeBridge); + FeedOfflineBridgeJni.get().onNoListeners(mNativeBridge, FeedOfflineBridge.this); } } } @@ -98,7 +101,7 @@ if (mNativeBridge != 0) { List<String> userDrivenRemovals = takeUserDriveRemovalsOnly(contentRemoved); if (!userDrivenRemovals.isEmpty()) { - nativeOnContentRemoved(mNativeBridge, + FeedOfflineBridgeJni.get().onContentRemoved(mNativeBridge, FeedOfflineBridge.this, userDrivenRemovals.toArray(new String[userDrivenRemovals.size()])); } } @@ -107,7 +110,7 @@ @Override public void onNewContentReceived(boolean isNewRefresh, long contentCreationDateTimeMs) { if (mNativeBridge != 0) { - nativeOnNewContentReceived(mNativeBridge); + FeedOfflineBridgeJni.get().onNewContentReceived(mNativeBridge, FeedOfflineBridge.this); } } @@ -141,11 +144,12 @@ for (ContentMetadata metadata : metadataList) { long time_published_ms = TimeUnit.SECONDS.toMillis(metadata.getTimePublished()); - nativeAppendContentMetadata(mNativeBridge, metadata.getUrl(), metadata.getTitle(), + FeedOfflineBridgeJni.get().appendContentMetadata(mNativeBridge, + FeedOfflineBridge.this, metadata.getUrl(), metadata.getTitle(), time_published_ms, metadata.getImageUrl(), metadata.getPublisher(), metadata.getFaviconUrl(), metadata.getSnippet()); } - nativeOnGetKnownContentDone(mNativeBridge); + FeedOfflineBridgeJni.get().onGetKnownContentDone(mNativeBridge, FeedOfflineBridge.this); }); } @@ -156,16 +160,20 @@ } } - private native long nativeInit(Profile profile); - private native void nativeDestroy(long nativeFeedOfflineBridge); - private native Object nativeGetOfflineId(long nativeFeedOfflineBridge, String url); - private native void nativeGetOfflineStatus(long nativeFeedOfflineBridge, - String[] urlsToRetrieve, Callback<String[]> urlListConsumer); - private native void nativeOnContentRemoved(long nativeFeedOfflineBridge, String[] urlsRemoved); - private native void nativeOnNewContentReceived(long nativeFeedOfflineBridge); - private native void nativeOnNoListeners(long nativeFeedOfflineBridge); - private native void nativeAppendContentMetadata(long nativeFeedOfflineBridge, String url, - String title, long timePublishedMs, String imageUrl, String publisher, - String faviconUrl, String snippet); - private native void nativeOnGetKnownContentDone(long nativeFeedOfflineBridge); + @NativeMethods + interface Natives { + long init(FeedOfflineBridge caller, Profile profile); + void destroy(long nativeFeedOfflineBridge, FeedOfflineBridge caller); + Object getOfflineId(long nativeFeedOfflineBridge, FeedOfflineBridge caller, String url); + void getOfflineStatus(long nativeFeedOfflineBridge, FeedOfflineBridge caller, + String[] urlsToRetrieve, Callback<String[]> urlListConsumer); + void onContentRemoved( + long nativeFeedOfflineBridge, FeedOfflineBridge caller, String[] urlsRemoved); + void onNewContentReceived(long nativeFeedOfflineBridge, FeedOfflineBridge caller); + void onNoListeners(long nativeFeedOfflineBridge, FeedOfflineBridge caller); + void appendContentMetadata(long nativeFeedOfflineBridge, FeedOfflineBridge caller, + String url, String title, long timePublishedMs, String imageUrl, String publisher, + String faviconUrl, String snippet); + void onGetKnownContentDone(long nativeFeedOfflineBridge, FeedOfflineBridge caller); + } }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSchedulerBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSchedulerBridge.java index f473d796..f46d6ae 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSchedulerBridge.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSchedulerBridge.java
@@ -11,6 +11,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.feed.NativeRequestBehavior; @@ -28,13 +29,13 @@ * @param profile Profile of the user we are rendering the Feed for. */ public FeedSchedulerBridge(Profile profile) { - mNativeBridge = nativeInit(profile); + mNativeBridge = FeedSchedulerBridgeJni.get().init(FeedSchedulerBridge.this, profile); } @Override public void destroy() { assert mNativeBridge != 0; - nativeDestroy(mNativeBridge); + FeedSchedulerBridgeJni.get().destroy(mNativeBridge, FeedSchedulerBridge.this); mNativeBridge = 0; } @@ -56,7 +57,8 @@ if (mNativeBridge == 0) return SchedulerApi.RequestBehavior.UNKNOWN; @NativeRequestBehavior - int nativeBehavior = nativeShouldSessionRequestData(mNativeBridge, sessionState.hasContent, + int nativeBehavior = FeedSchedulerBridgeJni.get().shouldSessionRequestData(mNativeBridge, + FeedSchedulerBridge.this, sessionState.hasContent, sessionState.contentCreationDateTimeMs, sessionState.hasOutstandingRequest); // If this breaks, it is because SchedulerApi.RequestBehavior and the NativeRequestBehavior // defined in feed_scheduler_host.h have diverged. If this happens during a feed DEPS roll, @@ -84,39 +86,43 @@ @Override public void onReceiveNewContent(long contentCreationDateTimeMs) { if (mNativeBridge != 0) { - nativeOnReceiveNewContent(mNativeBridge, contentCreationDateTimeMs); + FeedSchedulerBridgeJni.get().onReceiveNewContent( + mNativeBridge, FeedSchedulerBridge.this, contentCreationDateTimeMs); } } @Override public void onRequestError(int networkResponseCode) { if (mNativeBridge != 0) { - nativeOnRequestError(mNativeBridge, networkResponseCode); + FeedSchedulerBridgeJni.get().onRequestError( + mNativeBridge, FeedSchedulerBridge.this, networkResponseCode); } } @Override public void onForegrounded() { assert mNativeBridge != 0; - nativeOnForegrounded(mNativeBridge); + FeedSchedulerBridgeJni.get().onForegrounded(mNativeBridge, FeedSchedulerBridge.this); } @Override public void onFixedTimer(Runnable onCompletion) { assert mNativeBridge != 0; - nativeOnFixedTimer(mNativeBridge, onCompletion); + FeedSchedulerBridgeJni.get().onFixedTimer( + mNativeBridge, FeedSchedulerBridge.this, onCompletion); } @Override public void onSuggestionConsumed() { assert mNativeBridge != 0; - nativeOnSuggestionConsumed(mNativeBridge); + FeedSchedulerBridgeJni.get().onSuggestionConsumed(mNativeBridge, FeedSchedulerBridge.this); } @Override public boolean onArticlesCleared(boolean suppressRefreshes) { assert mNativeBridge != 0; - return nativeOnArticlesCleared(mNativeBridge, suppressRefreshes); + return FeedSchedulerBridgeJni.get().onArticlesCleared( + mNativeBridge, FeedSchedulerBridge.this, suppressRefreshes); } @CalledByNative @@ -138,17 +144,21 @@ FeedRefreshTask.cancelWakeUp(); } - private native long nativeInit(Profile profile); - private native void nativeDestroy(long nativeFeedSchedulerBridge); - private native int nativeShouldSessionRequestData(long nativeFeedSchedulerBridge, - boolean hasContent, long contentCreationDateTimeMs, boolean hasOutstandingRequest); - private native void nativeOnReceiveNewContent( - long nativeFeedSchedulerBridge, long contentCreationDateTimeMs); - private native void nativeOnRequestError( - long nativeFeedSchedulerBridge, int networkResponseCode); - private native void nativeOnForegrounded(long nativeFeedSchedulerBridge); - private native void nativeOnFixedTimer(long nativeFeedSchedulerBridge, Runnable onCompletion); - private native void nativeOnSuggestionConsumed(long nativeFeedSchedulerBridge); - private native boolean nativeOnArticlesCleared( - long nativeFeedSchedulerBridge, boolean suppressRefreshes); + @NativeMethods + interface Natives { + long init(FeedSchedulerBridge caller, Profile profile); + void destroy(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller); + int shouldSessionRequestData(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller, + boolean hasContent, long contentCreationDateTimeMs, boolean hasOutstandingRequest); + void onReceiveNewContent(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller, + long contentCreationDateTimeMs); + void onRequestError(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller, + int networkResponseCode); + void onForegrounded(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller); + void onFixedTimer( + long nativeFeedSchedulerBridge, FeedSchedulerBridge caller, Runnable onCompletion); + void onSuggestionConsumed(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller); + boolean onArticlesCleared(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller, + boolean suppressRefreshes); + } }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java index 0246250c8..8431f5b 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
@@ -46,9 +46,9 @@ import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView; import org.chromium.chrome.browser.snackbar.Snackbar; import org.chromium.chrome.browser.snackbar.SnackbarManager; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.ViewResizer; import org.chromium.chrome.browser.util.ViewUtils; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; -import org.chromium.chrome.browser.widget.displaystyle.ViewResizer; import org.chromium.ui.UiUtils; import java.util.Arrays; @@ -290,8 +290,9 @@ mRootView = new RootView(mActivity); mRootView.setPadding(0, resources.getDimensionPixelOffset(R.dimen.tab_strip_height), 0, 0); - if (historyNavigationDelegate != null) + if (historyNavigationDelegate != null) { mRootView.setNavigationDelegate(historyNavigationDelegate); + } mUiConfig = new UiConfig(mRootView); // Mediator should be created before any Stream changes.
diff --git a/chrome/android/java/res/values/attrs.xml b/chrome/android/java/res/values/attrs.xml index b02fa410..a7e14bfd 100644 --- a/chrome/android/java/res/values/attrs.xml +++ b/chrome/android/java/res/values/attrs.xml
@@ -7,8 +7,6 @@ <declare-styleable name="HyperlinkPreference"> <!-- The URL to load when the preference is clicked --> <attr name="url" format="string" /> - <!-- True if the hyperlink should look like an <a> element. Default is false. --> - <attr name="imitateWebLink" format="boolean" /> </declare-styleable> <declare-styleable name="LearnMorePreference">
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index ef4c939..6d21b21a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -1425,13 +1425,9 @@ getCompositorViewHolder().addCompositorViewResizer( mManualFillingComponent.getKeyboardExtensionViewResizer()); - if (mBottomSheet == null && shouldInitializeBottomSheet()) { - // TODO(yusufo): Unify initialization. - initializeBottomSheet(true); - } - - if (mBottomSheet != null) { - mEphemeralTabCoordinator = new EphemeralTabCoordinator(this, mBottomSheetController); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.EPHEMERAL_TAB_USING_BOTTOM_SHEET)) { + mEphemeralTabCoordinator = + new EphemeralTabCoordinator(this, getBottomSheetController()); } // TODO(crbug.com/959841): Once crrev.com/c/1669360 is submitted, make the code below @@ -1452,7 +1448,10 @@ */ protected void registerDirectActions() { mDirectActionInitializer.registerCommonChromeActions(this, getActivityType(), this, - this::onBackPressed, mTabModelSelector, mBottomSheetController, mScrimView); + this::onBackPressed, mTabModelSelector, + AutofillAssistantFacade.areDirectActionsAvailable(getActivityType()) ? + getBottomSheetController() : null, + mScrimView); } /** @@ -1472,18 +1471,9 @@ } /** - * @return Whether this Activity should initialize the BottomSheet and BottomSheetController. - */ - protected boolean shouldInitializeBottomSheet() { - return AutofillAssistantFacade.areDirectActionsAvailable(getActivityType()); - } - - /** * Initializes the {@link BottomSheet} and {@link BottomSheetController} for use. - * @param suppressSheetForContextualSearch Whether the sheet should be suppressed when - * Contextual search is showing. */ - protected void initializeBottomSheet(boolean suppressSheetForContextualSearch) { + protected void initializeBottomSheet() { ViewGroup coordinator = findViewById(R.id.coordinator); getLayoutInflater().inflate(R.layout.bottom_sheet, coordinator); mBottomSheet = coordinator.findViewById(R.id.bottom_sheet); @@ -1493,8 +1483,7 @@ mBottomSheetController = new BottomSheetController(this, getLifecycleDispatcher(), mActivityTabProvider, mScrimView, mBottomSheet, - getCompositorViewHolder().getLayoutManager().getOverlayPanelManager(), - suppressSheetForContextualSearch); + getCompositorViewHolder().getLayoutManager().getOverlayPanelManager()); } /** @@ -2550,9 +2539,12 @@ return toPropagate == null || super.dispatchKeyEvent(toPropagate); } - /** Returns {@link BottomSheetController}, if present. */ - @Nullable + /** + * @return A lazily created {@link BottomSheetController}. The first time this method is called, + * a new controller is created. + */ public BottomSheetController getBottomSheetController() { + if (mBottomSheetController == null) initializeBottomSheet(); return mBottomSheetController; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index ad35eae..2015811 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -110,7 +110,6 @@ import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.search_engines.SearchEngineChoiceNotification; -import org.chromium.chrome.browser.send_tab_to_self.SendTabToSelfAndroidBridge; import org.chromium.chrome.browser.signin.SigninPromoUtil; import org.chromium.chrome.browser.snackbar.undo.UndoBarController; import org.chromium.chrome.browser.suggestions.SuggestionsEventReporterBridge; @@ -748,10 +747,6 @@ }; OnClickListener bookmarkClickHandler = v -> addOrEditBookmark(getActivityTab()); - if (shouldInitializeBottomSheet()) { - initializeBottomSheet(false); - } - getToolbarManager().initializeWithNative(mTabModelSelectorImpl, getFullscreenManager().getBrowserVisibilityDelegate(), mOverviewModeController, mLayoutManager, tabSwitcherClickHandler, newTabClickHandler, @@ -2359,13 +2354,6 @@ } @Override - protected boolean shouldInitializeBottomSheet() { - return super.shouldInitializeBottomSheet() || FeatureUtilities.isTabGroupsAndroidEnabled() - || ChromeFeatureList.isEnabled(ChromeFeatureList.OVERSCROLL_HISTORY_NAVIGATION) - || SendTabToSelfAndroidBridge.isSendingEnabled(); - } - - @Override public void onScreenshotTaken() { Tracker tracker = TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()); tracker.notifyEvent(EventConstants.SCREENSHOT_TAKEN_CHROME_IN_FOREGROUND);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java index 962d0e1..87c2566 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java
@@ -20,7 +20,7 @@ import org.chromium.chrome.browser.SynchronousInitializationActivity; import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem; import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver; -import org.chromium.chrome.browser.widget.TintedDrawable; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.components.bookmarks.BookmarkId; import java.util.ArrayList;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java index c065e5b3..84476fc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
@@ -17,7 +17,7 @@ import org.chromium.chrome.browser.SynchronousInitializationActivity; import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem; import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver; -import org.chromium.chrome.browser.widget.TintedDrawable; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.components.bookmarks.BookmarkId; import org.chromium.components.url_formatter.UrlFormatter;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java index e12af9b..40bac04d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
@@ -28,9 +28,9 @@ import org.chromium.chrome.browser.snackbar.SnackbarManager; import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.browser.util.UrlConstants; -import org.chromium.chrome.browser.widget.TintedDrawable; import org.chromium.components.bookmarks.BookmarkId; import org.chromium.components.bookmarks.BookmarkType; import org.chromium.ui.base.DeviceFormFactor;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelAnimation.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelAnimation.java index 40a72a3..9eac3e6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelAnimation.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelAnimation.java
@@ -15,8 +15,8 @@ import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.PanelState; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost; +import org.chromium.chrome.browser.ui.widget.animation.CancelAwareAnimatorListener; import org.chromium.chrome.browser.util.MathUtils; -import org.chromium.chrome.browser.widget.animation.CancelAwareAnimatorListener; /** * Base abstract class for animating the Overlay Panel.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomButtonParams.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomButtonParams.java index 9a855a94..695566f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomButtonParams.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomButtonParams.java
@@ -27,8 +27,8 @@ import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.util.IntentUtils; -import org.chromium.chrome.browser.widget.TintedDrawable; import org.chromium.ui.widget.Toast; import java.util.ArrayList;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 10eda8b1..e3b87ef 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -604,11 +604,6 @@ return component; } - @Override - protected boolean shouldInitializeBottomSheet() { - return super.shouldInitializeBottomSheet() || isAutofillAssistantEnabled(); - } - private boolean isAutofillAssistantEnabled() { return ChromeFeatureList.isEnabled(ChromeFeatureList.AUTOFILL_ASSISTANT) && AutofillAssistantFacade.isConfigured(getInitialIntent().getExtras());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index c631d83..01a7b6f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -47,10 +47,10 @@ import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleMetrics; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.browser.util.UrlConstants; -import org.chromium.chrome.browser.widget.TintedDrawable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java index 8b0c3c8c..13b21ca 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -71,7 +71,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -117,18 +116,6 @@ private static final String PREF_IS_DOWNLOAD_HOME_ENABLED = "org.chromium.chrome.browser.download.IS_DOWNLOAD_HOME_ENABLED"; - // Set will be more expensive to initialize, so use an ArrayList here. - private static final List<String> MIME_TYPES_TO_OPEN = new ArrayList<String>(Arrays.asList( - OMADownloadHandler.OMA_DOWNLOAD_DESCRIPTOR_MIME, - "application/pdf", - "application/x-x509-ca-cert", - "application/x-x509-user-cert", - "application/x-x509-server-cert", - "application/x-pkcs12", - "application/application/x-pem-file", - "application/pkix-cert", - "application/x-wifi-config")); - private static final Set<String> sFirstSeenDownloadIds = new HashSet<String>(); private static final Set<String> sBackgroundDownloadIds = new HashSet<String>();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java index 055d66a..d3dbd62 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java
@@ -23,8 +23,8 @@ import org.chromium.chrome.browser.download.home.DownloadManagerUiConfig; import org.chromium.chrome.browser.download.home.list.DateOrderedListCoordinator.DateOrderedListObserver; import org.chromium.chrome.browser.download.home.list.holder.ListItemViewHolder; -import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.HorizontalDisplayStyle; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.ui.modelutil.ForwardingListObservable; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; import org.chromium.ui.modelutil.RecyclerViewAdapter;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/toolbar/DownloadHomeToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/toolbar/DownloadHomeToolbar.java index d528315..da05ee6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/toolbar/DownloadHomeToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/toolbar/DownloadHomeToolbar.java
@@ -11,7 +11,7 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.browser.download.home.list.ListItem; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.chrome.browser.widget.selection.SelectableListToolbar; import org.chromium.chrome.download.R;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java index 023b14a..10326e48 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java
@@ -30,8 +30,8 @@ import org.chromium.chrome.browser.download.ui.BackendProvider.DownloadDelegate; import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.DownloadItemWrapper; import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.OfflineItemWrapper; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.chrome.browser.widget.DateDividedAdapter; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; import org.chromium.chrome.browser.widget.selection.SelectionDelegate; import org.chromium.chrome.download.R; import org.chromium.components.download.DownloadState; @@ -293,8 +293,9 @@ && wrapper.isVisibleToUser(DownloadFilter.Type.ALL)) { itemCounts[wrapper.getFilterType()]++; - if (DownloadUtils.isDownloadViewed(wrapper.getItem())) + if (DownloadUtils.isDownloadViewed(wrapper.getItem())) { viewedItemCounts[wrapper.getFilterType()]++; + } if (!isOffTheRecord && wrapper.getFilterType() == DownloadFilter.Type.OTHER) { RecordHistogram.recordEnumeratedHistogram( "Android.DownloadManager.OtherExtensions.InitialCount",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbarTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbarTablet.java index 978475a..98286d6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbarTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbarTablet.java
@@ -16,7 +16,7 @@ import android.widget.FrameLayout; import org.chromium.chrome.R; -import org.chromium.chrome.browser.widget.animation.CancelAwareAnimatorListener; +import org.chromium.chrome.browser.ui.widget.animation.CancelAwareAnimatorListener; /** * A tablet specific version of the {@link FindToolbar}.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationSheetMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationSheetMediator.java index a0f0ab6..0c6ddd8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationSheetMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationSheetMediator.java
@@ -16,10 +16,10 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.favicon.FaviconHelper; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.util.UrlConstants; import org.chromium.chrome.browser.util.ViewUtils; import org.chromium.chrome.browser.widget.RoundedIconGenerator; -import org.chromium.chrome.browser.widget.TintedDrawable; import org.chromium.content_public.browser.NavigationEntry; import org.chromium.content_public.browser.NavigationHistory; import org.chromium.ui.modelutil.MVCListAdapter.ListItem; @@ -33,7 +33,7 @@ import java.util.Set; /** - * Mediattor class for navigation sheet. + * Mediator class for navigation sheet. */ class NavigationSheetMediator { private final ClickListener mClickListener;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java index 1e4f9806..efa2c0c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
@@ -48,11 +48,11 @@ import org.chromium.chrome.browser.suggestions.tile.TileGridLayout; import org.chromium.chrome.browser.suggestions.tile.TileGroup; import org.chromium.chrome.browser.suggestions.tile.TileRenderer; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.chrome.browser.util.MathUtils; import org.chromium.chrome.browser.util.ViewUtils; import org.chromium.chrome.browser.vr.VrModeObserver; import org.chromium.chrome.browser.vr.VrModuleProvider; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; import org.chromium.ui.base.DeviceFormFactor; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java index 714630f..d8ea29eb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
@@ -31,9 +31,9 @@ import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; import org.chromium.chrome.browser.suggestions.tile.TileGroup; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.ViewResizer; import org.chromium.chrome.browser.util.ViewUtils; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; -import org.chromium.chrome.browser.widget.displaystyle.ViewResizer; /** * The native new tab page, represented by some basic data such as title and url, and an Android
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsGroupView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsGroupView.java index b3089798..3a214bbd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsGroupView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsGroupView.java
@@ -15,7 +15,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSession; -import org.chromium.chrome.browser.widget.TintedDrawable; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; /** * Header view shown above each group of items on the Recent Tabs page. Shows the name of the
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java index 461424b1..031442d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java
@@ -21,7 +21,7 @@ import org.chromium.chrome.browser.suggestions.SuggestionsRanker; import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java index 5382876..ccea493 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java
@@ -16,8 +16,8 @@ import org.chromium.chrome.browser.native_page.ContextMenuManager; import org.chromium.chrome.browser.native_page.ContextMenuManager.ContextMenuItemId; import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; -import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.HorizontalDisplayStyle; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; /** * Holder for a generic card.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java index eabb6000..ead15ebf4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java
@@ -33,7 +33,7 @@ import org.chromium.chrome.browser.suggestions.SuggestionsConfig; import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.ui.modelutil.ListObservable; import java.util.List;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/PersonalizedPromoViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/PersonalizedPromoViewHolder.java index 8ec47c3..f51515d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/PersonalizedPromoViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/PersonalizedPromoViewHolder.java
@@ -15,7 +15,7 @@ import org.chromium.chrome.browser.signin.SigninPromoController; import org.chromium.chrome.browser.signin.SigninPromoUtil; import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; /** * View Holder for {@link SignInPromo} if the personalized promo is to be shown.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/StatusCardViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/StatusCardViewHolder.java index 39d3b12..bcd23731 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/StatusCardViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/StatusCardViewHolder.java
@@ -17,7 +17,7 @@ import org.chromium.chrome.browser.native_page.ContextMenuManager; import org.chromium.chrome.browser.suggestions.SuggestionsMetrics; import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; /** * ViewHolder for Status and Promo cards.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SectionHeaderViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SectionHeaderViewHolder.java index 8dd2814..e7f6dc2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SectionHeaderViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SectionHeaderViewHolder.java
@@ -10,7 +10,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder; import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; /** * View holder for the header of a section of cards.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java index 27dd1bbf..55c7feb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java
@@ -22,8 +22,8 @@ import org.chromium.chrome.browser.suggestions.SuggestionsOfflineModelObserver; import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.widget.displaystyle.DisplayStyleObserverAdapter; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.DisplayStyleObserverAdapter; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.ui.mojom.WindowOpenDisposition; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java index c9f7732..c196326 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java
@@ -20,7 +20,7 @@ import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.toolbar.top.ToolbarTablet; -import org.chromium.chrome.browser.widget.animation.CancelAwareAnimatorListener; +import org.chromium.chrome.browser.ui.widget.animation.CancelAwareAnimatorListener; import org.chromium.ui.base.LocalizationUtils; import org.chromium.ui.interpolators.BakedBezierInterpolator;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/SuggestionView.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/SuggestionView.java index 48238ba..71830e51 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/SuggestionView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/SuggestionView.java
@@ -25,9 +25,9 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.util.KeyNavigationUtil; -import org.chromium.chrome.browser.widget.TintedDrawable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionView.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionView.java index c8ef243..a822fff 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionView.java
@@ -20,8 +20,8 @@ import android.widget.TextView; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.util.ColorUtils; -import org.chromium.chrome.browser.widget.TintedDrawable; /** * Container view for omnibox entity suggestions.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoView.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoView.java index c6b0258f..0994c40 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoView.java
@@ -29,7 +29,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; -import org.chromium.chrome.browser.widget.TintedDrawable; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import java.util.ArrayList; import java.util.List;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/DimmingDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/DimmingDialog.java index f9e2fdc..bbe68e9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/DimmingDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/DimmingDialog.java
@@ -29,8 +29,8 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.ui.widget.AlwaysDismissedDialog; +import org.chromium.chrome.browser.ui.widget.animation.AnimatorProperties; import org.chromium.chrome.browser.util.ColorUtils; -import org.chromium.chrome.browser.widget.animation.AnimatorProperties; /** * A fullscreen semitransparent dialog used for dimming Chrome when overlaying a bottom sheet
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestHeader.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestHeader.java index 9e69872bd..5de1787 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestHeader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestHeader.java
@@ -19,9 +19,9 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.omnibox.OmniboxUrlEmphasizer; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.util.UrlConstants; -import org.chromium.chrome.browser.widget.TintedDrawable; /** This class represents a bar to display at the top of the payment request UI. */ public class PaymentRequestHeader extends FrameLayout {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java index bfbbf49..aa5363f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java
@@ -38,7 +38,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.ui.widget.DualControlLayout; -import org.chromium.chrome.browser.widget.TintedDrawable; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.widget.prefeditor.EditableOption; import org.chromium.ui.HorizontalListDividerDrawable; import org.chromium.ui.UiUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java index 5b403b7..78873e1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
@@ -45,7 +45,7 @@ import org.chromium.chrome.browser.payments.ui.PaymentRequestSection.OptionSection; import org.chromium.chrome.browser.payments.ui.PaymentRequestSection.SectionSeparator; import org.chromium.chrome.browser.ui.widget.FadingEdgeScrollView; -import org.chromium.chrome.browser.widget.animation.FocusAnimator; +import org.chromium.chrome.browser.ui.widget.animation.FocusAnimator; import org.chromium.chrome.browser.widget.prefeditor.EditableOption; import org.chromium.chrome.browser.widget.prefeditor.EditorDialog; import org.chromium.chrome.browser.widget.prefeditor.EditorObserverForTest;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/HyperlinkPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/HyperlinkPreference.java index 78718fb..b2dc511 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/HyperlinkPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/HyperlinkPreference.java
@@ -7,13 +7,8 @@ import android.content.Context; import android.content.res.TypedArray; import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceViewHolder; import android.util.AttributeSet; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.TextView; -import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.ui.base.LocalizationUtils; @@ -25,18 +20,14 @@ public class HyperlinkPreference extends Preference { private final int mUrlResId; - private final int mColor; - private final boolean mImitateWebLink; public HyperlinkPreference(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HyperlinkPreference, 0, 0); mUrlResId = a.getResourceId(R.styleable.HyperlinkPreference_url, 0); - mImitateWebLink = a.getBoolean(R.styleable.HyperlinkPreference_imitateWebLink, false); a.recycle(); - mColor = ApiCompatibilityUtils.getColor( - context.getResources(), R.color.default_text_color_link); + setSingleLineTitle(false); } @Override @@ -44,24 +35,4 @@ CustomTabActivity.showInfoPage(WindowAndroid.activityFromContext(getContext()), LocalizationUtils.substituteLocalePlaceholder(getContext().getString(mUrlResId))); } - - @Override - public void onBindViewHolder(PreferenceViewHolder holder) { - super.onBindViewHolder(holder); - TextView titleView = (TextView) holder.findViewById(android.R.id.title); - titleView.setSingleLine(false); - - if (mImitateWebLink) { - setSelectable(false); - - titleView.setClickable(true); - titleView.setTextColor(mColor); - titleView.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - HyperlinkPreference.this.onClick(); - } - }); - } - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/languages/LanguageListPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/languages/LanguageListPreference.java index fe5720f..2c757fb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/languages/LanguageListPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/languages/LanguageListPreference.java
@@ -18,7 +18,7 @@ import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.ui.widget.ListMenuButton; import org.chromium.chrome.browser.ui.widget.ListMenuButton.Item; -import org.chromium.chrome.browser.widget.TintedDrawable; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import java.util.ArrayList;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfMetrics.java index ac4d97cf..18f92a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfMetrics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfMetrics.java
@@ -6,6 +6,7 @@ import androidx.annotation.IntDef; +import org.chromium.base.metrics.CachedMetrics; import org.chromium.base.metrics.RecordHistogram; import java.lang.annotation.Retention; @@ -55,9 +56,12 @@ int NUM_ENTRIES = 3; } + private static final CachedMetrics.EnumeratedHistogramSample CLICK_RESULT_METRIC = + new CachedMetrics.EnumeratedHistogramSample( + "SendTabToSelf.Notification", InteractionType.NUM_ENTRIES); + public static void recordClickResult(@InteractionType int result) { - RecordHistogram.recordEnumeratedHistogram( - "SendTabToSelf.Notification", result, InteractionType.NUM_ENTRIES); + CLICK_RESULT_METRIC.record(result); } } -} \ No newline at end of file +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java index afdd650..a84007f8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
@@ -27,7 +27,6 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; -import org.chromium.chrome.browser.externalauth.UserRecoverableErrorHandler; import org.chromium.components.signin.AccountIdProvider; import org.chromium.components.signin.AccountManagerFacade; import org.chromium.components.signin.AccountTrackerService; @@ -459,8 +458,6 @@ } else if (AccountIdProvider.getInstance().canBeUsed()) { mSignInState.mBlockedOnAccountSeeding = true; } else { - Activity activity = mSignInState.mActivity; - handleGooglePlayServicesUnavailability(activity, !isForceSigninEnabled()); Log.w(TAG, "Cancelling the sign-in process as Google Play services is unavailable"); abortSignIn(); } @@ -752,13 +749,6 @@ return SigninManagerJni.get().extractDomainName(email); } - private void handleGooglePlayServicesUnavailability(Activity activity, boolean cancelable) { - UserRecoverableErrorHandler errorHandler = activity != null - ? new UserRecoverableErrorHandler.ModalDialog(activity, cancelable) - : new UserRecoverableErrorHandler.SystemNotification(); - ExternalAuthUtils.getInstance().canUseGooglePlayServices(errorHandler); - } - private boolean isGooglePlayServicesPresent(Context context) { return !ExternalAuthUtils.getInstance().isGooglePlayServicesMissing(context); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsConfig.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsConfig.java index 6adab5b..3f3b1f27 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsConfig.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsConfig.java
@@ -12,9 +12,9 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.chrome.browser.util.FeatureUtilities; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsRecyclerView.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsRecyclerView.java index 4fc32d7..cba965f8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsRecyclerView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsRecyclerView.java
@@ -36,7 +36,7 @@ import org.chromium.chrome.browser.ntp.cards.NewTabPageAdapter; import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder; import org.chromium.chrome.browser.ntp.cards.ScrollToLoadListener; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import java.util.ArrayList; import java.util.Collections;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/SiteSection.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/SiteSection.java index 2c27273..99cd1c3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/SiteSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/SiteSection.java
@@ -20,7 +20,7 @@ import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.suggestions.SuggestionsConfig; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; /** * The model and controller for a group of site suggestions.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherDrawable.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherDrawable.java index 36fec4c..daf169a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherDrawable.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherDrawable.java
@@ -16,8 +16,8 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.util.ColorUtils; -import org.chromium.chrome.browser.widget.TintedDrawable; import java.util.Locale;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java index d91491852..ea755221 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java
@@ -59,9 +59,9 @@ import org.chromium.chrome.browser.tab.TrustedCdn; import org.chromium.chrome.browser.toolbar.ToolbarDataProvider; import org.chromium.chrome.browser.toolbar.ToolbarTabController; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.chrome.browser.util.ColorUtils; -import org.chromium.chrome.browser.widget.TintedDrawable; import org.chromium.components.url_formatter.UrlFormatter; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.common.ContentUrlConstants;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbarAnimationDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbarAnimationDelegate.java index a2fbf49..a68448d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbarAnimationDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbarAnimationDelegate.java
@@ -14,7 +14,7 @@ import android.widget.TextView; import org.chromium.chrome.R; -import org.chromium.chrome.browser.widget.animation.CancelAwareAnimatorListener; +import org.chromium.chrome.browser.ui.widget.animation.CancelAwareAnimatorListener; import org.chromium.ui.interpolators.BakedBezierInterpolator; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java index 500f4f7c..8fe04f4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java
@@ -31,9 +31,9 @@ import org.chromium.chrome.browser.toolbar.MenuButton; import org.chromium.chrome.browser.toolbar.NewTabButton; import org.chromium.chrome.browser.toolbar.TabCountProvider; +import org.chromium.chrome.browser.ui.widget.animation.CancelAwareAnimatorListener; import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.util.FeatureUtilities; -import org.chromium.chrome.browser.widget.animation.CancelAwareAnimatorListener; import org.chromium.ui.UiUtils; import org.chromium.ui.widget.OptimizedFrameLayout; @@ -269,8 +269,9 @@ mIncognitoStateProvider = provider; mIncognitoStateProvider.addIncognitoStateObserverAndTrigger(this); - if (mNewTabImageButton != null) + if (mNewTabImageButton != null) { mNewTabImageButton.setIncognitoStateProvider(mIncognitoStateProvider); + } } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index 0f54c4b2f..806ead7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -71,11 +71,11 @@ import org.chromium.chrome.browser.toolbar.TabCountProvider.TabCountObserver; import org.chromium.chrome.browser.toolbar.TabSwitcherDrawable; import org.chromium.chrome.browser.toolbar.top.TopToolbarCoordinator.UrlExpansionObserver; +import org.chromium.chrome.browser.ui.widget.animation.CancelAwareAnimatorListener; import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.MathUtils; import org.chromium.chrome.browser.util.ViewUtils; -import org.chromium.chrome.browser.widget.animation.CancelAwareAnimatorListener; import org.chromium.components.feature_engagement.EventConstants; import org.chromium.ui.base.LocalizationUtils; import org.chromium.ui.interpolators.BakedBezierInterpolator;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java index 1dcc13d..3c8d25f1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java
@@ -8,11 +8,7 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.net.Uri; import android.os.Build; -import android.support.v7.app.AlertDialog; import android.view.Gravity; import android.view.View; import android.view.accessibility.AccessibilityManager; @@ -21,10 +17,7 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.ApplicationStatus.ActivityStateListener; import org.chromium.base.ContextUtils; -import org.chromium.base.PackageUtils; import org.chromium.base.TraceEvent; -import org.chromium.chrome.R; -import org.chromium.ui.UiUtils; import org.chromium.ui.widget.Toast; import java.util.List; @@ -33,21 +26,6 @@ * Exposes information about the current accessibility state */ public class AccessibilityUtil { - // Whether we've already shown an alert that they have an old version of TalkBack running. - private static boolean sOldTalkBackVersionAlertShown; - - // The link to download or update TalkBack from the Play Store. - private static final String TALKBACK_MARKET_LINK = - "market://search?q=pname:com.google.android.marvin.talkback"; - - // The package name for TalkBack, an Android accessibility service. - private static final String TALKBACK_PACKAGE_NAME = - "com.google.android.marvin.talkback"; - - // The minimum TalkBack version that we support. This is the version that shipped with - // KitKat, from fall 2013. Versions older than that should be updated. - private static final int MIN_TALKBACK_VERSION = 105; - private static Boolean sIsAccessibilityEnabled; private static ActivityStateListener sActivityStateListener; @@ -115,7 +93,7 @@ } /** - * Checks whether the given {@link AccesibilityServiceInfo} can perform gestures. + * Checks whether the given {@link AccessibilityServiceInfo} can perform gestures. * @param service The service to check. * @return Whether the {@code service} can perform gestures. On N+, this relies on the * capabilities the service can perform. On L & M, this looks specifically for @@ -134,69 +112,6 @@ } /** - * Checks to see if an old version of TalkBack is running that Chrome doesn't support, - * and if so, shows an alert dialog prompting the user to update the app. - * @param context A {@link Context} instance. - * @return True if the dialog was shown. - */ - public static boolean showWarningIfOldTalkbackRunning(Context context) { - AccessibilityManager manager = (AccessibilityManager) - context.getSystemService(Context.ACCESSIBILITY_SERVICE); - if (manager == null) return false; - - boolean isTalkbackRunning = false; - try { - List<AccessibilityServiceInfo> services = - manager.getEnabledAccessibilityServiceList( - AccessibilityServiceInfo.FEEDBACK_SPOKEN); - for (AccessibilityServiceInfo service : services) { - if (service.getId().contains(TALKBACK_PACKAGE_NAME)) isTalkbackRunning = true; - } - } catch (NullPointerException e) { - // getEnabledAccessibilityServiceList() can throw an NPE due to a bad - // AccessibilityService. - } - if (!isTalkbackRunning) return false; - - if (PackageUtils.getPackageVersion(context, TALKBACK_PACKAGE_NAME) < MIN_TALKBACK_VERSION - && !sOldTalkBackVersionAlertShown) { - showOldTalkbackVersionAlertOnce(context); - return true; - } - - return false; - } - - private static void showOldTalkbackVersionAlertOnce(final Context context) { - if (sOldTalkBackVersionAlertShown) return; - sOldTalkBackVersionAlertShown = true; - - AlertDialog.Builder builder = - new UiUtils - .CompatibleAlertDialogBuilder(context, R.style.Theme_Chromium_AlertDialog) - .setTitle(R.string.old_talkback_title) - .setPositiveButton(R.string.update_from_market, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - Uri marketUri = Uri.parse(TALKBACK_MARKET_LINK); - Intent marketIntent = - new Intent(Intent.ACTION_VIEW, marketUri); - context.startActivity(marketIntent); - } - }) - .setNegativeButton(R.string.cancel_talkback_alert, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - // Do nothing, this alert is only shown once either way. - } - }); - AlertDialog dialog = builder.create(); - dialog.show(); - } - - /** * Shows the content description toast for items on the toolbar. * @param context The context to use for the toast. * @param view The view to anchor the toast.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java index 437c2da..974672d4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -51,9 +51,9 @@ import org.chromium.chrome.browser.tab.TabObserverRegistrar; import org.chromium.chrome.browser.tab.TabState; import org.chromium.chrome.browser.toolbar.top.ToolbarControlContainer; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.usage_stats.UsageStatsService; import org.chromium.chrome.browser.util.ColorUtils; -import org.chromium.chrome.browser.widget.TintedDrawable; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.NavigationHandle;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ScrimView.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ScrimView.java index bb49bfc..2cf172f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ScrimView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ScrimView.java
@@ -21,8 +21,8 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter; +import org.chromium.chrome.browser.ui.widget.animation.CancelAwareAnimatorListener; import org.chromium.chrome.browser.util.MathUtils; -import org.chromium.chrome.browser.widget.animation.CancelAwareAnimatorListener; import org.chromium.ui.UiUtils; import org.chromium.ui.interpolators.BakedBezierInterpolator;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/animation/AnimatorProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/animation/AnimatorProperties.java deleted file mode 100644 index 14a27c1c..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/animation/AnimatorProperties.java +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.widget.animation; - -import android.graphics.drawable.Drawable; -import android.util.Property; - -/** - * Holds different {@link Property} types that can be used with ObjectAnimators. - */ -public class AnimatorProperties { - public static final Property<Drawable, Integer> DRAWABLE_ALPHA_PROPERTY = - new Property<Drawable, Integer>(Integer.class, "alpha") { - @Override - public Integer get(Drawable d) { - // getAlpha() is only exposed on drawable in API 19+, so we rely on animations - // always setting the starting and ending values instead of relying on this - // property. - return 0; - } - - @Override - public void set(Drawable d, Integer alpha) { - d.setAlpha(alpha); - } - }; -} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java index 0a08e96..03331e4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java
@@ -11,7 +11,6 @@ import org.chromium.chrome.browser.ActivityTabProvider.HintlessActivityTabObserver; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager; -import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager.OverlayPanelManagerObserver; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.Destroyable; import org.chromium.chrome.browser.snackbar.SnackbarManager; @@ -64,9 +63,6 @@ /** The manager for overlay panels to attach listeners to. */ private OverlayPanelManager mOverlayPanelManager; - /** Whether the bottom sheet should be suppressed when Contextual Search is showing. */ - private boolean mSuppressSheetForContextualSearch; - /** A means for getting the activity's current tab and observing change events. */ private ActivityTabProvider mTabProvider; @@ -81,18 +77,14 @@ * @param scrim The scrim that shows when the bottom sheet is opened. * @param bottomSheet The bottom sheet that this class will be controlling. * @param overlayManager The manager for overlay panels to attach listeners to. - * @param suppressSheetForContextualSearch Whether the bottom sheet should be suppressed when - * Contextual Search is showing. */ public BottomSheetController(final Activity activity, final ActivityLifecycleDispatcher lifecycleDispatcher, final ActivityTabProvider activityTabProvider, final ScrimView scrim, - BottomSheet bottomSheet, OverlayPanelManager overlayManager, - boolean suppressSheetForContextualSearch) { + BottomSheet bottomSheet, OverlayPanelManager overlayManager) { mBottomSheet = bottomSheet; mTabProvider = activityTabProvider; mOverlayPanelManager = overlayManager; - mSuppressSheetForContextualSearch = suppressSheetForContextualSearch; mSnackbarManager = new SnackbarManager( activity, mBottomSheet.findViewById(R.id.bottom_sheet_snackbar_container)); @@ -216,20 +208,6 @@ mSnackbarManager.dismissAllSnackbars(); } }); - - if (mSuppressSheetForContextualSearch) { - mOverlayPanelManager.addObserver(new OverlayPanelManagerObserver() { - @Override - public void onOverlayPanelShown() { - suppressSheet(StateChangeReason.COMPOSITED_UI); - } - - @Override - public void onOverlayPanelHidden() { - unsuppressSheet(); - } - }); - } } // Destroyable implementation.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorDialog.java index bea6cac..3ee4344 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorDialog.java
@@ -50,7 +50,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.ui.widget.AlwaysDismissedDialog; import org.chromium.chrome.browser.ui.widget.FadingEdgeScrollView; -import org.chromium.chrome.browser.widget.TintedDrawable; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.ui.KeyboardVisibilityDelegate; import java.util.ArrayList;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorTextField.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorTextField.java index dd8573d..19ad109 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorTextField.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorTextField.java
@@ -28,8 +28,8 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.chrome.browser.widget.ChromeTextInputLayout; -import org.chromium.chrome.browser.widget.TintedDrawable; /** Handles validation and display of one field from the {@link EditorFieldModel}. */ @VisibleForTesting
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/HintedDropDownAdapterWithPlusIcon.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/HintedDropDownAdapterWithPlusIcon.java index 22c5c6f..fa83ebc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/HintedDropDownAdapterWithPlusIcon.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/HintedDropDownAdapterWithPlusIcon.java
@@ -13,7 +13,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.widget.TintedDrawable; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; import org.chromium.ui.UiUtils; import java.util.List;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableItemView.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableItemView.java index 630de4c..e0bb801 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableItemView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableItemView.java
@@ -18,7 +18,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.widget.TintedDrawable; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; /** * Default implementation of SelectableItemViewBase.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java index 77cd144..a92eca8f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
@@ -31,10 +31,10 @@ import org.chromium.chrome.browser.ui.widget.FadingShadow; import org.chromium.chrome.browser.ui.widget.FadingShadowView; import org.chromium.chrome.browser.ui.widget.LoadingView; -import org.chromium.chrome.browser.widget.displaystyle.DisplayStyleObserver; -import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig.DisplayStyle; +import org.chromium.chrome.browser.ui.widget.displaystyle.DisplayStyleObserver; +import org.chromium.chrome.browser.ui.widget.displaystyle.HorizontalDisplayStyle; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig.DisplayStyle; import org.chromium.chrome.browser.widget.selection.SelectionDelegate.SelectionObserver; import java.util.List;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java index 0d06610..503e49f7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java
@@ -39,14 +39,14 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.toolbar.top.ActionModeController; import org.chromium.chrome.browser.toolbar.top.ToolbarActionModeCallback; +import org.chromium.chrome.browser.ui.widget.TintedDrawable; +import org.chromium.chrome.browser.ui.widget.displaystyle.DisplayStyleObserver; +import org.chromium.chrome.browser.ui.widget.displaystyle.HorizontalDisplayStyle; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.vr.VrModeObserver; import org.chromium.chrome.browser.vr.VrModuleProvider; import org.chromium.chrome.browser.widget.NumberRollView; -import org.chromium.chrome.browser.widget.TintedDrawable; -import org.chromium.chrome.browser.widget.displaystyle.DisplayStyleObserver; -import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; import org.chromium.chrome.browser.widget.selection.SelectionDelegate.SelectionObserver; import org.chromium.ui.KeyboardVisibilityDelegate; import org.chromium.ui.UiUtils;
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 65cdddc2..674da814 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2204,15 +2204,9 @@ </message> <!-- TalkBack upgrade --> - <message name="IDS_OLD_TALKBACK_TITLE" desc="Title of dialog notifying user that the version of TalkBack they're running is too old."> - You need to update TalkBack to a newer version. - </message> <message name="IDS_UPDATE_FROM_MARKET" desc="Title of button that will direct the user to update TalkBack from the market (Play Store)"> Update </message> - <message name="IDS_CANCEL_TALKBACK_ALERT" desc="Title of button that will cancel the TalkBack alert dialog dialog."> - Cancel - </message> <!-- Android NFC Beam strings --> <message name="IDS_NFC_BEAM_ERROR_OVERLAY_ACTIVE" desc="Android Beam error - a tab is not in the foreground [CHAR-LIMIT=40]">
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java index ef5068c..ea1eb93f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
@@ -59,10 +59,10 @@ import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; import org.chromium.chrome.browser.suggestions.ThumbnailGradient; +import org.chromium.chrome.browser.ui.widget.displaystyle.HorizontalDisplayStyle; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.VerticalDisplayStyle; import org.chromium.chrome.browser.widget.ThumbnailProvider; -import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; -import org.chromium.chrome.browser.widget.displaystyle.VerticalDisplayStyle; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; import org.chromium.chrome.test.util.RenderTestRule;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGridLayoutTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGridLayoutTest.java index 3577c13..7a6d290 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGridLayoutTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGridLayoutTest.java
@@ -52,9 +52,9 @@ import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegateImpl; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.chrome.browser.util.UrlConstants; import org.chromium.chrome.browser.util.ViewUtils; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.NewTabPageTestUtils;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ScrimTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ScrimTest.java index 87c4e6a..4c8073b6c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ScrimTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ScrimTest.java
@@ -74,8 +74,7 @@ mSheetController = new BottomSheetController(activity, activity.getLifecycleDispatcher(), activity.getActivityTabProvider(), mScrim, mBottomSheet, - activity.getCompositorViewHolder().getLayoutManager().getOverlayPanelManager(), - true); + activity.getCompositorViewHolder().getLayoutManager().getOverlayPanelManager()); }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java index a9783a4..afa737e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java
@@ -75,8 +75,7 @@ mSheetController = new BottomSheetController(activity, activity.getLifecycleDispatcher(), activity.getActivityTabProvider(), scrim, mBottomSheet, - activity.getCompositorViewHolder().getLayoutManager().getOverlayPanelManager(), - true); + activity.getCompositorViewHolder().getLayoutManager().getOverlayPanelManager()); mLowPriorityContent = new TestBottomSheetContent( mActivityTestRule.getActivity(), ContentPriority.LOW, false);
diff --git a/chrome/android/junit/DEPS b/chrome/android/junit/DEPS index 69fb45d..22f9b33 100644 --- a/chrome/android/junit/DEPS +++ b/chrome/android/junit/DEPS
@@ -1,6 +1,7 @@ include_rules = [ "!clank/java/src/org/chromium/chrome/browser/AppHooksImpl.java", "+chrome/lib/lifecycle/public", + "+chrome/browser/ui/android/widget", "+components/autofill/android/java/src/org/chromium/components/autofill", "+components/background_task_scheduler/android", "+components/bookmarks/common/android",
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/ContentSuggestionsUnitTestUtils.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/ContentSuggestionsUnitTestUtils.java index 6f076bd..edda909 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/ContentSuggestionsUnitTestUtils.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/ContentSuggestionsUnitTestUtils.java
@@ -11,9 +11,9 @@ import org.chromium.chrome.browser.ntp.snippets.CategoryInt; import org.chromium.chrome.browser.ntp.snippets.SectionHeaderViewHolder; import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder; -import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; -import org.chromium.chrome.browser.widget.displaystyle.VerticalDisplayStyle; +import org.chromium.chrome.browser.ui.widget.displaystyle.HorizontalDisplayStyle; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.VerticalDisplayStyle; /** * JUnit specific utility classes for testing suggestions code. Other utility code is in
diff --git a/chrome/android/monochrome/BUILD.gn b/chrome/android/monochrome/BUILD.gn index 5932ab54..ebde7fe 100644 --- a/chrome/android/monochrome/BUILD.gn +++ b/chrome/android/monochrome/BUILD.gn
@@ -19,22 +19,24 @@ jacoco_never_instrument = true } -group("monochrome_apk_checker") { - testonly = true - data_deps = [ - "//chrome/android:chrome_modern_public_apk", - "//chrome/android:monochrome_public_apk", - ] - if (public_android_sdk) { - # system_webview_apk only defined for public sdk builds, so this dependency - # must be guarded. - data_deps += [ "//android_webview:system_webview_apk" ] - } +if (public_android_sdk) { + group("monochrome_apk_checker") { + testonly = true + data_deps = [ + "//chrome/android:chrome_modern_public_apk", + "//chrome/android:monochrome_public_apk", + ] + if (public_android_sdk) { + # system_webview_apk only defined for public sdk builds, so this dependency + # must be guarded. + data_deps += [ "//android_webview:system_webview_apk" ] + } - data = [ - "./scripts/monochrome_apk_checker.py", - "//testing/scripts/monochrome_apk_checker_wrapper.py", - "//testing/scripts/common.py", - "//testing/xvfb.py", - ] + data = [ + "./scripts/monochrome_apk_checker.py", + "//testing/scripts/monochrome_apk_checker_wrapper.py", + "//testing/scripts/common.py", + "//testing/xvfb.py", + ] + } }
diff --git a/chrome/android/touchless/java/DEPS b/chrome/android/touchless/java/DEPS index 0966a704..c17ad3c 100644 --- a/chrome/android/touchless/java/DEPS +++ b/chrome/android/touchless/java/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+chrome/lib/lifecycle/public", + "+chrome/browser/ui/android/widget", "+components/feature_engagement/public", "+components/offline_items_collection/core/android/java", "+content/public/android/java/src/org/chromium/content_public",
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessActionItemViewHolder.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessActionItemViewHolder.java index ca4b875..cb215cc 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessActionItemViewHolder.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessActionItemViewHolder.java
@@ -15,7 +15,7 @@ import org.chromium.chrome.browser.ntp.cards.ActionItem; import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.chrome.touchless.R; import org.chromium.ui.widget.ChromeImageView; import org.chromium.ui.widget.Toast;
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessArticleViewHolder.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessArticleViewHolder.java index 2c625c8..6db2539f 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessArticleViewHolder.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessArticleViewHolder.java
@@ -16,7 +16,7 @@ import org.chromium.chrome.browser.suggestions.SuggestionsBinder; import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.chrome.touchless.R; /**
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java index 9774482..a7be9503 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java
@@ -28,8 +28,8 @@ import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegateImpl; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.chrome.browser.util.UrlConstants; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; import org.chromium.chrome.touchless.R; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageAdapter.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageAdapter.java index 96d4053..f9df8b6b 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageAdapter.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageAdapter.java
@@ -17,7 +17,7 @@ import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.chrome.browser.ui.widget.displaystyle.UiConfig; import org.chromium.ui.modelutil.PropertyModel; import java.util.List;
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 1d59c1a..6dff8b89 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2717,6 +2717,8 @@ "android/webapk/webapk_post_share_target_navigator.cc", "android/webapk/webapk_post_share_target_navigator.h", "android/webapk/webapk_types.h", + "android/webapk/webapk_ukm_recorder.cc", + "android/webapk/webapk_ukm_recorder.h", "android/webapk/webapk_update_data_fetcher.cc", "android/webapk/webapk_update_data_fetcher.h", "android/webapk/webapk_update_manager.cc", @@ -2726,8 +2728,6 @@ "android/webapps/add_to_homescreen_data_fetcher.h", "android/webapps/add_to_homescreen_manager.cc", "android/webapps/add_to_homescreen_manager.h", - "android/webapps/webapk_ukm_recorder.cc", - "android/webapps/webapk_ukm_recorder.h", "android/webapps/webapp_registry.cc", "android/webapps/webapp_registry.h", "android/widget/thumbnail_generator.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index da6838f8..cd4006de 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1332,6 +1332,17 @@ }; #endif // !OS_ANDROID +// TODO(crbug.com/991082): Remove after proper service worker support for +// back-forward cache is implemented. +const FeatureEntry::FeatureParam kBackForwardCache_ServiceWorkerSupport[] = { + {"service_worker_supported", "true"}, +}; + +const FeatureEntry::FeatureVariation kBackForwardCacheVariations[] = { + {" even for ServiceWorker-controlled pages", + kBackForwardCache_ServiceWorkerSupport, 1, nullptr}, +}; + // RECORDING USER METRICS FOR FLAGS: // ----------------------------------------------------------------------------- // The first line of the entry is the internal name. @@ -4537,7 +4548,9 @@ {"back-forward-cache", flag_descriptions::kBackForwardCacheName, flag_descriptions::kBackForwardCacheDescription, kOsAll, - FEATURE_VALUE_TYPE(features::kBackForwardCache)}, + FEATURE_WITH_PARAMS_VALUE_TYPE(features::kBackForwardCache, + kBackForwardCacheVariations, + "BackForwardCache")}, // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag
diff --git a/chrome/browser/android/omnibox/omnibox_prerender.cc b/chrome/browser/android/omnibox/omnibox_prerender.cc index efe2d590..34164fe 100644 --- a/chrome/browser/android/omnibox/omnibox_prerender.cc +++ b/chrome/browser/android/omnibox/omnibox_prerender.cc
@@ -10,6 +10,8 @@ #include "chrome/browser/android/tab_android.h" #include "chrome/browser/predictors/autocomplete_action_predictor.h" #include "chrome/browser/predictors/autocomplete_action_predictor_factory.h" +#include "chrome/browser/predictors/loading_predictor.h" +#include "chrome/browser/predictors/loading_predictor_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_android.h" #include "components/omnibox/browser/autocomplete_match.h" @@ -98,19 +100,17 @@ action_predictor->RecommendAction(url_string, *default_match); GURL current_url = GURL(current_url_string); + // Ask for prerendering if the destination URL is different than the + // current URL. + if (default_match->destination_url == current_url) + return; + switch (recommended_action) { case AutocompleteActionPredictor::ACTION_PRERENDER: - // Ask for prerendering if the destination URL is different than the - // current URL. - if (default_match->destination_url != current_url) { - DoPrerender( - *default_match, - profile, - web_contents); - } + DoPrerender(*default_match, profile, web_contents); break; case AutocompleteActionPredictor::ACTION_PRECONNECT: - // TODO (apiccion) add preconnect logic + DoPreconnect(*default_match, profile); break; case AutocompleteActionPredictor::ACTION_NONE: break; @@ -136,3 +136,14 @@ web_contents->GetController().GetDefaultSessionStorageNamespace(), container_bounds.size()); } + +void OmniboxPrerender::DoPreconnect(const AutocompleteMatch& match, + Profile* profile) { + auto* loading_predictor = + predictors::LoadingPredictorFactory::GetForProfile(profile); + if (loading_predictor) { + loading_predictor->PrepareForPageLoad( + match.destination_url, predictors::HintOrigin::OMNIBOX, + predictors::AutocompleteActionPredictor::IsPreconnectable(match)); + } +}
diff --git a/chrome/browser/android/omnibox/omnibox_prerender.h b/chrome/browser/android/omnibox/omnibox_prerender.h index 6248b61..fa4f7e0 100644 --- a/chrome/browser/android/omnibox/omnibox_prerender.h +++ b/chrome/browser/android/omnibox/omnibox_prerender.h
@@ -63,6 +63,7 @@ void DoPrerender(const AutocompleteMatch& match, Profile* profile, content::WebContents* web_contents); + void DoPreconnect(const AutocompleteMatch& match, Profile* profile); JavaObjectWeakGlobalRef weak_java_omnibox_; DISALLOW_COPY_AND_ASSIGN(OmniboxPrerender);
diff --git a/chrome/browser/android/webapk/webapk_installer.cc b/chrome/browser/android/webapk/webapk_installer.cc index e764183..143937c4 100644 --- a/chrome/browser/android/webapk/webapk_installer.cc +++ b/chrome/browser/android/webapk/webapk_installer.cc
@@ -34,7 +34,7 @@ #include "chrome/browser/android/webapk/webapk_icon_hasher.h" #include "chrome/browser/android/webapk/webapk_install_service.h" #include "chrome/browser/android/webapk/webapk_metrics.h" -#include "chrome/browser/android/webapps/webapk_ukm_recorder.h" +#include "chrome/browser/android/webapk/webapk_ukm_recorder.h" #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_switches.h"
diff --git a/chrome/browser/android/webapps/webapk_ukm_recorder.cc b/chrome/browser/android/webapk/webapk_ukm_recorder.cc similarity index 98% rename from chrome/browser/android/webapps/webapk_ukm_recorder.cc rename to chrome/browser/android/webapk/webapk_ukm_recorder.cc index 3daab3c..b80df83 100644 --- a/chrome/browser/android/webapps/webapk_ukm_recorder.cc +++ b/chrome/browser/android/webapk/webapk_ukm_recorder.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/android/webapps/webapk_ukm_recorder.h" +#include "chrome/browser/android/webapk/webapk_ukm_recorder.h" #include <jni.h>
diff --git a/chrome/browser/android/webapps/webapk_ukm_recorder.h b/chrome/browser/android/webapk/webapk_ukm_recorder.h similarity index 86% rename from chrome/browser/android/webapps/webapk_ukm_recorder.h rename to chrome/browser/android/webapk/webapk_ukm_recorder.h index d8c02537..6e87fbb 100644 --- a/chrome/browser/android/webapps/webapk_ukm_recorder.h +++ b/chrome/browser/android/webapk/webapk_ukm_recorder.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ANDROID_WEBAPPS_WEBAPK_UKM_RECORDER_H_ -#define CHROME_BROWSER_ANDROID_WEBAPPS_WEBAPK_UKM_RECORDER_H_ +#ifndef CHROME_BROWSER_ANDROID_WEBAPK_WEBAPK_UKM_RECORDER_H_ +#define CHROME_BROWSER_ANDROID_WEBAPK_WEBAPK_UKM_RECORDER_H_ #include <stdint.h> @@ -35,4 +35,4 @@ DISALLOW_IMPLICIT_CONSTRUCTORS(WebApkUkmRecorder); }; -#endif // CHROME_BROWSER_ANDROID_WEBAPPS_WEBAPK_UKM_RECORDER_H_ +#endif // CHROME_BROWSER_ANDROID_WEBAPK_WEBAPK_UKM_RECORDER_H_
diff --git a/chrome/browser/availability/availability_prober.cc b/chrome/browser/availability/availability_prober.cc index 98a6d99..b758c326 100644 --- a/chrome/browser/availability/availability_prober.cc +++ b/chrome/browser/availability/availability_prober.cc
@@ -43,6 +43,7 @@ const char kCachePrefKeyPrefix[] = "Availability.Prober.cache"; const char kSuccessHistogram[] = "Availability.Prober.DidSucceed"; +const char kFinalResultHistogram[] = "Availability.Prober.FinalState"; const char kTimeUntilSuccess[] = "Availability.Prober.TimeUntilSuccess"; const char kTimeUntilFailure[] = "Availability.Prober.TimeUntilFailure"; const char kAttemptsBeforeSuccessHistogram[] = @@ -331,6 +332,23 @@ network_connection_tracker_->AddNetworkConnectionObserver(this); } +void AvailabilityProber::OnProbingEnd() { + base::Value* cache_entry = + cached_probe_results_->FindKey(GetCacheKeyForCurrentNetwork()); + if (cache_entry) { + base::Optional<AvailabilityProberCacheEntry> entry = + DecodeCacheEntryValue(*cache_entry); + if (entry.has_value()) { + base::BooleanHistogram::FactoryGet( + AppendNameToHistogram(kFinalResultHistogram), + base::HistogramBase::kUmaTargetedHistogramFlag) + ->Add(entry.value().is_success()); + } + } + + ResetState(); +} + void AvailabilityProber::ResetState() { time_when_set_active_ = base::nullopt; successive_retry_count_ = 0; @@ -408,7 +426,7 @@ DCHECK(!url_loader_); if (!delegate_->ShouldSendNextProbe()) { - ResetState(); + OnProbingEnd(); return; } @@ -531,7 +549,7 @@ return; } - ResetState(); + OnProbingEnd(); } void AvailabilityProber::ProcessProbeSuccess() { @@ -561,7 +579,7 @@ } RecordProbeResult(true); - ResetState(); + OnProbingEnd(); } base::Optional<bool> AvailabilityProber::LastProbeWasSuccessful() {
diff --git a/chrome/browser/availability/availability_prober.h b/chrome/browser/availability/availability_prober.h index ac85b7a..ae15d10 100644 --- a/chrome/browser/availability/availability_prober.h +++ b/chrome/browser/availability/availability_prober.h
@@ -217,6 +217,11 @@ void OnApplicationStateChange(base::android::ApplicationState new_state); #endif + // This is called whenever the prober goes inactive. This is caused whenever + // the probe succeeds, fails and there are no more retries, or the delegate + // stops the probing. + void OnProbingEnd(); + // Must outlive |this|. Delegate* delegate_;
diff --git a/chrome/browser/availability/availability_prober_unittest.cc b/chrome/browser/availability/availability_prober_unittest.cc index d4e69e5..c97d0f7b 100644 --- a/chrome/browser/availability/availability_prober_unittest.cc +++ b/chrome/browser/availability/availability_prober_unittest.cc
@@ -221,6 +221,8 @@ histogram_tester.ExpectUniqueSample( "Availability.Prober.DidSucceed.Litepages", true, 1); histogram_tester.ExpectUniqueSample( + "Availability.Prober.FinalState.Litepages", true, 1); + histogram_tester.ExpectUniqueSample( "Availability.Prober.NumAttemptsBeforeSuccess.Litepages", 1, 1); histogram_tester.ExpectUniqueSample( "Availability.Prober.ResponseCode.Litepages", net::HTTP_OK, 1); @@ -246,6 +248,8 @@ histogram_tester.ExpectUniqueSample( "Availability.Prober.DidSucceed.Litepages", true, 1); histogram_tester.ExpectUniqueSample( + "Availability.Prober.FinalState.Litepages", true, 1); + histogram_tester.ExpectUniqueSample( "Availability.Prober.ResponseCode.Litepages", net::HTTP_OK, 1); histogram_tester.ExpectUniqueSample("Availability.Prober.NetError.Litepages", std::abs(net::OK), 1); @@ -395,6 +399,8 @@ histogram_tester.ExpectUniqueSample( "Availability.Prober.DidSucceed.Litepages", true, 1); histogram_tester.ExpectUniqueSample( + "Availability.Prober.FinalState.Litepages", true, 1); + histogram_tester.ExpectUniqueSample( "Availability.Prober.ResponseCode.Litepages", net::HTTP_OK, 1); histogram_tester.ExpectUniqueSample("Availability.Prober.NetError.Litepages", std::abs(net::OK), 1); @@ -435,6 +441,8 @@ histogram_tester.ExpectUniqueSample( "Availability.Prober.DidSucceed.Litepages", false, 4); + histogram_tester.ExpectUniqueSample( + "Availability.Prober.FinalState.Litepages", false, 1); histogram_tester.ExpectTotalCount( "Availability.Prober.ResponseCode.Litepages", 0); histogram_tester.ExpectUniqueSample("Availability.Prober.NetError.Litepages", @@ -458,6 +466,8 @@ histogram_tester.ExpectUniqueSample( "Availability.Prober.DidSucceed.Litepages", false, 4); + histogram_tester.ExpectUniqueSample( + "Availability.Prober.FinalState.Litepages", false, 1); histogram_tester.ExpectTotalCount( "Availability.Prober.ResponseCode.Litepages", 0); histogram_tester.ExpectUniqueSample("Availability.Prober.NetError.Litepages", @@ -479,6 +489,8 @@ histogram_tester.ExpectUniqueSample( "Availability.Prober.DidSucceed.Litepages", false, 4); histogram_tester.ExpectUniqueSample( + "Availability.Prober.FinalState.Litepages", false, 1); + histogram_tester.ExpectUniqueSample( "Availability.Prober.ResponseCode.Litepages", net::HTTP_NOT_FOUND, 4); histogram_tester.ExpectUniqueSample("Availability.Prober.NetError.Litepages", std::abs(net::OK), 4); @@ -563,6 +575,11 @@ EXPECT_FALSE(prober->LastProbeWasSuccessful().value()); EXPECT_TRUE(prober->is_active()); + histogram_tester.ExpectUniqueSample( + "Availability.Prober.DidSucceed.Litepages", false, 1); + histogram_tester.ExpectTotalCount("Availability.Prober.FinalState.Litepages", + 0); + // First retry. FastForward(base::TimeDelta::FromMilliseconds(999)); VerifyNoRequests(); @@ -572,6 +589,11 @@ EXPECT_FALSE(prober->LastProbeWasSuccessful().value()); EXPECT_TRUE(prober->is_active()); + histogram_tester.ExpectUniqueSample( + "Availability.Prober.DidSucceed.Litepages", false, 2); + histogram_tester.ExpectTotalCount("Availability.Prober.FinalState.Litepages", + 0); + // Second retry should be another 1000ms later and be the final one. FastForward(base::TimeDelta::FromMilliseconds(999)); VerifyNoRequests(); @@ -583,6 +605,8 @@ histogram_tester.ExpectUniqueSample( "Availability.Prober.DidSucceed.Litepages", false, 3); + histogram_tester.ExpectUniqueSample( + "Availability.Prober.FinalState.Litepages", false, 1); histogram_tester.ExpectTotalCount( "Availability.Prober.ResponseCode.Litepages", 0); histogram_tester.ExpectUniqueSample("Availability.Prober.NetError.Litepages", @@ -608,6 +632,11 @@ EXPECT_FALSE(prober->LastProbeWasSuccessful().value()); EXPECT_TRUE(prober->is_active()); + histogram_tester.ExpectUniqueSample( + "Availability.Prober.DidSucceed.Litepages", false, 1); + histogram_tester.ExpectTotalCount("Availability.Prober.FinalState.Litepages", + 0); + // First retry. FastForward(base::TimeDelta::FromMilliseconds(999)); VerifyNoRequests(); @@ -617,6 +646,11 @@ EXPECT_FALSE(prober->LastProbeWasSuccessful().value()); EXPECT_TRUE(prober->is_active()); + histogram_tester.ExpectUniqueSample( + "Availability.Prober.DidSucceed.Litepages", false, 2); + histogram_tester.ExpectTotalCount("Availability.Prober.FinalState.Litepages", + 0); + // Second retry should be another 1000ms later and be the final one. FastForward(base::TimeDelta::FromMilliseconds(999)); VerifyNoRequests(); @@ -631,6 +665,8 @@ histogram_tester.ExpectBucketCount("Availability.Prober.DidSucceed.Litepages", true, 1); histogram_tester.ExpectUniqueSample( + "Availability.Prober.FinalState.Litepages", true, 1); + histogram_tester.ExpectUniqueSample( "Availability.Prober.NumAttemptsBeforeSuccess.Litepages", 3, 1); histogram_tester.ExpectUniqueSample( "Availability.Prober.ResponseCode.Litepages", net::HTTP_OK, 1); @@ -794,6 +830,8 @@ histogram_tester.ExpectTotalCount("Availability.Prober.DidSucceed.Litepages", 0); + histogram_tester.ExpectTotalCount("Availability.Prober.FinalState.Litepages", + 0); } TEST_F(AvailabilityProberTest, DelegateStopsRetries) {
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index ef52a97e..48c6c03 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1123,9 +1123,6 @@ #endif extra_parts_.push_back(new ChromeContentBrowserClientPerformanceManagerPart); - - gpu_binder_registry_.AddInterface( - base::Bind(&metrics::CallStackProfileCollector::Create)); } ChromeContentBrowserClient::~ChromeContentBrowserClient() { @@ -3883,12 +3880,10 @@ interface_name, std::move(interface_pipe), render_process_host, origin); } -void ChromeContentBrowserClient::BindInterfaceRequest( - const service_manager::BindSourceInfo& source_info, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle* interface_pipe) { - if (source_info.identity.name() == content::mojom::kGpuServiceName) - gpu_binder_registry_.TryBindInterface(interface_name, interface_pipe); +void ChromeContentBrowserClient::BindGpuHostReceiver( + mojo::GenericPendingReceiver receiver) { + if (auto r = receiver.As<metrics::mojom::CallStackProfileCollector>()) + metrics::CallStackProfileCollector::Create(std::move(r)); } void ChromeContentBrowserClient::BindHostReceiverForRenderer(
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index a219479..22e3d7b 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -398,10 +398,7 @@ const url::Origin& origin, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; - void BindInterfaceRequest( - const service_manager::BindSourceInfo& source_info, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle* interface_pipe) override; + void BindGpuHostReceiver(mojo::GenericPendingReceiver receiver) override; void BindHostReceiverForRenderer( content::RenderProcessHost* render_process_host, mojo::GenericPendingReceiver receiver) override; @@ -686,8 +683,6 @@ // Parts are deleted in the reverse order they are added. std::vector<ChromeContentBrowserClientParts*> extra_parts_; - service_manager::BinderRegistry gpu_binder_registry_; - scoped_refptr<safe_browsing::SafeBrowsingService> safe_browsing_service_; scoped_refptr<safe_browsing::UrlCheckerDelegate> safe_browsing_url_checker_delegate_;
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 563aeb3..8dadbe0 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -553,10 +553,6 @@ "arc/instance_throttle/arc_boot_phase_throttle_observer.h", "arc/instance_throttle/arc_instance_throttle.cc", "arc/instance_throttle/arc_instance_throttle.h", - "arc/instance_throttle/arc_throttle_observer.cc", - "arc/instance_throttle/arc_throttle_observer.h", - "arc/instance_throttle/window_throttle_observer_base.cc", - "arc/instance_throttle/window_throttle_observer_base.h", "arc/intent_helper/arc_external_protocol_dialog.cc", "arc/intent_helper/arc_external_protocol_dialog.h", "arc/intent_helper/arc_intent_picker_app_fetcher.cc", @@ -2113,6 +2109,8 @@ "tether/tether_service.h", "tether/tether_service_factory.cc", "tether/tether_service_factory.h", + "throttle_observer.cc", + "throttle_observer.h", "tpm_firmware_update.cc", "tpm_firmware_update.h", "tpm_firmware_update_notification.cc", @@ -2154,6 +2152,8 @@ "wilco_dtc_supportd/wilco_dtc_supportd_notification_controller.h", "wilco_dtc_supportd/wilco_dtc_supportd_web_request_service.cc", "wilco_dtc_supportd/wilco_dtc_supportd_web_request_service.h", + "window_throttle_observer_base.cc", + "window_throttle_observer_base.h", # Extension API implementations. "extensions/autotest_private/autotest_private_api.cc", @@ -2443,7 +2443,6 @@ "arc/instance_throttle/arc_active_window_throttle_observer_unittest.cc", "arc/instance_throttle/arc_boot_phase_throttle_observer_unittest.cc", "arc/instance_throttle/arc_instance_throttle_unittest.cc", - "arc/instance_throttle/arc_throttle_observer_unittest.cc", "arc/intent_helper/arc_external_protocol_dialog_unittest.cc", "arc/intent_helper/arc_intent_picker_app_fetcher_unittest.cc", "arc/intent_helper/arc_settings_service_unittest.cc", @@ -2803,6 +2802,7 @@ "system_logs/single_debug_daemon_log_source_unittest.cc", "system_logs/single_log_file_log_source_unittest.cc", "tether/tether_service_unittest.cc", + "throttle_observer_unittest.cc", "tpm_firmware_update_unittest.cc", "ui/gnubby_notification_unittest.cc", "ui/idle_app_name_notification_view_unittest.cc",
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_active_window_throttle_observer.cc b/chrome/browser/chromeos/arc/instance_throttle/arc_active_window_throttle_observer.cc index 7b3377c..75891b8 100644 --- a/chrome/browser/chromeos/arc/instance_throttle/arc_active_window_throttle_observer.cc +++ b/chrome/browser/chromeos/arc/instance_throttle/arc_active_window_throttle_observer.cc
@@ -9,7 +9,7 @@ namespace arc { ArcActiveWindowThrottleObserver::ArcActiveWindowThrottleObserver() - : WindowThrottleObserverBase(ArcThrottleObserver::PriorityLevel::CRITICAL, + : WindowThrottleObserverBase(ThrottleObserver::PriorityLevel::CRITICAL, "ArcWindowIsActiveWindow") {} bool ArcActiveWindowThrottleObserver::ProcessWindowActivation(
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_active_window_throttle_observer.h b/chrome/browser/chromeos/arc/instance_throttle/arc_active_window_throttle_observer.h index 95b507d..b30b690 100644 --- a/chrome/browser/chromeos/arc/instance_throttle/arc_active_window_throttle_observer.h +++ b/chrome/browser/chromeos/arc/instance_throttle/arc_active_window_throttle_observer.h
@@ -6,14 +6,14 @@ #define CHROME_BROWSER_CHROMEOS_ARC_INSTANCE_THROTTLE_ARC_ACTIVE_WINDOW_THROTTLE_OBSERVER_H_ #include "base/macros.h" -#include "chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.h" -#include "chrome/browser/chromeos/arc/instance_throttle/window_throttle_observer_base.h" +#include "chrome/browser/chromeos/window_throttle_observer_base.h" namespace arc { // This class observes window activations and sets the state to active if the // currently active window is an ARC window. -class ArcActiveWindowThrottleObserver : public WindowThrottleObserverBase { +class ArcActiveWindowThrottleObserver + : public chromeos::WindowThrottleObserverBase { public: ArcActiveWindowThrottleObserver(); ~ArcActiveWindowThrottleObserver() override = default;
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer.cc b/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer.cc index 1ea8a7e..92079e7e 100644 --- a/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer.cc +++ b/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer.cc
@@ -11,23 +11,21 @@ namespace arc { ArcBootPhaseThrottleObserver::ArcBootPhaseThrottleObserver() - : ArcThrottleObserver(ArcThrottleObserver::PriorityLevel::CRITICAL, - "ArcIsBooting") {} + : ThrottleObserver(ThrottleObserver::PriorityLevel::CRITICAL, + "ArcIsBooting") {} void ArcBootPhaseThrottleObserver::StartObserving( - ArcBridgeService* arc_bridge_service, content::BrowserContext* context, const ObserverStateChangedCallback& callback) { - DCHECK(!context_ && !boot_phase_monitor_); - ArcThrottleObserver::StartObserving(arc_bridge_service, context, callback); - context_ = context; + DCHECK(!boot_phase_monitor_); + ThrottleObserver::StartObserving(context, callback); auto* session_manager = ArcSessionManager::Get(); DCHECK(session_manager); session_manager->AddObserver(this); boot_phase_monitor_ = - ArcBootPhaseMonitorBridge::GetForBrowserContext(context_); + ArcBootPhaseMonitorBridge::GetForBrowserContext(context); DCHECK(boot_phase_monitor_); boot_phase_monitor_->AddObserver(this); @@ -44,8 +42,7 @@ DCHECK(session_manager); session_manager->RemoveObserver(this); - context_ = nullptr; - ArcThrottleObserver::StopObserving(); + ThrottleObserver::StopObserving(); } void ArcBootPhaseThrottleObserver::OnArcStarted() { @@ -85,7 +82,7 @@ SetActive(false); return; } - auto* profile = Profile::FromBrowserContext(context_); + auto* profile = Profile::FromBrowserContext(context()); const bool enabled_by_policy = IsArcPlayStoreEnabledForProfile(profile) && IsArcPlayStoreEnabledPreferenceManagedForProfile(profile);
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer.h b/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer.h index 9b0c0f7..0947e6f 100644 --- a/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer.h +++ b/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer.h
@@ -8,7 +8,7 @@ #include "base/macros.h" #include "chrome/browser/chromeos/arc/arc_session_manager.h" #include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" -#include "chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.h" +#include "chrome/browser/chromeos/throttle_observer.h" #include "chrome/browser/sessions/session_restore_observer.h" namespace content { @@ -17,11 +17,9 @@ namespace arc { -class ArcBridgeService; - // This class observes phases of ARC boot and unthrottles the container // when ARC is booting or restarting. -class ArcBootPhaseThrottleObserver : public ArcThrottleObserver, +class ArcBootPhaseThrottleObserver : public chromeos::ThrottleObserver, public ArcSessionManager::Observer, public ArcBootPhaseMonitorBridge::Observer, public SessionRestoreObserver { @@ -29,9 +27,8 @@ ArcBootPhaseThrottleObserver(); ~ArcBootPhaseThrottleObserver() override = default; - // ArcThrottleObserver: - void StartObserving(ArcBridgeService* arc_bridge_service, - content::BrowserContext* context, + // chromeos::ThrottleObserver: + void StartObserving(content::BrowserContext* context, const ObserverStateChangedCallback& callback) override; void StopObserving() override; @@ -53,7 +50,6 @@ // enable since in these cases ARC should always be unthrottled during boot. void MaybeSetActive(); - content::BrowserContext* context_ = nullptr; ArcBootPhaseMonitorBridge* boot_phase_monitor_ = nullptr; bool session_restore_loading_ = false; bool arc_is_booting_ = false;
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer_unittest.cc b/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer_unittest.cc index 1e04e35..b932992 100644 --- a/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer_unittest.cc +++ b/chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer_unittest.cc
@@ -45,7 +45,7 @@ ArcBootPhaseMonitorBridge::GetForBrowserContextForTesting(profile()); observer()->StartObserving( - nullptr, profile(), + profile(), ArcBootPhaseThrottleObserver::ObserverStateChangedCallback()); }
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle.cc b/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle.cc index eabfad92..00821f7 100644 --- a/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle.cc +++ b/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle.cc
@@ -10,7 +10,7 @@ #include "base/memory/singleton.h" #include "base/metrics/histogram_functions.h" #include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" -#include "chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.h" +#include "chrome/browser/chromeos/throttle_observer.h" #include "components/arc/arc_browser_context_keyed_service_factory_base.h" #include "components/arc/arc_util.h" @@ -73,15 +73,14 @@ ArcInstanceThrottle::ArcInstanceThrottle(content::BrowserContext* context, ArcBridgeService* bridge_service) - : arc_bridge_service_(bridge_service), - context_(context), + : context_(context), delegate_(std::make_unique<DefaultDelegateImpl>()), weak_ptr_factory_(this) { auto callback = base::BindRepeating(&ArcInstanceThrottle::OnObserverStateChanged, weak_ptr_factory_.GetWeakPtr()); for (auto* observer : GetAllObservers()) - observer->StartObserving(bridge_service, context, callback); + observer->StartObserving(context, callback); } ArcInstanceThrottle::~ArcInstanceThrottle() = default; @@ -92,9 +91,9 @@ } void ArcInstanceThrottle::OnObserverStateChanged() { - ArcThrottleObserver::PriorityLevel max_level = - ArcThrottleObserver::PriorityLevel::LOW; - ArcThrottleObserver* effective_observer = nullptr; + chromeos::ThrottleObserver::PriorityLevel max_level = + chromeos::ThrottleObserver::PriorityLevel::LOW; + chromeos::ThrottleObserver* effective_observer = nullptr; std::string active_observers; for (auto* observer : GetAllObservers()) { @@ -125,24 +124,25 @@ } void ArcInstanceThrottle::ThrottleInstance( - ArcThrottleObserver::PriorityLevel level) { + chromeos::ThrottleObserver::PriorityLevel level) { if (level_ == level) return; level_ = level; switch (level_) { - case ArcThrottleObserver::PriorityLevel::CRITICAL: - case ArcThrottleObserver::PriorityLevel::IMPORTANT: - case ArcThrottleObserver::PriorityLevel::NORMAL: + case chromeos::ThrottleObserver::PriorityLevel::CRITICAL: + case chromeos::ThrottleObserver::PriorityLevel::IMPORTANT: + case chromeos::ThrottleObserver::PriorityLevel::NORMAL: delegate_->SetCpuRestriction(false); break; - case ArcThrottleObserver::PriorityLevel::LOW: - case ArcThrottleObserver::PriorityLevel::UNKNOWN: + case chromeos::ThrottleObserver::PriorityLevel::LOW: + case chromeos::ThrottleObserver::PriorityLevel::UNKNOWN: delegate_->SetCpuRestriction(true); break; } } -std::vector<ArcThrottleObserver*> ArcInstanceThrottle::GetAllObservers() { +std::vector<chromeos::ThrottleObserver*> +ArcInstanceThrottle::GetAllObservers() { if (!observers_for_testing_.empty()) return observers_for_testing_; return {&active_window_throttle_observer_, &boot_phase_throttle_observer_}; @@ -153,7 +153,7 @@ } void ArcInstanceThrottle::SetObserversForTesting( - const std::vector<ArcThrottleObserver*>& observers) { + const std::vector<chromeos::ThrottleObserver*>& observers) { for (auto* observer : GetAllObservers()) observer->StopObserving(); observers_for_testing_ = observers; @@ -161,6 +161,6 @@ base::BindRepeating(&ArcInstanceThrottle::OnObserverStateChanged, weak_ptr_factory_.GetWeakPtr()); for (auto* observer : GetAllObservers()) - observer->StartObserving(arc_bridge_service_, context_, callback); + observer->StartObserving(context_, callback); } } // namespace arc
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle.h b/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle.h index c1cc998..57f6dc1 100644 --- a/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle.h +++ b/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle.h
@@ -14,7 +14,7 @@ #include "base/time/time.h" #include "chrome/browser/chromeos/arc/instance_throttle/arc_active_window_throttle_observer.h" #include "chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer.h" -#include "chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.h" +#include "chrome/browser/chromeos/throttle_observer.h" #include "components/keyed_service/core/keyed_service.h" namespace content { @@ -60,24 +60,23 @@ // Functions for testing void NotifyObserverStateChangedForTesting(); void SetObserversForTesting( - const std::vector<ArcThrottleObserver*>& observers); + const std::vector<chromeos::ThrottleObserver*>& observers); void set_delegate_for_testing(std::unique_ptr<Delegate> delegate) { delegate_ = std::move(delegate); } private: - std::vector<ArcThrottleObserver*> GetAllObservers(); + std::vector<chromeos::ThrottleObserver*> GetAllObservers(); void OnObserverStateChanged(); - void ThrottleInstance(ArcThrottleObserver::PriorityLevel level); + void ThrottleInstance(chromeos::ThrottleObserver::PriorityLevel level); - ArcBridgeService* arc_bridge_service_; content::BrowserContext* context_; - std::vector<ArcThrottleObserver*> observers_for_testing_; + std::vector<chromeos::ThrottleObserver*> observers_for_testing_; std::unique_ptr<Delegate> delegate_; - ArcThrottleObserver::PriorityLevel level_{ - ArcThrottleObserver::PriorityLevel::UNKNOWN}; - ArcThrottleObserver* last_effective_observer_ = nullptr; + chromeos::ThrottleObserver::PriorityLevel level_{ + chromeos::ThrottleObserver::PriorityLevel::UNKNOWN}; + chromeos::ThrottleObserver* last_effective_observer_ = nullptr; base::TimeTicks last_throttle_transition_; // Throttle Observers
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle_unittest.cc b/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle_unittest.cc index 4f91a2038..27f59a4 100644 --- a/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle_unittest.cc +++ b/chrome/browser/chromeos/arc/instance_throttle/arc_instance_throttle_unittest.cc
@@ -11,7 +11,7 @@ #include "base/test/task_environment.h" #include "chrome/browser/chromeos/arc/arc_session_manager.h" #include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" -#include "chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.h" +#include "chrome/browser/chromeos/throttle_observer.h" #include "chrome/test/base/testing_profile.h" #include "components/arc/arc_prefs.h" #include "components/arc/arc_service_manager.h" @@ -67,8 +67,10 @@ return enable_cpu_restriction_counter_; } - ArcThrottleObserver* critical_observer() { return &critical_observer_; } - ArcThrottleObserver* low_observer() { return &low_observer_; } + chromeos::ThrottleObserver* critical_observer() { + return &critical_observer_; + } + chromeos::ThrottleObserver* low_observer() { return &low_observer_; } const std::string& last_recorded_observer_name() const { return last_recorded_observer_name_; } @@ -102,10 +104,10 @@ ArcInstanceThrottle* arc_instance_throttle_; size_t disable_cpu_restriction_counter_; size_t enable_cpu_restriction_counter_; - ArcThrottleObserver critical_observer_{ - ArcThrottleObserver::PriorityLevel::CRITICAL, "CriticalObserver"}; - ArcThrottleObserver low_observer_{ArcThrottleObserver::PriorityLevel::LOW, - "LowObserver"}; + chromeos::ThrottleObserver critical_observer_{ + chromeos::ThrottleObserver::PriorityLevel::CRITICAL, "CriticalObserver"}; + chromeos::ThrottleObserver low_observer_{ + chromeos::ThrottleObserver::PriorityLevel::LOW, "LowObserver"}; std::string last_recorded_observer_name_; size_t record_uma_counter_; @@ -120,8 +122,8 @@ // a change in observers, but skips adjusting throttle if the new level is same // as before. TEST_F(ArcInstanceThrottleTest, TestOnObserverStateChanged) { - std::vector<ArcThrottleObserver*> observers = {critical_observer(), - low_observer()}; + std::vector<chromeos::ThrottleObserver*> observers = {critical_observer(), + low_observer()}; arc_instance_throttle()->SetObserversForTesting(observers); EXPECT_EQ(0U, disable_cpu_restriction_counter()); EXPECT_EQ(0U, enable_cpu_restriction_counter()); @@ -149,8 +151,8 @@ // Tests that ArcInstanceThrottle records the duration that the effective // observer is active. TEST_F(ArcInstanceThrottleTest, RecordCpuRestrictionDisabledUMA) { - std::vector<ArcThrottleObserver*> observers = {critical_observer(), - low_observer()}; + std::vector<chromeos::ThrottleObserver*> observers = {critical_observer(), + low_observer()}; arc_instance_throttle()->SetObserversForTesting(observers); EXPECT_EQ(0U, uma_count());
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.cc b/chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.cc deleted file mode 100644 index 6642464..0000000 --- a/chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.cc +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.h" - -namespace arc { - -namespace { - -std::string LevelToString(ArcThrottleObserver::PriorityLevel level) { - switch (level) { - case ArcThrottleObserver::PriorityLevel::LOW: - return "PriorityLevel::LOW"; - case ArcThrottleObserver::PriorityLevel::NORMAL: - return "PriorityLevel::NORMAL"; - case ArcThrottleObserver::PriorityLevel::IMPORTANT: - return "PriorityLevel::IMPORTANT"; - case ArcThrottleObserver::PriorityLevel::CRITICAL: - return "PriorityLevel::CRITICAL"; - case ArcThrottleObserver::PriorityLevel::UNKNOWN: - return "PriorityLevel::UNKNOWN"; - } -} - -} // namespace - -ArcThrottleObserver::ArcThrottleObserver( - ArcThrottleObserver::PriorityLevel level, - const std::string& name) - : level_(level), name_(name) {} - -ArcThrottleObserver::~ArcThrottleObserver() = default; - -void ArcThrottleObserver::StartObserving( - ArcBridgeService* arc_bridge_service, - content::BrowserContext* context, - const ObserverStateChangedCallback& callback) { - DCHECK(!callback_); - callback_ = callback; -} - -void ArcThrottleObserver::StopObserving() { - callback_.Reset(); -} - -void ArcThrottleObserver::SetActive(bool active) { - if (active_ == active) - return; - active_ = active; - if (callback_) - callback_.Run(); -} - -std::string ArcThrottleObserver::GetDebugDescription() const { - return ("ArcThrottleObserver(" + name() + ", " + LevelToString(level()) + - ", " + (active() ? "active" : "inactive") + ")"); -} - -} // namespace arc
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer_unittest.cc b/chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer_unittest.cc deleted file mode 100644 index a800012..0000000 --- a/chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer_unittest.cc +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.h" - -#include "base/bind.h" -#include "base/memory/weak_ptr.h" -#include "base/template_util.h" -#include "base/test/task_environment.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace arc { - -class ArcThrottleObserverTest - : public testing::Test, - public base::SupportsWeakPtr<ArcThrottleObserverTest> { - public: - ArcThrottleObserverTest() { - observer_.StartObserving( - nullptr /* ArcBridgeService* */, nullptr /* content::BrowserContext* */, - base::BindRepeating(&ArcThrottleObserverTest::OnObserverStateChanged, - AsWeakPtr())); - } - - void OnObserverStateChanged() { notify_count_++; } - - protected: - ArcThrottleObserver* observer() { return &observer_; } - size_t notify_count() const { return notify_count_; } - - private: - ArcThrottleObserver observer_{ArcThrottleObserver::PriorityLevel::LOW, - "TestObserver"}; - size_t notify_count_{0}; - - DISALLOW_COPY_AND_ASSIGN(ArcThrottleObserverTest); -}; - -// Tests that ArcThrottleObserver can be constructed and destructed. -TEST_F(ArcThrottleObserverTest, TestConstructDestruct) {} - -// Tests that ArcThrottleObserver notifies observers only when its 'active' -// state changes -TEST_F(ArcThrottleObserverTest, TestSetActive) { - EXPECT_EQ(0U, notify_count()); - EXPECT_FALSE(observer()->active()); - - observer()->SetActive(true); - EXPECT_TRUE(observer()->active()); - EXPECT_EQ(1U, notify_count()); - - observer()->SetActive(true); - EXPECT_TRUE(observer()->active()); - EXPECT_EQ(1U, notify_count()); - - observer()->SetActive(false); - EXPECT_FALSE(observer()->active()); - EXPECT_EQ(2U, notify_count()); -} - -} // namespace arc
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.cc b/chrome/browser/chromeos/crostini/crostini_manager.cc index 12d5ef2..fa66ea9 100644 --- a/chrome/browser/chromeos/crostini/crostini_manager.cc +++ b/chrome/browser/chromeos/crostini/crostini_manager.cc
@@ -1113,7 +1113,6 @@ request.set_vm_name(std::move(vm_name)); request.set_container_name(std::move(container_name)); request.set_owner_id(owner_id_); - request.set_async(true); if (auto* integration_service = drive::DriveIntegrationServiceFactory::GetForProfile(profile_)) { request.set_drivefs_mount_path(
diff --git a/chrome/browser/chromeos/throttle_observer.cc b/chrome/browser/chromeos/throttle_observer.cc new file mode 100644 index 0000000..f1210d2 --- /dev/null +++ b/chrome/browser/chromeos/throttle_observer.cc
@@ -0,0 +1,59 @@ +// 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/chromeos/throttle_observer.h" + +namespace chromeos { +namespace { + +std::string LevelToString(ThrottleObserver::PriorityLevel level) { + switch (level) { + case ThrottleObserver::PriorityLevel::LOW: + return "PriorityLevel::LOW"; + case ThrottleObserver::PriorityLevel::NORMAL: + return "PriorityLevel::NORMAL"; + case ThrottleObserver::PriorityLevel::IMPORTANT: + return "PriorityLevel::IMPORTANT"; + case ThrottleObserver::PriorityLevel::CRITICAL: + return "PriorityLevel::CRITICAL"; + case ThrottleObserver::PriorityLevel::UNKNOWN: + return "PriorityLevel::UNKNOWN"; + } +} + +} // namespace + +ThrottleObserver::ThrottleObserver(ThrottleObserver::PriorityLevel level, + const std::string& name) + : level_(level), name_(name) {} + +ThrottleObserver::~ThrottleObserver() = default; + +void ThrottleObserver::StartObserving( + content::BrowserContext* context, + const ObserverStateChangedCallback& callback) { + DCHECK(!callback_); + callback_ = callback; + context_ = context; +} + +void ThrottleObserver::StopObserving() { + callback_.Reset(); + context_ = nullptr; +} + +void ThrottleObserver::SetActive(bool active) { + if (active_ == active) + return; + active_ = active; + if (callback_) + callback_.Run(); +} + +std::string ThrottleObserver::GetDebugDescription() const { + return ("ThrottleObserver(" + name() + ", " + LevelToString(level()) + ", " + + (active() ? "active" : "inactive") + ")"); +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.h b/chrome/browser/chromeos/throttle_observer.h similarity index 70% rename from chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.h rename to chrome/browser/chromeos/throttle_observer.h index 2abf55a..3d0c22c7 100644 --- a/chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.h +++ b/chrome/browser/chromeos/throttle_observer.h
@@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_ARC_INSTANCE_THROTTLE_ARC_THROTTLE_OBSERVER_H_ -#define CHROME_BROWSER_CHROMEOS_ARC_INSTANCE_THROTTLE_ARC_THROTTLE_OBSERVER_H_ +#ifndef CHROME_BROWSER_CHROMEOS_THROTTLE_OBSERVER_H_ +#define CHROME_BROWSER_CHROMEOS_THROTTLE_OBSERVER_H_ #include <string> #include "base/callback.h" +#include "base/macros.h" #include "base/observer_list.h" #include "base/observer_list_types.h" @@ -15,26 +16,25 @@ class BrowserContext; } -namespace arc { -class ArcBridgeService; +namespace chromeos { // Base throttle observer class. Each throttle observer watches a particular // condition (window activates, mojom instance disconnects, and so on) and -// notifies any observers when there is a change. -class ArcThrottleObserver { +// calls the ObserverStateChangedCallback when there is a change. +class ThrottleObserver { public: using ObserverStateChangedCallback = base::RepeatingCallback<void()>; enum class PriorityLevel { UNKNOWN, LOW, NORMAL, IMPORTANT, CRITICAL }; - ArcThrottleObserver(PriorityLevel level, const std::string& name); - virtual ~ArcThrottleObserver(); + ThrottleObserver(PriorityLevel level, const std::string& name); + virtual ~ThrottleObserver(); // Starts observing. This is overridden in derived classes to register self as // observer for a particular condition. However, the base method should be // called in overridden methods, so that the callback_ member is initialized. - virtual void StartObserving(ArcBridgeService* arc_bridge_service, - content::BrowserContext* content, + virtual void StartObserving(content::BrowserContext* content, const ObserverStateChangedCallback& callback); + // Stops observing. This method is the last place in which context can be // used. virtual void StopObserving(); @@ -50,15 +50,19 @@ bool active() const { return active_; } protected: + content::BrowserContext* context() { return context_; } + const PriorityLevel level_{PriorityLevel::UNKNOWN}; bool active_ = false; const std::string name_; // For logging purposes ObserverStateChangedCallback callback_; private: - DISALLOW_COPY_AND_ASSIGN(ArcThrottleObserver); + content::BrowserContext* context_; + + DISALLOW_COPY_AND_ASSIGN(ThrottleObserver); }; -} // namespace arc +} // namespace chromeos -#endif // CHROME_BROWSER_CHROMEOS_ARC_INSTANCE_THROTTLE_ARC_THROTTLE_OBSERVER_H_ +#endif // CHROME_BROWSER_CHROMEOS_THROTTLE_OBSERVER_H_
diff --git a/chrome/browser/chromeos/throttle_observer_unittest.cc b/chrome/browser/chromeos/throttle_observer_unittest.cc new file mode 100644 index 0000000..20b2d9e --- /dev/null +++ b/chrome/browser/chromeos/throttle_observer_unittest.cc
@@ -0,0 +1,62 @@ +// 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/chromeos/throttle_observer.h" + +#include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "base/template_util.h" +#include "base/test/task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { + +class ThrottleObserverTest + : public testing::Test, + public base::SupportsWeakPtr<ThrottleObserverTest> { + public: + ThrottleObserverTest() { + observer_.StartObserving( + nullptr /* content::BrowserContext* */, + base::BindRepeating(&ThrottleObserverTest::OnObserverStateChanged, + AsWeakPtr())); + } + + void OnObserverStateChanged() { notify_count_++; } + + protected: + ThrottleObserver* observer() { return &observer_; } + size_t notify_count() const { return notify_count_; } + + private: + ThrottleObserver observer_{ThrottleObserver::PriorityLevel::LOW, + "TestObserver"}; + size_t notify_count_{0}; + + DISALLOW_COPY_AND_ASSIGN(ThrottleObserverTest); +}; + +// Tests that ThrottleObserver can be constructed and destructed. +TEST_F(ThrottleObserverTest, TestConstructDestruct) {} + +// Tests that ThrottleObserver notifies observers only when its 'active' +// state changes +TEST_F(ThrottleObserverTest, TestSetActive) { + EXPECT_EQ(0U, notify_count()); + EXPECT_FALSE(observer()->active()); + + observer()->SetActive(true); + EXPECT_TRUE(observer()->active()); + EXPECT_EQ(1U, notify_count()); + + observer()->SetActive(true); + EXPECT_TRUE(observer()->active()); + EXPECT_EQ(1U, notify_count()); + + observer()->SetActive(false); + EXPECT_FALSE(observer()->active()); + EXPECT_EQ(2U, notify_count()); +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/arc/instance_throttle/window_throttle_observer_base.cc b/chrome/browser/chromeos/window_throttle_observer_base.cc similarity index 88% rename from chrome/browser/chromeos/arc/instance_throttle/window_throttle_observer_base.cc rename to chrome/browser/chromeos/window_throttle_observer_base.cc index 5a2fe86a..4aecc9ee 100644 --- a/chrome/browser/chromeos/arc/instance_throttle/window_throttle_observer_base.cc +++ b/chrome/browser/chromeos/window_throttle_observer_base.cc
@@ -2,15 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/arc/instance_throttle/window_throttle_observer_base.h" +#include "chrome/browser/chromeos/window_throttle_observer_base.h" #include "ash/public/cpp/shell_window_ids.h" -#include "chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.h" #include "components/exo/wm_helper.h" #include "ui/aura/window.h" #include "ui/wm/public/activation_change_observer.h" -namespace arc { +namespace chromeos { namespace { // Returns true if the window is in the app list window container. @@ -63,22 +62,21 @@ } // namespace WindowThrottleObserverBase::WindowThrottleObserverBase( - ArcThrottleObserver::PriorityLevel level, + ThrottleObserver::PriorityLevel level, std::string name) - : ArcThrottleObserver(level, name) {} + : ThrottleObserver(level, name) {} void WindowThrottleObserverBase::StartObserving( - ArcBridgeService* arc_bridge_service, content::BrowserContext* context, const ObserverStateChangedCallback& callback) { - ArcThrottleObserver::StartObserving(arc_bridge_service, context, callback); + ThrottleObserver::StartObserving(context, callback); if (!exo::WMHelper::HasInstance()) // for unit testing return; exo::WMHelper::GetInstance()->AddActivationObserver(this); } void WindowThrottleObserverBase::StopObserving() { - ArcThrottleObserver::StopObserving(); + ThrottleObserver::StopObserving(); if (!exo::WMHelper::HasInstance()) return; exo::WMHelper::GetInstance()->RemoveActivationObserver(this); @@ -92,4 +90,4 @@ SetActive(ProcessWindowActivation(reason, gained_active, lost_active)); } -} // namespace arc +} // namespace chromeos
diff --git a/chrome/browser/chromeos/arc/instance_throttle/window_throttle_observer_base.h b/chrome/browser/chromeos/window_throttle_observer_base.h similarity index 65% rename from chrome/browser/chromeos/arc/instance_throttle/window_throttle_observer_base.h rename to chrome/browser/chromeos/window_throttle_observer_base.h index a4c1aa80..abad75a 100644 --- a/chrome/browser/chromeos/arc/instance_throttle/window_throttle_observer_base.h +++ b/chrome/browser/chromeos/window_throttle_observer_base.h
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_ARC_INSTANCE_THROTTLE_WINDOW_THROTTLE_OBSERVER_BASE_H_ -#define CHROME_BROWSER_CHROMEOS_ARC_INSTANCE_THROTTLE_WINDOW_THROTTLE_OBSERVER_BASE_H_ +#ifndef CHROME_BROWSER_CHROMEOS_WINDOW_THROTTLE_OBSERVER_BASE_H_ +#define CHROME_BROWSER_CHROMEOS_WINDOW_THROTTLE_OBSERVER_BASE_H_ #include "base/macros.h" -#include "chrome/browser/chromeos/arc/instance_throttle/arc_throttle_observer.h" +#include "chrome/browser/chromeos/throttle_observer.h" #include "ui/wm/public/activation_change_observer.h" namespace content { @@ -17,21 +17,18 @@ class Window; } -namespace arc { - -class ArcBridgeService; +namespace chromeos { // Base class for locks that observe changes in window activation. -class WindowThrottleObserverBase : public ArcThrottleObserver, +class WindowThrottleObserverBase : public ThrottleObserver, public wm::ActivationChangeObserver { public: - WindowThrottleObserverBase(ArcThrottleObserver::PriorityLevel level, + WindowThrottleObserverBase(ThrottleObserver::PriorityLevel level, std::string name); ~WindowThrottleObserverBase() override = default; - // ArcThrottleObserver: - void StartObserving(ArcBridgeService* arc_bridge_service, - content::BrowserContext* context, + // ThrottleObserver: + void StartObserving(content::BrowserContext* context, const ObserverStateChangedCallback& callback) override; void StopObserving() override; @@ -51,6 +48,6 @@ DISALLOW_COPY_AND_ASSIGN(WindowThrottleObserverBase); }; -} // namespace arc +} // namespace chromeos -#endif // CHROME_BROWSER_CHROMEOS_ARC_INSTANCE_THROTTLE_WINDOW_THROTTLE_OBSERVER_BASE_H_ +#endif // CHROME_BROWSER_CHROMEOS_WINDOW_THROTTLE_OBSERVER_BASE_H_
diff --git a/chrome/browser/enterprise_reporting/report_uploader.cc b/chrome/browser/enterprise_reporting/report_uploader.cc index 614087a3..38795ba 100644 --- a/chrome/browser/enterprise_reporting/report_uploader.cc +++ b/chrome/browser/enterprise_reporting/report_uploader.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/metrics/histogram_functions.h" #include "base/time/time.h" #include "components/policy/core/common/cloud/cloud_policy_client.h" @@ -25,6 +26,10 @@ false // Do not always use initial delay. }; +void RecordReportResponseMetrics(ReportResponseMetricsStatus status) { + base::UmaHistogramEnumeration("Enterprise.CloudReportingResponse", status); +} + } // namespace ReportUploader::ReportUploader(policy::CloudPolicyClient* client, @@ -51,27 +56,40 @@ void ReportUploader::OnRequestFinished(bool status) { if (status) { NextRequest(); + RecordReportResponseMetrics(ReportResponseMetricsStatus::kSuccess); return; } switch (client_->status()) { case policy::DM_STATUS_REQUEST_FAILED: // network error + RecordReportResponseMetrics(ReportResponseMetricsStatus::kNetworkError); + Retry(); + break; case policy::DM_STATUS_TEMPORARY_UNAVAILABLE: // 5xx server error + RecordReportResponseMetrics( + ReportResponseMetricsStatus::kTemporaryServerError); + Retry(); + break; // DM_STATUS_SERVICE_DEVICE_ID_CONFLICT is caused by 409 conflict. It can // be caused by either device id conflict or DDS concur error which is // a database error. We only want to retry for the second case. However, // there is no way for us to tell difference right now so we will retry // regardless. case policy::DM_STATUS_SERVICE_DEVICE_ID_CONFLICT: + RecordReportResponseMetrics( + ReportResponseMetricsStatus::kDDSConcurrencyError); Retry(); break; case policy::DM_STATUS_REQUEST_TOO_LARGE: // Treats the REQUEST_TOO_LARGE error as a success upload. It's likely // a calculation error during request generating and there is nothing // can be done here. + RecordReportResponseMetrics( + ReportResponseMetricsStatus::kRequestTooLargeError); NextRequest(); break; default: + RecordReportResponseMetrics(ReportResponseMetricsStatus::kOtherError); SendResponse(ReportStatus::kPersistentError); break; }
diff --git a/chrome/browser/enterprise_reporting/report_uploader.h b/chrome/browser/enterprise_reporting/report_uploader.h index e4337b56..44b6900 100644 --- a/chrome/browser/enterprise_reporting/report_uploader.h +++ b/chrome/browser/enterprise_reporting/report_uploader.h
@@ -90,6 +90,16 @@ DISALLOW_COPY_AND_ASSIGN(ReportUploader); }; +enum ReportResponseMetricsStatus { + kSuccess = 0, + kNetworkError = 1, + kTemporaryServerError = 2, + kDDSConcurrencyError = 3, + kRequestTooLargeError = 4, + kOtherError = 5, + kMaxValue = kOtherError, +}; + } // namespace enterprise_reporting #endif // CHROME_BROWSER_ENTERPRISE_REPORTING_REPORT_UPLOADER_H_
diff --git a/chrome/browser/enterprise_reporting/report_uploader_unittest.cc b/chrome/browser/enterprise_reporting/report_uploader_unittest.cc index f00e0f1..b1b25b1 100644 --- a/chrome/browser/enterprise_reporting/report_uploader_unittest.cc +++ b/chrome/browser/enterprise_reporting/report_uploader_unittest.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" #include "testing/gmock/include/gmock/gmock.h" @@ -20,6 +21,8 @@ namespace enterprise_reporting { namespace { constexpr const char* kOsUserNames[] = {"name1", "name2"}; +constexpr char kResponseMetricsName[] = "Enterprise.CloudReportingResponse"; + } // namespace class ReportUploaderTest : public ::testing::Test { @@ -82,6 +85,7 @@ std::unique_ptr<ReportUploader> uploader_; policy::MockCloudPolicyClient client_; bool has_responded_ = false; + base::HistogramTester histogram_tester_; private: DISALLOW_COPY_AND_ASSIGN(ReportUploaderTest); @@ -98,6 +102,8 @@ ReportUploader::kSuccess); RunNextTask(); EXPECT_TRUE(has_responded_); + histogram_tester_.ExpectUniqueSample( + kResponseMetricsName, ReportResponseMetricsStatus::kSuccess, 1); ::testing::Mock::VerifyAndClearExpectations(&client_); } @@ -110,6 +116,8 @@ ReportUploader::kPersistentError); RunNextTask(); EXPECT_TRUE(has_responded_); + histogram_tester_.ExpectUniqueSample( + kResponseMetricsName, ReportResponseMetricsStatus::kOtherError, 1); ::testing::Mock::VerifyAndClearExpectations(&client_); } @@ -124,6 +132,9 @@ ReportUploader::kSuccess); RunNextTask(); EXPECT_TRUE(has_responded_); + histogram_tester_.ExpectUniqueSample( + kResponseMetricsName, ReportResponseMetricsStatus::kRequestTooLargeError, + 2); ::testing::Mock::VerifyAndClearExpectations(&client_); } @@ -143,6 +154,12 @@ RunNextTask(); EXPECT_TRUE(has_responded_); ::testing::Mock::VerifyAndClearExpectations(&client_); + histogram_tester_.ExpectTotalCount(kResponseMetricsName, 2); + histogram_tester_.ExpectBucketCount(kResponseMetricsName, + ReportResponseMetricsStatus::kSuccess, 1); + histogram_tester_.ExpectBucketCount( + kResponseMetricsName, ReportResponseMetricsStatus::kTemporaryServerError, + 1); } TEST_F(ReportUploaderTest, RetryAndFailedWithPersistentError) { @@ -155,6 +172,10 @@ ReportUploader::kPersistentError); RunNextTask(); + histogram_tester_.ExpectUniqueSample( + kResponseMetricsName, ReportResponseMetricsStatus::kTemporaryServerError, + 1); + // No response, request is retried. EXPECT_FALSE(has_responded_); // Error is changed. @@ -162,6 +183,9 @@ RunNextTask(); EXPECT_TRUE(has_responded_); ::testing::Mock::VerifyAndClearExpectations(&client_); + histogram_tester_.ExpectTotalCount(kResponseMetricsName, 2); + histogram_tester_.ExpectBucketCount( + kResponseMetricsName, ReportResponseMetricsStatus::kOtherError, 1); } TEST_F(ReportUploaderTest, RetryAndFailedWithTransientError) { @@ -174,10 +198,17 @@ ReportUploader::kTransientError); RunNextTask(); + histogram_tester_.ExpectUniqueSample( + kResponseMetricsName, ReportResponseMetricsStatus::kTemporaryServerError, + 1); + // No response, request is retried. EXPECT_FALSE(has_responded_); RunNextTask(); EXPECT_TRUE(has_responded_); + histogram_tester_.ExpectUniqueSample( + kResponseMetricsName, ReportResponseMetricsStatus::kTemporaryServerError, + 2); ::testing::Mock::VerifyAndClearExpectations(&client_); }
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index 542abde..23337da2 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -94,17 +94,6 @@ } #if defined(OS_CHROMEOS) -Profile* GetPrimaryProfile() { - // Obtains the primary profile. - if (!user_manager::UserManager::IsInitialized()) - return nullptr; - const user_manager::User* primary_user = - user_manager::UserManager::Get()->GetPrimaryUser(); - if (!primary_user) - return nullptr; - return chromeos::ProfileHelper::Get()->GetProfileByUser(primary_user); -} - bool ShouldUseBuiltinCertVerifier(Profile* profile) { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(chromeos::switches::kForceCertVerifierBuiltin)) @@ -115,41 +104,12 @@ return true; } - // TODO(https://crbug.com/982936): Instead of evaluating the primary profile - // prefs explicitly, register the pref with LocalState and evaluate the pref - // there. Note that currently that is not possible because the LocalState - // prefs may not reflect the primary profile policy state at the time this - // function is executed. - - // Explicitly check if |profile| is the primary profile. GetPrimaryProfile - // only returns non-null pretty late in the primary profile initialization - // stage, and the NetworkContext is created before that. - Profile* primary_profile = nullptr; - if (chromeos::ProfileHelper::Get()->IsPrimaryProfile(profile)) - primary_profile = profile; - - if (!primary_profile) - primary_profile = GetPrimaryProfile(); - if (!primary_profile) { - NOTREACHED(); - return base::FeatureList::IsEnabled( - net::features::kCertVerifierBuiltinFeature); - } - - // The policy evaluated through the pref is not updatable dynamically, so - // assert that the pref system is already initialized at the time this is - // called. - DCHECK_NE(PrefService::INITIALIZATION_STATUS_WAITING, - primary_profile->GetPrefs()->GetInitializationStatus()); const PrefService::Preference* builtin_cert_verifier_enabled_pref = - primary_profile->GetPrefs()->FindPreference( + g_browser_process->local_state()->FindPreference( prefs::kBuiltinCertificateVerifierEnabled); if (builtin_cert_verifier_enabled_pref->IsManaged()) return builtin_cert_verifier_enabled_pref->GetValue()->GetBool(); - // TODO(https://crbug.com/939344): Also evaluate whether there are - // extension-specific certificates to be used, and if yes, enable the built-in - // cert verifier. return base::FeatureList::IsEnabled( net::features::kCertVerifierBuiltinFeature); } @@ -274,18 +234,18 @@ void ProfileNetworkContextService::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { registry->RegisterBooleanPref(prefs::kQuicAllowed, true); -#if defined(OS_CHROMEOS) - // Note that the default value is not relevant because the pref is only - // evaluated when it is managed. - registry->RegisterBooleanPref(prefs::kBuiltinCertificateVerifierEnabled, - false); -#endif } // static void ProfileNetworkContextService::RegisterLocalStatePrefs( PrefRegistrySimple* registry) { registry->RegisterListPref(prefs::kHSTSPolicyBypassList); +#if defined(OS_CHROMEOS) + // Note that the default value is not relevant because the pref is only + // evaluated when it is managed. + registry->RegisterBooleanPref(prefs::kBuiltinCertificateVerifierEnabled, + false); +#endif } void ProfileNetworkContextService::DisableQuicIfNotAllowed() {
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 6ce972a..2804343 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -300,9 +300,12 @@ "var oldSendScriptingMessage = " " PDFViewer.prototype.sendScriptingMessage_;" "PDFViewer.prototype.sendScriptingMessage_ = function(message) {" - " oldSendScriptingMessage.bind(this)(message);" - " if (message.type == 'getSelectedTextReply')" - " this.parentWindow_.postMessage('flush', '*');" + " try {" + " oldSendScriptingMessage.bind(this)(message);" + " } finally {" + " if (message.type == 'getSelectedTextReply')" + " this.parentWindow_.postMessage('flush', '*');" + " }" "}")); // Add an event listener for flush messages and request the selected text. @@ -756,6 +759,12 @@ true); } +// TODO(crbug.com/1004425): Should be allowed? +IN_PROC_BROWSER_TEST_F(PDFExtensionTest, EnsureOpaqueOriginRepliesBlocked) { + TestGetSelectedTextReply( + embedded_test_server()->GetURL("/pdf/data_url_rectangles.html"), false); +} + // Ensure that the PDF component extension cannot be loaded directly. IN_PROC_BROWSER_TEST_F(PDFExtensionTest, BlockDirectAccess) { WebContents* web_contents = GetActiveWebContents();
diff --git a/chrome/browser/resources/local_ntp/customize.js b/chrome/browser/resources/local_ntp/customize.js index 6d530d04..c5ccf952 100644 --- a/chrome/browser/resources/local_ntp/customize.js +++ b/chrome/browser/resources/local_ntp/customize.js
@@ -1520,7 +1520,6 @@ customize.init = function(showErrorNotification, hideCustomLinkNotification) { ntpApiHandle = window.chrome.embeddedSearch.newTabPage; const editDialog = $(customize.IDS.EDIT_BG_DIALOG); - const menu = $(customize.IDS.MENU); $(customize.IDS.OPTIONS_TITLE).textContent = configData.translatedStrings.customizeThisPage; @@ -1555,6 +1554,8 @@ } }; $(customize.IDS.EDIT_BG).onclick = function(event) { + $(customize.IDS.CUSTOMIZATION_MENU) + .classList.add(customize.CLASSES.MOUSE_NAV); editDialog.classList.add(customize.CLASSES.MOUSE_NAV); editBackgroundInteraction(); };
diff --git a/chrome/browser/resources/local_ntp/local_ntp.css b/chrome/browser/resources/local_ntp/local_ntp.css index cf1641a..ef4c5ba 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.css +++ b/chrome/browser/resources/local_ntp/local_ntp.css
@@ -754,7 +754,13 @@ font-size: 12px; line-height: 32px; margin-bottom: 0; - max-width: 505px; + /* TODO(crbug.com/969062): this magic constant would be better implemented as + * real multi-line promo text support or a better QA process to check that + * promo messages aren't ellided. It's ultimately quite hard to make any pixel + * value here useful as font face, sizes, and zoom can all vary. Pushing for + * a more dynamic UI or better qualification process has been met with + * significant resistance, so we keep arbitrarily changing this value. */ + max-width: 537px; overflow: hidden; padding: 0 16px; pointer-events: all; @@ -1085,6 +1091,7 @@ } } +#customization-menu.using-mouse-nav, .using-mouse-nav .bg-sel-tile:focus { outline: none; }
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.html b/chrome/browser/resources/settings/a11y_page/a11y_page.html index 74d602e6..078fc8f 100644 --- a/chrome/browser/resources/settings/a11y_page/a11y_page.html +++ b/chrome/browser/resources/settings/a11y_page/a11y_page.html
@@ -19,43 +19,24 @@ <dom-module id="settings-a11y-page"> <template> <style include="settings-shared"></style> - <template is="dom-if" if="[[showCaptionSettings_]]"> - <cr-link-row class="hr" id="captions" label="$i18n{captionsTitle}" - on-click="onCaptionsClick_"> - </cr-link-row> - </template> <settings-animated-pages id="pages" current-route="{{currentRoute}}" section="a11y" focus-config="[[focusConfig_]]"> -<if expr="not chromeos"> <div route-path="default"> - <settings-toggle-button - id="a11yImageLabels" - hidden$="[[!showAccessibilityLabelsSetting_]]" - pref="{{prefs.settings.a11y.enable_accessibility_image_labels}}" - on-change="onToggleAccessibilityImageLabels_" - label="$i18n{accessibleImageLabelsTitle}" - sub-label="$i18n{accessibleImageLabelsSubtitle}"> - </settings-toggle-button> - <cr-link-row class="hr" label="$i18n{moreFeaturesLink}" - on-click="onMoreFeaturesLinkClick_" sub-label="$i18n{a11yWebStore}" - external> - </cr-link-row> - </div> -</if> -<if expr="chromeos or is_linux or is_win"> - <template is="dom-if" if="[[showCaptionSettings_]]"> - <template is="dom-if" route-path="/captions"> - <settings-subpage - associated-control="[[$$('#captions')]]" - page-title="$i18n{captionsTitle}"> - <settings-captions prefs="{{prefs}}"></settings-captions> - </settings-subpage> - </template> - </template> + <cr-link-row class="hr" id="captions" label="$i18n{captionsTitle}" + on-click="onCaptionsClick_" external$="[[captionSettingsOpensExternally_]]"> + </cr-link-row> +<if expr="not chromeos"> + <settings-toggle-button + id="a11yImageLabels" + hidden$="[[!showAccessibilityLabelsSetting_]]" + pref="{{prefs.settings.a11y.enable_accessibility_image_labels}}" + on-change="onToggleAccessibilityImageLabels_" + label="$i18n{accessibleImageLabelsTitle}" + sub-label="$i18n{accessibleImageLabelsSubtitle}"> + </settings-toggle-button> </if> <if expr="chromeos"> - <template is="dom-if" if="[[pageVisibility.webstoreLink]]"> - <div route-path="default"> + <template is="dom-if" if="[[pageVisibility.webstoreLink]]"> <settings-toggle-button id="a11yImageLabels" hidden$="[[!showAccessibilityLabelsSetting_]]" @@ -73,7 +54,26 @@ on-click="onManageAccessibilityFeaturesTap_" sub-label="$i18n{moreFeaturesLinkDescription}"> </cr-link-row> - </div> + </template> +</if> + <cr-link-row class="hr" label="$i18n{moreFeaturesLink}" + on-click="onMoreFeaturesLinkClick_" sub-label="$i18n{a11yWebStore}" + hidden="[[pageVisibility.webstoreLink]]" external> + </cr-link-row> + </div> +<if expr="not is_macosx"> + <template is="dom-if" if="[[showCaptionSettings_]]"> + <template is="dom-if" route-path="/captions"> + <settings-subpage + associated-control="[[$$('#captions')]]" + page-title="$i18n{captionsTitle}"> + <settings-captions prefs="{{prefs}}"></settings-captions> + </settings-subpage> + </template> + </template> +</if> +<if expr="chromeos"> + <template is="dom-if" if="[[pageVisibility.webstoreLink]]"> <template is="dom-if" route-path="/manageAccessibility"> <settings-subpage associated-control="[[$$('#subpage-trigger')]]" @@ -86,8 +86,7 @@ <settings-subpage associated-control="[[$$('#subpage-trigger')]]" page-title="$i18n{manageTtsSettings}"> - <settings-tts-subpage prefs="{{prefs}}"> - </settings-tts-subpage> + <settings-tts-subpage prefs="{{prefs}}"></settings-tts-subpage> </settings-subpage> </template> <template is="dom-if" route-path="/manageAccessibility/switchAccess"> @@ -100,12 +99,6 @@ </template> </if> </settings-animated-pages> -<if expr="chromeos"> - <cr-link-row class="hr" label="$i18n{moreFeaturesLink}" - on-click="onMoreFeaturesLinkClick_" sub-label="$i18n{a11yWebStore}" - hidden="[[pageVisibility.webstoreLink]]" external> - </cr-link-row> -</if> </template> <script src="a11y_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.js b/chrome/browser/resources/settings/a11y_page/a11y_page.js index 6629ff7..3104568 100644 --- a/chrome/browser/resources/settings/a11y_page/a11y_page.js +++ b/chrome/browser/resources/settings/a11y_page/a11y_page.js
@@ -67,6 +67,26 @@ }, }, + /** + * Whether the caption settings link opens externally. + * @private {boolean} + */ + captionSettingsOpensExternally_: { + type: Boolean, + value: function() { + let opensExternally = false; + // <if expr="is_macosx"> + opensExternally = true; + // </if> + + // <if expr="is_win"> + opensExternally = loadTimeData.getBoolean('isWindows10OrNewer'); + // </if> + + return opensExternally; + }, + }, + // <if expr="chromeos"> /** * Whether to show experimental accessibility features.
diff --git a/chrome/browser/resources/settings/search_settings.js b/chrome/browser/resources/settings/search_settings.js index 98d7979..a98f501 100644 --- a/chrome/browser/resources/settings/search_settings.js +++ b/chrome/browser/resources/settings/search_settings.js
@@ -153,7 +153,7 @@ parent = parent.nodeType == Node.DOCUMENT_FRAGMENT_NODE ? parent.host : parent.parentNode; - if (parent.nodeName == 'SETTINGS-SUBPAGE') { + if (parent && parent.nodeName == 'SETTINGS-SUBPAGE') { // TODO(dpapad): Cast to SettingsSubpageElement here. associatedControl = assert( parent.associatedControl,
diff --git a/chrome/browser/ui/android/widget/BUILD.gn b/chrome/browser/ui/android/widget/BUILD.gn index d9997707..da3befb 100644 --- a/chrome/browser/ui/android/widget/BUILD.gn +++ b/chrome/browser/ui/android/widget/BUILD.gn
@@ -15,6 +15,16 @@ "java/src/org/chromium/chrome/browser/ui/widget/FadingEdgeScrollView.java", "java/src/org/chromium/chrome/browser/ui/widget/ListMenuButton.java", "java/src/org/chromium/chrome/browser/ui/widget/LoadingView.java", + "java/src/org/chromium/chrome/browser/ui/widget/TintedDrawable.java", + "java/src/org/chromium/chrome/browser/ui/widget/animation/AnimatorProperties.java", + "java/src/org/chromium/chrome/browser/ui/widget/animation/CancelAwareAnimatorListener.java", + "java/src/org/chromium/chrome/browser/ui/widget/animation/FocusAnimator.java", + "java/src/org/chromium/chrome/browser/ui/widget/displaystyle/DisplayStyleObserver.java", + "java/src/org/chromium/chrome/browser/ui/widget/displaystyle/DisplayStyleObserverAdapter.java", + "java/src/org/chromium/chrome/browser/ui/widget/displaystyle/HorizontalDisplayStyle.java", + "java/src/org/chromium/chrome/browser/ui/widget/displaystyle/UiConfig.java", + "java/src/org/chromium/chrome/browser/ui/widget/displaystyle/VerticalDisplayStyle.java", + "java/src/org/chromium/chrome/browser/ui/widget/displaystyle/ViewResizer.java", "java/src/org/chromium/chrome/browser/ui/widget/text/AccessibleTextView.java", "java/src/org/chromium/chrome/browser/ui/widget/text/AlertDialogEditText.java", "java/src/org/chromium/chrome/browser/ui/widget/text/TextViewWithCompoundDrawables.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/TintedDrawable.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/TintedDrawable.java similarity index 96% rename from chrome/android/java/src/org/chromium/chrome/browser/widget/TintedDrawable.java rename to chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/TintedDrawable.java index fb60e32f..16d811e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/TintedDrawable.java +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/TintedDrawable.java
@@ -2,7 +2,7 @@ // 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.widget; +package org.chromium.chrome.browser.ui.widget; import android.content.Context; import android.content.res.ColorStateList; @@ -12,8 +12,6 @@ import android.graphics.drawable.BitmapDrawable; import android.support.v7.content.res.AppCompatResources; -import org.chromium.chrome.R; - /** * Implementation of BitmapDrawable that allows to tint the color of the drawable for all * bitmap drawable states.
diff --git a/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/animation/AnimatorProperties.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/animation/AnimatorProperties.java new file mode 100644 index 0000000..33ef12b --- /dev/null +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/animation/AnimatorProperties.java
@@ -0,0 +1,29 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.ui.widget.animation; + +import android.graphics.drawable.Drawable; +import android.util.Property; + +/** + * Holds different {@link Property} types that can be used with ObjectAnimators. + */ +public class AnimatorProperties { + public static final Property<Drawable, Integer> DRAWABLE_ALPHA_PROPERTY = + new Property<Drawable, Integer>(Integer.class, "alpha") { + @Override + public Integer get(Drawable d) { + // getAlpha() is only exposed on drawable in API 19+, so we rely on animations + // always setting the starting and ending values instead of relying on this + // property. + return 0; + } + + @Override + public void set(Drawable d, Integer alpha) { + d.setAlpha(alpha); + } + }; +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/animation/CancelAwareAnimatorListener.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/animation/CancelAwareAnimatorListener.java similarity index 89% rename from chrome/android/java/src/org/chromium/chrome/browser/widget/animation/CancelAwareAnimatorListener.java rename to chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/animation/CancelAwareAnimatorListener.java index 76ef1171..d8039dda 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/animation/CancelAwareAnimatorListener.java +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/animation/CancelAwareAnimatorListener.java
@@ -2,7 +2,7 @@ // 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.widget.animation; +package org.chromium.chrome.browser.ui.widget.animation; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -41,16 +41,16 @@ /** * Notifies the start of the animator. */ - public void onStart(Animator animator) { } + public void onStart(Animator animator) {} /** * Notifies that the animator was cancelled. */ - public void onCancel(Animator animator) { } + public void onCancel(Animator animator) {} /** * Notifies that the animator has finished running. This method will not be called if the * animator is canclled. */ - public void onEnd(Animator animator) { } + public void onEnd(Animator animator) {} }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/animation/FocusAnimator.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/animation/FocusAnimator.java similarity index 98% rename from chrome/android/java/src/org/chromium/chrome/browser/widget/animation/FocusAnimator.java rename to chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/animation/FocusAnimator.java index deb5b17..27b4a1de 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/animation/FocusAnimator.java +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/animation/FocusAnimator.java
@@ -2,7 +2,7 @@ // 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.widget.animation; +package org.chromium.chrome.browser.ui.widget.animation; import android.animation.Animator; import android.animation.AnimatorListenerAdapter;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/DisplayStyleObserver.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/DisplayStyleObserver.java similarity index 74% rename from chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/DisplayStyleObserver.java rename to chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/DisplayStyleObserver.java index a58b93633..6fdaa91 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/DisplayStyleObserver.java +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/DisplayStyleObserver.java
@@ -2,14 +2,14 @@ // 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.widget.displaystyle; +package org.chromium.chrome.browser.ui.widget.displaystyle; /** * Gets notified of changes in the display style. * * @see UiConfig.DisplayStyle * @see UiConfig#getCurrentDisplayStyle() - * @see org.chromium.chrome.browser.widget.displaystyle.DisplayStyleObserverAdapter + * @see DisplayStyleObserverAdapter */ public interface DisplayStyleObserver { void onDisplayStyleChanged(UiConfig.DisplayStyle newDisplayStyle);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/DisplayStyleObserverAdapter.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/DisplayStyleObserverAdapter.java similarity index 97% rename from chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/DisplayStyleObserverAdapter.java rename to chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/DisplayStyleObserverAdapter.java index 343bf3db..1ea95501 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/DisplayStyleObserverAdapter.java +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/DisplayStyleObserverAdapter.java
@@ -2,7 +2,7 @@ // 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.widget.displaystyle; +package org.chromium.chrome.browser.ui.widget.displaystyle; import android.view.View;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/HorizontalDisplayStyle.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/HorizontalDisplayStyle.java similarity index 90% rename from chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/HorizontalDisplayStyle.java rename to chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/HorizontalDisplayStyle.java index 57e1acc..a0c45cd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/HorizontalDisplayStyle.java +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/HorizontalDisplayStyle.java
@@ -2,7 +2,7 @@ // 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.widget.displaystyle; +package org.chromium.chrome.browser.ui.widget.displaystyle; import androidx.annotation.IntDef;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/OWNERS b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/OWNERS similarity index 100% rename from chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/OWNERS rename to chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/OWNERS
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/UiConfig.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/UiConfig.java similarity index 98% rename from chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/UiConfig.java rename to chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/UiConfig.java index 834e485..b524c8c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/UiConfig.java +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/UiConfig.java
@@ -2,7 +2,7 @@ // 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.widget.displaystyle; +package org.chromium.chrome.browser.ui.widget.displaystyle; import android.content.Context; import android.view.View;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/VerticalDisplayStyle.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/VerticalDisplayStyle.java similarity index 89% rename from chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/VerticalDisplayStyle.java rename to chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/VerticalDisplayStyle.java index 32db1266..645998b0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/VerticalDisplayStyle.java +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/VerticalDisplayStyle.java
@@ -2,7 +2,7 @@ // 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.widget.displaystyle; +package org.chromium.chrome.browser.ui.widget.displaystyle; import androidx.annotation.IntDef;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/ViewResizer.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/ViewResizer.java similarity index 98% rename from chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/ViewResizer.java rename to chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/ViewResizer.java index 749d3e44..77f25ce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/ViewResizer.java +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/displaystyle/ViewResizer.java
@@ -2,7 +2,7 @@ // 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.widget.displaystyle; +package org.chromium.chrome.browser.ui.widget.displaystyle; import android.content.res.Resources; import android.support.v4.view.ViewCompat;
diff --git a/chrome/browser/ui/app_list/search/mixer.cc b/chrome/browser/ui/app_list/search/mixer.cc index e15bf9f..011e089b 100644 --- a/chrome/browser/ui/app_list/search/mixer.cc +++ b/chrome/browser/ui/app_list/search/mixer.cc
@@ -29,7 +29,14 @@ : result(result), score(score) {} bool Mixer::SortData::operator<(const SortData& other) const { - // This data precedes (less than) |other| if it has higher score. + // This data precedes (less than) |other| if it has specified display index or + // higher score. + ash::SearchResultDisplayIndex index1 = result->display_index(); + ash::SearchResultDisplayIndex index2 = other.result->display_index(); + // The |kUndefined| index is larger than other specified indexes. + if (index1 != index2) + return index1 < index2; + return score > other.score; }
diff --git a/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc b/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc index 8a3e04bd..01df87f 100644 --- a/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc +++ b/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc
@@ -77,6 +77,7 @@ count_(0), bad_relevance_range_(false), small_relevance_range_(false), + last_result_has_display_index_(false), display_type_(ash::SearchResultDisplayType::kList), result_type_(result_type) {} ~TestSearchProvider() override {} @@ -99,6 +100,10 @@ TestSearchResult* result = new TestSearchResult(id, relevance); result->SetDisplayType(display_type_); result->SetResultType(result_type_); + + if (last_result_has_display_index_ && i == count_ - 1) + result->SetDisplayIndex(ash::SearchResultDisplayIndex::kFirstIndex); + Add(std::unique_ptr<ChromeSearchResult>(result)); } } @@ -110,12 +115,16 @@ void set_count(size_t count) { count_ = count; } void set_bad_relevance_range() { bad_relevance_range_ = true; } void set_small_relevance_range() { small_relevance_range_ = true; } + void set_last_result_has_display_index() { + last_result_has_display_index_ = true; + } private: std::string prefix_; size_t count_; bool bad_relevance_range_; bool small_relevance_range_; + bool last_result_has_display_index_; ChromeSearchResult::DisplayType display_type_; ResultType result_type_; @@ -237,8 +246,7 @@ {2, 10, 2, "app0,omnibox0,app1,omnibox1,omnibox2,omnibox3,playstore0,playstore1"}, {2, 0, 2, "app0,app1,playstore0,playstore1"}, - {0, 0, 0, ""}, - }; + {0, 0, 0, ""}}; for (size_t i = 0; i < base::size(kTestCases); ++i) { app_provider()->set_count(kTestCases[i].app_results); @@ -250,6 +258,34 @@ } } +// Tests that results with display index defined, will be shown in the final +// results. +TEST_F(MixerTest, ResultsWithDisplayIndex) { + CreateMixer(); + + // If the last result has no display index defined, it will not shown in the + // final results. + app_provider()->set_count(6); + omnibox_provider()->set_count(6); + playstore_provider()->set_count(6); + RunQuery(); + + EXPECT_EQ( + "app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3,playstore0," + "playstore1", + GetResults()); + + // If the last result has display index defined, it will be in the final + // results. + app_provider()->set_last_result_has_display_index(); + RunQuery(); + + EXPECT_EQ( + "app5,app0,omnibox0,app1,omnibox1,app2,omnibox2,omnibox3,playstore0," + "playstore1", + GetResults()); +} + TEST_F(MixerTest, RemoveDuplicates) { CreateMixer();
diff --git a/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc b/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc index 0f276415..399b8e4 100644 --- a/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc +++ b/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc
@@ -146,7 +146,7 @@ waiter.Wait(); } -IN_PROC_BROWSER_TEST_P(ScreenRotationTest, RotateInTableOverview) { +IN_PROC_BROWSER_TEST_P(ScreenRotationTest, RotateInTabletOverview) { // Browser window is used just to identify display. BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); gfx::NativeWindow browser_window = @@ -176,8 +176,8 @@ waiter.Wait(); } -// TODO(oshma): Support split screen in tablet mode. -// TODO(oshma): Support overview mode. +// TODO(oshima): Support split screen in tablet mode. +// TODO(oshima): Support overview mode. INSTANTIATE_TEST_SUITE_P(, ScreenRotationTest,
diff --git a/chrome/browser/ui/tabs/tab_utils.cc b/chrome/browser/ui/tabs/tab_utils.cc index e34276d9..a4aee330 100644 --- a/chrome/browser/ui/tabs/tab_utils.cc +++ b/chrome/browser/ui/tabs/tab_utils.cc
@@ -15,9 +15,11 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/usb/usb_tab_helper.h" #include "chrome/browser/vr/vr_tab_helper.h" +#include "chrome/grit/generated_resources.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "content/public/common/content_features.h" #include "content/public/common/url_constants.h" +#include "ui/base/l10n/l10n_util.h" namespace chrome { @@ -77,6 +79,44 @@ return TabAlertState::NONE; } +base::string16 GetTabAlertStateText(const TabAlertState alert_state) { + switch (alert_state) { + case TabAlertState::AUDIO_PLAYING: + return l10n_util::GetStringUTF16( + IDS_TOOLTIP_TAB_ALERT_STATE_AUDIO_PLAYING); + case TabAlertState::AUDIO_MUTING: + return l10n_util::GetStringUTF16( + IDS_TOOLTIP_TAB_ALERT_STATE_AUDIO_MUTING); + case TabAlertState::MEDIA_RECORDING: + return l10n_util::GetStringUTF16( + IDS_TOOLTIP_TAB_ALERT_STATE_MEDIA_RECORDING); + case TabAlertState::TAB_CAPTURING: + return l10n_util::GetStringUTF16( + IDS_TOOLTIP_TAB_ALERT_STATE_TAB_CAPTURING); + case TabAlertState::BLUETOOTH_CONNECTED: + return l10n_util::GetStringUTF16( + IDS_TOOLTIP_TAB_ALERT_STATE_BLUETOOTH_CONNECTED); + case TabAlertState::USB_CONNECTED: + return l10n_util::GetStringUTF16( + IDS_TOOLTIP_TAB_ALERT_STATE_USB_CONNECTED); + case TabAlertState::SERIAL_CONNECTED: + return l10n_util::GetStringUTF16( + IDS_TOOLTIP_TAB_ALERT_STATE_SERIAL_CONNECTED); + case TabAlertState::PIP_PLAYING: + return l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_ALERT_STATE_PIP_PLAYING); + case TabAlertState::DESKTOP_CAPTURING: + return l10n_util::GetStringUTF16( + IDS_TOOLTIP_TAB_ALERT_STATE_DESKTOP_CAPTURING); + case TabAlertState::VR_PRESENTING_IN_HEADSET: + return l10n_util::GetStringUTF16( + IDS_TOOLTIP_TAB_ALERT_STATE_VR_PRESENTING); + case TabAlertState::NONE: + return base::string16(); + } + NOTREACHED(); + return base::string16(); +} + bool CanToggleAudioMute(content::WebContents* contents) { switch (chrome::GetTabAlertStateForContents(contents)) { case TabAlertState::NONE:
diff --git a/chrome/browser/ui/tabs/tab_utils.h b/chrome/browser/ui/tabs/tab_utils.h index e9ff577..c4316dd 100644 --- a/chrome/browser/ui/tabs/tab_utils.h +++ b/chrome/browser/ui/tabs/tab_utils.h
@@ -61,6 +61,9 @@ // relevant to user privacy concerns is selected. TabAlertState GetTabAlertStateForContents(content::WebContents* contents); +// Returns a localized string describing the |alert_state|. +base::string16 GetTabAlertStateText(const TabAlertState alert_state); + // Returns true if audio mute can be activated/deactivated for the given // |contents|. bool CanToggleAudioMute(content::WebContents* contents);
diff --git a/chrome/browser/ui/views/passwords/credentials_item_view.cc b/chrome/browser/ui/views/passwords/credentials_item_view.cc index 15201ce..2f7ca7c 100644 --- a/chrome/browser/ui/views/passwords/credentials_item_view.cc +++ b/chrome/browser/ui/views/passwords/credentials_item_view.cc
@@ -62,17 +62,15 @@ const base::string16& lower_text, SkColor hover_color, const autofill::PasswordForm* form, - network::mojom::URLLoaderFactory* loader_factory) - : Button(button_listener), - form_(form), - upper_label_(nullptr), - lower_label_(nullptr), - info_icon_(nullptr), - hover_color_(hover_color) { + network::mojom::URLLoaderFactory* loader_factory, + int upper_text_style, + int lower_text_style) + : Button(button_listener), form_(form), hover_color_(hover_color) { set_notify_enter_exit_on_child(true); // Create an image-view for the avatar. Make sure it ignores events so that // the parent can receive the events instead. - image_view_ = new CircularImageView; + auto image_view = std::make_unique<CircularImageView>(); + image_view_ = image_view.get(); image_view_->set_can_process_events_within_subtree(false); gfx::Image image = ui::ResourceBundle::GetSharedInstance().GetImageNamed( IDR_PROFILE_AVATAR_PLACEHOLDER_LARGE); @@ -85,31 +83,30 @@ form_->icon_url, weak_ptr_factory_.GetWeakPtr()); fetcher->Start(loader_factory); } - AddChildView(image_view_); + AddChildView(std::move(image_view)); // TODO(tapted): Check these (and the STYLE_ values below) against the spec on // http://crbug.com/651681. const int kLabelContext = CONTEXT_BODY_TEXT_SMALL; if (!upper_text.empty()) { - upper_label_ = new views::Label(upper_text, kLabelContext, - views::style::STYLE_PRIMARY); - upper_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); - AddChildView(upper_label_); + auto upper_label = std::make_unique<views::Label>(upper_text, kLabelContext, + upper_text_style); + upper_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + upper_label_ = AddChildView(std::move(upper_label)); } if (!lower_text.empty()) { - lower_label_ = new views::Label(lower_text, kLabelContext, - views::style::STYLE_SECONDARY); - lower_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); - lower_label_->SetMultiLine(true); - AddChildView(lower_label_); + auto lower_label = std::make_unique<views::Label>(lower_text, kLabelContext, + lower_text_style); + lower_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + lower_label->SetMultiLine(true); + lower_label_ = AddChildView(std::move(lower_label)); } if (form_->is_public_suffix_match) { - info_icon_ = new views::TooltipIcon( - base::UTF8ToUTF16(form_->origin.GetOrigin().spec())); - AddChildView(info_icon_); + info_icon_ = AddChildView(std::make_unique<views::TooltipIcon>( + base::UTF8ToUTF16(form_->origin.GetOrigin().spec()))); } if (!upper_text.empty() && !lower_text.empty())
diff --git a/chrome/browser/ui/views/passwords/credentials_item_view.h b/chrome/browser/ui/views/passwords/credentials_item_view.h index b95bc6a..c7dbde1d 100644 --- a/chrome/browser/ui/views/passwords/credentials_item_view.h +++ b/chrome/browser/ui/views/passwords/credentials_item_view.h
@@ -9,6 +9,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/ui/passwords/account_avatar_fetcher.h" #include "ui/views/controls/button/button.h" +#include "ui/views/style/typography.h" namespace autofill { struct PasswordForm; @@ -39,7 +40,9 @@ const base::string16& lower_text, SkColor hover_color, const autofill::PasswordForm* form, - network::mojom::URLLoaderFactory* loader_factory); + network::mojom::URLLoaderFactory* loader_factory, + int upper_text_style = views::style::STYLE_PRIMARY, + int lower_text_style = views::style::STYLE_SECONDARY); ~CredentialsItemView() override; const autofill::PasswordForm* form() const { return form_; } @@ -62,9 +65,9 @@ const autofill::PasswordForm* form_; views::ImageView* image_view_; - views::Label* upper_label_; - views::Label* lower_label_; - views::ImageView* info_icon_; + views::Label* upper_label_ = nullptr; + views::Label* lower_label_ = nullptr; + views::ImageView* info_icon_ = nullptr; SkColor hover_color_;
diff --git a/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc b/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc index 3d915c8..64cb729 100644 --- a/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc +++ b/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/passwords/password_dialog_prompts.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/passwords/credentials_item_view.h" #include "chrome/grit/generated_resources.h" @@ -44,7 +45,8 @@ form.username_value, kButtonHoverColor, &form, content::BrowserContext::GetDefaultStoragePartition(model()->GetProfile()) ->GetURLLoaderFactoryForBrowserProcess() - .get()); + .get(), + STYLE_HINT, views::style::STYLE_PRIMARY); credential->SetEnabled(false); AddChildView(credential);
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index 0d1eaf52..78edbd1d 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -742,6 +742,8 @@ } void Tab::AlertStateChanged() { + if (controller_->HoverCardIsShowingForTab(this)) + controller_->UpdateHoverCard(this); Layout(); } @@ -821,51 +823,7 @@ base::string16 result = title; if (!result.empty()) result.append(1, '\n'); - switch (alert_state) { - case TabAlertState::AUDIO_PLAYING: - result.append( - l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_ALERT_STATE_AUDIO_PLAYING)); - break; - case TabAlertState::AUDIO_MUTING: - result.append( - l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_ALERT_STATE_AUDIO_MUTING)); - break; - case TabAlertState::MEDIA_RECORDING: - result.append(l10n_util::GetStringUTF16( - IDS_TOOLTIP_TAB_ALERT_STATE_MEDIA_RECORDING)); - break; - case TabAlertState::TAB_CAPTURING: - result.append( - l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_ALERT_STATE_TAB_CAPTURING)); - break; - case TabAlertState::BLUETOOTH_CONNECTED: - result.append(l10n_util::GetStringUTF16( - IDS_TOOLTIP_TAB_ALERT_STATE_BLUETOOTH_CONNECTED)); - break; - case TabAlertState::USB_CONNECTED: - result.append( - l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_ALERT_STATE_USB_CONNECTED)); - break; - case TabAlertState::SERIAL_CONNECTED: - result.append(l10n_util::GetStringUTF16( - IDS_TOOLTIP_TAB_ALERT_STATE_SERIAL_CONNECTED)); - break; - case TabAlertState::PIP_PLAYING: - result.append( - l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_ALERT_STATE_PIP_PLAYING)); - break; - case TabAlertState::DESKTOP_CAPTURING: - result.append(l10n_util::GetStringUTF16( - IDS_TOOLTIP_TAB_ALERT_STATE_DESKTOP_CAPTURING)); - break; - case TabAlertState::VR_PRESENTING_IN_HEADSET: - result.append( - l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_ALERT_STATE_VR_PRESENTING)); - break; - case TabAlertState::NONE: - NOTREACHED(); - break; - } + result.append(chrome::GetTabAlertStateText(alert_state)); return result; }
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc index cf1f435..de6448d 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -317,6 +317,13 @@ /* adjust_height_for_width */ true)); AddChildView(title_label_); + alert_state_label_ = new views::Label( + base::string16(), CONTEXT_BODY_TEXT_LARGE, views::style::STYLE_SECONDARY); + alert_state_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); + alert_state_label_->SetMultiLine(false); + alert_state_label_->SetVisible(false); + AddChildView(alert_state_label_); + domain_label_ = new views::Label( base::string16(), CONTEXT_BODY_TEXT_LARGE, views::style::STYLE_SECONDARY, gfx::DirectionalityMode::DIRECTIONALITY_AS_URL); @@ -353,6 +360,9 @@ views::FlexSpecification::ForSizeRule( views::MinimumFlexSizeRule::kScaleToMinimum, views::MaximumFlexSizeRule::kPreferred)); + alert_state_label_->SetProperty(views::kMarginsKey, + gfx::Insets(kLineSpacing, kVerticalMargin, + kLineSpacing, kVerticalMargin)); domain_label_->SetProperty(views::kMarginsKey, gfx::Insets(kLineSpacing, kVerticalMargin, kHorizontalMargin, kVerticalMargin)); @@ -543,6 +553,7 @@ void TabHoverCardBubbleView::UpdateCardContent(const Tab* tab) { base::string16 title; + TabAlertState alert_state; GURL domain_url; // Use committed URL to determine if no page has yet loaded, since the title // can be blank for some web pages. @@ -551,9 +562,11 @@ title = tab->data().IsCrashed() ? l10n_util::GetStringUTF16(IDS_HOVER_CARD_CRASHED_TITLE) : l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE); + alert_state = TabAlertState::NONE; } else { domain_url = tab->data().last_committed_url; title = tab->data().title; + alert_state = tab->data().alert_state; } base::string16 domain; if (domain_url.SchemeIsFile()) { @@ -572,6 +585,14 @@ net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr); } title_label_->SetText(title); + // If there is no alert state do not show the label. + if (alert_state == TabAlertState::NONE) { + alert_state_label_->SetText(base::string16()); + alert_state_label_->SetVisible(false); + } else { + alert_state_label_->SetText(chrome::GetTabAlertStateText(alert_state)); + alert_state_label_->SetVisible(true); + } domain_label_->SetText(domain); // If the preview image feature is not enabled, |preview_image_| will be null.
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h index eaa40d8..e43d4cf 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h
@@ -11,6 +11,7 @@ #include "base/scoped_observer.h" #include "base/time/time.h" #include "base/timer/timer.h" +#include "chrome/browser/ui/tabs/tab_utils.h" #include "chrome/browser/ui/thumbnails/thumbnail_image.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" @@ -72,7 +73,7 @@ void FadeInToShow(); - // Updates and formats title, domain, and preview image. + // Updates and formats title, alert state, domain, and preview image. void UpdateCardContent(const Tab* tab); void RegisterToThumbnailImageUpdates( @@ -107,6 +108,7 @@ views::Widget* widget_ = nullptr; views::Label* title_label_ = nullptr; + views::Label* alert_state_label_ = nullptr; views::Label* domain_label_ = nullptr; views::ImageView* preview_image_ = nullptr;
diff --git a/chrome/browser/ui/webui/devtools_ui_data_source.cc b/chrome/browser/ui/webui/devtools_ui_data_source.cc index c29ccd0..95e73c5 100644 --- a/chrome/browser/ui/webui/devtools_ui_data_source.cc +++ b/chrome/browser/ui/webui/devtools_ui_data_source.cc
@@ -57,9 +57,6 @@ } else if (base::EndsWith(filename, ".js", base::CompareCase::INSENSITIVE_ASCII)) { return "application/javascript"; - } else if (base::EndsWith(filename, ".mjs", - base::CompareCase::INSENSITIVE_ASCII)) { - return "application/javascript"; } else if (base::EndsWith(filename, ".png", base::CompareCase::INSENSITIVE_ASCII)) { return "image/png";
diff --git a/chrome/browser/web_applications/components/BUILD.gn b/chrome/browser/web_applications/components/BUILD.gn index 3c3060d2..2ba3ece 100644 --- a/chrome/browser/web_applications/components/BUILD.gn +++ b/chrome/browser/web_applications/components/BUILD.gn
@@ -37,6 +37,8 @@ "web_app_constants.h", "web_app_data_retriever.cc", "web_app_data_retriever.h", + "web_app_file_extension_registration.h", + "web_app_file_extension_registration_win.cc", "web_app_helpers.cc", "web_app_helpers.h", "web_app_icon_generator.cc", @@ -102,6 +104,7 @@ testonly = true sources = [ + "file_handler_manager_unittest.cc", "pending_app_manager_unittest.cc", "web_app_data_retriever_unittest.cc", "web_app_helpers_unittest.cc",
diff --git a/chrome/browser/web_applications/components/file_handler_manager.cc b/chrome/browser/web_applications/components/file_handler_manager.cc index 5ab054b..c05ac3e 100644 --- a/chrome/browser/web_applications/components/file_handler_manager.cc +++ b/chrome/browser/web_applications/components/file_handler_manager.cc
@@ -4,6 +4,11 @@ #include "chrome/browser/web_applications/components/file_handler_manager.h" +#include "base/feature_list.h" +#include "build/build_config.h" +#include "chrome/browser/web_applications/components/web_app_file_extension_registration.h" +#include "third_party/blink/public/common/features.h" + namespace web_app { FileHandlerManager::FileHandlerManager(Profile* profile) @@ -17,17 +22,39 @@ } void FileHandlerManager::OnWebAppInstalled(const AppId& installed_app_id) { - // TODO(davidbienvenu): Hook up with file association registration code on - // windows. +#if defined(OS_WIN) + if (!base::FeatureList::IsEnabled(blink::features::kFileHandlingAPI)) + return; + std::string app_name = registrar_->GetAppShortName(installed_app_id); + const std::vector<apps::FileHandlerInfo>* file_handlers = + GetFileHandlers(installed_app_id); + if (!file_handlers) + return; + std::set<std::string> file_extensions = + GetFileExtensionsFromFileHandlers(*file_handlers); + RegisterFileHandlersForWebApp(installed_app_id, app_name, *profile_, + file_extensions); +#endif // OS_WIN } void FileHandlerManager::OnWebAppUninstalled(const AppId& installed_app_id) { - // TODO(davidbienvenu): Hook up to file association de-registration code on - // windows. +#if defined(OS_WIN) + UnregisterFileHandlersForWebApp(installed_app_id, *profile_); +#endif // OS_WIN } void FileHandlerManager::OnAppRegistrarDestroyed() { registrar_observer_.RemoveAll(); } +std::set<std::string> GetFileExtensionsFromFileHandlers( + const std::vector<apps::FileHandlerInfo>& file_handlers) { + std::set<std::string> file_extensions; + for (const auto& file_handler : file_handlers) { + for (const auto& file_ext : file_handler.extensions) + file_extensions.insert(file_ext); + } + return file_extensions; +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/components/file_handler_manager.h b/chrome/browser/web_applications/components/file_handler_manager.h index 91a8b22c..a88aee9 100644 --- a/chrome/browser/web_applications/components/file_handler_manager.h +++ b/chrome/browser/web_applications/components/file_handler_manager.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_FILE_HANDLER_MANAGER_H_ #define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_FILE_HANDLER_MANAGER_H_ +#include <set> +#include <string> #include <vector> #include "base/macros.h" @@ -49,6 +51,10 @@ DISALLOW_COPY_AND_ASSIGN(FileHandlerManager); }; +// Compute the set of file extensions specified in |file_handlers|. +std::set<std::string> GetFileExtensionsFromFileHandlers( + const std::vector<apps::FileHandlerInfo>& file_handlers); + } // namespace web_app #endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_FILE_HANDLER_MANAGER_H_
diff --git a/chrome/browser/web_applications/components/file_handler_manager_unittest.cc b/chrome/browser/web_applications/components/file_handler_manager_unittest.cc new file mode 100644 index 0000000..ee368406 --- /dev/null +++ b/chrome/browser/web_applications/components/file_handler_manager_unittest.cc
@@ -0,0 +1,35 @@ +// 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/file_handler_manager.h" + +#include <set> +#include <string> +#include <vector> + +#include "chrome/browser/web_applications/test/test_file_handler_manager.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace web_app { + +TEST(FileHandlerUtilsTest, GetFileExtensionsFromFileHandlers) { + // Construct FileHandlerInfo vector with multiple file extensions. + const std::vector<std::string> test_file_extensions = {"txt", "xls", "doc"}; + apps::FileHandlerInfo fhi1; + apps::FileHandlerInfo fhi2; + fhi1.extensions.insert(test_file_extensions[0]); + fhi1.extensions.insert(test_file_extensions[1]); + fhi2.extensions.insert(test_file_extensions[2]); + std::vector<apps::FileHandlerInfo> file_handlers = {fhi1, fhi2}; + std::set<std::string> file_extensions = + GetFileExtensionsFromFileHandlers(file_handlers); + + EXPECT_EQ(file_extensions.size(), test_file_extensions.size()); + for (const auto& test_file_extension : test_file_extensions) { + EXPECT_TRUE(file_extensions.find(test_file_extension) != + file_extensions.end()); + } +} + +} // namespace web_app
diff --git a/chrome/browser/web_applications/components/web_app_file_extension_registration.h b/chrome/browser/web_applications/components/web_app_file_extension_registration.h new file mode 100644 index 0000000..f214279 --- /dev/null +++ b/chrome/browser/web_applications/components/web_app_file_extension_registration.h
@@ -0,0 +1,33 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_FILE_EXTENSION_REGISTRATION_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_FILE_EXTENSION_REGISTRATION_H_ + +#include <set> +#include <string> + +#include "chrome/browser/web_applications/components/web_app_helpers.h" + +class Profile; + +namespace web_app { + +// Do OS-specific registration to handle opening files with the specified +// |file_extensions| with the PWA with the specified |app_id|. +// This may also involve creating a shim app to launch Chrome from. +void RegisterFileHandlersForWebApp( + const AppId& app_id, + const std::string& app_name, + const Profile& profile, + const std::set<std::string>& file_extensions); + +// Undo the file extensions registration for the PWA with specified |app_id|. +// If a shim app was required, also removes the shim app. +void UnregisterFileHandlersForWebApp(const AppId& app_id, + const Profile& profile); + +} // namespace web_app + +#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_FILE_EXTENSION_REGISTRATION_H_
diff --git a/chrome/browser/web_applications/components/web_app_file_extension_registration_win.cc b/chrome/browser/web_applications/components/web_app_file_extension_registration_win.cc new file mode 100644 index 0000000..82120fd --- /dev/null +++ b/chrome/browser/web_applications/components/web_app_file_extension_registration_win.cc
@@ -0,0 +1,25 @@ +// 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_file_extension_registration.h" + +#include "chrome/browser/profiles/profile.h" + +namespace web_app { + +void RegisterFileHandlersForWebApp( + const AppId& app_id, + const std::string& app_name, + const Profile& profile, + const std::set<std::string>& file_extensions) { + // TODO(davidbienvenu): Setup shim app and windows registry for this |app_id|. +} + +void UnregisterFileHandlersForWebApp(const AppId& app_id, + const Profile& profile) { + // TODO(davidbienvenu): Cleanup windows registry entries for this + // |app_id|. +} + +} // namespace web_app
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/NewTabPageControllerTest.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/NewTabPageControllerTest.java index 15f065f..b13bfdf 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/NewTabPageControllerTest.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/NewTabPageControllerTest.java
@@ -7,6 +7,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; +import android.support.test.filters.LargeTest; import android.support.test.filters.SmallTest; import org.junit.Assert; @@ -56,6 +57,7 @@ assertNotEquals(isHidden, mController.areArticlesHidden()); } + @LargeTest @Test public void testScrollPage() { mController.scrollToTop();
diff --git a/chrome/test/base/browser_tests_main_chromeos.cc b/chrome/test/base/browser_tests_main_chromeos.cc index 5426703..55106b29 100644 --- a/chrome/test/base/browser_tests_main_chromeos.cc +++ b/chrome/test/base/browser_tests_main_chromeos.cc
@@ -30,10 +30,8 @@ public: int RunTestSuite(int argc, char** argv) override { BrowserTestSuiteChromeOS test_suite(argc, argv); - // Browser tests are expected not to tear-down various globals and may - // complete with the thread priority being above NORMAL. + // Browser tests are expected not to tear-down various globals. test_suite.DisableCheckForLeakedGlobals(); - test_suite.DisableCheckForThreadPriorityAtTestEnd(); return test_suite.Run(); } };
diff --git a/chrome/test/base/chrome_test_launcher.cc b/chrome/test/base/chrome_test_launcher.cc index 76fdb406..ad45e43b 100644 --- a/chrome/test/base/chrome_test_launcher.cc +++ b/chrome/test/base/chrome_test_launcher.cc
@@ -76,10 +76,8 @@ int ChromeTestSuiteRunner::RunTestSuite(int argc, char** argv) { ChromeTestSuite test_suite(argc, argv); - // Browser tests are expected not to tear-down various globals and may - // complete with the thread priority being above NORMAL. + // Browser tests are expected not to tear-down various globals. test_suite.DisableCheckForLeakedGlobals(); - test_suite.DisableCheckForThreadPriorityAtTestEnd(); #if defined(OS_ANDROID) // Android browser tests run child processes as threads instead. content::ContentTestSuiteBase::RegisterInProcessThreads();
diff --git a/chrome/test/base/interactive_ui_tests_main.cc b/chrome/test/base/interactive_ui_tests_main.cc index abc8ab2..051d4b3 100644 --- a/chrome/test/base/interactive_ui_tests_main.cc +++ b/chrome/test/base/interactive_ui_tests_main.cc
@@ -41,10 +41,8 @@ protected: // ChromeTestSuite overrides: void Initialize() override { - // Browser tests are expected not to tear-down various globals and may - // complete with the thread priority being above NORMAL. + // Browser tests are expected not to tear-down various globals. base::TestSuite::DisableCheckForLeakedGlobals(); - base::TestSuite::DisableCheckForThreadPriorityAtTestEnd(); ChromeTestSuite::Initialize();
diff --git a/chrome/test/data/pdf/data_url_rectangles.html b/chrome/test/data/pdf/data_url_rectangles.html new file mode 100644 index 0000000..9510906 --- /dev/null +++ b/chrome/test/data/pdf/data_url_rectangles.html
@@ -0,0 +1,16 @@ +<!doctype html> +<meta charset="utf-8"> +<title>data: of //pdf/test/data/rectangles.pdf</title> +<embed type="application/pdf" width="640" height="480" +src="data:application/pdf;base64, +JVBERi0xLjcKJaDypPQKMSAwIG9iaiA8PAogIC9UeXBlIC9DYXRhbG9nCiAgL1BhZ2VzIDIgMCBS +Cj4+CmVuZG9iagoyIDAgb2JqIDw8CiAgL1R5cGUgL1BhZ2VzCiAgL01lZGlhQm94IFsgMCAwIDIw +MCAzMDAgXQogIC9Db3VudCAxCiAgL0tpZHMgWyAzIDAgUiBdCj4+CmVuZG9iagozIDAgb2JqIDw8 +CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAgL0NvbnRlbnRzIDQgMCBSCj4+CmVuZG9i +ago0IDAgb2JqIDw8Cj4+CnN0cmVhbQpxCjAgMCAwIHJnCjAgMjkwIDEwIDEwIHJlIEIqCjEwIDE1 +MCA1MCAzMCByZSBCKgowIDAgMSByZwoxOTAgMjkwIDEwIDEwIHJlIEIqCjcwIDIzMiA1MCAzMCBy +ZSBCKgowIDEgMCByZwoxOTAgMCAxMCAxMCByZSBCKgoxMzAgMTUwIDUwIDMwIHJlIEIqCjEgMCAw +IHJnCjAgMCAxMCAxMCByZSBCKgo3MCA2NyA1MCAzMCByZSBCKgpRCmVuZHN0cmVhbQplbmRvYmoK +eHJlZgowIDUKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDAw +NjggMDAwMDAgbiAKMDAwMDAwMDE2MSAwMDAwMCBuIAowMDAwMDAwMjMwIDAwMDAwIG4gCnRyYWls +ZXI8PCAvUm9vdCAxIDAgUiAvU2l6ZSA1ID4+CnN0YXJ0eHJlZgo0NTYKJSVFT0YK">
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 470d7e29..12f6da1 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -911,7 +911,9 @@ "os": ["chromeos"], "test_policy": { "BuiltinCertificateVerifierEnabled": true }, "pref_mappings": [ - { "pref": "builtin_certificate_verifier_enabled" } + { "pref": "builtin_certificate_verifier_enabled", + "local_state": true + } ] },
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index 0489240..880e0e4d 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -10,17 +10,16 @@ // Polymer BrowserTest fixture. GEN_INCLUDE(['//chrome/test/data/webui/polymer_browser_test_base.js']); +// Only run in release builds because we frequently see test timeouts in debug. +// We suspect this is because the settings page loads slowly in debug. +// https://crbug.com/1003483 +GEN('#if defined(NDEBUG)'); + GEN('#include "ash/public/cpp/ash_features.h"'); GEN('#include "build/branding_buildflags.h"'); GEN('#include "chrome/common/chrome_features.h"'); GEN('#include "chromeos/constants/chromeos_features.h"'); -GEN('#if !defined(NDEBUG)'); -GEN('#define MAYBE_AllJsTests DISABLED_AllJsTests'); -GEN('#else'); -GEN('#define MAYBE_AllJsTests AllJsTests'); -GEN('#endif'); - // Generic test fixture for CrOS Polymer Settings elements to be overridden by // individual element tests. const OSSettingsBrowserTest = class extends PolymerTest { @@ -95,7 +94,7 @@ } }; -TEST_F('OSSettingsAddUsersTest', 'MAYBE_AllJsTests', () => { +TEST_F('OSSettingsAddUsersTest', 'AllJsTests', () => { mocha.run(); }); @@ -111,9 +110,6 @@ } }; -// Times out on debug builders because the Settings page can take several -// seconds to load in a Release build and several times that in a Debug build. -// See https://crbug.com/558434. // Disabled due to flakiness on linux-chromeos-rel. https://crbug.com/992116 TEST_F('OSSettingsAdvancedPageBrowserTest', 'DISABLED_AllJsTests', () => { // Run all registered tests. @@ -192,8 +188,7 @@ } }; -// Flaky in debug. https://crbug.com/1003483 -TEST_F('OSSettingsAppManagementPageTest', 'MAYBE_AllJsTests', () => { +TEST_F('OSSettingsAppManagementPageTest', 'AllJsTests', () => { mocha.run(); }); @@ -260,8 +255,7 @@ } }; -// Flaky in debug. https://crbug.com/1003483 -TEST_F('OSSettingsAppManagementManagedAppTest', 'MAYBE_AllJsTests', () => { +TEST_F('OSSettingsAppManagementManagedAppTest', 'AllJsTests', () => { mocha.run(); }); @@ -548,7 +542,7 @@ } }; -TEST_F('OSSettingsMainTest', 'MAYBE_AllJsTests', () => { +TEST_F('OSSettingsMainTest', 'AllJsTests', () => { mocha.run(); }); @@ -564,7 +558,7 @@ } }; -TEST_F('OSSettingsMenuTest', 'MAYBE_AllJsTests', () => { +TEST_F('OSSettingsMenuTest', 'AllJsTests', () => { mocha.run(); }); @@ -855,8 +849,7 @@ } }; -// Flaky in debug. https://crbug.com/1003483 -TEST_F('OSSettingsPersonalizationPageTest', 'MAYBE_AllJsTests', () => { +TEST_F('OSSettingsPersonalizationPageTest', 'AllJsTests', () => { mocha.run(); }); @@ -1012,8 +1005,7 @@ } }; -// Flaky in debug. https://crbug.com/1003483 -TEST_F('OSSettingsResetPageTest', 'MAYBE_AllJsTests', () => { +TEST_F('OSSettingsResetPageTest', 'AllJsTests', () => { mocha.run(); }); @@ -1035,8 +1027,7 @@ } }; -// Settings tests are flaky on debug. See https://crbug.com/968608. -TEST_F('OSSettingsSearchPageTest', 'MAYBE_AllJsTests', () => { +TEST_F('OSSettingsSearchPageTest', 'AllJsTests', () => { mocha.run(); }); @@ -1058,7 +1049,8 @@ } }; -// Settings tests are flaky on debug. See https://crbug.com/968608. -TEST_F('OSSettingsSmbPageTest', 'MAYBE_AllJsTests', () => { +TEST_F('OSSettingsSmbPageTest', 'AllJsTests', () => { mocha.run(); }); + +GEN('#endif // defined(NDEBUG)');
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_ui_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_ui_browsertest.js index 1326a35d3..10fd8d8 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_ui_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_ui_browsertest.js
@@ -7,6 +7,11 @@ GEN_INCLUDE(['//chrome/test/data/webui/polymer_browser_test_base.js']); +// Only run in release builds because we frequently see test timeouts in debug. +// We suspect this is because the settings page loads slowly in debug. +// https://crbug.com/1003483 +GEN('#if defined(NDEBUG)'); + GEN('#include "chromeos/constants/chromeos_features.h"'); // Test fixture for the top-level OS settings UI. @@ -29,15 +34,7 @@ } }; -// Timeouts in debug because the page can be slow to load. -// https://crbug.com/987512 -GEN('#if !defined(NDEBUG)'); -GEN('#define MAYBE_AllJsTests DISABLED_AllJsTests'); -GEN('#else'); -GEN('#define MAYBE_AllJsTests AllJsTests'); -GEN('#endif'); - -TEST_F('OSSettingsUIBrowserTest', 'MAYBE_AllJsTests', () => { +TEST_F('OSSettingsUIBrowserTest', 'AllJsTests', () => { suite('os-settings-ui', () => { let ui; @@ -223,3 +220,5 @@ mocha.run(); }); + +GEN('#endif // defined(NDEBUG)');
diff --git a/chrome/test/data/webui/settings/search_settings_test.js b/chrome/test/data/webui/settings/search_settings_test.js index 63067ea..971b59b 100644 --- a/chrome/test/data/webui/settings/search_settings_test.js +++ b/chrome/test/data/webui/settings/search_settings_test.js
@@ -249,5 +249,24 @@ }); }); }); + + test('match text outside of a settings section', async function() { + document.body.innerHTML = ` + <div id="mydiv">Match</div> + <settings-section></settings-section>`; + + const section = document.querySelector('settings-section'); + const mydiv = document.querySelector('#mydiv'); + + await searchManager.search('Match', document.body); + assertTrue(section.hiddenBySearch); + + const highlight = mydiv.querySelector('.search-highlight-wrapper'); + assertTrue(!!highlight); + + const searchHits = highlight.querySelectorAll('.search-highlight-hit'); + assertEquals(1, searchHits.length); + assertEquals('Match', searchHits[0].textContent); + }); }); });
diff --git a/chromecast/app/cast_test_launcher.cc b/chromecast/app/cast_test_launcher.cc index e9719c0..34693e3 100644 --- a/chromecast/app/cast_test_launcher.cc +++ b/chromecast/app/cast_test_launcher.cc
@@ -23,10 +23,8 @@ int RunTestSuite(int argc, char** argv) override { base::TestSuite test_suite(argc, argv); - // Browser tests are expected not to tear-down various globals and may - // complete with the thread priority being above NORMAL. + // Browser tests are expected not to tear-down various globals. test_suite.DisableCheckForLeakedGlobals(); - test_suite.DisableCheckForThreadPriorityAtTestEnd(); return test_suite.Run(); }
diff --git a/chromeos/dbus/fake_cicerone_client.cc b/chromeos/dbus/fake_cicerone_client.cc index 0608e6f..456a415b 100644 --- a/chromeos/dbus/fake_cicerone_client.cc +++ b/chromeos/dbus/fake_cicerone_client.cc
@@ -201,30 +201,28 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), start_lxd_container_response_)); - if (request.async()) { - // Trigger CiceroneClient::Observer::NotifyLxdContainerStartingSignal. - vm_tools::cicerone::LxdContainerStartingSignal signal; + + // Trigger CiceroneClient::Observer::NotifyLxdContainerStartingSignal. + vm_tools::cicerone::LxdContainerStartingSignal signal; + signal.set_owner_id(request.owner_id()); + signal.set_vm_name(request.vm_name()); + signal.set_container_name(request.container_name()); + signal.set_status(lxd_container_starting_signal_status_); + signal.mutable_os_release()->CopyFrom(lxd_container_os_release_); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&FakeCiceroneClient::NotifyLxdContainerStarting, + base::Unretained(this), std::move(signal))); + + if (send_container_started_signal_) { + // Trigger CiceroneClient::Observer::NotifyContainerStartedSignal. + vm_tools::cicerone::ContainerStartedSignal signal; signal.set_owner_id(request.owner_id()); signal.set_vm_name(request.vm_name()); signal.set_container_name(request.container_name()); - signal.set_status(lxd_container_starting_signal_status_); - signal.mutable_os_release()->CopyFrom(lxd_container_os_release_); + signal.set_container_username(last_container_username_); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(&FakeCiceroneClient::NotifyLxdContainerStarting, - base::Unretained(this), std::move(signal))); - - if (send_container_started_signal_) { - // Trigger CiceroneClient::Observer::NotifyContainerStartedSignal. - vm_tools::cicerone::ContainerStartedSignal signal; - signal.set_owner_id(request.owner_id()); - signal.set_vm_name(request.vm_name()); - signal.set_container_name(request.container_name()); - signal.set_container_username(last_container_username_); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&FakeCiceroneClient::NotifyContainerStarted, - base::Unretained(this), std::move(signal))); - } + FROM_HERE, base::BindOnce(&FakeCiceroneClient::NotifyContainerStarted, + base::Unretained(this), std::move(signal))); } }
diff --git a/chromeos/profiles/OWNERS b/chromeos/profiles/OWNERS index 0d73e4e..d9a84e7 100644 --- a/chromeos/profiles/OWNERS +++ b/chromeos/profiles/OWNERS
@@ -1 +1,6 @@ -per-file orderfile.newest.txt=* +# Chrome OS Toolchain Team +gbiv@chromium.org +tcwang@chromium.org + +# For skia autoroller to submmit CLs +chromium-autoroll@skia-public.iam.gserviceaccount.com
diff --git a/chromeos/profiles/airmont.afdo.newest.txt b/chromeos/profiles/airmont.afdo.newest.txt new file mode 100644 index 0000000..705bd87 --- /dev/null +++ b/chromeos/profiles/airmont.afdo.newest.txt
@@ -0,0 +1 @@ +chromeos-chrome-amd64-airmont-79-3900.0-1568629889-benchmark-78.0.3902.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/broadwell.afdo.newest.txt b/chromeos/profiles/broadwell.afdo.newest.txt new file mode 100644 index 0000000..97d8aa23 --- /dev/null +++ b/chromeos/profiles/broadwell.afdo.newest.txt
@@ -0,0 +1 @@ +chromeos-chrome-amd64-broadwell-79-3865.63-1568626808-benchmark-78.0.3902.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/silvermont.afdo.newest.txt b/chromeos/profiles/silvermont.afdo.newest.txt new file mode 100644 index 0000000..92d2fcdc --- /dev/null +++ b/chromeos/profiles/silvermont.afdo.newest.txt
@@ -0,0 +1 @@ +chromeos-chrome-amd64-silvermont-79-3903.0-1568628088-benchmark-78.0.3902.0-r1-redacted.afdo.xz
diff --git a/chromeos/services/cros_healthd/public/cpp/service_connection.cc b/chromeos/services/cros_healthd/public/cpp/service_connection.cc index e3fd1d6..bc0b2f23 100644 --- a/chromeos/services/cros_healthd/public/cpp/service_connection.cc +++ b/chromeos/services/cros_healthd/public/cpp/service_connection.cc
@@ -27,9 +27,9 @@ private: // ServiceConnection overrides: - void ProbeNonRemovableBlockDeviceInfo( - mojom::CrosHealthdService::ProbeNonRemovableBlockDeviceInfoCallback - callback) override; + void ProbeTelemetryInfo( + const std::vector<mojom::ProbeCategoryEnum>& categories_to_test, + mojom::CrosHealthdService::ProbeTelemetryInfoCallback callback) override; // Binds the top level interface |cros_healthd_service_| to an // implementation in the cros_healthd daemon, if it is not already bound. The @@ -50,12 +50,13 @@ DISALLOW_COPY_AND_ASSIGN(ServiceConnectionImpl); }; -void ServiceConnectionImpl::ProbeNonRemovableBlockDeviceInfo( - mojom::CrosHealthdService::ProbeNonRemovableBlockDeviceInfoCallback - callback) { +void ServiceConnectionImpl::ProbeTelemetryInfo( + const std::vector<mojom::ProbeCategoryEnum>& categories_to_test, + mojom::CrosHealthdService::ProbeTelemetryInfoCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); BindCrosHealthdServiceIfNeeded(); - cros_healthd_service_->ProbeNonRemovableBlockDeviceInfo(std::move(callback)); + cros_healthd_service_->ProbeTelemetryInfo(categories_to_test, + std::move(callback)); } void ServiceConnectionImpl::BindCrosHealthdServiceIfNeeded() {
diff --git a/chromeos/services/cros_healthd/public/cpp/service_connection.h b/chromeos/services/cros_healthd/public/cpp/service_connection.h index d91f05f..c545d91f 100644 --- a/chromeos/services/cros_healthd/public/cpp/service_connection.h +++ b/chromeos/services/cros_healthd/public/cpp/service_connection.h
@@ -17,10 +17,12 @@ public: static ServiceConnection* GetInstance(); - // Gather various info on non-removeable block devices. - virtual void ProbeNonRemovableBlockDeviceInfo( - mojom::CrosHealthdService::ProbeNonRemovableBlockDeviceInfoCallback - callback) = 0; + // Gather pieces of information about the platform. See + // src/chromeos/service/cros_healthd/public/mojom/cros_healthd.mojom for + // details. + virtual void ProbeTelemetryInfo( + const std::vector<mojom::ProbeCategoryEnum>& categories_to_test, + mojom::CrosHealthdService::ProbeTelemetryInfoCallback callback) = 0; protected: ServiceConnection() = default;
diff --git a/chromeos/services/cros_healthd/public/cpp/service_connection_unittest.cc b/chromeos/services/cros_healthd/public/cpp/service_connection_unittest.cc index ea43f33ea..f644899c 100644 --- a/chromeos/services/cros_healthd/public/cpp/service_connection_unittest.cc +++ b/chromeos/services/cros_healthd/public/cpp/service_connection_unittest.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/macros.h" +#include "base/optional.h" #include "base/run_loop.h" #include "base/test/task_environment.h" #include "chromeos/dbus/cros_healthd/cros_healthd_client.h" @@ -25,7 +26,7 @@ namespace cros_healthd { namespace { -std::vector<mojom::NonRemovableBlockDeviceInfoPtr> +base::Optional<std::vector<mojom::NonRemovableBlockDeviceInfoPtr>> MakeNonRemovableBlockDeviceInfo() { std::vector<mojom::NonRemovableBlockDeviceInfoPtr> info; info.push_back(mojom::NonRemovableBlockDeviceInfo::New( @@ -34,7 +35,28 @@ info.push_back(mojom::NonRemovableBlockDeviceInfo::New( "test_path2", 124 /* size */, "test_type2", 11 /* manfid */, "test_name2", 767 /* serial */)); - return info; + return base::Optional<std::vector<mojom::NonRemovableBlockDeviceInfoPtr>>( + std::move(info)); +} + +mojom::BatteryInfoPtr MakeBatteryInfo() { + return mojom::BatteryInfo::New( + 2 /* cycle_count */, 12.9 /* voltage_now */, + "battery_vendor" /* vendor */, "serial_number" /* serial_number */, + 5.275 /* charge_full_design */, 5.292 /* charge_full */, + 11.55 /* voltage_min_design */, 51785890 /* manufacture_date_smart */); +} + +mojom::CachedVpdInfoPtr MakeCachedVpdInfo() { + return mojom::CachedVpdInfo::New("fake_sku_number" /* sku_number */); +} + +mojom::TelemetryInfoPtr MakeTelemetryInfo() { + return mojom::TelemetryInfo::New( + MakeBatteryInfo() /* battery_info */, + MakeNonRemovableBlockDeviceInfo() /* block_device_info */, + MakeCachedVpdInfo() /* vpd_info */ + ); } class MockCrosHealthdService : public mojom::CrosHealthdService { @@ -43,8 +65,10 @@ return receiver_.BindNewPipeAndPassRemote(); } - MOCK_METHOD1(ProbeNonRemovableBlockDeviceInfo, - void(ProbeNonRemovableBlockDeviceInfoCallback callback)); + MOCK_METHOD2( + ProbeTelemetryInfo, + void(const std::vector<mojom::ProbeCategoryEnum>& categories_to_test, + ProbeTelemetryInfoCallback callback)); private: mojo::Receiver<mojom::CrosHealthdService> receiver_{this}; @@ -70,19 +94,22 @@ DISALLOW_COPY_AND_ASSIGN(CrosHealthdServiceConnectionTest); }; -TEST_F(CrosHealthdServiceConnectionTest, ProbeNonRemovableBlockDeviceInfo) { - EXPECT_CALL(*mock_service(), ProbeNonRemovableBlockDeviceInfo(_)) - .WillOnce(WithArgs<0>(Invoke( - [](mojom::CrosHealthdService::ProbeNonRemovableBlockDeviceInfoCallback - callback) { - std::move(callback).Run(MakeNonRemovableBlockDeviceInfo()); +TEST_F(CrosHealthdServiceConnectionTest, ProbeTelemetryInfo) { + EXPECT_CALL(*mock_service(), ProbeTelemetryInfo(_, _)) + .WillOnce(WithArgs<1>(Invoke( + [](mojom::CrosHealthdService::ProbeTelemetryInfoCallback callback) { + std::move(callback).Run(MakeTelemetryInfo()); }))); + const std::vector<mojom::ProbeCategoryEnum> categories_to_test = { + mojom::ProbeCategoryEnum::kBattery, + mojom::ProbeCategoryEnum::kNonRemovableBlockDevices, + mojom::ProbeCategoryEnum::kCachedVpdData}; bool callback_done = false; - ServiceConnection::GetInstance()->ProbeNonRemovableBlockDeviceInfo( + ServiceConnection::GetInstance()->ProbeTelemetryInfo( + categories_to_test, base::BindOnce( - [](bool* callback_done, - std::vector<mojom::NonRemovableBlockDeviceInfoPtr> info) { - EXPECT_EQ(info, MakeNonRemovableBlockDeviceInfo()); + [](bool* callback_done, mojom::TelemetryInfoPtr info) { + EXPECT_EQ(info, MakeTelemetryInfo()); *callback_done = true; }, &callback_done));
diff --git a/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom b/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom index d98cbe9..3d1e10b5 100644 --- a/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom +++ b/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom
@@ -16,10 +16,26 @@ interface CrosHealthdService { // ------------------- Start of probe definitions --------------------- - // Returns an array of all non-removable block devices and associated - // up-to-date info. - ProbeNonRemovableBlockDeviceInfo() - => (array<NonRemovableBlockDeviceInfo> devices); + // Returns telemetry information for the desired categories. This IPC is + // exposed so that the browser can pull data from cros_healthd. The browser + // will periodically call ProbeTelemetryInfo and upload the results to the EMM + // API in the cloud, where the data collected from cros_healthd will be made + // available to OEMs. Since the browser is making requests and cros_healthd is + // replying, we can consider cros_healthd the privileged side of this + // communication. ProbeTelemetryInfo only returns parsed data, so the browser + // will not do any parsing. cros_healthd does not process input that could be + // controlled by a malicious attacker. + // + // The request: + // * |categories| - list of each of the categories that ProbeTelemetryInfo + // should return information for. + // + // The response: + // * |telemetry_info| - information for each of the requested categories. Only + // the fields corresponding to the requested categories + // will be non-null. + ProbeTelemetryInfo(array<ProbeCategoryEnum> categories) + => (TelemetryInfo telemetry_info); // ------------------- End of probe definitions ----------------------- };
diff --git a/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom b/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom index 41dee83..f28c1a5f 100644 --- a/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom +++ b/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom
@@ -10,6 +10,37 @@ module chromeos.cros_healthd.mojom; +// An enumeration of each category of information that cros_healthd can report. +[Extensible] +enum ProbeCategoryEnum { + kBattery, + kNonRemovableBlockDevices, + kCachedVpdData, +}; + +// Information related to the main battery. +struct BatteryInfo { + // TODO(https://crbug.com/979245): Update "smart" cycle count. + int64 cycle_count; + // Current battery voltage (V) + double voltage_now; + // Manufacturer of the battery + string vendor; + // Serial number of the battery + string serial_number; + // Design capacity (Ah) + double charge_full_design; + // Full capacity (Ah) + double charge_full; + // Desired minimum output voltage (V) + double voltage_min_design; + // Smart Manufacture Date is defined in + // http://sbs-forum.org/specs/sbdat110.pdf. The value is calculated by + // ((year-1980) * 512 + month * 32 + day). + int64 manufacture_date_smart; +}; + +// Information related to a specific non-removable block device. struct NonRemovableBlockDeviceInfo { // The path of this storage on the system. It is useful if caller needs to // correlate with other information. @@ -25,3 +56,27 @@ // PSN: Product serial number, 32 bits uint32 serial; }; + +// Cached VPD read from sysfs. +struct CachedVpdInfo { + // Contents of /sys/firmware/vpd/ro/sku_number. + string sku_number; +}; + +// A collection of all the device's telemetry information that cros_healthd is +// capable of reporting. Note that every field in TelemetryInfo is nullable, and +// the response for a particular ProbeTelemetryInfo request will only contain +// fields corresponding to the categories passed to the ProbeTelemetryInfo +// request. +struct TelemetryInfo { + // Information about the device's main battery. Only present when kBattery was + // included in the categories input to ProbeTelemetryInfo. + BatteryInfo? battery_info; + // Information about all of the device's non-removable block devices. Only + // present when kNonRemovableBlockDevices was included in the categories input + // to ProbeTelemetryInfo. + array<NonRemovableBlockDeviceInfo>? block_device_info; + // Only present when kCachedVpdData was included in the categories input to + // ProbeTelemetryInfo. + CachedVpdInfo? vpd_info; +};
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager.cc b/components/autofill/core/browser/payments/credit_card_access_manager.cc index ab11f3c6..4cd28db83 100644 --- a/components/autofill/core/browser/payments/credit_card_access_manager.cc +++ b/components/autofill/core/browser/payments/credit_card_access_manager.cc
@@ -277,7 +277,9 @@ return; #else if (opt_in) { - GetOrCreateFIDOAuthenticator()->Register(std::move(creation_options)); + GetOrCreateFIDOAuthenticator()->Register( + /*card_authorization_token=*/std::string(), + std::move(creation_options)); } else { GetOrCreateFIDOAuthenticator()->OptOut(); } @@ -338,23 +340,43 @@ response.cvc); can_fetch_unmask_details_.Signal(); - if (!response.did_succeed) + if (!response.did_succeed || response.card_authorization_token.empty()) return; #if defined(OS_ANDROID) - // Now that unmask flow is complete, on Android, if GetRealPan includes - // |creation_options|, completely hand over registration flow to - // CreditCardFIDOAuthenticator. + // Opt-in was already offered at this point for Android. + bool should_offer_fido_auth = false; +#elif !defined(OS_IOS) + bool should_offer_fido_auth = unmask_details_.offer_fido_opt_in; +#endif + +#if !defined(OS_IOS) + // Now that unmask flow is complete and form is filled, the remaining flows + // will be completely handed over to CreditCardFIDOAuthenticator. + // If the GetRealPan response includes |creation_options| or + // |request_options|, that means the user showed intention to opt-in while + // unmasking (this can only happen on Android) and must complete the challenge + // before successfully opting-in. If UnmaskDetails contained + // |request_options|, that means the user is already opted-into FIDO auth, and + // this is the first time use of a new card, and must complete the challenge + // to successfully authorize the card. Otherwise, if on desktop and eligible, + // show the dialog that offers opting-in to FIDO authentication in the future. if (response.creation_options.has_value()) { DCHECK(response.creation_options->is_dict()); GetOrCreateFIDOAuthenticator()->Register( - response.creation_options->Clone()); + response.card_authorization_token, response.creation_options->Clone()); + } else if (response.request_options.has_value()) { + DCHECK(response.request_options->is_dict()); + GetOrCreateFIDOAuthenticator()->Authorize( + response.card_authorization_token, response.request_options->Clone()); + } else if (should_offer_fido_auth) { + GetOrCreateFIDOAuthenticator()->ShowWebauthnOfferDialog( + response.card_authorization_token); + } else if (unmask_details_.fido_request_options.is_dict()) { + GetOrCreateFIDOAuthenticator()->Authorize( + response.card_authorization_token, + std::move(unmask_details_.fido_request_options)); } -#elif !defined(OS_IOS) - // CreditCardFIDOAuthenticator does not exist on iOS. - // On desktop, prompts dialog to show the authentication offer. - if (unmask_details_.offer_fido_opt_in) - GetOrCreateFIDOAuthenticator()->ShowWebauthnOfferDialog(); #endif }
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc index 51aa87d..dcd91cf 100644 --- a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
@@ -218,7 +218,8 @@ // Returns true if full card request was sent from CVC auth. bool GetRealPanForCVCAuth(AutofillClient::PaymentsRpcResult result, const std::string& real_pan, - bool fido_opt_in = false) { + bool fido_opt_in = false, + bool follow_with_fido_auth = false) { payments::FullCardRequest* full_card_request = GetCVCAuthenticator()->full_card_request_.get(); @@ -227,9 +228,13 @@ payments::PaymentsClient::UnmaskResponseDetails response; #if !defined(OS_IOS) + response.card_authorization_token = "dummy_card_authorization_token"; if (fido_opt_in) { response.fido_creation_options = GetTestCreationOptions(); } + if (follow_with_fido_auth) { + response.fido_request_options = GetTestRequestOptions(); + } #endif full_card_request->OnDidGetRealPan(result, response.with_real_pan(real_pan)); @@ -298,6 +303,11 @@ GetFIDOAuthenticator()->OnDidGetOptChangeResult(result, response); } + // Mocks user response for the offer dialog. + void AcceptWebauthnOfferDialog(bool did_accept) { + GetFIDOAuthenticator()->OnWebauthnOfferDialogUserResponse(did_accept); + } + TestCreditCardFIDOAuthenticator* GetFIDOAuthenticator() { return static_cast<TestCreditCardFIDOAuthenticator*>( credit_card_access_manager_->GetOrCreateFIDOAuthenticator()); @@ -587,14 +597,10 @@ EXPECT_TRUE(accessor_->did_succeed()); EXPECT_EQ(ASCIIToUTF16(kTestNumber), accessor_->number()); } -#endif -// TODO(crbug.com/991037): Add tests for desktop separately after the -// WebauthnOfferDelegate functions are implemented since the flows are different -// on desktop and Android. #if defined(OS_ANDROID) // Ensures that the WebAuthn enrollment prompt is invoked after user opts in. -TEST_F(CreditCardAccessManagerTest, FIDOEnrollmentSuccess) { +TEST_F(CreditCardAccessManagerTest, FIDOEnrollmentSuccess_Android) { CreateServerCard(kTestGUID, kTestNumber); CreditCard* card = credit_card_access_manager_->GetCreditCard(kTestGUID); GetFIDOAuthenticator()->SetUserVerifiable(true); @@ -663,7 +669,117 @@ EXPECT_FALSE(GetFIDOAuthenticator()->IsUserOptedIn()); } -#endif + +// Ensures that use of new card invokes authorization flow when user is +// opted-in. +TEST_F(CreditCardAccessManagerTest, FIDONewCardAuthorization) { + CreateServerCard(kTestGUID, kTestNumber); + CreditCard* card = credit_card_access_manager_->GetCreditCard(kTestGUID); + // Opt the user in, but don't include the card above. + std::string other_server_id = "00000000-0000-0000-0000-000000000034"; + payments_client_->AddFidoEligibleCard(other_server_id, kCredentialId, + kGooglePaymentsRpid); + GetFIDOAuthenticator()->SetUserVerifiable(true); + SetUserOptedIn(true); + + credit_card_access_manager_->PrepareToFetchCreditCard(); + WaitForCallbacks(); + + credit_card_access_manager_->FetchCreditCard(card, accessor_->GetWeakPtr()); + InvokeUnmaskDetailsTimeout(); + WaitForCallbacks(); + + EXPECT_TRUE(GetRealPanForCVCAuth(AutofillClient::SUCCESS, kTestNumber, + /*fido_opt_in=*/false, + /*follow_with_fido_auth=*/true)); + + // Mock user response and OptChange payments call. + EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::FOLLOWUP_AFTER_CVC_AUTH_FLOW, + GetFIDOAuthenticator()->current_flow()); + TestCreditCardFIDOAuthenticator::GetAssertion(GetFIDOAuthenticator(), + /*did_succeed=*/true); + OptChange(AutofillClient::SUCCESS, true); + + EXPECT_TRUE(GetFIDOAuthenticator()->IsUserOptedIn()); +} +#else // defined(OS_ANDROID) +// Ensures that the WebAuthn enrollment prompt is invoked after user opts in. In +// this case, the user is not yet enrolled server-side, and thus receives +// |creation_options|. +TEST_F(CreditCardAccessManagerTest, + FIDOEnrollmentSuccess_CreationOptions_Desktop) { + CreateServerCard(kTestGUID, kTestNumber); + CreditCard* card = credit_card_access_manager_->GetCreditCard(kTestGUID); + GetFIDOAuthenticator()->SetUserVerifiable(true); + SetUserOptedIn(false); + payments_client_->AllowFidoRegistration(true); + + credit_card_access_manager_->FetchCreditCard(card, accessor_->GetWeakPtr()); + InvokeUnmaskDetailsTimeout(); + WaitForCallbacks(); + + // Mock user and payments response. + AcceptWebauthnOfferDialog(/*did_accept=*/true); + EXPECT_TRUE(GetRealPanForCVCAuth(AutofillClient::SUCCESS, kTestNumber, + /*fido_opt_in=*/false)); + WaitForCallbacks(); + + OptChange(AutofillClient::SUCCESS, /*user_is_opted_in=*/false, + /*include_creation_options=*/true); + + // Mock user response and OptChange payments call. + EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::OPT_IN_WITH_CHALLENGE_FLOW, + GetFIDOAuthenticator()->current_flow()); + TestCreditCardFIDOAuthenticator::MakeCredential(GetFIDOAuthenticator(), + /*did_succeed=*/true); + OptChange(AutofillClient::SUCCESS, /*user_is_opted_in=*/true); + + EXPECT_EQ(kGooglePaymentsRpid, GetFIDOAuthenticator()->GetRelyingPartyId()); + EXPECT_EQ(kTestChallenge, + BytesToBase64(GetFIDOAuthenticator()->GetChallenge())); + EXPECT_TRUE(GetFIDOAuthenticator()->IsUserOptedIn()); +} + +// Ensures that the WebAuthn enrollment prompt is invoked after user opts in. In +// this case, the user is already enrolled server-side, and thus receives +// |request_options|. +TEST_F(CreditCardAccessManagerTest, + FIDOEnrollmentSuccess_RequestOptions_Desktop) { + CreateServerCard(kTestGUID, kTestNumber); + CreditCard* card = credit_card_access_manager_->GetCreditCard(kTestGUID); + GetFIDOAuthenticator()->SetUserVerifiable(true); + SetUserOptedIn(false); + payments_client_->AllowFidoRegistration(true); + + credit_card_access_manager_->FetchCreditCard(card, accessor_->GetWeakPtr()); + InvokeUnmaskDetailsTimeout(); + WaitForCallbacks(); + + // Mock user and payments response. + AcceptWebauthnOfferDialog(/*did_accept=*/true); + EXPECT_TRUE(GetRealPanForCVCAuth(AutofillClient::SUCCESS, kTestNumber, + /*fido_opt_in=*/false)); + WaitForCallbacks(); + + OptChange(AutofillClient::SUCCESS, /*user_is_opted_in=*/false, + /*include_creation_options=*/false, + /*include_request_options=*/true); + + // Mock user response and OptChange payments call. + EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::OPT_IN_WITH_CHALLENGE_FLOW, + GetFIDOAuthenticator()->current_flow()); + TestCreditCardFIDOAuthenticator::GetAssertion(GetFIDOAuthenticator(), + /*did_succeed=*/true); + OptChange(AutofillClient::SUCCESS, /*user_is_opted_in=*/true); + + EXPECT_EQ(kGooglePaymentsRpid, GetFIDOAuthenticator()->GetRelyingPartyId()); + EXPECT_EQ(kTestChallenge, + BytesToBase64(GetFIDOAuthenticator()->GetChallenge())); + EXPECT_TRUE(GetFIDOAuthenticator()->IsUserOptedIn()); +} + +#endif // defined(OS_ANDROID) +#endif // !defined(OS_IOS) // Ensures that |is_authentication_in_progress_| is set correctly. TEST_F(CreditCardAccessManagerTest, AuthenticationInProgress) {
diff --git a/components/autofill/core/browser/payments/credit_card_cvc_authenticator.cc b/components/autofill/core/browser/payments/credit_card_cvc_authenticator.cc index 7a021d8..d8f1cb1 100644 --- a/components/autofill/core/browser/payments/credit_card_cvc_authenticator.cc +++ b/components/autofill/core/browser/payments/credit_card_cvc_authenticator.cc
@@ -41,14 +41,16 @@ const payments::FullCardRequest& full_card_request, const CreditCard& card, const base::string16& cvc) { + payments::PaymentsClient::UnmaskResponseDetails response = + full_card_request.unmask_response_details(); requester_->OnCVCAuthenticationComplete( CVCAuthenticationResponse() .with_did_succeed(true) .with_card(&card) .with_cvc(cvc) - .with_creation_options( - std::move(full_card_request.unmask_response_details() - .fido_creation_options))); + .with_creation_options(std::move(response.fido_creation_options)) + .with_request_options(std::move(response.fido_request_options)) + .with_card_authorization_token(response.card_authorization_token)); } void CreditCardCVCAuthenticator::OnFullCardRequestFailed() {
diff --git a/components/autofill/core/browser/payments/credit_card_cvc_authenticator.h b/components/autofill/core/browser/payments/credit_card_cvc_authenticator.h index f065b6d0..a470eb8 100644 --- a/components/autofill/core/browser/payments/credit_card_cvc_authenticator.h +++ b/components/autofill/core/browser/payments/credit_card_cvc_authenticator.h
@@ -47,11 +47,16 @@ request_options = std::move(v); return *this; } + CVCAuthenticationResponse& with_card_authorization_token(std::string s) { + card_authorization_token = s; + return *this; + } bool did_succeed = false; const CreditCard* card = nullptr; base::string16 cvc = base::string16(); base::Optional<base::Value> creation_options = base::nullopt; base::Optional<base::Value> request_options = base::nullopt; + std::string card_authorization_token = std::string(); }; class Requester { public:
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc index 3f9e7a7..44105f7 100644 --- a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc +++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc
@@ -61,7 +61,9 @@ CreditCardFIDOAuthenticator::~CreditCardFIDOAuthenticator() {} -void CreditCardFIDOAuthenticator::ShowWebauthnOfferDialog() { +void CreditCardFIDOAuthenticator::ShowWebauthnOfferDialog( + std::string card_authorization_token) { + card_authorization_token_ = card_authorization_token; autofill_client_->ShowWebauthnOfferDialog(base::BindRepeating( &CreditCardFIDOAuthenticator::OnWebauthnOfferDialogUserResponse, weak_ptr_factory_.GetWeakPtr())); @@ -84,22 +86,39 @@ } } -void CreditCardFIDOAuthenticator::Register(base::Value creation_options) { +void CreditCardFIDOAuthenticator::Register(std::string card_authorization_token, + base::Value creation_options) { // If |creation_options| is set, then must enroll a new credential. Otherwise // directly send request to payments for opting in. + card_authorization_token_ = card_authorization_token; if (creation_options.is_dict()) { if (IsValidCreationOptions(creation_options)) { current_flow_ = OPT_IN_WITH_CHALLENGE_FLOW; MakeCredential(ParseCreationOptions(creation_options)); } } else { - current_flow_ = OPT_IN_WITHOUT_CHALLENGE_FLOW; + current_flow_ = OPT_IN_FETCH_CHALLENGE_FLOW; OptChange(/*opt_in=*/true); } } +void CreditCardFIDOAuthenticator::Authorize( + std::string card_authorization_token, + base::Value request_options) { + card_authorization_token_ = card_authorization_token; + if (IsValidRequestOptions(request_options)) { + // If user is already opted-in, then a new card is trying to be + // authorized. Otherwise, a user with a credential on file is trying to + // opt-in. + current_flow_ = IsUserOptedIn() ? FOLLOWUP_AFTER_CVC_AUTH_FLOW + : OPT_IN_WITH_CHALLENGE_FLOW; + GetAssertion(ParseRequestOptions(std::move(request_options))); + } +} + void CreditCardFIDOAuthenticator::OptOut() { current_flow_ = OPT_OUT_FLOW; + card_authorization_token_ = std::string(); OptChange(/*opt_in=*/false); } @@ -160,8 +179,21 @@ void CreditCardFIDOAuthenticator::GetAssertion( PublicKeyCredentialRequestOptionsPtr request_options) { - autofill_driver_->ConnectToAuthenticator( - authenticator_.BindNewPipeAndPassReceiver()); + if (!authenticator_.is_bound()) { + autofill_driver_->ConnectToAuthenticator( + authenticator_.BindNewPipeAndPassReceiver()); + } +#if !defined(OS_ANDROID) + // On desktop, during an opt-in flow, close the WebAuthn offer dialog and get + // ready to show the OS level authentication dialog. If dialog is already + // closed, then the offer was declined during the fetching challenge process, + // and thus returned early. + if (current_flow_ == OPT_IN_WITH_CHALLENGE_FLOW && + !autofill_client_->CloseWebauthnOfferDialog()) { + current_flow_ = NONE_FLOW; + return; + } +#endif authenticator_->GetAssertion( std::move(request_options), base::BindOnce(&CreditCardFIDOAuthenticator::OnDidGetAssertion, @@ -170,8 +202,10 @@ void CreditCardFIDOAuthenticator::MakeCredential( PublicKeyCredentialCreationOptionsPtr creation_options) { - autofill_driver_->ConnectToAuthenticator( - authenticator_.BindNewPipeAndPassReceiver()); + if (!authenticator_.is_bound()) { + autofill_driver_->ConnectToAuthenticator( + authenticator_.BindNewPipeAndPassReceiver()); + } #if !defined(OS_ANDROID) // On desktop, close the WebAuthn offer dialog and get ready to show the OS // level authentication dialog. If dialog is already closed, then the offer @@ -188,15 +222,29 @@ weak_ptr_factory_.GetWeakPtr())); } -void CreditCardFIDOAuthenticator::OptChange(bool opt_in, - base::Value attestation_response) { +void CreditCardFIDOAuthenticator::OptChange( + bool opt_in, + base::Value authenticator_response) { payments::PaymentsClient::OptChangeRequestDetails request_details; request_details.app_locale = autofill_client_->GetPersonalDataManager()->app_locale(); request_details.opt_in = opt_in; - if (attestation_response.is_dict()) { + + // If |authenticator_response| is set, that means the user just signed a + // challenge. In which case, if |card_authorization_token_| is not empty, then + // that will be required to bind a previous CVC check with this signature. + // This will opt the user in and authorize the card corresponding to + // |card_authorization_token_|. + // If |authenticator_response| is not set, that means the user was fetching a + // challenge, in which case |card_authorization_token_| will be required for + // the subsequent OptChange call. + if (authenticator_response.is_dict()) { request_details.fido_authenticator_response = - std::move(attestation_response); + std::move(authenticator_response); + if (!card_authorization_token_.empty()) { + request_details.card_authorization_token = card_authorization_token_; + card_authorization_token_ = std::string(); + } } payments_client_->OptChange( request_details, @@ -209,18 +257,30 @@ GetAssertionAuthenticatorResponsePtr assertion_response) { // End the flow if there was an authentication error. if (status != AuthenticatorStatus::SUCCESS) { + // Report failure to |requester_| if card unmasking was requested. + if (current_flow_ == AUTHENTICATION_FLOW) + requester_->OnFIDOAuthenticationComplete(/*did_succeed=*/false); current_flow_ = NONE_FLOW; - requester_->OnFIDOAuthenticationComplete(/*did_succeed=*/false); return; } - base::Value response = ParseAssertionResponse(std::move(assertion_response)); - full_card_request_.reset(new payments::FullCardRequest( - autofill_client_, autofill_client_->GetPaymentsClient(), - autofill_client_->GetPersonalDataManager(), form_parsed_timestamp_)); - full_card_request_->GetFullCardViaFIDO( - *card_, AutofillClient::UNMASK_FOR_AUTOFILL, - weak_ptr_factory_.GetWeakPtr(), std::move(response)); + if (current_flow_ == AUTHENTICATION_FLOW) { + base::Value response = + ParseAssertionResponse(std::move(assertion_response)); + full_card_request_.reset(new payments::FullCardRequest( + autofill_client_, autofill_client_->GetPaymentsClient(), + autofill_client_->GetPersonalDataManager(), form_parsed_timestamp_)); + full_card_request_->GetFullCardViaFIDO( + *card_, AutofillClient::UNMASK_FOR_AUTOFILL, + weak_ptr_factory_.GetWeakPtr(), std::move(response)); + } else { + DCHECK(current_flow_ == FOLLOWUP_AFTER_CVC_AUTH_FLOW || + current_flow_ == OPT_IN_WITH_CHALLENGE_FLOW); + base::Value response = base::Value(base::Value::Type::DICTIONARY); + response.SetKey("fido_assertion_info", + ParseAssertionResponse(std::move(assertion_response))); + OptChange(/*opt_in=*/true, std::move(response)); + } } void CreditCardFIDOAuthenticator::OnDidMakeCredential( @@ -239,9 +299,10 @@ void CreditCardFIDOAuthenticator::OnDidGetOptChangeResult( AutofillClient::PaymentsRpcResult result, payments::PaymentsClient::OptChangeResponseDetails& response) { - DCHECK(current_flow_ == OPT_IN_WITHOUT_CHALLENGE_FLOW || + DCHECK(current_flow_ == OPT_IN_FETCH_CHALLENGE_FLOW || current_flow_ == OPT_OUT_FLOW || - current_flow_ == OPT_IN_WITH_CHALLENGE_FLOW); + current_flow_ == OPT_IN_WITH_CHALLENGE_FLOW || + current_flow_ == FOLLOWUP_AFTER_CVC_AUTH_FLOW); // End the flow if the server responded with an error. if (result != AutofillClient::PaymentsRpcResult::SUCCESS) { current_flow_ = NONE_FLOW; @@ -255,12 +316,17 @@ autofill_client_->GetPrefs(), response.user_is_opted_in.value()); } - // If response contains |creation_options| and the last opt-in attempt did not - // include a challenge, then invoke WebAuthn registration prompt. Otherwise - // end the flow. - if (response.fido_creation_options.has_value() && - current_flow_ == OPT_IN_WITHOUT_CHALLENGE_FLOW) { - Register(std::move(response.fido_creation_options.value())); + // If response contains |creation_options| or |request_options| and the last + // opt-in attempt did not include a challenge, then invoke WebAuthn + // registration/verification prompt. Otherwise end the flow. + if (current_flow_ == OPT_IN_FETCH_CHALLENGE_FLOW) { + if (response.fido_creation_options.has_value()) { + Register(card_authorization_token_, + std::move(response.fido_creation_options.value())); + } else if (response.fido_request_options.has_value()) { + Authorize(card_authorization_token_, + std::move(response.fido_request_options.value())); + } } else { current_flow_ = NONE_FLOW; } @@ -269,9 +335,10 @@ void CreditCardFIDOAuthenticator::OnWebauthnOfferDialogUserResponse( bool did_accept) { if (did_accept) { - Register(); + Register(card_authorization_token_); } else { payments_client_->CancelRequest(); + card_authorization_token_ = std::string(); current_flow_ = NONE_FLOW; } }
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator.h b/components/autofill/core/browser/payments/credit_card_fido_authenticator.h index eeb1952d..60dd2c6 100644 --- a/components/autofill/core/browser/payments/credit_card_fido_authenticator.h +++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator.h
@@ -53,9 +53,11 @@ // Registration flow, including a challenge to sign. OPT_IN_WITH_CHALLENGE_FLOW, // Opt-in attempt flow, no challenge to sign. - OPT_IN_WITHOUT_CHALLENGE_FLOW, + OPT_IN_FETCH_CHALLENGE_FLOW, // Opt-out flow. OPT_OUT_FLOW, + // Authorization of a new card. + FOLLOWUP_AFTER_CVC_AUTH_FLOW, }; class Requester { public: @@ -68,16 +70,25 @@ ~CreditCardFIDOAuthenticator() override; // Offer the option to use WebAuthn for authenticating future card unmasking. - void ShowWebauthnOfferDialog(); + void ShowWebauthnOfferDialog(std::string card_authorization_token); - // Authentication + // Invokes Authentication flow. Responds to |accessor_| with full pan. void Authenticate(const CreditCard* card, base::WeakPtr<Requester> requester, base::TimeTicks form_parsed_timestamp, base::Value request_options); - // Registration - void Register(base::Value creation_options = base::Value()); + // Invokes Registration flow. Sends credentials created from + // |creation_options| along with the |card_authorization_token| to Payments in + // order to enroll the user and authorize the corresponding card. + void Register(std::string card_authorization_token = std::string(), + base::Value creation_options = base::Value()); + + // Invokes an Authorization flow. Sends signature created from + // |request_options| along with the |card_authorization_token| to Payments in + // order to authorize the corresponding card. + void Authorize(std::string card_authorization_token, + base::Value request_options); // Opts the user out. void OptOut(); @@ -124,7 +135,8 @@ PublicKeyCredentialCreationOptionsPtr creation_options); // Makes a request to payments to either opt-in or opt-out the user. - void OptChange(bool opt_in, base::Value attestation_response = base::Value()); + void OptChange(bool opt_in, + base::Value authenticator_response = base::Value()); // The callback invoked from the WebAuthn prompt including the // |assertion_response|, which will be sent to Google Payments to retrieve @@ -193,6 +205,10 @@ // The current flow in progress. Flow current_flow_ = NONE_FLOW; + // Token used for authorizing new cards. Helps tie CVC auth and FIDO calls + // together in order to support FIDO-only unmasking on future attempts. + std::string card_authorization_token_; + // Meant for histograms recorded in FullCardRequest. base::TimeTicks form_parsed_timestamp_;
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc b/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc index ae007591..c088e89e 100644 --- a/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc
@@ -85,6 +85,7 @@ const char kTestCredentialId[] = "VGhpcyBpcyBhIHRlc3QgQ3JlZGVudGlhbCBJRC4="; // Base64 encoding of "This is a test signature". const char kTestSignature[] = "VGhpcyBpcyBhIHRlc3Qgc2lnbmF0dXJl"; +const char kTestAuthToken[] = "dummy_card_authorization_token"; std::string NextMonth() { base::Time::Exploded now; @@ -422,8 +423,8 @@ features::kAutofillCreditCardAuthentication); EXPECT_FALSE(fido_authenticator_->IsUserOptedIn()); - fido_authenticator_->Register(); - EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::OPT_IN_WITHOUT_CHALLENGE_FLOW, + fido_authenticator_->Register(kTestAuthToken); + EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::OPT_IN_FETCH_CHALLENGE_FLOW, fido_authenticator_->current_flow()); // Mock payments response. @@ -437,8 +438,8 @@ features::kAutofillCreditCardAuthentication); EXPECT_FALSE(fido_authenticator_->IsUserOptedIn()); - fido_authenticator_->Register(); - EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::OPT_IN_WITHOUT_CHALLENGE_FLOW, + fido_authenticator_->Register(kTestAuthToken); + EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::OPT_IN_FETCH_CHALLENGE_FLOW, fido_authenticator_->current_flow()); // Mock payments response. @@ -453,6 +454,7 @@ EXPECT_FALSE(fido_authenticator_->IsUserOptedIn()); fido_authenticator_->Register( + kTestAuthToken, GetTestCreationOptions(/*challenge=*/"", kTestRelyingPartyId)); EXPECT_FALSE(fido_authenticator_->IsUserOptedIn()); @@ -464,6 +466,7 @@ EXPECT_FALSE(fido_authenticator_->IsUserOptedIn()); fido_authenticator_->Register( + kTestAuthToken, GetTestCreationOptions(kTestChallenge, kTestRelyingPartyId)); EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::OPT_IN_WITH_CHALLENGE_FLOW, fido_authenticator_->current_flow()); @@ -480,6 +483,7 @@ EXPECT_FALSE(fido_authenticator_->IsUserOptedIn()); fido_authenticator_->Register( + kTestAuthToken, GetTestCreationOptions(kTestChallenge, kTestRelyingPartyId)); EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::OPT_IN_WITH_CHALLENGE_FLOW, fido_authenticator_->current_flow()); @@ -498,8 +502,8 @@ features::kAutofillCreditCardAuthentication); EXPECT_FALSE(fido_authenticator_->IsUserOptedIn()); - fido_authenticator_->Register(); - EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::OPT_IN_WITHOUT_CHALLENGE_FLOW, + fido_authenticator_->Register(kTestAuthToken); + EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::OPT_IN_FETCH_CHALLENGE_FLOW, fido_authenticator_->current_flow()); // Mock payments response with challenge to invoke enrollment flow. @@ -517,6 +521,53 @@ EXPECT_TRUE(fido_authenticator_->IsUserOptedIn()); } +TEST_F(CreditCardFIDOAuthenticatorTest, + Register_OptInAttemptReturnsRequestOptions) { + scoped_feature_list_.InitAndEnableFeature( + features::kAutofillCreditCardAuthentication); + EXPECT_FALSE(fido_authenticator_->IsUserOptedIn()); + + fido_authenticator_->Register(kTestAuthToken); + EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::OPT_IN_FETCH_CHALLENGE_FLOW, + fido_authenticator_->current_flow()); + + // Mock payments response with challenge to invoke opt-in flow. + OptChange(AutofillClient::PaymentsRpcResult::SUCCESS, + /*user_is_opted_in=*/false, /*include_creation_options=*/false, + /*include_request_options=*/true); + EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::OPT_IN_WITH_CHALLENGE_FLOW, + fido_authenticator_->current_flow()); + EXPECT_FALSE(fido_authenticator_->IsUserOptedIn()); + + // Mock user response and second payments response. + TestCreditCardFIDOAuthenticator::GetAssertion(fido_authenticator_.get(), + /*did_succeed=*/true); + OptChange(AutofillClient::PaymentsRpcResult::SUCCESS, + /*user_is_opted_in=*/true); + EXPECT_TRUE(fido_authenticator_->IsUserOptedIn()); +} + +TEST_F(CreditCardFIDOAuthenticatorTest, Register_NewCardAuthorization) { + scoped_feature_list_.InitAndEnableFeature( + features::kAutofillCreditCardAuthentication); + ::autofill::prefs::SetCreditCardFIDOAuthEnabled(autofill_client_.GetPrefs(), + true); + EXPECT_TRUE(fido_authenticator_->IsUserOptedIn()); + + fido_authenticator_->Authorize( + kTestAuthToken, GetTestRequestOptions(kTestChallenge, kTestRelyingPartyId, + kTestCredentialId)); + EXPECT_EQ(CreditCardFIDOAuthenticator::Flow::FOLLOWUP_AFTER_CVC_AUTH_FLOW, + fido_authenticator_->current_flow()); + + // Mock user response and second payments response. + TestCreditCardFIDOAuthenticator::GetAssertion(fido_authenticator_.get(), + /*did_succeed=*/true); + OptChange(AutofillClient::PaymentsRpcResult::SUCCESS, + /*user_is_opted_in=*/true); + EXPECT_TRUE(fido_authenticator_->IsUserOptedIn()); +} + TEST_F(CreditCardFIDOAuthenticatorTest, OptOut_Success) { scoped_feature_list_.InitAndEnableFeature( features::kAutofillCreditCardAuthentication);
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn index af7a8db..3be99d4 100644 --- a/components/cronet/android/BUILD.gn +++ b/components/cronet/android/BUILD.gn
@@ -498,6 +498,9 @@ script = "//components/cronet/tools/generate_proguard_file.py" sources = [ "//base/android/proguard/chromium_code.flags", + + # Massage the proguard rules to work with AppReduce. + "//components/cronet/android/cronet_appreduce_workaround.patch", "//components/cronet/android/cronet_impl_native_proguard.cfg", ] outputs = [
diff --git a/components/cronet/android/cronet_appreduce_workaround.patch b/components/cronet/android/cronet_appreduce_workaround.patch new file mode 100644 index 0000000..55de3bc --- /dev/null +++ b/components/cronet/android/cronet_appreduce_workaround.patch
@@ -0,0 +1,34 @@ +This patchfile is a stop-gap solution to accomodate differences in syntax for +AppReduce, which is used internally in place of ProGuard. See crbug.com/1004516. + +This patches base/android/proguard/chromium_code.flags. + +It can be re-generated using these steps: + +cd src +export ORIG_FLAGS="base/android/proguard/chromium_code.flags" +cp $ORIG_FLAGS modified.flags +$EDITOR modified.flags +diff -u "$ORIG_FLAGS" modified.flags > "components/cronet/android/cronet_appreduce_workaround.patch" + +To test whether the patch applies cleanly use: + +autoninja -C out/Release cronet_combine_proguard_flags + +--- base/android/proguard/chromium_code.flags 2019-09-16 16:39:21.108477065 -0700 ++++ modified.flags 2019-09-17 12:12:17.487606737 -0700 +@@ -50,9 +50,12 @@ + -assumenosideeffects class ** { + # Remove @RemovableInRelease methods so long as return values are unused. + @org.chromium.base.annotations.RemovableInRelease <methods>; ++} ++ ++-assumevalues class ** { + # Remove object @RemovableInRelease methods even when return value is used. +- # Note: * in return type does not match primitives. +- @org.chromium.base.annotations.RemovableInRelease * *(...) return null; ++ # Note: ** in return type does not match primitives. ++ @org.chromium.base.annotations.RemovableInRelease ** *(...) return null; + # Remove boolean @RemovableInRelease methods even when return value is used. + @org.chromium.base.annotations.RemovableInRelease boolean *(...) return false; + }
diff --git a/components/cronet/ios/test/cronet_prefs_test.mm b/components/cronet/ios/test/cronet_prefs_test.mm index 4c47613..2a99e53 100644 --- a/components/cronet/ios/test/cronet_prefs_test.mm +++ b/components/cronet/ios/test/cronet_prefs_test.mm
@@ -79,7 +79,7 @@ NSURLSession* session_; }; -TEST_F(PrefsTest, DISABLED_HttpSeverProperties) { +TEST_F(PrefsTest, HttpServerProperties) { base::FilePath storage_path; bool result = base::PathService::Get(base::DIR_CACHE, &storage_path); ASSERT_TRUE(result); @@ -115,13 +115,11 @@ // Check the file content ASSERT_TRUE(prefs_file_content); ASSERT_TRUE( - [prefs_file_content containsString:@"{\"http_server_properties\":{"]) + [prefs_file_content containsString:@"{\"http_server_properties\":"]) << "Unable to find 'http_server_properties' in the JSON prefs."; - ASSERT_TRUE( - [prefs_file_content containsString:@"\"supports_quic\":{\"address\"" - ":\"127.0.0.1\",\"used_quic\":true}"]) + ASSERT_TRUE([prefs_file_content containsString:@"\"supports_quic\":"]) << "Unable to find 'supports_quic' in the JSON prefs."; - ASSERT_TRUE([prefs_file_content containsString:@"{\"server_info\":\""]) + ASSERT_TRUE([prefs_file_content containsString:@"\"server_info\":"]) << "Unable to find 'server_info' in the JSON prefs."; // Delete the prefs file to avoid side effects with other tests.
diff --git a/components/cronet/tools/generate_proguard_file.py b/components/cronet/tools/generate_proguard_file.py index 6d7e530a..edaebb0 100755 --- a/components/cronet/tools/generate_proguard_file.py +++ b/components/cronet/tools/generate_proguard_file.py
@@ -4,20 +4,42 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +# Tool that combines a sequence of input proguard files and outputs a single +# proguard file. +# +# The final output file is formed by concatenating all of the +# input proguard files, and then sequentally applying any .patch files that +# were given in the input. +# +# This tool requires the ability to shell execute the 'patch' tool, and is +# expected to only be run on Linux. + import optparse import sys +import subprocess -# Combines files in |input_files| as one proguard file and write that to -# |output_file| -def GenerateProguardFile(output_file, input_files): + +def ReadFile(path): + with open(path, 'rb') as f: + return f.read() + + +def IsPatchFile(path): + return path.endswith('.patch') + + +def ApplyPatch(output_file, patch_file): try: - with open(output_file, "wb") as target: - for input_file in input_files: - f = open(input_file, "rb") - for line in f: - target.write(line) - except IOError: - raise Exception("Proguard file generation failed") + subprocess.check_call(['patch', '--quiet', output_file, patch_file]) + except: + message = ''' +Failed applying patch %s to %s + +For help on fixing read the documentation in the patch file. + +''' + sys.stderr.write(message % (patch_file, output_file)) + raise def main(): @@ -26,7 +48,18 @@ help='Output file for the generated proguard file') options, input_files = parser.parse_args() - GenerateProguardFile(options.output_file, input_files) + + proguard_files = [path for path in input_files if not IsPatchFile(path)] + patch_files = [path for path in input_files if IsPatchFile(path)] + + # Concatenate all the proguard files. + with open(options.output_file, 'wb') as target: + for input_file in proguard_files: + target.write(ReadFile(input_file)) + + # Apply any patch files. + for patch_file in patch_files: + ApplyPatch(options.output_file, patch_file) if __name__ == '__main__':
diff --git a/components/dom_distiller/core/html/dom_distiller_viewer.html b/components/dom_distiller/core/html/dom_distiller_viewer.html index f67f4ed..950be52 100644 --- a/components/dom_distiller/core/html/dom_distiller_viewer.html +++ b/components/dom_distiller/core/html/dom_distiller_viewer.html
@@ -35,15 +35,5 @@ </div> <a data-original-url="$7" id="closeReaderView">$8</a> </div> - <div id="feedbackContainer" class="footerFeedback hidden"> - <div class="feedbackContent"> - <div id="feedbackQuestion"></div> - <div class="feedbackButtonWrap"> - <a class="feedbackButton" id="feedbackNo"></a> - <a class="feedbackButton" id="feedbackYes"></a> - </div> - </div> - <div class="clear"></div> - </div> </body> </html>
diff --git a/components/offline_pages/core/background/request_coordinator.cc b/components/offline_pages/core/background/request_coordinator.cc index df0a163b..13607b0 100644 --- a/components/offline_pages/core/background/request_coordinator.cc +++ b/components/offline_pages/core/background/request_coordinator.cc
@@ -545,22 +545,26 @@ RequestAvailability availability, AddRequestResult result, const SavePageRequest& request) { - NotifyAdded(request); - // Inform the scheduler that we have an outstanding task. - scheduler_->Schedule(GetTriggerConditions(kUserRequest)); + if (result == AddRequestResult::SUCCESS) { + NotifyAdded(request); + // Inform the scheduler that we have an outstanding task. + scheduler_->Schedule(GetTriggerConditions(kUserRequest)); - if (availability == RequestAvailability::DISABLED_FOR_OFFLINER) { - // Mark attempt started (presuming it is disabled for background offliner - // because foreground offlining is happening). - queue_->MarkAttemptStarted( - request.request_id(), - base::BindOnce(&RequestCoordinator::MarkAttemptDone, - weak_ptr_factory_.GetWeakPtr(), request.request_id(), - request.client_id().name_space)); - } else if (request.user_requested()) { - StartImmediatelyIfConnected(); + if (availability == RequestAvailability::DISABLED_FOR_OFFLINER) { + // Mark attempt started (presuming it is disabled for background offliner + // because foreground offlining is happening). + queue_->MarkAttemptStarted( + request.request_id(), + base::BindOnce(&RequestCoordinator::MarkAttemptDone, + weak_ptr_factory_.GetWeakPtr(), request.request_id(), + request.client_id().name_space)); + } else if (request.user_requested()) { + StartImmediatelyIfConnected(); + } + } else { + event_logger_.RecordAddRequestFailed(request.client_id().name_space, + result); } - std::move(save_page_later_callback).Run(result); }
diff --git a/components/offline_pages/core/background/request_coordinator_event_logger.cc b/components/offline_pages/core/background/request_coordinator_event_logger.cc index ef2a136..26a18022 100644 --- a/components/offline_pages/core/background/request_coordinator_event_logger.cc +++ b/components/offline_pages/core/background/request_coordinator_event_logger.cc
@@ -4,6 +4,10 @@ #include "components/offline_pages/core/background/request_coordinator_event_logger.h" +#include <string> +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" + namespace offline_pages { namespace { @@ -33,7 +37,7 @@ return "DOWNLOAD_THROTTLED"; default: NOTREACHED(); - return std::to_string(static_cast<int>(result)); + return base::NumberToString(static_cast<int>(result)); } } @@ -47,7 +51,7 @@ return "REQUEST_DOES_NOT_EXIST"; default: NOTREACHED(); - return std::to_string(static_cast<int>(result)); + return base::NumberToString(static_cast<int>(result)); } } @@ -57,7 +61,7 @@ const std::string& name_space, Offliner::RequestStatus new_status, int64_t request_id) { - std::string request_id_str = std::to_string(request_id); + std::string request_id_str = base::NumberToString(request_id); RecordActivity("Background save attempt for " + name_space + ":" + request_id_str + " - " + Offliner::RequestStatusToString(new_status)); @@ -67,7 +71,7 @@ const std::string& name_space, RequestNotifier::BackgroundSavePageResult result, int64_t request_id) { - std::string request_id_str = std::to_string(request_id); + std::string request_id_str = base::NumberToString(request_id); RecordActivity("Background save request removed " + name_space + ":" + request_id_str + " - " + BackgroundSavePageResultToString(result)); @@ -80,4 +84,12 @@ UpdateRequestResultToString(result)); } +void RequestCoordinatorEventLogger::RecordAddRequestFailed( + const std::string& name_space, + AddRequestResult result) { + RecordActivity( + base::StrCat({"Add request failed for ", name_space, " - code ", + base::NumberToString(static_cast<int>(result))})); +} + } // namespace offline_pages
diff --git a/components/offline_pages/core/background/request_coordinator_event_logger.h b/components/offline_pages/core/background/request_coordinator_event_logger.h index 92bd009..a86e91c 100644 --- a/components/offline_pages/core/background/request_coordinator_event_logger.h +++ b/components/offline_pages/core/background/request_coordinator_event_logger.h
@@ -31,6 +31,9 @@ void RecordUpdateRequestFailed(const std::string& name_space, UpdateRequestResult result); + + void RecordAddRequestFailed(const std::string& name_space, + AddRequestResult result); }; } // namespace offline_pages
diff --git a/components/offline_pages/core/background/request_coordinator_unittest.cc b/components/offline_pages/core/background/request_coordinator_unittest.cc index 79615d7b..e84b2de 100644 --- a/components/offline_pages/core/background/request_coordinator_unittest.cc +++ b/components/offline_pages/core/background/request_coordinator_unittest.cc
@@ -16,6 +16,7 @@ #include "base/logging.h" #include "base/synchronization/waitable_event.h" #include "base/system/sys_info.h" +#include "base/test/bind_test_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_mock_time_task_runner.h" @@ -80,17 +81,11 @@ class ObserverStub : public RequestCoordinator::Observer { public: - ObserverStub() - : added_called_(false), - completed_called_(false), - changed_called_(false), - network_progress_called_(false), - network_progress_bytes_(0), - last_status_(RequestCoordinator::BackgroundSavePageResult::SUCCESS), - state_(SavePageRequest::RequestState::OFFLINING) {} + ObserverStub() { Clear(); } void Clear() { added_called_ = false; + added_call_count_ = 0; completed_called_ = false; changed_called_ = false; network_progress_called_ = false; @@ -101,6 +96,7 @@ void OnAdded(const SavePageRequest& request) override { added_called_ = true; + ++added_call_count_; state_ = request.request_state(); pending_state_ = request.pending_state(); } @@ -125,6 +121,7 @@ } bool added_called() { return added_called_; } + int added_call_count() const { return added_call_count_; } bool completed_called() { return completed_called_; } bool changed_called() { return changed_called_; } bool network_progress_called() { return network_progress_called_; } @@ -137,6 +134,7 @@ private: bool added_called_; + int added_call_count_; bool completed_called_; bool changed_called_; bool network_progress_called_; @@ -1879,4 +1877,28 @@ EXPECT_EQ(PendingState::PENDING_ANOTHER_DOWNLOAD, observer().pending_state()); } +TEST_F(RequestCoordinatorTest, SavePageLaterRejectedDuplicateUrl) { + // Request the same URL twice using the 'disallow_duplicate_requests' option, + // and verify the second request is rejected. + EnableOfflinerCallback(false); + + RequestCoordinator::SavePageLaterParams params; + params.url = kUrl1; + params.client_id = kClientId1; + params.add_options.disallow_duplicate_requests = true; + std::vector<AddRequestResult> results; + auto callback = base::BindLambdaForTesting( + [&](AddRequestResult result) { results.push_back(result); }); + + EXPECT_NE(0, coordinator()->SavePageLater(params, callback)); + EXPECT_NE(0, coordinator()->SavePageLater(params, callback)); + PumpLoop(); + + // Only one is added. + EXPECT_EQ(1, observer().added_call_count()); + EXPECT_EQ(std::vector<AddRequestResult>( + {AddRequestResult::SUCCESS, AddRequestResult::DUPLICATE_URL}), + results); +} + } // namespace offline_pages
diff --git a/components/omnibox/browser/document_provider.h b/components/omnibox/browser/document_provider.h index 36ccd799..7eb401d 100644 --- a/components/omnibox/browser/document_provider.h +++ b/components/omnibox/browser/document_provider.h
@@ -104,6 +104,7 @@ FRIEND_TEST_ALL_PREFIXES(DocumentProviderTest, GenerateLastModifiedString); FRIEND_TEST_ALL_PREFIXES(DocumentProviderTest, Scoring); FRIEND_TEST_ALL_PREFIXES(DocumentProviderTest, Caching); + FRIEND_TEST_ALL_PREFIXES(DocumentProviderTest, MinQueryLength); using MatchesCache = base::MRUCache<GURL, AutocompleteMatch>;
diff --git a/components/omnibox/browser/document_provider_unittest.cc b/components/omnibox/browser/document_provider_unittest.cc index 7d6a218..6c7fdeea 100644 --- a/components/omnibox/browser/document_provider_unittest.cc +++ b/components/omnibox/browser/document_provider_unittest.cc
@@ -916,3 +916,29 @@ testing::ElementsAre(ACMatchClassification{0, 2}, ACMatchClassification{5, 0})); } + +TEST_F(DocumentProviderTest, MinQueryLength) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(omnibox::kDocumentProvider); + EXPECT_CALL(*client_.get(), SearchSuggestEnabled()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*client_.get(), IsAuthenticated()).WillRepeatedly(Return(true)); + EXPECT_CALL(*client_.get(), IsSyncActive()).WillRepeatedly(Return(true)); + EXPECT_CALL(*client_.get(), IsOffTheRecord()).WillRepeatedly(Return(false)); + + // Expect document provider to ignore inputs shorter than min_query_length_. + AutocompleteInput short_input(base::ASCIIToUTF16("12"), + metrics::OmniboxEventProto::OTHER, + TestSchemeClassifier()); + short_input.set_want_asynchronous_matches(false); + provider_->Start(short_input, false); + EXPECT_NE(short_input.text(), provider_->input_.text()); + + // Expect document provider to process inputs longer than min_query_length_. + AutocompleteInput long_input(base::ASCIIToUTF16("123456"), + metrics::OmniboxEventProto::OTHER, + TestSchemeClassifier()); + long_input.set_want_asynchronous_matches(false); + provider_->Start(long_input, false); + EXPECT_EQ(long_input.text(), provider_->input_.text()); +}
diff --git a/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc b/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc index 96add61..97d9a8d 100644 --- a/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc +++ b/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc
@@ -181,29 +181,29 @@ quad4_root_1->SetNew(shared_quad_state4_root, /*rect=*/rect4_root, /*visible_rect=*/rect4_root, /*render_pass_id=*/1, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); auto* quad4_root_2 = pass4_root->quad_list.AllocateAndConstruct<RenderPassDrawQuad>(); quad4_root_2->SetNew(shared_quad_state4_root, /*rect=*/rect4_root, /*visible_rect=*/rect4_root, /*render_pass_id=*/2, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); auto* quad4_root_3 = pass4_root->quad_list.AllocateAndConstruct<RenderPassDrawQuad>(); quad4_root_3->SetNew(shared_quad_state4_root, /*rect=*/rect4_root, /*visible_rect=*/rect4_root, /*render_pass_id=*/3, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); auto* quad4_root_4 = pass4_root->quad_list.AllocateAndConstruct<RenderPassDrawQuad>(); quad4_root_4->SetNew(shared_quad_state4_root, /*rect=*/rect4_root, /*visible_rect=*/rect4_root, /*render_pass_id=*/4, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); pass_list.push_back(std::move(pass4_root)); auto compositor_frame = @@ -460,8 +460,7 @@ render_pass_quad_1->SetNew( pass2->shared_quad_state_list.back(), child_rect, child_rect, /*render_pass_id=*/1, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), gfx::PointF(), - gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); SurfaceId child_surface_id3 = CreateChildSurfaceId(4); gfx::Rect child_rect3(500, 500, 100, 100); auto* surface_quad_3 = pass2->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); @@ -474,8 +473,7 @@ render_pass_quad_2->SetNew( pass2->shared_quad_state_list.back(), child_rect2, child_rect2, /*render_pass_id=*/1, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), gfx::PointF(), - gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); pass_list.push_back(std::move(pass2)); // The root RenderPass that has three RenderPassDrawQuad point to pass2. @@ -490,22 +488,19 @@ render_pass_quad_3->SetNew( pass_root->shared_quad_state_list.back(), child_rect, child_rect, /*render_pass_id=*/4, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), gfx::PointF(), - gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); auto* render_pass_quad_4 = pass_root->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); render_pass_quad_4->SetNew( pass_root->shared_quad_state_list.back(), child_rect2, child_rect2, /*render_pass_id=*/4, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), gfx::PointF(), - gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); auto* render_pass_quad_5 = pass_root->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); render_pass_quad_5->SetNew( pass_root->shared_quad_state_list.back(), child_rect, child_rect, /*render_pass_id=*/4, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 10), gfx::PointF(), - gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 10), gfx::PointF(), gfx::RectF(), false, 1.0f); pass_list.push_back(std::move(pass_root)); CompositorFrame compositor_frame =
diff --git a/components/viz/common/quads/draw_quad_unittest.cc b/components/viz/common/quads/draw_quad_unittest.cc index 197e9dd..2ee5914e 100644 --- a/components/viz/common/quads/draw_quad_unittest.cc +++ b/components/viz/common/quads/draw_quad_unittest.cc
@@ -161,11 +161,11 @@ } \ SETUP_AND_COPY_QUAD_ALL_RP(Type, quad_all, copy_a); -#define CREATE_QUAD_NEW_RP(Type, a, b, c, d, e, f, g, h, i, j, k, copy_a) \ +#define CREATE_QUAD_NEW_RP(Type, a, b, c, d, e, f, g, h, i, j, copy_a) \ Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>(); \ { \ QUAD_DATA quad_new->SetNew(shared_state, quad_rect, a, b, c, d, e, f, g, \ - h, i, j, k); \ + h, i, j); \ } \ SETUP_AND_COPY_QUAD_NEW_RP(Type, quad_new, copy_a); @@ -193,7 +193,6 @@ ResourceId mask_resource_id = 78; gfx::RectF mask_uv_rect(0, 0, 33.f, 19.f); gfx::Size mask_texture_size(128, 134); - bool mask_applies_to_backdrop = false; gfx::Vector2dF filters_scale; gfx::PointF filters_origin; gfx::RectF tex_coord_rect(1, 1, 255, 254); @@ -205,9 +204,9 @@ CREATE_QUAD_NEW_RP(RenderPassDrawQuad, visible_rect, render_pass_id, mask_resource_id, mask_uv_rect, mask_texture_size, - mask_applies_to_backdrop, filters_scale, filters_origin, - tex_coord_rect, force_anti_aliasing_off, - backdrop_filter_quality, copied_render_pass_id); + filters_scale, filters_origin, tex_coord_rect, + force_anti_aliasing_off, backdrop_filter_quality, + copied_render_pass_id); EXPECT_EQ(DrawQuad::Material::kRenderPass, copy_quad->material); EXPECT_EQ(visible_rect, copy_quad->visible_rect); EXPECT_EQ(copied_render_pass_id, copy_quad->render_pass_id); @@ -215,24 +214,6 @@ EXPECT_EQ(mask_uv_rect.ToString(), copy_quad->mask_uv_rect.ToString()); EXPECT_EQ(mask_texture_size.ToString(), copy_quad->mask_texture_size.ToString()); - EXPECT_EQ(mask_applies_to_backdrop, copy_quad->mask_applies_to_backdrop); - EXPECT_EQ(filters_scale, copy_quad->filters_scale); - EXPECT_EQ(filters_origin, copy_quad->filters_origin); - EXPECT_EQ(tex_coord_rect.ToString(), copy_quad->tex_coord_rect.ToString()); - - mask_applies_to_backdrop = true; - CREATE_QUAD_ALL_RP(RenderPassDrawQuad, render_pass_id, mask_resource_id, - mask_uv_rect, mask_texture_size, mask_applies_to_backdrop, - filters_scale, filters_origin, tex_coord_rect, - force_anti_aliasing_off, backdrop_filter_quality, - copied_render_pass_id); - EXPECT_EQ(DrawQuad::Material::kRenderPass, copy_quad->material); - EXPECT_EQ(copied_render_pass_id, copy_quad->render_pass_id); - EXPECT_EQ(mask_resource_id, copy_quad->mask_resource_id()); - EXPECT_EQ(mask_uv_rect.ToString(), copy_quad->mask_uv_rect.ToString()); - EXPECT_EQ(mask_texture_size.ToString(), - copy_quad->mask_texture_size.ToString()); - EXPECT_EQ(mask_applies_to_backdrop, copy_quad->mask_applies_to_backdrop); EXPECT_EQ(filters_scale, copy_quad->filters_scale); EXPECT_EQ(filters_origin, copy_quad->filters_origin); EXPECT_EQ(tex_coord_rect.ToString(), copy_quad->tex_coord_rect.ToString()); @@ -548,7 +529,6 @@ ResourceId mask_resource_id = 78; gfx::RectF mask_uv_rect(0.f, 0.f, 33.f, 19.f); gfx::Size mask_texture_size(128, 134); - bool mask_applies_to_backdrop = false; gfx::Vector2dF filters_scale(2.f, 3.f); gfx::PointF filters_origin(0.f, 0.f); gfx::RectF tex_coord_rect(1.f, 1.f, 33.f, 19.f); @@ -560,33 +540,19 @@ CREATE_SHARED_STATE(); CREATE_QUAD_NEW_RP(RenderPassDrawQuad, visible_rect, render_pass_id, mask_resource_id, mask_uv_rect, mask_texture_size, - mask_applies_to_backdrop, filters_scale, filters_origin, - tex_coord_rect, force_anti_aliasing_off, - backdrop_filter_quality, copied_render_pass_id); + filters_scale, filters_origin, tex_coord_rect, + force_anti_aliasing_off, backdrop_filter_quality, + copied_render_pass_id); EXPECT_EQ(mask_resource_id, quad_new->mask_resource_id()); EXPECT_EQ(1, IterateAndCount(quad_new)); EXPECT_EQ(mask_resource_id + 1, quad_new->mask_resource_id()); - EXPECT_EQ(mask_applies_to_backdrop, quad_new->mask_applies_to_backdrop); - mask_applies_to_backdrop = true; - quad_new->SetNew(shared_state, visible_rect, visible_rect, render_pass_id, - mask_resource_id, mask_uv_rect, mask_texture_size, - mask_applies_to_backdrop, filters_scale, filters_origin, - tex_coord_rect, force_anti_aliasing_off, - backdrop_filter_quality); - EXPECT_EQ(mask_resource_id, quad_new->mask_resource_id()); - EXPECT_EQ(1, IterateAndCount(quad_new)); - EXPECT_EQ(mask_resource_id + 1, quad_new->mask_resource_id()); - EXPECT_EQ(mask_applies_to_backdrop, quad_new->mask_applies_to_backdrop); - - mask_applies_to_backdrop = false; ResourceId new_mask_resource_id = 0; gfx::Rect quad_rect(30, 40, 50, 60); quad_new->SetNew(shared_state, quad_rect, visible_rect, render_pass_id, new_mask_resource_id, mask_uv_rect, mask_texture_size, - mask_applies_to_backdrop, filters_scale, filters_origin, - tex_coord_rect, force_anti_aliasing_off, - backdrop_filter_quality); + filters_scale, filters_origin, tex_coord_rect, + force_anti_aliasing_off, backdrop_filter_quality); EXPECT_EQ(0, IterateAndCount(quad_new)); EXPECT_EQ(0u, quad_new->mask_resource_id()); }
diff --git a/components/viz/common/quads/render_pass_draw_quad.cc b/components/viz/common/quads/render_pass_draw_quad.cc index d2e5017f..096a0013 100644 --- a/components/viz/common/quads/render_pass_draw_quad.cc +++ b/components/viz/common/quads/render_pass_draw_quad.cc
@@ -26,7 +26,6 @@ ResourceId mask_resource_id, const gfx::RectF& mask_uv_rect, const gfx::Size& mask_texture_size, - bool mask_applies_to_backdrop, const gfx::Vector2dF& filters_scale, const gfx::PointF& filters_origin, const gfx::RectF& tex_coord_rect, @@ -36,9 +35,9 @@ bool needs_blending = true; SetAll(shared_quad_state, rect, visible_rect, needs_blending, render_pass_id, - mask_resource_id, mask_uv_rect, mask_texture_size, - mask_applies_to_backdrop, filters_scale, filters_origin, - tex_coord_rect, force_anti_aliasing_off, backdrop_filter_quality); + mask_resource_id, mask_uv_rect, mask_texture_size, filters_scale, + filters_origin, tex_coord_rect, force_anti_aliasing_off, + backdrop_filter_quality); } void RenderPassDrawQuad::SetAll(const SharedQuadState* shared_quad_state, @@ -49,7 +48,6 @@ ResourceId mask_resource_id, const gfx::RectF& mask_uv_rect, const gfx::Size& mask_texture_size, - bool mask_applies_to_backdrop, const gfx::Vector2dF& filters_scale, const gfx::PointF& filters_origin, const gfx::RectF& tex_coord_rect, @@ -64,7 +62,6 @@ resources.count = mask_resource_id ? 1 : 0; this->mask_uv_rect = mask_uv_rect; this->mask_texture_size = mask_texture_size; - this->mask_applies_to_backdrop = mask_applies_to_backdrop; this->filters_scale = filters_scale; this->filters_origin = filters_origin; this->tex_coord_rect = tex_coord_rect; @@ -85,7 +82,6 @@ value->SetInteger("mask_resource_id", resources.ids[kMaskResourceIdIndex]); cc::MathUtil::AddToTracedValue("mask_texture_size", mask_texture_size, value); cc::MathUtil::AddToTracedValue("mask_uv_rect", mask_uv_rect, value); - value->SetBoolean("mask_applies_to_backdrop", mask_applies_to_backdrop); cc::MathUtil::AddToTracedValue("tex_coord_rect", tex_coord_rect, value); value->SetBoolean("force_anti_aliasing_off", force_anti_aliasing_off); value->SetDouble("backdrop_filter_quality", backdrop_filter_quality);
diff --git a/components/viz/common/quads/render_pass_draw_quad.h b/components/viz/common/quads/render_pass_draw_quad.h index ccb08c3..6d68a8d 100644 --- a/components/viz/common/quads/render_pass_draw_quad.h +++ b/components/viz/common/quads/render_pass_draw_quad.h
@@ -34,7 +34,6 @@ ResourceId mask_resource_id, const gfx::RectF& mask_uv_rect, const gfx::Size& mask_texture_size, - bool mask_applies_to_backdrop, const gfx::Vector2dF& filters_scale, const gfx::PointF& filters_origin, const gfx::RectF& tex_coord_rect, @@ -49,7 +48,6 @@ ResourceId mask_resource_id, const gfx::RectF& mask_uv_rect, const gfx::Size& mask_texture_size, - bool mask_applies_to_backdrop, const gfx::Vector2dF& filters_scale, const gfx::PointF& filters_origin, const gfx::RectF& tex_coord_rect, @@ -75,7 +73,6 @@ float backdrop_filter_quality; bool force_anti_aliasing_off; - bool mask_applies_to_backdrop; ResourceId mask_resource_id() const { return resources.ids[kMaskResourceIdIndex];
diff --git a/components/viz/common/quads/render_pass_unittest.cc b/components/viz/common/quads/render_pass_unittest.cc index 3f083eb2..48a39eac 100644 --- a/components/viz/common/quads/render_pass_unittest.cc +++ b/components/viz/common/quads/render_pass_unittest.cc
@@ -227,8 +227,8 @@ auto pass_quad = std::make_unique<RenderPassDrawQuad>(); pass_quad->SetNew(pass->shared_quad_state_list.back(), contrib_output_rect, contrib_output_rect, contrib_id, 0, gfx::RectF(), - gfx::Size(), false, gfx::Vector2dF(), gfx::PointF(), - gfx::RectF(), false, 1.0f); + gfx::Size(), gfx::Vector2dF(), gfx::PointF(), gfx::RectF(), + false, 1.0f); pass_list.push_back(std::move(pass)); pass_list.push_back(std::move(contrib));
diff --git a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc index 9116f9c..e072576 100644 --- a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc +++ b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc
@@ -332,7 +332,6 @@ /*mask_resource_id=*/ResourceId(), /*mask_uv_rect=*/gfx::RectF(), /*mask_texture_size=*/gfx::Size(), - /*mask_applies_to_backdrop=*/false, /*filters_scale=*/gfx::Vector2dF(), /*filters_origin=*/gfx::PointF(), /*tex_coord_rect=*/tex_coord_rect,
diff --git a/components/viz/service/display/display_unittest.cc b/components/viz/service/display/display_unittest.cc index e2f3b6f..94d630c3 100644 --- a/components/viz/service/display/display_unittest.cc +++ b/components/viz/service/display/display_unittest.cc
@@ -2569,7 +2569,7 @@ SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad1->SetNew(shared_quad_state2, rect1, rect1, render_pass_id, - mask_resource_id, gfx::RectF(), gfx::Size(), false, + mask_resource_id, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); EXPECT_EQ(1u, frame.render_pass_list.front()->quad_list.size()); @@ -2815,10 +2815,10 @@ rect4, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); R1->SetNew(shared_quad_state, rect1, rect1, render_pass_id, - mask_resource_id, gfx::RectF(), gfx::Size(), false, + mask_resource_id, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); R2->SetNew(shared_quad_state, rect2, rect2, render_pass_id, - mask_resource_id, gfx::RectF(), gfx::Size(), false, + mask_resource_id, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); D1->SetNew(shared_quad_state3, rect3, rect3, SK_ColorBLACK, false); D2->SetNew(shared_quad_state4, rect4, rect4, SK_ColorBLACK, false); @@ -2863,10 +2863,10 @@ rect6, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); R1->SetNew(shared_quad_state, rect5, rect5, render_pass_id, - mask_resource_id, gfx::RectF(), gfx::Size(), false, + mask_resource_id, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); R2->SetNew(shared_quad_state, rect1, rect1, render_pass_id, - mask_resource_id, gfx::RectF(), gfx::Size(), false, + mask_resource_id, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); D1->SetNew(shared_quad_state3, rect3, rect3, SK_ColorBLACK, false); D2->SetNew(shared_quad_state4, rect6, rect6, SK_ColorBLACK, false); @@ -2910,10 +2910,10 @@ rect7, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); R1->SetNew(shared_quad_state, rect5, rect5, render_pass_id, - mask_resource_id, gfx::RectF(), gfx::Size(), false, + mask_resource_id, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); R2->SetNew(shared_quad_state, rect1, rect1, render_pass_id, - mask_resource_id, gfx::RectF(), gfx::Size(), false, + mask_resource_id, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); D1->SetNew(shared_quad_state3, rect3, rect3, SK_ColorBLACK, false); D2->SetNew(shared_quad_state4, rect7, rect7, SK_ColorBLACK, false);
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index 8c67161c..e138b733 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc
@@ -982,72 +982,6 @@ paint.setImageFilter( SkiaHelper::BuildOpacityFilter(quad->shared_quad_state->opacity)); } - // Apply the mask image, if present, to filtered backdrop content. Note that - // this needs to be performed here, in addition to elsewhere, because of the - // order of operations: - // 1. Render the child render pass (containing backdrop-filtered element), - // including any masks, typically built as child DstIn layers. - // 2. Render the parent render pass (containing the "backdrop image" to be - // filtered). - // 3. Run this code, to filter, and possibly mask, the backdrop image. - sk_sp<const SkImage> mask_image = nullptr; - base::Optional<DisplayResourceProvider::ScopedReadLockSkImage> - backdrop_image_lock_sk; - base::Optional<DisplayResourceProvider::ScopedSamplerGL> - backdrop_image_lock_gl; - if (quad->mask_applies_to_backdrop && quad->mask_resource_id()) { - if (resource_provider_->GetResourceTextureTarget( - quad->mask_resource_id()) == GL_TEXTURE_RECTANGLE_ARB) { - // On some platforms, Skia doesn't know that the hardware supports - // GL_TEXTURE_RECTANGLE. So for texture rectangles, fall back to using - // CopyTextureCHROMIUM to copy from the mask resource to a newly-created - // texture, and then wrap that texture with an SkImage. - backdrop_image_lock_gl.emplace(resource_provider_, - quad->mask_resource_id(), GL_LINEAR); - GLenum source_id = backdrop_image_lock_gl->texture_id(); - GLint internalformat = GLInternalFormat( - resource_provider_->GetResourceFormat(quad->mask_resource_id())); - GLuint dest_id; - gl_->GenTextures(1, &dest_id); - gl_->BindTexture(GL_TEXTURE_2D, dest_id); - // Format is the same as internalformat for the formats being considered. - GLint format = internalformat; - gl_->TexImage2D(GL_TEXTURE_2D, 0, internalformat, - quad->mask_texture_size.width(), - quad->mask_texture_size.height(), 0, format, - GL_UNSIGNED_BYTE, nullptr); - gl_->CopyTextureCHROMIUM(source_id, 0, GL_TEXTURE_2D, dest_id, 0, - internalformat, GL_UNSIGNED_BYTE, - /*unpack_flip_y=*/false, - /*unpack_premultiply_alpha=*/false, - /*unpack_unmultiply_alpha=*/false); - mask_image = WrapTexture(dest_id, GL_TEXTURE_2D, quad->mask_texture_size, - use_gr_context->context(), - /*flip_texture=*/!FlippedFramebuffer(), - GlFormatToSkFormat(internalformat), - /*adopt_texture=*/true); - } else { - backdrop_image_lock_sk.emplace( - resource_provider_, quad->mask_resource_id(), kPremul_SkAlphaType, - kTopLeft_GrSurfaceOrigin); - mask_image = backdrop_image_lock_sk->TakeSkImage(); - } - DCHECK(mask_image); - } - if (mask_image) { - // Scale normalized uv rect into absolute texel coordinates. - SkRect mask_rect = gfx::RectFToSkRect( - gfx::ScaleRect(quad->mask_uv_rect, quad->mask_texture_size.width(), - quad->mask_texture_size.height())); - // Map to full quad rect so that mask coordinates don't change with - // clipping. - SkMatrix mask_to_quad_matrix = SkMatrix::MakeRectToRect( - mask_rect, gfx::RectToSkRect(quad->rect), SkMatrix::kFill_ScaleToFit); - paint.setMaskFilter( - SkShaderMaskFilter::Make(mask_image->makeShader(&mask_to_quad_matrix))); - DCHECK(paint.getMaskFilter()); - } - // Now paint the pre-filtered image onto the canvas (possibly with mask // applied). surface->getCanvas()->drawImageRect(filtered_image, subset, dest_rect, @@ -1246,9 +1180,8 @@ } } if (params->background_image_id) { - // Reset original background texture if there is not any mask, or if the - // mask was used for backdrop filter only. - if (!quad->mask_resource_id() || quad->mask_applies_to_backdrop) { + // Reset original background texture if there is not any mask. + if (!quad->mask_resource_id()) { gl_->DeleteTextures(1, ¶ms->background_texture); params->background_texture = 0; } @@ -1276,7 +1209,6 @@ if (params->background_texture && params->background_image_id) { DCHECK(params->mask_for_background); DCHECK(quad->mask_resource_id()); - DCHECK(!quad->mask_applies_to_backdrop); } DCHECK_EQ(params->background_texture || params->background_image_id, @@ -1377,8 +1309,7 @@ void GLRenderer::UpdateRPDQTexturesForSampling( DrawRenderPassDrawQuadParams* params) { - if (!params->quad->mask_applies_to_backdrop && - params->quad->mask_resource_id()) { + if (params->quad->mask_resource_id()) { params->mask_resource_lock.reset( new DisplayResourceProvider::ScopedSamplerGL( resource_provider_, params->quad->mask_resource_id(), GL_TEXTURE1,
diff --git a/components/viz/service/display/overlay_unittest.cc b/components/viz/service/display/overlay_unittest.cc index 74c2eca..aa340b5b 100644 --- a/components/viz/service/display/overlay_unittest.cc +++ b/components/viz/service/display/overlay_unittest.cc
@@ -1386,7 +1386,7 @@ RenderPassDrawQuad* quad = pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); quad->SetNew(pass->shared_quad_state_list.back(), kOverlayRect, kOverlayRect, - render_pass_id, 0, gfx::RectF(), gfx::Size(), false, + render_pass_id, 0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); CreateFullscreenCandidateQuad( @@ -2840,7 +2840,7 @@ auto* child_pass1_rpdq = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); child_pass1_rpdq->SetNew(child_pass1_sqs, unit_rect, unit_rect, - child_pass1_id, 0, gfx::RectF(), gfx::Size(), false, + child_pass1_id, 0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(), gfx::RectF(0, 0, 1, 1), false, 1.0f); @@ -2853,7 +2853,7 @@ auto* child_pass2_rpdq = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); child_pass2_rpdq->SetNew(child_pass2_sqs, unit_rect, unit_rect, - child_pass2_id, 0, gfx::RectF(), gfx::Size(), false, + child_pass2_id, 0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(), gfx::RectF(0, 0, 1, 1), false, 1.0f); @@ -3711,8 +3711,7 @@ TEST_F(CALayerOverlayRPDQTest, RenderPassDrawQuadNoFilters) { quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, kOverlayRect, render_pass_id_, 0, gfx::RectF(), gfx::Size(), - false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, - 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); ProcessForOverlays(); EXPECT_EQ(1U, ca_layer_list_.size()); @@ -3733,8 +3732,7 @@ render_pass_filters_[render_pass_id_] = &filters_; quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, kOverlayRect, render_pass_id_, 0, gfx::RectF(), gfx::Size(), - false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, - 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); ProcessForOverlays(); EXPECT_EQ(1U, ca_layer_list_.size()); @@ -3745,8 +3743,7 @@ render_pass_filters_[render_pass_id_] = &filters_; quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, kOverlayRect, render_pass_id_, 0, gfx::RectF(), gfx::Size(), - false, gfx::Vector2dF(1, 2), gfx::PointF(), gfx::RectF(), false, - 1.0f); + gfx::Vector2dF(1, 2), gfx::PointF(), gfx::RectF(), false, 1.0f); ProcessForOverlays(); EXPECT_EQ(1U, ca_layer_list_.size()); } @@ -3756,8 +3753,7 @@ render_pass_filters_[render_pass_id_] = &filters_; quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, kOverlayRect, render_pass_id_, 0, gfx::RectF(), gfx::Size(), - false, gfx::Vector2dF(1, 2), gfx::PointF(), gfx::RectF(), false, - 1.0f); + gfx::Vector2dF(1, 2), gfx::PointF(), gfx::RectF(), false, 1.0f); ProcessForOverlays(); EXPECT_EQ(1U, ca_layer_list_.size()); } @@ -3768,8 +3764,7 @@ render_pass_filters_[render_pass_id_] = &filters_; quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, kOverlayRect, render_pass_id_, 0, gfx::RectF(), gfx::Size(), - false, gfx::Vector2dF(1, 2), gfx::PointF(), gfx::RectF(), false, - 1.0f); + gfx::Vector2dF(1, 2), gfx::PointF(), gfx::RectF(), false, 1.0f); ProcessForOverlays(); EXPECT_EQ(1U, ca_layer_list_.size()); } @@ -3779,19 +3774,7 @@ render_pass_backdrop_filters_[render_pass_id_] = &backdrop_filters_; quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, kOverlayRect, render_pass_id_, 0, gfx::RectF(), gfx::Size(), - false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, - 1.0f); - ProcessForOverlays(); - EXPECT_EQ(0U, ca_layer_list_.size()); -} - -TEST_F(CALayerOverlayRPDQTest, RenderPassDrawQuadBackgroundFilterWithMask) { - backdrop_filters_.Append(cc::FilterOperation::CreateGrayscaleFilter(0.1f)); - render_pass_backdrop_filters_[render_pass_id_] = &backdrop_filters_; - quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, - kOverlayRect, render_pass_id_, 2, gfx::RectF(), gfx::Size(), - true, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, - 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); ProcessForOverlays(); EXPECT_EQ(0U, ca_layer_list_.size()); } @@ -3799,8 +3782,7 @@ TEST_F(CALayerOverlayRPDQTest, RenderPassDrawQuadMask) { quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, kOverlayRect, render_pass_id_, 2, gfx::RectF(), gfx::Size(), - false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, - 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); ProcessForOverlays(); EXPECT_EQ(1U, ca_layer_list_.size()); } @@ -3810,8 +3792,7 @@ render_pass_filters_[render_pass_id_] = &filters_; quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, kOverlayRect, render_pass_id_, 0, gfx::RectF(), gfx::Size(), - false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, - 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); ProcessForOverlays(); EXPECT_EQ(0U, ca_layer_list_.size()); } @@ -3824,8 +3805,8 @@ auto* quad = pass_->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); quad->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, kOverlayRect, render_pass_id_, 2, gfx::RectF(), gfx::Size(), - false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), - false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); } ProcessForOverlays();
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index e86e5ea..62b35741 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -182,7 +182,6 @@ 0, // mask_resource_id gfx::RectF(), // mask_uv_rect gfx::Size(), // mask_texture_size - false, // mask_applies_to_backdrop gfx::Vector2dF(), // filters scale gfx::PointF(), // filter origin gfx::RectF(rect), // tex_coord_rect @@ -2086,7 +2085,7 @@ auto* render_pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); render_pass_quad->SetNew(pass_shared_state, pass_rect, pass_rect, - child_pass_id, 0, gfx::RectF(), gfx::Size(), false, + child_pass_id, 0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(), gfx::RectF(pass_rect), false, 1.0f); @@ -2146,7 +2145,7 @@ auto* render_pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); render_pass_quad->SetNew(pass_shared_state, pass_rect, pass_rect, - child_pass_id, 0, gfx::RectF(), gfx::Size(), false, + child_pass_id, 0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(), gfx::RectF(pass_rect), false, 1.0f); @@ -2207,7 +2206,7 @@ auto* render_pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); render_pass_quad->SetNew(pass_shared_state, pass_rect, pass_rect, - child_pass_id, 0, gfx::RectF(), gfx::Size(), false, + child_pass_id, 0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(), gfx::RectF(pass_rect), false, 1.0f); @@ -2289,7 +2288,7 @@ auto* render_pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); render_pass_quad->SetNew(pass_shared_state, pass_rect, pass_rect, - child_pass_id, 0, gfx::RectF(), gfx::Size(), false, + child_pass_id, 0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(), gfx::RectF(pass_rect), false, 1.0f); @@ -2481,7 +2480,6 @@ gfx::ScaleRect(gfx::RectF(sub_rect), 2.f / mask_rect.width(), 2.f / mask_rect.height()), // mask_uv_rect gfx::Size(mask_rect.size()), // mask_texture_size - false, // mask_applies_to_backdrop gfx::Vector2dF(), // filters scale gfx::PointF(), // filter origin gfx::RectF(sub_rect), // tex_coord_rect @@ -2579,7 +2577,6 @@ gfx::ScaleRect(gfx::RectF(sub_rect), 2.f / mask_rect.width(), 2.f / mask_rect.height()), // mask_uv_rect gfx::Size(mask_rect.size()), // mask_texture_size - false, // mask_applies_to_backdrop gfx::Vector2dF(), // filters scale gfx::PointF(), // filter origin gfx::RectF(sub_rect), // tex_coord_rect @@ -2665,7 +2662,6 @@ 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 - false, // mask_applies_to_backdrop gfx::Vector2dF(), // filters scale gfx::PointF(), // filter origin gfx::RectF(viewport_rect), // tex_coord_rect @@ -2770,7 +2766,6 @@ 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 - false, // mask_applies_to_backdrop gfx::Vector2dF(), // filters scale gfx::PointF(), // filter origin gfx::RectF(viewport_rect), // tex_coord_rect @@ -2888,7 +2883,6 @@ filter_pass_layer_rect_, filter_pass_id, mapped_mask_resource_id, mask_uv_rect, mask_texture_size, - true, // mask_applies_to_backdrop gfx::Vector2dF(1.0f, 1.0f), // filters_scale gfx::PointF(), // filters_origin gfx::RectF(), // tex_coord_rect @@ -3304,7 +3298,7 @@ RenderPassDrawQuad* pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); pass_quad->SetAll(pass_shared_state, rect, rect, needs_blending, - child_pass_id, 0, gfx::RectF(), gfx::Size(), false, + child_pass_id, 0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(), gfx::RectF(rect), force_anti_aliasing_off, backdrop_filter_quality); @@ -3468,7 +3462,7 @@ root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); child_pass_quad->SetNew(child_pass_shared_state, child_pass_rect, child_pass_rect, child_pass_id, 0, gfx::RectF(), - gfx::Size(), false, gfx::Vector2dF(), gfx::PointF(), + gfx::Size(), gfx::Vector2dF(), gfx::PointF(), gfx::RectF(child_pass_rect), false, 1.0f); RenderPassList pass_list;
diff --git a/components/viz/service/display/software_renderer.cc b/components/viz/service/display/software_renderer.cc index e9ed3923..1f01fbe 100644 --- a/components/viz/service/display/software_renderer.cc +++ b/components/viz/service/display/software_renderer.cc
@@ -522,7 +522,7 @@ &content_mat); } - if (!quad->mask_applies_to_backdrop && quad->mask_resource_id()) { + if (quad->mask_resource_id()) { DisplayResourceProvider::ScopedReadLockSkImage mask_lock( resource_provider_, quad->mask_resource_id()); if (!mask_lock.valid()) @@ -849,35 +849,6 @@ SkiaHelper::BuildOpacityFilter(quad->shared_quad_state->opacity)); } - // Apply the mask image, if present, to filtered backdrop content. Note that - // this needs to be performed here, in addition to elsewhere, because of the - // order of operations: - // 1. Render the child render pass (containing backdrop-filtered element), - // including any masks, typically built as child DstIn layers. - // 2. Render the parent render pass (containing the "backdrop image" to be - // filtered). - // 3. Run this code, to filter, and possibly mask, the backdrop image. - const SkImage* mask_image = nullptr; - base::Optional<DisplayResourceProvider::ScopedReadLockSkImage> - backdrop_image_lock; - if (quad->mask_applies_to_backdrop && quad->mask_resource_id()) { - backdrop_image_lock.emplace(resource_provider_, quad->mask_resource_id()); - mask_image = backdrop_image_lock->sk_image(); - } - if (mask_image) { - // Scale normalized uv rect into absolute texel coordinates. - SkRect mask_rect = gfx::RectFToSkRect( - gfx::ScaleRect(quad->mask_uv_rect, quad->mask_texture_size.width(), - quad->mask_texture_size.height())); - // Map to full quad rect so that mask coordinates don't change with - // clipping. - SkMatrix mask_to_quad_matrix = SkMatrix::MakeRectToRect( - mask_rect, gfx::RectToSkRect(quad->rect), SkMatrix::kFill_ScaleToFit); - paint.setMaskFilter( - SkShaderMaskFilter::Make(mask_image->makeShader(&mask_to_quad_matrix))); - DCHECK(paint.getMaskFilter()); - } - // Now paint the pre-filtered image onto the canvas. SkRect src_rect = SkRect::MakeXYWH(0, 0, backdrop_bitmap.width(), backdrop_bitmap.height());
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc index bac5070..d2a50d2 100644 --- a/components/viz/service/display/surface_aggregator.cc +++ b/components/viz/service/display/surface_aggregator.cc
@@ -668,8 +668,7 @@ RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id); quad->SetNew(shared_quad_state, scaled_rect, scaled_visible_rect, remapped_pass_id, 0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(), - gfx::PointF(), gfx::RectF(scaled_rect), + gfx::Vector2dF(), gfx::PointF(), gfx::RectF(scaled_rect), /*force_anti_aliasing_off=*/false, /* backdrop_filter_quality*/ 1.0f); } @@ -800,8 +799,7 @@ color_conversion_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); quad->SetNew(shared_quad_state, output_rect, output_rect, root_render_pass->id, 0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(), - gfx::PointF(), gfx::RectF(output_rect), + gfx::Vector2dF(), gfx::PointF(), gfx::RectF(output_rect), /*force_anti_aliasing_off=*/false, /*backdrop_filter_quality*/ 1.0f); dest_pass_list_->push_back(std::move(color_conversion_pass)); @@ -851,8 +849,7 @@ display_transform_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); quad->SetNew(shared_quad_state, output_rect, output_rect, root_render_pass->id, 0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(), - gfx::PointF(), gfx::RectF(output_rect), + gfx::Vector2dF(), gfx::PointF(), gfx::RectF(output_rect), /*force_anti_aliasing_off=*/false, /*backdrop_filter_quality*/ 1.0f); dest_pass_list_->push_back(std::move(display_transform_pass));
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc index 9a766f0..f0363a8c 100644 --- a/components/viz/service/display/surface_aggregator_unittest.cc +++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -383,8 +383,8 @@ 0); auto* quad = pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); quad->SetNew(shared_state, output_rect, output_rect, render_pass_id, 0, - gfx::RectF(), gfx::Size(), false, gfx::Vector2dF(), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(), + gfx::RectF(), false, 1.0f); } static void AddYUVVideoQuad(RenderPass* pass, const gfx::Rect& output_rect) {
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc index 0f910e3..7c845f5 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
@@ -280,22 +280,22 @@ quad5_root_1->SetNew(shared_quad_state5_root, /*rect=*/rect5_root, /*visible_rect=*/rect5_root, /*render_pass_id=*/2, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); auto* quad5_root_2 = pass5_root->quad_list.AllocateAndConstruct<RenderPassDrawQuad>(); quad5_root_2->SetNew(shared_quad_state5_root, /*rect=*/rect5_root, /*visible_rect=*/rect5_root, /*render_pass_id=*/3, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); auto* quad5_root_3 = pass5_root->quad_list.AllocateAndConstruct<RenderPassDrawQuad>(); quad5_root_3->SetNew(shared_quad_state5_root, /*rect=*/rect5_root, /*visible_rect=*/rect5_root, /*render_pass_id=*/4, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); pass_list.push_back(std::move(pass5_root)); SendRenderPassList(&pass_list); @@ -439,7 +439,6 @@ quad3_root_1->SetNew(shared_quad_state3_root, /*rect=*/rect3_root, /*visible_rect=*/rect3_root, /*render_pass_id=*/3, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); auto* quad3_root_2 = @@ -447,7 +446,6 @@ quad3_root_2->SetNew(shared_quad_state3_root, /*rect=*/rect3_root, /*visible_rect=*/rect3_root, /*render_pass_id=*/4, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); pass_list.push_back(std::move(pass3_root)); @@ -516,7 +514,6 @@ quad4_root_1->SetNew(shared_quad_state4_root, /*rect=*/rect4_root, /*visible_rect=*/rect4_root, /*render_pass_id=*/5, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); auto* quad4_root_2 = @@ -524,7 +521,6 @@ quad4_root_2->SetNew(shared_quad_state4_root, /*rect=*/rect4_root, /*visible_rect=*/rect4_root, /*render_pass_id=*/6, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); pass_list.push_back(std::move(pass4_root)); @@ -595,7 +591,6 @@ quad5_root_1->SetNew(shared_quad_state5_root, /*rect=*/rect5_root, /*visible_rect=*/rect5_root, /*render_pass_id=*/7, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); auto* quad5_root_2 = @@ -603,7 +598,6 @@ quad5_root_2->SetNew(shared_quad_state5_root, /*rect=*/rect5_root, /*visible_rect=*/rect5_root, /*render_pass_id=*/8, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); pass_list.push_back(std::move(pass5_root)); @@ -675,7 +669,6 @@ quad6_root_1->SetNew(shared_quad_state6_root, /*rect=*/rect6_root, /*visible_rect=*/rect6_root, /*render_pass_id=*/9, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); auto* quad6_root_2 = @@ -683,7 +676,6 @@ quad6_root_2->SetNew(shared_quad_state6_root, /*rect=*/rect6_root, /*visible_rect=*/rect6_root, /*render_pass_id=*/10, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); pass_list.push_back(std::move(pass6_root));
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index bc086ef..b1cf940 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -417,7 +417,7 @@ // Gets the text offsets where new lines start. std::vector<int> GetLineStartOffsets() const; - virtual gfx::NativeViewAccessible GetNativeViewAccessible(); + gfx::NativeViewAccessible GetNativeViewAccessible() override; // AXPosition Support
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index 62f17dc..e76ed011 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -3116,6 +3116,7 @@ NSAccessibilityStartTextMarkerAttribute, NSAccessibilitySubroleAttribute, NSAccessibilityTitleAttribute, + NSAccessibilityTitleUIElementAttribute, NSAccessibilityTopLevelUIElementAttribute, NSAccessibilityValueAttribute, NSAccessibilityVisitedAttribute,
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index 0a11baa..a6ddde7 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -51,14 +51,13 @@ switches::kUseFakeUIForMediaStream); base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kIgnoreCertificateErrors); - feature_list_.InitWithFeatures(FeaturesToEnable(), {}); + feature_list_.InitAndEnableFeatureWithParameters( + features::kBackForwardCache, GetFeatureParams()); ContentBrowserTest::SetUpCommandLine(command_line); } - virtual std::vector<base::Feature> FeaturesToEnable() { - return std::vector<base::Feature>({features::kBackForwardCache}); - } + virtual base::FieldTrialParams GetFeatureParams() { return {}; } void SetUpOnMainThread() override { host_resolver()->AddRule("*", "127.0.0.1"); @@ -1828,11 +1827,8 @@ ~BackForwardCacheBrowserTestWithServiceWorkerEnabled() override {} protected: - std::vector<base::Feature> FeaturesToEnable() override { - std::vector<base::Feature> result = - BackForwardCacheBrowserTest::FeaturesToEnable(); - result.push_back(kBackForwardCacheWithServiceWorker); - return result; + base::FieldTrialParams GetFeatureParams() override { + return {{"service_worker_supported", "true"}}; } };
diff --git a/content/browser/frame_host/back_forward_cache.cc b/content/browser/frame_host/back_forward_cache.cc index 3d67b7cc..90b7294 100644 --- a/content/browser/frame_host/back_forward_cache.cc +++ b/content/browser/frame_host/back_forward_cache.cc
@@ -11,6 +11,7 @@ #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/common/page_messages.h" +#include "content/public/common/content_features.h" #include "content/public/common/navigation_policy.h" #include "net/http/http_status_code.h" #include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h" @@ -91,6 +92,12 @@ return true; } +bool IsServiceWorkerSupported() { + static constexpr base::FeatureParam<bool> service_worker_supported( + &features::kBackForwardCache, "service_worker_supported", false); + return service_worker_supported.Get(); +} + uint64_t GetDisallowedFeatures() { // TODO(lowell): Finalize disallowed feature list, and test for each // disallowed feature. @@ -120,7 +127,7 @@ uint64_t result = kAlwaysDisallowedFeatures; - if (!base::FeatureList::IsEnabled(kBackForwardCacheWithServiceWorker)) { + if (!IsServiceWorkerSupported()) { result |= ToFeatureBit(WebSchedulerTrackedFeature::kServiceWorkerControlledPage); } @@ -129,9 +136,6 @@ } // namespace -const base::Feature kBackForwardCacheWithServiceWorker = { - "BackForwardCacheWithServiceWorker", base::FEATURE_DISABLED_BY_DEFAULT}; - BackForwardCache::BackForwardCache() : weak_factory_(this) {} BackForwardCache::~BackForwardCache() = default;
diff --git a/content/browser/frame_host/back_forward_cache.h b/content/browser/frame_host/back_forward_cache.h index a23765df..af4e448 100644 --- a/content/browser/frame_host/back_forward_cache.h +++ b/content/browser/frame_host/back_forward_cache.h
@@ -147,12 +147,6 @@ DISALLOW_COPY_AND_ASSIGN(BackForwardCache); }; -// TODO(crbug.com/991082): We need to implement frozen frame enumeration -// before we can properly support pages with ServiceWorker in back-forward -// cache. This flag allows to bypass this restriction for local testing. -// Remove after ServiceWorker support is implemented. -CONTENT_EXPORT extern const base::Feature kBackForwardCacheWithServiceWorker; - } // namespace content #endif // CONTENT_BROWSER_FRAME_HOST_BACK_FORWARD_CACHE_H_
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 7ae9b631e..591e39e 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -487,10 +487,7 @@ const std::string& interface_name, mojo::ScopedMessagePipeHandle* interface_pipe, service_manager::Connector* connector) override { - if (!registry_.TryBindInterface(interface_name, interface_pipe)) { - GetContentClient()->browser()->BindInterfaceRequest( - source_info, interface_name, interface_pipe); - } + registry_.TryBindInterface(interface_name, interface_pipe); } service_manager::BinderRegistry registry_; @@ -619,7 +616,11 @@ base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&FieldTrialRecorder::Create, std::move(receiver))); + return; } + + GetContentClient()->browser()->BindGpuHostReceiver( + std::move(generic_receiver)); } void GpuProcessHost::RunService(
diff --git a/content/browser/snapshot_browsertest.cc b/content/browser/snapshot_browsertest.cc index 3a190a62..4e2c122 100644 --- a/content/browser/snapshot_browsertest.cc +++ b/content/browser/snapshot_browsertest.cc
@@ -320,13 +320,6 @@ } IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_AsyncMultiWindowTest) { - // TODO(jonross): Re-enable this once the root cause of the failure has been - // fixed. https://crbug.com/1003375 - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kUseVulkan)) - return; - SetupTestServer(); for (int i = 0; i < 3; ++i) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index a9131e7..c021a78c 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -115,7 +115,6 @@ namespace service_manager { class Identity; class Service; -struct BindSourceInfo; } namespace net { @@ -967,14 +966,9 @@ const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) {} - // (Currently called only from GPUProcessHost, move somewhere more central). - // Called when a request to bind |interface_name| on |interface_pipe| is - // received from |source_info.identity|. If the request is bound, - // |interface_pipe| will become invalid (taken by the client). - virtual void BindInterfaceRequest( - const service_manager::BindSourceInfo& source_info, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle* interface_pipe) {} + // Handles an unhandled incoming interface binding request from the GPU + // process. Called on the IO thread. + virtual void BindGpuHostReceiver(mojo::GenericPendingReceiver receiver) {} // Called on the main thread to handle an unhandled interface receiver binding // request from a render process. See |RenderThread::BindHostReceiver()|.
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 7a098ee..26a7850 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -1479,12 +1479,14 @@ render_view->GetWidget(), web_frame); render_widget->Init(std::move(show_callback), web_frame_widget); - render_view->AttachWebFrameWidget(web_frame_widget); - // TODO(crbug.com/419087): This was added in 6ccadf770766e89c3 to prevent an - // empty ScreenInfo, but the WebView has already been created and initialized - // by RenderViewImpl, so this is surely redundant? + + // This call makes sure the page zoom is propagated to the provisional frame + // since it has to go through the WebViewImpl, and it may not be be changed + // in OnSynchronizeVisualProperties(), which would pass it along if it did + // change. render_widget->UpdateWebViewWithDeviceScaleFactor(); + render_widget->OnSynchronizeVisualProperties(params->visual_properties); // The WebFrame created here was already attached to the Page as its // main frame, and the WebFrameWidget has been initialized, so we can call
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 6e9a34c..1ed4369a 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -534,9 +534,7 @@ if (params->window_was_created_with_opener) webview()->SetOpenedByDOM(); - GetWidget()->UpdateWebViewWithDeviceScaleFactor(); OnSetRendererPrefs(*params->renderer_preferences); - GetWidget()->OnSynchronizeVisualProperties(params->visual_properties); GetContentClient()->renderer()->RenderViewCreated(this); page_zoom_level_ = 0;
diff --git a/content/test/content_test_launcher.cc b/content/test/content_test_launcher.cc index 7fd5bcb2..37aec6f6 100644 --- a/content/test/content_test_launcher.cc +++ b/content/test/content_test_launcher.cc
@@ -39,10 +39,9 @@ protected: void Initialize() override { - // Browser tests are expected not to tear-down various globals and may - // complete with the thread priority being above NORMAL. + // Browser tests are expected not to tear-down various globals. (Must run + // before the base class is initialized.) base::TestSuite::DisableCheckForLeakedGlobals(); - base::TestSuite::DisableCheckForThreadPriorityAtTestEnd(); ContentTestSuiteBase::Initialize();
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt index bc395e6..052ca8c 100644 --- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -29,7 +29,7 @@ [ android ] Pixel_Canvas2DTabSwitch_SoftwareCompositing [ Skip ] # Skip tab switching tests on Android webview since it doesn't have tabs -[ android-webview-instrumentation ] Pixel_Canvas2DTabSwitch [ Skip ] +[ android android-webview-instrumentation ] Pixel_Canvas2DTabSwitch [ Skip ] # Tests running with SwiftShader are skipped on platforms where SwiftShader # isn't supported. @@ -187,6 +187,13 @@ # Fails on Intel crbug.com/991289 [ linux skia-renderer intel ] Pixel_CSS3DBlueBox [ Skip ] +# Fails when the browser features SkiaRenderer & Vulkan are enabled on Intel +crbug.com/1004837 [ linux skia-renderer use-vulkan intel ] Pixel_Canvas2DRedBox [ Skip ] +crbug.com/1004837 [ linux skia-renderer use-vulkan intel ] Pixel_Canvas2DTabSwitch [ Skip ] +crbug.com/1004840 [ linux skia-renderer use-vulkan intel ] Pixel_WebGLGreenTriangle_AA_Alpha [ Skip ] +crbug.com/1004840 [ linux skia-renderer use-vulkan intel ] Pixel_WebGLGreenTriangle_AA_NoAlpha [ Skip ] +crbug.com/1004840 [ linux skia-renderer use-vulkan intel ] Pixel_WebGLGreenTriangle_NoAA_NoAlpha [ Skip ] + # Fails when the browser features SkiaRenderer & Vulkan are enabled on Android crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_2DCanvasWebGL [ Failure ] crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_BackgroundImage [ Skip ]
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn index 5dfd6535..7dcfcd0 100644 --- a/device/bluetooth/BUILD.gn +++ b/device/bluetooth/BUILD.gn
@@ -522,7 +522,9 @@ java_files = java_sources_needing_jni deps = [ "//base:base_java", + "//base:jni_java", "//components/location/android:location_java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] } }
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java index b6067bfb..d106844 100644 --- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java +++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java
@@ -19,6 +19,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNIAdditionalImport; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import org.chromium.components.location.LocationUtils; import java.util.List; @@ -288,7 +289,8 @@ // Object can be destroyed, but Android keeps calling onScanResult. if (mNativeBluetoothAdapterAndroid != 0) { - nativeCreateOrUpdateDeviceOnScan(mNativeBluetoothAdapterAndroid, + ChromeBluetoothAdapterJni.get().createOrUpdateDeviceOnScan( + mNativeBluetoothAdapterAndroid, ChromeBluetoothAdapter.this, result.getDevice().getAddress(), result.getDevice(), result.getScanRecord_getDeviceName(), result.getRssi(), uuid_strings, result.getScanRecord_getTxPowerLevel(), serviceDataKeys, serviceDataValues, @@ -299,7 +301,8 @@ @Override public void onScanFailed(int errorCode) { Log.w(TAG, "onScanFailed: %d", errorCode); - nativeOnScanFailed(mNativeBluetoothAdapterAndroid); + ChromeBluetoothAdapterJni.get().onScanFailed( + mNativeBluetoothAdapterAndroid, ChromeBluetoothAdapter.this); } } @@ -315,10 +318,12 @@ switch (state) { case BluetoothAdapter.STATE_ON: - nativeOnAdapterStateChanged(mNativeBluetoothAdapterAndroid, true); + ChromeBluetoothAdapterJni.get().onAdapterStateChanged( + mNativeBluetoothAdapterAndroid, ChromeBluetoothAdapter.this, true); break; case BluetoothAdapter.STATE_OFF: - nativeOnAdapterStateChanged(mNativeBluetoothAdapterAndroid, false); + ChromeBluetoothAdapterJni.get().onAdapterStateChanged( + mNativeBluetoothAdapterAndroid, ChromeBluetoothAdapter.this, false); break; default: // do nothing @@ -342,20 +347,21 @@ } } - // --------------------------------------------------------------------------------------------- - // BluetoothAdapterAndroid C++ methods declared for access from java: + @NativeMethods + interface Natives { + // Binds to BluetoothAdapterAndroid::OnScanFailed. + void onScanFailed(long nativeBluetoothAdapterAndroid, ChromeBluetoothAdapter caller); - // Binds to BluetoothAdapterAndroid::OnScanFailed. - private native void nativeOnScanFailed(long nativeBluetoothAdapterAndroid); + // Binds to BluetoothAdapterAndroid::CreateOrUpdateDeviceOnScan. + void createOrUpdateDeviceOnScan(long nativeBluetoothAdapterAndroid, + ChromeBluetoothAdapter caller, String address, + Wrappers.BluetoothDeviceWrapper deviceWrapper, String localName, int rssi, + String[] advertisedUuids, int txPower, String[] serviceDataKeys, + Object[] serviceDataValues, int[] manufacturerDataKeys, + Object[] manufacturerDataValues); - // Binds to BluetoothAdapterAndroid::CreateOrUpdateDeviceOnScan. - private native void nativeCreateOrUpdateDeviceOnScan(long nativeBluetoothAdapterAndroid, - String address, Wrappers.BluetoothDeviceWrapper deviceWrapper, String localName, - int rssi, String[] advertisedUuids, int txPower, String[] serviceDataKeys, - Object[] serviceDataValues, int[] manufacturerDataKeys, - Object[] manufacturerDataValues); - - // Binds to BluetoothAdapterAndroid::nativeOnAdapterStateChanged - private native void nativeOnAdapterStateChanged( - long nativeBluetoothAdapterAndroid, boolean powered); + // Binds to BluetoothAdapterAndroid::nativeOnAdapterStateChanged + void onAdapterStateChanged( + long nativeBluetoothAdapterAndroid, ChromeBluetoothAdapter caller, boolean powered); + } }
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java index da726ec8..e134b66 100644 --- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java +++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java
@@ -13,6 +13,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNIAdditionalImport; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import org.chromium.base.metrics.RecordHistogram; import java.util.HashMap; @@ -149,7 +150,8 @@ status); } if (mNativeBluetoothDeviceAndroid != 0) { - nativeOnConnectionStateChange(mNativeBluetoothDeviceAndroid, status, + ChromeBluetoothDeviceJni.get().onConnectionStateChange( + mNativeBluetoothDeviceAndroid, ChromeBluetoothDevice.this, status, newState == android.bluetooth.BluetoothProfile.STATE_CONNECTED); } } @@ -185,10 +187,12 @@ // between service instances with the same UUID on this device. String serviceInstanceId = getAddress() + "/" + service.getUuid().toString() + "," + service.getInstanceId(); - nativeCreateGattRemoteService( - mNativeBluetoothDeviceAndroid, serviceInstanceId, service); + ChromeBluetoothDeviceJni.get().createGattRemoteService( + mNativeBluetoothDeviceAndroid, ChromeBluetoothDevice.this, + serviceInstanceId, service); } - nativeOnGattServicesDiscovered(mNativeBluetoothDeviceAndroid); + ChromeBluetoothDeviceJni.get().onGattServicesDiscovered( + mNativeBluetoothDeviceAndroid, ChromeBluetoothDevice.this); } } }); @@ -304,17 +308,19 @@ } } - // --------------------------------------------------------------------------------------------- - // BluetoothAdapterDevice C++ methods declared for access from java: + @NativeMethods + interface Natives { + // Binds to BluetoothDeviceAndroid::OnConnectionStateChange. + void onConnectionStateChange(long nativeBluetoothDeviceAndroid, + ChromeBluetoothDevice caller, int status, boolean connected); - // Binds to BluetoothDeviceAndroid::OnConnectionStateChange. - private native void nativeOnConnectionStateChange( - long nativeBluetoothDeviceAndroid, int status, boolean connected); + // Binds to BluetoothDeviceAndroid::CreateGattRemoteService. + void createGattRemoteService(long nativeBluetoothDeviceAndroid, + ChromeBluetoothDevice caller, String instanceId, + Wrappers.BluetoothGattServiceWrapper serviceWrapper); - // Binds to BluetoothDeviceAndroid::CreateGattRemoteService. - private native void nativeCreateGattRemoteService(long nativeBluetoothDeviceAndroid, - String instanceId, Wrappers.BluetoothGattServiceWrapper serviceWrapper); - - // Binds to BluetoothDeviceAndroid::GattServicesDiscovered. - private native void nativeOnGattServicesDiscovered(long nativeBluetoothDeviceAndroid); + // Binds to BluetoothDeviceAndroid::GattServicesDiscovered. + void onGattServicesDiscovered( + long nativeBluetoothDeviceAndroid, ChromeBluetoothDevice caller); + } }
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattCharacteristic.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattCharacteristic.java index 06b63aaa..41344a1 100644 --- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattCharacteristic.java +++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattCharacteristic.java
@@ -11,6 +11,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNIAdditionalImport; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import java.util.List; @@ -63,7 +64,9 @@ void onCharacteristicChanged(byte[] value) { Log.i(TAG, "onCharacteristicChanged"); if (mNativeBluetoothRemoteGattCharacteristicAndroid != 0) { - nativeOnChanged(mNativeBluetoothRemoteGattCharacteristicAndroid, value); + ChromeBluetoothRemoteGattCharacteristicJni.get().onChanged( + mNativeBluetoothRemoteGattCharacteristicAndroid, + ChromeBluetoothRemoteGattCharacteristic.this, value); } } @@ -71,7 +74,9 @@ Log.i(TAG, "onCharacteristicRead status:%d==%s", status, status == android.bluetooth.BluetoothGatt.GATT_SUCCESS ? "OK" : "Error"); if (mNativeBluetoothRemoteGattCharacteristicAndroid != 0) { - nativeOnRead(mNativeBluetoothRemoteGattCharacteristicAndroid, status, + ChromeBluetoothRemoteGattCharacteristicJni.get().onRead( + mNativeBluetoothRemoteGattCharacteristicAndroid, + ChromeBluetoothRemoteGattCharacteristic.this, status, mCharacteristic.getValue()); } } @@ -80,7 +85,9 @@ Log.i(TAG, "onCharacteristicWrite status:%d==%s", status, status == android.bluetooth.BluetoothGatt.GATT_SUCCESS ? "OK" : "Error"); if (mNativeBluetoothRemoteGattCharacteristicAndroid != 0) { - nativeOnWrite(mNativeBluetoothRemoteGattCharacteristicAndroid, status); + ChromeBluetoothRemoteGattCharacteristicJni.get().onWrite( + mNativeBluetoothRemoteGattCharacteristicAndroid, + ChromeBluetoothRemoteGattCharacteristic.this, status); } } @@ -156,27 +163,31 @@ for (Wrappers.BluetoothGattDescriptorWrapper descriptor : descriptors) { String descriptorInstanceId = mInstanceId + "/" + descriptor.getUuid().toString() + ";" + instanceIdCounter++; - nativeCreateGattRemoteDescriptor(mNativeBluetoothRemoteGattCharacteristicAndroid, - descriptorInstanceId, descriptor, mChromeDevice); + ChromeBluetoothRemoteGattCharacteristicJni.get().createGattRemoteDescriptor( + mNativeBluetoothRemoteGattCharacteristicAndroid, + ChromeBluetoothRemoteGattCharacteristic.this, descriptorInstanceId, descriptor, + mChromeDevice); } } - // --------------------------------------------------------------------------------------------- - // BluetoothAdapterDevice C++ methods declared for access from java: + @NativeMethods + interface Natives { + // Binds to BluetoothRemoteGattCharacteristicAndroid::OnChanged. + void onChanged(long nativeBluetoothRemoteGattCharacteristicAndroid, + ChromeBluetoothRemoteGattCharacteristic caller, byte[] value); - // Binds to BluetoothRemoteGattCharacteristicAndroid::OnChanged. - native void nativeOnChanged(long nativeBluetoothRemoteGattCharacteristicAndroid, byte[] value); + // Binds to BluetoothRemoteGattCharacteristicAndroid::OnRead. + void onRead(long nativeBluetoothRemoteGattCharacteristicAndroid, + ChromeBluetoothRemoteGattCharacteristic caller, int status, byte[] value); - // Binds to BluetoothRemoteGattCharacteristicAndroid::OnRead. - native void nativeOnRead( - long nativeBluetoothRemoteGattCharacteristicAndroid, int status, byte[] value); + // Binds to BluetoothRemoteGattCharacteristicAndroid::OnWrite. + void onWrite(long nativeBluetoothRemoteGattCharacteristicAndroid, + ChromeBluetoothRemoteGattCharacteristic caller, int status); - // Binds to BluetoothRemoteGattCharacteristicAndroid::OnWrite. - native void nativeOnWrite(long nativeBluetoothRemoteGattCharacteristicAndroid, int status); - - // Binds to BluetoothRemoteGattCharacteristicAndroid::CreateGattRemoteDescriptor. - private native void nativeCreateGattRemoteDescriptor( - long nativeBluetoothRemoteGattCharacteristicAndroid, String instanceId, - Wrappers.BluetoothGattDescriptorWrapper descriptorWrapper, - ChromeBluetoothDevice chromeBluetoothDevice); + // Binds to BluetoothRemoteGattCharacteristicAndroid::CreateGattRemoteDescriptor. + void createGattRemoteDescriptor(long nativeBluetoothRemoteGattCharacteristicAndroid, + ChromeBluetoothRemoteGattCharacteristic caller, String instanceId, + Wrappers.BluetoothGattDescriptorWrapper descriptorWrapper, + ChromeBluetoothDevice chromeBluetoothDevice); + } }
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattDescriptor.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattDescriptor.java index a90608b..4214c428 100644 --- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattDescriptor.java +++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattDescriptor.java
@@ -8,6 +8,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNIAdditionalImport; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; /** * Exposes android.bluetooth.BluetoothGattDescriptor as necessary @@ -50,8 +51,9 @@ Log.i(TAG, "onDescriptorRead status:%d==%s", status, status == android.bluetooth.BluetoothGatt.GATT_SUCCESS ? "OK" : "Error"); if (mNativeBluetoothRemoteGattDescriptorAndroid != 0) { - nativeOnRead( - mNativeBluetoothRemoteGattDescriptorAndroid, status, mDescriptor.getValue()); + ChromeBluetoothRemoteGattDescriptorJni.get().onRead( + mNativeBluetoothRemoteGattDescriptorAndroid, + ChromeBluetoothRemoteGattDescriptor.this, status, mDescriptor.getValue()); } } @@ -59,7 +61,9 @@ Log.i(TAG, "onDescriptorWrite status:%d==%s", status, status == android.bluetooth.BluetoothGatt.GATT_SUCCESS ? "OK" : "Error"); if (mNativeBluetoothRemoteGattDescriptorAndroid != 0) { - nativeOnWrite(mNativeBluetoothRemoteGattDescriptorAndroid, status); + ChromeBluetoothRemoteGattDescriptorJni.get().onWrite( + mNativeBluetoothRemoteGattDescriptorAndroid, + ChromeBluetoothRemoteGattDescriptor.this, status); } } @@ -106,13 +110,14 @@ return true; } - // --------------------------------------------------------------------------------------------- - // BluetoothAdapterDevice C++ methods declared for access from java: + @NativeMethods + interface Natives { + // Binds to BluetoothRemoteGattDescriptorAndroid::OnRead. + void onRead(long nativeBluetoothRemoteGattDescriptorAndroid, + ChromeBluetoothRemoteGattDescriptor caller, int status, byte[] value); - // Binds to BluetoothRemoteGattDescriptorAndroid::OnRead. - native void nativeOnRead( - long nativeBluetoothRemoteGattDescriptorAndroid, int status, byte[] value); - - // Binds to BluetoothRemoteGattDescriptorAndroid::OnWrite. - native void nativeOnWrite(long nativeBluetoothRemoteGattDescriptorAndroid, int status); + // Binds to BluetoothRemoteGattDescriptorAndroid::OnWrite. + void onWrite(long nativeBluetoothRemoteGattDescriptorAndroid, + ChromeBluetoothRemoteGattDescriptor caller, int status); + } }
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java index 6f2989eb..fd6803e 100644 --- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java +++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java
@@ -8,6 +8,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNIAdditionalImport; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import java.util.List; @@ -46,9 +47,6 @@ mNativeBluetoothRemoteGattServiceAndroid = 0; } - // --------------------------------------------------------------------------------------------- - // BluetoothRemoteGattServiceAndroid methods implemented in java: - // Implements BluetoothRemoteGattServiceAndroid::Create. @CalledByNative private static ChromeBluetoothRemoteGattService create( @@ -76,17 +74,18 @@ // characteristic instances with the same UUID on this service. String characteristicInstanceId = mInstanceId + "/" + characteristic.getUuid().toString() + "," + characteristic.getInstanceId(); - nativeCreateGattRemoteCharacteristic(mNativeBluetoothRemoteGattServiceAndroid, + ChromeBluetoothRemoteGattServiceJni.get().createGattRemoteCharacteristic( + mNativeBluetoothRemoteGattServiceAndroid, ChromeBluetoothRemoteGattService.this, characteristicInstanceId, characteristic, mChromeDevice); } } - // --------------------------------------------------------------------------------------------- - // BluetoothAdapterDevice C++ methods declared for access from java: - - // Binds to BluetoothRemoteGattServiceAndroid::CreateGattRemoteCharacteristic. - private native void nativeCreateGattRemoteCharacteristic( - long nativeBluetoothRemoteGattServiceAndroid, String instanceId, - Wrappers.BluetoothGattCharacteristicWrapper characteristicWrapper, - ChromeBluetoothDevice chromeBluetoothDevice); + @NativeMethods + interface Natives { + // Binds to BluetoothRemoteGattServiceAndroid::CreateGattRemoteCharacteristic. + void createGattRemoteCharacteristic(long nativeBluetoothRemoteGattServiceAndroid, + ChromeBluetoothRemoteGattService caller, String instanceId, + Wrappers.BluetoothGattCharacteristicWrapper characteristicWrapper, + ChromeBluetoothDevice chromeBluetoothDevice); + } }
diff --git a/device/gamepad/BUILD.gn b/device/gamepad/BUILD.gn index 67d823d6..8442e95 100644 --- a/device/gamepad/BUILD.gn +++ b/device/gamepad/BUILD.gn
@@ -184,8 +184,10 @@ ] deps = [ "//base:base_java", + "//base:jni_java", "//third_party/android_deps:androidx_annotation_annotation_java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] srcjar_deps = [ ":java_enums_srcjar" ] }
diff --git a/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadList.java b/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadList.java index 0991f38..eb1b9862 100644 --- a/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadList.java +++ b/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadList.java
@@ -16,6 +16,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; /** * Class to manage connected gamepad devices list. @@ -288,11 +289,12 @@ final GamepadDevice device = getDevice(i); if (device != null) { device.updateButtonsAndAxesMapping(); - nativeSetGamepadData(webGamepadsPtr, i, device.isStandardGamepad(), true, - device.getName(), device.getTimestamp(), device.getAxes(), - device.getButtons()); + GamepadListJni.get().setGamepadData(GamepadList.this, webGamepadsPtr, i, + device.isStandardGamepad(), true, device.getName(), + device.getTimestamp(), device.getAxes(), device.getButtons()); } else { - nativeSetGamepadData(webGamepadsPtr, i, false, false, null, 0, null, null); + GamepadListJni.get().setGamepadData( + GamepadList.this, webGamepadsPtr, i, false, false, null, 0, null, null); } } } @@ -316,10 +318,14 @@ } } - private native void nativeSetGamepadData(long webGamepadsPtr, int index, boolean mapping, - boolean connected, String devicename, long timestamp, float[] axes, float[] buttons); - private static class LazyHolder { private static final GamepadList INSTANCE = new GamepadList(); } + + @NativeMethods + interface Natives { + void setGamepadData(GamepadList caller, long webGamepadsPtr, int index, boolean mapping, + boolean connected, String devicename, long timestamp, float[] axes, + float[] buttons); + } }
diff --git a/device/vr/BUILD.gn b/device/vr/BUILD.gn index cf71125..775c999 100644 --- a/device/vr/BUILD.gn +++ b/device/vr/BUILD.gn
@@ -401,8 +401,10 @@ java_files = java_sources_needing_jni deps = [ "//base:base_java", + "//base:jni_java", "//third_party/gvr-android-sdk:gvr_common_java", "//ui/android:ui_java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] } }
diff --git a/device/vr/android/java/src/org/chromium/device/vr/NonPresentingGvrContext.java b/device/vr/android/java/src/org/chromium/device/vr/NonPresentingGvrContext.java index d7ba07e6..20acaecf 100644 --- a/device/vr/android/java/src/org/chromium/device/vr/NonPresentingGvrContext.java +++ b/device/vr/android/java/src/org/chromium/device/vr/NonPresentingGvrContext.java
@@ -15,6 +15,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; /** * Creates an active GvrContext from a GvrApi created from the Application Context. This GvrContext @@ -90,8 +91,14 @@ public void onDisplayConfigurationChanged() { mGvrApi.refreshDisplayMetrics(); - if (mNativeGvrDevice != 0) nativeOnDisplayConfigurationChanged(mNativeGvrDevice); + if (mNativeGvrDevice != 0) { + NonPresentingGvrContextJni.get().onDisplayConfigurationChanged( + mNativeGvrDevice, NonPresentingGvrContext.this); + } } - private native void nativeOnDisplayConfigurationChanged(long nativeGvrDevice); + @NativeMethods + interface Natives { + void onDisplayConfigurationChanged(long nativeGvrDevice, NonPresentingGvrContext caller); + } }
diff --git a/docs/infra/cq_builders.md b/docs/infra/cq_builders.md index 46f1562..793ff45f 100644 --- a/docs/infra/cq_builders.md +++ b/docs/infra/cq_builders.md
@@ -91,18 +91,24 @@ * [android_compile_x64_dbg](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/android_compile_x64_dbg) ([`commit-queue.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:commit-queue.cfg+chromium/try/android_compile_x64_dbg)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+android_compile_x64_dbg)) Path regular expressions: + * [`//chrome/android/java/src/org/chromium/chrome/browser/vr/.+`](https://cs.chromium.org/chromium/src/chrome/android/java/src/org/chromium/chrome/browser/vr/) + * [`//chrome/browser/vr/.+`](https://cs.chromium.org/chromium/src/chrome/browser/vr/) * [`//sandbox/linux/seccomp-bpf/.+`](https://cs.chromium.org/chromium/src/sandbox/linux/seccomp-bpf/) * [`//sandbox/linux/seccomp-bpf-helpers/.+`](https://cs.chromium.org/chromium/src/sandbox/linux/seccomp-bpf-helpers/) * [`//sandbox/linux/system_headers/.+`](https://cs.chromium.org/chromium/src/sandbox/linux/system_headers/) * [`//sandbox/linux/tests/.+`](https://cs.chromium.org/chromium/src/sandbox/linux/tests/) + * [`//third_party/gvr-android-sdk/.+`](https://cs.chromium.org/chromium/src/third_party/gvr-android-sdk/) * [android_compile_x86_dbg](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/android_compile_x86_dbg) ([`commit-queue.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:commit-queue.cfg+chromium/try/android_compile_x86_dbg)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+android_compile_x86_dbg)) Path regular expressions: + * [`//chrome/android/java/src/org/chromium/chrome/browser/vr/.+`](https://cs.chromium.org/chromium/src/chrome/android/java/src/org/chromium/chrome/browser/vr/) + * [`//chrome/browser/vr/.+`](https://cs.chromium.org/chromium/src/chrome/browser/vr/) * [`//sandbox/linux/seccomp-bpf/.+`](https://cs.chromium.org/chromium/src/sandbox/linux/seccomp-bpf/) * [`//sandbox/linux/seccomp-bpf-helpers/.+`](https://cs.chromium.org/chromium/src/sandbox/linux/seccomp-bpf-helpers/) * [`//sandbox/linux/system_headers/.+`](https://cs.chromium.org/chromium/src/sandbox/linux/system_headers/) * [`//sandbox/linux/tests/.+`](https://cs.chromium.org/chromium/src/sandbox/linux/tests/) + * [`//third_party/gvr-android-sdk/.+`](https://cs.chromium.org/chromium/src/third_party/gvr-android-sdk/) * [android_optional_gpu_tests_rel](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/android_optional_gpu_tests_rel) ([`commit-queue.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:commit-queue.cfg+chromium/try/android_optional_gpu_tests_rel)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+android_optional_gpu_tests_rel)) @@ -312,6 +318,10 @@ * Experimental percentage: 5 +* [fuchsia-compile-x64-dbg](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/fuchsia-compile-x64-dbg) ([`commit-queue.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:commit-queue.cfg+chromium/try/fuchsia-compile-x64-dbg)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+fuchsia-compile-x64-dbg)) + + * Experimental percentage: 5 + * [ios-device](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/ios-device) ([`commit-queue.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:commit-queue.cfg+chromium/try/ios-device)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+ios-device)) https://crbug.com/739556; make this non-experimental ASAP.
diff --git a/extensions/shell/test/shell_test_launcher_delegate.cc b/extensions/shell/test/shell_test_launcher_delegate.cc index d0a9430e..2f680e4a 100644 --- a/extensions/shell/test/shell_test_launcher_delegate.cc +++ b/extensions/shell/test/shell_test_launcher_delegate.cc
@@ -13,10 +13,8 @@ int AppShellTestLauncherDelegate::RunTestSuite(int argc, char** argv) { base::TestSuite test_suite(argc, argv); - // Browser tests are expected not to tear-down various globals and may - // complete with the thread priority being above NORMAL. + // Browser tests are expected not to tear-down various globals. test_suite.DisableCheckForLeakedGlobals(); - test_suite.DisableCheckForThreadPriorityAtTestEnd(); return test_suite.Run(); }
diff --git a/fuchsia/engine/renderer/web_engine_content_renderer_client.cc b/fuchsia/engine/renderer/web_engine_content_renderer_client.cc index 0137a81..17c53ae9 100644 --- a/fuchsia/engine/renderer/web_engine_content_renderer_client.cc +++ b/fuchsia/engine/renderer/web_engine_content_renderer_client.cc
@@ -18,6 +18,23 @@ #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/widevine/cdm/widevine_cdm_common.h" +namespace { + +// Returns true if the specified video format can be decoded on hardware. +bool IsSupportedHardwareVideoCodec(const media::VideoType& type) { + // TODO(fxb/36000): Replace these hardcoded checks with a query to the + // fuchsia.mediacodec FIDL service. + if (type.codec == media::kCodecH264 && type.level <= 41) + return true; + + if (type.codec == media::kCodecVP9 && type.level <= 40) + return true; + + return false; +} + +} // namespace + WebEngineContentRendererClient::WebEngineContentRendererClient() = default; WebEngineContentRendererClient::~WebEngineContentRendererClient() = default; @@ -67,8 +84,25 @@ std::vector<std::unique_ptr<media::KeySystemProperties>>* key_systems) { if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableWidevine)) { - // TODO(yucliu): Check supported hw video decoders. - media::SupportedCodecs supported_video_codecs = media::EME_CODEC_NONE; + media::SupportedCodecs supported_video_codecs = 0; + constexpr uint8_t kUnknownCodecLevel = 0; + if (IsSupportedHardwareVideoCodec(media::VideoType{ + media::kCodecVP9, media::VP9PROFILE_PROFILE0, kUnknownCodecLevel, + media::VideoColorSpace::REC709()})) { + supported_video_codecs |= media::EME_CODEC_VP9_PROFILE0; + } + + if (IsSupportedHardwareVideoCodec(media::VideoType{ + media::kCodecVP9, media::VP9PROFILE_PROFILE2, kUnknownCodecLevel, + media::VideoColorSpace::REC709()})) { + supported_video_codecs |= media::EME_CODEC_VP9_PROFILE2; + } + + if (IsSupportedHardwareVideoCodec(media::VideoType{ + media::kCodecH264, media::H264PROFILE_MAIN, kUnknownCodecLevel, + media::VideoColorSpace::REC709()})) { + supported_video_codecs |= media::EME_CODEC_AVC1; + } base::flat_set<media::EncryptionMode> encryption_schemes{ media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs}; @@ -101,13 +135,5 @@ return ContentRendererClient::IsSupportedVideoType(type); } - // TODO(fxb/36000): Replace these hardcoded checks with a query to the - // fuchsia.mediacodec FIDL service. - if (type.codec == media::kCodecH264 && type.level <= 41) - return true; - - if (type.codec == media::kCodecVP9 && type.level <= 40) - return true; - - return false; + return IsSupportedHardwareVideoCodec(type); }
diff --git a/fuchsia/engine/test/web_engine_test_launcher.cc b/fuchsia/engine/test/web_engine_test_launcher.cc index 9789ec4..d989d0a 100644 --- a/fuchsia/engine/test/web_engine_test_launcher.cc +++ b/fuchsia/engine/test/web_engine_test_launcher.cc
@@ -25,10 +25,8 @@ // content::TestLauncherDelegate implementation: int RunTestSuite(int argc, char** argv) override { base::TestSuite test_suite(argc, argv); - // Browser tests are expected not to tear-down various globals and may - // complete with the thread priority being above NORMAL. + // Browser tests are expected not to tear-down various globals. test_suite.DisableCheckForLeakedGlobals(); - test_suite.DisableCheckForThreadPriorityAtTestEnd(); return test_suite.Run(); }
diff --git a/fuchsia/runners/cast/cast_component.cc b/fuchsia/runners/cast/cast_component.cc index 9aed46f..c78f06a 100644 --- a/fuchsia/runners/cast/cast_component.cc +++ b/fuchsia/runners/cast/cast_component.cc
@@ -21,6 +21,7 @@ namespace { constexpr int kBindingsFailureExitCode = 129; +constexpr int kRewriteRulesProviderDisconnectExitCode = 130; constexpr char kStubBindingsPath[] = FILE_PATH_LITERAL("fuchsia/runners/cast/not_implemented_api_bindings.js"); @@ -50,6 +51,7 @@ std::move(params.controller_request)), agent_manager_(std::move(params.agent_manager)), application_config_(std::move(params.app_config)), + rewrite_rules_provider_(std::move(params.rewrite_rules_provider)), touch_input_policy_( TouchInputPolicyFromApplicationConfig(application_config_)), connector_(frame()), @@ -57,6 +59,15 @@ navigation_listener_binding_(this) { base::AutoReset<bool> constructor_active_reset(&constructor_active_, true); + rewrite_rules_provider_.set_error_handler([this](zx_status_t status) { + ZX_LOG(ERROR, status) << "UrlRequestRewriteRulesProvider disconnected."; + DestroyComponent(kRewriteRulesProviderDisconnectExitCode, + fuchsia::sys::TerminationReason::INTERNAL_ERROR); + }); + + DCHECK(params.rewrite_rules); + OnRewriteRulesReceived(std::move(params.rewrite_rules.value())); + frame()->SetEnableInput(false); frame()->SetNavigationEventListener( navigation_listener_binding_.NewBinding()); @@ -83,6 +94,14 @@ WebComponent::DestroyComponent(termination_exit_code, reason); } +void CastComponent::OnRewriteRulesReceived( + std::vector<fuchsia::web::UrlRequestRewriteRule> rewrite_rules) { + frame()->SetUrlRequestRewriteRules(std::move(rewrite_rules), [this]() { + rewrite_rules_provider_->GetUrlRequestRewriteRules( + fit::bind_member(this, &CastComponent::OnRewriteRulesReceived)); + }); +} + void CastComponent::OnNavigationStateChanged( fuchsia::web::NavigationState change, OnNavigationStateChangedCallback callback) {
diff --git a/fuchsia/runners/cast/cast_component.h b/fuchsia/runners/cast/cast_component.h index 9b1fe7d..cbb3859 100644 --- a/fuchsia/runners/cast/cast_component.h +++ b/fuchsia/runners/cast/cast_component.h
@@ -36,8 +36,9 @@ fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller_request; chromium::cast::ApplicationConfig app_config; - fuchsia::web::AdditionalHeadersProviderPtr headers_provider; - base::Optional<std::vector<fuchsia::net::http::Header>> headers; + chromium::cast::UrlRequestRewriteRulesProviderPtr rewrite_rules_provider; + base::Optional<std::vector<fuchsia::web::UrlRequestRewriteRule>> + rewrite_rules; }; CastComponent(CastRunner* runner, CastComponentParams params); @@ -51,6 +52,9 @@ void DestroyComponent(int termination_exit_code, fuchsia::sys::TerminationReason reason) override; + void OnRewriteRulesReceived( + std::vector<fuchsia::web::UrlRequestRewriteRule> rewrite_rules); + // fuchsia::web::NavigationEventListener implementation. // Triggers the injection of API channels into the page content. void OnNavigationStateChanged( @@ -59,6 +63,7 @@ std::unique_ptr<cr_fuchsia::AgentManager> agent_manager_; chromium::cast::ApplicationConfig application_config_; + chromium::cast::UrlRequestRewriteRulesProviderPtr rewrite_rules_provider_; bool constructor_active_ = false; TouchInputPolicy touch_input_policy_;
diff --git a/fuchsia/runners/cast/cast_runner.cc b/fuchsia/runners/cast/cast_runner.cc index a6d9368..0d8ba3bf 100644 --- a/fuchsia/runners/cast/cast_runner.cc +++ b/fuchsia/runners/cast/cast_runner.cc
@@ -4,7 +4,6 @@ #include "fuchsia/runners/cast/cast_runner.h" -#include <fuchsia/sys/cpp/fidl.h> #include <memory> #include <string> #include <utility> @@ -67,25 +66,26 @@ base::BindOnce(&CastRunner::MaybeStartComponent, base::Unretained(this), base::Unretained(pending_component.get()))); - // Get AdditionalHeadersProvider from the Agent. - fidl::InterfaceHandle<fuchsia::web::AdditionalHeadersProvider> - additional_headers_provider; + // Get UrlRequestRewriteRulesProvider from the Agent. + fidl::InterfaceHandle<chromium::cast::UrlRequestRewriteRulesProvider> + url_request_rules_provider; pending_component->agent_manager->ConnectToAgentService( - kAgentComponentUrl, additional_headers_provider.NewRequest()); - pending_component->headers_provider = additional_headers_provider.Bind(); - pending_component->headers_provider.set_error_handler( - [this, pending_component = pending_component.get()](zx_status_t error) { - if (pending_component->headers.has_value()) - return; - pending_component->headers = {}; - MaybeStartComponent(pending_component); + kAgentComponentUrl, url_request_rules_provider.NewRequest()); + pending_component->rewrite_rules_provider = url_request_rules_provider.Bind(); + pending_component->rewrite_rules_provider.set_error_handler( + [this, pending_component = pending_component.get()](zx_status_t status) { + ZX_LOG(ERROR, status) << "UrlRequestRewriteRulesProvider disconnected."; + + // The rules provider disconnected, cancel the component launch. + size_t count = pending_components_.erase(pending_component); + DCHECK_EQ(count, 1u); }); - pending_component->headers_provider->GetHeaders( + pending_component->rewrite_rules_provider->GetUrlRequestRewriteRules( [this, pending_component = pending_component.get()]( - std::vector<fuchsia::net::http::Header> headers, zx_time_t expiry) { - pending_component->headers = - base::Optional<std::vector<fuchsia::net::http::Header>>( - std::move(headers)); + std::vector<fuchsia::web::UrlRequestRewriteRule> rewrite_rules) { + pending_component->rewrite_rules = + base::Optional<std::vector<fuchsia::web::UrlRequestRewriteRule>>( + std::move(rewrite_rules)); MaybeStartComponent(pending_component); }); @@ -126,19 +126,17 @@ return; if (!pending_component->api_bindings_client->HasBindings()) return; - if (!pending_component->headers.has_value()) + if (!pending_component->rewrite_rules.has_value()) return; // Create a component based on the returned configuration, and pass it the // |pending_component|. - std::vector<fuchsia::net::http::Header> additional_headers = - pending_component->headers.value(); - GURL cast_app_url(pending_component->app_config.web_url()); auto component = std::make_unique<CastComponent>(this, std::move(*pending_component)); pending_components_.erase(pending_component); - component->LoadUrl(std::move(cast_app_url), std::move(additional_headers)); + component->LoadUrl(std::move(cast_app_url), + std::vector<fuchsia::net::http::Header>()); RegisterComponent(std::move(component)); }
diff --git a/fuchsia/runners/cast/cast_runner.h b/fuchsia/runners/cast/cast_runner.h index afbcaae6..f2ca037 100644 --- a/fuchsia/runners/cast/cast_runner.h +++ b/fuchsia/runners/cast/cast_runner.h
@@ -12,7 +12,9 @@ #include "base/callback.h" #include "base/containers/flat_set.h" #include "base/containers/unique_ptr_adapters.h" +#include "base/fuchsia/startup_context.h" #include "base/macros.h" +#include "fuchsia/base/agent_manager.h" #include "fuchsia/fidl/chromium/cast/cpp/fidl.h" #include "fuchsia/runners/cast/cast_component.h" #include "fuchsia/runners/common/web_content_runner.h"
diff --git a/fuchsia/runners/cast/cast_runner_integration_test.cc b/fuchsia/runners/cast/cast_runner_integration_test.cc index 37c9676..2de8956 100644 --- a/fuchsia/runners/cast/cast_runner_integration_test.cc +++ b/fuchsia/runners/cast/cast_runner_integration_test.cc
@@ -23,6 +23,7 @@ #include "fuchsia/base/result_receiver.h" #include "fuchsia/base/string_util.h" #include "fuchsia/base/test_navigation_listener.h" +#include "fuchsia/base/url_request_rewrite_test_util.h" #include "fuchsia/runners/cast/cast_runner.h" #include "fuchsia/runners/cast/fake_application_config_manager.h" #include "fuchsia/runners/cast/test_api_bindings.h" @@ -45,28 +46,36 @@ ADD_FAILURE(); } -class FakeAdditionalHeadersProvider - : public fuchsia::web::AdditionalHeadersProvider { +class FakeUrlRequestRewriteRulesProvider + : public chromium::cast::UrlRequestRewriteRulesProvider { public: - explicit FakeAdditionalHeadersProvider(sys::OutgoingDirectory* directory) + explicit FakeUrlRequestRewriteRulesProvider(sys::OutgoingDirectory* directory) : binding_(directory, this) {} - ~FakeAdditionalHeadersProvider() override = default; + ~FakeUrlRequestRewriteRulesProvider() override = default; private: - void GetHeaders(GetHeadersCallback callback) override { - std::vector<fuchsia::net::http::Header> headers; - fuchsia::net::http::Header header; - header.name = cr_fuchsia::StringToBytes("Test"); - header.value = cr_fuchsia::StringToBytes("Value"); - headers.push_back(std::move(header)); - callback(std::move(headers), 0); + void GetUrlRequestRewriteRules( + GetUrlRequestRewriteRulesCallback callback) override { + // Only send the rules once. They do not expire + if (rules_sent_) + return; + rules_sent_ = true; + + std::vector<fuchsia::web::UrlRequestRewrite> rewrites; + rewrites.push_back(cr_fuchsia::CreateRewriteAddHeaders("Test", "Value")); + fuchsia::web::UrlRequestRewriteRule rule; + rule.set_rewrites(std::move(rewrites)); + std::vector<fuchsia::web::UrlRequestRewriteRule> rules; + rules.push_back(std::move(rule)); + callback(std::move(rules)); } + bool rules_sent_ = false; const base::fuchsia::ScopedServiceBinding< - fuchsia::web::AdditionalHeadersProvider> + chromium::cast::UrlRequestRewriteRulesProvider> binding_; - DISALLOW_COPY_AND_ASSIGN(FakeAdditionalHeadersProvider); + DISALLOW_COPY_AND_ASSIGN(FakeUrlRequestRewriteRulesProvider); }; class FakeApplicationControllerReceiver @@ -104,8 +113,8 @@ bool provide_controller_receiver) : ComponentStateBase(component_url), app_config_binding_(outgoing_directory(), app_config_manager), - additional_headers_provider_( - std::make_unique<FakeAdditionalHeadersProvider>( + url_request_rules_provider_( + std::make_unique<FakeUrlRequestRewriteRulesProvider>( outgoing_directory())) { if (bindings_manager) { bindings_manager_binding_ = std::make_unique< @@ -138,7 +147,8 @@ std::unique_ptr< base::fuchsia::ScopedServiceBinding<chromium::cast::ApiBindings>> bindings_manager_binding_; - std::unique_ptr<FakeAdditionalHeadersProvider> additional_headers_provider_; + std::unique_ptr<FakeUrlRequestRewriteRulesProvider> + url_request_rules_provider_; FakeApplicationControllerReceiver controller_receiver_; base::Optional<base::fuchsia::ScopedServiceBinding< chromium::cast::ApplicationControllerReceiver>> @@ -394,7 +404,7 @@ EXPECT_FALSE(web_component.has_value()); } -TEST_F(CastRunnerIntegrationTest, AdditionalHeadersProvider) { +TEST_F(CastRunnerIntegrationTest, UrlRequestRewriteRulesProvider) { const char kEchoAppId[] = "00000000"; const char kEchoAppPath[] = "/echoheader?Test"; const GURL echo_app_url = test_server_.GetURL(kEchoAppPath);
diff --git a/headless/test/headless_test_launcher.cc b/headless/test/headless_test_launcher.cc index d0b1430..6d8ee1c 100644 --- a/headless/test/headless_test_launcher.cc +++ b/headless/test/headless_test_launcher.cc
@@ -41,10 +41,8 @@ // content::TestLauncherDelegate implementation: int RunTestSuite(int argc, char** argv) override { base::TestSuite test_suite(argc, argv); - // Browser tests are expected not to tear-down various globals and may - // complete with the thread priority being above NORMAL. + // Browser tests are expected not to tear-down various globals. test_suite.DisableCheckForLeakedGlobals(); - test_suite.DisableCheckForThreadPriorityAtTestEnd(); return test_suite.Run(); }
diff --git a/infra/config/commit-queue.cfg b/infra/config/commit-queue.cfg index bd0c4e5..ea03def8 100644 --- a/infra/config/commit-queue.cfg +++ b/infra/config/commit-queue.cfg
@@ -159,17 +159,23 @@ } builders { name: "chromium/try/android_compile_x64_dbg" + location_regexp: ".+/[+]/chrome/android/java/src/org/chromium/chrome/browser/vr/.+" + location_regexp: ".+/[+]/chrome/browser/vr/.+" location_regexp: ".+/[+]/sandbox/linux/seccomp-bpf/.+" location_regexp: ".+/[+]/sandbox/linux/seccomp-bpf-helpers/.+" location_regexp: ".+/[+]/sandbox/linux/system_headers/.+" location_regexp: ".+/[+]/sandbox/linux/tests/.+" + location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" } builders { name: "chromium/try/android_compile_x86_dbg" + location_regexp: ".+/[+]/chrome/android/java/src/org/chromium/chrome/browser/vr/.+" + location_regexp: ".+/[+]/chrome/browser/vr/.+" location_regexp: ".+/[+]/sandbox/linux/seccomp-bpf/.+" location_regexp: ".+/[+]/sandbox/linux/seccomp-bpf-helpers/.+" location_regexp: ".+/[+]/sandbox/linux/system_headers/.+" location_regexp: ".+/[+]/sandbox/linux/tests/.+" + location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" } builders { name: "chromium/try/android_optional_gpu_tests_rel" @@ -363,6 +369,10 @@ name: "chromium/try/chromeos-kevin-experimental-rel" experiment_percentage: 5 } + builders { + name: "chromium/try/fuchsia-compile-x64-dbg" + experiment_percentage: 5 + } # https://crbug.com/739556; make this non-experimental ASAP. builders { name: "chromium/try/ios-device"
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg index 422ab62..5d1db2e3 100644 --- a/infra/config/cr-buildbucket.cfg +++ b/infra/config/cr-buildbucket.cfg
@@ -1209,6 +1209,21 @@ } builders { + name: "android-avd-packager" + mixins: "linux-xenial" + mixins: "builderless" + service_account: "chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com" + recipe { + name: "android/avd_packager" + properties_j: <<END + avd_configs: [ + "tools/android/avd/proto/generic_android28.textpb" + ] + END + } + } + + builders { name: "android-code-coverage" mixins: "code-coverage" mixins: "java-coverage" @@ -1609,6 +1624,12 @@ } builders { + name: "fuchsia-x64-dbg" + mixins: "linux-ci" + mixins: "builderless" + } + + builders { name: "Fuchsia x64" mixins: "linux-ci-goma-rbe-prod" mixins: "builderless" @@ -4392,10 +4413,15 @@ name: "fuchsia-fyi-x64-rel" } builders { + mixins: "builderless" mixins: "linux-try" - name: "fuchsia_x64" + name: "fuchsia-compile-x64-dbg" + } + builders { + mixins: "linux-try" mixins: "builderless" mixins: "goma-rbe-prod" + name: "fuchsia_x64" } builders { mixins: "builderless"
diff --git a/infra/config/luci-milo.cfg b/infra/config/luci-milo.cfg index 724f744..d80d5029 100644 --- a/infra/config/luci-milo.cfg +++ b/infra/config/luci-milo.cfg
@@ -571,6 +571,10 @@ short_name: "aud" } builders { + name: "buildbucket/luci.chromium.ci/Fuchsia ARM64" + category: "chromium.linux|fuchsia|a64" + } + builders { name: "buildbucket/luci.chromium.ci/fuchsia-arm64-cast" category: "chromium.linux|fuchsia|cast" short_name: "a64" @@ -581,21 +585,21 @@ short_name: "x64" } builders { - name: "buildbucket/luci.chromium.ci/Fuchsia ARM64" - category: "chromium.linux|fuchsia|misc" - short_name: "a64" - } - builders { - name: "buildbucket/luci.chromium.ci/Fuchsia x64" - category: "chromium.linux|fuchsia|misc" - short_name: "x64" + name: "buildbucket/luci.chromium.ci/fuchsia-x64-dbg" + category: "chromium.linux|fuchsia|x64" + short_name: "dbg" } builders { name: "buildbucket/luci.chromium.ci/Deterministic Fuchsia (dbg)" - category: "chromium.linux|fuchsia|misc" + category: "chromium.linux|fuchsia|x64" short_name: "det" } builders { + name: "buildbucket/luci.chromium.ci/Fuchsia x64" + category: "chromium.linux|fuchsia|x64" + short_name: "rel" + } + builders { name: "buildbucket/luci.chromium.ci/Linux ChromiumOS Full" category: "chromium.chromiumos|default" short_name: "ful" @@ -994,6 +998,10 @@ short_name: "aud" } builders { + name: "buildbucket/luci.chromium.ci/Fuchsia ARM64" + category: "fuchsia|a64" + } + builders { name: "buildbucket/luci.chromium.ci/fuchsia-arm64-cast" category: "fuchsia|cast" short_name: "a64" @@ -1004,20 +1012,20 @@ short_name: "x64" } builders { - name: "buildbucket/luci.chromium.ci/Fuchsia ARM64" - category: "fuchsia|misc" - short_name: "a64" - } - builders { - name: "buildbucket/luci.chromium.ci/Fuchsia x64" - category: "fuchsia|misc" - short_name: "x64" + name: "buildbucket/luci.chromium.ci/fuchsia-x64-dbg" + category: "fuchsia|x64" + short_name: "dbg" } builders { name: "buildbucket/luci.chromium.ci/Deterministic Fuchsia (dbg)" - category: "fuchsia|misc" + category: "fuchsia|x64" short_name: "det" } + builders { + name: "buildbucket/luci.chromium.ci/Fuchsia x64" + category: "fuchsia|x64" + short_name: "rel" + } } consoles { @@ -4586,6 +4594,9 @@ name: "buildbucket/luci.chromium.try/fuchsia-arm64-cast" } builders { + name: "buildbucket/luci.chromium.try/fuchsia-compile-x64-dbg" + } + builders { name: "buildbucket/luci.chromium.try/fuchsia-fyi-arm64-rel" } builders { @@ -5194,6 +5205,9 @@ name: "buildbucket/luci.chromium.try/fuchsia-angle-rel" } builders { + name: "buildbucket/luci.chromium.try/fuchsia-compile-x64-dbg" + } + builders { name: "buildbucket/luci.chromium.try/gpu-fyi-try-android-l-nexus-5-32" } builders {
diff --git a/infra/config/luci-notify.cfg b/infra/config/luci-notify.cfg index cba5cb9..7e5000b 100644 --- a/infra/config/luci-notify.cfg +++ b/infra/config/luci-notify.cfg
@@ -196,6 +196,10 @@ name: "fuchsia-x64-cast" bucket: "ci" } + builders { + name: "fuchsia-x64-dbg" + bucket: "ci" + } } notifiers {
diff --git a/infra/config/luci-scheduler.cfg b/infra/config/luci-scheduler.cfg index db876c7..c95f6f73 100644 --- a/infra/config/luci-scheduler.cfg +++ b/infra/config/luci-scheduler.cfg
@@ -153,6 +153,7 @@ triggers: "fuchsia-arm64-cast" triggers: "Fuchsia ARM64" triggers: "fuchsia-x64-cast" + triggers: "fuchsia-x64-dbg" triggers: "Fuchsia x64" triggers: "GPU FYI Linux Builder (dbg)" triggers: "GPU FYI Linux Builder" @@ -730,6 +731,18 @@ } job { + id: "android-avd-packager" + acl_sets: "default" + # Run weekly, on Sunday morning at midnight. + schedule: "0 7 * * 0 *" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "android-avd-packager" + } +} + +job { id: "android-code-coverage" acl_sets: "default" buildbucket: { @@ -1531,6 +1544,16 @@ } job { + id: "fuchsia-x64-dbg" + acl_sets: "default" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "fuchsia-x64-dbg" + } +} + +job { id: "GPU FYI Linux Builder" acl_sets: "default" buildbucket: {
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index 4747f36..36a5e887 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -2169,61 +2169,41 @@ disableWebUsageDuringRemoval = NO; } - ProceduralBlock removeBrowsingDataBlock = ^{ - if (disableWebUsageDuringRemoval) { - // Disables browsing and purges web views. - // Must be called only on the main thread. - DCHECK([NSThread isMainThread]); - self.interfaceProvider.mainInterface.userInteractionEnabled = NO; - self.interfaceProvider.incognitoInterface.userInteractionEnabled = NO; - } else if (showActivityIndicator) { - // Show activity overlay so users know that clear browsing data is in - // progress. - [self.mainBVC.dispatcher showActivityOverlay:YES]; - } - - BrowsingDataRemoverFactory::GetForBrowserState(browserState) - ->Remove(timePeriod, removeMask, base::BindOnce(^{ - // Activates browsing and enables web views. - // Must be called only on the main thread. - DCHECK([NSThread isMainThread]); - if (showActivityIndicator) { - // User interaction still needs to be disabled as a way to - // force reload all the web states and to reset NTPs. - self.interfaceProvider.mainInterface - .userInteractionEnabled = NO; - self.interfaceProvider.incognitoInterface - .userInteractionEnabled = NO; - - [self.mainBVC.dispatcher showActivityOverlay:NO]; - } - self.interfaceProvider.mainInterface.userInteractionEnabled = - YES; - self.interfaceProvider.incognitoInterface - .userInteractionEnabled = YES; - [self.currentBVC setPrimary:YES]; - - if (completionBlock) - completionBlock(); - })); - }; - - // Removing browsing data triggers session restore in navigation manager. If - // there is an in-progress session restore, wait for it to finish before - // attempting to clear browsing data again. - web::WebState* webState = - self.currentBVC.tabModel - ? self.currentBVC.tabModel.webStateList->GetActiveWebState() - : nullptr; - if (webState && webState->GetNavigationManager()) { - webState->GetNavigationManager()->AddRestoreCompletionCallback( - base::BindOnce(^{ - removeBrowsingDataBlock(); - })); - return; + if (disableWebUsageDuringRemoval) { + // Disables browsing and purges web views. + // Must be called only on the main thread. + DCHECK([NSThread isMainThread]); + self.interfaceProvider.mainInterface.userInteractionEnabled = NO; + self.interfaceProvider.incognitoInterface.userInteractionEnabled = NO; + } else if (showActivityIndicator) { + // Show activity overlay so users know that clear browsing data is in + // progress. + [self.mainBVC.dispatcher showActivityOverlay:YES]; } - removeBrowsingDataBlock(); + BrowsingDataRemoverFactory::GetForBrowserState(browserState) + ->Remove( + timePeriod, removeMask, base::BindOnce(^{ + // Activates browsing and enables web views. + // Must be called only on the main thread. + DCHECK([NSThread isMainThread]); + if (showActivityIndicator) { + // User interaction still needs to be disabled as a way to + // force reload all the web states and to reset NTPs. + self.interfaceProvider.mainInterface.userInteractionEnabled = NO; + self.interfaceProvider.incognitoInterface.userInteractionEnabled = + NO; + + [self.mainBVC.dispatcher showActivityOverlay:NO]; + } + self.interfaceProvider.mainInterface.userInteractionEnabled = YES; + self.interfaceProvider.incognitoInterface.userInteractionEnabled = + YES; + [self.currentBVC setPrimary:YES]; + + if (completionBlock) + completionBlock(); + })); } #pragma mark - Navigation Controllers
diff --git a/ios/chrome/browser/ui/tab_grid/grid/BUILD.gn b/ios/chrome/browser/ui/tab_grid/grid/BUILD.gn index 3de2a01..e22d4c1 100644 --- a/ios/chrome/browser/ui/tab_grid/grid/BUILD.gn +++ b/ios/chrome/browser/ui/tab_grid/grid/BUILD.gn
@@ -34,6 +34,8 @@ deps = [ ":grid_ui_constants", "resources:grid_cell_close_button", + "resources:grid_theme_dark_selection_tint_color", + "resources:grid_theme_selection_tint_color", "//base", "//ios/chrome/app/strings", "//ios/chrome/browser",
diff --git a/ios/chrome/browser/ui/tab_grid/grid/grid_cell.mm b/ios/chrome/browser/ui/tab_grid/grid/grid_cell.mm index 44fb0515..9855f33 100644 --- a/ios/chrome/browser/ui/tab_grid/grid/grid_cell.mm +++ b/ios/chrome/browser/ui/tab_grid/grid/grid_cell.mm
@@ -214,17 +214,14 @@ // When iOS 12 is dropped, only the next switch statement is needed for // styling. - // TODO (crbug.com/995746): New colors (|kGridThemeSelectionTintColor| - // and |kGridThemeDarkSelectionTintColor|), which are only used in tab - // grid, should be local colors instead of global. switch (theme) { case GridThemeLight: self.border.layer.borderColor = - [UIColor colorNamed:kGridThemeSelectionTintColor].CGColor; + [UIColor colorNamed:@"grid_theme_selection_tint_color"].CGColor; break; case GridThemeDark: self.border.layer.borderColor = - [UIColor colorNamed:kGridThemeDarkSelectionTintColor].CGColor; + [UIColor colorNamed:@"grid_theme_dark_selection_tint_color"].CGColor; break; } _theme = theme;
diff --git a/ios/chrome/browser/ui/tab_grid/grid/resources/BUILD.gn b/ios/chrome/browser/ui/tab_grid/grid/resources/BUILD.gn index 3bffe21..0cd6645 100644 --- a/ios/chrome/browser/ui/tab_grid/grid/resources/BUILD.gn +++ b/ios/chrome/browser/ui/tab_grid/grid/resources/BUILD.gn
@@ -11,3 +11,15 @@ "grid_cell_close_button.imageset/grid_cell_close_button@3x.png", ] } + +colorset("grid_theme_selection_tint_color") { + sources = [ + "grid_theme_selection_tint_color.colorset/Contents.json", + ] +} + +colorset("grid_theme_dark_selection_tint_color") { + sources = [ + "grid_theme_dark_selection_tint_color.colorset/Contents.json", + ] +}
diff --git a/ios/chrome/common/colors/resources/grid_theme_dark_selection_tint_color.colorset/Contents.json b/ios/chrome/browser/ui/tab_grid/grid/resources/grid_theme_dark_selection_tint_color.colorset/Contents.json similarity index 100% rename from ios/chrome/common/colors/resources/grid_theme_dark_selection_tint_color.colorset/Contents.json rename to ios/chrome/browser/ui/tab_grid/grid/resources/grid_theme_dark_selection_tint_color.colorset/Contents.json
diff --git a/ios/chrome/common/colors/resources/grid_theme_selection_tint_color.colorset/Contents.json b/ios/chrome/browser/ui/tab_grid/grid/resources/grid_theme_selection_tint_color.colorset/Contents.json similarity index 100% rename from ios/chrome/common/colors/resources/grid_theme_selection_tint_color.colorset/Contents.json rename to ios/chrome/browser/ui/tab_grid/grid/resources/grid_theme_selection_tint_color.colorset/Contents.json
diff --git a/ios/chrome/common/colors/resources/BUILD.gn b/ios/chrome/common/colors/resources/BUILD.gn index b250ff0e..90dcbb7 100644 --- a/ios/chrome/common/colors/resources/BUILD.gn +++ b/ios/chrome/common/colors/resources/BUILD.gn
@@ -27,8 +27,6 @@ ":grey_700_color", ":grey_800_color", ":grey_900_color", - ":grid_theme_dark_selection_tint_color", - ":grid_theme_selection_tint_color", ":mdc_ink_color", ":mdc_secondary_ink_color", ":placeholder_image_tint_color", @@ -173,18 +171,6 @@ ] } -colorset("grid_theme_selection_tint_color") { - sources = [ - "grid_theme_selection_tint_color.colorset/Contents.json", - ] -} - -colorset("grid_theme_dark_selection_tint_color") { - sources = [ - "grid_theme_dark_selection_tint_color.colorset/Contents.json", - ] -} - colorset("grey_900_color") { sources = [ "grey_900_color.colorset/Contents.json",
diff --git a/ios/chrome/common/colors/semantic_color_names.h b/ios/chrome/common/colors/semantic_color_names.h index 257b2fd..c09eab1 100644 --- a/ios/chrome/common/colors/semantic_color_names.h +++ b/ios/chrome/common/colors/semantic_color_names.h
@@ -12,7 +12,6 @@ extern NSString* const kBackgroundColor; extern NSString* const kCloseButtonColor; extern NSString* const kDisabledTintColor; -extern NSString* const kGridThemeSelectionTintColor; // Background color used in the rounded squares behind favicons. extern NSString* const kFaviconBackgroundColor; // Ink color for an MDC button. @@ -69,7 +68,6 @@ extern NSString* const kBackgroundDarkColor; extern NSString* const kCloseButtonDarkColor; -extern NSString* const kGridThemeDarkSelectionTintColor; extern NSString* const kTableViewRowHighlightDarkColor; extern NSString* const kTextPrimaryDarkColor; extern NSString* const kTextSecondaryDarkColor;
diff --git a/ios/chrome/common/colors/semantic_color_names.mm b/ios/chrome/common/colors/semantic_color_names.mm index 8ad3832c..e1a632b 100644 --- a/ios/chrome/common/colors/semantic_color_names.mm +++ b/ios/chrome/common/colors/semantic_color_names.mm
@@ -12,8 +12,6 @@ NSString* const kBackgroundColor = @"background_color"; NSString* const kCloseButtonColor = @"close_button_color"; NSString* const kDisabledTintColor = @"disabled_tint_color"; -NSString* const kGridThemeSelectionTintColor = - @"grid_theme_selection_tint_color"; NSString* const kFaviconBackgroundColor = @"favicon_background_color"; NSString* const kMDCInkColor = @"mdc_ink_color"; NSString* const kMDCSecondaryInkColor = @"mdc_secondary_ink_color"; @@ -51,8 +49,6 @@ NSString* const kBackgroundDarkColor = @"background_dark_color"; NSString* const kCloseButtonDarkColor = @"close_button_dark_color"; -NSString* const kGridThemeDarkSelectionTintColor = - @"grid_theme_dark_selection_tint_color"; NSString* const kTableViewRowHighlightDarkColor = @"table_view_row_highlight_dark_color"; NSString* const kTextPrimaryDarkColor = @"text_primary_dark_color";
diff --git a/ios/third_party/material_components_ios/BUILD.gn b/ios/third_party/material_components_ios/BUILD.gn index 94aa1ce..1e182c2 100644 --- a/ios/third_party/material_components_ios/BUILD.gn +++ b/ios/third_party/material_components_ios/BUILD.gn
@@ -380,6 +380,8 @@ "src/components/private/Application/src/MaterialApplication.h", "src/components/private/Application/src/UIApplication+AppExtensions.h", "src/components/private/Application/src/UIApplication+AppExtensions.m", + "src/components/private/Color/src/UIColor+MaterialBlending.h", + "src/components/private/Color/src/UIColor+MaterialBlending.m", "src/components/private/Color/src/UIColor+MaterialDynamic.h", "src/components/private/Color/src/UIColor+MaterialDynamic.m", "src/components/private/Icons/icons/ic_arrow_back/src/MaterialIcons+ic_arrow_back.h",
diff --git a/media/base/android/BUILD.gn b/media/base/android/BUILD.gn index 01c6322c..10726cb 100644 --- a/media/base/android/BUILD.gn +++ b/media/base/android/BUILD.gn
@@ -168,8 +168,10 @@ deps = [ ":media_java_resources", "//base:base_java", + "//base:jni_java", "//third_party/android_deps:androidx_annotation_annotation_java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] srcjar_deps = [ ":java_enums", ":java_switches",
diff --git a/media/base/android/java/src/org/chromium/media/AudioManagerAndroid.java b/media/base/android/java/src/org/chromium/media/AudioManagerAndroid.java index 63bb172..621f27ea 100644 --- a/media/base/android/java/src/org/chromium/media/AudioManagerAndroid.java +++ b/media/base/android/java/src/org/chromium/media/AudioManagerAndroid.java
@@ -33,6 +33,7 @@ import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import java.lang.reflect.Method; import java.util.ArrayList; @@ -1118,8 +1119,9 @@ // slider all the way down in communication mode but the callback // implementation can ensure that the volume is completely muted. int volume = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); - if (DEBUG) logd("nativeSetMute: " + (volume == 0)); - nativeSetMute(mNativeAudioManagerAndroid, (volume == 0)); + if (DEBUG) logd("AudioManagerAndroidJni.get().setMute: " + (volume == 0)); + AudioManagerAndroidJni.get().setMute( + mNativeAudioManagerAndroid, AudioManagerAndroid.this, (volume == 0)); } }; @@ -1234,5 +1236,8 @@ mUsbAudioReceiver = null; } - private native void nativeSetMute(long nativeAudioManagerAndroid, boolean muted); + @NativeMethods + interface Natives { + void setMute(long nativeAudioManagerAndroid, AudioManagerAndroid caller, boolean muted); + } }
diff --git a/media/base/android/java/src/org/chromium/media/AudioTrackOutputStream.java b/media/base/android/java/src/org/chromium/media/AudioTrackOutputStream.java index 2189f27..9b976a1c 100644 --- a/media/base/android/java/src/org/chromium/media/AudioTrackOutputStream.java +++ b/media/base/android/java/src/org/chromium/media/AudioTrackOutputStream.java
@@ -14,6 +14,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import java.nio.ByteBuffer; @@ -122,17 +123,20 @@ @Override public AudioBufferInfo onMoreData(ByteBuffer audioData, long delayInFrames) { - return nativeOnMoreData(mNativeAudioTrackOutputStream, audioData, delayInFrames); + return AudioTrackOutputStreamJni.get().onMoreData(mNativeAudioTrackOutputStream, + AudioTrackOutputStream.this, audioData, delayInFrames); } @Override public long getAddress(ByteBuffer byteBuffer) { - return nativeGetAddress(mNativeAudioTrackOutputStream, byteBuffer); + return AudioTrackOutputStreamJni.get().getAddress( + mNativeAudioTrackOutputStream, AudioTrackOutputStream.this, byteBuffer); } @Override public void onError() { - nativeOnError(mNativeAudioTrackOutputStream); + AudioTrackOutputStreamJni.get().onError( + mNativeAudioTrackOutputStream, AudioTrackOutputStream.this); } }; } @@ -313,8 +317,12 @@ return mAudioTrack.write(mWriteBuffer, mLeftSize, AudioTrack.WRITE_BLOCKING); } - private native AudioBufferInfo nativeOnMoreData( - long nativeAudioTrackOutputStream, ByteBuffer audioData, long delayInFrames); - private native void nativeOnError(long nativeAudioTrackOutputStream); - private native long nativeGetAddress(long nativeAudioTrackOutputStream, ByteBuffer byteBuffer); + @NativeMethods + interface Natives { + AudioBufferInfo onMoreData(long nativeAudioTrackOutputStream, AudioTrackOutputStream caller, + ByteBuffer audioData, long delayInFrames); + void onError(long nativeAudioTrackOutputStream, AudioTrackOutputStream caller); + long getAddress(long nativeAudioTrackOutputStream, AudioTrackOutputStream caller, + ByteBuffer byteBuffer); + } }
diff --git a/media/base/android/java/src/org/chromium/media/HdrMetadata.java b/media/base/android/java/src/org/chromium/media/HdrMetadata.java index d51daed..add144d 100644 --- a/media/base/android/java/src/org/chromium/media/HdrMetadata.java +++ b/media/base/android/java/src/org/chromium/media/HdrMetadata.java
@@ -14,6 +14,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.MainDex; +import org.chromium.base.annotations.NativeMethods; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -61,13 +62,13 @@ // TODO(sandv): Use color space matrix when android has support for it. int colorStandard = getColorStandard(); - if (colorStandard != -1) + if (colorStandard != -1) { format.setInteger(MediaFormat.KEY_COLOR_STANDARD, colorStandard); - + } int colorTransfer = getColorTransfer(); - if (colorTransfer != -1) + if (colorTransfer != -1) { format.setInteger(MediaFormat.KEY_COLOR_TRANSFER, colorTransfer); - + } int colorRange = getColorRange(); if (colorRange != -1) format.setInteger(MediaFormat.KEY_COLOR_RANGE, colorRange); @@ -92,10 +93,9 @@ } } - private native int nativePrimaries(long nativeJniHdrMetadata); private int getColorStandard() { // media/base/video_color_space.h - switch (nativePrimaries(mNativeJniHdrMetadata)) { + switch (HdrMetadataJni.get().primaries(mNativeJniHdrMetadata, HdrMetadata.this)) { case 1: return MediaFormat.COLOR_STANDARD_BT709; case 4: // BT.470M. @@ -110,10 +110,9 @@ } } - private native int nativeColorTransfer(long nativeJniHdrMetadata); private int getColorTransfer() { // media/base/video_color_space.h - switch (nativeColorTransfer(mNativeJniHdrMetadata)) { + switch (HdrMetadataJni.get().colorTransfer(mNativeJniHdrMetadata, HdrMetadata.this)) { case 1: // BT.709. case 6: // SMPTE 170M. case 7: // SMPTE 240M. @@ -129,10 +128,9 @@ } } - private native int nativeRange(long nativeJniHdrMetadata); private int getColorRange() { // media/base/video_color_space.h - switch (nativeRange(mNativeJniHdrMetadata)) { + switch (HdrMetadataJni.get().range(mNativeJniHdrMetadata, HdrMetadata.this)) { case 1: return MediaFormat.COLOR_RANGE_LIMITED; case 2: @@ -142,63 +140,73 @@ } } - private native float nativePrimaryRChromaticityX(long nativeJniHdrMetadata); private float primaryRChromaticityX() { - return nativePrimaryRChromaticityX(mNativeJniHdrMetadata); + return HdrMetadataJni.get().primaryRChromaticityX(mNativeJniHdrMetadata, HdrMetadata.this); } - private native float nativePrimaryRChromaticityY(long nativeJniHdrMetadata); private float primaryRChromaticityY() { - return nativePrimaryRChromaticityY(mNativeJniHdrMetadata); + return HdrMetadataJni.get().primaryRChromaticityY(mNativeJniHdrMetadata, HdrMetadata.this); } - private native float nativePrimaryGChromaticityX(long nativeJniHdrMetadata); private float primaryGChromaticityX() { - return nativePrimaryGChromaticityX(mNativeJniHdrMetadata); + return HdrMetadataJni.get().primaryGChromaticityX(mNativeJniHdrMetadata, HdrMetadata.this); } - private native float nativePrimaryGChromaticityY(long nativeJniHdrMetadata); private float primaryGChromaticityY() { - return nativePrimaryGChromaticityY(mNativeJniHdrMetadata); + return HdrMetadataJni.get().primaryGChromaticityY(mNativeJniHdrMetadata, HdrMetadata.this); } - private native float nativePrimaryBChromaticityX(long nativeJniHdrMetadata); private float primaryBChromaticityX() { - return nativePrimaryBChromaticityX(mNativeJniHdrMetadata); + return HdrMetadataJni.get().primaryBChromaticityX(mNativeJniHdrMetadata, HdrMetadata.this); } - private native float nativePrimaryBChromaticityY(long nativeJniHdrMetadata); private float primaryBChromaticityY() { - return nativePrimaryBChromaticityY(mNativeJniHdrMetadata); + return HdrMetadataJni.get().primaryBChromaticityY(mNativeJniHdrMetadata, HdrMetadata.this); } - private native float nativeWhitePointChromaticityX(long nativeJniHdrMetadata); private float whitePointChromaticityX() { - return nativeWhitePointChromaticityX(mNativeJniHdrMetadata); + return HdrMetadataJni.get().whitePointChromaticityX( + mNativeJniHdrMetadata, HdrMetadata.this); } - private native float nativeWhitePointChromaticityY(long nativeJniHdrMetadata); private float whitePointChromaticityY() { - return nativeWhitePointChromaticityY(mNativeJniHdrMetadata); + return HdrMetadataJni.get().whitePointChromaticityY( + mNativeJniHdrMetadata, HdrMetadata.this); } - private native float nativeMaxMasteringLuminance(long nativeJniHdrMetadata); private float maxMasteringLuminance() { - return nativeMaxMasteringLuminance(mNativeJniHdrMetadata); + return HdrMetadataJni.get().maxMasteringLuminance(mNativeJniHdrMetadata, HdrMetadata.this); } - private native float nativeMinMasteringLuminance(long nativeJniHdrMetadata); private float minMasteringLuminance() { - return nativeMinMasteringLuminance(mNativeJniHdrMetadata); + return HdrMetadataJni.get().minMasteringLuminance(mNativeJniHdrMetadata, HdrMetadata.this); } - private native int nativeMaxContentLuminance(long nativeJniHdrMetadata); private int maxContentLuminance() { - return nativeMaxContentLuminance(mNativeJniHdrMetadata); + return HdrMetadataJni.get().maxContentLuminance(mNativeJniHdrMetadata, HdrMetadata.this); } - private native int nativeMaxFrameAverageLuminance(long nativeJniHdrMetadata); private int maxFrameAverageLuminance() { - return nativeMaxFrameAverageLuminance(mNativeJniHdrMetadata); + return HdrMetadataJni.get().maxFrameAverageLuminance( + mNativeJniHdrMetadata, HdrMetadata.this); + } + + @NativeMethods + interface Natives { + int primaries(long nativeJniHdrMetadata, HdrMetadata caller); + int colorTransfer(long nativeJniHdrMetadata, HdrMetadata caller); + int range(long nativeJniHdrMetadata, HdrMetadata caller); + float primaryRChromaticityX(long nativeJniHdrMetadata, HdrMetadata caller); + float primaryRChromaticityY(long nativeJniHdrMetadata, HdrMetadata caller); + float primaryGChromaticityX(long nativeJniHdrMetadata, HdrMetadata caller); + float primaryGChromaticityY(long nativeJniHdrMetadata, HdrMetadata caller); + float primaryBChromaticityX(long nativeJniHdrMetadata, HdrMetadata caller); + float primaryBChromaticityY(long nativeJniHdrMetadata, HdrMetadata caller); + float whitePointChromaticityX(long nativeJniHdrMetadata, HdrMetadata caller); + float whitePointChromaticityY(long nativeJniHdrMetadata, HdrMetadata caller); + float maxMasteringLuminance(long nativeJniHdrMetadata, HdrMetadata caller); + float minMasteringLuminance(long nativeJniHdrMetadata, HdrMetadata caller); + int maxContentLuminance(long nativeJniHdrMetadata, HdrMetadata caller); + int maxFrameAverageLuminance(long nativeJniHdrMetadata, HdrMetadata caller); } }
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java index 4a8050d..8543b7e 100644 --- a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java +++ b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
@@ -22,6 +22,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.MainDex; +import org.chromium.base.annotations.NativeMethods; import java.nio.ByteBuffer; import java.util.LinkedList; @@ -280,12 +281,16 @@ mNativeMediaCodecBridge = nativeMediaCodecBridge; // If any buffers or errors occurred before this, trigger the callback now. - if (!mPendingInputBuffers.isEmpty() || !mPendingOutputBuffers.isEmpty() || mPendingError) + if (!mPendingInputBuffers.isEmpty() || !mPendingOutputBuffers.isEmpty() || mPendingError) { notifyBuffersAvailable(); + } } private synchronized void notifyBuffersAvailable() { - if (mNativeMediaCodecBridge != 0) nativeOnBuffersAvailable(mNativeMediaCodecBridge); + if (mNativeMediaCodecBridge != 0) { + MediaCodecBridgeJni.get().onBuffersAvailable( + mNativeMediaCodecBridge, MediaCodecBridge.this); + } } public synchronized void onError(MediaCodec.CodecException e) { @@ -396,8 +401,9 @@ if (mUseAsyncApi) { synchronized (this) { if (mPendingError) return new DequeueInputResult(MediaCodecStatus.ERROR, -1); - if (mPendingStart || mPendingInputBuffers.isEmpty()) + if (mPendingStart || mPendingInputBuffers.isEmpty()) { return new DequeueInputResult(MediaCodecStatus.TRY_AGAIN_LATER, -1); + } return mPendingInputBuffers.remove(); } } @@ -631,8 +637,9 @@ private DequeueOutputResult dequeueOutputBuffer(long timeoutUs) { if (mUseAsyncApi) { synchronized (this) { - if (mPendingError) + if (mPendingError) { return new DequeueOutputResult(MediaCodecStatus.ERROR, -1, 0, 0, 0, 0); + } if (mPendingOutputBuffers.isEmpty()) { return new DequeueOutputResult( MediaCodecStatus.TRY_AGAIN_LATER, -1, 0, 0, 0, 0); @@ -757,5 +764,8 @@ sCallbackHandler = new Handler(sCallbackHandlerThread.getLooper()); } - private native void nativeOnBuffersAvailable(long nativeMediaCodecBridge); + @NativeMethods + interface Natives { + void onBuffersAvailable(long nativeMediaCodecBridge, MediaCodecBridge caller); + } }
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 95cd4cf..14128647 100644 --- a/media/base/android/java/src/org/chromium/media/MediaDrmBridge.java +++ b/media/base/android/java/src/org/chromium/media/MediaDrmBridge.java
@@ -16,6 +16,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.MainDex; +import org.chromium.base.annotations.NativeMethods; import org.chromium.media.MediaDrmSessionManager.SessionId; import org.chromium.media.MediaDrmSessionManager.SessionInfo; @@ -582,7 +583,7 @@ * Provision the current origin. Normally provisioning will be triggered * automatically when MediaCrypto is needed (in the constructor). * However, this is available to preprovision an origin separately. - * nativeOnProvisioningComplete() will be called indicating success/failure. + * MediaDrmBridgeJni.get().onProvisioningComplete() will be called indicating success/failure. */ @CalledByNative private void provision() { @@ -594,7 +595,8 @@ // Provision only works for origin isolated storage. if (!mOriginSet) { Log.e(TAG, "Calling provision() without an origin."); - nativeOnProvisioningComplete(mNativeMediaDrmBridge, false); + MediaDrmBridgeJni.get().onProvisioningComplete( + mNativeMediaDrmBridge, MediaDrmBridge.this, false); return; } @@ -615,12 +617,14 @@ } // Indicate that provisioning succeeded. - nativeOnProvisioningComplete(mNativeMediaDrmBridge, true); + MediaDrmBridgeJni.get().onProvisioningComplete( + mNativeMediaDrmBridge, MediaDrmBridge.this, true); } catch (android.media.NotProvisionedException e) { if (!startProvisioning()) { // Indicate that provisioning failed. - nativeOnProvisioningComplete(mNativeMediaDrmBridge, false); + MediaDrmBridgeJni.get().onProvisioningComplete( + mNativeMediaDrmBridge, MediaDrmBridge.this, false); } } } @@ -1200,7 +1204,8 @@ return false; } - nativeOnProvisionRequest(mNativeMediaDrmBridge, request.getDefaultUrl(), request.getData()); + MediaDrmBridgeJni.get().onProvisionRequest(mNativeMediaDrmBridge, MediaDrmBridge.this, + request.getDefaultUrl(), request.getData()); return true; } @@ -1266,7 +1271,8 @@ void onProvisioned(boolean success) { if (!mRequiresMediaCrypto) { // No MediaCrypto required, so notify provisioning complete. - nativeOnProvisioningComplete(mNativeMediaDrmBridge, success); + MediaDrmBridgeJni.get().onProvisioningComplete( + mNativeMediaDrmBridge, MediaDrmBridge.this, success); if (!success) { release(); } @@ -1318,26 +1324,30 @@ private void onMediaCryptoReady(MediaCrypto mediaCrypto) { if (isNativeMediaDrmBridgeValid()) { - nativeOnMediaCryptoReady(mNativeMediaDrmBridge, mediaCrypto); + MediaDrmBridgeJni.get().onMediaCryptoReady( + mNativeMediaDrmBridge, MediaDrmBridge.this, mediaCrypto); } } private void onPromiseResolved(final long promiseId) { if (isNativeMediaDrmBridgeValid()) { - nativeOnPromiseResolved(mNativeMediaDrmBridge, promiseId); + MediaDrmBridgeJni.get().onPromiseResolved( + mNativeMediaDrmBridge, MediaDrmBridge.this, promiseId); } } private void onPromiseResolvedWithSession(final long promiseId, final SessionId sessionId) { if (isNativeMediaDrmBridgeValid()) { - nativeOnPromiseResolvedWithSession(mNativeMediaDrmBridge, promiseId, sessionId.emeId()); + MediaDrmBridgeJni.get().onPromiseResolvedWithSession( + mNativeMediaDrmBridge, MediaDrmBridge.this, promiseId, sessionId.emeId()); } } private void onPromiseRejected(final long promiseId, final String errorMessage) { Log.e(TAG, "onPromiseRejected: %s", errorMessage); if (isNativeMediaDrmBridgeValid()) { - nativeOnPromiseRejected(mNativeMediaDrmBridge, promiseId, errorMessage); + MediaDrmBridgeJni.get().onPromiseRejected( + mNativeMediaDrmBridge, MediaDrmBridge.this, promiseId, errorMessage); } } @@ -1356,28 +1366,29 @@ : MediaDrm.KeyRequest.REQUEST_TYPE_RENEWAL; } - nativeOnSessionMessage( - mNativeMediaDrmBridge, sessionId.emeId(), requestType, request.getData()); + MediaDrmBridgeJni.get().onSessionMessage(mNativeMediaDrmBridge, MediaDrmBridge.this, + sessionId.emeId(), requestType, request.getData()); } private void onSessionClosed(final SessionId sessionId) { if (isNativeMediaDrmBridgeValid()) { - nativeOnSessionClosed(mNativeMediaDrmBridge, sessionId.emeId()); + MediaDrmBridgeJni.get().onSessionClosed( + mNativeMediaDrmBridge, MediaDrmBridge.this, sessionId.emeId()); } } private void onSessionKeysChange(final SessionId sessionId, final Object[] keysInfo, final boolean hasAdditionalUsableKey, final boolean isKeyRelease) { if (isNativeMediaDrmBridgeValid()) { - nativeOnSessionKeysChange(mNativeMediaDrmBridge, sessionId.emeId(), keysInfo, - hasAdditionalUsableKey, isKeyRelease); + MediaDrmBridgeJni.get().onSessionKeysChange(mNativeMediaDrmBridge, MediaDrmBridge.this, + sessionId.emeId(), keysInfo, hasAdditionalUsableKey, isKeyRelease); } } private void onSessionExpirationUpdate(final SessionId sessionId, final long expirationTime) { if (isNativeMediaDrmBridgeValid()) { - nativeOnSessionExpirationUpdate( - mNativeMediaDrmBridge, sessionId.emeId(), expirationTime); + MediaDrmBridgeJni.get().onSessionExpirationUpdate( + mNativeMediaDrmBridge, MediaDrmBridge.this, sessionId.emeId(), expirationTime); } } @@ -1529,26 +1540,30 @@ } } - // Native functions. At the native side, must post the task immediately to - // avoid reentrancy issues. - private native void nativeOnMediaCryptoReady( - long nativeMediaDrmBridge, MediaCrypto mediaCrypto); + // At the native side, must post the task immediately to avoid reentrancy issues. + @NativeMethods + interface Natives { + void onMediaCryptoReady( + long nativeMediaDrmBridge, MediaDrmBridge caller, MediaCrypto mediaCrypto); - private native void nativeOnProvisionRequest( - long nativeMediaDrmBridge, String defaultUrl, byte[] requestData); - private native void nativeOnProvisioningComplete(long nativeMediaDrmBridge, boolean success); + void onProvisionRequest(long nativeMediaDrmBridge, MediaDrmBridge caller, String defaultUrl, + byte[] requestData); + void onProvisioningComplete( + long nativeMediaDrmBridge, MediaDrmBridge caller, boolean success); - private native void nativeOnPromiseResolved(long nativeMediaDrmBridge, long promiseId); - private native void nativeOnPromiseResolvedWithSession( - long nativeMediaDrmBridge, long promiseId, byte[] emeSessionId); - private native void nativeOnPromiseRejected( - long nativeMediaDrmBridge, long promiseId, String errorMessage); + void onPromiseResolved(long nativeMediaDrmBridge, MediaDrmBridge caller, long promiseId); + void onPromiseResolvedWithSession(long nativeMediaDrmBridge, MediaDrmBridge caller, + long promiseId, byte[] emeSessionId); + void onPromiseRejected(long nativeMediaDrmBridge, MediaDrmBridge caller, long promiseId, + String errorMessage); - private native void nativeOnSessionMessage( - long nativeMediaDrmBridge, byte[] emeSessionId, int requestType, byte[] message); - private native void nativeOnSessionClosed(long nativeMediaDrmBridge, byte[] emeSessionId); - private native void nativeOnSessionKeysChange(long nativeMediaDrmBridge, byte[] emeSessionId, - Object[] keysInfo, boolean hasAdditionalUsableKey, boolean isKeyRelease); - private native void nativeOnSessionExpirationUpdate( - long nativeMediaDrmBridge, byte[] emeSessionId, long expirationTime); + void onSessionMessage(long nativeMediaDrmBridge, MediaDrmBridge caller, byte[] emeSessionId, + int requestType, byte[] message); + void onSessionClosed(long nativeMediaDrmBridge, MediaDrmBridge caller, byte[] emeSessionId); + void onSessionKeysChange(long nativeMediaDrmBridge, MediaDrmBridge caller, + byte[] emeSessionId, Object[] keysInfo, boolean hasAdditionalUsableKey, + boolean isKeyRelease); + void onSessionExpirationUpdate(long nativeMediaDrmBridge, MediaDrmBridge caller, + byte[] emeSessionId, long expirationTime); + } }
diff --git a/media/base/android/java/src/org/chromium/media/MediaDrmStorageBridge.java b/media/base/android/java/src/org/chromium/media/MediaDrmStorageBridge.java index 8cfe7a5..13ced310 100644 --- a/media/base/android/java/src/org/chromium/media/MediaDrmStorageBridge.java +++ b/media/base/android/java/src/org/chromium/media/MediaDrmStorageBridge.java
@@ -11,6 +11,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.MainDex; +import org.chromium.base.annotations.NativeMethods; /** * Origin isolated media drm scope id storage. Isolated origin is guranteed by native @@ -85,7 +86,8 @@ */ void onProvisioned(Callback<Boolean> cb) { if (isNativeMediaDrmStorageValid()) { - nativeOnProvisioned(mNativeMediaDrmStorageBridge, cb); + MediaDrmStorageBridgeJni.get().onProvisioned( + mNativeMediaDrmStorageBridge, MediaDrmStorageBridge.this, cb); } else { cb.onResult(true); } @@ -96,7 +98,8 @@ */ void loadInfo(byte[] emeId, Callback<PersistentInfo> cb) { if (isNativeMediaDrmStorageValid()) { - nativeOnLoadInfo(mNativeMediaDrmStorageBridge, emeId, cb); + MediaDrmStorageBridgeJni.get().onLoadInfo( + mNativeMediaDrmStorageBridge, MediaDrmStorageBridge.this, emeId, cb); } else { cb.onResult(null); } @@ -107,7 +110,8 @@ */ void saveInfo(PersistentInfo info, Callback<Boolean> cb) { if (isNativeMediaDrmStorageValid()) { - nativeOnSaveInfo(mNativeMediaDrmStorageBridge, info, cb); + MediaDrmStorageBridgeJni.get().onSaveInfo( + mNativeMediaDrmStorageBridge, MediaDrmStorageBridge.this, info, cb); } else { cb.onResult(false); } @@ -118,7 +122,8 @@ */ void clearInfo(byte[] emeId, Callback<Boolean> cb) { if (isNativeMediaDrmStorageValid()) { - nativeOnClearInfo(mNativeMediaDrmStorageBridge, emeId, cb); + MediaDrmStorageBridgeJni.get().onClearInfo( + mNativeMediaDrmStorageBridge, MediaDrmStorageBridge.this, emeId, cb); } else { cb.onResult(true); } @@ -128,11 +133,15 @@ return mNativeMediaDrmStorageBridge != INVALID_NATIVE_MEDIA_DRM_STORAGE_BRIDGE; } - private native void nativeOnProvisioned(long nativeMediaDrmStorageBridge, Callback<Boolean> cb); - private native void nativeOnLoadInfo( - long nativeMediaDrmStorageBridge, byte[] sessionId, Callback<PersistentInfo> cb); - private native void nativeOnSaveInfo( - long nativeMediaDrmStorageBridge, PersistentInfo info, Callback<Boolean> cb); - private native void nativeOnClearInfo( - long nativeMediaDrmStorageBridge, byte[] sessionId, Callback<Boolean> cb); + @NativeMethods + interface Natives { + void onProvisioned(long nativeMediaDrmStorageBridge, MediaDrmStorageBridge caller, + Callback<Boolean> cb); + void onLoadInfo(long nativeMediaDrmStorageBridge, MediaDrmStorageBridge caller, + byte[] sessionId, Callback<PersistentInfo> cb); + void onSaveInfo(long nativeMediaDrmStorageBridge, MediaDrmStorageBridge caller, + PersistentInfo info, Callback<Boolean> cb); + void onClearInfo(long nativeMediaDrmStorageBridge, MediaDrmStorageBridge caller, + byte[] sessionId, Callback<Boolean> cb); + } }
diff --git a/media/base/android/java/src/org/chromium/media/MediaPlayerBridge.java b/media/base/android/java/src/org/chromium/media/MediaPlayerBridge.java index aaeef434..79b54374 100644 --- a/media/base/android/java/src/org/chromium/media/MediaPlayerBridge.java +++ b/media/base/android/java/src/org/chromium/media/MediaPlayerBridge.java
@@ -20,6 +20,7 @@ import org.chromium.base.StreamUtil; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import org.chromium.base.task.AsyncTask; import java.io.ByteArrayInputStream; @@ -236,7 +237,8 @@ deleteFile(); assert (mNativeMediaPlayerBridge != 0); - nativeOnDidSetDataUriDataSource(mNativeMediaPlayerBridge, result); + MediaPlayerBridgeJni.get().onDidSetDataUriDataSource( + mNativeMediaPlayerBridge, MediaPlayerBridge.this, result); } private void deleteFile() { @@ -328,13 +330,16 @@ return new AllowedOperations(canSeekForward, canSeekBackward); } - private native void nativeOnDidSetDataUriDataSource(long nativeMediaPlayerBridge, - boolean success); - private void cancelLoadDataUriTask() { if (mLoadDataUriTask != null) { mLoadDataUriTask.cancel(true); mLoadDataUriTask = null; } } + + @NativeMethods + interface Natives { + void onDidSetDataUriDataSource( + long nativeMediaPlayerBridge, MediaPlayerBridge caller, boolean success); + } }
diff --git a/media/base/android/java/src/org/chromium/media/MediaPlayerListener.java b/media/base/android/java/src/org/chromium/media/MediaPlayerListener.java index 9c4e601..86426ff 100644 --- a/media/base/android/java/src/org/chromium/media/MediaPlayerListener.java +++ b/media/base/android/java/src/org/chromium/media/MediaPlayerListener.java
@@ -8,6 +8,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; // This class implements all the listener interface for android mediaplayer. // Callbacks will be sent to the native class for processing. @@ -66,23 +67,27 @@ errorType = MEDIA_ERROR_INVALID_CODE; break; } - nativeOnMediaError(mNativeMediaPlayerListener, errorType); + MediaPlayerListenerJni.get().onMediaError( + mNativeMediaPlayerListener, MediaPlayerListener.this, errorType); return true; } @Override public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { - nativeOnVideoSizeChanged(mNativeMediaPlayerListener, width, height); + MediaPlayerListenerJni.get().onVideoSizeChanged( + mNativeMediaPlayerListener, MediaPlayerListener.this, width, height); } @Override public void onCompletion(MediaPlayer mp) { - nativeOnPlaybackComplete(mNativeMediaPlayerListener); + MediaPlayerListenerJni.get().onPlaybackComplete( + mNativeMediaPlayerListener, MediaPlayerListener.this); } @Override public void onPrepared(MediaPlayer mp) { - nativeOnMediaPrepared(mNativeMediaPlayerListener); + MediaPlayerListenerJni.get().onMediaPrepared( + mNativeMediaPlayerListener, MediaPlayerListener.this); } @CalledByNative @@ -101,15 +106,14 @@ /** * See media/base/android/media_player_listener.cc for all the following functions. */ - private native void nativeOnMediaError( - long nativeMediaPlayerListener, - int errorType); - private native void nativeOnVideoSizeChanged( - long nativeMediaPlayerListener, - int width, int height); - - private native void nativeOnMediaPrepared(long nativeMediaPlayerListener); - - private native void nativeOnPlaybackComplete(long nativeMediaPlayerListener); + @NativeMethods + interface Natives { + void onMediaError( + long nativeMediaPlayerListener, MediaPlayerListener caller, int errorType); + void onVideoSizeChanged( + long nativeMediaPlayerListener, MediaPlayerListener caller, int width, int height); + void onMediaPrepared(long nativeMediaPlayerListener, MediaPlayerListener caller); + void onPlaybackComplete(long nativeMediaPlayerListener, MediaPlayerListener caller); + } }
diff --git a/media/base/android/java/src/org/chromium/media/MediaServerCrashListener.java b/media/base/android/java/src/org/chromium/media/MediaServerCrashListener.java index 04c5787..409eef9 100644 --- a/media/base/android/java/src/org/chromium/media/MediaServerCrashListener.java +++ b/media/base/android/java/src/org/chromium/media/MediaServerCrashListener.java
@@ -11,6 +11,7 @@ import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; /** * Class for listening to Android MediaServer crashes to throttle media decoding @@ -83,7 +84,8 @@ || (currentTime - mLastReportedWatchdogCreationFailure) > APPROX_MEDIA_SERVER_RESTART_TIME_IN_MS) { Log.e(TAG, "Unable to create watchdog player, treating it as server crash."); - nativeOnMediaServerCrashDetected(mNativeMediaServerCrashListener, false); + MediaServerCrashListenerJni.get().onMediaServerCrashDetected( + mNativeMediaServerCrashListener, MediaServerCrashListener.this, false); mLastReportedWatchdogCreationFailure = currentTime; } return false; @@ -92,12 +94,16 @@ @Override public boolean onError(MediaPlayer mp, int what, int extra) { if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) { - nativeOnMediaServerCrashDetected(mNativeMediaServerCrashListener, true); + MediaServerCrashListenerJni.get().onMediaServerCrashDetected( + mNativeMediaServerCrashListener, MediaServerCrashListener.this, true); releaseWatchdog(); } return true; } - private native void nativeOnMediaServerCrashDetected( - long nativeMediaServerCrashListener, boolean watchdogNeedsRelease); + @NativeMethods + interface Natives { + void onMediaServerCrashDetected(long nativeMediaServerCrashListener, + MediaServerCrashListener caller, boolean watchdogNeedsRelease); + } }
diff --git a/media/base/cdm_context.cc b/media/base/cdm_context.cc index 6f8fadb..90e69383 100644 --- a/media/base/cdm_context.cc +++ b/media/base/cdm_context.cc
@@ -37,6 +37,12 @@ } #endif +#if defined(OS_FUCHSIA) +FuchsiaCdmContext* CdmContext::GetFuchsiaCdmContext() { + return nullptr; +} +#endif + void IgnoreCdmAttached(bool /* success */) {} } // namespace media
diff --git a/media/base/cdm_context.h b/media/base/cdm_context.h index cd59098..eaa4d15a 100644 --- a/media/base/cdm_context.h +++ b/media/base/cdm_context.h
@@ -18,6 +18,10 @@ class Decryptor; class MediaCryptoContext; +#if defined(OS_FUCHSIA) +class FuchsiaCdmContext; +#endif + // An interface representing the context that a media player needs from a // content decryption module (CDM) to decrypt (and decode) encrypted buffers. // Typically this will be passed to the media player (e.g. using SetCdm()). @@ -90,6 +94,12 @@ virtual MediaCryptoContext* GetMediaCryptoContext(); #endif +#if defined(OS_FUCHSIA) + // Returns FuchsiaCdmContext interface when the context is backed by Fuchsia + // CDM. Otherwise returns nullptr. + virtual FuchsiaCdmContext* GetFuchsiaCdmContext(); +#endif + protected: CdmContext();
diff --git a/media/capture/content/android/BUILD.gn b/media/capture/content/android/BUILD.gn index 6c2530e..6f4eb569 100644 --- a/media/capture/content/android/BUILD.gn +++ b/media/capture/content/android/BUILD.gn
@@ -38,6 +38,8 @@ android_library("screen_capture_java") { deps = [ "//base:base_java", + "//base:jni_java", ] java_files = [ "java/src/org/chromium/media/ScreenCapture.java" ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] }
diff --git a/media/capture/content/android/java/src/org/chromium/media/ScreenCapture.java b/media/capture/content/android/java/src/org/chromium/media/ScreenCapture.java index 73789db..5b53ede5 100644 --- a/media/capture/content/android/java/src/org/chromium/media/ScreenCapture.java +++ b/media/capture/content/android/java/src/org/chromium/media/ScreenCapture.java
@@ -34,6 +34,7 @@ import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -143,7 +144,8 @@ throw new IllegalStateException(); } - nativeOnRGBAFrameAvailable(mNativeScreenCaptureMachineAndroid, + ScreenCaptureJni.get().onRGBAFrameAvailable( + mNativeScreenCaptureMachineAndroid, ScreenCapture.this, image.getPlanes()[0].getBuffer(), image.getPlanes()[0].getRowStride(), image.getCropRect().left, image.getCropRect().top, image.getCropRect().width(), @@ -158,7 +160,8 @@ // The pixel stride of Y plane is always 1. The U/V planes are guaranteed // to have the same row stride and pixel stride. - nativeOnI420FrameAvailable(mNativeScreenCaptureMachineAndroid, + ScreenCaptureJni.get().onI420FrameAvailable( + mNativeScreenCaptureMachineAndroid, ScreenCapture.this, image.getPlanes()[0].getBuffer(), image.getPlanes()[0].getRowStride(), image.getPlanes()[1].getBuffer(), image.getPlanes()[2].getBuffer(), @@ -294,8 +297,8 @@ mResultData = data; changeCaptureStateAndNotify(CaptureState.ALLOWED); } - nativeOnActivityResult( - mNativeScreenCaptureMachineAndroid, resultCode == Activity.RESULT_OK); + ScreenCaptureJni.get().onActivityResult(mNativeScreenCaptureMachineAndroid, + ScreenCapture.this, resultCode == Activity.RESULT_OK); } @CalledByNative @@ -423,7 +426,8 @@ mCurrentOrientation = orientation; rotateCaptureOrientation(orientation); - nativeOnOrientationChange(mNativeScreenCaptureMachineAndroid, rotation); + ScreenCaptureJni.get().onOrientationChange( + mNativeScreenCaptureMachineAndroid, ScreenCapture.this, rotation); return true; } @@ -434,21 +438,23 @@ } } - // Method for ScreenCapture implementations to call back native code. - private native void nativeOnRGBAFrameAvailable(long nativeScreenCaptureMachineAndroid, - ByteBuffer buf, int rowStride, int left, int top, int width, int height, - long timestamp); + @NativeMethods + interface Natives { + // Method for ScreenCapture implementations to call back native code. + void onRGBAFrameAvailable(long nativeScreenCaptureMachineAndroid, ScreenCapture caller, + ByteBuffer buf, int rowStride, int left, int top, int width, int height, + long timestamp); - private native void nativeOnI420FrameAvailable(long nativeScreenCaptureMachineAndroid, - ByteBuffer yBuffer, int yStride, ByteBuffer uBuffer, ByteBuffer vBuffer, - int uvRowStride, int uvPixelStride, int left, int top, int width, int height, - long timestamp); + void onI420FrameAvailable(long nativeScreenCaptureMachineAndroid, ScreenCapture caller, + ByteBuffer yBuffer, int yStride, ByteBuffer uBuffer, ByteBuffer vBuffer, + int uvRowStride, int uvPixelStride, int left, int top, int width, int height, + long timestamp); + // Method for ScreenCapture implementations to notify activity result. + void onActivityResult( + long nativeScreenCaptureMachineAndroid, ScreenCapture caller, boolean result); - // Method for ScreenCapture implementations to notify activity result. - private native void nativeOnActivityResult( - long nativeScreenCaptureMachineAndroid, boolean result); - - // Method for ScreenCapture implementations to notify orientation change. - private native void nativeOnOrientationChange( - long nativeScreenCaptureMachineAndroid, int rotation); + // Method for ScreenCapture implementations to notify orientation change. + void onOrientationChange( + long nativeScreenCaptureMachineAndroid, ScreenCapture caller, int rotation); + } }
diff --git a/media/capture/video/android/BUILD.gn b/media/capture/video/android/BUILD.gn index bf3297e..8c8d366 100644 --- a/media/capture/video/android/BUILD.gn +++ b/media/capture/video/android/BUILD.gn
@@ -51,8 +51,10 @@ android_library("capture_java") { deps = [ "//base:base_java", + "//base:jni_java", "//third_party/android_deps:androidx_annotation_annotation_java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] srcjar_deps = [ ":media_java_enums_srcjar" ]
diff --git a/media/capture/video/android/java/src/org/chromium/media/VideoCapture.java b/media/capture/video/android/java/src/org/chromium/media/VideoCapture.java index 9853d9c..e35e102 100644 --- a/media/capture/video/android/java/src/org/chromium/media/VideoCapture.java +++ b/media/capture/video/android/java/src/org/chromium/media/VideoCapture.java
@@ -12,6 +12,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -64,11 +65,11 @@ int width, int height, int frameRate, boolean enableFaceDetection); // Success is indicated by returning true and a callback to - // nativeOnStarted(), which may occur synchronously or asynchronously. - // Failure can be indicated by one of the following: - // * Returning false. In this case no callback to nativeOnStarted() is made. - // * Returning true, and asynchronously invoking nativeOnError. In this case - // also no callback to nativeOnStarted() is made. + // VideoCaptureJni.get().onStarted(, VideoCapture.this), which may occur synchronously or + // asynchronously. Failure can be indicated by one of the following: + // * Returning false. In this case no callback to VideoCaptureJni.get().onStarted() is made. + // * Returning true, and asynchronously invoking VideoCaptureJni.get().onError. In this case + // also no callback to VideoCaptureJni.get().onStarted() is made. @CalledByNative public abstract boolean startCaptureMaybeAsync(); @@ -76,7 +77,7 @@ @CalledByNative public abstract boolean stopCaptureAndBlockUntilStopped(); - // Replies by calling nativeOnGetPhotoCapabilitiesReply(). Will pass |null| + // Replies by calling VideoCaptureJni.get().onGetPhotoCapabilitiesReply(). Will pass |null| // for parameter |result| to indicate failure. @CalledByNative public abstract void getPhotoCapabilitiesAsync(long callbackId); @@ -107,7 +108,7 @@ int whiteBalanceMode, double iso, boolean hasRedEyeReduction, boolean redEyeReduction, int fillLightMode, boolean hasTorch, boolean torch, double colorTemperature); - // Replies by calling nativeOnPhotoTaken(). + // Replies by calling VideoCaptureJni.get().onPhotoTaken(). @CalledByNative public abstract void takePhotoAsync(long callbackId); @@ -177,10 +178,11 @@ return orientation; } - // {@link nativeOnPhotoTaken()} needs to be called back if there's any + // {@link VideoCaptureJni.get().onPhotoTaken()} needs to be called back if there's any // problem after {@link takePhotoAsync()} has returned true. protected void notifyTakePhotoError(long callbackId) { - nativeOnPhotoTaken(mNativeVideoCaptureDeviceAndroid, callbackId, null); + VideoCaptureJni.get().onPhotoTaken( + mNativeVideoCaptureDeviceAndroid, VideoCapture.this, callbackId, null); } /** @@ -237,34 +239,35 @@ return intArray; } - // Method for VideoCapture implementations to call back native code. - public native void nativeOnFrameAvailable( - long nativeVideoCaptureDeviceAndroid, byte[] data, int length, int rotation); + @NativeMethods + interface Natives { + // Method for VideoCapture implementations to call back native code. + void onFrameAvailable(long nativeVideoCaptureDeviceAndroid, VideoCapture caller, + byte[] data, int length, int rotation); - public native void nativeOnI420FrameAvailable(long nativeVideoCaptureDeviceAndroid, - ByteBuffer yBuffer, int yStride, ByteBuffer uBuffer, ByteBuffer vBuffer, - int uvRowStride, int uvPixelStride, int width, int height, int rotation, - long timestamp); + void onI420FrameAvailable(long nativeVideoCaptureDeviceAndroid, VideoCapture caller, + ByteBuffer yBuffer, int yStride, ByteBuffer uBuffer, ByteBuffer vBuffer, + int uvRowStride, int uvPixelStride, int width, int height, int rotation, + long timestamp); + // Method for VideoCapture implementations to signal an asynchronous error. + void onError(long nativeVideoCaptureDeviceAndroid, VideoCapture caller, + int androidVideoCaptureError, String message); - // Method for VideoCapture implementations to signal an asynchronous error. - public native void nativeOnError( - long nativeVideoCaptureDeviceAndroid, int androidVideoCaptureError, String message); + // Method for VideoCapture implementations to signal that a frame was dropped. + void onFrameDropped(long nativeVideoCaptureDeviceAndroid, VideoCapture caller, + int androidVideoCaptureFrameDropReason); - // Method for VideoCapture implementations to signal that a frame was dropped. - public native void nativeOnFrameDropped( - long nativeVideoCaptureDeviceAndroid, int androidVideoCaptureFrameDropReason); + void onGetPhotoCapabilitiesReply(long nativeVideoCaptureDeviceAndroid, VideoCapture caller, + long callbackId, PhotoCapabilities result); + // Callback for calls to takePhoto(). This can indicate both success and + // failure. Failure is indicated by |data| being null. + void onPhotoTaken(long nativeVideoCaptureDeviceAndroid, VideoCapture caller, + long callbackId, byte[] data); - public native void nativeOnGetPhotoCapabilitiesReply( - long nativeVideoCaptureDeviceAndroid, long callbackId, PhotoCapabilities result); + // Method for VideoCapture implementations to report device started event. + void onStarted(long nativeVideoCaptureDeviceAndroid, VideoCapture caller); - // Callback for calls to takePhoto(). This can indicate both success and - // failure. Failure is indicated by |data| being null. - public native void nativeOnPhotoTaken( - long nativeVideoCaptureDeviceAndroid, long callbackId, byte[] data); - - // Method for VideoCapture implementations to report device started event. - public native void nativeOnStarted(long nativeVideoCaptureDeviceAndroid); - - public native void nativeDCheckCurrentlyOnIncomingTaskRunner( - long nativeVideoCaptureDeviceAndroid); + void dCheckCurrentlyOnIncomingTaskRunner( + long nativeVideoCaptureDeviceAndroid, VideoCapture caller); + } }
diff --git a/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera.java b/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera.java index d541593d..95ede71 100644 --- a/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera.java +++ b/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera.java
@@ -142,7 +142,7 @@ private class CrErrorCallback implements android.hardware.Camera.ErrorCallback { @Override public void onError(int error, android.hardware.Camera camera) { - nativeOnError(mNativeVideoCaptureDeviceAndroid, + VideoCaptureJni.get().onError(mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera.this, AndroidVideoCaptureError.ANDROID_API_1_CAMERA_ERROR_CALLBACK_RECEIVED, "Error id: " + error); @@ -170,8 +170,8 @@ } synchronized (mPhotoTakenCallbackLock) { if (mPhotoTakenCallbackId != 0) { - nativeOnPhotoTaken( - mNativeVideoCaptureDeviceAndroid, mPhotoTakenCallbackId, data); + VideoCaptureJni.get().onPhotoTaken(mNativeVideoCaptureDeviceAndroid, + VideoCaptureCamera.this, mPhotoTakenCallbackId, data); } mPhotoTakenCallbackId = 0; } @@ -451,7 +451,8 @@ mPreviewBufferLock.lock(); try { - nativeOnStarted(mNativeVideoCaptureDeviceAndroid); + VideoCaptureJni.get().onStarted( + mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera.this); mIsRunning = true; } finally { mPreviewBufferLock.unlock(); @@ -485,7 +486,8 @@ public void getPhotoCapabilitiesAsync(long callbackId) { final android.hardware.Camera.Parameters parameters = getCameraParameters(mCamera); if (parameters == null) { - nativeOnGetPhotoCapabilitiesReply(mNativeVideoCaptureDeviceAndroid, callbackId, null); + VideoCaptureJni.get().onGetPhotoCapabilitiesReply( + mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera.this, callbackId, null); return; } PhotoCapabilities.Builder builder = new PhotoCapabilities.Builder(); @@ -628,9 +630,10 @@ .setInt(PhotoCapabilityInt.STEP_COLOR_TEMPERATURE, 50); if (jniWhiteBalanceMode == AndroidMeteringMode.FIXED) { final int index = COLOR_TEMPERATURES_MAP.indexOfValue(parameters.getWhiteBalance()); - if (index >= 0) + if (index >= 0) { builder.setInt(PhotoCapabilityInt.CURRENT_COLOR_TEMPERATURE, COLOR_TEMPERATURES_MAP.keyAt(index)); + } } final List<String> flashModes = parameters.getSupportedFlashModes(); @@ -657,8 +660,8 @@ builder.setFillLightModeArray(integerArrayListToArray(modes)); } - nativeOnGetPhotoCapabilitiesReply( - mNativeVideoCaptureDeviceAndroid, callbackId, builder.build()); + VideoCaptureJni.get().onGetPhotoCapabilitiesReply(mNativeVideoCaptureDeviceAndroid, + VideoCaptureCamera.this, callbackId, builder.build()); } @Override @@ -892,10 +895,11 @@ return; } if (data.length == mExpectedFrameSize) { - nativeOnFrameAvailable(mNativeVideoCaptureDeviceAndroid, data, mExpectedFrameSize, - getCameraRotation()); + VideoCaptureJni.get().onFrameAvailable(mNativeVideoCaptureDeviceAndroid, + VideoCaptureCamera.this, data, mExpectedFrameSize, getCameraRotation()); } else { - nativeOnFrameDropped(mNativeVideoCaptureDeviceAndroid, + VideoCaptureJni.get().onFrameDropped(mNativeVideoCaptureDeviceAndroid, + VideoCaptureCamera.this, AndroidVideoCaptureFrameDropReason.ANDROID_API_1_UNEXPECTED_DATA_LENGTH); } } finally {
diff --git a/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java b/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java index 25049fa..bd68edca 100644 --- a/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java +++ b/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java
@@ -87,7 +87,8 @@ cameraDevice.close(); mCameraDevice = null; changeCameraStateAndNotify(CameraState.STOPPED); - nativeOnError(mNativeVideoCaptureDeviceAndroid, + VideoCaptureJni.get().onError(mNativeVideoCaptureDeviceAndroid, + VideoCaptureCamera2.this, AndroidVideoCaptureError.ANDROID_API_2_CAMERA_DEVICE_ERROR_RECEIVED, "Camera device error " + Integer.toString(error)); } @@ -146,7 +147,8 @@ } changeCameraStateAndNotify(CameraState.STARTED); - nativeOnStarted(mNativeVideoCaptureDeviceAndroid); + VideoCaptureJni.get().onStarted( + mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera2.this); // Frames will be arriving at CrPreviewReaderListener.onImageAvailable(); } @@ -160,7 +162,8 @@ // cleanup? changeCameraStateAndNotify(CameraState.STOPPED); mPreviewSession = null; - nativeOnError(mNativeVideoCaptureDeviceAndroid, + VideoCaptureJni.get().onError(mNativeVideoCaptureDeviceAndroid, + VideoCaptureCamera2.this, AndroidVideoCaptureError.ANDROID_API_2_CAPTURE_SESSION_CONFIGURE_FAILED, "Camera session configuration error"); } @@ -186,14 +189,16 @@ try (Image image = reader.acquireLatestImage()) { if (image == null) { - nativeOnFrameDropped(mNativeVideoCaptureDeviceAndroid, + VideoCaptureJni.get().onFrameDropped(mNativeVideoCaptureDeviceAndroid, + VideoCaptureCamera2.this, AndroidVideoCaptureFrameDropReason .ANDROID_API_2_ACQUIRED_IMAGE_IS_NULL); return; } if (image.getFormat() != ImageFormat.YUV_420_888 || image.getPlanes().length != 3) { - nativeOnError(mNativeVideoCaptureDeviceAndroid, + VideoCaptureJni.get().onError(mNativeVideoCaptureDeviceAndroid, + VideoCaptureCamera2.this, AndroidVideoCaptureError .ANDROID_API_2_IMAGE_READER_UNEXPECTED_IMAGE_FORMAT, "Unexpected image format: " + image.getFormat() @@ -203,7 +208,8 @@ if (reader.getWidth() != image.getWidth() || reader.getHeight() != image.getHeight()) { - nativeOnError(mNativeVideoCaptureDeviceAndroid, + VideoCaptureJni.get().onError(mNativeVideoCaptureDeviceAndroid, + VideoCaptureCamera2.this, AndroidVideoCaptureError .ANDROID_API_2_IMAGE_READER_SIZE_DID_NOT_MATCH_IMAGE_SIZE, "ImageReader size (" + reader.getWidth() + "x" + reader.getHeight() @@ -212,12 +218,12 @@ throw new IllegalStateException(); } - nativeOnI420FrameAvailable(mNativeVideoCaptureDeviceAndroid, - image.getPlanes()[0].getBuffer(), image.getPlanes()[0].getRowStride(), - image.getPlanes()[1].getBuffer(), image.getPlanes()[2].getBuffer(), - image.getPlanes()[1].getRowStride(), image.getPlanes()[1].getPixelStride(), - image.getWidth(), image.getHeight(), getCameraRotation(), - image.getTimestamp()); + VideoCaptureJni.get().onI420FrameAvailable(mNativeVideoCaptureDeviceAndroid, + VideoCaptureCamera2.this, image.getPlanes()[0].getBuffer(), + image.getPlanes()[0].getRowStride(), image.getPlanes()[1].getBuffer(), + image.getPlanes()[2].getBuffer(), image.getPlanes()[1].getRowStride(), + image.getPlanes()[1].getPixelStride(), image.getWidth(), image.getHeight(), + getCameraRotation(), image.getTimestamp()); } catch (IllegalStateException ex) { Log.e(TAG, "acquireLatestImage():", ex); } @@ -315,7 +321,8 @@ } final byte[] capturedData = readCapturedData(image); - nativeOnPhotoTaken(mNativeVideoCaptureDeviceAndroid, mCallbackId, capturedData); + VideoCaptureJni.get().onPhotoTaken(mNativeVideoCaptureDeviceAndroid, + VideoCaptureCamera2.this, mCallbackId, capturedData); } catch (IllegalStateException ex) { notifyTakePhotoError(mCallbackId); @@ -464,9 +471,10 @@ if (mCurrentFocusDistance == 0) { Log.d(TAG, "infinity focus."); mCurrentFocusDistance = (long) Double.POSITIVE_INFINITY; - } else if (mCurrentFocusDistance > 0) + } else if (mCurrentFocusDistance > 0) { builder.setDouble(PhotoCapabilityDouble.CURRENT_FOCUS_DISTANCE, 1 / mCurrentFocusDistance); + } } else { // null value Log.d(TAG, "LENS_FOCUS_DISTANCE is null"); } @@ -510,9 +518,10 @@ } else if (focusMode == CameraMetadata.CONTROL_AF_MODE_OFF) { jniFocusMode = AndroidMeteringMode.FIXED; // Set focus distance here. - if (mCurrentFocusDistance > 0) + if (mCurrentFocusDistance > 0) { builder.setDouble(PhotoCapabilityDouble.CURRENT_FOCUS_DISTANCE, 1 / mCurrentFocusDistance); + } } else { assert jniFocusMode == CameraMetadata.CONTROL_AF_MODE_EDOF; } @@ -675,8 +684,8 @@ builder.setFillLightModeArray(integerArrayListToArray(modes)); } - nativeOnGetPhotoCapabilitiesReply( - mNativeVideoCaptureDeviceAndroid, mCallbackId, builder.build()); + VideoCaptureJni.get().onGetPhotoCapabilitiesReply(mNativeVideoCaptureDeviceAndroid, + VideoCaptureCamera2.this, mCallbackId, builder.build()); } } @@ -755,14 +764,16 @@ } if (mOptions.focusMode != AndroidMeteringMode.NOT_SET) mFocusMode = mOptions.focusMode; - if (mOptions.currentFocusDistance != 0) + if (mOptions.currentFocusDistance != 0) { mCurrentFocusDistance = (float) mOptions.currentFocusDistance; - if (mOptions.exposureMode != AndroidMeteringMode.NOT_SET) + } + if (mOptions.exposureMode != AndroidMeteringMode.NOT_SET) { mExposureMode = mOptions.exposureMode; + } if (mOptions.exposureTime != 0) mLastExposureTimeNs = (long) mOptions.exposureTime; - if (mOptions.whiteBalanceMode != AndroidMeteringMode.NOT_SET) + if (mOptions.whiteBalanceMode != AndroidMeteringMode.NOT_SET) { mWhiteBalanceMode = mOptions.whiteBalanceMode; - + } if (mOptions.width > 0) mPhotoWidth = (int) Math.round(mOptions.width); if (mOptions.height > 0) mPhotoHeight = (int) Math.round(mOptions.height); @@ -819,12 +830,13 @@ .floatValue()); } if (mOptions.iso > 0) mIso = (int) Math.round(mOptions.iso); - if (mOptions.colorTemperature > 0) + if (mOptions.colorTemperature > 0) { mColorTemperature = (int) Math.round(mOptions.colorTemperature); - + } if (mOptions.hasRedEyeReduction) mRedEyeReduction = mOptions.redEyeReduction; - if (mOptions.fillLightMode != AndroidFillLightMode.NOT_SET) + if (mOptions.fillLightMode != AndroidFillLightMode.NOT_SET) { mFillLightMode = mOptions.fillLightMode; + } if (mOptions.hasTorch) mTorch = mOptions.torch; if (mPreviewSession != null) { @@ -1016,8 +1028,8 @@ if (createPreviewObjectsAndStartPreview()) return; changeCameraStateAndNotify(CameraState.STOPPED); - nativeOnError(mNativeVideoCaptureDeviceAndroid, androidVideoCaptureError, - "Error starting or restarting preview"); + VideoCaptureJni.get().onError(mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera2.this, + androidVideoCaptureError, "Error starting or restarting preview"); } private boolean createPreviewObjectsAndStartPreview() { @@ -1410,7 +1422,8 @@ VideoCaptureCamera2(int id, long nativeVideoCaptureDeviceAndroid) { super(id, nativeVideoCaptureDeviceAndroid); - nativeDCheckCurrentlyOnIncomingTaskRunner(mNativeVideoCaptureDeviceAndroid); + VideoCaptureJni.get().dCheckCurrentlyOnIncomingTaskRunner( + mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera2.this); HandlerThread thread = new HandlerThread("VideoCaptureCamera2_CameraThread"); thread.start(); @@ -1431,7 +1444,8 @@ @Override public boolean allocate(int width, int height, int frameRate, boolean enableFaceDetection) { Log.d(TAG, "allocate: requested (%d x %d) @%dfps", width, height, frameRate); - nativeDCheckCurrentlyOnIncomingTaskRunner(mNativeVideoCaptureDeviceAndroid); + VideoCaptureJni.get().dCheckCurrentlyOnIncomingTaskRunner( + mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera2.this); synchronized (mCameraStateLock) { if (mCameraState == CameraState.OPENING || mCameraState == CameraState.CONFIGURING) { Log.e(TAG, "allocate() invoked while Camera is busy opening/configuring."); @@ -1489,7 +1503,8 @@ @Override public boolean startCaptureMaybeAsync() { - nativeDCheckCurrentlyOnIncomingTaskRunner(mNativeVideoCaptureDeviceAndroid); + VideoCaptureJni.get().dCheckCurrentlyOnIncomingTaskRunner( + mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera2.this); changeCameraStateAndNotify(CameraState.OPENING); final CameraManager manager = @@ -1511,7 +1526,8 @@ @Override public boolean stopCaptureAndBlockUntilStopped() { - nativeDCheckCurrentlyOnIncomingTaskRunner(mNativeVideoCaptureDeviceAndroid); + VideoCaptureJni.get().dCheckCurrentlyOnIncomingTaskRunner( + mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera2.this); try (TraceEvent trace_event = TraceEvent.scoped("VideoCaptureCamera2.stopCaptureAndBlockUntilStopped")) { // With Camera2 API, the capture is started asynchronously, which will cause problem if @@ -1538,7 +1554,8 @@ @Override public void getPhotoCapabilitiesAsync(long callbackId) { - nativeDCheckCurrentlyOnIncomingTaskRunner(mNativeVideoCaptureDeviceAndroid); + VideoCaptureJni.get().dCheckCurrentlyOnIncomingTaskRunner( + mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera2.this); mCameraThreadHandler.post(new GetPhotoCapabilitiesTask(callbackId)); } @@ -1548,7 +1565,8 @@ boolean hasExposureCompensation, double exposureCompensation, double exposureTime, int whiteBalanceMode, double iso, boolean hasRedEyeReduction, boolean redEyeReduction, int fillLightMode, boolean hasTorch, boolean torch, double colorTemperature) { - nativeDCheckCurrentlyOnIncomingTaskRunner(mNativeVideoCaptureDeviceAndroid); + VideoCaptureJni.get().dCheckCurrentlyOnIncomingTaskRunner( + mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera2.this); mCameraThreadHandler.post(new SetPhotoOptionsTask( new PhotoOptions(zoom, focusMode, currentFocusDistance, exposureMode, width, height, pointsOfInterest2D, hasExposureCompensation, exposureCompensation, @@ -1558,7 +1576,8 @@ @Override public void takePhotoAsync(long callbackId) { - nativeDCheckCurrentlyOnIncomingTaskRunner(mNativeVideoCaptureDeviceAndroid); + VideoCaptureJni.get().dCheckCurrentlyOnIncomingTaskRunner( + mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera2.this); TraceEvent.instant("VideoCaptureCamera2.java", "takePhotoAsync"); mCameraThreadHandler.post(new TakePhotoTask(callbackId));
diff --git a/media/filters/BUILD.gn b/media/filters/BUILD.gn index 9022a76..4cb86a2 100644 --- a/media/filters/BUILD.gn +++ b/media/filters/BUILD.gn
@@ -212,6 +212,7 @@ "//gpu/command_buffer/client", "//gpu/command_buffer/common", "//gpu/ipc/common", + "//media/fuchsia/cdm", "//media/fuchsia/common", "//third_party/fuchsia-sdk/sdk:media", "//third_party/fuchsia-sdk/sdk:mediacodec",
diff --git a/media/filters/fuchsia/fuchsia_video_decoder.cc b/media/filters/fuchsia/fuchsia_video_decoder.cc index 2c8e526..e5be008 100644 --- a/media/filters/fuchsia/fuchsia_video_decoder.cc +++ b/media/filters/fuchsia/fuchsia_video_decoder.cc
@@ -33,6 +33,9 @@ #include "media/base/video_decoder_config.h" #include "media/base/video_frame.h" #include "media/base/video_util.h" +#include "media/fuchsia/cdm/fuchsia_cdm_context.h" +#include "media/fuchsia/cdm/fuchsia_decryptor.h" +#include "media/fuchsia/cdm/fuchsia_stream_decryptor.h" #include "media/fuchsia/common/stream_processor_helper.h" #include "media/fuchsia/common/sysmem_buffer_pool.h" #include "media/fuchsia/common/sysmem_buffer_writer_queue.h" @@ -152,7 +155,8 @@ } // namespace -class FuchsiaVideoDecoder : public VideoDecoder { +class FuchsiaVideoDecoder : public VideoDecoder, + public FuchsiaSecureStreamDecryptor::Client { public: FuchsiaVideoDecoder(gpu::SharedImageInterface* shared_image_interface, gpu::ContextSupport* gpu_context_support, @@ -174,6 +178,12 @@ int GetMaxDecodeRequests() const override; private: + // FuchsiaSecureStreamDecryptor::Client implementation. + void OnDecryptorOutputPacket(StreamProcessorHelper::IoPacket packet) override; + void OnDecryptorEndOfStreamPacket() override; + void OnDecryptorError() override; + void OnDecryptorNoKey() override; + // Event handlers for |codec_|. void OnStreamFailed(uint64_t stream_lifetime_ordinal, fuchsia::media::StreamError error); @@ -227,6 +237,9 @@ // value is used only if the aspect ratio is not specified in the bitstream. float container_pixel_aspect_ratio_ = 1.0; + // Decryptor is allocated only for encrypted streams. + std::unique_ptr<FuchsiaSecureStreamDecryptor> decryptor_; + // TODO(sergeyu): Use StreamProcessorHelper. fuchsia::media::StreamProcessorPtr codec_; BufferAllocator sysmem_allocator_; @@ -238,16 +251,22 @@ // stream_lifetime_ordinal_. bool active_stream_ = false; - // Input buffers. - uint64_t input_buffer_lifetime_ordinal_ = 1; + // Callbacks for pending Decode() request. + std::deque<DecodeCB> decode_callbacks_; + + // Buffer queue for |codec_|. Used only for clear streams, i.e. when there + // is no |decryptor_|. SysmemBufferWriterQueue input_writer_queue_; + + // Input buffers for |codec_|. + uint64_t input_buffer_lifetime_ordinal_ = 1; std::unique_ptr<SysmemBufferPool::Creator> input_buffer_collection_creator_; + size_t num_input_buffers_ = 0; std::unique_ptr<SysmemBufferPool> input_buffer_collection_; base::flat_map<size_t, StreamProcessorHelper::IoPacket> in_flight_input_packets_; - std::deque<DecodeCB> decode_callbacks_; - // Output buffers. + // Output buffers for |codec_|. fuchsia::media::VideoUncompressedFormat output_format_; uint64_t output_buffer_lifetime_ordinal_ = 1; fuchsia::sysmem::BufferCollectionPtr output_buffer_collection_; @@ -303,15 +322,17 @@ return; } - // If decryptor is decrypt only, return false here to allow decoder selector - // to choose DecryptingDemuxerStream, which will handle the decryption and - // pass the clear stream to this decoder. - Decryptor* decryptor = cdm_context->GetDecryptor(); - if (decryptor && decryptor->CanAlwaysDecrypt()) { - DVLOG(1) << "Decryptor can always decrypt, return false."; + // If Cdm is not FuchsiaCdm then fail initialization to allow decoder + // selector to choose DecryptingDemuxerStream, which will handle the + // decryption and pass the clear stream to this decoder. + FuchsiaCdmContext* fuchsia_cdm = cdm_context->GetFuchsiaCdmContext(); + if (!fuchsia_cdm) { + DVLOG(1) << "FuchsiaVideoDecoder is compatible only with Fuchsia CDM."; std::move(done_callback).Run(false); return; } + + decryptor_ = fuchsia_cdm->CreateSecureDecryptor(this); } output_cb_ = output_cb; @@ -387,7 +408,12 @@ } decode_callbacks_.push_back(std::move(decode_cb)); - input_writer_queue_.EnqueueBuffer(buffer); + + if (decryptor_) { + decryptor_->Decrypt(std::move(buffer)); + } else { + input_writer_queue_.EnqueueBuffer(buffer); + } } void FuchsiaVideoDecoder::Reset(base::OnceClosure closure) { @@ -420,7 +446,24 @@ int FuchsiaVideoDecoder::GetMaxDecodeRequests() const { // Add one extra request to be able to send new InputBuffer immediately after // OnFreeInputPacket(). - return input_writer_queue_.num_buffers() + 1; + return num_input_buffers_ + 1; +} + +void FuchsiaVideoDecoder::OnDecryptorOutputPacket( + StreamProcessorHelper::IoPacket packet) { + SendInputPacket(nullptr, std::move(packet)); +} + +void FuchsiaVideoDecoder::OnDecryptorEndOfStreamPacket() { + ProcessEndOfStream(); +} + +void FuchsiaVideoDecoder::OnDecryptorError() { + OnError(); +} +void FuchsiaVideoDecoder::OnDecryptorNoKey() { + NOTIMPLEMENTED(); + OnError(); } void FuchsiaVideoDecoder::OnStreamFailed(uint64_t stream_lifetime_ordinal, @@ -440,21 +483,32 @@ input_buffer_collection_.reset(); input_writer_queue_.ResetBuffers(); + num_input_buffers_ = 0; // Create buffer constrains for the input buffer collection. - base::Optional<fuchsia::sysmem::BufferCollectionConstraints> - buffer_constraints = - SysmemBufferWriter::GetRecommendedConstraints(stream_constraints); - if (!buffer_constraints.has_value()) { - OnError(); - return; + size_t num_tokens; + fuchsia::sysmem::BufferCollectionConstraints buffer_constraints; + + if (decryptor_) { + // For encrypted streams the sysmem buffer collection is used for decryptor + // output and decoder input. It is not used directly. + num_tokens = 2; + buffer_constraints.usage.none = fuchsia::sysmem::noneUsage; + } else { + num_tokens = 1; + auto writer_constraints = + SysmemBufferWriter::GetRecommendedConstraints(stream_constraints); + if (!writer_constraints.has_value()) { + OnError(); + return; + } + buffer_constraints = std::move(writer_constraints).value(); } - // Request SysmemBufferPool with one token to share with the codec. input_buffer_collection_creator_ = - sysmem_allocator_.MakeBufferPoolCreator(1 /* num_shared_token */); + sysmem_allocator_.MakeBufferPoolCreator(num_tokens); input_buffer_collection_creator_->Create( - std::move(buffer_constraints).value(), + std::move(buffer_constraints), base::BindOnce(&FuchsiaVideoDecoder::OnInputBufferPoolCreated, base::Unretained(this), std::move(stream_constraints))); } @@ -469,6 +523,9 @@ } input_buffer_collection_ = std::move(pool); + num_input_buffers_ = + constraints.default_settings().packet_count_for_server() + + constraints.default_settings().packet_count_for_client(); fuchsia::media::StreamBufferPartialSettings settings; settings.set_buffer_lifetime_ordinal(input_buffer_lifetime_ordinal_); @@ -479,11 +536,18 @@ constraints.default_settings().packet_count_for_server()); settings.set_packet_count_for_client( constraints.default_settings().packet_count_for_client()); - settings.set_sysmem_token(std::move(input_buffer_collection_->TakeToken())); + settings.set_sysmem_token(input_buffer_collection_->TakeToken()); codec_->SetInputBufferPartialSettings(std::move(settings)); - input_buffer_collection_->CreateWriter(base::BindOnce( - &FuchsiaVideoDecoder::OnWriterCreated, base::Unretained(this))); + if (decryptor_) { + decryptor_->SetOutputBufferCollectionToken( + input_buffer_collection_->TakeToken(), + constraints.default_settings().packet_count_for_client(), + constraints.default_settings().packet_count_for_server()); + } else { + input_buffer_collection_->CreateWriter(base::BindOnce( + &FuchsiaVideoDecoder::OnWriterCreated, base::Unretained(this))); + } } void FuchsiaVideoDecoder::OnWriterCreated( @@ -550,15 +614,6 @@ return; } - if (free_input_packet.packet_index() >= input_writer_queue_.num_buffers()) { - DLOG(ERROR) << "fuchsia.mediacodec sent OnFreeInputPacket() for an unknown " - "packet: buffer_lifetime_ordinal=" - << free_input_packet.buffer_lifetime_ordinal() - << " packet_index=" << free_input_packet.packet_index(); - OnError(); - return; - } - auto it = in_flight_input_packets_.find(free_input_packet.packet_index()); if (it == in_flight_input_packets_.end()) { DLOG(ERROR) << "Received OnFreeInputPacket() with invalid packet index."; @@ -828,6 +883,8 @@ } decode_callbacks_.clear(); + decryptor_.reset(); + input_writer_queue_.ResetBuffers(); input_writer_queue_.ResetQueue();
diff --git a/media/fuchsia/cdm/BUILD.gn b/media/fuchsia/cdm/BUILD.gn index 93f868a..bc242ec 100644 --- a/media/fuchsia/cdm/BUILD.gn +++ b/media/fuchsia/cdm/BUILD.gn
@@ -8,6 +8,7 @@ sources = [ "fuchsia_cdm.cc", "fuchsia_cdm.h", + "fuchsia_cdm_context.h", "fuchsia_cdm_factory.cc", "fuchsia_cdm_factory.h", "fuchsia_cdm_provider.h",
diff --git a/media/fuchsia/cdm/fuchsia_cdm.cc b/media/fuchsia/cdm/fuchsia_cdm.cc index df3ed2e..afa0769 100644 --- a/media/fuchsia/cdm/fuchsia_cdm.cc +++ b/media/fuchsia/cdm/fuchsia_cdm.cc
@@ -244,6 +244,11 @@ FuchsiaCdm::~FuchsiaCdm() = default; +std::unique_ptr<FuchsiaSecureStreamDecryptor> FuchsiaCdm::CreateSecureDecryptor( + FuchsiaSecureStreamDecryptor::Client* client) { + return FuchsiaSecureStreamDecryptor::Create(cdm_.get(), client); +} + void FuchsiaCdm::SetServerCertificate( const std::vector<uint8_t>& certificate, std::unique_ptr<SimpleCdmPromise> promise) { @@ -422,4 +427,8 @@ return kInvalidCdmId; } +FuchsiaCdmContext* FuchsiaCdm::GetFuchsiaCdmContext() { + return this; +} + } // namespace media
diff --git a/media/fuchsia/cdm/fuchsia_cdm.h b/media/fuchsia/cdm/fuchsia_cdm.h index b12e527..c9ac613 100644 --- a/media/fuchsia/cdm/fuchsia_cdm.h +++ b/media/fuchsia/cdm/fuchsia_cdm.h
@@ -13,11 +13,14 @@ #include "media/base/cdm_context.h" #include "media/base/cdm_promise_adapter.h" #include "media/base/content_decryption_module.h" +#include "media/fuchsia/cdm/fuchsia_cdm_context.h" namespace media { class FuchsiaDecryptor; -class FuchsiaCdm : public ContentDecryptionModule, public CdmContext { +class FuchsiaCdm : public ContentDecryptionModule, + public CdmContext, + public FuchsiaCdmContext { public: struct SessionCallbacks { SessionCallbacks(); @@ -62,6 +65,11 @@ EventCB event_cb) override; Decryptor* GetDecryptor() override; int GetCdmId() const override; + FuchsiaCdmContext* GetFuchsiaCdmContext() override; + + // FuchsiaCdmContext implementation: + std::unique_ptr<FuchsiaSecureStreamDecryptor> CreateSecureDecryptor( + FuchsiaSecureStreamDecryptor::Client* client) override; private: class CdmSession;
diff --git a/media/fuchsia/cdm/fuchsia_cdm_context.h b/media/fuchsia/cdm/fuchsia_cdm_context.h new file mode 100644 index 0000000..dd614ff --- /dev/null +++ b/media/fuchsia/cdm/fuchsia_cdm_context.h
@@ -0,0 +1,27 @@ +// 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 MEDIA_FUCHSIA_CDM_FUCHSIA_CDM_CONTEXT_H_ +#define MEDIA_FUCHSIA_CDM_FUCHSIA_CDM_CONTEXT_H_ + +#include "media/fuchsia/cdm/fuchsia_stream_decryptor.h" + +namespace media { + +// Interface for Fuchsia-specific extensions to the CdmContext interface. +class FuchsiaCdmContext { + public: + FuchsiaCdmContext() = default; + + // Creates FuchsiaSecureStreamDecryptor instance for the CDM context. + virtual std::unique_ptr<FuchsiaSecureStreamDecryptor> CreateSecureDecryptor( + FuchsiaSecureStreamDecryptor::Client* client) = 0; + + protected: + virtual ~FuchsiaCdmContext() = default; +}; + +} // namespace media + +#endif // MEDIA_FUCHSIA_CDM_FUCHSIA_CDM_CONTEXT_H_
diff --git a/media/fuchsia/cdm/fuchsia_decryptor.cc b/media/fuchsia/cdm/fuchsia_decryptor.cc index 17b946b..e1c8ba79 100644 --- a/media/fuchsia/cdm/fuchsia_decryptor.cc +++ b/media/fuchsia/cdm/fuchsia_decryptor.cc
@@ -29,7 +29,6 @@ scoped_refptr<DecoderBuffer> encrypted, const DecryptCB& decrypt_cb) { if (stream_type != StreamType::kAudio) { - NOTREACHED(); decrypt_cb.Run(Status::kError, nullptr); return; } @@ -41,26 +40,26 @@ } void FuchsiaDecryptor::CancelDecrypt(StreamType stream_type) { - DCHECK_EQ(stream_type, StreamType::kAudio); - audio_decryptor_->CancelDecrypt(); + if (stream_type == StreamType::kAudio) { + audio_decryptor_->CancelDecrypt(); + } } void FuchsiaDecryptor::InitializeAudioDecoder(const AudioDecoderConfig& config, const DecoderInitCB& init_cb) { - // Only supports decrypt for audio stream. - NOTREACHED(); + // Only decryption is supported. init_cb.Run(false); } void FuchsiaDecryptor::InitializeVideoDecoder(const VideoDecoderConfig& config, const DecoderInitCB& init_cb) { + // Only decryption is supported. init_cb.Run(false); } void FuchsiaDecryptor::DecryptAndDecodeAudio( scoped_refptr<DecoderBuffer> encrypted, const AudioDecodeCB& audio_decode_cb) { - // Only supports decrypt for audio stream. NOTREACHED(); audio_decode_cb.Run(Status::kError, AudioFrames()); }
diff --git a/media/fuchsia/cdm/fuchsia_decryptor.h b/media/fuchsia/cdm/fuchsia_decryptor.h index cc15dd9..5a84135a 100644 --- a/media/fuchsia/cdm/fuchsia_decryptor.h +++ b/media/fuchsia/cdm/fuchsia_decryptor.h
@@ -8,6 +8,7 @@ #include <memory> #include "media/base/decryptor.h" +#include "media/fuchsia/cdm/fuchsia_stream_decryptor.h" namespace fuchsia { namespace media {
diff --git a/media/fuchsia/cdm/fuchsia_stream_decryptor.cc b/media/fuchsia/cdm/fuchsia_stream_decryptor.cc index 3eb847b3..79e8ed8 100644 --- a/media/fuchsia/cdm/fuchsia_stream_decryptor.cc +++ b/media/fuchsia/cdm/fuchsia_stream_decryptor.cc
@@ -95,7 +95,6 @@ void FuchsiaStreamDecryptorBase::DecryptInternal( scoped_refptr<DecoderBuffer> encrypted) { - DCHECK(!encrypted->end_of_stream()) << "EOS frame is always clear."; input_writer_queue_.EnqueueBuffer(std::move(encrypted)); } @@ -156,7 +155,8 @@ std::move(writer), base::BindRepeating(&FuchsiaStreamDecryptorBase::SendInputPacket, base::Unretained(this)), - SysmemBufferWriterQueue::EndOfStreamCB()); + base::BindRepeating(&FuchsiaStreamDecryptorBase::ProcessEndOfStream, + base::Unretained(this))); } void FuchsiaStreamDecryptorBase::SendInputPacket( @@ -176,6 +176,10 @@ processor_.Process(std::move(packet)); } +void FuchsiaStreamDecryptorBase::ProcessEndOfStream() { + processor_.ProcessEos(); +} + std::unique_ptr<FuchsiaClearStreamDecryptor> FuchsiaClearStreamDecryptor::Create( fuchsia::media::drm::ContentDecryptionModule* cdm) { @@ -223,17 +227,19 @@ return; } - size_t max_used_output_buffers = std::max( + size_t num_buffers_for_client = std::max( kMinClearStreamOutputFrames, static_cast<size_t>(stream_constraints.packet_count_for_client_min())); + size_t num_buffers_for_server = + stream_constraints.default_settings().packet_count_for_server(); output_pool_creator_ = allocator_.MakeBufferPoolCreator(1 /* num_shared_token */); - output_pool_creator_->Create( - SysmemBufferReader::GetRecommendedConstraints(max_used_output_buffers), + SysmemBufferReader::GetRecommendedConstraints(num_buffers_for_client), base::BindOnce(&FuchsiaClearStreamDecryptor::OnOutputBufferPoolCreated, - base::Unretained(this), max_used_output_buffers)); + base::Unretained(this), num_buffers_for_client, + num_buffers_for_server)); } void FuchsiaClearStreamDecryptor::OnProcessEos() { @@ -316,7 +322,8 @@ } void FuchsiaClearStreamDecryptor::OnOutputBufferPoolCreated( - size_t max_used_output_buffers, + size_t num_buffers_for_client, + size_t num_buffers_for_server, std::unique_ptr<SysmemBufferPool> pool) { if (!pool) { LOG(ERROR) << "Fail to allocate output buffer."; @@ -328,7 +335,8 @@ // Provide token before enabling reader. Tokens must be provided to // StreamProcessor before getting the allocated buffers. - processor_.CompleteOutputBuffersAllocation(max_used_output_buffers, + processor_.CompleteOutputBuffersAllocation(num_buffers_for_client, + num_buffers_for_server, output_pool_->TakeToken()); output_pool_->CreateReader(base::BindOnce( @@ -348,4 +356,81 @@ output_reader_ = std::move(reader); } +// static +std::unique_ptr<FuchsiaSecureStreamDecryptor> +FuchsiaSecureStreamDecryptor::Create( + fuchsia::media::drm::ContentDecryptionModule* cdm, + Client* client) { + DCHECK(cdm); + + fuchsia::media::drm::DecryptorParams params; + + // TODO(crbug.com/997853): Enable secure mode when it's implemented in sysmem. + params.set_require_secure_mode(false); + + params.mutable_input_details()->set_format_details_version_ordinal(0); + fuchsia::media::StreamProcessorPtr stream_processor; + cdm->CreateDecryptor(std::move(params), stream_processor.NewRequest()); + + return std::make_unique<FuchsiaSecureStreamDecryptor>( + std::move(stream_processor), client); +} + +FuchsiaSecureStreamDecryptor::FuchsiaSecureStreamDecryptor( + fuchsia::media::StreamProcessorPtr processor, + Client* client) + : FuchsiaStreamDecryptorBase(std::move(processor)), client_(client) {} + +FuchsiaSecureStreamDecryptor::~FuchsiaSecureStreamDecryptor() = default; + +void FuchsiaSecureStreamDecryptor::SetOutputBufferCollectionToken( + fuchsia::sysmem::BufferCollectionTokenPtr token, + size_t num_buffers_for_decryptor, + size_t num_buffers_for_codec) { + DCHECK(!complete_buffer_allocation_callback_); + complete_buffer_allocation_callback_ = + base::BindOnce(&StreamProcessorHelper::CompleteOutputBuffersAllocation, + base::Unretained(&processor_), num_buffers_for_decryptor, + num_buffers_for_codec, std::move(token)); + if (waiting_output_buffers_) { + std::move(complete_buffer_allocation_callback_).Run(); + waiting_output_buffers_ = false; + } +} + +void FuchsiaSecureStreamDecryptor::Decrypt( + scoped_refptr<DecoderBuffer> encrypted) { + DecryptInternal(std::move(encrypted)); +} + +void FuchsiaSecureStreamDecryptor::AllocateOutputBuffers( + const fuchsia::media::StreamBufferConstraints& stream_constraints) { + if (complete_buffer_allocation_callback_) { + std::move(complete_buffer_allocation_callback_).Run(); + } else { + waiting_output_buffers_ = true; + } +} + +void FuchsiaSecureStreamDecryptor::OnProcessEos() { + client_->OnDecryptorEndOfStreamPacket(); +} + +void FuchsiaSecureStreamDecryptor::OnOutputFormat( + fuchsia::media::StreamOutputFormat format) {} + +void FuchsiaSecureStreamDecryptor::OnOutputPacket( + StreamProcessorHelper::IoPacket packet) { + client_->OnDecryptorOutputPacket(std::move(packet)); +} + +void FuchsiaSecureStreamDecryptor::OnNoKey() { + client_->OnDecryptorNoKey(); +} + +void FuchsiaSecureStreamDecryptor::OnError() { + ResetStream(); + client_->OnDecryptorError(); +} + } // namespace media
diff --git a/media/fuchsia/cdm/fuchsia_stream_decryptor.h b/media/fuchsia/cdm/fuchsia_stream_decryptor.h index 8679521..0d07690 100644 --- a/media/fuchsia/cdm/fuchsia_stream_decryptor.h +++ b/media/fuchsia/cdm/fuchsia_stream_decryptor.h
@@ -41,6 +41,7 @@ void OnWriterCreated(std::unique_ptr<SysmemBufferWriter> writer); void SendInputPacket(const DecoderBuffer* buffer, StreamProcessorHelper::IoPacket packet); + void ProcessEndOfStream(); SysmemBufferWriterQueue input_writer_queue_; std::unique_ptr<SysmemBufferPool::Creator> input_pool_creator_; @@ -49,7 +50,8 @@ DISALLOW_COPY_AND_ASSIGN(FuchsiaStreamDecryptorBase); }; -// Stream decryptor used by FuchsiaDecryptor for audio streams. +// Stream decryptor that copies output to clear DecodeBuffer's. Used for audio +// streams. class FuchsiaClearStreamDecryptor : public FuchsiaStreamDecryptorBase { public: static std::unique_ptr<FuchsiaClearStreamDecryptor> Create( @@ -73,7 +75,8 @@ void OnNoKey() override; void OnError() override; - void OnOutputBufferPoolCreated(size_t max_used_output_buffers, + void OnOutputBufferPoolCreated(size_t num_buffers_for_client, + size_t num_buffers_for_server, std::unique_ptr<SysmemBufferPool> pool); void OnOutputBufferPoolReaderCreated( std::unique_ptr<SysmemBufferReader> reader); @@ -92,6 +95,55 @@ DISALLOW_COPY_AND_ASSIGN(FuchsiaClearStreamDecryptor); }; +// Stream decryptor that decrypts data to secure sysmem buffers. Used for video +// stream. +class FuchsiaSecureStreamDecryptor : public FuchsiaStreamDecryptorBase { + public: + class Client { + public: + virtual void OnDecryptorOutputPacket( + StreamProcessorHelper::IoPacket packet) = 0; + virtual void OnDecryptorEndOfStreamPacket() = 0; + virtual void OnDecryptorError() = 0; + virtual void OnDecryptorNoKey() = 0; + + protected: + virtual ~Client() = default; + }; + + static std::unique_ptr<FuchsiaSecureStreamDecryptor> Create( + fuchsia::media::drm::ContentDecryptionModule* cdm, + Client* client); + + FuchsiaSecureStreamDecryptor(fuchsia::media::StreamProcessorPtr processor, + Client* client); + ~FuchsiaSecureStreamDecryptor() override; + + void SetOutputBufferCollectionToken( + fuchsia::sysmem::BufferCollectionTokenPtr token, + size_t num_buffers_for_decryptor, + size_t num_buffers_for_codec); + + void Decrypt(scoped_refptr<DecoderBuffer> encrypted); + + private: + // StreamProcessorHelper::Client overrides. + void AllocateOutputBuffers(const fuchsia::media::StreamBufferConstraints& + stream_constraints) override; + void OnProcessEos() override; + void OnOutputFormat(fuchsia::media::StreamOutputFormat format) override; + void OnOutputPacket(StreamProcessorHelper::IoPacket packet) override; + void OnNoKey() override; + void OnError() override; + + Client* const client_; + + bool waiting_output_buffers_ = false; + base::OnceClosure complete_buffer_allocation_callback_; + + DISALLOW_COPY_AND_ASSIGN(FuchsiaSecureStreamDecryptor); +}; + } // namespace media #endif // MEDIA_FUCHSIA_CDM_FUCHSIA_STREAM_DECRYPTOR_H_
diff --git a/media/fuchsia/common/stream_processor_helper.cc b/media/fuchsia/common/stream_processor_helper.cc index c403017..ba9f7bcc 100644 --- a/media/fuchsia/common/stream_processor_helper.cc +++ b/media/fuchsia/common/stream_processor_helper.cc
@@ -317,10 +317,11 @@ } void StreamProcessorHelper::CompleteOutputBuffersAllocation( - size_t max_used_output_buffers, + size_t num_buffers_for_client, + size_t num_buffers_for_server, fuchsia::sysmem::BufferCollectionTokenPtr collection_token) { DCHECK(!output_buffer_constraints_.IsEmpty()); - DCHECK_LE(max_used_output_buffers, + DCHECK_LE(num_buffers_for_client, output_buffer_constraints_.packet_count_for_client_max()); // Pass new output buffer settings to the stream processor. @@ -328,9 +329,8 @@ settings.set_buffer_lifetime_ordinal(output_buffer_lifetime_ordinal_); settings.set_buffer_constraints_version_ordinal( output_buffer_constraints_.buffer_constraints_version_ordinal()); - settings.set_packet_count_for_client(max_used_output_buffers); - settings.set_packet_count_for_server( - output_buffer_constraints_.packet_count_for_server_recommended()); + settings.set_packet_count_for_client(num_buffers_for_client); + settings.set_packet_count_for_server(num_buffers_for_server); settings.set_sysmem_token(std::move(collection_token)); processor_->SetOutputBufferPartialSettings(std::move(settings)); processor_->CompleteOutputBufferPartialSettings(
diff --git a/media/fuchsia/common/stream_processor_helper.h b/media/fuchsia/common/stream_processor_helper.h index babbaac6..87411f2 100644 --- a/media/fuchsia/common/stream_processor_helper.h +++ b/media/fuchsia/common/stream_processor_helper.h
@@ -121,7 +121,8 @@ void CompleteInputBuffersAllocation( fuchsia::sysmem::BufferCollectionTokenPtr token); void CompleteOutputBuffersAllocation( - size_t max_used_output_buffers, + size_t num_buffers_for_client, + size_t num_buffers_for_server, fuchsia::sysmem::BufferCollectionTokenPtr token); void Reset();
diff --git a/media/midi/BUILD.gn b/media/midi/BUILD.gn index 69ee4260..60005a4 100644 --- a/media/midi/BUILD.gn +++ b/media/midi/BUILD.gn
@@ -49,7 +49,9 @@ android_library("midi_java") { deps = [ "//base:base_java", + "//base:jni_java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] java_files = [ "java/src/org/chromium/midi/MidiDeviceAndroid.java",
diff --git a/media/midi/java/src/org/chromium/midi/MidiInputPortAndroid.java b/media/midi/java/src/org/chromium/midi/MidiInputPortAndroid.java index f866c51e..2b0e001 100644 --- a/media/midi/java/src/org/chromium/midi/MidiInputPortAndroid.java +++ b/media/midi/java/src/org/chromium/midi/MidiInputPortAndroid.java
@@ -12,6 +12,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import java.io.IOException; @@ -73,7 +74,8 @@ if (mPort == null) { return; } - nativeOnData(mNativeReceiverPointer, bs, offset, count, timestamp); + MidiInputPortAndroidJni.get().onData( + mNativeReceiverPointer, bs, offset, count, timestamp); } } }); @@ -97,6 +99,9 @@ mPort = null; } - private static native void nativeOnData( - long nativeMidiInputPortAndroid, byte[] bs, int offset, int count, long timestamp); + @NativeMethods + interface Natives { + void onData( + long nativeMidiInputPortAndroid, byte[] bs, int offset, int count, long timestamp); + } }
diff --git a/media/midi/java/src/org/chromium/midi/MidiManagerAndroid.java b/media/midi/java/src/org/chromium/midi/MidiManagerAndroid.java index e0a4cbbd..953571c1 100644 --- a/media/midi/java/src/org/chromium/midi/MidiManagerAndroid.java +++ b/media/midi/java/src/org/chromium/midi/MidiManagerAndroid.java
@@ -17,6 +17,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import java.util.ArrayList; import java.util.HashSet; @@ -106,7 +107,7 @@ if (mStopped) { return; } - nativeOnInitializationFailed(mNativeManagerPointer); + MidiManagerAndroidJni.get().onInitializationFailed(mNativeManagerPointer); } } }); @@ -137,7 +138,7 @@ return; } if (mPendingDevices.isEmpty() && !mIsInitialized) { - nativeOnInitialized( + MidiManagerAndroidJni.get().onInitialized( mNativeManagerPointer, mDevices.toArray(new MidiDeviceAndroid[0])); mIsInitialized = true; } @@ -185,7 +186,7 @@ for (MidiDeviceAndroid device : mDevices) { if (device.isOpen() && device.getInfo().getId() == info.getId()) { device.close(); - nativeOnDetached(mNativeManagerPointer, device); + MidiManagerAndroidJni.get().onDetached(mNativeManagerPointer, device); } } } @@ -199,18 +200,21 @@ MidiDeviceAndroid xdevice = new MidiDeviceAndroid(device); mDevices.add(xdevice); if (mIsInitialized) { - nativeOnAttached(mNativeManagerPointer, xdevice); + MidiManagerAndroidJni.get().onAttached(mNativeManagerPointer, xdevice); } } if (!mIsInitialized && mPendingDevices.isEmpty()) { - nativeOnInitialized(mNativeManagerPointer, mDevices.toArray(new MidiDeviceAndroid[0])); + MidiManagerAndroidJni.get().onInitialized( + mNativeManagerPointer, mDevices.toArray(new MidiDeviceAndroid[0])); mIsInitialized = true; } } - static native void nativeOnInitialized( - long nativeMidiManagerAndroid, MidiDeviceAndroid[] devices); - static native void nativeOnInitializationFailed(long nativeMidiManagerAndroid); - static native void nativeOnAttached(long nativeMidiManagerAndroid, MidiDeviceAndroid device); - static native void nativeOnDetached(long nativeMidiManagerAndroid, MidiDeviceAndroid device); + @NativeMethods + interface Natives { + void onInitialized(long nativeMidiManagerAndroid, MidiDeviceAndroid[] devices); + void onInitializationFailed(long nativeMidiManagerAndroid); + void onAttached(long nativeMidiManagerAndroid, MidiDeviceAndroid device); + void onDetached(long nativeMidiManagerAndroid, MidiDeviceAndroid device); + } }
diff --git a/media/midi/java/src/org/chromium/midi/UsbMidiDeviceAndroid.java b/media/midi/java/src/org/chromium/midi/UsbMidiDeviceAndroid.java index 323b0da..6f19d11 100644 --- a/media/midi/java/src/org/chromium/midi/UsbMidiDeviceAndroid.java +++ b/media/midi/java/src/org/chromium/midi/UsbMidiDeviceAndroid.java
@@ -16,6 +16,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import java.nio.ByteBuffer; import java.util.Arrays; @@ -187,7 +188,7 @@ if (mIsClosed) { return; } - nativeOnData(mNativePointer, endpointNumber, bs); + UsbMidiDeviceAndroidJni.get().onData(mNativePointer, endpointNumber, bs); } }); } @@ -318,6 +319,8 @@ return position; } - private static native void nativeOnData( - long nativeUsbMidiDeviceAndroid, int endpointNumber, byte[] data); + @NativeMethods + interface Natives { + void onData(long nativeUsbMidiDeviceAndroid, int endpointNumber, byte[] data); + } }
diff --git a/media/midi/java/src/org/chromium/midi/UsbMidiDeviceFactoryAndroid.java b/media/midi/java/src/org/chromium/midi/UsbMidiDeviceFactoryAndroid.java index 4f64b01c..9511ab1 100644 --- a/media/midi/java/src/org/chromium/midi/UsbMidiDeviceFactoryAndroid.java +++ b/media/midi/java/src/org/chromium/midi/UsbMidiDeviceFactoryAndroid.java
@@ -18,6 +18,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import java.util.ArrayList; import java.util.HashSet; @@ -107,8 +108,8 @@ * Enumerates USB-MIDI devices. * If there are devices having USB-MIDI interfaces, this function requests permission for * accessing the device to the user. - * When the permission request is accepted or rejected, nativeOnUsbMidiDeviceRequestDone - * will be called. + * When the permission request is accepted or rejected, + * UsbMidiDeviceFactoryAndroidJni.get().onUsbMidiDeviceRequestDone will be called. * * If there are no USB-MIDI interfaces, this function returns false. * @return true if some permission requests are in progress. @@ -184,7 +185,7 @@ return; } if (mNativePointer != 0) { - nativeOnUsbMidiDeviceDetached(mNativePointer, i); + UsbMidiDeviceFactoryAndroidJni.get().onUsbMidiDeviceDetached(mNativePointer, i); } return; } @@ -236,10 +237,12 @@ } if (mIsEnumeratingDevices) { - nativeOnUsbMidiDeviceRequestDone(mNativePointer, mDevices.toArray()); + UsbMidiDeviceFactoryAndroidJni.get().onUsbMidiDeviceRequestDone( + mNativePointer, mDevices.toArray()); mIsEnumeratingDevices = false; } else if (midiDevice != null) { - nativeOnUsbMidiDeviceAttached(mNativePointer, midiDevice); + UsbMidiDeviceFactoryAndroidJni.get().onUsbMidiDeviceAttached( + mNativePointer, midiDevice); } } @@ -252,10 +255,10 @@ ContextUtils.getApplicationContext().unregisterReceiver(mReceiver); } - private static native void nativeOnUsbMidiDeviceRequestDone( - long nativeUsbMidiDeviceFactoryAndroid, Object[] devices); - private static native void nativeOnUsbMidiDeviceAttached( - long nativeUsbMidiDeviceFactoryAndroid, Object device); - private static native void nativeOnUsbMidiDeviceDetached( - long nativeUsbMidiDeviceFactoryAndroid, int index); + @NativeMethods + interface Natives { + void onUsbMidiDeviceRequestDone(long nativeUsbMidiDeviceFactoryAndroid, Object[] devices); + void onUsbMidiDeviceAttached(long nativeUsbMidiDeviceFactoryAndroid, Object device); + void onUsbMidiDeviceDetached(long nativeUsbMidiDeviceFactoryAndroid, int index); + } }
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index 6636834..dfe949f 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -634,25 +634,13 @@ -SkFloatToScalar(image.height() * 0.5f)); } - // This is a workaround for crbug.com/524717. A texture backed image is not - // safe to access on another thread or GL context. So if we're drawing into a - // recording canvas we read the texture back into CPU memory and record that - // sw image into the SkPicture. The long term solution is for Skia to provide - // a SkPicture filter that makes a picture safe for multiple CPU raster - // threads. (skbug.com/4321). - if (canvas->imageInfo().colorType() == kUnknown_SkColorType && - image.IsTextureBacked()) { - sk_sp<SkImage> non_texture_image = - image.GetSkImage()->makeNonTextureImage(); - image = cc::PaintImageBuilder::WithProperties(image) - .set_image(std::move(non_texture_image), image.content_id()) - .TakePaintImage(); - } - SkImageInfo info; size_t row_bytes; SkIPoint origin; void* pixels = nullptr; + // This if is a special handling of video for SkiaPaintcanvas backend, where + // the video does not need any transform and it is enough to draw the frame + // directly into the skia canvas if (!need_transform && video_frame->IsMappable() && flags.getAlpha() == SK_AlphaOPAQUE && flags.getBlendMode() == SkBlendMode::kSrc && @@ -1469,7 +1457,8 @@ DCHECK(!source_mailbox.IsZero()); DCHECK(source_texture); auto* gl = context_provider->ContextGL(); - gl->DeleteTextures(1, &source_texture); + if (!texture_ownership_in_skia) + gl->DeleteTextures(1, &source_texture); if (!wraps_video_frame_texture) { gpu::SyncToken sync_token; gl->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); @@ -1478,6 +1467,26 @@ } } +bool PaintCanvasVideoRenderer::Cache::Recycle() { + if (!texture_ownership_in_skia) + return true; + + auto sk_image = paint_image.GetSkImage(); + paint_image = cc::PaintImage(); + if (!sk_image->unique()) + return false; + + // Flush any pending GPU work using this texture. + sk_image->flush(context_provider->GrContext()); + + // We need a new texture ID because skia will destroy the previous one with + // the SkImage. + texture_ownership_in_skia = false; + source_texture = SynchronizeAndImportMailbox( + context_provider->ContextGL(), gpu::SyncToken(), source_mailbox); + return true; +} + bool PaintCanvasVideoRenderer::UpdateLastImage( scoped_refptr<VideoFrame> video_frame, viz::ContextProvider* context_provider, @@ -1515,7 +1524,8 @@ video_frame->ColorSpace(), context_provider); } else { if (cache_ && cache_->context_provider == context_provider && - cache_->coded_size == video_frame->coded_size()) { + cache_->coded_size == video_frame->coded_size() && + cache_->Recycle()) { // We can reuse the shared image from the previous cache. cache_->frame_id = video_frame->unique_id(); } else { @@ -1527,6 +1537,8 @@ cache_->source_texture = SynchronizeAndImportMailbox( gl, sii->GenUnverifiedSyncToken(), cache_->source_mailbox); } + + DCHECK(!cache_->texture_ownership_in_skia); ScopedSharedImageAccess dest_access( gl, cache_->source_texture, cache_->source_mailbox, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); @@ -1561,9 +1573,32 @@ cache_->context_provider = context_provider; cache_->coded_size = video_frame->coded_size(); cache_->visible_rect = video_frame->visible_rect(); - paint_image_builder.set_image( - source_image->makeSubset(gfx::RectToSkIRect(cache_->visible_rect)), - cc::PaintImage::GetNextContentId()); + sk_sp<SkImage> source_subset = + source_image->makeSubset(gfx::RectToSkIRect(cache_->visible_rect)); + if (source_subset) { + // We use the flushPendingGrContextIO = true so we can flush any pending + // GPU work on the GrContext to ensure that skia exectues the work for + // generating the subset and it can be safely destroyed. + GrBackendTexture image_backend = + source_image->getBackendTexture(/*flushPendingGrContextIO*/ true); + GrBackendTexture subset_backend = + source_subset->getBackendTexture(/*flushPendingGrContextIO*/ true); +#if DCHECK_IS_ON() + GrGLTextureInfo backend_info; + if (image_backend.getGLTextureInfo(&backend_info)) + DCHECK_EQ(backend_info.fID, cache_->source_texture); +#endif + if (subset_backend.isValid() && + subset_backend.isSameTexture(image_backend)) { + cache_->texture_ownership_in_skia = true; + source_subset = SkImage::MakeFromAdoptedTexture( + cache_->context_provider->GrContext(), image_backend, + kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, + kPremul_SkAlphaType, source_image->imageInfo().refColorSpace()); + } + } + paint_image_builder.set_image(source_subset, + cc::PaintImage::GetNextContentId()); } else { cache_.emplace(video_frame->unique_id()); paint_image_builder.set_paint_image_generator(
diff --git a/media/renderers/paint_canvas_video_renderer.h b/media/renderers/paint_canvas_video_renderer.h index 2628f28..02c277cf 100644 --- a/media/renderers/paint_canvas_video_renderer.h +++ b/media/renderers/paint_canvas_video_renderer.h
@@ -226,6 +226,14 @@ // Whether |source_mailbox| directly points to a texture of the VideoFrame // (if true), or to an allocated shared image (if false). bool wraps_video_frame_texture = false; + + // Whether the texture pointed by |paint_image| is owned by skia or not. + bool texture_ownership_in_skia = false; + + // Used to allow recycling of the previous shared image. This requires that + // no external users have access to this resource via SkImage. Returns true + // if the existing resource can be recycled. + bool Recycle(); }; // Update the cache holding the most-recently-painted frame. Returns false
diff --git a/media/renderers/paint_canvas_video_renderer_unittest.cc b/media/renderers/paint_canvas_video_renderer_unittest.cc index e18311b..3876b63 100644 --- a/media/renderers/paint_canvas_video_renderer_unittest.cc +++ b/media/renderers/paint_canvas_video_renderer_unittest.cc
@@ -1174,6 +1174,14 @@ gfx::Rect(2, 2, 12, 4), std::move(closure)); } + // Creates a cropped I420 VideoFrame. |closure| is run once the shared images + // backing the VideoFrame have been destroyed. + scoped_refptr<VideoFrame> CreateTestI420FrameNotSubset( + base::OnceClosure closure) { + return CreateSharedImageI420Frame(media_context_, gfx::Size(16, 8), + gfx::Rect(0, 0, 16, 8), + std::move(closure)); + } // Checks that the contents of a texture/canvas match the expectations for the // cropped I420 frame above. |get_color| is a callback that returns the actual @@ -1192,6 +1200,23 @@ EXPECT_EQ(SK_ColorWHITE, get_color.Run(11, 3)); } + // Checks that the contents of a texture/canvas match the expectations for the + // cropped I420 frame above. |get_color| is a callback that returns the actual + // color at a given pixel location. + static void CheckI420FramePixelsNotSubset(GetColorCallback get_color) { + // Avoid checking around the "seams" where subsamples may be interpolated. + EXPECT_EQ(SK_ColorBLACK, get_color.Run(2, 2)); + EXPECT_EQ(SK_ColorRED, get_color.Run(5, 2)); + EXPECT_EQ(SK_ColorRED, get_color.Run(6, 2)); + EXPECT_EQ(SK_ColorGREEN, get_color.Run(9, 2)); + EXPECT_EQ(SK_ColorGREEN, get_color.Run(10, 2)); + EXPECT_EQ(SK_ColorYELLOW, get_color.Run(13, 2)); + EXPECT_EQ(SK_ColorBLUE, get_color.Run(2, 5)); + EXPECT_EQ(SK_ColorMAGENTA, get_color.Run(5, 5)); + EXPECT_EQ(SK_ColorCYAN, get_color.Run(9, 5)); + EXPECT_EQ(SK_ColorWHITE, get_color.Run(13, 5)); + } + // Creates a cropped NV12 VideoFrame, or nullptr if the needed extension is // not available. |closure| is run once the shared images backing the // VideoFrame have been destroyed. @@ -1344,6 +1369,19 @@ run_loop.Run(); } +// Checks that we correctly paint a I420 shared image VideoFrame, including +// correct cropping. +TEST_F(PaintCanvasVideoRendererWithGLTest, PaintI420NotSubset) { + base::RunLoop run_loop; + scoped_refptr<VideoFrame> frame = + CreateTestI420FrameNotSubset(run_loop.QuitClosure()); + + PaintVideoFrameAndCheckPixels(frame, &CheckI420FramePixelsNotSubset); + + frame.reset(); + run_loop.Run(); +} + // Checks that we correctly copy a NV12 shared image VideoFrame when using // CopyVideoFrameYUVDataToGLTexture, including correct cropping. TEST_F(PaintCanvasVideoRendererWithGLTest,
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc index 9a37558..b36b5d40 100644 --- a/mojo/core/node_controller.cc +++ b/mojo/core/node_controller.cc
@@ -14,7 +14,6 @@ #include "base/logging.h" #include "base/macros.h" #include "base/message_loop/message_loop_current.h" -#include "base/metrics/histogram_macros.h" #include "base/process/process_handle.h" #include "base/rand_util.h" #include "base/time/time.h"
diff --git a/mojo/core/user_message_impl.cc b/mojo/core/user_message_impl.cc index fb59eba76..2f1665e 100644 --- a/mojo/core/user_message_impl.cc +++ b/mojo/core/user_message_impl.cc
@@ -9,7 +9,6 @@ #include "base/atomicops.h" #include "base/memory/ptr_util.h" -#include "base/metrics/histogram_macros_local.h" #include "base/no_destructor.h" #include "base/numerics/safe_conversions.h" #include "base/numerics/safe_math.h"
diff --git a/mojo/public/cpp/base/big_buffer.cc b/mojo/public/cpp/base/big_buffer.cc index 85ba9c96..9d44b13 100644 --- a/mojo/public/cpp/base/big_buffer.cc +++ b/mojo/public/cpp/base/big_buffer.cc
@@ -81,7 +81,15 @@ BigBuffer::BigBuffer() : storage_type_(StorageType::kBytes), bytes_size_(0) {} -BigBuffer::BigBuffer(BigBuffer&& other) = default; +BigBuffer::BigBuffer(BigBuffer&& other) + : storage_type_(other.storage_type_), + bytes_(std::move(other.bytes_)), + bytes_size_(other.bytes_size_), + shared_memory_(std::move(other.shared_memory_)) { + // Make sure |other| looks empty. + other.storage_type_ = StorageType::kInvalidBuffer; + other.bytes_size_ = 0; +} BigBuffer::BigBuffer(base::span<const uint8_t> data) { *this = BigBufferView::ToBigBuffer(BigBufferView(data)); @@ -106,7 +114,16 @@ BigBuffer::~BigBuffer() = default; -BigBuffer& BigBuffer::operator=(BigBuffer&& other) = default; +BigBuffer& BigBuffer::operator=(BigBuffer&& other) { + storage_type_ = other.storage_type_; + bytes_ = std::move(other.bytes_); + bytes_size_ = other.bytes_size_; + shared_memory_ = std::move(other.shared_memory_); + // Make sure |other| looks empty. + other.storage_type_ = StorageType::kInvalidBuffer; + other.bytes_size_ = 0; + return *this; +} uint8_t* BigBuffer::data() { return const_cast<uint8_t*>(const_cast<const BigBuffer*>(this)->data());
diff --git a/mojo/public/cpp/bindings/connector.h b/mojo/public/cpp/bindings/connector.h index c2cf962..f97cfcd1 100644 --- a/mojo/public/cpp/bindings/connector.h +++ b/mojo/public/cpp/bindings/connector.h
@@ -18,6 +18,7 @@ #include "base/optional.h" #include "base/sequence_checker.h" #include "base/sequenced_task_runner.h" +#include "mojo/public/c/system/quota.h" #include "mojo/public/cpp/bindings/connection_group.h" #include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/sequence_local_sync_event_watcher.h" @@ -307,6 +308,11 @@ SEQUENCE_CHECKER(sequence_checker_); + // If this instance was selected for unread message measurement, contains + // the max send quota usage seen so far. If this instance was not selected + // contains MOJO_QUOTA_LIMIT_NONE as a sentinel value. + uint64_t max_unread_message_quota_used_ = MOJO_QUOTA_LIMIT_NONE; + base::Lock connected_lock_; bool connected_ = true;
diff --git a/mojo/public/cpp/bindings/features.cc b/mojo/public/cpp/bindings/features.cc index 9026ba7..29f1226 100644 --- a/mojo/public/cpp/bindings/features.cc +++ b/mojo/public/cpp/bindings/features.cc
@@ -22,5 +22,12 @@ const base::Feature kTaskPerMessage{"MojoTaskPerMessage", base::FEATURE_ENABLED_BY_DEFAULT}; +// Enables measurement of MessageChannel unread message counts. When enabled, a +// small random selection of Connectors enable the unread message count quota +// on their associated message pipe, and record the highest unread message count +// seen during the Connector's lifetime. +const base::Feature kMojoRecordUnreadMessageCount{ + "MojoRecordUnreadMessageCount", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace features } // namespace mojo
diff --git a/mojo/public/cpp/bindings/features.h b/mojo/public/cpp/bindings/features.h index 5d58f0d7..8684f5a 100644 --- a/mojo/public/cpp/bindings/features.h +++ b/mojo/public/cpp/bindings/features.h
@@ -14,6 +14,9 @@ COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) extern const base::Feature kTaskPerMessage; +COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) +extern const base::Feature kMojoRecordUnreadMessageCount; + } // namespace features } // namespace mojo
diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc index d0739dd..d8bea67 100644 --- a/mojo/public/cpp/bindings/lib/connector.cc +++ b/mojo/public/cpp/bindings/lib/connector.cc
@@ -12,7 +12,10 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop_current.h" +#include "base/metrics/field_trial_params.h" +#include "base/metrics/histogram_macros.h" #include "base/no_destructor.h" +#include "base/rand_util.h" #include "base/run_loop.h" #include "base/synchronization/lock.h" #include "base/threading/sequence_local_storage_slot.h" @@ -50,6 +53,30 @@ return enable; } +const base::FeatureParam<int> kMojoRecordUnreadMessageCountSampleRate = { + &features::kMojoRecordUnreadMessageCount, "SampleRate", + 100 // Sample 1% of Connectors by default. +}; + +const base::FeatureParam<int> kMojoRecordUnreadMessageCountQuotaValue = { + &features::kMojoRecordUnreadMessageCount, "QuotaValue", + 100 // Use a 100 message quote by default. +}; + +int UnreadMessageCountQuota() { + static const bool enabled = + base::FeatureList::IsEnabled(features::kMojoRecordUnreadMessageCount); + if (!enabled) + return 0; + + static const int sample_rate = kMojoRecordUnreadMessageCountSampleRate.Get(); + if (base::RandInt(0, sample_rate - 1) != 0) + return 0; + + static const int quota = kMojoRecordUnreadMessageCountQuotaValue.Get(); + return quota; +} + } // namespace // Used to efficiently maintain a doubly-linked list of all Connectors @@ -158,9 +185,27 @@ // Even though we don't have an incoming receiver, we still want to monitor // the message pipe to know if is closed or encounters an error. WaitToReadMore(); + + int unread_message_count_quota = UnreadMessageCountQuota(); + if (unread_message_count_quota != 0) { + // This connector has been sampled to record the max unread message count. + // Note that setting the quota to N results in over-counting usage by up to + // N/2, in addition to overcounting due to message transit delays. As result + // it's best to treat the resulting metric as N-granular. + MojoResult rv = MojoSetQuota(message_pipe_.get().value(), + MOJO_QUOTA_TYPE_UNREAD_MESSAGE_COUNT, + unread_message_count_quota, nullptr); + if (rv == MOJO_RESULT_OK) + max_unread_message_quota_used_ = 0U; + } } Connector::~Connector() { + if (max_unread_message_quota_used_ != MOJO_QUOTA_LIMIT_NONE) { + UMA_HISTOGRAM_COUNTS_1M("Mojo.Connector.MaxUnreadMessageQuotaUsed", + max_unread_message_quota_used_); + } + { // Allow for quick destruction on any sequence if the pipe is already // closed. @@ -317,6 +362,15 @@ DCHECK(dump_result); } #endif + if (max_unread_message_quota_used_ != MOJO_QUOTA_LIMIT_NONE) { + uint64_t limit = 0; + uint64_t usage = 0; + MojoResult rv = MojoQueryQuota(message_pipe_.get().value(), + MOJO_QUOTA_TYPE_UNREAD_MESSAGE_COUNT, + nullptr, &limit, &usage); + if (rv == MOJO_RESULT_OK && usage > max_unread_message_quota_used_) + max_unread_message_quota_used_ = usage; + } MojoResult rv = WriteMessageNew(message_pipe_.get(), message->TakeMojoMessage(),
diff --git a/printing/BUILD.gn b/printing/BUILD.gn index cef76da6f..67e0e0c 100644 --- a/printing/BUILD.gn +++ b/printing/BUILD.gn
@@ -382,6 +382,7 @@ android_library("printing_java") { deps = [ "//base:base_java", + "//base:jni_java", "//ui/android:ui_java", ] java_files = [ @@ -393,5 +394,6 @@ "android/java/src/org/chromium/printing/PrintingController.java", "android/java/src/org/chromium/printing/PrintingControllerImpl.java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] } }
diff --git a/printing/android/java/src/org/chromium/printing/PrintingContext.java b/printing/android/java/src/org/chromium/printing/PrintingContext.java index 6924e36b..7d52e71 100644 --- a/printing/android/java/src/org/chromium/printing/PrintingContext.java +++ b/printing/android/java/src/org/chromium/printing/PrintingContext.java
@@ -10,6 +10,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import org.chromium.ui.base.WindowAndroid; /** @@ -106,8 +107,8 @@ ThreadUtils.assertOnUiThread(); // If the printing dialog has already finished, tell Chromium that operation is cancelled. if (mController.hasPrintingFinished()) { - // NOTE: We don't call nativeAskUserForSettingsReply (hence Chromium callback in - // AskUserForSettings callback) twice. + // NOTE: We don't call PrintingContextJni.get().askUserForSettingsReply (hence Chromium + // callback in AskUserForSettings callback) twice. askUserForSettingsReply(false); } else { mController.setPrintingContext(this); @@ -117,16 +118,19 @@ private void askUserForSettingsReply(boolean success) { assert mNativeObject != 0; - nativeAskUserForSettingsReply(mNativeObject, success); + PrintingContextJni.get().askUserForSettingsReply( + mNativeObject, PrintingContext.this, success); } private void showSystemDialogDone() { assert mNativeObject != 0; - nativeShowSystemDialogDone(mNativeObject); + PrintingContextJni.get().showSystemDialogDone(mNativeObject, PrintingContext.this); } - private native void nativeAskUserForSettingsReply( - long nativePrintingContextAndroid, boolean success); - - private native void nativeShowSystemDialogDone(long nativePrintingContextAndroid); + @NativeMethods + interface Natives { + void askUserForSettingsReply( + long nativePrintingContextAndroid, PrintingContext caller, boolean success); + void showSystemDialogDone(long nativePrintingContextAndroid, PrintingContext caller); + } }
diff --git a/remoting/host/installer/linux/debian/postinst b/remoting/host/installer/linux/debian/postinst index b0f9f146..682fc88b 100755 --- a/remoting/host/installer/linux/debian/postinst +++ b/remoting/host/installer/linux/debian/postinst
@@ -18,7 +18,9 @@ NOTIFIER_DIR="/var/lib/update-notifier/user.d" VAR_DIR="/var/lib/chrome-remote-desktop" HASHES_FILE="$VAR_DIR/hashes" -USER_SESSION_PATH="/opt/google/chrome-remote-desktop/user-session" +INSTALL_DIR="/opt/google/chrome-remote-desktop" +USER_SESSION_PATH="$INSTALL_DIR/user-session" +HOST_PATH="$INSTALL_DIR/chrome-remote-desktop-host" CRD_GROUP="chrome-remote-desktop" case "$1" in @@ -35,11 +37,12 @@ chown root:"$CRD_GROUP" "$USER_SESSION_PATH" chmod u=srwx,g=rx,o=r "$USER_SESSION_PATH" fi - # Kill host processes. The wrapper script will restart them. - # TODO(lambroslambrou): Remove the '-9' when the underlying problem with - # hosts not responding to SIGTERM has been fixed - http://crbug.com/420090 + # Kill host processes. SIGKILL is used because the wrapper script will + # restart the host immediately (so any cleanup that might otherwise happen + # is not useful), and this ensures that hosts restart even if they are + # deadlocked. echo "Shutting down Chrome Remote Desktop hosts (they will restart automatically)..." - killall -9 -q chrome-remote-desktop-host || true + killall -9 -q "$HOST_PATH" || true # If any files have changed that require the user to restart their virtual # desktops (eg, the wrapper script itself) then notify them but don't do # anything that would result in them losing state.
diff --git a/sandbox/win/src/acl.cc b/sandbox/win/src/acl.cc index 2f78c164..bd0b181 100644 --- a/sandbox/win/src/acl.cc +++ b/sandbox/win/src/acl.cc
@@ -151,4 +151,21 @@ return true; } +bool ReplacePackageSidInDacl(HANDLE object, + SE_OBJECT_TYPE object_type, + const Sid& package_sid, + ACCESS_MASK access) { + if (!AddKnownSidToObject(object, object_type, package_sid, REVOKE_ACCESS, + 0)) { + return false; + } + + Sid any_package_sid(::WinBuiltinAnyPackageSid); + if (!AddKnownSidToObject(object, object_type, any_package_sid, GRANT_ACCESS, + access)) { + return false; + } + return true; +} + } // namespace sandbox
diff --git a/sandbox/win/src/acl.h b/sandbox/win/src/acl.h index 86bb92f9..194edb0 100644 --- a/sandbox/win/src/acl.h +++ b/sandbox/win/src/acl.h
@@ -51,6 +51,14 @@ ACCESS_MODE access_mode, ACCESS_MASK access); +// Replace package SID in DACL to the "any package" SID. It allows Low-IL +// tokens to open the object which is important for warm up when using renderer +// AppContainer. +bool ReplacePackageSidInDacl(HANDLE object, + SE_OBJECT_TYPE object_type, + const Sid& package_sid, + ACCESS_MASK access); + } // namespace sandbox #endif // SANDBOX_SRC_ACL_H_
diff --git a/sandbox/win/src/restricted_token_unittest.cc b/sandbox/win/src/restricted_token_unittest.cc index d8798e9..88cae12 100644 --- a/sandbox/win/src/restricted_token_unittest.cc +++ b/sandbox/win/src/restricted_token_unittest.cc
@@ -11,6 +11,7 @@ #include "base/win/atl.h" #include "base/win/scoped_handle.h" #include "base/win/windows_version.h" +#include "sandbox/win/src/acl.h" #include "sandbox/win/src/security_capabilities.h" #include "sandbox/win/src/sid.h" #include "testing/gtest/include/gtest/gtest.h" @@ -84,6 +85,46 @@ information); } +void CheckDaclForPackageSid(const base::win::ScopedHandle& token, + PSECURITY_CAPABILITIES security_capabilities, + bool package_sid_required) { + DWORD length_needed = 0; + ::GetKernelObjectSecurity(token.Get(), DACL_SECURITY_INFORMATION, nullptr, 0, + &length_needed); + ASSERT_EQ(::GetLastError(), DWORD{ERROR_INSUFFICIENT_BUFFER}); + + std::vector<char> security_desc_buffer(length_needed); + SECURITY_DESCRIPTOR* security_desc = + reinterpret_cast<SECURITY_DESCRIPTOR*>(security_desc_buffer.data()); + + ASSERT_TRUE(::GetKernelObjectSecurity(token.Get(), DACL_SECURITY_INFORMATION, + security_desc, length_needed, + &length_needed)); + + ATL::CSecurityDesc token_sd(*security_desc); + ATL::CDacl dacl; + ASSERT_TRUE(token_sd.GetDacl(&dacl)); + + ATL::CSid package_sid( + static_cast<SID*>(security_capabilities->AppContainerSid)); + ATL::CSid all_package_sid( + static_cast<SID*>(sandbox::Sid(::WinBuiltinAnyPackageSid).GetPSID())); + + unsigned int ace_count = dacl.GetAceCount(); + for (unsigned int i = 0; i < ace_count; ++i) { + ATL::CSid sid; + ACCESS_MASK mask = 0; + BYTE type = 0; + dacl.GetAclEntry(i, &sid, &mask, &type); + if (mask != TOKEN_ALL_ACCESS || type != ACCESS_ALLOWED_ACE_TYPE) + continue; + if (sid == package_sid) + EXPECT_TRUE(package_sid_required); + else if (sid == all_package_sid) + EXPECT_FALSE(package_sid_required); + } +} + void CheckLowBoxToken(const base::win::ScopedHandle& token, TOKEN_TYPE token_type, PSECURITY_CAPABILITIES security_capabilities) { @@ -126,38 +167,7 @@ security_capabilities->Capabilities[index].Sid)); } - DWORD length_needed = 0; - ::GetKernelObjectSecurity(token.Get(), DACL_SECURITY_INFORMATION, nullptr, 0, - &length_needed); - ASSERT_EQ(::GetLastError(), DWORD{ERROR_INSUFFICIENT_BUFFER}); - - std::vector<char> security_desc_buffer(length_needed); - SECURITY_DESCRIPTOR* security_desc = - reinterpret_cast<SECURITY_DESCRIPTOR*>(security_desc_buffer.data()); - - ASSERT_TRUE(::GetKernelObjectSecurity(token.Get(), DACL_SECURITY_INFORMATION, - security_desc, length_needed, - &length_needed)); - - ATL::CSecurityDesc token_sd(*security_desc); - ATL::CSid check_sid( - static_cast<SID*>(security_capabilities->AppContainerSid)); - bool package_sid_found = false; - - ATL::CDacl dacl; - ASSERT_TRUE(token_sd.GetDacl(&dacl)); - unsigned int ace_count = dacl.GetAceCount(); - for (unsigned int i = 0; i < ace_count; ++i) { - ATL::CSid sid; - ACCESS_MASK mask = 0; - BYTE type = 0; - dacl.GetAclEntry(i, &sid, &mask, &type); - if (sid == check_sid && mask == TOKEN_ALL_ACCESS && - type == ACCESS_ALLOWED_ACE_TYPE) { - package_sid_found = true; - } - } - ASSERT_TRUE(package_sid_found); + CheckDaclForPackageSid(token, security_capabilities, true); } // Checks if a sid is in the restricting list of the restricted token. @@ -761,6 +771,11 @@ ASSERT_TRUE(token.IsValid()); CheckLowBoxToken(token, ::TokenPrimary, &caps_no_capabilities); + ASSERT_TRUE(ReplacePackageSidInDacl(token.Get(), SE_KERNEL_OBJECT, + Sid(caps_no_capabilities.AppContainerSid), + TOKEN_ALL_ACCESS)); + CheckDaclForPackageSid(token, &caps_no_capabilities, false); + ASSERT_EQ(DWORD{ERROR_SUCCESS}, CreateLowBoxToken(nullptr, IMPERSONATION, &caps_no_capabilities, nullptr, 0, &token));
diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc index dc4375b..d53d074 100644 --- a/sandbox/win/src/sandbox_policy_base.cc +++ b/sandbox/win/src/sandbox_policy_base.cc
@@ -15,6 +15,7 @@ #include "base/strings/stringprintf.h" #include "base/win/win_util.h" #include "base/win/windows_version.h" +#include "sandbox/win/src/acl.h" #include "sandbox/win/src/filesystem_policy.h" #include "sandbox/win/src/interception.h" #include "sandbox/win/src/job.h" @@ -473,6 +474,11 @@ saved_handles_count, lowbox) != ERROR_SUCCESS) { return SBOX_ERROR_GENERIC; } + + if (!ReplacePackageSidInDacl(lowbox->Get(), SE_KERNEL_OBJECT, package_sid, + TOKEN_ALL_ACCESS)) { + return SBOX_ERROR_GENERIC; + } } // Create the 'better' token. We use this token as the one that the main
diff --git a/services/data_decoder/public/cpp/android/BUILD.gn b/services/data_decoder/public/cpp/android/BUILD.gn index 3474ecf2..8db1e96c 100644 --- a/services/data_decoder/public/cpp/android/BUILD.gn +++ b/services/data_decoder/public/cpp/android/BUILD.gn
@@ -15,7 +15,9 @@ android_library("safe_json_java") { deps = [ "//base:base_java", + "//base:jni_java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] java_files = [] + _jni_sources } }
diff --git a/services/data_decoder/public/cpp/android/java/src/org/chromium/services/data_decoder/JsonSanitizer.java b/services/data_decoder/public/cpp/android/java/src/org/chromium/services/data_decoder/JsonSanitizer.java index b3c4bfa..f398f41 100644 --- a/services/data_decoder/public/cpp/android/java/src/org/chromium/services/data_decoder/JsonSanitizer.java +++ b/services/data_decoder/public/cpp/android/java/src/org/chromium/services/data_decoder/JsonSanitizer.java
@@ -12,6 +12,7 @@ import org.chromium.base.StreamUtil; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import java.io.IOException; import java.io.StringReader; @@ -115,10 +116,10 @@ try { result = sanitize(unsafeJson); } catch (IOException | IllegalStateException e) { - nativeOnError(nativePtr, e.getMessage()); + JsonSanitizerJni.get().onError(nativePtr, e.getMessage()); return; } - nativeOnSuccess(nativePtr, result); + JsonSanitizerJni.get().onSuccess(nativePtr, result); } /** @@ -189,7 +190,9 @@ || (codePoint > 0xFDEF && codePoint <= 0x10FFFF && (codePoint & 0xFFFE) != 0xFFFE); } - private static native void nativeOnSuccess(long id, String json); - - private static native void nativeOnError(long id, String error); + @NativeMethods + interface Natives { + void onSuccess(long id, String json); + void onError(long id, String error); + } }
diff --git a/services/device/generic_sensor/BUILD.gn b/services/device/generic_sensor/BUILD.gn index 3fea2ec2..6e0ae74d 100644 --- a/services/device/generic_sensor/BUILD.gn +++ b/services/device/generic_sensor/BUILD.gn
@@ -140,7 +140,9 @@ java_files = device_sensors_jni_sources deps = [ "//base:base_java", + "//base:jni_java", "//services/device/public/mojom:generic_sensor_java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] } }
diff --git a/services/device/generic_sensor/android/java/src/org/chromium/device/sensors/PlatformSensor.java b/services/device/generic_sensor/android/java/src/org/chromium/device/sensors/PlatformSensor.java index 85d7c7d..d16d43d 100644 --- a/services/device/generic_sensor/android/java/src/org/chromium/device/sensors/PlatformSensor.java +++ b/services/device/generic_sensor/android/java/src/org/chromium/device/sensors/PlatformSensor.java
@@ -12,6 +12,7 @@ import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import org.chromium.device.mojom.ReportingMode; import java.util.List; @@ -218,7 +219,8 @@ * Notifies native device::PlatformSensorAndroid when there is an error. */ protected void sensorError() { - nativeNotifyPlatformSensorError(mNativePlatformSensorAndroid); + PlatformSensorJni.get().notifyPlatformSensorError( + mNativePlatformSensorAndroid, PlatformSensor.this); } /** @@ -226,8 +228,8 @@ */ protected void updateSensorReading( double timestamp, double value1, double value2, double value3, double value4) { - nativeUpdatePlatformSensorReading( - mNativePlatformSensorAndroid, timestamp, value1, value2, value3, value4); + PlatformSensorJni.get().updatePlatformSensorReading(mNativePlatformSensorAndroid, + PlatformSensor.this, timestamp, value1, value2, value3, value4); } @Override @@ -264,7 +266,10 @@ } } - private native void nativeNotifyPlatformSensorError(long nativePlatformSensorAndroid); - private native void nativeUpdatePlatformSensorReading(long nativePlatformSensorAndroid, - double timestamp, double value1, double value2, double value3, double value4); + @NativeMethods + interface Natives { + void notifyPlatformSensorError(long nativePlatformSensorAndroid, PlatformSensor caller); + void updatePlatformSensorReading(long nativePlatformSensorAndroid, PlatformSensor caller, + double timestamp, double value1, double value2, double value3, double value4); + } }
diff --git a/services/device/geolocation/BUILD.gn b/services/device/geolocation/BUILD.gn index 03a2fa7e..be8abf4 100644 --- a/services/device/geolocation/BUILD.gn +++ b/services/device/geolocation/BUILD.gn
@@ -146,9 +146,11 @@ "$google_play_services_package:google_play_services_basement_java", "$google_play_services_package:google_play_services_location_java", "//base:base_java", + "//base:jni_java", "//components/location/android:location_java", "//services/device/public/java:geolocation_java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] } }
diff --git a/services/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderAdapter.java b/services/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderAdapter.java index 442ec64..52c501c 100644 --- a/services/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderAdapter.java +++ b/services/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderAdapter.java
@@ -10,6 +10,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.NativeMethods; import java.util.concurrent.FutureTask; @@ -76,20 +77,24 @@ } public static void onNewLocationAvailable(Location location) { - nativeNewLocationAvailable(location.getLatitude(), location.getLongitude(), - location.getTime() / 1000.0, location.hasAltitude(), location.getAltitude(), - location.hasAccuracy(), location.getAccuracy(), location.hasBearing(), - location.getBearing(), location.hasSpeed(), location.getSpeed()); + LocationProviderAdapterJni.get().newLocationAvailable(location.getLatitude(), + location.getLongitude(), location.getTime() / 1000.0, location.hasAltitude(), + location.getAltitude(), location.hasAccuracy(), location.getAccuracy(), + location.hasBearing(), location.getBearing(), location.hasSpeed(), + location.getSpeed()); } public static void newErrorAvailable(String message) { Log.e(TAG, "newErrorAvailable %s", message); - nativeNewErrorAvailable(message); + LocationProviderAdapterJni.get().newErrorAvailable(message); } - // Native functions - private static native void nativeNewLocationAvailable(double latitude, double longitude, - double timeStamp, boolean hasAltitude, double altitude, boolean hasAccuracy, - double accuracy, boolean hasHeading, double heading, boolean hasSpeed, double speed); - private static native void nativeNewErrorAvailable(String message); + @NativeMethods + interface Natives { + void newLocationAvailable(double latitude, double longitude, double timeStamp, + boolean hasAltitude, double altitude, boolean hasAccuracy, double accuracy, + boolean hasHeading, double heading, boolean hasSpeed, double speed); + + void newErrorAvailable(String message); + } }
diff --git a/services/device/time_zone_monitor/BUILD.gn b/services/device/time_zone_monitor/BUILD.gn index 1f56c9f..58b31ed 100644 --- a/services/device/time_zone_monitor/BUILD.gn +++ b/services/device/time_zone_monitor/BUILD.gn
@@ -73,6 +73,8 @@ java_files = [ "android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java" ] deps = [ "//base:base_java", + "//base:jni_java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] } }
diff --git a/services/device/time_zone_monitor/android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java b/services/device/time_zone_monitor/android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java index f927cd8..2214843 100644 --- a/services/device/time_zone_monitor/android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java +++ b/services/device/time_zone_monitor/android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java
@@ -13,6 +13,7 @@ import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; /** * Android implementation details for device::TimeZoneMonitorAndroid. @@ -30,7 +31,7 @@ return; } - nativeTimeZoneChangedFromJava(mNativePtr); + TimeZoneMonitorJni.get().timeZoneChangedFromJava(mNativePtr, TimeZoneMonitor.this); } }; @@ -59,9 +60,12 @@ mNativePtr = 0; } - /** - * Native JNI call to device::TimeZoneMonitorAndroid::TimeZoneChanged. - * See device/time_zone_monitor/time_zone_monitor_android.cc. - */ - private native void nativeTimeZoneChangedFromJava(long nativeTimeZoneMonitorAndroid); + @NativeMethods + interface Natives { + /** + * Native JNI call to device::TimeZoneMonitorAndroid::TimeZoneChanged. See + * device/time_zone_monitor/time_zone_monitor_android.cc. + */ + void timeZoneChangedFromJava(long nativeTimeZoneMonitorAndroid, TimeZoneMonitor caller); + } }
diff --git a/services/device/usb/BUILD.gn b/services/device/usb/BUILD.gn index b2ba8073..a28fdc7d 100644 --- a/services/device/usb/BUILD.gn +++ b/services/device/usb/BUILD.gn
@@ -209,6 +209,8 @@ java_files = java_sources_needing_jni deps = [ "//base:base_java", + "//base:jni_java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] } }
diff --git a/services/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbService.java b/services/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbService.java index be304a7f..d4587b7 100644 --- a/services/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbService.java +++ b/services/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbService.java
@@ -17,6 +17,7 @@ import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; import java.util.HashMap; @@ -70,7 +71,8 @@ private void requestDevicePermission(ChromeUsbDevice wrapper) { UsbDevice device = wrapper.getDevice(); if (mUsbManager.hasPermission(device)) { - nativeDevicePermissionRequestComplete(mUsbServiceAndroid, device.getDeviceId(), true); + ChromeUsbServiceJni.get().devicePermissionRequestComplete( + mUsbServiceAndroid, ChromeUsbService.this, device.getDeviceId(), true); } else { PendingIntent intent = PendingIntent.getBroadcast( ContextUtils.getApplicationContext(), 0, new Intent(ACTION_USB_PERMISSION), 0); @@ -83,24 +85,20 @@ unregisterForUsbDeviceIntentBroadcast(); } - private native void nativeDeviceAttached(long nativeUsbServiceAndroid, UsbDevice device); - - private native void nativeDeviceDetached(long nativeUsbServiceAndroid, int deviceId); - - private native void nativeDevicePermissionRequestComplete( - long nativeUsbServiceAndroid, int deviceId, boolean granted); - private void registerForUsbDeviceIntentBroadcast() { mUsbDeviceReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) { - nativeDeviceAttached(mUsbServiceAndroid, device); + ChromeUsbServiceJni.get().deviceAttached( + mUsbServiceAndroid, ChromeUsbService.this, device); } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) { - nativeDeviceDetached(mUsbServiceAndroid, device.getDeviceId()); + ChromeUsbServiceJni.get().deviceDetached( + mUsbServiceAndroid, ChromeUsbService.this, device.getDeviceId()); } else if (ACTION_USB_PERMISSION.equals(intent.getAction())) { - nativeDevicePermissionRequestComplete(mUsbServiceAndroid, device.getDeviceId(), + ChromeUsbServiceJni.get().devicePermissionRequestComplete(mUsbServiceAndroid, + ChromeUsbService.this, device.getDeviceId(), intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)); } } @@ -117,4 +115,13 @@ ContextUtils.getApplicationContext().unregisterReceiver(mUsbDeviceReceiver); mUsbDeviceReceiver = null; } + + @NativeMethods + interface Natives { + void deviceAttached( + long nativeUsbServiceAndroid, ChromeUsbService caller, UsbDevice device); + void deviceDetached(long nativeUsbServiceAndroid, ChromeUsbService caller, int deviceId); + void devicePermissionRequestComplete(long nativeUsbServiceAndroid, ChromeUsbService caller, + int deviceId, boolean granted); + } }
diff --git a/services/viz/public/cpp/compositing/mojom_traits_unittest.cc b/services/viz/public/cpp/compositing/mojom_traits_unittest.cc index 2eee226d..b167ef914 100644 --- a/services/viz/public/cpp/compositing/mojom_traits_unittest.cc +++ b/services/viz/public/cpp/compositing/mojom_traits_unittest.cc
@@ -939,8 +939,8 @@ RenderPassDrawQuad* render_pass_quad = render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); render_pass_quad->SetNew(sqs, rect4, rect4, render_pass_id, resource_id4, - mask_uv_rect, mask_texture_size, false, - filters_scale, filters_origin, tex_coord_rect, + mask_uv_rect, mask_texture_size, filters_scale, + filters_origin, tex_coord_rect, force_anti_aliasing_off, backdrop_filter_quality); const gfx::Rect rect5(123, 567, 91011, 131415); @@ -1016,7 +1016,6 @@ EXPECT_EQ(render_pass_id, out_render_pass_draw_quad->render_pass_id); EXPECT_EQ(resource_id4, out_render_pass_draw_quad->mask_resource_id()); EXPECT_EQ(mask_texture_size, out_render_pass_draw_quad->mask_texture_size); - EXPECT_FALSE(out_render_pass_draw_quad->mask_applies_to_backdrop); EXPECT_EQ(filters_scale, out_render_pass_draw_quad->filters_scale); EXPECT_EQ(force_anti_aliasing_off, out_render_pass_draw_quad->force_anti_aliasing_off);
diff --git a/services/viz/public/cpp/compositing/quads_mojom_traits.cc b/services/viz/public/cpp/compositing/quads_mojom_traits.cc index 3d35e2fd..e41f086 100644 --- a/services/viz/public/cpp/compositing/quads_mojom_traits.cc +++ b/services/viz/public/cpp/compositing/quads_mojom_traits.cc
@@ -72,7 +72,6 @@ quad->resources.ids[viz::RenderPassDrawQuad::kMaskResourceIdIndex] = data.mask_resource_id(); quad->resources.count = data.mask_resource_id() ? 1 : 0; - quad->mask_applies_to_backdrop = data.mask_applies_to_backdrop(); quad->render_pass_id = data.render_pass_id(); // RenderPass ids are never zero. if (!quad->render_pass_id)
diff --git a/services/viz/public/cpp/compositing/quads_mojom_traits.h b/services/viz/public/cpp/compositing/quads_mojom_traits.h index b62fcf4..b1cc3237 100644 --- a/services/viz/public/cpp/compositing/quads_mojom_traits.h +++ b/services/viz/public/cpp/compositing/quads_mojom_traits.h
@@ -224,12 +224,6 @@ return quad->mask_texture_size; } - static bool mask_applies_to_backdrop(const viz::DrawQuad& input) { - const viz::RenderPassDrawQuad* quad = - viz::RenderPassDrawQuad::MaterialCast(&input); - return quad->mask_applies_to_backdrop; - } - static const gfx::Vector2dF& filters_scale(const viz::DrawQuad& input) { const viz::RenderPassDrawQuad* quad = viz::RenderPassDrawQuad::MaterialCast(&input);
diff --git a/services/viz/public/mojom/compositing/quads.mojom b/services/viz/public/mojom/compositing/quads.mojom index cdfaa7b0..438c869 100644 --- a/services/viz/public/mojom/compositing/quads.mojom +++ b/services/viz/public/mojom/compositing/quads.mojom
@@ -35,10 +35,6 @@ gfx.mojom.RectF mask_uv_rect; gfx.mojom.Size mask_texture_size; - // If true, the mask described by mask_resource_id should be applied to only - // the backdrop-filtered image. - bool mask_applies_to_backdrop; - // The scale from layer space of the root layer of the render pass to // the render pass physical pixels. This scale is applied to the filter // parameters for pixel-moving filters. This scale should include
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index aaf6a62..a19a93da 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -25400,90 +25400,112 @@ "junit_tests": [ { "name": "android_webview_junit_tests", + "swarming": {}, "test": "android_webview_junit_tests" }, { "name": "base_junit_tests", + "swarming": {}, "test": "base_junit_tests" }, { "name": "chrome_junit_tests", + "swarming": {}, "test": "chrome_junit_tests" }, { "name": "components_background_task_scheduler_junit_tests", + "swarming": {}, "test": "components_background_task_scheduler_junit_tests" }, { "name": "components_gcm_driver_junit_tests", + "swarming": {}, "test": "components_gcm_driver_junit_tests" }, { "name": "components_invalidation_impl_junit_tests", + "swarming": {}, "test": "components_invalidation_impl_junit_tests" }, { "name": "components_policy_junit_tests", + "swarming": {}, "test": "components_policy_junit_tests" }, { "name": "components_signin_junit_tests", + "swarming": {}, "test": "components_signin_junit_tests" }, { "name": "components_variations_junit_tests", + "swarming": {}, "test": "components_variations_junit_tests" }, { "name": "content_junit_tests", + "swarming": {}, "test": "content_junit_tests" }, { "name": "device_junit_tests", + "swarming": {}, "test": "device_junit_tests" }, { "name": "junit_unit_tests", + "swarming": {}, "test": "junit_unit_tests" }, { "name": "keyboard_accessory_junit_tests", + "swarming": {}, "test": "keyboard_accessory_junit_tests" }, { "name": "media_base_junit_tests", + "swarming": {}, "test": "media_base_junit_tests" }, { "name": "media_router_junit_tests", + "swarming": {}, "test": "media_router_junit_tests" }, { "name": "module_installer_junit_tests", + "swarming": {}, "test": "module_installer_junit_tests" }, { "name": "net_junit_tests", + "swarming": {}, "test": "net_junit_tests" }, { "name": "service_junit_tests", + "swarming": {}, "test": "service_junit_tests" }, { "name": "ui_junit_tests", + "swarming": {}, "test": "ui_junit_tests" }, { "name": "webapk_client_junit_tests", + "swarming": {}, "test": "webapk_client_junit_tests" }, { "name": "webapk_shell_apk_h2o_junit_tests", + "swarming": {}, "test": "webapk_shell_apk_h2o_junit_tests" }, { "name": "webapk_shell_apk_junit_tests", + "swarming": {}, "test": "webapk_shell_apk_junit_tests" } ]
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json index d83cccf4..f58d98c9 100644 --- a/testing/buildbot/chromium.clang.json +++ b/testing/buildbot/chromium.clang.json
@@ -7542,90 +7542,112 @@ "junit_tests": [ { "name": "android_webview_junit_tests", + "swarming": {}, "test": "android_webview_junit_tests" }, { "name": "base_junit_tests", + "swarming": {}, "test": "base_junit_tests" }, { "name": "chrome_junit_tests", + "swarming": {}, "test": "chrome_junit_tests" }, { "name": "components_background_task_scheduler_junit_tests", + "swarming": {}, "test": "components_background_task_scheduler_junit_tests" }, { "name": "components_gcm_driver_junit_tests", + "swarming": {}, "test": "components_gcm_driver_junit_tests" }, { "name": "components_invalidation_impl_junit_tests", + "swarming": {}, "test": "components_invalidation_impl_junit_tests" }, { "name": "components_policy_junit_tests", + "swarming": {}, "test": "components_policy_junit_tests" }, { "name": "components_signin_junit_tests", + "swarming": {}, "test": "components_signin_junit_tests" }, { "name": "components_variations_junit_tests", + "swarming": {}, "test": "components_variations_junit_tests" }, { "name": "content_junit_tests", + "swarming": {}, "test": "content_junit_tests" }, { "name": "device_junit_tests", + "swarming": {}, "test": "device_junit_tests" }, { "name": "junit_unit_tests", + "swarming": {}, "test": "junit_unit_tests" }, { "name": "keyboard_accessory_junit_tests", + "swarming": {}, "test": "keyboard_accessory_junit_tests" }, { "name": "media_base_junit_tests", + "swarming": {}, "test": "media_base_junit_tests" }, { "name": "media_router_junit_tests", + "swarming": {}, "test": "media_router_junit_tests" }, { "name": "module_installer_junit_tests", + "swarming": {}, "test": "module_installer_junit_tests" }, { "name": "net_junit_tests", + "swarming": {}, "test": "net_junit_tests" }, { "name": "service_junit_tests", + "swarming": {}, "test": "service_junit_tests" }, { "name": "ui_junit_tests", + "swarming": {}, "test": "ui_junit_tests" }, { "name": "webapk_client_junit_tests", + "swarming": {}, "test": "webapk_client_junit_tests" }, { "name": "webapk_shell_apk_h2o_junit_tests", + "swarming": {}, "test": "webapk_shell_apk_h2o_junit_tests" }, { "name": "webapk_shell_apk_junit_tests", + "swarming": {}, "test": "webapk_shell_apk_junit_tests" } ]
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index c4c0e09..6412dfe 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -7494,91 +7494,135 @@ ], "junit_tests": [ { + "isolate_coverage_data": true, "name": "android_webview_junit_tests", + "swarming": {}, "test": "android_webview_junit_tests" }, { + "isolate_coverage_data": true, "name": "base_junit_tests", + "swarming": {}, "test": "base_junit_tests" }, { + "isolate_coverage_data": true, "name": "chrome_junit_tests", + "swarming": {}, "test": "chrome_junit_tests" }, { + "isolate_coverage_data": true, "name": "components_background_task_scheduler_junit_tests", + "swarming": {}, "test": "components_background_task_scheduler_junit_tests" }, { + "isolate_coverage_data": true, "name": "components_gcm_driver_junit_tests", + "swarming": {}, "test": "components_gcm_driver_junit_tests" }, { + "isolate_coverage_data": true, "name": "components_invalidation_impl_junit_tests", + "swarming": {}, "test": "components_invalidation_impl_junit_tests" }, { + "isolate_coverage_data": true, "name": "components_policy_junit_tests", + "swarming": {}, "test": "components_policy_junit_tests" }, { + "isolate_coverage_data": true, "name": "components_signin_junit_tests", + "swarming": {}, "test": "components_signin_junit_tests" }, { + "isolate_coverage_data": true, "name": "components_variations_junit_tests", + "swarming": {}, "test": "components_variations_junit_tests" }, { + "isolate_coverage_data": true, "name": "content_junit_tests", + "swarming": {}, "test": "content_junit_tests" }, { + "isolate_coverage_data": true, "name": "device_junit_tests", + "swarming": {}, "test": "device_junit_tests" }, { + "isolate_coverage_data": true, "name": "junit_unit_tests", + "swarming": {}, "test": "junit_unit_tests" }, { + "isolate_coverage_data": true, "name": "keyboard_accessory_junit_tests", + "swarming": {}, "test": "keyboard_accessory_junit_tests" }, { + "isolate_coverage_data": true, "name": "media_base_junit_tests", + "swarming": {}, "test": "media_base_junit_tests" }, { + "isolate_coverage_data": true, "name": "media_router_junit_tests", + "swarming": {}, "test": "media_router_junit_tests" }, { + "isolate_coverage_data": true, "name": "module_installer_junit_tests", + "swarming": {}, "test": "module_installer_junit_tests" }, { + "isolate_coverage_data": true, "name": "net_junit_tests", + "swarming": {}, "test": "net_junit_tests" }, { + "isolate_coverage_data": true, "name": "service_junit_tests", + "swarming": {}, "test": "service_junit_tests" }, { + "isolate_coverage_data": true, "name": "ui_junit_tests", + "swarming": {}, "test": "ui_junit_tests" }, { + "isolate_coverage_data": true, "name": "webapk_client_junit_tests", + "swarming": {}, "test": "webapk_client_junit_tests" }, { + "isolate_coverage_data": true, "name": "webapk_shell_apk_h2o_junit_tests", + "swarming": {}, "test": "webapk_shell_apk_h2o_junit_tests" }, { + "isolate_coverage_data": true, "name": "webapk_shell_apk_junit_tests", + "swarming": {}, "test": "webapk_shell_apk_junit_tests" } ]
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 0490998..d750df34 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -10807,6 +10807,7 @@ "--driver-logging", "--test-list=../../testing/buildbot/filters/gpu.skiarenderer_vulkan_blink_web_tests.filter", "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/enable-features=UseSkiaRenderer", + "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/enable-gpu-rasterization", "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/use-vulkan=native" ], "isolate_name": "blink_web_tests_exparchive", @@ -11353,6 +11354,7 @@ "--driver-logging", "--test-list=../../testing/buildbot/filters/gpu.skiarenderer_vulkan_blink_web_tests.filter", "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/enable-features=UseSkiaRenderer", + "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/enable-gpu-rasterization", "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/use-vulkan=native" ], "isolate_name": "blink_web_tests_exparchive",
diff --git a/testing/buildbot/generate_buildbot_json.py b/testing/buildbot/generate_buildbot_json.py index 49cfea3..50c23016 100755 --- a/testing/buildbot/generate_buildbot_json.py +++ b/testing/buildbot/generate_buildbot_json.py
@@ -633,14 +633,17 @@ def generate_junit_test(self, waterfall, tester_name, tester_config, test_name, test_config): - del tester_config if not self.should_run_on_tester(waterfall, tester_name, test_name, test_config): return None - result = { + result = copy.deepcopy(test_config) + result.update({ 'name': test_name, 'test': test_config.get('test', test_name), - } + }) + self.initialize_args_for_test(result, tester_config) + result = self.update_and_cleanup_test( + result, test_name, tester_name, tester_config, waterfall) return result def generate_instrumentation_test(self, waterfall, tester_name, tester_config,
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index d89479a8..8eb5b9a 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -3340,6 +3340,7 @@ '--driver-logging', '--test-list=../../testing/buildbot/filters/gpu.skiarenderer_vulkan_blink_web_tests.filter', '--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/enable-features=UseSkiaRenderer', + '--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/enable-gpu-rasterization', '--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/use-vulkan=native', ], 'isolate_name': 'blink_web_tests_exparchive',
diff --git a/testing/buildbot/tryserver.chromium.android.json b/testing/buildbot/tryserver.chromium.android.json index fdbb364..666075a92 100644 --- a/testing/buildbot/tryserver.chromium.android.json +++ b/testing/buildbot/tryserver.chromium.android.json
@@ -2883,91 +2883,135 @@ ], "junit_tests": [ { + "isolate_coverage_data": true, "name": "android_webview_junit_tests", + "swarming": {}, "test": "android_webview_junit_tests" }, { + "isolate_coverage_data": true, "name": "base_junit_tests", + "swarming": {}, "test": "base_junit_tests" }, { + "isolate_coverage_data": true, "name": "chrome_junit_tests", + "swarming": {}, "test": "chrome_junit_tests" }, { + "isolate_coverage_data": true, "name": "components_background_task_scheduler_junit_tests", + "swarming": {}, "test": "components_background_task_scheduler_junit_tests" }, { + "isolate_coverage_data": true, "name": "components_gcm_driver_junit_tests", + "swarming": {}, "test": "components_gcm_driver_junit_tests" }, { + "isolate_coverage_data": true, "name": "components_invalidation_impl_junit_tests", + "swarming": {}, "test": "components_invalidation_impl_junit_tests" }, { + "isolate_coverage_data": true, "name": "components_policy_junit_tests", + "swarming": {}, "test": "components_policy_junit_tests" }, { + "isolate_coverage_data": true, "name": "components_signin_junit_tests", + "swarming": {}, "test": "components_signin_junit_tests" }, { + "isolate_coverage_data": true, "name": "components_variations_junit_tests", + "swarming": {}, "test": "components_variations_junit_tests" }, { + "isolate_coverage_data": true, "name": "content_junit_tests", + "swarming": {}, "test": "content_junit_tests" }, { + "isolate_coverage_data": true, "name": "device_junit_tests", + "swarming": {}, "test": "device_junit_tests" }, { + "isolate_coverage_data": true, "name": "junit_unit_tests", + "swarming": {}, "test": "junit_unit_tests" }, { + "isolate_coverage_data": true, "name": "keyboard_accessory_junit_tests", + "swarming": {}, "test": "keyboard_accessory_junit_tests" }, { + "isolate_coverage_data": true, "name": "media_base_junit_tests", + "swarming": {}, "test": "media_base_junit_tests" }, { + "isolate_coverage_data": true, "name": "media_router_junit_tests", + "swarming": {}, "test": "media_router_junit_tests" }, { + "isolate_coverage_data": true, "name": "module_installer_junit_tests", + "swarming": {}, "test": "module_installer_junit_tests" }, { + "isolate_coverage_data": true, "name": "net_junit_tests", + "swarming": {}, "test": "net_junit_tests" }, { + "isolate_coverage_data": true, "name": "service_junit_tests", + "swarming": {}, "test": "service_junit_tests" }, { + "isolate_coverage_data": true, "name": "ui_junit_tests", + "swarming": {}, "test": "ui_junit_tests" }, { + "isolate_coverage_data": true, "name": "webapk_client_junit_tests", + "swarming": {}, "test": "webapk_client_junit_tests" }, { + "isolate_coverage_data": true, "name": "webapk_shell_apk_h2o_junit_tests", + "swarming": {}, "test": "webapk_shell_apk_h2o_junit_tests" }, { + "isolate_coverage_data": true, "name": "webapk_shell_apk_junit_tests", + "swarming": {}, "test": "webapk_shell_apk_junit_tests" } ]
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index f266b50..64e963c 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1517,6 +1517,21 @@ ] } ], + "CertVerifierBuiltin": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CertVerifierBuiltin" + ] + } + ] + } + ], "ChromeCleanupDistribution": [ { "platforms": [
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc index aeaa0c8..722bc55 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc
@@ -107,9 +107,11 @@ } } - // If child has the same style as parent, parent will compute relative - // offset. - if (&child->Style() != container_style) { + // For implementation reasons, text nodes inherit computed style from their + // container, including everything, also non-inherited properties. So, if + // the container has a relative offset, this will be falsely reflected on + // text children. We need to guard against this. + if (!child->IsText()) { child_scroll_overflow.offset += ComputeRelativeOffset(child->Style(), container_writing_mode, container_direction, container_physical_size);
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc index ab9781059..fc9b820 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -1730,10 +1730,12 @@ mask_layer_ = CreateGraphicsLayer(CompositingReason::kLayerForMask); mask_layer_->SetPaintingPhase(kGraphicsLayerPaintMask); CompositorElementId element_id = CompositorElementIdFromUniqueObjectId( - owning_layer_.GetLayoutObject().UniqueId(), + GetLayoutObject().UniqueId(), CompositorElementIdNamespace::kEffectMask); mask_layer_->SetElementId(element_id); - mask_layer_->CcLayer()->set_is_mask(); + mask_layer_->CcLayer()->SetIsMask(true); + if (GetLayoutObject().HasBackdropFilter()) + mask_layer_->CcLayer()->SetIsBackdropFilterMask(true); layer_changed = true; } } else if (mask_layer_) {
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc index 0a1dbd7..c54b6c8 100644 --- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc +++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -888,38 +888,18 @@ if (interval_.BeginsAfter(presentation_time)) { next_interesting_interval_time = interval_.begin; } else if (interval_.EndsAfter(presentation_time)) { - next_interesting_interval_time = interval_.end; - SMILTime simple_duration = SimpleDuration(); - if (simple_duration) { + if (SMILTime simple_duration = SimpleDuration()) { SMILTime next_repeat_time = ComputeNextRepeatTime( interval_.begin, simple_duration, presentation_time); DCHECK(next_repeat_time.IsFinite()); - // Because of floating point issues we can end up getting a - // |next_repeat_time| == |presentation_time|, which would fail our - // requirement, meaning we wouldn't make progress. Integers FTW! - if (presentation_time < next_repeat_time) { - next_interesting_interval_time = - std::min(next_interesting_interval_time, next_repeat_time); - } + next_interesting_interval_time = + std::min(next_repeat_time, interval_.end); + } else { + next_interesting_interval_time = interval_.end; } } - // TODO(edvardt): This is a vile hack. - // Removing 0.5ms, which is less than the minimum precision time. - // - // Removing this will break most repeatn-* tests, and - // most tests with onmouse syncbases. These are a few: - // svg/animations/reapeatn-* - // external/wpt/svg/animations/scripted/onhover-syncbases.html - // external/wpt/svg/animations/slider-switch.html - // These break because the updates land ON THE SAME TIMES as the - // instance times. And the animation cannot then get a new interval - // from that instance time. - const SMILTime half_ms = SMILTime::FromSecondsD(0.0005); - const SMILTime instance_time = - FindInstanceTime(kBegin, presentation_time, false) - half_ms; - if (presentation_time < instance_time) - return std::min(next_interesting_interval_time, instance_time); - return next_interesting_interval_time; + return std::min(next_interesting_interval_time, + FindInstanceTime(kBegin, presentation_time, false)); } void SVGSMILElement::BeginListChanged(SMILTime event_time) {
diff --git a/third_party/blink/renderer/devtools/.eslintrc.js b/third_party/blink/renderer/devtools/.eslintrc.js index 401bb011..10cc7cb 100644 --- a/third_party/blink/renderer/devtools/.eslintrc.js +++ b/third_party/blink/renderer/devtools/.eslintrc.js
@@ -7,8 +7,7 @@ }, "parserOptions": { - "ecmaVersion": 9, - "sourceType": "module" + "ecmaVersion": 9 }, /**
diff --git a/third_party/blink/renderer/devtools/BUILD.gn b/third_party/blink/renderer/devtools/BUILD.gn index 3b9d6d3..917c44c 100644 --- a/third_party/blink/renderer/devtools/BUILD.gn +++ b/third_party/blink/renderer/devtools/BUILD.gn
@@ -786,6 +786,7 @@ "front_end/toolbox.js", "front_end/toolbox.json", "front_end/ui/ActionRegistry.js", + "front_end/ui/ARIAUtils.js", "front_end/ui/checkboxTextLabel.css", "front_end/ui/closeButton.css", "front_end/ui/confirmDialog.css", @@ -957,12 +958,6 @@ all_devtools_files += lighthouse_locale_files -all_devtools_modules = [ - "front_end/root.js", - "front_end/ui/ARIAUtils.js", - "front_end/ui/UI.js", -] - devtools_test_files = [ "//third_party/axe-core/axe.js", "front_end/accessibility_test_runner/AccessibilityPaneTestRunner.js", @@ -1154,12 +1149,6 @@ "front_end/worker_app.html", ] -copied_devtools_modules = [ - "$resources_out_dir/root.js", - "$resources_out_dir/ui/ARIAUtils.js", - "$resources_out_dir/ui/UI.js", -] - generated_applications = [ "$resources_out_dir/audits_worker.js", "$resources_out_dir/devtools_app.html", @@ -1278,7 +1267,7 @@ visibility = [ "//third_party/blink/*" ] group("devtools_all_files") { - data = all_devtools_files + all_devtools_modules + data = all_devtools_files deps = [ ":devtools_frontend_resources_data", ] @@ -1295,7 +1284,6 @@ ":devtools_extension_api", ":frontend_protocol_sources", ":supported_css_properties", - ":copy_devtools_modules", ] if (debug_devtools) { @@ -1360,8 +1348,8 @@ ] grd_files = - all_devtools_modules + generated_applications + - generated_non_autostart_non_remote_modules + devtools_embedder_scripts + + generated_applications + generated_non_autostart_non_remote_modules + + devtools_embedder_scripts + [ "$resources_out_dir/devtools_extension_api.js" ] # Bundle remote modules in ChromeOS. @@ -1480,24 +1468,6 @@ ] } -action("copy_devtools_modules") { - script = "scripts/build/copy_devtools_modules.py" - - deps = [ - ":build_release_devtools", - ] - - inputs = all_devtools_modules - outputs = copied_devtools_modules - - args = all_devtools_modules + [ - "--input_path", - rebase_path(".", root_build_dir), - "--output_path", - rebase_path(resources_out_dir, root_build_dir), - ] -} - if (debug_devtools) { resources_out_debug_dir = "$root_out_dir/resources/inspector/debug"
diff --git a/third_party/blink/renderer/devtools/PRESUBMIT.py b/third_party/blink/renderer/devtools/PRESUBMIT.py index 4768b66..1166bdb 100644 --- a/third_party/blink/renderer/devtools/PRESUBMIT.py +++ b/third_party/blink/renderer/devtools/PRESUBMIT.py
@@ -78,8 +78,8 @@ # Use eslint to autofix the braces. # Also fix semicolon to avoid confusing clang-format. eslint_process = popen([ - local_node.node_path(), - local_node.eslint_path(), '--no-eslintrc', '--fix', '--env=es6', '--parser-options=ecmaVersion:9,sourceType:module', + local_node.node_path(), local_node.eslint_path(), + '--no-eslintrc', '--fix', '--env=es6', '--parser-options=ecmaVersion:9', '--rule={"curly": [2, "multi-or-nest", "consistent"], "semi": 2}' ] + affected_files) eslint_process.communicate()
diff --git a/third_party/blink/renderer/devtools/front_end/devtools_app.html b/third_party/blink/renderer/devtools/front_end/devtools_app.html index 2460c329..81b6645 100644 --- a/third_party/blink/renderer/devtools/front_end/devtools_app.html +++ b/third_party/blink/renderer/devtools/front_end/devtools_app.html
@@ -9,9 +9,8 @@ <meta charset="utf-8"> <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com"> <meta name="referrer" content="no-referrer"> - <script type="module" src="root.js"></script> - <script defer src="Runtime.js"></script> - <script defer src="devtools_app.js"></script> + <script src="Runtime.js"></script> + <script src="devtools_app.js"></script> </head> <body class="undocked" id="-blink-dev-tools"></body> </html>
diff --git a/third_party/blink/renderer/devtools/front_end/inspector.html b/third_party/blink/renderer/devtools/front_end/inspector.html index 1ab4d319..b5d6f04e 100644 --- a/third_party/blink/renderer/devtools/front_end/inspector.html +++ b/third_party/blink/renderer/devtools/front_end/inspector.html
@@ -9,9 +9,8 @@ <meta charset="utf-8"> <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com"> <meta name="referrer" content="no-referrer"> - <script type="module" src="root.js"></script> - <script defer src="Runtime.js"></script> - <script defer src="inspector.js"></script> + <script src="Runtime.js"></script> + <script src="inspector.js"></script> </head> <body class="undocked" id="-blink-dev-tools"></body> </html>
diff --git a/third_party/blink/renderer/devtools/front_end/integration_test_runner.html b/third_party/blink/renderer/devtools/front_end/integration_test_runner.html index 073b301..ca7cc521 100644 --- a/third_party/blink/renderer/devtools/front_end/integration_test_runner.html +++ b/third_party/blink/renderer/devtools/front_end/integration_test_runner.html
@@ -8,9 +8,8 @@ <head> <meta charset="utf-8"> <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com"> - <script type="module" src="root.js"></script> - <script defer src="Runtime.js"></script> - <script defer src="integration_test_runner.js"></script> + <script src="Runtime.js"></script> + <script src="integration_test_runner.js"></script> </head> <body id="-blink-dev-tools"></body> </html>
diff --git a/third_party/blink/renderer/devtools/front_end/js_app.html b/third_party/blink/renderer/devtools/front_end/js_app.html index 8cc144c..7105918 100644 --- a/third_party/blink/renderer/devtools/front_end/js_app.html +++ b/third_party/blink/renderer/devtools/front_end/js_app.html
@@ -9,9 +9,8 @@ <meta charset="utf-8"> <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com"> <meta name="referrer" content="no-referrer"> - <script type="module" src="root.js"></script> - <script defer src="Runtime.js"></script> - <script defer src="js_app.js"></script> + <script src="Runtime.js"></script> + <script src="js_app.js"></script> </head> <body class="undocked" id="-blink-dev-tools"></body> </html>
diff --git a/third_party/blink/renderer/devtools/front_end/ndb_app.html b/third_party/blink/renderer/devtools/front_end/ndb_app.html index d6f17486..ac0dee1 100644 --- a/third_party/blink/renderer/devtools/front_end/ndb_app.html +++ b/third_party/blink/renderer/devtools/front_end/ndb_app.html
@@ -9,9 +9,8 @@ <meta charset="utf-8"> <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com"> <meta name="referrer" content="no-referrer"> - <script type="module" src="root.js"></script> - <script defer src="Runtime.js"></script> - <script defer src="ndb_app.js"></script> + <script src="Runtime.js"></script> + <script src="ndb_app.js"></script> </head> <body class="undocked" id="-blink-dev-tools"></body> </html>
diff --git a/third_party/blink/renderer/devtools/front_end/node_app.html b/third_party/blink/renderer/devtools/front_end/node_app.html index 5b475a11..05aa910 100644 --- a/third_party/blink/renderer/devtools/front_end/node_app.html +++ b/third_party/blink/renderer/devtools/front_end/node_app.html
@@ -9,9 +9,8 @@ <meta charset="utf-8"> <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com"> <meta name="referrer" content="no-referrer"> - <script type="module" src="root.js"></script> - <script defer src="Runtime.js"></script> - <script defer src="node_app.js"></script> + <script src="Runtime.js"></script> + <script src="node_app.js"></script> </head> <body class="undocked" id="-blink-dev-tools"></body> </html>
diff --git a/third_party/blink/renderer/devtools/front_end/root.js b/third_party/blink/renderer/devtools/front_end/root.js deleted file mode 100644 index 90ae39a..0000000 --- a/third_party/blink/renderer/devtools/front_end/root.js +++ /dev/null
@@ -1,5 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import './ui/UI.js'; \ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js b/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js index 8c846ad8e..3c79383 100644 --- a/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js +++ b/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js
@@ -65,7 +65,6 @@ const initialNavigatorWidth = 225; this.editorView = new UI.SplitWidget(true, false, 'sourcesPanelNavigatorSplitViewState', initialNavigatorWidth); this.editorView.enableShowModeSaving(); - this.editorView.element.tabIndex = 0; this._splitWidget.setMainWidget(this.editorView); // Create navigator tabbed pane with toolbar.
diff --git a/third_party/blink/renderer/devtools/front_end/toolbox.html b/third_party/blink/renderer/devtools/front_end/toolbox.html index ab892052..c48ad36 100644 --- a/third_party/blink/renderer/devtools/front_end/toolbox.html +++ b/third_party/blink/renderer/devtools/front_end/toolbox.html
@@ -8,9 +8,8 @@ <head> <meta charset="utf-8"> <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' "> - <script type="module" src="root.js"></script> - <script defer src="Runtime.js"></script> - <script defer src="toolbox.js"></script> + <script src="Runtime.js"></script> + <script src="toolbox.js"></script> </head> <body class="undocked" id="-blink-dev-tools"></body> </html>
diff --git a/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js b/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js index 088e6ee..fd1aad50 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js +++ b/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js
@@ -2,326 +2,327 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -let _id = 0; - -/** - * @param {string} prefix - * @return {string} - */ -export function nextId(prefix) { - return (prefix || '') + ++_id; -} +UI.ARIAUtils = {}; +UI.ARIAUtils._id = 0; /** * @param {!Element} label * @param {!Element} control */ -export function bindLabelToControl(label, control) { - const controlId = nextId('labelledControl'); +UI.ARIAUtils.bindLabelToControl = function(label, control) { + const controlId = UI.ARIAUtils.nextId('labelledControl'); control.id = controlId; label.setAttribute('for', controlId); -} +}; /** * @param {!Element} element */ -export function markAsAlert(element) { +UI.ARIAUtils.markAsAlert = function(element) { element.setAttribute('role', 'alert'); element.setAttribute('aria-live', 'polite'); -} +}; /** * @param {!Element} element */ -export function markAsButton(element) { +UI.ARIAUtils.markAsButton = function(element) { element.setAttribute('role', 'button'); -} +}; /** * @param {!Element} element */ -export function markAsCheckbox(element) { +UI.ARIAUtils.markAsCheckbox = function(element) { element.setAttribute('role', 'checkbox'); -} +}; /** * @param {!Element} element * @param {boolean=} modal */ -export function markAsDialog(element, modal) { +UI.ARIAUtils.markAsDialog = function(element, modal) { element.setAttribute('role', 'dialog'); if (modal) element.setAttribute('aria-modal', 'true'); -} +}; /** * @param {!Element} element */ -export function markAsGroup(element) { +UI.ARIAUtils.markAsGroup = function(element) { element.setAttribute('role', 'group'); -} +}; /** * @param {!Element} element */ -export function markAsLink(element) { +UI.ARIAUtils.markAsLink = function(element) { element.setAttribute('role', 'link'); -} +}; /** * @param {!Element} element */ -export function markAsMenuButton(element) { - markAsButton(element); +UI.ARIAUtils.markAsMenuButton = function(element) { + UI.ARIAUtils.markAsButton(element); element.setAttribute('aria-haspopup', true); -} +}; /** * @param {!Element} element */ -export function markAsProgressBar(element) { +UI.ARIAUtils.markAsProgressBar = function(element) { element.setAttribute('role', 'progressbar'); element.setAttribute('aria-valuemin', 0); element.setAttribute('aria-valuemax', 100); -} +}; /** * @param {!Element} element */ -export function markAsTab(element) { +UI.ARIAUtils.markAsTab = function(element) { element.setAttribute('role', 'tab'); -} +}; /** * @param {!Element} element */ -export function markAsTree(element) { +UI.ARIAUtils.markAsTree = function(element) { element.setAttribute('role', 'tree'); -} +}; /** * @param {!Element} element */ -export function markAsTreeitem(element) { +UI.ARIAUtils.markAsTreeitem = function(element) { element.setAttribute('role', 'treeitem'); -} +}; /** * @param {!Element} element */ -export function markAsTextBox(element) { +UI.ARIAUtils.markAsTextBox = function(element) { element.setAttribute('role', 'textbox'); -} +}; /** * @param {!Element} element */ -export function markAsMenu(element) { +UI.ARIAUtils.markAsMenu = function(element) { element.setAttribute('role', 'menu'); -} +}; /** * @param {!Element} element */ -export function markAsMenuItem(element) { +UI.ARIAUtils.markAsMenuItem = function(element) { element.setAttribute('role', 'menuitem'); -} +}; /** * @param {!Element} element */ -export function markAsMenuItemSubMenu(element) { - markAsMenuItem(element); +UI.ARIAUtils.markAsMenuItemSubMenu = function(element) { + UI.ARIAUtils.markAsMenuItem(element); element.setAttribute('aria-haspopup', true); -} +}; /** * Must contain children whose role is option. * @param {!Element} element */ -export function markAsListBox(element) { +UI.ARIAUtils.markAsListBox = function(element) { element.setAttribute('role', 'listbox'); -} +}; /** * @param {!Element} element */ -export function markAsMultiSelectable(element) { +UI.ARIAUtils.markAsMultiSelectable = function(element) { element.setAttribute('aria-multiselectable', 'true'); -} +}; /** * Must be contained in, or owned by, an element with the role listbox. * @param {!Element} element */ -export function markAsOption(element) { +UI.ARIAUtils.markAsOption = function(element) { element.setAttribute('role', 'option'); -} +}; /** * @param {!Element} element */ -export function markAsRadioGroup(element) { +UI.ARIAUtils.markAsRadioGroup = function(element) { element.setAttribute('role', 'radiogroup'); -} +}; /** * @param {!Element} element */ -export function markAsHidden(element) { +UI.ARIAUtils.markAsHidden = function(element) { element.setAttribute('aria-hidden', 'true'); -} +}; /** * @param {!Element} element * @param {number} level */ -export function markAsHeading(element, level) { +UI.ARIAUtils.markAsHeading = function(element, level) { element.setAttribute('role', 'heading'); element.setAttribute('aria-level', level); -} +}; /** * @param {!Element} element */ -export function markAsPoliteLiveRegion(element) { +UI.ARIAUtils.markAsPoliteLiveRegion = function(element) { element.setAttribute('aria-live', 'polite'); -} +}; /** * @param {!Element} element * @param {?string} placeholder */ -export function setPlaceholder(element, placeholder) { +UI.ARIAUtils.setPlaceholder = function(element, placeholder) { if (placeholder) element.setAttribute('aria-placeholder', placeholder); else element.removeAttribute('aria-placeholder'); -} +}; /** * @param {!Element} element */ -export function markAsPresentation(element) { +UI.ARIAUtils.markAsPresentation = function(element) { element.setAttribute('role', 'presentation'); -} +}; /** * @param {!Element} element */ -export function markAsStatus(element) { +UI.ARIAUtils.markAsStatus = function(element) { element.setAttribute('role', 'status'); -} +}; /** * @param {!Element} element */ -export function ensureId(element) { +UI.ARIAUtils.ensureId = function(element) { if (!element.id) - element.id = nextId('ariaElement'); -} + element.id = UI.ARIAUtils.nextId('ariaElement'); +}; + +/** + * @param {string} prefix + * @return {string} + */ +UI.ARIAUtils.nextId = function(prefix) { + return (prefix || '') + ++UI.ARIAUtils._id; +}; /** * @param {!Element} element * @param {?Element} controlledElement */ -export function setControls(element, controlledElement) { +UI.ARIAUtils.setControls = function(element, controlledElement) { if (!controlledElement) { element.removeAttribute('aria-controls'); return; } - ensureId(controlledElement); + UI.ARIAUtils.ensureId(controlledElement); element.setAttribute('aria-controls', controlledElement.id); -} +}; /** * @param {!Element} element * @param {boolean} value */ -export function setChecked(element, value) { +UI.ARIAUtils.setChecked = function(element, value) { element.setAttribute('aria-checked', !!value); -} +}; /** * @param {!Element} element */ -export function setCheckboxAsIndeterminate(element) { +UI.ARIAUtils.setCheckboxAsIndeterminate = function(element) { element.setAttribute('aria-checked', 'mixed'); -} +}; /** * @param {!Element} element * @param {boolean} value */ -export function setExpanded(element, value) { +UI.ARIAUtils.setExpanded = function(element, value) { element.setAttribute('aria-expanded', !!value); -} +}; /** * @param {!Element} element */ -export function unsetExpandable(element) { +UI.ARIAUtils.unsetExpandable = function(element) { element.removeAttribute('aria-expanded'); -} +}; /** * @param {!Element} element * @param {boolean} value */ -export function setSelected(element, value) { +UI.ARIAUtils.setSelected = function(element, value) { // aria-selected behaves differently for false and undefined. // Often times undefined values are unintentionally typed as booleans. // Use !! to make sure this is true or false. element.setAttribute('aria-selected', !!value); -} +}; /** * @param {!Element} element * @param {boolean} value */ -export function setInvalid(element, value) { +UI.ARIAUtils.setInvalid = function(element, value) { if (value) element.setAttribute('aria-invalid', value); else element.removeAttribute('aria-invalid'); -} +}; /** * @param {!Element} element * @param {boolean} value */ -export function setPressed(element, value) { +UI.ARIAUtils.setPressed = function(element, value) { // aria-pressed behaves differently for false and undefined. // Often times undefined values are unintentionally typed as booleans. // Use !! to make sure this is true or false. element.setAttribute('aria-pressed', !!value); -} +}; /** * @param {!Element} element * @param {number} value */ -export function setProgressBarCurrentPercentage(element, value) { +UI.ARIAUtils.setProgressBarCurrentPercentage = function(element, value) { element.setAttribute('aria-valuenow', value); -} +}; /** * @param {!Element} element * @param {string} name */ -export function setAccessibleName(element, name) { +UI.ARIAUtils.setAccessibleName = function(element, name) { element.setAttribute('aria-label', name); -} +}; /** @type {!WeakMap<!Element, !Element>} */ -const _descriptionMap = new WeakMap(); +UI.ARIAUtils._descriptionMap = new WeakMap(); /** * @param {!Element} element * @param {string} description */ -export function setDescription(element, description) { +UI.ARIAUtils.setDescription = function(element, description) { // Nodes in the accesesibility tree are made up of a core // triplet of "name", "value", "description" // The "description" field is taken from either @@ -347,12 +348,12 @@ // The rest of DevTools shouldn't have to worry about this, // so there is some unfortunate code below. - if (_descriptionMap.has(element)) - _descriptionMap.get(element).remove(); + if (UI.ARIAUtils._descriptionMap.has(element)) + UI.ARIAUtils._descriptionMap.get(element).remove(); element.removeAttribute('data-aria-utils-animation-hack'); if (!description) { - _descriptionMap.delete(element); + UI.ARIAUtils._descriptionMap.delete(element); element.removeAttribute('aria-describedby'); return; } @@ -362,9 +363,9 @@ const descriptionElement = createElement('span'); descriptionElement.textContent = description; descriptionElement.style.display = 'none'; - ensureId(descriptionElement); + UI.ARIAUtils.ensureId(descriptionElement); element.setAttribute('aria-describedby', descriptionElement.id); - _descriptionMap.set(element, descriptionElement); + UI.ARIAUtils._descriptionMap.set(element, descriptionElement); // Now we have to actually put this description element // somewhere in the DOM so that we can point to it. @@ -397,20 +398,20 @@ element.setAttribute('data-aria-utils-animation-hack', 'sorry'); element.addEventListener('animationend', () => { // Someone might have made a new description in the meantime. - if (_descriptionMap.get(element) !== descriptionElement) + if (UI.ARIAUtils._descriptionMap.get(element) !== descriptionElement) return; element.removeAttribute('data-aria-utils-animation-hack'); // Try it again. This time we are in the DOM, so it *should* work. element.insertAdjacentElement('afterend', descriptionElement); }, {once: true}); -} +}; /** * @param {!Element} element * @param {?Element} activedescendant */ -export function setActiveDescendant(element, activedescendant) { +UI.ARIAUtils.setActiveDescendant = function(element, activedescendant) { if (!activedescendant) { element.removeAttribute('aria-activedescendant'); return; @@ -418,19 +419,17 @@ console.assert(element.hasSameShadowRoot(activedescendant), 'elements are not in the same shadow dom'); - ensureId(activedescendant); + UI.ARIAUtils.ensureId(activedescendant); element.setAttribute('aria-activedescendant', activedescendant.id); -} - -const AlertElementSymbol = Symbol('AlertElementSybmol'); +}; /** * @param {string} message * @param {!Element} element */ -export function alert(message, element) { +UI.ARIAUtils.alert = function(message, element) { const document = element.ownerDocument; - if (!document[AlertElementSymbol]) { + if (!document[UI.ARIAUtils.AlertElementSymbol]) { const alertElement = document.body.createChild('div'); alertElement.style.position = 'absolute'; alertElement.style.left = '-999em'; @@ -438,54 +437,9 @@ alertElement.style.overflow = 'hidden'; alertElement.setAttribute('role', 'alert'); alertElement.setAttribute('aria-atomic', 'true'); - document[AlertElementSymbol] = alertElement; + document[UI.ARIAUtils.AlertElementSymbol] = alertElement; } - - document[AlertElementSymbol].textContent = message.trimEndWithMaxLength(10000); -} - -/** Legacy exported object @suppress {const} */ -self.UI = self.UI || {}; -self.UI.ARIAUtils = { - nextId, - bindLabelToControl, - markAsAlert, - markAsButton, - markAsCheckbox, - markAsDialog, - markAsGroup, - markAsLink, - markAsMenuButton, - markAsProgressBar, - markAsTab, - markAsTree, - markAsTreeitem, - markAsTextBox, - markAsMenu, - markAsMenuItem, - markAsMenuItemSubMenu, - markAsListBox, - markAsMultiSelectable, - markAsOption, - markAsRadioGroup, - markAsHidden, - markAsHeading, - markAsPoliteLiveRegion, - setPlaceholder, - markAsPresentation, - markAsStatus, - ensureId, - setControls, - setChecked, - setCheckboxAsIndeterminate, - setExpanded, - unsetExpandable, - setSelected, - setInvalid, - setPressed, - setProgressBarCurrentPercentage, - setAccessibleName, - setDescription, - setActiveDescendant, - alert, + document[UI.ARIAUtils.AlertElementSymbol].textContent = message.trimEndWithMaxLength(10000); }; + +UI.ARIAUtils.AlertElementSymbol = Symbol('AlertElementSybmol');
diff --git a/third_party/blink/renderer/devtools/front_end/ui/UI.js b/third_party/blink/renderer/devtools/front_end/ui/UI.js deleted file mode 100644 index 262177a9..0000000 --- a/third_party/blink/renderer/devtools/front_end/ui/UI.js +++ /dev/null
@@ -1,5 +0,0 @@ -import * as ARIAUtils from './ARIAUtils.js'; - -export { - ARIAUtils, -}; \ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/ui/module.json b/third_party/blink/renderer/devtools/front_end/ui/module.json index 2dcde6f..bd5f5a1e 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/module.json +++ b/third_party/blink/renderer/devtools/front_end/ui/module.json
@@ -54,16 +54,13 @@ "SuggestBox.js", "TabbedPane.js", "UIUtils.js", + "ARIAUtils.js", "ZoomManager.js", "ShortcutsScreen.js", "Geometry.js", "XLink.js", "XWidget.js" ], - "modules": [ - "ARIAUtils.js", - "UI.js" - ], "resources": [ "checkboxTextLabel.css", "closeButton.css",
diff --git a/third_party/blink/renderer/devtools/front_end/worker_app.html b/third_party/blink/renderer/devtools/front_end/worker_app.html index c041d37..e5827b5e 100644 --- a/third_party/blink/renderer/devtools/front_end/worker_app.html +++ b/third_party/blink/renderer/devtools/front_end/worker_app.html
@@ -9,9 +9,8 @@ <meta charset="utf-8"> <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com"> <meta name="referrer" content="no-referrer"> - <script type="module" src="root.js"></script> - <script defer src="Runtime.js"></script> - <script defer src="worker_app.js"></script> + <script src="Runtime.js"></script> + <script src="worker_app.js"></script> </head> <body class="undocked" id="-blink-dev-tools"></body> </html>
diff --git a/third_party/blink/renderer/devtools/package.json b/third_party/blink/renderer/devtools/package.json index 42d8d90..feea3f1a 100644 --- a/third_party/blink/renderer/devtools/package.json +++ b/third_party/blink/renderer/devtools/package.json
@@ -35,10 +35,6 @@ "bugs": { "url": "https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component:Platform%3EDevTools%20&sort=-opened&colspec=ID%20Stars%20Owner%20Summary%20Modified%20Opened" }, - "type": "module", - "files": [ - "front_end/**/*.mjs" - ], "homepage": "https://devtools.chrome.com", "devDependencies": { "ajv": "^5.1.5"
diff --git a/third_party/blink/renderer/devtools/scripts/build/build_release_applications.py b/third_party/blink/renderer/devtools/scripts/build/build_release_applications.py index db32b006..74e1c10 100755 --- a/third_party/blink/renderer/devtools/scripts/build/build_release_applications.py +++ b/third_party/blink/renderer/devtools/scripts/build/build_release_applications.py
@@ -133,13 +133,13 @@ output = StringIO() with open(join(self.application_dir, html_name), 'r') as app_input_html: for line in app_input_html: - if ('<script ' in line and 'type="module"' not in line) or '<link ' in line: + if '<script ' in line or '<link ' in line: continue if '</head>' in line: self._write_include_tags(self.descriptors, output) js_file = join(self.application_dir, self.app_file('js')) if path.exists(js_file): - output.write(' <script type="module">%s</script>\n' % minify_js(read_file(js_file))) + output.write(' <script>%s</script>\n' % minify_js(read_file(js_file))) output.write(line) write_file(join(self.output_dir, html_name), output.getvalue()) @@ -154,7 +154,7 @@ def _generate_include_tag(self, resource_path): if resource_path.endswith('.js'): - return ' <script defer src="%s"></script>\n' % resource_path + return ' <script type="text/javascript" src="%s"></script>\n' % resource_path else: assert resource_path
diff --git a/third_party/blink/renderer/devtools/scripts/build/copy_devtools_modules.py b/third_party/blink/renderer/devtools/scripts/build/copy_devtools_modules.py deleted file mode 100755 index 10d9ee235..0000000 --- a/third_party/blink/renderer/devtools/scripts/build/copy_devtools_modules.py +++ /dev/null
@@ -1,32 +0,0 @@ -#!/usr/bin/env python -# -*- coding: UTF-8 -*- -# -# 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. -""" -Copies the modules into the resources folder -""" - -from os.path import join, relpath -import shutil -import sys - - -def main(argv): - try: - input_path_flag_index = argv.index('--input_path') - input_path = argv[input_path_flag_index + 1] - output_path_flag_index = argv.index('--output_path') - output_path = argv[output_path_flag_index + 1] - devtools_modules = argv[1:input_path_flag_index] - except: - print 'Usage: %s module_1 module_2 ... module_N --input_path <input_path> --output_path <output_path>' % argv[0] - raise - - for file_name in devtools_modules: - shutil.copy(join(input_path, file_name), join(output_path, relpath(file_name, 'front_end'))) - - -if __name__ == '__main__': - sys.exit(main(sys.argv))
diff --git a/third_party/blink/renderer/devtools/scripts/build/modular_build.py b/third_party/blink/renderer/devtools/scripts/build/modular_build.py index c818ad95..90d6697 100755 --- a/third_party/blink/renderer/devtools/scripts/build/modular_build.py +++ b/third_party/blink/renderer/devtools/scripts/build/modular_build.py
@@ -76,7 +76,7 @@ for name in self.sorted_modules(): module = self.modules[name] skipped_files = set(module.get('skip_compilation', [])) - for script in module.get('scripts', []) + module.get('modules', []): + for script in module.get('scripts', []): if script not in skipped_files: files[path.normpath(path.join(self.application_dir, name, script))] = True return files.keys()
diff --git a/third_party/blink/renderer/devtools/scripts/check_localizability.js b/third_party/blink/renderer/devtools/scripts/check_localizability.js index 91e7158..000a294 100644 --- a/third_party/blink/renderer/devtools/scripts/check_localizability.js +++ b/third_party/blink/renderer/devtools/scripts/check_localizability.js
@@ -284,7 +284,7 @@ if (path.extname(filePath) === '.grdp') return auditGrdpFile(filePath, fileContent, errors); - const ast = esprima.parseModule(fileContent, {loc: true}); + const ast = esprima.parse(fileContent, {loc: true}); const relativeFilePath = localizationUtils.getRelativeFilePathFromSrc(filePath); for (const node of ast.body)
diff --git a/third_party/blink/renderer/devtools/scripts/check_localizable_resources.js b/third_party/blink/renderer/devtools/scripts/check_localizable_resources.js index acf7e72..50a2859 100644 --- a/third_party/blink/renderer/devtools/scripts/check_localizable_resources.js +++ b/third_party/blink/renderer/devtools/scripts/check_localizable_resources.js
@@ -32,7 +32,6 @@ else await getErrors(); } catch (e) { - console.log(e.stack); console.log(`Error: ${e.message}`); process.exit(1); }
diff --git a/third_party/blink/renderer/devtools/scripts/compile_frontend.py b/third_party/blink/renderer/devtools/scripts/compile_frontend.py index 78a553da..53ad724f 100755 --- a/third_party/blink/renderer/devtools/scripts/compile_frontend.py +++ b/third_party/blink/renderer/devtools/scripts/compile_frontend.py
@@ -77,7 +77,6 @@ GLOBAL_EXTERNS_FILE = to_platform_path(path.join(DEVTOOLS_FRONTEND_PATH, 'externs.js')) DEFAULT_PROTOCOL_EXTERNS_FILE = path.join(DEVTOOLS_FRONTEND_PATH, 'protocol_externs.js') RUNTIME_FILE = to_platform_path(path.join(DEVTOOLS_FRONTEND_PATH, 'Runtime.js')) -ROOT_MODULE_FILE = to_platform_path(path.join(DEVTOOLS_FRONTEND_PATH, 'root.js')) CLOSURE_COMPILER_JAR = to_platform_path(path.join(SCRIPTS_PATH, 'closure', 'compiler.jar')) CLOSURE_RUNNER_JAR = to_platform_path(path.join(SCRIPTS_PATH, 'closure', 'closure_runner', 'closure_runner.jar')) @@ -280,8 +279,6 @@ namespace_externs_path, '--js', RUNTIME_FILE, - '--js', - ROOT_MODULE_FILE, ] all_files = descriptors.all_compiled_files()
diff --git a/third_party/blink/renderer/devtools/scripts/localization_utils/check_localized_strings.js b/third_party/blink/renderer/devtools/scripts/localization_utils/check_localized_strings.js index 4281b65c..d2ac8e67 100644 --- a/third_party/blink/renderer/devtools/scripts/localization_utils/check_localized_strings.js +++ b/third_party/blink/renderer/devtools/scripts/localization_utils/check_localized_strings.js
@@ -93,7 +93,7 @@ if (path.basename(filePath) === 'module.json') return parseLocalizableStringFromModuleJson(fileContent, filePath); - const ast = esprima.parseModule(fileContent, {loc: true}); + const ast = esprima.parse(fileContent, {loc: true}); for (const node of ast.body) parseLocalizableStringFromNode(node, filePath); }
diff --git a/third_party/blink/renderer/devtools/tsconfig.json b/third_party/blink/renderer/devtools/tsconfig.json new file mode 100644 index 0000000..1dbc1cc --- /dev/null +++ b/third_party/blink/renderer/devtools/tsconfig.json
@@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "typeRoots": ["../../../devtools-node-modules/third_party/node_modules/@types"] + } +}
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc index 359306f..a562d98 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -297,7 +297,7 @@ return nullptr; } - if (layout_object_->IsAnonymousBlock() && layout_object_->ContainingBlock()) { + if (layout_object_->IsAnonymous() && layout_object_->ContainingBlock()) { return layout_object_->ContainingBlock()->GetNode(); }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.h b/third_party/blink/renderer/modules/accessibility/ax_layout_object.h index 96868bd..8c5c0a9 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
@@ -56,7 +56,7 @@ ax::mojom::Role DetermineAccessibilityRole() override; ax::mojom::Role NativeRoleIgnoringAria() const override; - // If this is an anonymous block, returns the node of its containing layout + // If this is an anonymous node, returns the node of its containing layout // block, otherwise returns the node of this layout object. Node* GetNodeOrContainingBlockNode() const;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_position_test.cc b/third_party/blink/renderer/modules/accessibility/ax_position_test.cc index f0742e5d..c571e5eb 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_position_test.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
@@ -1236,6 +1236,36 @@ EXPECT_EQ(12, position_after.GetPosition().OffsetInContainerNode()); } +TEST_F(AccessibilityTest, PositionInCSSImageContent) { + constexpr char css_content_no_text[] = R"HTML( + <style> + .heading::before { + content: url(data:image/gif;base64,); + } + </style> + <h1 id="heading" class="heading">Heading</h1>)HTML"; + SetBodyInnerHTML(css_content_no_text); + + const Node* heading = GetElementById("heading"); + ASSERT_NE(nullptr, heading); + + const AXObject* ax_heading = GetAXObjectByElementId("heading"); + ASSERT_NE(nullptr, ax_heading); + ASSERT_EQ(ax::mojom::Role::kHeading, ax_heading->RoleValue()); + ASSERT_EQ(2, ax_heading->ChildCount()); + + const AXObject* ax_css_before = ax_heading->FirstChild(); + ASSERT_NE(nullptr, ax_css_before); + ASSERT_EQ(ax::mojom::Role::kImage, ax_css_before->RoleValue()); + + const auto ax_position_before = + AXPosition::CreateFirstPositionInObject(*ax_css_before); + const auto position = ax_position_before.ToPositionWithAffinity( + AXPositionAdjustmentBehavior::kMoveLeft); + EXPECT_EQ(GetDocument().body(), position.AnchorNode()); + EXPECT_EQ(3, position.GetPosition().OffsetInContainerNode()); +} + TEST_F(AccessibilityTest, PositionInTableWithCSSContent) { SetBodyInnerHTML(kHTMLTable);
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.cc b/third_party/blink/renderer/platform/graphics/graphics_layer.cc index ffc1af79..34d27b1 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_layer.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_layer.cc
@@ -474,7 +474,6 @@ // SetDrawsContent() and SetContentsVisible(). contents_layer_->SetIsDrawable(contents_visible_); contents_layer_->SetHitTestable(contents_visible_); - contents_layer_->SetMaskLayer(nullptr); contents_layer_->Set3dSortingContextId(rendering_context3d_); }
diff --git a/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py b/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py index fb2dc36..ff9d78c1 100644 --- a/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py +++ b/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py
@@ -260,7 +260,8 @@ def _collect_tests(self, args): return self._finder.find_tests(args, test_list=self._options.test_list, - fastest_percentile=self._options.fastest) + fastest_percentile=self._options.fastest, + filters=self._options.isolated_script_test_filter) def _is_http_test(self, test): return (
diff --git a/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_finder.py b/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_finder.py index 3a2cdbc..f27532f 100644 --- a/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_finder.py +++ b/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_finder.py
@@ -27,6 +27,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import errno +import fnmatch import json import logging import math @@ -47,7 +48,8 @@ self._filesystem = self._port.host.filesystem self.WEB_TESTS_DIRECTORIES = ('src', 'third_party', 'blink', 'web_tests') - def find_tests(self, args, test_list=None, fastest_percentile=None): + def find_tests(self, args, test_list=None, fastest_percentile=None, filters=None): + filters = filters or [] paths = self._strip_test_dir_prefixes(args) if test_list: paths += self._strip_test_dir_prefixes(self._read_test_names_from_file(test_list, self._port.TEST_PATH_SEPARATOR)) @@ -77,6 +79,7 @@ test_files = all_tests running_all_tests = True + test_files = filter_tests(test_files, [f.split('::') for f in filters]) return (paths, test_files, running_all_tests) def _times_trie(self): @@ -213,3 +216,57 @@ index, count, len(tests_to_run), len(test_names)) return tests_to_run, other_tests + + +def filter_tests(tests, filters): + """Returns a filtered list of tests to run. + + The test-filtering semantics are documented in + https://bit.ly/chromium-test-runner-api and + https://bit.ly/chromium-test-list-format, but are as follows: + + Each filter is a list of glob expressions, with each expression optionally + prefixed by a "-". If the glob starts with a "-", it is a negative glob, + otherwise it is a positive glob. + + A test passes the filter if and only if it is explicitly matched by at + least one positive glob and no negative globs, or if there are no + positive globs and it is not matched by any negative globs. + + Globbing is fairly limited; "?" is not allowed, and "*" must only appear + at the end of the glob. If multiple globs match a test, the longest match + wins. If both globs are the same length, an error is raised. + + A test will be run only if it passes every filter. + """ + + def glob_sort_key(k): + if k and k[0] == '-': + return (len(k[1:]), k[1:]) + else: + return (len(k), k) + + for globs in filters: + include_by_default = all(glob.startswith('-') for glob in globs) + filtered_tests = [] + for test in tests: + include = include_by_default + for glob in sorted(globs, key=glob_sort_key): + if not glob[:-1]: + raise ValueError('Empty glob filter "%s"' % (filter,)) + if '*' in glob[:-1]: + raise ValueError('Bad test filter "%s" specified; ' + 'wildcards are only allowed at the end' + % (glob,)) + if glob.startswith('-') and glob[1:] in globs: + raise ValueError('Both "%s" and "%s" specified in test ' + 'filter' % (glob, glob[1:])) + if glob.startswith('-'): + include = include and not fnmatch.fnmatch(test, glob[1:]) + else: + include = include or fnmatch.fnmatch(test, glob) + if include: + filtered_tests.append(test) + tests = filtered_tests + + return tests
diff --git a/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_finder_unittest.py b/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_finder_unittest.py index cb4de53..af79323 100644 --- a/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_finder_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_finder_unittest.py
@@ -128,3 +128,79 @@ self.assertEqual(([3, 6], [1, 2, 4, 5]), split(tests, 0, 3)) self.assertEqual(([1, 4], [2, 3, 5, 6]), split(tests, 1, 3)) self.assertEqual(([2, 5], [1, 3, 4, 6]), split(tests, 2, 3)) + + +class FilterTestsTests(unittest.TestCase): + simple_test_list = ['a/a1.html', 'a/a2.html', 'b/b1.html'] + + def check(self, tests, filters, expected_tests): + self.assertEqual(expected_tests, + web_test_finder.filter_tests(tests, filters)) + + def test_no_filters(self): + self.check(self.simple_test_list, [], + self.simple_test_list) + + def test_empty_glob_is_rejected(self): + self.assertRaises(ValueError, self.check, + self.simple_test_list, [['']], []) + self.assertRaises(ValueError, self.check, + self.simple_test_list, [['-']], []) + + def test_one_all_positive_filter(self): + self.check(self.simple_test_list, [['a*']], + ['a/a1.html', 'a/a2.html']) + + self.check(self.simple_test_list, [['a*', 'b*']], + self.simple_test_list) + + def test_one_all_negative_filter(self): + self.check(self.simple_test_list, [['-c*']], + self.simple_test_list) + + def test_one_mixed_filter(self): + self.check(self.simple_test_list, [['a*', '-c*']], + ['a/a1.html', 'a/a2.html']) + + def test_two_all_positive_filters(self): + self.check(self.simple_test_list, [['a*'], ['b*']], + []) + + def test_two_all_negative_filters(self): + self.check(self.simple_test_list, [['-a*'], ['-b*']], + []) + + self.check(self.simple_test_list, [['-a*'], ['-c*']], + ['b/b1.html']) + + def test_two_mixed_filters(self): + self.check(self.simple_test_list, [['a*'], ['-b*']], + ['a/a1.html', 'a/a2.html']) + + def test_longest_glob_wins(self): + # These test that if two matching globs are specified as + # part of the same filter expression, the longest matching + # glob wins (takes precedence). The order of the two globs + # must not matter. + self.check(self.simple_test_list, [['a/a*', '-a/a2*']], + ['a/a1.html']) + self.check(self.simple_test_list, [['-a/a*', 'a/a2*']], + ['a/a2.html']) + + # In this test, the positive and negative globs are in + # separate filter expressions, so a2 should be filtered out + # and nothing should run (tests should only be run if they + # would be run by every filter individually). + self.check(self.simple_test_list, [['-a/a*'], ['a/a2*']], + []) + + def test_only_trailing_globs_work(self): + self.check(self.simple_test_list, [['a*']], + ['a/a1.html', 'a/a2.html']) + + # These test that if you have a glob that contains a "*" that isn't + # at the end, it is rejected; only globs at the end should work. + self.assertRaises(ValueError, self.check, + self.simple_test_list, [['*1.html']], []) + self.assertRaises(ValueError, self.check, + self.simple_test_list, [['a*.html']], [])
diff --git a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py index b221564..beef9c82 100644 --- a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py +++ b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
@@ -438,9 +438,10 @@ help='read list of tests to run from file'), optparse.make_option( '--isolated-script-test-filter', + action='append', type='string', - help='A list of tests to run separated by TWO colons, e.g. fast::css/test.html, ' - 'same as listing them as positional arguments'), + help='A list of test globs to run or skip, separated by TWO colons, e.g. fast::css/test.html; ' + 'prefix the glob with "-" to skip it'), # TODO(crbug.com/893235): Remove gtest_filter when FindIt no longer uses it. optparse.make_option( '--gtest_filter', @@ -594,9 +595,6 @@ if not options.skipped: options.skipped = 'default' - if options.isolated_script_test_filter: - args.extend(options.isolated_script_test_filter.split('::')) - if options.gtest_filter: args.extend(options.gtest_filter.split(':'))
diff --git a/third_party/blink/tools/blinkpy/web_tests/run_web_tests_unittest.py b/third_party/blink/tools/blinkpy/web_tests/run_web_tests_unittest.py index 5e779d1..2244f962 100644 --- a/third_party/blink/tools/blinkpy/web_tests/run_web_tests_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/run_web_tests_unittest.py
@@ -519,7 +519,26 @@ ['--isolated-script-test-filter=passes/text.html::passes/image.html', 'passes/error.html'], host=host ) - self.assertEqual(sorted(tests_run), ['passes/error.html', 'passes/image.html', 'passes/text.html']) + self.assertEqual(sorted(tests_run), []) + + tests_run = get_tests_run( + ['--isolated-script-test-filter=passes/error.html::passes/image.html', 'passes/error.html'], + host=host + ) + self.assertEqual(sorted(tests_run), ['passes/error.html']) + + tests_run = get_tests_run( + ['--isolated-script-test-filter=passes/error.html::passes/image.html'], + host=host + ) + self.assertEqual(sorted(tests_run), ['passes/error.html', 'passes/image.html']) + + tests_run = get_tests_run( + ['--isolated-script-test-filter=passes/error.html::passes/image.html', + '--isolated-script-test-filter=passes/error.html'], + host=host + ) + self.assertEqual(sorted(tests_run), ['passes/error.html']) def test_gtest_filter(self): host = MockHost()
diff --git a/third_party/blink/web_tests/FlagExpectations/use-vulkan=native b/third_party/blink/web_tests/FlagExpectations/use-vulkan=native index ab7813b..4d61824 100644 --- a/third_party/blink/web_tests/FlagExpectations/use-vulkan=native +++ b/third_party/blink/web_tests/FlagExpectations/use-vulkan=native
@@ -1,52 +1,3 @@ -# Native Failures -# Backing Failure -crbug.com/978628 media/remoteplayback/prompt-twice-throws.html [ Skip ] -crbug.com/978628 media/video-controls-fullscreen.html [ Skip ] -crbug.com/978628 media/audio-delete-while-slider-thumb-clicked.html [ Skip ] -crbug.com/978628 media/video-controls-overflow-menu-fullscreen-button.html [ Skip ] -crbug.com/978628 media/video-persistence.html [ Skip ] -crbug.com/978628 media/video-src-blob.html [ Skip ] - -# Input timing doesn't match screenshots -crbug.com/935970 compositing/gestures/gesture-tapHighlight-img-and-text.html [ Skip ] -crbug.com/935970 compositing/gestures/gesture-tapHighlight-multicol.html [ Skip ] -crbug.com/935970 compositing/gestures/gesture-tapHighlight-nested-cursor.html [ Skip ] -crbug.com/935970 compositing/gestures/gesture-tapHighlight-nested-cursor3.html [ Skip ] -crbug.com/935970 compositing/gestures/gesture-tapHighlight-simple-scaled-document.html [ Skip ] -crbug.com/935970 compositing/gestures/gesture-tapHighlight-with-squashing.html [ Skip ] -crbug.com/935970 compositing/iframes/layout-on-compositing-change.html [ Skip ] -crbug.com/935970 compositing/squashing/squash-compositing-hover.html [ Skip ] -crbug.com/935970 compositing/squashing/squash-transform-repainting-child.html [ Skip ] -crbug.com/935970 compositing/squashing/squash-transform-repainting-transformed-child.html [ Skip ] -crbug.com/935970 css3/viewport-percentage-lengths/vh-resize.html [ Skip ] -crbug.com/935970 images/drag-image-2.html [ Skip ] -crbug.com/935970 images/drag-image-descendant-iframe-composited.html [ Skip ] -crbug.com/935970 images/drag-image-descendant-painting-sibling.html [ Skip ] -crbug.com/935970 images/drag-image-transformed-child.html [ Skip ] -crbug.com/935970 images/drag-image-transformed-parent.html [ Skip ] -crbug.com/935970 images/drag-image.html [ Skip ] -crbug.com/935970 images/huge-image-viewport-scale.html [ Skip ] -crbug.com/935970 images/image-map-multiple-xhtml.xhtml [ Skip ] -crbug.com/935970 images/image-map-multiple.html [ Skip ] -crbug.com/935970 images/server-side-imagemap.html [ Skip ] -crbug.com/935970 media/controls-drag-timebar.html [ Skip ] -crbug.com/935970 media/controls-timeline.html [ Skip ] -crbug.com/935970 media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Skip ] -crbug.com/935970 media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Skip ] -crbug.com/935970 media/media-controls-tap-show-controls-without-activating.html [ Skip ] -crbug.com/935970 media/video-controls-always-visible-when-control-hovered.html [ Skip ] -crbug.com/935970 media/video-controls-auto-hide-after-play-by-touch.html [ Skip ] -crbug.com/935970 media/video-controls-hide-after-touch-on-control.html [ Skip ] -crbug.com/935970 media/video-controls-hide-on-move-outside-controls.html [ Skip ] -crbug.com/935970 media/video-controls-mouse-events-captured.html [ Skip ] -crbug.com/935970 media/video-controls-overflow-menu-closed-captions-button.html [ Skip ] -crbug.com/935970 media/video-controls-overflow-menu-mute-button.html [ Skip ] -crbug.com/935970 media/video-controls-overflow-menu-play-button.html [ Skip ] -crbug.com/935970 media/video-controls-transformed.html [ Skip ] -crbug.com/935970 media/video-controls-visibility-multimodal-mouse-after-touch.html [ Skip ] -crbug.com/935970 media/video-controls-visibility-multimodal-touch-after-mouse.html [ Skip ] -crbug.com/935970 media/video-controls-visible-audio-only.html [ Skip ] - # Need a Vulkan native specific baseline. crbug.com/993384 compositing/geometry/vertical-scroll-composited.html [ Skip ] crbug.com/993384 compositing/lots-of-img-layers.html [ Skip ]
diff --git a/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader b/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader index cd3775b..294938b 100644 --- a/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader +++ b/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader
@@ -1,16 +1,3 @@ -# SwiftShader Unimplemented Blend Mode -crbug.com/972096 compositing/reflections/animation-inside-reflection.html [ Skip ] -crbug.com/972096 compositing/reflections/nested-reflection-anchor-point.html [ Skip ] -crbug.com/972096 compositing/reflections/nested-reflection-animated.html [ Skip ] -crbug.com/972096 compositing/reflections/nested-reflection-on-overflow.html [ Skip ] -crbug.com/972096 compositing/reflections/nested-reflection-opacity.html [ Skip ] -crbug.com/972096 compositing/reflections/nested-reflection-transformed.html [ Skip ] -crbug.com/972096 compositing/reflections/nested-reflection-transformed2.html [ Skip ] -crbug.com/972096 compositing/reflections/nested-reflection.html [ Skip ] -crbug.com/972096 compositing/reflections/transform-inside-reflection.html [ Skip ] -crbug.com/972096 css3/filters/composited-reflected.html [ Skip ] -crbug.com/972096 media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Skip ] - # Test consistently hitting default timeout. Bug(none) css3/filters/effect-reference-subregion.html [ Skip ]
diff --git a/third_party/blink/web_tests/animations/interpolation/perspective-interpolation.html b/third_party/blink/web_tests/animations/interpolation/perspective-interpolation.html deleted file mode 100644 index 53ec74ed..0000000 --- a/third_party/blink/web_tests/animations/interpolation/perspective-interpolation.html +++ /dev/null
@@ -1,97 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<style> -.parent { - perspective: 30px; -} -.target { - display: inline-block; - margin-top: 50px; - margin-bottom: 25px; - perspective: 10px; -} -.transformed { - width: 50px; - height: 50px; - background: black; - transform: rotateY(45deg); -} -.expected .transformed { - background: green; -} -.expected { - position: relative; - left: -50px; - opacity: 0.75; -} -</style> -<body> -<template id="target-template"> -<div><div class="transformed"></div></div> -</template> -<script src="resources/interpolation-test.js"></script> -<script> -assertInterpolation({ - property: 'perspective', - from: neutralKeyframe, - to: '20px', -}, [ - {at: -20, is: 'none'}, - {at: -1, is: 'none'}, - {at: -0.3, is: '7px'}, - {at: 0, is: '10px'}, - {at: 0.3, is: '13px'}, - {at: 0.6, is: '16px'}, - {at: 1, is: '20px'}, - {at: 1.5, is: '25px'}, -]); - -assertNoInterpolation({ - property: 'perspective', - from: 'initial', - to: '20px', -}); - -assertInterpolation({ - property: 'perspective', - from: 'inherit', - to: '20px', -}, [ - {at: -20, is: '230px'}, - {at: -1, is: '40px'}, - {at: -0.3, is: '33px'}, - {at: 0, is: '30px'}, - {at: 0.3, is: '27px'}, - {at: 0.6, is: '24px'}, - {at: 1, is: '20px'}, - {at: 1.5, is: '15px'}, -]); - -assertNoInterpolation({ - property: 'perspective', - from: 'unset', - to: '20px', -}); - -assertInterpolation({ - property: 'perspective', - from: '50px', - to: '100px', -}, [ - {at: -20, is: 'none'}, // perspective does not accept 0 or negative values - {at: -1, is: 'none'}, // perspective does not accept 0 or negative values - {at: -0.3, is: '35px'}, - {at: 0, is: '50px'}, - {at: 0.3, is: '65px'}, - {at: 0.6, is: '80px'}, - {at: 1, is: '100px'}, - {at: 1.5, is: '125px'}, -]); - -assertNoInterpolation({ - property: 'perspective', - from: '50px', - to: 'none', -}); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/interpolation/perspective-origin-interpolation.html b/third_party/blink/web_tests/animations/interpolation/perspective-origin-interpolation.html index 7ff11af1..d5021aed 100644 --- a/third_party/blink/web_tests/animations/interpolation/perspective-origin-interpolation.html +++ b/third_party/blink/web_tests/animations/interpolation/perspective-origin-interpolation.html
@@ -33,71 +33,6 @@ </template> <script src="resources/interpolation-test.js"></script> <script> -assertInterpolation({ - property: 'perspective-origin', - from: neutralKeyframe, - to: '20px 20px', -}, [ - {at: -0.3, is: '7px 33px'}, - {at: 0, is: '10px 30px'}, - {at: 0.3, is: '13px 27px'}, - {at: 0.6, is: '16px 24px'}, - {at: 1, is: '20px 20px'}, - {at: 1.5, is: '25px 15px'}, -]); - -assertInterpolation({ - property: 'perspective-origin', - from: 'initial', - to: '20px 20px', -}, [ - {at: -0.3, is: '26.5px 26.5px'}, - {at: 0, is: '25px 25px'}, - {at: 0.3, is: '23.5px 23.5px'}, - {at: 0.6, is: '22px 22px'}, - {at: 1, is: '20px 20px'}, - {at: 1.5, is: '17.5px 17.5px'}, -]); - -assertInterpolation({ - property: 'perspective-origin', - from: 'inherit', - to: '20px 20px', -}, [ - {at: -0.3, is: '33px 7px'}, - {at: 0, is: '30px 10px'}, - {at: 0.3, is: '27px 13px'}, - {at: 0.6, is: '24px 16px'}, - {at: 1, is: '20px 20px'}, - {at: 1.5, is: '15px 25px'}, -]); - -assertInterpolation({ - property: 'perspective-origin', - from: 'unset', - to: '20px 20px', -}, [ - {at: -0.3, is: '26.5px 26.5px'}, - {at: 0, is: '25px 25px'}, - {at: 0.3, is: '23.5px 23.5px'}, - {at: 0.6, is: '22px 22px'}, - {at: 1, is: '20px 20px'}, - {at: 1.5, is: '17.5px 17.5px'}, -]); - -assertInterpolation({ - property: 'perspective-origin', - from: '0% 50%', - to: '100% 150%' -}, [ - {at: -0.3, is: '-30% 20%'}, - {at: 0, is: '0% 50%'}, - {at: 0.3, is: '30% 80%'}, - {at: 0.6, is: '60% 110%'}, - {at: 1, is: '100% 150%'}, - {at: 1.5, is: '150% 200%'} -]); - // Regression test for https://crbug.com/984700 assertInterpolation({ property: 'perspective-origin',
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/relpos-percentage-left-in-scrollable-2.html b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/relpos-percentage-left-in-scrollable-2.html new file mode 100644 index 0000000..0c7584d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/relpos-percentage-left-in-scrollable-2.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/CSS22/visuren.html#propdef-left"> +<link rel="help" href="https://www.w3.org/TR/CSS22/visuren.html#relative-positioning"> +<link rel="help" href="https://www.w3.org/TR/CSS22/visuren.html#anonymous-block-level"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1002485"> +<p>There should be no red, and no scrollbar.</p> +<div id="container" style="overflow:auto; width:500px; background:red;"> + <div style="padding-right:90%; background:yellow;"> + <div style="position:relative; left:900%; background:cyan;"> + <div></div> + + </div> + </div> +</div> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + container.scrollLeft = 123456; + test(()=> { + assert_equals(container.scrollLeft, 0); + }, "Left percentage resolved correctly for overflow contribution"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-interpolation.html new file mode 100644 index 0000000..a27f84a1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-interpolation.html
@@ -0,0 +1,101 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title> perspective interpolation</title> +<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#propdef-perspective"> +<meta name="assert" content="perspective supports animation"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<style> +.parent { + perspective: 30px; +} +.target { + perspective: 10px; +} +.transformed { + width: 50px; + height: 50px; + background: black; + transform: rotateY(45deg); +} +.expected .transformed { + background: green; +} +.expected { + position: relative; + left: -50px; + opacity: 0.75; +} +</style> +<body> +<template id="target-template"> +<div><div class="transformed"></div></div> +</template> +<script> +test_interpolation({ + property: 'perspective', + from: neutralKeyframe, + to: '20px', +}, [ + {at: -20, expect: 'none'}, + {at: -1, expect: 'none'}, + {at: -0.3, expect: '7px'}, + {at: 0, expect: '10px'}, + {at: 0.3, expect: '13px'}, + {at: 0.6, expect: '16px'}, + {at: 1, expect: '20px'}, + {at: 1.5, expect: '25px'}, +]); + +test_no_interpolation({ + property: 'perspective', + from: 'initial', + to: '20px', +}); + +test_interpolation({ + property: 'perspective', + from: 'inherit', + to: '20px', +}, [ + {at: -20, expect: '230px'}, + {at: -1, expect: '40px'}, + {at: -0.3, expect: '33px'}, + {at: 0, expect: '30px'}, + {at: 0.3, expect: '27px'}, + {at: 0.6, expect: '24px'}, + {at: 1, expect: '20px'}, + {at: 1.5, expect: '15px'}, +]); + +test_no_interpolation({ + property: 'perspective', + from: 'unset', + to: '20px', +}); + +test_interpolation({ + property: 'perspective', + from: '50px', + to: '100px', +}, [ + {at: -20, expect: 'none'}, // perspective does not accept 0 or negative values + {at: -1, expect: 'none'}, // perspective does not accept 0 or negative values + {at: -0.3, expect: '35px'}, + {at: 0, expect: '50px'}, + {at: 0.3, expect: '65px'}, + {at: 0.6, expect: '80px'}, + {at: 1, expect: '100px'}, + {at: 1.5, expect: '125px'}, +]); + +test_no_interpolation({ + property: 'perspective', + from: '50px', + to: 'none', +}); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-origin-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-origin-interpolation.html new file mode 100644 index 0000000..0a1e74cb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-origin-interpolation.html
@@ -0,0 +1,107 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>perspective-origin interpolation</title> +<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#perspective-origin-property"> +<meta name="assert" content="perspective-origin supports animation"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<style> +.parent { + perspective-origin: 30px 10px; +} +.target { + display: inline-block; + perspective: 50; + margin-top: 50px; + margin-bottom: 25px; + perspective-origin: 10px 30px; +} +.transformed { + width: 50px; + height: 50px; + background: black; + transform: rotateY(45deg); +} +.expected .transformed { + background: green; +} +.expected { + position: relative; + left: -50px; + opacity: 0.75; +} +</style> +<body> +<template id="target-template"> +<div><div class="transformed"></div></div> +</template> +<script> +test_interpolation({ + property: 'perspective-origin', + from: neutralKeyframe, + to: '20px 20px', +}, [ + {at: -0.3, expect: '7px 33px'}, + {at: 0, expect: '10px 30px'}, + {at: 0.3, expect: '13px 27px'}, + {at: 0.6, expect: '16px 24px'}, + {at: 1, expect: '20px 20px'}, + {at: 1.5, expect: '25px 15px'}, +]); + +test_interpolation({ + property: 'perspective-origin', + from: 'initial', + to: '20px 20px', +}, [ + {at: -0.3, expect: '26.5px 26.5px'}, + {at: 0, expect: '25px 25px'}, + {at: 0.3, expect: '23.5px 23.5px'}, + {at: 0.6, expect: '22px 22px'}, + {at: 1, expect: '20px 20px'}, + {at: 1.5, expect: '17.5px 17.5px'}, +]); + +test_interpolation({ + property: 'perspective-origin', + from: 'inherit', + to: '20px 20px', +}, [ + {at: -0.3, expect: '33px 7px'}, + {at: 0, expect: '30px 10px'}, + {at: 0.3, expect: '27px 13px'}, + {at: 0.6, expect: '24px 16px'}, + {at: 1, expect: '20px 20px'}, + {at: 1.5, expect: '15px 25px'}, +]); + +test_interpolation({ + property: 'perspective-origin', + from: 'unset', + to: '20px 20px', +}, [ + {at: -0.3, expect: '26.5px 26.5px'}, + {at: 0, expect: '25px 25px'}, + {at: 0.3, expect: '23.5px 23.5px'}, + {at: 0.6, expect: '22px 22px'}, + {at: 1, expect: '20px 20px'}, + {at: 1.5, expect: '17.5px 17.5px'}, +]); + +test_interpolation({ + property: 'perspective-origin', + from: '0% 50%', + to: '100% 150%' +}, [ + {at: -0.3, expect: '-30% 20%'}, + {at: 0, expect: '0% 50%'}, + {at: 0.3, expect: '30% 80%'}, + {at: 0.6, expect: '60% 110%'}, + {at: 1, expect: '100% 150%'}, + {at: 1.5, expect: '150% 200%'} +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-drawImage-video-reset-expected.png b/third_party/blink/web_tests/fast/canvas/canvas-drawImage-video-reset-expected.png new file mode 100644 index 0000000..50e6f75 --- /dev/null +++ b/third_party/blink/web_tests/fast/canvas/canvas-drawImage-video-reset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-drawImage-video-reset.html b/third_party/blink/web_tests/fast/canvas/canvas-drawImage-video-reset.html new file mode 100644 index 0000000..6abd6a3 --- /dev/null +++ b/third_party/blink/web_tests/fast/canvas/canvas-drawImage-video-reset.html
@@ -0,0 +1,41 @@ +<html> +<head> + <title>Ensure correct behavior of drawImage video elements.</title> + <style type="text/css"> + video { + display: none; + } + </style> +</head> +<body> + <canvas id="canvas"></canvas> + <video id="video"> + <source src="resources/canvas_video.webm" type='video/webm' /> + <source src="resources/canvas_video.mp4" type='video/mp4' /> + <source src="resources/canvas_video.ogv" type='video/ogg' /> + </video> + <script> + var length = 150; + var canvas = document.getElementById("canvas"); + canvas.setAttribute("width", length); + canvas.setAttribute("height", length); + var ctx = canvas.getContext("2d"); + + var video = document.getElementById("video"); + video.addEventListener("playing", drawImageToCanvas, true); + video.play(); + + function drawImageToCanvas() { + video.removeEventListener("playing", drawImageToCanvas, true); + ctx.fillStyle = "blue"; + ctx.fillRect(0, 0, length, length); + ctx.drawImage(video, 0, 0); + ctx.globalAlpha = 0.5; + ctx.drawImage(video, 0, 60); + video.srcObject = null; + if (window.testRunner) + testRunner.notifyDone(); + } + </script> +</body> +</html>
diff --git a/third_party/blink/web_tests/platform/linux/fast/canvas/canvas-drawImage-video-reset-expected.png b/third_party/blink/web_tests/platform/linux/fast/canvas/canvas-drawImage-video-reset-expected.png new file mode 100644 index 0000000..a58254b --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/fast/canvas/canvas-drawImage-video-reset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-pattern-video-reset-expected.png b/third_party/blink/web_tests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-pattern-video-reset-expected.png new file mode 100644 index 0000000..71553edf --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-pattern-video-reset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/gpu/fast/canvas/canvas-drawImage-video-reset-expected.png b/third_party/blink/web_tests/platform/linux/virtual/gpu/fast/canvas/canvas-drawImage-video-reset-expected.png new file mode 100644 index 0000000..a58254b --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/gpu/fast/canvas/canvas-drawImage-video-reset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/canvas/canvas-drawImage-video-reset-expected.png b/third_party/blink/web_tests/platform/mac/fast/canvas/canvas-drawImage-video-reset-expected.png new file mode 100644 index 0000000..0232744 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/fast/canvas/canvas-drawImage-video-reset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/gpu/fast/canvas/canvas-drawImage-video-reset-expected.png b/third_party/blink/web_tests/platform/mac/virtual/gpu/fast/canvas/canvas-drawImage-video-reset-expected.png new file mode 100644 index 0000000..0232744 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/gpu/fast/canvas/canvas-drawImage-video-reset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/gpu/fast/canvas/canvas-drawImage-video-reset-expected.png b/third_party/blink/web_tests/virtual/gpu/fast/canvas/canvas-drawImage-video-reset-expected.png new file mode 100644 index 0000000..d67d3cb --- /dev/null +++ b/third_party/blink/web_tests/virtual/gpu/fast/canvas/canvas-drawImage-video-reset-expected.png Binary files differ
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index 110c766..cb923505 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-10-1-48-g99f23d6ff -Revision: 99f23d6ff2203966d210bccd49eacc62a20328f9 +Version: VER-2-10-1-49-g04ebb2a00 +Revision: 04ebb2a000ee40df2a9900198ec62d79af745b1f License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses" License File: src/docs/FTL.TXT
diff --git a/third_party/protobuf/OWNERS b/third_party/protobuf/OWNERS index 3c525a7..979e0de 100644 --- a/third_party/protobuf/OWNERS +++ b/third_party/protobuf/OWNERS
@@ -1,5 +1,6 @@ ajwong@chromium.org lgrey@chromium.org +nyquist@chromium.org pkasting@chromium.org # COMPONENT: Internals
diff --git a/tools/android/avd/avd.py b/tools/android/avd/avd.py old mode 100644 new mode 100755 index 7405601..c574e0eb --- a/tools/android/avd/avd.py +++ b/tools/android/avd/avd.py
@@ -1,12 +1,16 @@ +#! /usr/bin/env vpython # 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. +import argparse import contextlib +import json import logging import os import socket import stat +import subprocess import sys import threading @@ -23,9 +27,21 @@ sys.path.append( os.path.join(_SRC_ROOT, 'third_party', 'catapult', 'devil')) from devil.android.sdk import adb_wrapper +from devil.android.tools import script_common from devil.utils import cmd_helper +from devil.utils import logging_common from devil.utils import timeout_retry +sys.path.append( + os.path.join(_SRC_ROOT, 'build', 'android')) +import devil_chromium + + +_ALL_PACKAGES = object() +_DEFAULT_AVDMANAGER_PATH = os.path.join( + _SRC_ROOT, 'third_party', 'android_sdk', 'public', + 'tools', 'bin', 'avdmanager') + class AvdException(Exception): """Raised when this module has a problem interacting with an AVD.""" @@ -58,6 +74,92 @@ return text_format.Merge(avd_proto_file.read(), avd_pb2.Avd()) +class _AvdManagerAgent(object): + """Private utility for interacting with avdmanager.""" + + def __init__(self, avd_home, sdk_root): + """Create an _AvdManagerAgent. + + Args: + avd_home: path to ANDROID_AVD_HOME directory. + Typically something like /path/to/dir/.android/avd + sdk_root: path to SDK root directory. + """ + self._avd_home = avd_home + self._sdk_root = sdk_root + + self._env = dict(os.environ) + + # avdmanager, like many tools that have evolved from `android` + # (http://bit.ly/2m9JiTx), uses toolsdir to find the SDK root. + # Pass avdmanager a fake directory under the directory in which + # we install the system images s.t. avdmanager can find the + # system images. + fake_tools_dir = os.path.join( + self._sdk_root, + 'non-existent-tools') + self._env.update({ + 'ANDROID_AVD_HOME': self._avd_home, + 'AVDMANAGER_OPTS': + '-Dcom.android.sdkmanager.toolsdir=%s' % fake_tools_dir, + }) + + def Create(self, avd_name, system_image, force=False): + """Call `avdmanager create`. + + Args: + avd_name: name of the AVD to create. + system_image: system image to use for the AVD. + force: whether to force creation, overwriting any existing + AVD with the same name. + """ + create_cmd = [ + _DEFAULT_AVDMANAGER_PATH, + '-v', + 'create', + 'avd', + '-n', avd_name, + '-k', system_image, + ] + if force: + create_cmd += ['--force'] + + create_proc = cmd_helper.Popen( + create_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, env=self._env) + output, error = create_proc.communicate(input='\n') + if create_proc.returncode != 0: + raise AvdException( + 'AVD creation failed', + command=create_cmd, + stdout=output, + stderr=error) + + for line in output.splitlines(): + logging.info(' %s', line) + + def Delete(self, avd_name): + """Call `avdmanager delete`. + + Args: + avd_name: name of the AVD to delete. + """ + delete_cmd = [ + _DEFAULT_AVDMANAGER_PATH, + '-v', + 'delete', + 'avd', + '-n', avd_name, + ] + try: + for line in cmd_helper.IterCmdOutputLines(delete_cmd, env=self._env): + logging.info(' %s', line) + except subprocess.CalledProcessError as e: + raise AvdException( + 'AVD deletion failed: %s' % str(e), + command=delete_cmd) + + class AvdConfig(object): """Represents a particular AVD configuration. @@ -84,16 +186,118 @@ self._initialized = False self._initializer_lock = threading.Lock() - def Install(self): + def Create(self, force=False, snapshot=False, keep=False, + cipd_json_output=None): + """Create an instance of the AVD CIPD package. + + This method: + - installs the requisite system image + - creates the AVD + - modifies the AVD's ini files to support running chromium tests + in chromium infrastructure + - optionally starts & stops the AVD for snapshotting (default no) + - creates and uploads an instance of the AVD CIPD package + - optionally deletes the AVD (default yes) + + Args: + force: bool indicating whether to force create the AVD. + snapshot: bool indicating whether to snapshot the AVD before creating + the CIPD package. + keep: bool indicating whether to keep the AVD after creating + the CIPD package. + cipd_json_output: string path to pass to `cipd create` via -json-output. + """ + logging.info('Installing required packages.') + self.Install(packages=[self._config.system_image_package]) + + android_avd_home = os.path.join(self._emulator_home, 'avd') + + if not os.path.exists(android_avd_home): + os.makedirs(android_avd_home) + + avd_manager = _AvdManagerAgent( + avd_home=android_avd_home, + sdk_root=self._emulator_sdk_root) + + logging.info('Creating AVD.') + avd_manager.Create( + avd_name=self._config.avd_name, + system_image=self._config.system_image_name, + force=force) + + try: + logging.info('Modifying AVD configuration.') + + root_ini = os.path.join( + android_avd_home, '%s.ini' % self._config.avd_name) + avd_dir = os.path.join( + android_avd_home, '%s.avd' % self._config.avd_name) + config_ini = os.path.join(avd_dir, 'config.ini') + + with open(root_ini, 'a') as root_ini_file: + root_ini_file.write('path.rel=avd/%s.avd\n' % self._config.avd_name) + + with open(config_ini, 'a') as config_ini_file: + config_ini_file.write('disk.dataPartition.size=4G\n') + + # Start & stop the AVD. + if snapshot: + # TODO(crbug.com/922145): Implement support for snapshotting. + raise NotImplementedError('Snapshotting is not supported yet.') + + package_def_content = { + 'package': self._config.avd_package.package_name, + 'root': self._emulator_home, + 'install_mode': 'copy', + 'data': [ + {'dir': os.path.relpath(avd_dir, self._emulator_home)}, + {'file': os.path.relpath(root_ini, self._emulator_home)}, + ], + } + + logging.info('Creating AVD CIPD package.') + logging.debug('ensure file content: %s', + json.dumps(package_def_content, indent=2)) + + with tempfile_ext.TemporaryFileName(suffix='.json') as package_def_path: + with open(package_def_path, 'w') as package_def_file: + json.dump(package_def_content, package_def_file) + + logging.info(' %s', self._config.avd_package.package_name) + cipd_create_cmd = [ + 'cipd', 'create', '-pkg-def', package_def_path, + ] + if cipd_json_output: + cipd_create_cmd.extend([ + '-json-output', cipd_json_output, + ]) + try: + for line in cmd_helper.IterCmdOutputLines(cipd_create_cmd): + logging.info(' %s', line) + except subprocess.CalledProcessError as e: + raise AvdException( + 'CIPD package creation failed: %s' % str(e), + command=cipd_create_cmd) + + finally: + if not keep: + logging.info('Deleting AVD.') + avd_manager.Delete(avd_name=self._config.avd_name) + + def Install(self, packages=_ALL_PACKAGES): """Installs the requested CIPD packages. Returns: None Raises: AvdException on failure to install. """ pkgs_by_dir = {} - for pkg in (self._config.emulator_package, - self._config.system_image_package, - self._config.avd_package): + if packages is _ALL_PACKAGES: + packages = [ + self._config.avd_package, + self._config.emulator_package, + self._config.system_image_package, + ] + for pkg in packages: if not pkg.dest_path in pkgs_by_dir: pkgs_by_dir[pkg.dest_path] = [] pkgs_by_dir[pkg.dest_path].append(pkg) @@ -114,13 +318,14 @@ ensure_cmd = [ 'cipd', 'ensure', '-ensure-file', ensure_path, '-root', cipd_root, ] - status, output, error = cmd_helper.GetCmdStatusOutputAndError(ensure_cmd) - if status: + try: + for line in cmd_helper.IterCmdOutputLines(ensure_cmd): + logging.info(' %s', line) + except subprocess.CalledProcessError as e: raise AvdException( - 'Failed to install CIPD package %s' % pkg.package_name, - command=ensure_cmd, - stdout=output, - stderr=error) + 'Failed to install CIPD package %s: %s' % ( + pkg.package_name, str(e)), + command=ensure_cmd) # The emulator requires that some files are writable. for dirname, _, filenames in os.walk(self._emulator_home): @@ -247,3 +452,72 @@ @property def serial(self): return self._emulator_serial + + +def main(raw_args): + + parser = argparse.ArgumentParser() + + def add_common_arguments(parser): + logging_common.AddLoggingArguments(parser) + script_common.AddEnvironmentArguments(parser) + parser.add_argument( + '--avd-config', + type=os.path.realpath, + metavar='PATH', + required=True, + help='Path to an AVD config text protobuf.') + + subparsers = parser.add_subparsers() + install_parser = subparsers.add_parser( + 'install', + help='Install the CIPD packages specified in the given config.') + add_common_arguments(install_parser) + + def install_cmd(args): + AvdConfig(args.avd_config).Install() + return 0 + + install_parser.set_defaults(func=install_cmd) + + create_parser = subparsers.add_parser( + 'create', + help='Create an AVD CIPD package according to the given config.') + add_common_arguments(create_parser) + create_parser.add_argument( + '--snapshot', + action='store_true', + help='Snapshot the AVD before creating the CIPD package.') + create_parser.add_argument( + '--force', + action='store_true', + help='Pass --force to AVD creation.') + create_parser.add_argument( + '--keep', + action='store_true', + help='Keep the AVD after creating the CIPD package.') + create_parser.add_argument( + '--cipd-json-output', + type=os.path.realpath, + metavar='PATH', + help='Path to which `cipd create` should dump json output ' + 'via -json-output.') + + def create_cmd(args): + AvdConfig(args.avd_config).Create( + force=args.force, snapshot=args.snapshot, keep=args.keep, + cipd_json_output=args.cipd_json_output) + return 0 + + create_parser.set_defaults(func=create_cmd) + + # TODO(jbudorick): Expose `start` as a subcommand. + + args = parser.parse_args(raw_args) + logging_common.InitializeLogging(args) + devil_chromium.Initialize(adb_path=args.adb_path) + return args.func(args) + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:]))
diff --git a/tools/android/avd/avd.pydeps b/tools/android/avd/avd.pydeps index c9fd880..3aa0c24 100644 --- a/tools/android/avd/avd.pydeps +++ b/tools/android/avd/avd.pydeps
@@ -1,5 +1,9 @@ # Generated by running: # build/print_python_deps.py --root tools/android/avd --output tools/android/avd/avd.pydeps tools/android/avd/avd.py +../../../build/android/devil_chromium.py +../../../build/android/pylib/__init__.py +../../../build/android/pylib/constants/__init__.py +../../../build/android/pylib/constants/host_paths.py ../../../third_party/catapult/common/py_utils/py_utils/__init__.py ../../../third_party/catapult/common/py_utils/py_utils/cloud_storage.py ../../../third_party/catapult/common/py_utils/py_utils/cloud_storage_global_lock.py @@ -17,20 +21,50 @@ ../../../third_party/catapult/dependency_manager/dependency_manager/uploader.py ../../../third_party/catapult/devil/devil/__init__.py ../../../third_party/catapult/devil/devil/android/__init__.py +../../../third_party/catapult/devil/devil/android/apk_helper.py +../../../third_party/catapult/devil/devil/android/constants/__init__.py +../../../third_party/catapult/devil/devil/android/constants/chrome.py +../../../third_party/catapult/devil/devil/android/constants/file_system.py ../../../third_party/catapult/devil/devil/android/decorators.py +../../../third_party/catapult/devil/devil/android/device_blacklist.py ../../../third_party/catapult/devil/devil/android/device_errors.py +../../../third_party/catapult/devil/devil/android/device_signal.py +../../../third_party/catapult/devil/devil/android/device_temp_file.py +../../../third_party/catapult/devil/devil/android/device_utils.py +../../../third_party/catapult/devil/devil/android/install_commands.py +../../../third_party/catapult/devil/devil/android/logcat_monitor.py +../../../third_party/catapult/devil/devil/android/md5sum.py +../../../third_party/catapult/devil/devil/android/ndk/__init__.py +../../../third_party/catapult/devil/devil/android/ndk/abis.py ../../../third_party/catapult/devil/devil/android/sdk/__init__.py +../../../third_party/catapult/devil/devil/android/sdk/aapt.py ../../../third_party/catapult/devil/devil/android/sdk/adb_wrapper.py +../../../third_party/catapult/devil/devil/android/sdk/build_tools.py +../../../third_party/catapult/devil/devil/android/sdk/bundletool.py +../../../third_party/catapult/devil/devil/android/sdk/intent.py +../../../third_party/catapult/devil/devil/android/sdk/keyevent.py +../../../third_party/catapult/devil/devil/android/sdk/split_select.py +../../../third_party/catapult/devil/devil/android/sdk/version_codes.py +../../../third_party/catapult/devil/devil/android/tools/__init__.py +../../../third_party/catapult/devil/devil/android/tools/script_common.py ../../../third_party/catapult/devil/devil/base_error.py +../../../third_party/catapult/devil/devil/constants/__init__.py +../../../third_party/catapult/devil/devil/constants/exit_codes.py ../../../third_party/catapult/devil/devil/devil_env.py ../../../third_party/catapult/devil/devil/utils/__init__.py ../../../third_party/catapult/devil/devil/utils/cmd_helper.py +../../../third_party/catapult/devil/devil/utils/host_utils.py ../../../third_party/catapult/devil/devil/utils/lazy/__init__.py ../../../third_party/catapult/devil/devil/utils/lazy/weak_constant.py +../../../third_party/catapult/devil/devil/utils/logging_common.py +../../../third_party/catapult/devil/devil/utils/lsusb.py ../../../third_party/catapult/devil/devil/utils/parallelizer.py ../../../third_party/catapult/devil/devil/utils/reraiser_thread.py +../../../third_party/catapult/devil/devil/utils/reset_usb.py +../../../third_party/catapult/devil/devil/utils/run_tests_helper.py ../../../third_party/catapult/devil/devil/utils/timeout_retry.py ../../../third_party/catapult/devil/devil/utils/watchdog_timer.py +../../../third_party/catapult/devil/devil/utils/zip_utils.py ../../../third_party/catapult/third_party/zipfile/zipfile_2_7_13.py avd.py proto/__init__.py
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 083e5ec..5d41172 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -440,6 +440,7 @@ 'Linux Builder': 'gpu_tests_release_bot', 'fuchsia-arm64-cast': 'release_bot_fuchsia_arm64_cast', 'fuchsia-x64-cast': 'release_bot_fuchsia_cast', + 'fuchsia-x64-dbg': 'debug_bot_fuchsia_compile_only', 'linux-gcc-rel': 'release_bot_x86_minimal_symbols_no_clang_cxx11', # linux-jumbo-rel is identical to linux-rel for perf comparisons, except # for the jumbo part. @@ -756,6 +757,7 @@ 'closure_compilation': 'closure_compilation', 'fuchsia_arm64': 'release_trybot_fuchsia_arm64', 'fuchsia-arm64-cast': 'release_trybot_fuchsia_arm64_cast', + 'fuchsia-compile-x64-dbg': 'debug_trybot_fuchsia_compile_only', 'fuchsia-fyi-arm64-rel': 'release_trybot_fuchsia_arm64', 'fuchsia-fyi-x64-dbg': 'debug_trybot_fuchsia', 'fuchsia-fyi-x64-rel': 'release_trybot_fuchsia', @@ -1475,6 +1477,10 @@ 'debug_bot', 'fuchsia', ], + 'debug_bot_fuchsia_compile_only': [ + 'debug_bot', 'fuchsia', 'compile_only', + ], + 'debug_bot_x86': [ 'debug_bot', 'x86', ], @@ -1503,6 +1509,10 @@ 'debug_trybot', 'fuchsia', ], + 'debug_trybot_fuchsia_compile_only': [ + 'debug_trybot', 'fuchsia', 'compile_only', + ], + 'debug_trybot_x86': [ 'debug_trybot', 'x86', ],
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 42a42420..01907ac2 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -17119,6 +17119,16 @@ <int value="1" label="Cound not bind to domain controller."/> </enum> +<enum name="EnterpriseCloudReportingResponse"> + <summary>Result of uploading an enterprise report.</summary> + <int value="0" label="Success"/> + <int value="1" label="Network error"/> + <int value="2" label="Temporary server error"/> + <int value="3" label="DDS concurrency error"/> + <int value="4" label="Request too large error"/> + <int value="5" label="Other error"/> +</enum> + <enum name="EnterpriseDeviceManagementStatus"> <summary> Status codes produced by DeviceManagementService for requests made to the
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 60d54dc..0115272 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -12880,7 +12880,20 @@ enum="BooleanSuccess" expires_after="2020-08-01"> <owner>robertogden@chromium.org</owner> <owner>tbansal@chromium.org</owner> - <summary>Records the completion status of a probe when it completes.</summary> + <summary> + Records the completion status of a probe when it completes each attempt. + </summary> +</histogram> + +<histogram base="true" name="Availability.Prober.FinalState" + enum="BooleanSuccess" expires_after="2020-08-01"> + <owner>robertogden@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + Records the end state of a probe just before it goes inactive. This happens + when the prober succeeds, fails and has no more retries, or the delegate + stops probing. + </summary> </histogram> <histogram base="true" name="Availability.Prober.NetError" enum="NetErrorCodes" @@ -35923,6 +35936,16 @@ </summary> </histogram> +<histogram name="Enterprise.CloudReportingResponse" + enum="EnterpriseCloudReportingResponse" expires_after="M83"> + <owner>zmin@chromium.org</owner> + <summary> + The upload result for each cloud reporting request. Note that there may be + multiple requests per report. Also, one request may creates multiple data + point due to retry. + </summary> +</histogram> + <histogram name="Enterprise.DevicePolicyInvalidations" enum="EnterprisePolicyInvalidations"> <owner>bartfab@chromium.org</owner> @@ -49232,7 +49255,7 @@ </histogram> <histogram name="GoogleUpdate.Inline.AppUpdateInfo.InstallStatus" - enum="InlineUpdateInstallStatus" expires_after="2019-10-30"> + enum="InlineUpdateInstallStatus" expires_after="2020-02-15"> <owner>dtrainor@chromium.org</owner> <owner>nyquist@chromium.org</owner> <summary> @@ -49242,7 +49265,7 @@ </histogram> <histogram name="GoogleUpdate.Inline.AppUpdateInfo.UpdateAvailability" - enum="InlineUpdateAvailability" expires_after="2019-10-30"> + enum="InlineUpdateAvailability" expires_after="2020-02-15"> <owner>dtrainor@chromium.org</owner> <owner>nyquist@chromium.org</owner> <summary> @@ -49252,7 +49275,7 @@ </histogram> <histogram name="GoogleUpdate.Inline.CallFailure" - enum="InlineUpdateCallFailure" expires_after="2019-10-30"> + enum="InlineUpdateCallFailure" expires_after="2020-02-15"> <owner>dtrainor@chromium.org</owner> <owner>nyquist@chromium.org</owner> <summary> @@ -49261,7 +49284,7 @@ </histogram> <histogram name="GoogleUpdate.Inline.StateChange.Error" - enum="InlineUpdateErrorCodes" expires_after="2019-10-30"> + enum="InlineUpdateErrorCodes" expires_after="2020-02-15"> <!-- Name completed by histogram_suffixes name="GoogleUpdate.Inline.InstallStatus" --> <owner>dtrainor@chromium.org</owner> @@ -49274,7 +49297,7 @@ </histogram> <histogram name="GoogleUpdate.Inline.UI.Install.Source" - enum="UpdateInteractionSource" expires_after="2019-10-30"> + enum="UpdateInteractionSource" expires_after="2020-02-15"> <owner>dtrainor@chromium.org</owner> <owner>nyquist@chromium.org</owner> <summary> @@ -49284,7 +49307,7 @@ </histogram> <histogram name="GoogleUpdate.Inline.UI.Retry.Source" - enum="UpdateInteractionSource" expires_after="2019-10-30"> + enum="UpdateInteractionSource" expires_after="2020-02-15"> <owner>dtrainor@chromium.org</owner> <owner>nyquist@chromium.org</owner> <summary> @@ -49293,7 +49316,7 @@ </histogram> <histogram name="GoogleUpdate.Inline.UI.Start.Source" - enum="UpdateInteractionSource" expires_after="2019-10-30"> + enum="UpdateInteractionSource" expires_after="2020-02-15"> <owner>dtrainor@chromium.org</owner> <owner>nyquist@chromium.org</owner> <summary> @@ -49388,7 +49411,7 @@ </histogram> <histogram name="GoogleUpdate.StartUp.State" enum="UpdateState" - expires_after="2019-10-30"> + expires_after="2020-02-15"> <owner>dtrainor@chromium.org</owner> <owner>nyquist@chromium.org</owner> <summary> @@ -69331,6 +69354,19 @@ </summary> </histogram> +<histogram name="Mojo.Connector.MaxUnreadMessageQuotaUsed" units="messages" + expires_after="2020-10-01"> + <owner>siggi@chromium.org</owner> + <owner>rockot@chromium.org</owner> + <summary> + The maximal unread message quota used for the lifetime of a Connector. This + is sampled for a configurable percentage of Connectors only when the feature + MojoRecordUnreadMessageCount is enabled. By default 1% of Connectors are + sampled, as there's some overhead involved in enabling the unread message + quota on a MessagePipe. See //mojo/public/cpp/bindings/lib/connector.cc. + </summary> +</histogram> + <histogram name="Mojo.MachPortRelay.BrokerError" enum="MojoMachPortRelayBrokerError" expires_after="M77"> <obsolete> @@ -162909,6 +162945,7 @@ label="Origin check for Litepage previews"/> <affected-histogram name="Availability.Prober.CacheEntryAge"/> <affected-histogram name="Availability.Prober.DidSucceed"/> + <affected-histogram name="Availability.Prober.FinalState"/> <affected-histogram name="Availability.Prober.NetError"/> <affected-histogram name="Availability.Prober.NumAttemptsBeforeSuccess"/> <affected-histogram name="Availability.Prober.ResponseCode"/>
diff --git a/tools/perf/process_perf_results.py b/tools/perf/process_perf_results.py index 0fb87dd..1b660dd 100755 --- a/tools/perf/process_perf_results.py +++ b/tools/perf/process_perf_results.py
@@ -56,6 +56,7 @@ 'angle_perftests', 'cc_perftests', 'gpu_perftests', + 'latency_perftests', 'media_perftests', 'views_perftests', 'xr.vr.common_perftests',
diff --git a/tools/traffic_annotation/scripts/extractor.py b/tools/traffic_annotation/scripts/extractor.py index b2572af..5c45726 100755 --- a/tools/traffic_annotation/scripts/extractor.py +++ b/tools/traffic_annotation/scripts/extractor.py
@@ -247,6 +247,11 @@ for annotation in annotation_definitions: print(annotation.clang_tool_output_string()) + # If all files were successfully checked for annotations but none of them had + # any, print something so that the traffic_annotation_auditor knows there was + # no error so that the files get checked for deleted annotations. + if not annotation_definitions: + print('No annotations in these files.') return 0
diff --git a/ui/accessibility/ax_node.h b/ui/accessibility/ax_node.h index 25ec866..86d35fe 100644 --- a/ui/accessibility/ax_node.h +++ b/ui/accessibility/ax_node.h
@@ -16,6 +16,7 @@ #include "build/build_config.h" #include "ui/accessibility/ax_export.h" #include "ui/accessibility/ax_node_data.h" +#include "ui/accessibility/ax_tree_id.h" namespace ui { @@ -49,6 +50,8 @@ }; // See AXTree. + virtual AXTreeID GetAXTreeID() const = 0; + // See AXTree. virtual AXTableInfo* GetTableInfo(const AXNode* table_node) const = 0; // See AXTree. virtual AXNode* GetFromId(int32_t id) const = 0;
diff --git a/ui/accessibility/ax_position.h b/ui/accessibility/ax_position.h index 0b2945b6..30db03f 100644 --- a/ui/accessibility/ax_position.h +++ b/ui/accessibility/ax_position.h
@@ -670,17 +670,12 @@ return CreateNextAnchorPosition()->IsNullPosition() && AtEndOfAnchor(); } - // This method returns a position instead of a node because this allows us to - // return the corresponding text offset or child index in the ancestor that - // relates to the current position. - // Also, this method uses position instead of tree logic to traverse the tree, - // because positions can handle moving across multiple trees, while trees - // cannot. - AXPositionInstance LowestCommonAncestor(const AXPosition& second) const { + // This method finds the lowest common AXNodeType of |this| and |second|. + AXNodeType* LowestCommonAnchor(const AXPosition& second) const { if (IsNullPosition() || second.IsNullPosition()) - return CreateNullPosition(); + return nullptr; if (GetAnchor() == second.GetAnchor()) - return Clone(); + return GetAnchor(); base::stack<AXNodeType*> our_ancestors = GetAncestorAnchors(); base::stack<AXNodeType*> other_ancestors = second.GetAncestorAnchors(); @@ -692,6 +687,17 @@ our_ancestors.pop(); other_ancestors.pop(); } + return common_anchor; + } + + // This method returns a position instead of a node because this allows us to + // return the corresponding text offset or child index in the ancestor that + // relates to the current position. + // Also, this method uses position instead of tree logic to traverse the tree, + // because positions can handle moving across multiple trees, while trees + // cannot. + AXPositionInstance LowestCommonAncestor(const AXPosition& second) const { + AXNodeType* common_anchor = LowestCommonAnchor(second); if (!common_anchor) return CreateNullPosition();
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc index 3eac95a..fbfca41b 100644 --- a/ui/accessibility/ax_tree.cc +++ b/ui/accessibility/ax_tree.cc
@@ -578,6 +578,10 @@ observers_.RemoveObserver(observer); } +AXTreeID AXTree::GetAXTreeID() const { + return data().tree_id; +} + AXNode* AXTree::GetFromId(int32_t id) const { auto iter = id_map_.find(id); return iter != id_map_.end() ? iter->second : nullptr;
diff --git a/ui/accessibility/ax_tree.h b/ui/accessibility/ax_tree.h index 9e048cb..a706758 100644 --- a/ui/accessibility/ax_tree.h +++ b/ui/accessibility/ax_tree.h
@@ -55,6 +55,10 @@ const AXTreeData& data() const { return data_; } // AXNode::OwnerTree override. + // Returns the globally unique ID of this accessibility tree. + AXTreeID GetAXTreeID() const override; + + // AXNode::OwnerTree override. // Returns the AXNode with the given |id| if it is part of this AXTree. AXNode* GetFromId(int32_t id) const override;
diff --git a/ui/accessibility/platform/ax_fragment_root_win.h b/ui/accessibility/platform/ax_fragment_root_win.h index c71af51..61743958 100644 --- a/ui/accessibility/platform/ax_fragment_root_win.h +++ b/ui/accessibility/platform/ax_fragment_root_win.h
@@ -39,7 +39,7 @@ gfx::AcceleratedWidget widget); // Returns the NativeViewAccessible for this fragment root. - gfx::NativeViewAccessible GetNativeViewAccessible(); + gfx::NativeViewAccessible GetNativeViewAccessible() override; // Assistive technologies will typically use UI Automation's control or // content view rather than the raw view.
diff --git a/ui/accessibility/platform/ax_fragment_root_win_unittest.cc b/ui/accessibility/platform/ax_fragment_root_win_unittest.cc index 304c2e4..87f2774a 100644 --- a/ui/accessibility/platform/ax_fragment_root_win_unittest.cc +++ b/ui/accessibility/platform/ax_fragment_root_win_unittest.cc
@@ -5,10 +5,12 @@ #include "ui/accessibility/platform/ax_fragment_root_win.h" #include "ui/accessibility/platform/ax_platform_node_win.h" #include "ui/accessibility/platform/ax_platform_node_win_unittest.h" +#include "ui/accessibility/platform/test_ax_node_wrapper.h" #include <UIAutomationClient.h> #include <UIAutomationCoreApi.h> +#include "base/auto_reset.h" #include "base/win/scoped_safearray.h" #include "base/win/scoped_variant.h" #include "testing/gtest/include/gtest/gtest.h" @@ -77,6 +79,13 @@ EXPECT_HRESULT_SUCCEEDED(fragment_root_prov->ElementProviderFromPoint( 47, 67, &provider_from_point)); EXPECT_EQ(root_provider.Get(), provider_from_point.Get()); + + // This is on node 1 with scale factor of 1.5. + std::unique_ptr<base::AutoReset<float>> scale_factor_reset = + TestAXNodeWrapper::SetScaleFactor(1.5); + EXPECT_HRESULT_SUCCEEDED(fragment_root_prov->ElementProviderFromPoint( + 60, 60, &provider_from_point)); + EXPECT_EQ(element1_provider.Get(), provider_from_point.Get()); } TEST_F(AXFragmentRootTest, TestUIAGetFocus) {
diff --git a/ui/accessibility/platform/ax_platform_node_delegate.h b/ui/accessibility/platform/ax_platform_node_delegate.h index dd264149..88d346ff7 100644 --- a/ui/accessibility/platform/ax_platform_node_delegate.h +++ b/ui/accessibility/platform/ax_platform_node_delegate.h
@@ -77,6 +77,10 @@ // method is only meaningful on macOS. virtual gfx::NativeViewAccessible GetNSWindow() = 0; + // Get the node for this delegate, which may be an AXPlatformNode or it may + // be a native accessible object implemented by another class. + virtual gfx::NativeViewAccessible GetNativeViewAccessible() = 0; + // Get the parent of the node, which may be an AXPlatformNode or it may // be a native accessible object implemented by another class. virtual gfx::NativeViewAccessible GetParent() = 0;
diff --git a/ui/accessibility/platform/ax_platform_node_delegate_base.cc b/ui/accessibility/platform/ax_platform_node_delegate_base.cc index a07e5c145..6c420da 100644 --- a/ui/accessibility/platform/ax_platform_node_delegate_base.cc +++ b/ui/accessibility/platform/ax_platform_node_delegate_base.cc
@@ -44,6 +44,11 @@ return nullptr; } +gfx::NativeViewAccessible +AXPlatformNodeDelegateBase::GetNativeViewAccessible() { + return nullptr; +} + gfx::NativeViewAccessible AXPlatformNodeDelegateBase::GetParent() { return nullptr; }
diff --git a/ui/accessibility/platform/ax_platform_node_delegate_base.h b/ui/accessibility/platform/ax_platform_node_delegate_base.h index 6fdcd60..6f2c452a 100644 --- a/ui/accessibility/platform/ax_platform_node_delegate_base.h +++ b/ui/accessibility/platform/ax_platform_node_delegate_base.h
@@ -44,6 +44,10 @@ // See comments in AXPlatformNodeDelegate. gfx::NativeViewAccessible GetNSWindow() override; + // Get the node for this delegate, which may be an AXPlatformNode or it may + // be a native accessible object implemented by another class. + gfx::NativeViewAccessible GetNativeViewAccessible() override; + // Get the parent of the node, which may be an AXPlatformNode or it may // be a native accessible object implemented by another class. gfx::NativeViewAccessible GetParent() override;
diff --git a/ui/accessibility/platform/ax_platform_node_textchildprovider_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_textchildprovider_win_unittest.cc index b8825da..ac7518e 100644 --- a/ui/accessibility/platform/ax_platform_node_textchildprovider_win_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_textchildprovider_win_unittest.cc
@@ -71,6 +71,8 @@ AXNode* root_node = GetRootNode(); AXNodePosition::SetTree(tree_.get()); + AXTreeManagerMap::GetInstance().AddTreeManager(update.tree_data.tree_id, + this); AXNode* nontext_child_of_root_node = root_node->children()[0]; AXNode* text_child_of_root_node = root_node->children()[1]; AXNode* nontext_child_of_nontext_node =
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc index 55a42f7..89bfc03 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc
@@ -453,17 +453,22 @@ WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_GETENCLOSINGELEMENT); UIA_VALIDATE_TEXTRANGEPROVIDER_CALL(); - AXPositionInstance common_ancestor = start_->LowestCommonAncestor(*end_); - AXPlatformNode* node = GetDelegate(common_ancestor.get()) - ->GetFromNodeID(common_ancestor->anchor_id()); - DCHECK(node); - while (ui::IsIgnored(node->GetDelegate()->GetData())) { - node = static_cast<AXPlatformNodeWin*>( - AXPlatformNode::FromNativeViewAccessible( - node->GetDelegate()->GetParent())); - DCHECK(node); + AXNode* common_anchor = start_->LowestCommonAnchor(*end_); + DCHECK(common_anchor); + if (!common_anchor) + return UIA_E_ELEMENTNOTAVAILABLE; + + const AXTreeID tree_id = common_anchor->tree()->GetAXTreeID(); + const AXNode::AXID node_id = common_anchor->id(); + AXPlatformNodeDelegate* delegate = GetDelegate(tree_id, node_id); + DCHECK(delegate); + while (ui::IsIgnored(delegate->GetData())) { + AXPlatformNodeWin* parent = static_cast<AXPlatformNodeWin*>( + AXPlatformNode::FromNativeViewAccessible(delegate->GetParent())); + DCHECK(parent); + delegate = parent->GetDelegate(); } - node->GetNativeViewAccessible()->QueryInterface(IID_PPV_ARGS(element)); + delegate->GetNativeViewAccessible()->QueryInterface(IID_PPV_ARGS(element)); DCHECK(*element); return S_OK; @@ -812,11 +817,15 @@ AXPlatformNodeDelegate* AXPlatformNodeTextRangeProviderWin::GetDelegate( const AXPositionInstanceType* position) const { - AXTreeManager* manager = - AXTreeManagerMap::GetInstance().GetManager(position->tree_id()); - return manager - ? manager->GetDelegate(position->tree_id(), position->anchor_id()) - : owner()->GetDelegate(); + return GetDelegate(position->tree_id(), position->anchor_id()); +} + +AXPlatformNodeDelegate* AXPlatformNodeTextRangeProviderWin::GetDelegate( + const AXTreeID tree_id, + const AXNode::AXID node_id) const { + AXTreeManager* manager = AXTreeManagerMap::GetInstance().GetManager(tree_id); + return manager ? manager->GetDelegate(tree_id, node_id) + : owner()->GetDelegate(); } AXPlatformNodeTextRangeProviderWin::AXPositionInstance
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h index 6a3ff0d..1ddc770 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h
@@ -92,6 +92,8 @@ AXPlatformNodeWin* owner() const; AXPlatformNodeDelegate* GetDelegate( const AXPositionInstanceType* position) const; + AXPlatformNodeDelegate* GetDelegate(const AXTreeID tree_id, + const AXNode::AXID node_id) const; template <typename AnchorIterator, typename ExpandMatchLambda> HRESULT FindAttributeRange(const TEXTATTRIBUTEID text_attribute_id,
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc index 0e89882..2316b6ac7 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc
@@ -948,8 +948,11 @@ TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderExpandToEnclosingCharacter) { - Init(BuildTextDocument({"some text", "more text"})); + ui::AXTreeUpdate update = BuildTextDocument({"some text", "more text"}); + Init(update); AXNodePosition::SetTree(tree_.get()); + AXTreeManagerMap::GetInstance().AddTreeManager(update.tree_data.tree_id, + this); AXNode* root_node = GetRootNode(); ComPtr<ITextRangeProvider> text_range_provider;
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_win_unittest.cc index a79d784a..3730d65 100644 --- a/ui/accessibility/platform/ax_platform_node_win_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
@@ -9,6 +9,7 @@ #include <memory> +#include "base/auto_reset.h" #include "base/stl_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/win/atl.h" @@ -445,7 +446,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleHitTest) { AXNodeData root; root.id = 1; - root.relative_bounds.bounds = gfx::RectF(0, 0, 30, 30); + root.relative_bounds.bounds = gfx::RectF(0, 0, 40, 40); AXNodeData node1; node1.id = 2; @@ -455,7 +456,7 @@ AXNodeData node2; node2.id = 3; - node2.relative_bounds.bounds = gfx::RectF(20, 20, 10, 10); + node2.relative_bounds.bounds = gfx::RectF(20, 20, 20, 20); node2.SetName("Name2"); root.child_ids.push_back(node2.id); @@ -463,17 +464,23 @@ ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedVariant obj; + // This is way outside of the root node. + ScopedVariant obj_1; + EXPECT_EQ(S_FALSE, root_obj->accHitTest(50, 50, obj_1.Receive())); + EXPECT_EQ(VT_EMPTY, obj_1.type()); - // This is way outside of the root node - EXPECT_EQ(S_FALSE, root_obj->accHitTest(50, 50, obj.Receive())); - EXPECT_EQ(VT_EMPTY, obj.type()); + // This is directly on node 1. + EXPECT_EQ(S_OK, root_obj->accHitTest(5, 5, obj_1.Receive())); + ASSERT_NE(nullptr, obj_1.ptr()); + CheckVariantHasName(obj_1, L"Name1"); - // this is directly on node 1. - EXPECT_EQ(S_OK, root_obj->accHitTest(5, 5, obj.Receive())); - ASSERT_NE(nullptr, obj.ptr()); - - CheckVariantHasName(obj, L"Name1"); + // This is directly on node 2 with a scale factor of 1.5. + ScopedVariant obj_2; + std::unique_ptr<base::AutoReset<float>> scale_factor_reset = + TestAXNodeWrapper::SetScaleFactor(1.5); + EXPECT_EQ(S_OK, root_obj->accHitTest(38, 38, obj_2.Receive())); + ASSERT_NE(nullptr, obj_2.ptr()); + CheckVariantHasName(obj_2, L"Name2"); } TEST_F(AXPlatformNodeWinTest, TestIAccessibleName) {
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc index 764241fb..2b289f04 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.cc +++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -26,6 +26,9 @@ // A global coordinate offset. gfx::Vector2d g_offset; +// A global scale factor. +float g_scale_factor = 1.0; + // A global map that stores which node is focused on a determined tree. // - If a tree has no node being focused, there shouldn't be any entry on the // map associated with such tree, i.e. a pair {tree, nullptr} is invalid. @@ -88,6 +91,12 @@ return g_node_from_last_default_action; } +// static +std::unique_ptr<base::AutoReset<float>> TestAXNodeWrapper::SetScaleFactor( + float value) { + return std::make_unique<base::AutoReset<float>>(&g_scale_factor, value); +} + TestAXNodeWrapper::~TestAXNodeWrapper() { platform_node_->Destroy(); } @@ -111,6 +120,10 @@ ax::mojom::TextAffinity::kDownstream); } +gfx::NativeViewAccessible TestAXNodeWrapper::GetNativeViewAccessible() { + return ax_platform_node()->GetNativeViewAccessible(); +} + gfx::NativeViewAccessible TestAXNodeWrapper::GetParent() { TestAXNodeWrapper* parent_wrapper = GetOrCreate(tree_, node_->GetUnignoredParent()); @@ -224,7 +237,8 @@ } gfx::NativeViewAccessible TestAXNodeWrapper::HitTestSync(int x, int y) { - TestAXNodeWrapper* wrapper = HitTestSyncInternal(x, y); + TestAXNodeWrapper* wrapper = + HitTestSyncInternal(x / g_scale_factor, y / g_scale_factor); return wrapper ? wrapper->ax_platform_node()->GetNativeViewAccessible() : nullptr; }
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.h b/ui/accessibility/platform/test_ax_node_wrapper.h index eff3778..e3fc5ae 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.h +++ b/ui/accessibility/platform/test_ax_node_wrapper.h
@@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "base/auto_reset.h" #include "build/build_config.h" #include "ui/accessibility/ax_node.h" #include "ui/accessibility/ax_tree.h" @@ -40,6 +41,9 @@ // called from for testing. static const AXNode* GetNodeFromLastDefaultAction(); + // Set a global scale factor for testing. + static std::unique_ptr<base::AutoReset<float>> SetScaleFactor(float value); + ~TestAXNodeWrapper() override; AXPlatformNode* ax_platform_node() const { return platform_node_; } @@ -55,6 +59,7 @@ const AXTree::Selection GetUnignoredSelection() const override; AXNodePosition::AXPositionInstance CreateTextPositionAt( int offset) const override; + gfx::NativeViewAccessible GetNativeViewAccessible() override; gfx::NativeViewAccessible GetParent() override; int GetChildCount() override; gfx::NativeViewAccessible ChildAtIndex(int index) override;
diff --git a/ui/base/cocoa/menu_controller.h b/ui/base/cocoa/menu_controller.h index 69bea16..72f990a8 100644 --- a/ui/base/cocoa/menu_controller.h +++ b/ui/base/cocoa/menu_controller.h
@@ -25,9 +25,6 @@ @interface MenuControllerCocoa : NSObject<NSMenuDelegate, NSUserInterfaceValidations> -// The Model passed in to -initWithModel:. -@property(nonatomic, assign) ui::MenuModel* model; - // Whether to activate selected menu items via a posted task. This may allow the // selection to be handled earlier, whilst the menu is fading out. If the posted // task wasn't processed by the time the action is normally sent, it will be @@ -54,6 +51,9 @@ // Programmatically close the constructed menu. - (void)cancel; +- (ui::MenuModel*)model; +- (void)setModel:(ui::MenuModel*)model; + // Access to the constructed menu if the complex initializer was used. If the // default initializer was used, then this will create the menu on first call. - (NSMenu*)menu;
diff --git a/ui/base/cocoa/menu_controller.mm b/ui/base/cocoa/menu_controller.mm index 647c8bb2..4128846 100644 --- a/ui/base/cocoa/menu_controller.mm +++ b/ui/base/cocoa/menu_controller.mm
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/cancelable_callback.h" #include "base/logging.h" +#include "base/mac/foundation_util.h" #include "base/strings/sys_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "ui/base/accelerators/accelerator.h" @@ -44,6 +45,42 @@ } // namespace +// This class stores a base::WeakPtr<ui::MenuModel> as an Objective-C object, +// which allows it to be stored in the representedObject field of an NSMenuItem. +@interface WeakPtrToMenuModelAsNSObject : NSObject ++ (instancetype)weakPtrForModel:(ui::MenuModel*)model; ++ (ui::MenuModel*)getFrom:(id)instance; +- (instancetype)initWithModel:(ui::MenuModel*)model; +- (ui::MenuModel*)menuModel; +@end + +@implementation WeakPtrToMenuModelAsNSObject { + base::WeakPtr<ui::MenuModel> model_; +} + ++ (instancetype)weakPtrForModel:(ui::MenuModel*)model { + return + [[[WeakPtrToMenuModelAsNSObject alloc] initWithModel:model] autorelease]; +} + ++ (ui::MenuModel*)getFrom:(id)instance { + return [base::mac::ObjCCastStrict<WeakPtrToMenuModelAsNSObject>(instance) + menuModel]; +} + +- (instancetype)initWithModel:(ui::MenuModel*)model { + if ((self = [super init])) { + model_ = model->AsWeakPtr(); + } + return self; +} + +- (ui::MenuModel*)menuModel { + return model_.get(); +} + +@end + // Internal methods. @interface MenuControllerCocoa () // Called before the menu is to be displayed to update the state (enabled, @@ -83,7 +120,7 @@ @end @implementation MenuControllerCocoa { - ui::MenuModel* model_; // Weak. + base::WeakPtr<ui::MenuModel> model_; base::scoped_nsobject<NSMenu> menu_; BOOL useWithPopUpButtonCell_; // If YES, 0th item is blank BOOL isMenuOpen_; @@ -91,10 +128,17 @@ std::unique_ptr<base::CancelableClosure> postedItemSelectedTask_; } -@synthesize model = model_; @synthesize useWithPopUpButtonCell = useWithPopUpButtonCell_; @synthesize postItemSelectedAsTask = postItemSelectedAsTask_; +- (ui::MenuModel*)model { + return model_.get(); +} + +- (void)setModel:(ui::MenuModel*)model { + model_ = model->AsWeakPtr(); +} + - (instancetype)init { self = [super init]; return self; @@ -103,7 +147,7 @@ - (instancetype)initWithModel:(ui::MenuModel*)model useWithPopUpButtonCell:(BOOL)useWithCell { if ((self = [super init])) { - model_ = model; + model_ = model->AsWeakPtr(); useWithPopUpButtonCell_ = useWithCell; [self menu]; } @@ -117,14 +161,15 @@ // while its context menu is still open. [self cancel]; - model_ = NULL; + model_ = nullptr; [super dealloc]; } - (void)cancel { if (isMenuOpen_) { [menu_ cancelTracking]; - model_->MenuWillClose(); + if (model_) + model_->MenuWillClose(); isMenuOpen_ = NO; } } @@ -190,8 +235,8 @@ // in validation of the menu items. [item setTag:index]; [item setTarget:self]; - NSValue* modelObject = [NSValue valueWithPointer:model]; - [item setRepresentedObject:modelObject]; // Retains |modelObject|. + [item setRepresentedObject:[WeakPtrToMenuModelAsNSObject + weakPtrForModel:model]]; // On the Mac, context menus never have accelerators. Menus constructed // for context use have useWithPopUpButtonCell_ set to NO. if (useWithPopUpButtonCell_) { @@ -216,8 +261,7 @@ NSInteger modelIndex = [item tag]; ui::MenuModel* model = - static_cast<ui::MenuModel*>( - [[(id)item representedObject] pointerValue]); + [WeakPtrToMenuModelAsNSObject getFrom:[(id)item representedObject]]; DCHECK(model); if (model) { BOOL checked = model->IsItemCheckedAt(modelIndex); @@ -303,8 +347,7 @@ NSInteger modelIndex = [sender tag]; ui::MenuModel* model = - static_cast<ui::MenuModel*>( - [[sender representedObject] pointerValue]); + [WeakPtrToMenuModelAsNSObject getFrom:[sender representedObject]]; DCHECK(model); if (model) model->ActivatedAt(modelIndex, uiEventFlags); @@ -313,7 +356,7 @@ - (NSMenu*)menu { if (!menu_ && model_) { - menu_.reset([[self menuFromModel:model_] retain]); + menu_.reset([[self menuFromModel:model_.get()] retain]); [menu_ setDelegate:self]; // If this is to be used with a NSPopUpButtonCell, add an item at the 0th // position that's empty. Doing it after the menu has been constructed won't @@ -334,13 +377,15 @@ - (void)menuWillOpen:(NSMenu*)menu { isMenuOpen_ = YES; - model_->MenuWillShow(); // Note: |model_| may trigger -[self dealloc]. + if (model_) + model_->MenuWillShow(); // Note: |model_| may trigger -[self dealloc]. } - (void)menuDidClose:(NSMenu*)menu { if (isMenuOpen_) { isMenuOpen_ = NO; - model_->MenuWillClose(); // Note: |model_| may trigger -[self dealloc]. + if (model_) + model_->MenuWillClose(); // Note: |model_| may trigger -[self dealloc]. } }
diff --git a/ui/base/cocoa/menu_controller_unittest.mm b/ui/base/cocoa/menu_controller_unittest.mm index 7b30ecb..6ae968c14 100644 --- a/ui/base/cocoa/menu_controller_unittest.mm +++ b/ui/base/cocoa/menu_controller_unittest.mm
@@ -281,7 +281,6 @@ NSString* title = [itemTwo title]; EXPECT_EQ(ASCIIToUTF16("three"), base::SysNSStringToUTF16(title)); EXPECT_EQ(2, [itemTwo tag]); - EXPECT_EQ([[itemTwo representedObject] pointerValue], &model); EXPECT_TRUE([[[menu menu] itemAtIndex:3] isSeparatorItem]); } @@ -315,7 +314,6 @@ NSString* title = [submenuItem title]; EXPECT_EQ(ASCIIToUTF16("sub-two"), base::SysNSStringToUTF16(title)); EXPECT_EQ(1, [submenuItem tag]); - EXPECT_EQ([[submenuItem representedObject] pointerValue], &submodel); // Make sure the item after the submenu is correct and its represented // object is back to the top model. @@ -323,7 +321,6 @@ title = [item title]; EXPECT_EQ(ASCIIToUTF16("three"), base::SysNSStringToUTF16(title)); EXPECT_EQ(2, [item tag]); - EXPECT_EQ([[item representedObject] pointerValue], &model); } TEST_F(MenuControllerTest, EmptySubmenu) {
diff --git a/ui/base/models/menu_model.h b/ui/base/models/menu_model.h index e0324ff1..b0ae539 100644 --- a/ui/base/models/menu_model.h +++ b/ui/base/models/menu_model.h
@@ -5,6 +5,7 @@ #ifndef UI_BASE_MODELS_MENU_MODEL_H_ #define UI_BASE_MODELS_MENU_MODEL_H_ +#include "base/memory/weak_ptr.h" #include "base/strings/string16.h" #include "ui/base/models/menu_model_delegate.h" #include "ui/base/models/menu_separator_types.h" @@ -24,7 +25,7 @@ class ButtonMenuItemModel; // An interface implemented by an object that provides the content of a menu. -class UI_BASE_EXPORT MenuModel { +class UI_BASE_EXPORT MenuModel : public base::SupportsWeakPtr<MenuModel> { public: // The type of item. enum ItemType {
diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc index 6f4f9e4..222ac2f 100644 --- a/ui/base/resource/resource_bundle.cc +++ b/ui/base/resource/resource_bundle.cc
@@ -632,19 +632,20 @@ return base::StringPiece(); } -std::string ResourceBundle::DecompressDataResource(int resource_id) { +std::string ResourceBundle::DecompressDataResource(int resource_id) const { return DecompressDataResourceScaled(resource_id, ui::SCALE_FACTOR_NONE); } std::string ResourceBundle::DecompressDataResourceScaled( int resource_id, - ScaleFactor scaling_factor) { + ScaleFactor scaling_factor) const { std::string output; Decompress(GetRawDataResourceForScale(resource_id, scaling_factor), &output); return output; } -std::string ResourceBundle::DecompressLocalizedDataResource(int resource_id) { +std::string ResourceBundle::DecompressLocalizedDataResource( + int resource_id) const { base::AutoLock lock_scope(*locale_resources_data_lock_); base::StringPiece data; if (!(locale_resources_data_.get() &&
diff --git a/ui/base/resource/resource_bundle.h b/ui/base/resource/resource_bundle.h index 22df0e6..e987fca 100644 --- a/ui/base/resource/resource_bundle.h +++ b/ui/base/resource/resource_bundle.h
@@ -254,16 +254,16 @@ // into a newly allocated string given the resource id. Todo: Look into // introducing an Async version of this function in the future. // Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=973417 - std::string DecompressDataResource(int resource_id); + std::string DecompressDataResource(int resource_id) const; // Return the contents of a scale dependent resource, decompressed into // a newly allocated string given the resource id. std::string DecompressDataResourceScaled(int resource_id, - ScaleFactor scaling_factor); + ScaleFactor scaling_factor) const; // Return the contents of a localized resource, decompressed into a // newly allocated string given the resource id. - std::string DecompressLocalizedDataResource(int resource_id); + std::string DecompressLocalizedDataResource(int resource_id) const; // Get a localized string given a message id. Returns an empty string if the // resource_id is not found.
diff --git a/ui/gfx/font_fallback_win.cc b/ui/gfx/font_fallback_win.cc index 3108d82..65d96cb0 100644 --- a/ui/gfx/font_fallback_win.cc +++ b/ui/gfx/font_fallback_win.cc
@@ -4,15 +4,9 @@ #include "ui/gfx/font_fallback_win.h" -#include <dwrite_2.h> -#include <usp10.h> -#include <wrl.h> -#include <wrl/client.h> - #include <algorithm> #include <map> -#include "base/i18n/rtl.h" #include "base/macros.h" #include "base/memory/singleton.h" #include "base/message_loop/message_loop_current.h" @@ -23,7 +17,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" #include "base/win/registry.h" -#include "base/win/scoped_gdi_object.h" #include "ui/gfx/font.h" #include "ui/gfx/font_fallback.h" #include "ui/gfx/font_fallback_skia_impl.h"
diff --git a/ui/gl/init/gl_factory_x11.cc b/ui/gl/init/gl_factory_x11.cc index 576f2d2..dcd3183 100644 --- a/ui/gl/init/gl_factory_x11.cc +++ b/ui/gl/init/gl_factory_x11.cc
@@ -79,9 +79,11 @@ return InitializeGLSurface(new GLSurfaceGLXX11(window)); case kGLImplementationSwiftShaderGL: case kGLImplementationEGLGLES2: - case kGLImplementationEGLANGLE: DCHECK(window != gfx::kNullAcceleratedWidget); return InitializeGLSurface(new NativeViewGLSurfaceEGLX11(window)); + case kGLImplementationEGLANGLE: + DCHECK(window != gfx::kNullAcceleratedWidget); + return InitializeGLSurface(new NativeViewGLSurfaceEGL(window, nullptr)); case kGLImplementationMockGL: case kGLImplementationStubGL: return new GLSurfaceStub;
diff --git a/ui/latency/histograms_perftest.cc b/ui/latency/histograms_perftest.cc index ab7480f..b05dbb84 100644 --- a/ui/latency/histograms_perftest.cc +++ b/ui/latency/histograms_perftest.cc
@@ -10,7 +10,7 @@ #include "base/metrics/sample_vector.h" #include "base/time/time.h" #include "testing/gtest/include/gtest/gtest.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" #include "ui/latency/fixed_point.h" #include "ui/latency/frame_metrics_test_common.h" @@ -52,6 +52,12 @@ DISALLOW_COPY_AND_ASSIGN(RatioHistogramBaseline); }; +perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) { + perf_test::PerfResultReporter reporter("FrameMetricsHistograms", story_name); + reporter.RegisterImportantMetric(".speedup", "score"); + return reporter; +} + TEST(FrameMetricsHistogramsPerfTest, RatioEntireRange) { const int kStride = 0x1000; @@ -90,8 +96,9 @@ } } - double X = base_time.InSecondsF() / impl_time.InSecondsF(); - perf_test::PrintResult(__FUNCTION__, "", __FUNCTION__, X, "x", true); + double speedup = base_time.InSecondsF() / impl_time.InSecondsF(); + perf_test::PerfResultReporter reporter = SetUpReporter("RatioEntireRange"); + reporter.AddResult(".speedup", speedup); } TEST(FrameMetricsHistogramsPerfTest, RatioCommonRange) { @@ -132,8 +139,9 @@ } } - double X = base_time.InSecondsF() / impl_time.InSecondsF(); - perf_test::PrintResult(__FUNCTION__, "", __FUNCTION__, X, "x", true); + double speedup = base_time.InSecondsF() / impl_time.InSecondsF(); + perf_test::PerfResultReporter reporter = SetUpReporter("RatioCommonRange"); + reporter.AddResult(".speedup", speedup); } // A version of VSyncHistogram based on the default implementations @@ -207,8 +215,9 @@ } } - double X = base_time.InSecondsF() / impl_time.InSecondsF(); - perf_test::PrintResult(__FUNCTION__, "", __FUNCTION__, X, "x", true); + double speedup = base_time.InSecondsF() / impl_time.InSecondsF(); + perf_test::PerfResultReporter reporter = SetUpReporter("VSyncEntireRange"); + reporter.AddResult(".speedup", speedup); } TEST(FrameMetricsHistogramsPerfTest, VSyncCommonRange) { @@ -249,8 +258,9 @@ } } - double X = base_time.InSecondsF() / impl_time.InSecondsF(); - perf_test::PrintResult(__FUNCTION__, "", __FUNCTION__, X, "x", true); + double speedup = base_time.InSecondsF() / impl_time.InSecondsF(); + perf_test::PerfResultReporter reporter = SetUpReporter("VSyncCommonRange"); + reporter.AddResult(".speedup", speedup); } } // namespace frame_metrics
diff --git a/ui/views/accessibility/ax_virtual_view.cc b/ui/views/accessibility/ax_virtual_view.cc index a1096586..23d8495b 100644 --- a/ui/views/accessibility/ax_virtual_view.cc +++ b/ui/views/accessibility/ax_virtual_view.cc
@@ -245,6 +245,10 @@ return nullptr; } +gfx::NativeViewAccessible AXVirtualView::GetNativeViewAccessible() { + return GetNativeObject(); +} + gfx::NativeViewAccessible AXVirtualView::GetParent() { if (parent_view_) return parent_view_->GetNativeObject();
diff --git a/ui/views/accessibility/ax_virtual_view.h b/ui/views/accessibility/ax_virtual_view.h index 9b808ad..799bf1b 100644 --- a/ui/views/accessibility/ax_virtual_view.h +++ b/ui/views/accessibility/ax_virtual_view.h
@@ -127,6 +127,7 @@ int GetChildCount() override; gfx::NativeViewAccessible ChildAtIndex(int index) override; gfx::NativeViewAccessible GetNSWindow() override; + gfx::NativeViewAccessible GetNativeViewAccessible() override; gfx::NativeViewAccessible GetParent() override; gfx::Rect GetBoundsRect( const ui::AXCoordinateSystem coordinate_system,
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate.cc b/ui/views/accessibility/view_ax_platform_node_delegate.cc index 0290635..f05bab0e4 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate.cc +++ b/ui/views/accessibility/view_ax_platform_node_delegate.cc
@@ -16,6 +16,7 @@ #include "ui/accessibility/platform/ax_platform_node.h" #include "ui/accessibility/platform/ax_platform_node_base.h" #include "ui/accessibility/platform/ax_unique_id.h" +#include "ui/base/layout.h" #include "ui/events/event_utils.h" #include "ui/views/accessibility/view_accessibility_utils.h" #include "ui/views/controls/native/native_view_host.h" @@ -284,6 +285,11 @@ return nullptr; } +gfx::NativeViewAccessible +ViewAXPlatformNodeDelegate::GetNativeViewAccessible() { + return GetNativeObject(); +} + gfx::NativeViewAccessible ViewAXPlatformNodeDelegate::GetParent() { if (view()->parent()) return view()->parent()->GetNativeViewAccessible(); @@ -320,6 +326,15 @@ if (IsLeaf()) return GetNativeObject(); + gfx::NativeView native_view = view()->GetWidget()->GetNativeView(); + float scale_factor = 1.0; + if (native_view) { + scale_factor = ui::GetScaleFactorForNativeView(native_view); + scale_factor = scale_factor <= 0 ? 1.0 : scale_factor; + } + x /= scale_factor; + y /= scale_factor; + // Search child widgets first, since they're on top in the z-order. for (Widget* child_widget : GetChildWidgets().child_widgets) { View* child_root_view = child_widget->GetRootView();
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate.h b/ui/views/accessibility/view_ax_platform_node_delegate.h index 6723ecf..c4ffb09ba2 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate.h +++ b/ui/views/accessibility/view_ax_platform_node_delegate.h
@@ -50,6 +50,7 @@ int GetChildCount() override; gfx::NativeViewAccessible ChildAtIndex(int index) override; gfx::NativeViewAccessible GetNSWindow() override; + gfx::NativeViewAccessible GetNativeViewAccessible() override; gfx::NativeViewAccessible GetParent() override; gfx::Rect GetBoundsRect( const ui::AXCoordinateSystem coordinate_system,
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate_auralinux.cc b/ui/views/accessibility/view_ax_platform_node_delegate_auralinux.cc index c2584d93..6733d69 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate_auralinux.cc +++ b/ui/views/accessibility/view_ax_platform_node_delegate_auralinux.cc
@@ -62,7 +62,7 @@ window->AddObserver(this); } - gfx::NativeViewAccessible GetNativeViewAccessible() { + gfx::NativeViewAccessible GetNativeViewAccessible() override { return platform_node_->GetNativeViewAccessible(); }
diff --git a/weblayer/OWNERS b/weblayer/OWNERS index f0bb477f..ec16922 100644 --- a/weblayer/OWNERS +++ b/weblayer/OWNERS
@@ -3,6 +3,7 @@ darin@chromium.org jam@chromium.org rockot@chromium.org +sky@chromium.org torne@chromium.org # TEAM: weblayer-dev@chromium.org
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/BrowserControllerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/BrowserControllerImpl.java index 6558a644..8d26cd4 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/BrowserControllerImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/BrowserControllerImpl.java
@@ -150,6 +150,12 @@ return ObjectWrapper.wrap(mContentViewRenderView); } + @Override + public void setSupportsEmbedding(boolean enable) { + mContentViewRenderView.requestMode(enable ? ContentViewRenderView.MODE_TEXTURE_VIEW + : ContentViewRenderView.MODE_SURFACE_VIEW); + } + private static native long nativeCreateBrowserController(long profile); private native void nativeSetTopControlsContainerView( long nativeBrowserControllerImpl, long nativeTopControlsContainerView);
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java b/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java index e7a96db..2de22ad2 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
@@ -127,7 +127,6 @@ mSurfaceView = new SurfaceView(getContext()); mSurfaceView.setZOrderMediaOverlay(true); mSurfaceView.setBackgroundColor(mBackgroundColor); - mWindowAndroid.setAnimationPlaceholderView(mSurfaceView); mSurfaceCallback = new SurfaceHolder.Callback() { @Override @@ -171,7 +170,6 @@ private void uninitializeSurfaceView() { if (mSurfaceView == null) return; removeView(mSurfaceView); - mWindowAndroid.setAnimationPlaceholderView(null); mSurfaceView.getHolder().removeCallback(mSurfaceCallback); mSurfaceCallback = null; mSurfaceView = null;
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/aidl/IBrowserController.aidl b/weblayer/browser/java/org/chromium/weblayer_private/aidl/IBrowserController.aidl index 778e044..d6cb2b6 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/aidl/IBrowserController.aidl +++ b/weblayer/browser/java/org/chromium/weblayer_private/aidl/IBrowserController.aidl
@@ -17,4 +17,6 @@ void destroy() = 3; IObjectWrapper onCreateView() = 4; + + void setSupportsEmbedding(in boolean enable) = 5; }
diff --git a/weblayer/public/java/org/chromium/weblayer/BrowserFragmentImpl.java b/weblayer/public/java/org/chromium/weblayer/BrowserFragmentImpl.java index 2400431..6914a11 100644 --- a/weblayer/public/java/org/chromium/weblayer/BrowserFragmentImpl.java +++ b/weblayer/public/java/org/chromium/weblayer/BrowserFragmentImpl.java
@@ -46,6 +46,21 @@ } } + /** + * Control support for embedding use cases such as animations. This should be enabled when the + * container view of the fragment is animated in any way, needs to be rotated or blended, or + * need to control z-order with other views or other BrowserFragmentImpls. Note embedder should + * keep WebLayer in the default non-embedding mode when user is interacting with the web + * content. + */ + public void setSupportsEmbedding(boolean enable) { + try { + getIBrowserController().setSupportsEmbedding(enable); + } catch (RemoteException e) { + throw new APICallException(e); + } + } + public BrowserController getBrowserController() { return mBrowserController; }
diff --git a/weblayer/shell/android/BUILD.gn b/weblayer/shell/android/BUILD.gn index 9549b9b4f..d6749d2 100644 --- a/weblayer/shell/android/BUILD.gn +++ b/weblayer/shell/android/BUILD.gn
@@ -59,6 +59,73 @@ native_lib_placeholders = [ "libdummy.so" ] } +generate_wrapper("run_weblayer_shell") { + testonly = true + wrapper_script = "$root_out_dir/bin/run_weblayer_shell" + executable = "//weblayer/tools/run_weblayer_shell.py" + executable_args = [ + "--shell-apk-path", + "@WrappedPath(apks/WebLayerShell.apk)", + "--support-apk-path", + "@WrappedPath(apks/WebLayerSupport.apk)", + ] + + deps = [ + ":weblayer_shell_apk", + ":weblayer_support_apk", + ] +} + +demo_apk_manifest = "$target_gen_dir/demo_apk_manifest/AndroidManifest.xml" + +jinja_template("demo_apk_manifest") { + input = "demo_apk/AndroidManifest.xml" + output = demo_apk_manifest +} + +android_assets("demo_apk_assets") { + testonly = true + + sources = [ + "$root_out_dir/weblayer_shell.pak", + ] + disable_compression = true + deps = [ + "//weblayer/shell:shell_pak", + ] +} + +android_library("demo_apk_java") { + testonly = true + + deps = [ + ":demo_apk_manifest", + "//third_party/android_deps:android_support_v4_java", + "//weblayer/public/java", + ] + java_files = [ "demo_apk/src/org/chromium/weblayer/demo/WebLayerAnimationDemoActivity.java" ] + + android_manifest_for_lint = demo_apk_manifest +} + +android_apk("weblayer_demo_apk") { + testonly = true + + deps = [ + ":demo_apk_assets", + ":demo_apk_java", + ":demo_apk_manifest", + ] + apk_name = "WebLayerDemo" + android_manifest = demo_apk_manifest + min_sdk_version = 21 + target_sdk_version = 28 + android_manifest_dep = ":demo_apk_manifest" + + # Add a native lib so the ABI is compatible with the implementation APK. + native_lib_placeholders = [ "libdummy.so" ] +} + weblayer_support_manifest = "$target_gen_dir/weblayer_support_manifest/AndroidManifest.xml" @@ -117,23 +184,6 @@ shared_libraries = [ "//weblayer:libweblayer" ] } -generate_wrapper("run_weblayer_shell") { - testonly = true - wrapper_script = "$root_out_dir/bin/run_weblayer_shell" - executable = "//weblayer/tools/run_weblayer_shell.py" - executable_args = [ - "--shell-apk-path", - "@WrappedPath(apks/WebLayerShell.apk)", - "--support-apk-path", - "@WrappedPath(apks/WebLayerSupport.apk)", - ] - - deps = [ - ":weblayer_shell_apk", - ":weblayer_support_apk", - ] -} - instrumentation_test_apk("weblayer_instrumentation_test_apk") { apk_name = "WebLayerInstrumentationTest" apk_under_test = "//weblayer/shell/android:weblayer_shell_apk" @@ -146,6 +196,7 @@ ] java_files = [ "javatests/src/org/chromium/weblayer/test/NavigationTest.java", + "javatests/src/org/chromium/weblayer/test/SmokeTest.java", "javatests/src/org/chromium/weblayer/test/WebLayerShellActivityTestRule.java", "shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java", ]
diff --git a/weblayer/shell/android/demo_apk/AndroidManifest.xml b/weblayer/shell/android/demo_apk/AndroidManifest.xml new file mode 100644 index 0000000..2ecd2b3 --- /dev/null +++ b/weblayer/shell/android/demo_apk/AndroidManifest.xml
@@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- 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. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.chromium.weblayer.demo"> + + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> + <uses-permission android:name="android.permission.CAMERA"/> + <uses-permission android:name="android.permission.INTERNET"/> + <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> + <uses-permission android:name="android.permission.RECORD_AUDIO"/> + <uses-permission android:name="android.permission.VIBRATE"/> + <uses-permission android:name="android.permission.WAKE_LOCK"/> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> + + <application android:label="Demo"> + <activity android:name="WebLayerAnimationDemoActivity" + android:launchMode="singleTask" + android:theme="@android:style/Theme.Holo.Light.NoActionBar" + android:configChanges="orientation|keyboardHidden|keyboard|screenSize" + android:windowSoftInputMode="adjustPan|stateUnspecified"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> + </application> +</manifest>
diff --git a/weblayer/shell/android/demo_apk/DEPS b/weblayer/shell/android/demo_apk/DEPS new file mode 100644 index 0000000..fd9e2a83 --- /dev/null +++ b/weblayer/shell/android/demo_apk/DEPS
@@ -0,0 +1,4 @@ +noparent = True +include_rules = [ + "+weblayer/public/java", +]
diff --git a/weblayer/shell/android/demo_apk/README.md b/weblayer/shell/android/demo_apk/README.md new file mode 100644 index 0000000..5b91539 --- /dev/null +++ b/weblayer/shell/android/demo_apk/README.md
@@ -0,0 +1,11 @@ +# WebLayer Shell + +This directory contains a demo app to demonstrate capabilities of WebLayer. + +To build and run on Android: +``` +autoninja -C out/Default weblayer_support_apk weblayer_demo_apk +out/Default/bin/weblayer_support_apk install +out/Default/bin/weblayer_demo_apk install +adb shell am start org.chromium.weblayer.demo/.WebLayerAnimationDemoActivity +```
diff --git a/weblayer/shell/android/demo_apk/src/org/chromium/weblayer/demo/WebLayerAnimationDemoActivity.java b/weblayer/shell/android/demo_apk/src/org/chromium/weblayer/demo/WebLayerAnimationDemoActivity.java new file mode 100644 index 0000000..a8d5cca --- /dev/null +++ b/weblayer/shell/android/demo_apk/src/org/chromium/weblayer/demo/WebLayerAnimationDemoActivity.java
@@ -0,0 +1,241 @@ +// 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.weblayer.demo; + +import android.content.Context; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentTransaction; +import android.text.InputType; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.TextView; +import android.widget.TextView.OnEditorActionListener; + +import org.chromium.weblayer.BrowserController; +import org.chromium.weblayer.BrowserFragmentImpl; +import org.chromium.weblayer.BrowserObserver; +import org.chromium.weblayer.Profile; +import org.chromium.weblayer.WebLayer; + +/** + * Activity for managing the Demo Shell. + */ +public class WebLayerAnimationDemoActivity extends FragmentActivity { + private static final String TAG = "AnimationDemo"; + + private Profile mProfile; + private final BrowserFragmentImpl mBrowserFragments[] = new BrowserFragmentImpl[4]; + private final ContainerFrameLayout mContainerViews[] = new ContainerFrameLayout[4]; + private FrameLayout mMainView; + + public static class ShellFragment extends Fragment { + private BrowserFragmentImpl mBrowserFragment; + + ShellFragment(BrowserFragmentImpl browserFragment) { + mBrowserFragment = browserFragment; + } + + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return mBrowserFragment.onCreateView(); + } + } + + public static class ContainerFrameLayout extends FrameLayout { + private int mIndex; + private boolean mInterceptTouchEvent; + + public ContainerFrameLayout(Context context, int index) { + super(context); + mIndex = index; + } + + public void setInterceptTouchEvent(boolean intercept) { + mInterceptTouchEvent = intercept; + } + + public int getIndex() { + return mIndex; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return mInterceptTouchEvent; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (!mInterceptTouchEvent) return super.onTouchEvent(event); + if (event.getAction() == KeyEvent.ACTION_UP) { + performClick(); + } + return true; + } + } + + private void createNewFragment(int index) { + ContainerFrameLayout container = new ContainerFrameLayout(this, index); + mContainerViews[index] = container; + int viewId = View.generateViewId(); + container.setId(viewId); + mMainView.addView(container); + + mBrowserFragments[index] = mProfile.createBrowserFragment(this); + final BrowserController controller = mBrowserFragments[index].getBrowserController(); + + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + transaction.add(viewId, new ShellFragment(mBrowserFragments[index])); + transaction.commit(); + + EditText urlView = new EditText(this); + urlView.setSelectAllOnFocus(true); + urlView.setInputType(InputType.TYPE_TEXT_VARIATION_URI); + urlView.setImeOptions(EditorInfo.IME_ACTION_GO); + // The background of the top-view must be opaque, otherwise it bleeds through to the + // cc::Layer that mirrors the contents of the top-view. + urlView.setBackgroundColor(0xFFa9a9a9); + urlView.setOnEditorActionListener(new OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if ((actionId != EditorInfo.IME_ACTION_GO) + && (event == null || event.getKeyCode() != KeyEvent.KEYCODE_ENTER + || event.getAction() != KeyEvent.ACTION_DOWN)) { + return false; + } + String url = urlView.getText().toString(); + controller.getNavigationController().navigate(Uri.parse(sanitizeUrl(url))); + return true; + } + }); + mBrowserFragments[index].setTopView(urlView); + + controller.addObserver(new BrowserObserver() { + @Override + public void displayURLChanged(Uri uri) { + urlView.setText(uri.toString()); + } + }); + } + + @Override + protected void onCreate(final Bundle savedInstanceState) { + // Only call init for main process. + WebLayer.getInstance().init(getApplication()); + + super.onCreate(savedInstanceState); + + FrameLayout mainView = new FrameLayout(this); + mMainView = mainView; + setContentView(mainView); + + mProfile = WebLayer.getInstance().createProfile(null); + + createNewFragment(0); + createNewFragment(1); + createNewFragment(2); + + mBrowserFragments[0].getBrowserController().getNavigationController().navigate( + Uri.parse(sanitizeUrl("https://www.google.com"))); + mBrowserFragments[1].getBrowserController().getNavigationController().navigate( + Uri.parse(sanitizeUrl("https://en.wikipedia.org"))); + mBrowserFragments[2].getBrowserController().getNavigationController().navigate( + Uri.parse(sanitizeUrl("https://www.chromium.org"))); + } + + @Override + protected void onDestroy() { + for (int i = 0; i < mBrowserFragments.length; ++i) { + BrowserFragmentImpl fragment = mBrowserFragments[i]; + if (fragment != null) fragment.destroy(); + mBrowserFragments[i] = null; + } + if (mProfile != null) mProfile.destroy(); + super.onDestroy(); + } + + @Override + protected void onStart() { + super.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + + mContainerViews[0].setOnClickListener(new OnClickImpl()); + mContainerViews[1].setOnClickListener(new OnClickImpl()); + mContainerViews[2].setOnClickListener(new OnClickImpl()); + mContainerViews[0].post(() -> { + mBrowserFragments[0].setSupportsEmbedding(true); + mBrowserFragments[1].setSupportsEmbedding(true); + mBrowserFragments[2].setSupportsEmbedding(true); + animateDown(mContainerViews[0]); + animateDown(mContainerViews[1]); + animateDown(mContainerViews[2]); + }); + } + + private ContainerFrameLayout mFullscreenContainer; + public class OnClickImpl implements View.OnClickListener { + @Override + public void onClick(View v) { + ContainerFrameLayout container = (ContainerFrameLayout) v; + if (mFullscreenContainer == container) return; + + mMainView.removeView(container); + mMainView.addView(container, 0); + + if (mFullscreenContainer != null) { + animateDown(mFullscreenContainer); + } + animateUp(container); + mFullscreenContainer = container; + } + } + + private static void animateDown(ContainerFrameLayout container) { + int index = container.getIndex(); + container.animate() + .scaleX(1.0f / 3) + .scaleY(1.0f / 3) + .translationX(-container.getWidth() / 3.0f + (container.getWidth() / 3.0f * index)) + .translationY(container.getHeight() / 3.0f) + .alpha(0.8f) + .setDuration(500); + container.setInterceptTouchEvent(true); + } + + private static void animateUp(ContainerFrameLayout container) { + container.animate() + .scaleX(1.0f) + .scaleY(1.0f) + .translationX(0) + .translationY(0) + .alpha(1.0f) + .setDuration(500); + container.setInterceptTouchEvent(false); + } + + /** + * Given an URL, this performs minimal sanitizing to ensure it will be valid. + * @param url The url to be sanitized. + * @return The sanitized URL. + */ + public static String sanitizeUrl(String url) { + if (url == null) return null; + if (url.startsWith("www.") || url.indexOf(":") == -1) url = "http://" + url; + return url; + } +}
diff --git a/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/SmokeTest.java b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/SmokeTest.java new file mode 100644 index 0000000..945087f --- /dev/null +++ b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/SmokeTest.java
@@ -0,0 +1,36 @@ +// 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.weblayer.test; + +import android.support.test.filters.SmallTest; + +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.weblayer.shell.WebLayerShellActivity; + +@RunWith(BaseJUnit4ClassRunner.class) +public class SmokeTest { + @Rule + public WebLayerShellActivityTestRule mActivityTestRule = new WebLayerShellActivityTestRule(); + + @Test + @SmallTest + public void testSetSupportEmbedding() { + WebLayerShellActivity activity = mActivityTestRule.launchShellWithUrl("about:blank"); + Assert.assertNotNull(activity); + + TestThreadUtils.runOnUiThreadBlocking( + () -> { activity.getBrowserFragmentImpl().setSupportsEmbedding(true); }); + + String url = "data:text,foo"; + mActivityTestRule.loadUrl(url); + mActivityTestRule.waitForNavigation(url); + } +}
diff --git a/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java b/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java index 10ffcab3..39fd147 100644 --- a/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java +++ b/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java
@@ -58,6 +58,10 @@ return mBrowserController; } + public BrowserFragmentImpl getBrowserFragmentImpl() { + return mBrowserFragment; + } + @Override protected void onCreate(final Bundle savedInstanceState) { // Only call init for main process.